52 wxBoxSizer* mainSizer =
new wxBoxSizer( wxVERTICAL );
54#if !wxCHECK_VERSION( 3, 3, 0 )
58 wxPGInitResourceModule();
65 wxPGEditor_TextCtrl =
nullptr;
66 wxPGEditor_Choice =
nullptr;
67 wxPGEditor_ComboBox =
nullptr;
68 wxPGEditor_TextCtrlAndButton =
nullptr;
69 wxPGEditor_CheckBox =
nullptr;
70 wxPGEditor_ChoiceAndButton =
nullptr;
71 wxPGEditor_SpinCtrl =
nullptr;
72 wxPGEditor_DatePickerCtrl =
nullptr;
75 if( !
Pgm().m_PropertyGridInitialized )
82 m_caption =
new wxStaticText(
this, wxID_ANY,
_(
"No objects selected" ) );
83 mainSizer->Add(
m_caption, 0, wxALL | wxEXPAND, 5 );
85 m_grid =
new wxPropertyGrid(
this );
86 m_grid->SetUnspecifiedValueAppearance( wxPGCell( wxT(
"<...>" ) ) );
87 m_grid->SetExtraStyle( wxPG_EX_HELP_AS_TOOLTIPS );
89#if wxCHECK_VERSION( 3, 3, 0 )
90 m_grid->SetValidationFailureBehavior( wxPGVFBFlags::MarkCell );
92 m_grid->SetValidationFailureBehavior( wxPG_VFB_MARK_CELL );
95#if wxCHECK_VERSION( 3, 3, 0 )
96 m_grid->AddActionTrigger( wxPGKeyboardAction::NextProperty, WXK_RETURN );
97 m_grid->AddActionTrigger( wxPGKeyboardAction::NextProperty, WXK_NUMPAD_ENTER );
98 m_grid->AddActionTrigger( wxPGKeyboardAction::NextProperty, WXK_DOWN );
99 m_grid->AddActionTrigger( wxPGKeyboardAction::PrevProperty, WXK_UP );
100 m_grid->AddActionTrigger( wxPGKeyboardAction::Edit, WXK_SPACE );
102 m_grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_RETURN );
103 m_grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_NUMPAD_ENTER );
104 m_grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_DOWN );
105 m_grid->AddActionTrigger( wxPG_ACTION_PREV_PROPERTY, WXK_UP );
106 m_grid->AddActionTrigger( wxPG_ACTION_EDIT, WXK_SPACE );
109 m_grid->DedicateKey( WXK_RETURN );
110 m_grid->DedicateKey( WXK_NUMPAD_ENTER );
111 m_grid->DedicateKey( WXK_DOWN );
112 m_grid->DedicateKey( WXK_UP );
113 mainSizer->Add(
m_grid, 1, wxEXPAND, 5 );
115 m_grid->SetCellDisabledTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
119 m_grid->SetCaptionTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_CAPTIONTEXT ) );
124 SetSizer( mainSizer );
134 Bind( wxEVT_PG_COL_END_DRAG,
135 [&]( wxPropertyGridEvent& )
141 [&]( wxSizeEvent& aEvent )
194 if(
m_grid->IsEditorFocused() )
195 m_grid->CommitChangesFromEditor();
201 if( aSelection.
Empty() )
203 m_caption->SetLabel(
_(
"No objects selected" ) );
207 else if( aSelection.
Size() == 1 )
213 m_caption->SetLabel( wxString::Format(
_(
"%d objects selected" ), aSelection.
Size() ) );
217 std::set<TYPE_ID> types;
222 wxCHECK( !types.empty(), );
225 std::map<wxString, PROPERTY_BASE*> commonProps;
226 const std::vector<PROPERTY_BASE*>& allProperties = propMgr.
GetProperties( *types.begin() );
229 commonProps.emplace( property->Name(), property );
231 std::map<wxString, int> displayOrder;
233 displayOrder.emplace( entry.first->Name(), entry.second );
236 std::set<wxString> groups( groupDisplayOrder.begin(), groupDisplayOrder.end() );
239 for(
auto itType = std::next( types.begin() ); itType != types.end(); ++itType )
245 if( !groups.count(
group ) )
247 groupDisplayOrder.emplace_back(
group );
248 groups.insert(
group );
252 for(
auto it = commonProps.begin(); it != commonProps.end(); )
255 it = commonProps.erase( it );
267 std::set<wxString> availableProps;
270 for(
auto& [
name, property] : commonProps )
272 if( property->IsHiddenFromPropertiesManager() )
275 if( isLibraryEditor && property->IsHiddenFromLibraryEditors() )
278 if( isDesignEditor && property->IsHiddenFromDesignEditors() )
286 availableProps.insert(
name );
289 bool writeable =
true;
290 std::set<wxString> existingProps;
292 for( wxPropertyGridIterator it =
m_grid->GetIterator(); !it.AtEnd(); it.Next() )
294 wxPGProperty* pgProp = it.GetProperty();
295 wxString
name = pgProp->GetName();
299 existingProps.insert(
name );
301 if( !availableProps.count(
name ) )
309 if( choices.GetCount() > 0 )
310 pgProp->SetChoices( choices );
312 pgProp->SetValue( commonVal );
313 pgProp->Enable( writeable );
316 if( !existingProps.empty() && existingProps == availableProps )
322 std::map<wxPGProperty*, int> pgPropOrders;
323 std::map<wxString, std::vector<wxPGProperty*>> pgPropGroups;
325 for(
const wxString&
name : availableProps )
337 if( choices.GetCount() )
338 pgProp->SetChoices( choices );
340 pgProp->SetValue( commonVal );
341 pgProp->Enable( writeable );
344 wxASSERT( displayOrder.count(
name ) );
345 pgPropOrders[pgProp] = displayOrder[
name];
346 pgPropGroups[
property->Group()].emplace_back( pgProp );
350 const wxString unspecifiedGroupCaption =
_(
"Basic Properties" );
352 for(
const wxString& groupName : groupDisplayOrder )
354 if( !pgPropGroups.count( groupName ) )
357 std::vector<wxPGProperty*>& properties = pgPropGroups[groupName];
358 wxString groupCaption = wxGetTranslation( groupName );
360 auto groupItem =
new wxPropertyCategory( groupName.IsEmpty() ? unspecifiedGroupCaption
363 m_grid->Append( groupItem );
365 std::sort( properties.begin(), properties.end(),
366 [&]( wxPGProperty*& aFirst, wxPGProperty*& aSecond )
368 return pgPropOrders[aFirst] < pgPropOrders[aSecond];
371 for( wxPGProperty* property : properties )
372 m_grid->Append( property );
411 wxVariant& aValue,
bool& aWritable, wxPGChoices& aChoices )
414 bool different =
false;
429 if( property->IsHiddenFromPropertiesManager() )
432 wxPGChoices choices =
property->
GetChoices( item );
441 wxArrayString labels = choices.GetLabels();
442 wxArrayInt values = choices.GetValuesForStrings( labels );
444 if( labels != aChoices.GetLabels() || values != aChoices.GetValuesForStrings( labels ) )
457 if( !different && !aValue.IsNull() && value != aValue )
462 else if( !different )
490 if( aEvent.GetKeyCode() == WXK_TAB && !aEvent.ShiftDown() )
494 if( wxPGProperty* prop =
m_grid->GetSelectedProperty() )
495 oldValue = prop->GetValue();
497 m_grid->CommitChangesFromEditor();
500 if( wxPGProperty* prop =
m_grid->GetSelectedProperty() )
502 if( prop->GetValue() == oldValue )
509 if( aEvent.GetKeyCode() == WXK_SPACE )
511 if( wxPGProperty* prop =
m_grid->GetSelectedProperty() )
513 if( prop->GetValueType() == wxT(
"bool" ) )
515 m_grid->SetPropertyValue( prop, !prop->GetValue().GetBool() );
521 if( aEvent.GetKeyCode() == WXK_RETURN || aEvent.GetKeyCode() == WXK_NUMPAD_ENTER
522 || aEvent.GetKeyCode() == WXK_DOWN || aEvent.GetKeyCode() == WXK_UP )
524 m_grid->CommitChangesFromEditor();
528 m_grid->SelectProperty(
m_grid->GetSelectedProperty(),
true );