Properties: fix rebuilding when availability changes
(cherry picked from commit 61dd4b7043
)
This commit is contained in:
parent
15bef82e1e
commit
1909ce9220
|
@ -65,8 +65,6 @@ PROPERTIES_PANEL::PROPERTIES_PANEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame )
|
||||||
delete wxPGGlobalVars->m_defaultRenderer;
|
delete wxPGGlobalVars->m_defaultRenderer;
|
||||||
wxPGGlobalVars->m_defaultRenderer = new PG_CELL_RENDERER();
|
wxPGGlobalVars->m_defaultRenderer = new PG_CELL_RENDERER();
|
||||||
|
|
||||||
m_cachedSelection = std::make_unique<SELECTION>();
|
|
||||||
|
|
||||||
m_caption = new wxStaticText( this, wxID_ANY, _( "No objects selected" ) );
|
m_caption = new wxStaticText( this, wxID_ANY, _( "No objects selected" ) );
|
||||||
mainSizer->Add( m_caption, 0, wxALL | wxEXPAND, 5 );
|
mainSizer->Add( m_caption, 0, wxALL | wxEXPAND, 5 );
|
||||||
|
|
||||||
|
@ -132,23 +130,20 @@ void PROPERTIES_PANEL::OnLanguageChanged()
|
||||||
|
|
||||||
void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||||
{
|
{
|
||||||
if( *m_cachedSelection == aSelection )
|
auto reset =
|
||||||
{
|
[&]()
|
||||||
updatePropertyValues( aSelection );
|
{
|
||||||
return;
|
if( m_grid->IsEditorFocused() )
|
||||||
}
|
m_grid->CommitChangesFromEditor();
|
||||||
|
|
||||||
*m_cachedSelection = aSelection;
|
m_grid->Clear();
|
||||||
|
m_displayed.clear();
|
||||||
if( m_grid->IsEditorFocused() )
|
};
|
||||||
m_grid->CommitChangesFromEditor();
|
|
||||||
|
|
||||||
m_grid->Clear();
|
|
||||||
m_displayed.clear();
|
|
||||||
|
|
||||||
if( aSelection.Empty() )
|
if( aSelection.Empty() )
|
||||||
{
|
{
|
||||||
m_caption->SetLabel( _( "No objects selected" ) );
|
m_caption->SetLabel( _( "No objects selected" ) );
|
||||||
|
reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,15 +155,6 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||||
|
|
||||||
wxCHECK( !types.empty(), /* void */ );
|
wxCHECK( !types.empty(), /* void */ );
|
||||||
|
|
||||||
if( aSelection.Size() > 1 )
|
|
||||||
{
|
|
||||||
m_caption->SetLabel( wxString::Format( _( "%d objects selected" ), aSelection.Size() ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_caption->SetLabel( aSelection.Front()->GetFriendlyName() );
|
|
||||||
}
|
|
||||||
|
|
||||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||||
propMgr.SetUnits( m_frame->GetUserUnits() );
|
propMgr.SetUnits( m_frame->GetUserUnits() );
|
||||||
propMgr.SetTransforms( &m_frame->GetOriginTransforms() );
|
propMgr.SetTransforms( &m_frame->GetOriginTransforms() );
|
||||||
|
@ -182,8 +168,7 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||||
std::vector<wxString> groupDisplayOrder = propMgr.GetGroupDisplayOrder( *types.begin() );
|
std::vector<wxString> groupDisplayOrder = propMgr.GetGroupDisplayOrder( *types.begin() );
|
||||||
std::set<wxString> groups( groupDisplayOrder.begin(), groupDisplayOrder.end() );
|
std::set<wxString> groups( groupDisplayOrder.begin(), groupDisplayOrder.end() );
|
||||||
|
|
||||||
std::map<wxPGProperty*, int> pgPropOrders;
|
std::set<PROPERTY_BASE*> availableProps;
|
||||||
std::map<wxString, std::vector<wxPGProperty*>> pgPropGroups;
|
|
||||||
|
|
||||||
// Get all possible properties
|
// Get all possible properties
|
||||||
for( const TYPE_ID& type : types )
|
for( const TYPE_ID& type : types )
|
||||||
|
@ -215,40 +200,74 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EDA_ITEM* firstItem = aSelection.Front();
|
||||||
|
|
||||||
// Find a set of properties that is common to all selected items
|
// Find a set of properties that is common to all selected items
|
||||||
for( PROPERTY_BASE* property : commonProps )
|
for( PROPERTY_BASE* property : commonProps )
|
||||||
{
|
{
|
||||||
if( property->IsInternal() )
|
if( property->IsInternal() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( !propMgr.IsAvailableFor( TYPE_HASH( *aSelection.Front() ), property,
|
if( propMgr.IsAvailableFor( TYPE_HASH( *firstItem ), property, firstItem ) )
|
||||||
aSelection.Front() ) )
|
availableProps.insert( property );
|
||||||
continue;
|
}
|
||||||
|
|
||||||
// Either determine the common value for a property or "<...>" to indicate multiple values
|
bool writeable = true;
|
||||||
bool available;
|
std::set<PROPERTY_BASE*> existingProps;
|
||||||
bool writeable;
|
|
||||||
|
for( wxPropertyGridIterator it = m_grid->GetIterator(); !it.AtEnd(); it.Next() )
|
||||||
|
{
|
||||||
|
wxPGProperty* pgProp = it.GetProperty();
|
||||||
|
|
||||||
|
PROPERTY_BASE* property = propMgr.GetProperty( TYPE_HASH( *firstItem ), pgProp->GetName() );
|
||||||
|
wxCHECK2( property, continue );
|
||||||
wxVariant commonVal;
|
wxVariant commonVal;
|
||||||
|
|
||||||
available = extractValueAndWritability( aSelection, property, commonVal, writeable );
|
extractValueAndWritability( aSelection, property, commonVal, writeable );
|
||||||
|
pgProp->SetValue( commonVal );
|
||||||
|
pgProp->Enable( writeable );
|
||||||
|
|
||||||
if( available )
|
existingProps.insert( property );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( existingProps == availableProps )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Some difference exists: start from scratch
|
||||||
|
reset();
|
||||||
|
|
||||||
|
std::map<wxPGProperty*, int> pgPropOrders;
|
||||||
|
std::map<wxString, std::vector<wxPGProperty*>> pgPropGroups;
|
||||||
|
|
||||||
|
for( PROPERTY_BASE* property : availableProps )
|
||||||
|
{
|
||||||
|
wxPGProperty* pgProp = createPGProperty( property );
|
||||||
|
wxVariant commonVal;
|
||||||
|
|
||||||
|
if( !extractValueAndWritability( aSelection, property, commonVal, writeable ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( pgProp )
|
||||||
{
|
{
|
||||||
wxPGProperty* pgProp = createPGProperty( property );
|
pgProp->SetValue( commonVal );
|
||||||
|
pgProp->Enable( writeable );
|
||||||
|
m_displayed.push_back( property );
|
||||||
|
|
||||||
if( pgProp )
|
wxASSERT( displayOrder.count( property ) );
|
||||||
{
|
pgPropOrders[pgProp] = displayOrder[property];
|
||||||
pgProp->SetValue( commonVal );
|
pgPropGroups[property->Group()].emplace_back( pgProp );
|
||||||
pgProp->Enable( writeable );
|
|
||||||
m_displayed.push_back( property );
|
|
||||||
|
|
||||||
wxASSERT( displayOrder.count( property ) );
|
|
||||||
pgPropOrders[pgProp] = displayOrder[property];
|
|
||||||
pgPropGroups[property->Group()].emplace_back( pgProp );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( aSelection.Size() > 1 )
|
||||||
|
{
|
||||||
|
m_caption->SetLabel( wxString::Format( _( "%d objects selected" ), aSelection.Size() ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_caption->SetLabel( aSelection.Front()->GetFriendlyName() );
|
||||||
|
}
|
||||||
|
|
||||||
const wxString unspecifiedGroupCaption = _( "Basic Properties" );
|
const wxString unspecifiedGroupCaption = _( "Basic Properties" );
|
||||||
|
|
||||||
for( const wxString& groupName : groupDisplayOrder )
|
for( const wxString& groupName : groupDisplayOrder )
|
||||||
|
|
|
@ -75,24 +75,10 @@ protected:
|
||||||
/**
|
/**
|
||||||
* Generates the property grid for a given selection of items.
|
* Generates the property grid for a given selection of items.
|
||||||
*
|
*
|
||||||
* Calling this will remove any existing properties shown, causing visible flicker on some
|
|
||||||
* platforms and canceling any pending edits. Make sure to only call this when the group of
|
|
||||||
* selected items has actually changed.
|
|
||||||
*
|
|
||||||
* @param aSelection is a set of items to show properties for.
|
* @param aSelection is a set of items to show properties for.
|
||||||
*/
|
*/
|
||||||
virtual void rebuildProperties( const SELECTION& aSelection );
|
virtual void rebuildProperties( const SELECTION& aSelection );
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the values shown in the property grid for the current selection.
|
|
||||||
*
|
|
||||||
* Does not add or remove properties from the display (@see rebuildProperties)
|
|
||||||
* This implies that aSelection must have the same contents as m_cachedSelection.
|
|
||||||
*
|
|
||||||
* @param aSelection is the set of selected items.
|
|
||||||
*/
|
|
||||||
virtual void updatePropertyValues( const SELECTION& aSelection ) {}
|
|
||||||
|
|
||||||
virtual wxPGProperty* createPGProperty( const PROPERTY_BASE* aProperty ) const = 0;
|
virtual wxPGProperty* createPGProperty( const PROPERTY_BASE* aProperty ) const = 0;
|
||||||
|
|
||||||
// Event handlers
|
// Event handlers
|
||||||
|
@ -128,9 +114,6 @@ protected:
|
||||||
|
|
||||||
/// Proportion of the grid column splitter that is used for the key column (0.0 - 1.0)
|
/// Proportion of the grid column splitter that is used for the key column (0.0 - 1.0)
|
||||||
float m_splitter_key_proportion;
|
float m_splitter_key_proportion;
|
||||||
|
|
||||||
/// A copy of the most recent selection passed to rebuildProperties
|
|
||||||
std::unique_ptr<SELECTION> m_cachedSelection;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* PROPERTIES_PANEL_H */
|
#endif /* PROPERTIES_PANEL_H */
|
||||||
|
|
|
@ -100,7 +100,7 @@ void PCB_PROPERTIES_PANEL::AfterCommit()
|
||||||
PCB_SELECTION_TOOL* selectionTool = m_frame->GetToolManager()->GetTool<PCB_SELECTION_TOOL>();
|
PCB_SELECTION_TOOL* selectionTool = m_frame->GetToolManager()->GetTool<PCB_SELECTION_TOOL>();
|
||||||
const SELECTION& selection = selectionTool->GetSelection();
|
const SELECTION& selection = selectionTool->GetSelection();
|
||||||
|
|
||||||
updatePropertyValues( selection );
|
rebuildProperties( selection );
|
||||||
|
|
||||||
CallAfter( [&]()
|
CallAfter( [&]()
|
||||||
{
|
{
|
||||||
|
@ -109,30 +109,6 @@ void PCB_PROPERTIES_PANEL::AfterCommit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PCB_PROPERTIES_PANEL::updatePropertyValues( const SELECTION& aSelection )
|
|
||||||
{
|
|
||||||
BOARD_ITEM* firstItem = static_cast<BOARD_ITEM*>( aSelection.Front() );
|
|
||||||
|
|
||||||
for( wxPropertyGridIterator it = m_grid->GetIterator(); !it.AtEnd(); it.Next() )
|
|
||||||
{
|
|
||||||
wxPGProperty* pgProp = it.GetProperty();
|
|
||||||
|
|
||||||
PROPERTY_BASE* property = m_propMgr.GetProperty( TYPE_HASH( *firstItem ),
|
|
||||||
pgProp->GetName() );
|
|
||||||
wxCHECK2( property, continue );
|
|
||||||
|
|
||||||
bool writeable = true;
|
|
||||||
wxVariant commonVal;
|
|
||||||
|
|
||||||
// Availablility of the property should not be changing here
|
|
||||||
wxASSERT( extractValueAndWritability( aSelection, property, commonVal, writeable ) );
|
|
||||||
|
|
||||||
pgProp->SetValue( commonVal );
|
|
||||||
pgProp->Enable( writeable );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxPGProperty* PCB_PROPERTIES_PANEL::createPGProperty( const PROPERTY_BASE* aProperty ) const
|
wxPGProperty* PCB_PROPERTIES_PANEL::createPGProperty( const PROPERTY_BASE* aProperty ) const
|
||||||
{
|
{
|
||||||
if( aProperty->TypeHash() == TYPE_HASH( PCB_LAYER_ID ) )
|
if( aProperty->TypeHash() == TYPE_HASH( PCB_LAYER_ID ) )
|
||||||
|
|
|
@ -52,8 +52,6 @@ protected:
|
||||||
///> Regenerates caches storing layer and net names
|
///> Regenerates caches storing layer and net names
|
||||||
void updateLists( const BOARD* aBoard );
|
void updateLists( const BOARD* aBoard );
|
||||||
|
|
||||||
void updatePropertyValues( const SELECTION& aSelection ) override;
|
|
||||||
|
|
||||||
PCB_EDIT_FRAME* m_frame;
|
PCB_EDIT_FRAME* m_frame;
|
||||||
PROPERTY_MANAGER& m_propMgr;
|
PROPERTY_MANAGER& m_propMgr;
|
||||||
PG_UNIT_EDITOR* m_unitEditorInstance;
|
PG_UNIT_EDITOR* m_unitEditorInstance;
|
||||||
|
|
Loading…
Reference in New Issue