32#include <wx/settings.h>
33#include <wx/stattext.h>
34#include <wx/propgrid/advprops.h>
38#if !wxCHECK_VERSION( 3, 3, 0 )
45 m_splitter_key_proportion( -1 )
47 wxBoxSizer* mainSizer =
new wxBoxSizer( wxVERTICAL );
52 wxPGInitResourceModule();
58 wxPGEditor_TextCtrl =
nullptr;
59 wxPGEditor_Choice =
nullptr;
60 wxPGEditor_ComboBox =
nullptr;
61 wxPGEditor_TextCtrlAndButton =
nullptr;
62 wxPGEditor_CheckBox =
nullptr;
63 wxPGEditor_ChoiceAndButton =
nullptr;
64 wxPGEditor_SpinCtrl =
nullptr;
65 wxPGEditor_DatePickerCtrl =
nullptr;
74 m_caption =
new wxStaticText(
this, wxID_ANY,
_(
"No objects selected" ) );
75 mainSizer->Add(
m_caption, 0, wxALL | wxEXPAND, 5 );
77 m_grid =
new wxPropertyGrid(
this );
78 m_grid->SetUnspecifiedValueAppearance( wxPGCell( wxT(
"<...>" ) ) );
79 m_grid->SetExtraStyle( wxPG_EX_HELP_AS_TOOLTIPS );
81#if wxCHECK_VERSION( 3, 3, 0 )
82 m_grid->SetValidationFailureBehavior( wxPGVFBFlags::MarkCell );
84 m_grid->SetValidationFailureBehavior( wxPG_VFB_MARK_CELL );
87#if wxCHECK_VERSION( 3, 3, 0 )
88 m_grid->AddActionTrigger( wxPGKeyboardActions::NextProperty, WXK_RETURN );
89 m_grid->AddActionTrigger( wxPGKeyboardActions::NextProperty, WXK_NUMPAD_ENTER );
90 m_grid->AddActionTrigger( wxPGKeyboardActions::NextProperty, WXK_DOWN );
91 m_grid->AddActionTrigger( wxPGKeyboardActions::PrevProperty, WXK_UP );
92 m_grid->AddActionTrigger( wxPGKeyboardActions::Edit, WXK_SPACE );
94 m_grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_RETURN );
95 m_grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_NUMPAD_ENTER );
96 m_grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_DOWN );
97 m_grid->AddActionTrigger( wxPG_ACTION_PREV_PROPERTY, WXK_UP );
98 m_grid->AddActionTrigger( wxPG_ACTION_EDIT, WXK_SPACE );
101 m_grid->DedicateKey( WXK_RETURN );
102 m_grid->DedicateKey( WXK_NUMPAD_ENTER );
103 m_grid->DedicateKey( WXK_DOWN );
104 m_grid->DedicateKey( WXK_UP );
105 mainSizer->Add(
m_grid, 1, wxEXPAND, 5 );
107 m_grid->SetCellDisabledTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
111 m_grid->SetCaptionTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_CAPTIONTEXT ) );
116 SetSizer( mainSizer );
126 Bind( wxEVT_PG_COL_END_DRAG,
127 [&]( wxPropertyGridEvent& )
130 static_cast<float>(
m_grid->GetSplitterPosition() ) /
m_grid->GetSize().x;
134 [&]( wxSizeEvent& aEvent )
156 if(
m_grid->IsEditorFocused() )
157 m_grid->CommitChangesFromEditor();
163 if( aSelection.
Empty() )
165 m_caption->SetLabel(
_(
"No objects selected" ) );
171 std::set<TYPE_ID> types;
176 wxCHECK( !types.empty(), );
179 std::set<PROPERTY_BASE*> commonProps;
182 copy( allProperties.begin(), allProperties.end(), inserter( commonProps, commonProps.begin() ) );
187 std::set<wxString> groups( groupDisplayOrder.begin(), groupDisplayOrder.end() );
189 std::set<PROPERTY_BASE*> availableProps;
192 for(
const TYPE_ID& type : types )
198 copy( itemDisplayOrder.begin(), itemDisplayOrder.end(),
199 inserter( displayOrder, displayOrder.begin() ) );
203 for(
const wxString&
group : itemGroups )
205 if( !groups.count(
group ) )
207 groupDisplayOrder.emplace_back(
group );
208 groups.insert(
group );
212 for(
auto it = commonProps.begin(); it != commonProps.end(); )
214 if( !binary_search( itemProps.begin(), itemProps.end(), *it ) )
215 it = commonProps.erase( it );
227 if( property->IsHiddenFromPropertiesManager() )
230 if( isFootprintEditor && property->IsHiddenFromLibraryEditors() )
234 availableProps.insert( property );
237 bool writeable =
true;
238 std::set<PROPERTY_BASE*> existingProps;
240 for( wxPropertyGridIterator it =
m_grid->GetIterator(); !it.AtEnd(); it.Next() )
242 wxPGProperty* pgProp = it.GetProperty();
252 pgProp->SetValue( commonVal );
253 pgProp->Enable( writeable );
255 existingProps.insert( property );
258 if( !existingProps.empty() && existingProps == availableProps )
264 std::map<wxPGProperty*, int> pgPropOrders;
265 std::map<wxString, std::vector<wxPGProperty*>> pgPropGroups;
277 pgProp->SetValue( commonVal );
278 pgProp->Enable( writeable );
281 wxASSERT( displayOrder.count( property ) );
282 pgPropOrders[pgProp] = displayOrder[property];
283 pgPropGroups[
property->Group()].emplace_back( pgProp );
287 if( aSelection.
Size() > 1 )
289 m_caption->SetLabel( wxString::Format(
_(
"%d objects selected" ), aSelection.
Size() ) );
296 const wxString unspecifiedGroupCaption =
_(
"Basic Properties" );
298 for(
const wxString& groupName : groupDisplayOrder )
300 if( !pgPropGroups.count( groupName ) )
303 std::vector<wxPGProperty*>& properties = pgPropGroups[groupName];
304 wxString groupCaption = wxGetTranslation( groupName );
306 auto groupItem =
new wxPropertyCategory( groupName.IsEmpty() ? unspecifiedGroupCaption
309 m_grid->Append( groupItem );
311 std::sort( properties.begin(), properties.end(),
312 [&]( wxPGProperty*& aFirst, wxPGProperty*& aSecond )
314 return pgPropOrders[aFirst] < pgPropOrders[aSecond];
317 for( wxPGProperty* property : properties )
318 m_grid->Append( property );
327 const wxAny& any = aItem->
Get( aProperty );
328 bool converted =
false;
334 converted = any.GetAs<
int>( &tmp );
337 aValue = wxVariant( tmp );
341 converted = any.GetAs( &aValue );
344 wxFAIL_MSG( wxS(
"Could not convert wxAny to wxVariant" ) );
352 wxVariant& aValue,
bool& aWritable )
355 bool different =
false;
374 if( !different && !aValue.IsNull() && value != aValue )
379 else if( !different )
397 if( aEvent.IsShown() )
404 if( aEvent.GetKeyCode() == WXK_TAB && !aEvent.ShiftDown() )
406 m_grid->CommitChangesFromEditor();
410 if( aEvent.GetKeyCode() == WXK_SPACE )
412 if( wxPGProperty* prop =
m_grid->GetSelectedProperty() )
414 if( prop->GetValueType() == wxT(
"bool" ) )
416 m_grid->SetPropertyValue( prop, !prop->GetValue().GetBool() );
422 if( aEvent.GetKeyCode() == WXK_RETURN || aEvent.GetKeyCode() == WXK_NUMPAD_ENTER )
424 m_grid->CommitChangesFromEditor();
The base frame for deriving all KiCad main window classes.
bool IsType(FRAME_T aType) const
A base class for most all the KiCad significant classes used in schematics and boards.
virtual wxString GetFriendlyName() const
wxAny Get(PROPERTY_BASE *aProperty) const
Enhanced renderer to work around some limitations in wxWidgets 3.0 capabilities.
float m_splitter_key_proportion
Proportion of the grid column splitter that is used for the key column (0.0 - 1.0)
PROPERTIES_PANEL(wxWindow *aParent, EDA_BASE_FRAME *aFrame)
virtual void valueChanging(wxPropertyGridEvent &aEvent)
bool extractValueAndWritability(const SELECTION &aSelection, PROPERTY_BASE *aProperty, wxVariant &aValue, bool &aWritable)
Processes a selection and determines whether the given property should be available or not and what t...
void RecalculateSplitterPos()
void SetSplitterProportion(float aProportion)
std::vector< PROPERTY_BASE * > m_displayed
virtual void UpdateData()=0
virtual void valueChanged(wxPropertyGridEvent &aEvent)
bool getItemValue(EDA_ITEM *aItem, PROPERTY_BASE *aProperty, wxVariant &aValue)
Utility to fetch a property value and convert to wxVariant Precondition: aItem is known to have prope...
virtual void rebuildProperties(const SELECTION &aSelection)
Generates the property grid for a given selection of items.
void onCharHook(wxKeyEvent &aEvent)
virtual wxPGProperty * createPGProperty(const PROPERTY_BASE *aProperty) const =0
void onShow(wxShowEvent &aEvent)
virtual bool HasChoices() const
Return true if this PROPERTY has a limited set of possible values.
Provide class metadata.Helper macro to map type hashes to names.
const PROPERTY_LIST & GetProperties(TYPE_ID aType) const
Return all properties for a specific type.
const PROPERTY_DISPLAY_ORDER & GetDisplayOrder(TYPE_ID aType) const
bool IsWriteableFor(TYPE_ID aItemClass, PROPERTY_BASE *aProp, INSPECTABLE *aItem)
Checks overriden availability and original availability of a property, returns false if the property ...
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE * GetProperty(TYPE_ID aType, const wxString &aProperty) const
Return a property for a specific type.
bool IsAvailableFor(TYPE_ID aItemClass, PROPERTY_BASE *aProp, INSPECTABLE *aItem)
Checks overriden availability and original availability of a property, returns false if the property ...
const std::vector< wxString > & GetGroupDisplayOrder(TYPE_ID aType) const
int Size() const
Returns the number of selected parts.
bool Empty() const
Checks if there is anything selected.
Base window classes and related definitions.
wxFont GetDockedPaneFont(wxWindow *aWindow)
APIIMPORT wxPGGlobalVarsClass * wxPGGlobalVars
std::vector< PROPERTY_BASE * > PROPERTY_LIST
std::map< PROPERTY_BASE *, int > PROPERTY_DISPLAY_ORDER
size_t TYPE_ID
Unique type identifier.