ADDED: Properties panel for schematic editor

Initial infrastructure work; follow-ons will add more
properties for schematic items.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/6351
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14105
This commit is contained in:
Jon Evans 2023-06-20 21:57:20 -04:00
parent 39073642a7
commit 3a0f8214fa
49 changed files with 897 additions and 64 deletions

View File

@ -434,6 +434,7 @@ set( COMMON_SRCS
tool/grid_helper.cpp
tool/grid_menu.cpp
tool/picker_tool.cpp
tool/properties_tool.cpp
tool/selection.cpp
tool/selection_tool.cpp
tool/selection_conditions.cpp
@ -466,6 +467,7 @@ set( COMMON_SRCS
project/project_file.cpp
project/project_local_settings.cpp
properties/color4d_variant.cpp
properties/eda_angle_variant.cpp
properties/pg_cell_renderer.cpp
properties/pg_editors.cpp

View File

@ -58,6 +58,7 @@
#include <view/view.h>
#include <drawing_sheet/ds_draw_item.h>
#include <widgets/msgpanel.h>
#include <widgets/properties_panel.h>
#include <wx/event.h>
#include <wx/snglinst.h>
#include <dialogs/dialog_grid_settings.h>
@ -115,6 +116,7 @@ EDA_DRAW_FRAME::EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame
m_polarCoords = false;
m_findReplaceData = std::make_unique<EDA_SEARCH_DATA>();
m_hotkeyPopup = nullptr;
m_propertiesPanel = nullptr;
SetUserUnits( EDA_UNITS::MILLIMETRES );
@ -278,6 +280,7 @@ void EDA_DRAW_FRAME::unitsChangeRefresh()
UpdateStatusBar();
UpdateMsgPanel();
UpdateProperties();
}
@ -1133,6 +1136,18 @@ void EDA_DRAW_FRAME::ShowChangedLanguage()
{
m_searchPane->OnLanguageChange();
}
if( m_propertiesPanel )
m_propertiesPanel->OnLanguageChanged();
}
void EDA_DRAW_FRAME::UpdateProperties()
{
if( !m_propertiesPanel || !m_propertiesPanel->IsShownOnScreen() )
return;
m_propertiesPanel->UpdateData();
}

View File

@ -0,0 +1,78 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <properties/color4d_variant.h>
COLOR4D_VARIANT_DATA::COLOR4D_VARIANT_DATA() :
wxVariantData()
{}
COLOR4D_VARIANT_DATA::COLOR4D_VARIANT_DATA( const wxString& aColorStr ) :
wxVariantData(),
m_color( aColorStr )
{}
COLOR4D_VARIANT_DATA::COLOR4D_VARIANT_DATA( const KIGFX::COLOR4D& aColor ) :
wxVariantData(),
m_color( aColor )
{}
bool COLOR4D_VARIANT_DATA::Eq( wxVariantData& aOther ) const
{
try
{
COLOR4D_VARIANT_DATA& evd = dynamic_cast<COLOR4D_VARIANT_DATA&>( aOther );
return evd.m_color == m_color;
}
catch( std::bad_cast& )
{
return false;
}
}
bool COLOR4D_VARIANT_DATA::Read( wxString& aString )
{
m_color = KIGFX::COLOR4D( aString );
return true;
}
bool COLOR4D_VARIANT_DATA::Write( wxString& aString ) const
{
aString = m_color.ToCSSString();
return true;
}
bool COLOR4D_VARIANT_DATA::GetAsAny( wxAny* aAny ) const
{
*aAny = m_color;
return true;
}
wxVariantData* COLOR4D_VARIANT_DATA::VariantDataFactory( const wxAny& aAny )
{
return new COLOR4D_VARIANT_DATA( aAny.As<KIGFX::COLOR4D>() );
}

View File

@ -26,6 +26,7 @@
#include <validators.h>
#include <eda_draw_frame.h>
#include <eda_units.h>
#include <properties/color4d_variant.h>
#include <properties/eda_angle_variant.h>
#include <properties/pg_properties.h>
#include <properties/pg_editors.h>
@ -77,6 +78,43 @@ wxAnyValueTypeScopedPtr wxAnyToEDA_ANGLE_VARIANTRegistrationImpl::s_instance( ne
static wxAnyToEDA_ANGLE_VARIANTRegistrationImpl s_wxAnyToEDA_ANGLE_VARIANTRegistration( &EDA_ANGLE_VARIANT_DATA::VariantDataFactory );
class wxAnyToCOLOR4D_VARIANTRegistrationImpl : public wxAnyToVariantRegistration
{
public:
wxAnyToCOLOR4D_VARIANTRegistrationImpl( wxVariantDataFactory factory )
: wxAnyToVariantRegistration( factory )
{
}
public:
static bool IsSameClass(const wxAnyValueType* otherType)
{
return AreSameClasses( *s_instance.get(), *otherType );
}
static wxAnyValueType* GetInstance()
{
return s_instance.get();
}
virtual wxAnyValueType* GetAssociatedType() override
{
return wxAnyToCOLOR4D_VARIANTRegistrationImpl::GetInstance();
}
private:
static bool AreSameClasses(const wxAnyValueType& a, const wxAnyValueType& b)
{
return wxTypeId(a) == wxTypeId(b);
}
static wxAnyValueTypeScopedPtr s_instance;
};
wxAnyValueTypeScopedPtr wxAnyToCOLOR4D_VARIANTRegistrationImpl::s_instance( new wxAnyValueTypeImpl<KIGFX::COLOR4D>() );
static wxAnyToCOLOR4D_VARIANTRegistrationImpl s_wxAnyToCOLOR4D_VARIANTRegistration( &COLOR4D_VARIANT_DATA::VariantDataFactory );
wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty, EDA_DRAW_FRAME* aFrame )
{
wxPGProperty* ret = nullptr;
@ -144,6 +182,10 @@ wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty, EDA_DRAW_FRAME*
{
ret = new PGPROPERTY_STRING();
}
else if( typeId == TYPE_HASH( COLOR4D ) )
{
ret = new PGPROPERTY_COLOR4D();
}
else
{
wxFAIL_MSG( wxString::Format( wxS( "Property %s not supported by PGPropertyFactory" ),
@ -195,6 +237,7 @@ wxString PGPROPERTY_DISTANCE::DistanceToString( wxVariant& aVariant, int aArgFla
long distanceIU = aVariant.GetLong();
ORIGIN_TRANSFORMS* transforms = PROPERTY_MANAGER::Instance().GetTransforms();
const EDA_IU_SCALE* iuScale = PROPERTY_MANAGER::Instance().GetIuScale();
if( transforms )
distanceIU = transforms->ToDisplay( static_cast<long long int>( distanceIU ), m_coordType );
@ -202,13 +245,13 @@ wxString PGPROPERTY_DISTANCE::DistanceToString( wxVariant& aVariant, int aArgFla
switch( PROPERTY_MANAGER::Instance().GetUnits() )
{
case EDA_UNITS::INCHES:
return wxString::Format( wxS( "%g in" ), pcbIUScale.IUToMils( distanceIU ) / 1000.0 );
return wxString::Format( wxS( "%g in" ), iuScale->IUToMils( distanceIU ) / 1000.0 );
case EDA_UNITS::MILS:
return wxString::Format( wxS( "%d mils" ), pcbIUScale.IUToMils( distanceIU ) );
return wxString::Format( wxS( "%d mils" ), iuScale->IUToMils( distanceIU ) );
case EDA_UNITS::MILLIMETRES:
return wxString::Format( wxS( "%g mm" ), pcbIUScale.IUTomm( distanceIU ) );
return wxString::Format( wxS( "%g mm" ), iuScale->IUTomm( distanceIU ) );
case EDA_UNITS::UNSCALED:
return wxString::Format( wxS( "%li" ), distanceIU );
@ -360,3 +403,31 @@ const wxPGEditor* PGPROPERTY_BOOL::DoGetEditorClass() const
wxT( "Make sure to set custom editor for PGPROPERTY_BOOL!" ) );
return m_customEditor;
}
PGPROPERTY_COLOR4D::PGPROPERTY_COLOR4D( const wxString& aLabel, const wxString& aName,
COLOR4D aValue ) :
wxColourProperty( aLabel, aName, aValue.ToColour() )
{
}
bool PGPROPERTY_COLOR4D::StringToValue( wxVariant& aVariant, const wxString& aString,
int aFlags ) const
{
aVariant.SetData( new COLOR4D_VARIANT_DATA( aString ) );
return true;
}
wxString PGPROPERTY_COLOR4D::ValueToString( wxVariant& aValue, int aFlags ) const
{
wxString ret;
if( aValue.IsType( wxS( "COLOR4D" ) ) )
static_cast<COLOR4D_VARIANT_DATA*>( aValue.GetData() )->Write( ret );
else
return wxColourProperty::ValueToString( aValue, aFlags );
return ret;
}

View File

@ -265,9 +265,10 @@ PROPERTY_MANAGER::CLASS_DESC& PROPERTY_MANAGER::getClass( TYPE_ID aTypeId )
void PROPERTY_MANAGER::CLASS_DESC::rebuild()
{
PROPERTY_SET replaced( m_replaced );
PROPERTY_SET replaced;
PROPERTY_SET masked;
m_allProperties.clear();
collectPropsRecur( m_allProperties, replaced, m_displayOrder, m_maskedBaseProperties );
collectPropsRecur( m_allProperties, replaced, m_displayOrder, masked );
// We need to keep properties sorted to be able to use std::set_* functions
sort( m_allProperties.begin(), m_allProperties.end() );
@ -307,11 +308,14 @@ void PROPERTY_MANAGER::CLASS_DESC::rebuild()
void PROPERTY_MANAGER::CLASS_DESC::collectPropsRecur( PROPERTY_LIST& aResult,
PROPERTY_SET& aReplaced,
PROPERTY_DISPLAY_ORDER& aDisplayOrder,
const PROPERTY_SET& aMasked ) const
PROPERTY_SET& aMasked ) const
{
for( const std::pair<size_t, wxString>& replacedEntry : m_replaced )
aReplaced.emplace( replacedEntry );
for( const std::pair<size_t, wxString>& maskedEntry : m_maskedBaseProperties )
aMasked.emplace( maskedEntry );
/*
* We want to insert our own properties in forward order, but earlier than anything already in
* the list (which will have been added by a subclass of us)

View File

@ -704,6 +704,11 @@ TOOL_ACTION ACTIONS::showFootprintEditor( TOOL_ACTION_ARGS()
.Flags( AF_NONE )
.Parameter( FRAME_FOOTPRINT_EDITOR ) );
TOOL_ACTION ACTIONS::showProperties( "common.Control.showProperties",
AS_GLOBAL, 0, "",
_( "Show Properties Manager" ), _( "Show/hide the properties manager" ),
BITMAPS::tools );
TOOL_ACTION ACTIONS::updatePcbFromSchematic( "common.Control.updatePcbFromSchematic",
AS_GLOBAL,
WXK_F8, LEGACY_HK_NAME( "Update PCB from Schematic" ),

View File

@ -18,14 +18,15 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "properties_tool.h"
#include <widgets/pcb_properties_panel.h>
#include <eda_draw_frame.h>
#include <tool/actions.h>
#include <tool/properties_tool.h>
#include <widgets/properties_panel.h>
int PROPERTIES_TOOL::UpdateProperties( const TOOL_EVENT& aEvent )
{
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
EDA_DRAW_FRAME* editFrame = getEditFrame<EDA_DRAW_FRAME>();
if( editFrame )
editFrame->UpdateProperties();

View File

@ -169,6 +169,7 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
propMgr.SetUnits( m_frame->GetUserUnits() );
propMgr.SetIuScale( &m_frame->GetIuScale() );
propMgr.SetTransforms( &m_frame->GetOriginTransforms() );
std::set<PROPERTY_BASE*> commonProps;
@ -249,7 +250,7 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
existingProps.insert( property );
}
if( existingProps == availableProps )
if( !existingProps.empty() && existingProps == availableProps )
return;
// Some difference exists: start from scratch

View File

@ -246,6 +246,7 @@ set( EESCHEMA_WIDGETS
widgets/pin_shape_combobox.cpp
widgets/pin_type_combobox.cpp
widgets/symbol_diff_widget.cpp
widgets/sch_properties_panel.cpp
widgets/sch_search_pane.cpp
widgets/search_handlers.cpp
widgets/symbol_preview_widget.cpp

View File

@ -226,6 +226,15 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() :
m_params.emplace_back( new PARAM<wxSize>( "aui.net_nav_panel_float_size",
&m_AuiPanels.net_nav_panel_float_size, wxSize( 200, 200 ) ) );
m_params.emplace_back( new PARAM<bool>( "aui.show_properties",
&m_AuiPanels.show_properties, true ) );
m_params.emplace_back( new PARAM<int>( "aui.properties_panel_width",
&m_AuiPanels.properties_panel_width, -1 ) );
m_params.emplace_back( new PARAM<float>( "aui.properties_splitter_proportion",
&m_AuiPanels.properties_splitter_proportion, 0.5f ) );
m_params.emplace_back( new PARAM<bool>( "autoplace_fields.enable",
&m_AutoplaceFields.enable, true ) );

View File

@ -94,6 +94,9 @@ public:
wxSize net_nav_panel_float_size;
bool float_net_nav_panel;
bool show_net_nav_panel;
int properties_panel_width;
float properties_splitter_proportion;
bool show_properties;
};
struct AUTOPLACE_FIELDS

View File

@ -176,6 +176,7 @@ void SCH_EDIT_FRAME::doReCreateMenuBar()
viewMenu->Add( ACTIONS::showSymbolBrowser );
viewMenu->Add( ACTIONS::showSearch, ACTION_MENU::CHECK );
viewMenu->Add( EE_ACTIONS::showHierarchy, ACTION_MENU::CHECK );
viewMenu->Add( ACTIONS::showProperties, ACTION_MENU::CHECK );
viewMenu->Add( EE_ACTIONS::navigateBack );
viewMenu->Add( EE_ACTIONS::navigateUp );
viewMenu->Add( EE_ACTIONS::navigateForward );

View File

@ -231,3 +231,14 @@ void SCH_BITMAP::ViewGetLayers( int aLayers[], int& aCount ) const
aLayers[0] = LAYER_DRAW_BITMAPS;
aLayers[1] = LAYER_SELECTION_SHADOWS;
}
static struct SCH_BITMAP_DESC
{
SCH_BITMAP_DESC()
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( SCH_BITMAP );
propMgr.InheritsAfter( TYPE_HASH( SCH_BITMAP ), TYPE_HASH( SCH_ITEM ) );
}
} _SCH_BITMAP_DESC;

View File

@ -568,3 +568,18 @@ bool SCH_BUS_WIRE_ENTRY::ConnectionPropagatesTo( const EDA_ITEM* aItem ) const
return true;
}
static struct SCH_BUS_ENTRY_DESC
{
SCH_BUS_ENTRY_DESC()
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( SCH_BUS_WIRE_ENTRY );
REGISTER_TYPE( SCH_BUS_BUS_ENTRY );
REGISTER_TYPE( SCH_BUS_ENTRY_BASE );
propMgr.InheritsAfter( TYPE_HASH( SCH_BUS_ENTRY_BASE ), TYPE_HASH( SCH_ITEM ) );
propMgr.InheritsAfter( TYPE_HASH( SCH_BUS_WIRE_ENTRY ), TYPE_HASH( SCH_BUS_ENTRY_BASE ) );
propMgr.InheritsAfter( TYPE_HASH( SCH_BUS_BUS_ENTRY ), TYPE_HASH( SCH_BUS_ENTRY_BASE ) );
}
} _SCH_BUS_ENTRY_DESC;

View File

@ -62,6 +62,7 @@
#include <tool/common_control.h>
#include <tool/common_tools.h>
#include <tool/picker_tool.h>
#include <tool/properties_tool.h>
#include <tool/selection.h>
#include <tool/tool_dispatcher.h>
#include <tool/tool_manager.h>
@ -81,6 +82,7 @@
#include <view/view_controls.h>
#include <widgets/wx_infobar.h>
#include <widgets/hierarchy_pane.h>
#include <widgets/sch_properties_panel.h>
#include <widgets/sch_search_pane.h>
#include <wildcards_and_files_ext.h>
#include <wx/cmdline.h>
@ -177,6 +179,9 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
m_pageSetupData.GetPrintData().SetNoCopies( 1 );
m_searchPane = new SCH_SEARCH_PANE( this );
m_propertiesPanel = new SCH_PROPERTIES_PANEL( this, this );
m_propertiesPanel->SetSplitterProportion( eeconfig()->m_AuiPanels.properties_splitter_proportion );
m_auimgr.SetManagedWindow( this );
@ -202,6 +207,10 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
.FloatingPosition( 50, 50 )
.Show( false ) );
m_auimgr.AddPane( m_propertiesPanel, EDA_PANE().Name( PropertiesPaneName() )
.Left().Layer( 3 ).Caption( _( "Properties" ) )
.PaneBorder( false ).MinSize( 240, -1 ).BestSize( 300, -1 ) );
m_auimgr.AddPane( createHighlightedNetNavigator(), defaultNetNavigatorPaneInfo() );
m_auimgr.AddPane( m_optionsToolBar, EDA_PANE().VToolbar().Name( wxS( "OptToolbar" ) )
@ -239,10 +248,12 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
wxAuiPaneInfo& hierarchy_pane = m_auimgr.GetPane( SchematicHierarchyPaneName() );
wxAuiPaneInfo& netNavigatorPane = m_auimgr.GetPane( NetNavigatorPaneName() );
wxAuiPaneInfo& propertiesPane = m_auimgr.GetPane( PropertiesPaneName() );
EESCHEMA_SETTINGS* cfg = eeconfig();
hierarchy_pane.Show( cfg->m_AuiPanels.show_schematic_hierarchy );
netNavigatorPane.Show( cfg->m_AuiPanels.show_net_nav_panel );
propertiesPane.Show( cfg->m_AuiPanels.show_properties );
if( cfg->m_AuiPanels.hierarchy_panel_float_width > 0
&& cfg->m_AuiPanels.hierarchy_panel_float_height > 0 )
@ -258,6 +269,9 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
netNavigatorPane.FloatingSize( cfg->m_AuiPanels.net_nav_panel_float_size );
}
if( cfg->m_AuiPanels.properties_panel_width > 0 )
SetAuiPaneSize( m_auimgr, propertiesPane, cfg->m_AuiPanels.properties_panel_width, -1 );
if( cfg->m_AuiPanels.schematic_hierarchy_float )
hierarchy_pane.Float();
@ -463,6 +477,7 @@ void SCH_EDIT_FRAME::setupTools()
m_toolManager->RegisterTool( new SCH_FIND_REPLACE_TOOL );
m_toolManager->RegisterTool( new EE_POINT_EDITOR );
m_toolManager->RegisterTool( new SCH_NAVIGATE_TOOL );
m_toolManager->RegisterTool( new PROPERTIES_TOOL );
m_toolManager->InitTools();
// Run the selection tool, it is supposed to be always active
@ -494,6 +509,12 @@ void SCH_EDIT_FRAME::setupUIConditions()
return m_auimgr.GetPane( SearchPaneName() ).IsShown();
};
auto propertiesCond =
[this] ( const SELECTION& )
{
return m_auimgr.GetPane( PropertiesPaneName() ).IsShown();
};
auto hierarchyNavigatorCond =
[ this ] ( const SELECTION& aSel )
{
@ -525,6 +546,7 @@ void SCH_EDIT_FRAME::setupUIConditions()
mgr->SetConditions( EE_ACTIONS::showSearch, CHECK( searchPaneCond ) );
mgr->SetConditions( EE_ACTIONS::showHierarchy, CHECK( hierarchyNavigatorCond ) );
mgr->SetConditions( EE_ACTIONS::showNetNavigator, CHECK( netNavigatorCond ) );
mgr->SetConditions( ACTIONS::showProperties, CHECK( propertiesCond ) );
mgr->SetConditions( ACTIONS::toggleGrid, CHECK( cond.GridVisible() ) );
mgr->SetConditions( ACTIONS::toggleCursorStyle, CHECK( cond.FullscreenCursor() ) );
mgr->SetConditions( ACTIONS::millimetersUnits,
@ -2314,4 +2336,6 @@ void SCH_EDIT_FRAME::unitsChangeRefresh()
m_netNavigator->DeleteAllItems();
RefreshNetNavigator( refreshSelection ? &itemData : nullptr );
}
UpdateProperties();
}

View File

@ -828,6 +828,8 @@ public:
*/
void ToggleSearch();
void ToggleProperties() override;
DIALOG_BOOK_REPORTER* GetSymbolDiffDialog();
DIALOG_ERC* GetErcDialog();

View File

@ -1136,3 +1136,30 @@ bool SCH_FIELD::operator <( const SCH_ITEM& aItem ) const
return GetName() < field->GetName();
}
static struct SCH_FIELD_DESC
{
SCH_FIELD_DESC()
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( SCH_FIELD );
propMgr.AddTypeCast( new TYPE_CAST<SCH_FIELD, SCH_ITEM> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_FIELD, EDA_TEXT> );
propMgr.InheritsAfter( TYPE_HASH( SCH_FIELD ), TYPE_HASH( SCH_ITEM ) );
propMgr.InheritsAfter( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ) );
propMgr.AddProperty( new PROPERTY<SCH_FIELD, bool>( _HKI( "Show Field Name" ),
&SCH_FIELD::SetNameShown, &SCH_FIELD::IsNameShown ) );
propMgr.AddProperty( new PROPERTY<SCH_FIELD, bool>( _HKI( "Allow Autoplacement" ),
&SCH_FIELD::SetCanAutoplace, &SCH_FIELD::CanAutoplace ) );
propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Thickness" ) );
propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Mirrored" ) );
propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Visible" ) );
propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Width" ) );
propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Height" ) );
}
} _SCH_FIELD_DESC;

View File

@ -318,3 +318,37 @@ void SCH_ITEM::Plot( PLOTTER* aPlotter, bool aBackground ) const
{
wxFAIL_MSG( wxT( "Plot() method not implemented for class " ) + GetClass() );
}
static struct SCH_ITEM_DESC
{
SCH_ITEM_DESC()
{
#ifdef NOTYET
ENUM_MAP<SCH_LAYER_ID>& layerEnum = ENUM_MAP<SCH_LAYER_ID>::Instance();
if( layerEnum.Choices().GetCount() == 0 )
{
layerEnum.Undefined( SCH_LAYER_ID_END );
for( SCH_LAYER_ID value : magic_enum::enum_values<SCH_LAYER_ID>() )
layerEnum.Map( value, LayerName( value ) );
}
#endif
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( SCH_ITEM );
propMgr.InheritsAfter( TYPE_HASH( SCH_ITEM ), TYPE_HASH( EDA_ITEM ) );
// Not sure if this will ever be needed
// propMgr.AddProperty( new PROPERTY_ENUM<SCH_ITEM, SCH_LAYER_ID>( _HKI( "Layer" ),
// &SCH_ITEM::SetLayer, &SCH_ITEM::GetLayer ) )
// .SetIsHiddenFromPropertiesManager();
// Not yet functional in UI
// propMgr.AddProperty( new PROPERTY<SCH_ITEM, bool>( _HKI( "Locked" ),
// &SCH_ITEM::SetLocked, &SCH_ITEM::IsLocked ) );
}
} _SCH_ITEM_DESC;
IMPLEMENT_ENUM_TO_WXANY( SCH_LAYER_ID )

View File

@ -509,4 +509,8 @@ protected:
bool m_connectivity_dirty;
};
#ifndef SWIG
DECLARE_ENUM_TO_WXANY( SCH_LAYER_ID );
#endif
#endif /* SCH_ITEM_H */

View File

@ -304,3 +304,13 @@ void SCH_JUNCTION::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANE
}
}
static struct SCH_JUNCTION_DESC
{
SCH_JUNCTION_DESC()
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( SCH_JUNCTION );
propMgr.InheritsAfter( TYPE_HASH( SCH_JUNCTION ), TYPE_HASH( SCH_ITEM ) );
}
} _SCH_JUNCTION_DESC;

View File

@ -1820,3 +1820,38 @@ HTML_MESSAGE_BOX* SCH_TEXT::ShowSyntaxHelp( wxWindow* aParentWindow )
return dlg;
}
static struct SCH_LABEL_DESC
{
SCH_LABEL_DESC()
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( SCH_LABEL_BASE );
REGISTER_TYPE( SCH_LABEL );
REGISTER_TYPE( SCH_HIERLABEL );
REGISTER_TYPE( SCH_GLOBALLABEL );
REGISTER_TYPE( SCH_DIRECTIVE_LABEL );
propMgr.AddTypeCast( new TYPE_CAST<SCH_LABEL, SCH_LABEL_BASE> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_HIERLABEL, SCH_LABEL_BASE> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_GLOBALLABEL, SCH_LABEL_BASE> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_DIRECTIVE_LABEL, SCH_LABEL_BASE> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_LABEL, SCH_TEXT> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_HIERLABEL, SCH_TEXT> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_GLOBALLABEL, SCH_TEXT> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_DIRECTIVE_LABEL, SCH_TEXT> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_LABEL, EDA_TEXT> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_HIERLABEL, EDA_TEXT> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_GLOBALLABEL, EDA_TEXT> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_DIRECTIVE_LABEL, EDA_TEXT> );
propMgr.InheritsAfter( TYPE_HASH( SCH_LABEL_BASE ), TYPE_HASH( SCH_TEXT ) );
propMgr.InheritsAfter( TYPE_HASH( SCH_LABEL ), TYPE_HASH( SCH_LABEL_BASE ) );
propMgr.InheritsAfter( TYPE_HASH( SCH_HIERLABEL ), TYPE_HASH( SCH_LABEL_BASE ) );
propMgr.InheritsAfter( TYPE_HASH( SCH_GLOBALLABEL ), TYPE_HASH( SCH_LABEL_BASE ) );
propMgr.InheritsAfter( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( SCH_LABEL_BASE ) );
}
} _SCH_LABEL_DESC;

View File

@ -976,3 +976,13 @@ bool SCH_LINE::IsBus() const
return ( GetLayer() == LAYER_BUS );
}
static struct SCH_LINE_DESC
{
SCH_LINE_DESC()
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( SCH_LINE );
propMgr.InheritsAfter( TYPE_HASH( SCH_LINE ), TYPE_HASH( SCH_ITEM ) );
}
} _SCH_LINE_DESC;

View File

@ -415,3 +415,14 @@ bool SCH_PIN::ConnectionPropagatesTo( const EDA_ITEM* aItem ) const
// Reciprocal checking is done in CONNECTION_GRAPH anyway
return !( m_libPin->GetType() == ELECTRICAL_PINTYPE::PT_NC );
}
static struct SCH_PIN_DESC
{
SCH_PIN_DESC()
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( SCH_PIN );
propMgr.InheritsAfter( TYPE_HASH( SCH_PIN ), TYPE_HASH( SCH_ITEM ) );
}
} _SCH_PIN_DESC;

View File

@ -517,3 +517,31 @@ void SCH_SHAPE::AddPoint( const VECTOR2I& aPosition )
}
static struct SCH_SHAPE_DESC
{
SCH_SHAPE_DESC()
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( SCH_SHAPE );
propMgr.AddTypeCast( new TYPE_CAST<SCH_SHAPE, SCH_ITEM> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_SHAPE, EDA_SHAPE> );
propMgr.InheritsAfter( TYPE_HASH( SCH_SHAPE ), TYPE_HASH( SCH_ITEM ) );
propMgr.InheritsAfter( TYPE_HASH( SCH_SHAPE ), TYPE_HASH( EDA_SHAPE ) );
// Only polygons have meaningful Position properties.
// On other shapes, these are duplicates of the Start properties.
auto isPolygon =
[]( INSPECTABLE* aItem ) -> bool
{
if( SCH_SHAPE* shape = dynamic_cast<SCH_SHAPE*>( aItem ) )
return shape->GetShape() == SHAPE_T::POLY;
return false;
};
propMgr.OverrideAvailability( TYPE_HASH( SCH_SHAPE ), TYPE_HASH( SCH_ITEM ),
_HKI( "Position X" ), isPolygon );
propMgr.OverrideAvailability( TYPE_HASH( SCH_SHAPE ), TYPE_HASH( SCH_ITEM ),
_HKI( "Position Y" ), isPolygon );
}
} _SCH_SHAPE_DESC;

View File

@ -1392,3 +1392,26 @@ void SCH_SHEET::Show( int nestLevel, std::ostream& os ) const
}
#endif
static struct SCH_SHEET_DESC
{
SCH_SHEET_DESC()
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( SCH_SHEET );
propMgr.InheritsAfter( TYPE_HASH( SCH_SHEET ), TYPE_HASH( SCH_ITEM ) );
propMgr.AddProperty( new PROPERTY<SCH_SHEET, wxString>( _HKI( "Sheet Name" ),
&SCH_SHEET::SetName, &SCH_SHEET::GetName ) );
propMgr.AddProperty( new PROPERTY<SCH_SHEET, int>( _HKI( "Border Width" ),
&SCH_SHEET::SetBorderWidth, &SCH_SHEET::GetBorderWidth,
PROPERTY_DISPLAY::PT_SIZE ) );
propMgr.AddProperty( new PROPERTY<SCH_SHEET, COLOR4D>( _HKI( "Border Color" ),
&SCH_SHEET::SetBorderColor, &SCH_SHEET::GetBorderColor ) );
propMgr.AddProperty( new PROPERTY<SCH_SHEET, COLOR4D>( _HKI( "Background Color" ),
&SCH_SHEET::SetBackgroundColor, &SCH_SHEET::GetBackgroundColor ) );
}
} _SCH_SHEET_DESC;

View File

@ -2414,3 +2414,14 @@ bool SCH_SYMBOL::IsPower() const
return m_part->IsPower();
}
static struct SCH_SYMBOL_DESC
{
SCH_SYMBOL_DESC()
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( SCH_SYMBOL );
propMgr.InheritsAfter( TYPE_HASH( SCH_SYMBOL ), TYPE_HASH( SCH_ITEM ) );
}
} _SCH_SYMBOL_DESC;

View File

@ -542,3 +542,20 @@ void SCH_TEXT::Show( int nestLevel, std::ostream& os ) const
#endif
static struct SCH_TEXT_DESC
{
SCH_TEXT_DESC()
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( SCH_TEXT );
propMgr.AddTypeCast( new TYPE_CAST<SCH_TEXT, SCH_ITEM> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_TEXT, EDA_TEXT> );
propMgr.InheritsAfter( TYPE_HASH( SCH_TEXT ), TYPE_HASH( SCH_ITEM ) );
propMgr.InheritsAfter( TYPE_HASH( SCH_TEXT ), TYPE_HASH( EDA_TEXT ) );
propMgr.Mask( TYPE_HASH( SCH_TEXT ), TYPE_HASH( EDA_TEXT ), _HKI( "Mirrored" ) );
propMgr.Mask( TYPE_HASH( SCH_TEXT ), TYPE_HASH( EDA_TEXT ), _HKI( "Visible" ) );
propMgr.Mask( TYPE_HASH( SCH_TEXT ), TYPE_HASH( EDA_TEXT ), _HKI( "Width" ) );
propMgr.Mask( TYPE_HASH( SCH_TEXT ), TYPE_HASH( EDA_TEXT ), _HKI( "Height" ) );
}
} _SCH_TEXT_DESC;

View File

@ -463,3 +463,25 @@ void SCH_TEXTBOX::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL
m_stroke.GetMsgPanelInfo( aFrame, aList );
}
static struct SCH_TEXTBOX_DESC
{
SCH_TEXTBOX_DESC()
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( SCH_TEXTBOX );
propMgr.AddTypeCast( new TYPE_CAST<SCH_TEXTBOX, SCH_SHAPE> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_TEXTBOX, EDA_TEXT> );
propMgr.InheritsAfter( TYPE_HASH( SCH_TEXTBOX ), TYPE_HASH( SCH_SHAPE ) );
propMgr.InheritsAfter( TYPE_HASH( SCH_TEXTBOX ), TYPE_HASH( EDA_TEXT ) );
propMgr.Mask( TYPE_HASH( SCH_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Shape" ) );
propMgr.Mask( TYPE_HASH( SCH_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start X" ) );
propMgr.Mask( TYPE_HASH( SCH_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start Y" ) );
propMgr.Mask( TYPE_HASH( SCH_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "End X" ) );
propMgr.Mask( TYPE_HASH( SCH_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "End Y" ) );
propMgr.Mask( TYPE_HASH( SCH_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Width" ) );
}
} _SCH_TEXTBOX_DESC;

View File

@ -37,6 +37,7 @@
#include <tools/ee_selection_tool.h>
#include <widgets/hierarchy_pane.h>
#include <widgets/wx_aui_utils.h>
#include <widgets/sch_properties_panel.h>
#include <widgets/sch_search_pane.h>
/* Create the main Horizontal Toolbar for the schematic editor
@ -213,6 +214,7 @@ void SCH_EDIT_FRAME::ReCreateOptToolbar()
m_optionsToolBar->AddScaledSeparator( this );
m_optionsToolBar->Add( EE_ACTIONS::showHierarchy, ACTION_TOOLBAR::TOGGLE );
m_optionsToolBar->Add( ACTIONS::showProperties, ACTION_TOOLBAR::TOGGLE );
if( ADVANCED_CFG::GetCfg().m_DrawBoundingBoxes )
m_optionsToolBar->Add( ACTIONS::toggleBoundingBoxes, ACTION_TOOLBAR::TOGGLE );
@ -265,6 +267,31 @@ void SCH_EDIT_FRAME::ToggleSearch()
}
void SCH_EDIT_FRAME::ToggleProperties()
{
if( !m_propertiesPanel )
return;
bool show = !m_propertiesPanel->IsShownOnScreen();
wxAuiPaneInfo& propertiesPaneInfo = m_auimgr.GetPane( PropertiesPaneName() );
propertiesPaneInfo.Show( show );
EESCHEMA_SETTINGS* settings = eeconfig();
if( show )
{
SetAuiPaneSize( m_auimgr, propertiesPaneInfo,
settings->m_AuiPanels.properties_panel_width, -1 );
}
else
{
settings->m_AuiPanels.properties_panel_width = m_propertiesPanel->GetSize().x;
m_auimgr.Update();
}
}
void SCH_EDIT_FRAME::ToggleSchematicHierarchy()
{
EESCHEMA_SETTINGS* cfg = eeconfig();

View File

@ -2125,6 +2125,13 @@ int SCH_EDITOR_CONTROL::ShowNetNavigator( const TOOL_EVENT& aEvent )
}
int SCH_EDITOR_CONTROL::ToggleProperties( const TOOL_EVENT& aEvent )
{
getEditFrame<SCH_EDIT_FRAME>()->ToggleProperties();
return 0;
}
int SCH_EDITOR_CONTROL::ToggleHiddenPins( const TOOL_EVENT& aEvent )
{
EESCHEMA_SETTINGS* cfg = m_frame->eeconfig();
@ -2438,6 +2445,7 @@ void SCH_EDITOR_CONTROL::setTransitions()
Go( &SCH_EDITOR_CONTROL::ShowSearch, EE_ACTIONS::showSearch.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::ShowHierarchy, EE_ACTIONS::showHierarchy.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::ShowNetNavigator, EE_ACTIONS::showNetNavigator.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::ToggleProperties, ACTIONS::showProperties.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::ToggleHiddenPins, EE_ACTIONS::toggleHiddenPins.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::ToggleHiddenFields, EE_ACTIONS::toggleHiddenFields.MakeEvent() );

View File

@ -126,6 +126,7 @@ public:
int ShowSearch( const TOOL_EVENT& aEvent );
int ShowHierarchy( const TOOL_EVENT& aEvent );
int ShowNetNavigator( const TOOL_EVENT& aEvent );
int ToggleProperties( const TOOL_EVENT& aEvent );
int ToggleHiddenPins( const TOOL_EVENT& aEvent );
int ToggleHiddenFields( const TOOL_EVENT& aEvent );

View File

@ -0,0 +1,190 @@
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2020 CERN
* Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sch_properties_panel.h"
#include <connection_graph.h>
#include <properties/pg_editors.h>
#include <properties/pg_properties.h>
#include <properties/property_mgr.h>
#include <sch_commit.h>
#include <sch_edit_frame.h>
#include <schematic.h>
#include <settings/color_settings.h>
#include <string_utils.h>
#include <tool/tool_manager.h>
#include <tools/ee_selection_tool.h>
SCH_PROPERTIES_PANEL::SCH_PROPERTIES_PANEL( wxWindow* aParent, SCH_BASE_FRAME* aFrame ) :
PROPERTIES_PANEL( aParent, aFrame ),
m_frame( aFrame ),
m_propMgr( PROPERTY_MANAGER::Instance() )
{
m_propMgr.Rebuild();
bool found = false;
wxASSERT( wxPGGlobalVars );
wxString editorKey = PG_UNIT_EDITOR::BuildEditorName( m_frame );
auto it = wxPGGlobalVars->m_mapEditorClasses.find( editorKey );
if( it != wxPGGlobalVars->m_mapEditorClasses.end() )
{
m_unitEditorInstance = static_cast<PG_UNIT_EDITOR*>( it->second );
m_unitEditorInstance->UpdateFrame( m_frame );
found = true;
}
if( !found )
{
PG_UNIT_EDITOR* new_editor = new PG_UNIT_EDITOR( m_frame );
m_unitEditorInstance = static_cast<PG_UNIT_EDITOR*>( wxPropertyGrid::RegisterEditorClass( new_editor ) );
}
it = wxPGGlobalVars->m_mapEditorClasses.find( PG_CHECKBOX_EDITOR::EDITOR_NAME );
if( it == wxPGGlobalVars->m_mapEditorClasses.end() )
{
PG_CHECKBOX_EDITOR* cbEditor = new PG_CHECKBOX_EDITOR();
m_checkboxEditorInstance = static_cast<PG_CHECKBOX_EDITOR*>( wxPropertyGrid::RegisterEditorClass( cbEditor ) );
}
else
{
m_checkboxEditorInstance = static_cast<PG_CHECKBOX_EDITOR*>( it->second );
}
}
SCH_PROPERTIES_PANEL::~SCH_PROPERTIES_PANEL()
{
m_unitEditorInstance->UpdateFrame( nullptr );
}
void SCH_PROPERTIES_PANEL::UpdateData()
{
EE_SELECTION_TOOL* selectionTool = m_frame->GetToolManager()->GetTool<EE_SELECTION_TOOL>();
const SELECTION& selection = selectionTool->GetSelection();
// TODO perhaps it could be called less often? use PROPERTIES_TOOL and catch MODEL_RELOAD?
if( SCH_EDIT_FRAME* schFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
updateLists( schFrame->Schematic() );
// Will actually just be updatePropertyValues() if selection hasn't changed
rebuildProperties( selection );
}
void SCH_PROPERTIES_PANEL::AfterCommit()
{
EE_SELECTION_TOOL* selectionTool = m_frame->GetToolManager()->GetTool<EE_SELECTION_TOOL>();
const SELECTION& selection = selectionTool->GetSelection();
rebuildProperties( selection );
CallAfter( [&]()
{
m_frame->GetCanvas()->SetFocus();
} );
}
wxPGProperty* SCH_PROPERTIES_PANEL::createPGProperty( const PROPERTY_BASE* aProperty ) const
{
return PGPropertyFactory( aProperty, m_frame );
}
PROPERTY_BASE* SCH_PROPERTIES_PANEL::getPropertyFromEvent( const wxPropertyGridEvent& aEvent ) const
{
EE_SELECTION_TOOL* selectionTool = m_frame->GetToolManager()->GetTool<EE_SELECTION_TOOL>();
const SELECTION& selection = selectionTool->GetSelection();
SCH_ITEM* firstItem = static_cast<SCH_ITEM*>( selection.Front() );
wxCHECK_MSG( firstItem, nullptr,
wxT( "getPropertyFromEvent for a property with nothing selected!") );
PROPERTY_BASE* property = m_propMgr.GetProperty( TYPE_HASH( *firstItem ),
aEvent.GetPropertyName() );
wxCHECK_MSG( property, nullptr,
wxT( "getPropertyFromEvent for a property not found on the selected item!" ) );
return property;
}
void SCH_PROPERTIES_PANEL::valueChanging( wxPropertyGridEvent& aEvent )
{
EE_SELECTION_TOOL* selectionTool = m_frame->GetToolManager()->GetTool<EE_SELECTION_TOOL>();
const SELECTION& selection = selectionTool->GetSelection();
EDA_ITEM* item = selection.Front();
PROPERTY_BASE* property = getPropertyFromEvent( aEvent );
wxCHECK( property, /* void */ );
wxCHECK( item, /* void */ );
wxVariant newValue = aEvent.GetPropertyValue();
if( VALIDATOR_RESULT validationFailure = property->Validate( newValue.GetAny(), item ) )
{
wxString errorMsg = wxString::Format( wxS( "%s: %s" ), wxGetTranslation( property->Name() ),
validationFailure->get()->Format( m_frame ) );
m_frame->ShowInfoBarError( errorMsg );
aEvent.Veto();
return;
}
}
void SCH_PROPERTIES_PANEL::valueChanged( wxPropertyGridEvent& aEvent )
{
EE_SELECTION_TOOL* selectionTool = m_frame->GetToolManager()->GetTool<EE_SELECTION_TOOL>();
const SELECTION& selection = selectionTool->GetSelection();
PROPERTY_BASE* property = getPropertyFromEvent( aEvent );
wxCHECK( property, /* void */ );
wxVariant newValue = aEvent.GetPropertyValue();
SCH_COMMIT changes( m_frame );
SCH_SCREEN* screen = m_frame->GetScreen();
for( EDA_ITEM* edaItem : selection )
{
SCH_ITEM* item = static_cast<SCH_ITEM*>( edaItem );
changes.Modify( item, screen );
item->Set( property, newValue );
}
changes.Push( _( "Change property" ) );
m_frame->Refresh();
// Perform grid updates as necessary based on value change
AfterCommit();
}
void SCH_PROPERTIES_PANEL::updateLists( const SCHEMATIC& aSchematic )
{
// No lists yet
}

View File

@ -0,0 +1,64 @@
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SCH_PROPERTIES_PANEL_H
#define SCH_PROPERTIES_PANEL_H
#include <widgets/properties_panel.h>
class SELECTION;
class SCHEMATIC;
class SCH_BASE_FRAME;
class PROPERTY_MANAGER;
class PG_UNIT_EDITOR;
class PG_CHECKBOX_EDITOR;
class SCH_PROPERTIES_PANEL : public PROPERTIES_PANEL
{
public:
SCH_PROPERTIES_PANEL( wxWindow* aParent, SCH_BASE_FRAME* aFrame );
virtual ~SCH_PROPERTIES_PANEL();
void UpdateData() override;
void AfterCommit() override;
protected:
wxPGProperty* createPGProperty( const PROPERTY_BASE* aProperty ) const override;
PROPERTY_BASE* getPropertyFromEvent( const wxPropertyGridEvent& aEvent ) const;
void valueChanging( wxPropertyGridEvent& aEvent ) override;
void valueChanged( wxPropertyGridEvent& aEvent ) override;
///< Regenerates caches of list properties
void updateLists( const SCHEMATIC& aSchematic );
SCH_BASE_FRAME* m_frame;
PROPERTY_MANAGER& m_propMgr;
PG_UNIT_EDITOR* m_unitEditorInstance;
PG_CHECKBOX_EDITOR* m_checkboxEditorInstance;
wxPGChoices m_nets;
};
#endif /* PCB_PROPERTIES_PANEL_H */

View File

@ -44,6 +44,7 @@ class APP_SETTINGS_BASE;
class wxFindReplaceData;
class SEARCH_PANE;
class HOTKEY_CYCLE_POPUP;
class PROPERTIES_PANEL;
namespace KIGFX
{
@ -387,6 +388,14 @@ public:
*/
virtual void UpdateMsgPanel();
PROPERTIES_PANEL* GetPropertiesPanel() { return m_propertiesPanel; }
void UpdateProperties();
virtual void ToggleProperties() {}
static const wxString PropertiesPaneName() { return wxS( "PropertiesManager" ); }
/**
* Fetch an item by KIID. Frame-type-specific implementation.
*/
@ -523,6 +532,7 @@ protected:
COLOR_SETTINGS* m_colorSettings;
SEARCH_PANE* m_searchPane;
PROPERTIES_PANEL* m_propertiesPanel;
HOTKEY_CYCLE_POPUP* m_hotkeyPopup;

View File

@ -0,0 +1,55 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KICAD_COLOR4D_VARIANT_H
#define KICAD_COLOR4D_VARIANT_H
#include <gal/color4d.h>
#include <wx/variant.h>
class COLOR4D_VARIANT_DATA : public wxVariantData
{
public:
COLOR4D_VARIANT_DATA();
COLOR4D_VARIANT_DATA( const wxString& aColorStr );
COLOR4D_VARIANT_DATA( const KIGFX::COLOR4D& aColor );
bool Eq( wxVariantData& aOther ) const override;
wxString GetType() const override { return wxT( "COLOR4D" ); }
bool Read( wxString& aString ) override;
bool Write( wxString& aString ) const override;
bool GetAsAny( wxAny* aAny ) const override;
static wxVariantData* VariantDataFactory( const wxAny& aAny );
const KIGFX::COLOR4D& Color() { return m_color; }
void SetColor( const KIGFX::COLOR4D& aColor ) { m_color = aColor; }
protected:
KIGFX::COLOR4D m_color;
};
#endif //KICAD_COLOR4D_VARIANT_H

View File

@ -26,6 +26,7 @@
#include <wx/propgrid/propgrid.h>
#include <wx/propgrid/property.h>
#include <wx/propgrid/props.h>
#include <wx/propgrid/advprops.h>
#include <common.h>
#include <origin_transforms.h>
@ -187,4 +188,19 @@ public:
const wxPGEditor* DoGetEditorClass() const override;
};
class PGPROPERTY_COLOR4D : public wxColourProperty
{
public:
PGPROPERTY_COLOR4D( const wxString& aLabel = wxPG_LABEL, const wxString& aName = wxPG_LABEL,
COLOR4D aValue = COLOR4D::UNSPECIFIED );
virtual ~PGPROPERTY_COLOR4D() = default;
wxString ValueToString( wxVariant& aValue, int aFlags = 0 ) const override;
bool StringToValue( wxVariant &aVariant, const wxString &aText,
int aFlags = 0 ) const override;
};
#endif /* PG_PROPERTIES_H */

View File

@ -26,6 +26,7 @@
#include <core/wx_stl_compat.h>
#include <origin_transforms.h>
#include <properties/color4d_variant.h>
#include <properties/eda_angle_variant.h>
#include <properties/property_validator.h>
@ -343,6 +344,11 @@ protected:
EDA_ANGLE_VARIANT_DATA* ad = static_cast<EDA_ANGLE_VARIANT_DATA*>( var.GetData() );
a = ad->Angle();
}
else if( pv.CheckType<KIGFX::COLOR4D>() )
{
COLOR4D_VARIANT_DATA* cd = static_cast<COLOR4D_VARIANT_DATA*>( var.GetData() );
a = cd->Color();
}
}
setter( aObject, a );

View File

@ -224,6 +224,9 @@ public:
ORIGIN_TRANSFORMS* GetTransforms() const { return m_originTransforms; }
void SetTransforms( ORIGIN_TRANSFORMS* aTransforms ) { m_originTransforms = aTransforms; }
const EDA_IU_SCALE* GetIuScale() const { return m_iuScale; }
void SetIuScale( const EDA_IU_SCALE* aScale ) { m_iuScale = aScale; }
/**
* Rebuild the list of all registered properties. Needs to be called
* once before GetProperty()/GetProperties() are used.
@ -247,7 +250,8 @@ private:
PROPERTY_MANAGER() :
m_dirty( false ),
m_units( EDA_UNITS::MILLIMETRES ),
m_originTransforms( nullptr )
m_originTransforms( nullptr ),
m_iuScale( &pcbIUScale )
{
}
@ -304,7 +308,7 @@ private:
///< all properties available to a type
void collectPropsRecur( PROPERTY_LIST& aResult, PROPERTY_SET& aReplaced,
PROPERTY_DISPLAY_ORDER& aDisplayOrder,
const PROPERTY_SET& aMasked ) const;
PROPERTY_SET& aMasked ) const;
};
///< Returns metadata for a specific type
@ -321,6 +325,8 @@ private:
EDA_UNITS m_units;
ORIGIN_TRANSFORMS* m_originTransforms;
const EDA_IU_SCALE* m_iuScale;
};

View File

@ -167,6 +167,7 @@ public:
static TOOL_ACTION showFootprintEditor;
static TOOL_ACTION updatePcbFromSchematic;
static TOOL_ACTION updateSchematicFromPcb;
static TOOL_ACTION showProperties;
// Internal
static TOOL_ACTION updateMenu;

View File

@ -21,19 +21,21 @@
#ifndef PROPERTIES_TOOL_H
#define PROPERTIES_TOOL_H
#include <tools/pcb_tool_base.h>
#include <tool/tool_interactive.h>
/**
* Action handler for the Properties panel
*/
class PROPERTIES_TOOL : public PCB_TOOL_BASE
class PROPERTIES_TOOL : public TOOL_INTERACTIVE
{
public:
PROPERTIES_TOOL()
: PCB_TOOL_BASE( "pcbnew.Properties" )
: TOOL_INTERACTIVE( "common.Properties" )
{
}
virtual void Reset( RESET_REASON aReason ) override {}
int UpdateProperties( const TOOL_EVENT& aEvent );
void setTransitions() override;

View File

@ -349,7 +349,6 @@ set( PCBNEW_CLASS_SRCS
tools/placement_tool.cpp
tools/pcb_point_editor.cpp
tools/position_relative_tool.cpp
tools/properties_tool.cpp
tools/tool_event_utils.cpp
tools/zone_create_helper.cpp
tools/zone_filler_tool.cpp

View File

@ -31,7 +31,6 @@
#include "tools/placement_tool.h"
#include "tools/pcb_point_editor.h"
#include "tools/pcb_selection_tool.h"
#include "tools/properties_tool.h"
#include <python/scripting/pcb_scripting_tool.h>
#include <3d_viewer/eda_3d_viewer_frame.h>
#include <bitmaps.h>
@ -56,6 +55,7 @@
#include <tool/action_toolbar.h>
#include <tool/common_control.h>
#include <tool/common_tools.h>
#include <tool/properties_tool.h>
#include <tool/selection.h>
#include <tool/tool_dispatcher.h>
#include <tool/tool_manager.h>
@ -222,7 +222,7 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
.Left().Layer( 4 )
.Caption( _( "Libraries" ) )
.MinSize( 250, -1 ).BestSize( 250, -1 ) );
m_auimgr.AddPane( m_propertiesPanel, EDA_PANE().Name( wxS( "PropertiesManager" ) )
m_auimgr.AddPane( m_propertiesPanel, EDA_PANE().Name( PropertiesPaneName() )
.Left().Layer( 3 ).Caption( _( "Properties" ) )
.PaneBorder( false ).MinSize( 240, -1 ).BestSize( 300, -1 ) );
m_auimgr.AddPane( m_optionsToolBar, EDA_PANE().VToolbar().Name( "OptToolbar" )
@ -245,7 +245,7 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
m_auimgr.GetPane( "LayersManager" ).Show( m_show_layer_manager_tools );
m_auimgr.GetPane( "SelectionFilter" ).Show( m_show_layer_manager_tools );
m_auimgr.GetPane( "PropertiesManager" ).Show( m_show_properties );
m_auimgr.GetPane( PropertiesPaneName() ).Show( GetSettings()->m_AuiPanels.show_properties );
// The selection filter doesn't need to grow in the vertical direction when docked
m_auimgr.GetPane( "SelectionFilter" ).dock_proportion = 0;
@ -639,7 +639,6 @@ void FOOTPRINT_EDIT_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg )
m_displayOptions = cfg->m_Display;
m_show_layer_manager_tools = cfg->m_AuiPanels.show_layer_manager;
m_show_properties = cfg->m_AuiPanels.show_properties;
GetToolManager()->GetTool<PCB_SELECTION_TOOL>()->GetFilter() = cfg->m_SelectionFilter;
m_selectionFilterPanel->SetCheckboxesFromFilter( cfg->m_SelectionFilter );
@ -672,7 +671,7 @@ void FOOTPRINT_EDIT_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg )
cfg->m_AuiPanels.right_panel_width = m_appearancePanel->GetSize().x;
cfg->m_AuiPanels.appearance_panel_tab = m_appearancePanel->GetTabIndex();
cfg->m_AuiPanels.show_properties = m_show_properties;
cfg->m_AuiPanels.show_properties = m_propertiesPanel->IsShownOnScreen();
cfg->m_AuiPanels.properties_panel_width = m_propertiesPanel->GetSize().x;
cfg->m_AuiPanels.properties_splitter_proportion =
@ -1239,7 +1238,7 @@ void FOOTPRINT_EDIT_FRAME::setupUIConditions()
auto propertiesCond =
[this] ( const SELECTION& )
{
return m_auimgr.GetPane( "PropertiesManager" ).IsShown();
return m_auimgr.GetPane( PropertiesPaneName() ).IsShown();
};
mgr->SetConditions( PCB_ACTIONS::toggleHV45Mode, CHECK( constrainedDrawingModeCond ) );

View File

@ -226,7 +226,7 @@ void PCB_EDIT_FRAME::doReCreateMenuBar()
viewMenu->Add( ACTIONS::showFootprintBrowser );
viewMenu->Add( PCB_ACTIONS::showProperties, ACTION_MENU::CHECK );
viewMenu->Add( ACTIONS::showProperties, ACTION_MENU::CHECK );
viewMenu->Add( PCB_ACTIONS::showSearch, ACTION_MENU::CHECK );
viewMenu->Add( ACTIONS::show3DViewer );

View File

@ -53,9 +53,7 @@ PCB_BASE_EDIT_FRAME::PCB_BASE_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent,
m_undoRedoBlocked( false ),
m_selectionFilterPanel( nullptr ),
m_appearancePanel( nullptr ),
m_propertiesPanel( nullptr ),
m_tabbedPanel( nullptr ),
m_show_properties( false )
m_tabbedPanel( nullptr )
{
m_darkMode = KIPLATFORM::UI::IsDarkTheme();
@ -290,28 +288,19 @@ void PCB_BASE_EDIT_FRAME::onDarkModeToggle()
}
void PCB_BASE_EDIT_FRAME::UpdateProperties()
{
if( !m_propertiesPanel || !m_propertiesPanel->IsShownOnScreen() )
return;
m_propertiesPanel->UpdateData();
}
void PCB_BASE_EDIT_FRAME::ToggleProperties()
{
if( !m_propertiesPanel )
return;
bool show = !m_propertiesPanel->IsShownOnScreen();
wxAuiPaneInfo& propertiesPaneInfo = m_auimgr.GetPane( PropertiesPaneName() );
propertiesPaneInfo.Show( show );
PCBNEW_SETTINGS* settings = GetPcbNewSettings();
m_show_properties = !m_show_properties;
wxAuiPaneInfo& propertiesPaneInfo = m_auimgr.GetPane( "PropertiesManager" );
propertiesPaneInfo.Show( m_show_properties );
if( m_show_properties )
if( show )
{
SetAuiPaneSize( m_auimgr, propertiesPaneInfo,
settings->m_AuiPanels.properties_panel_width, -1 );

View File

@ -32,7 +32,6 @@
class APPEARANCE_CONTROLS;
class BOARD_ITEM_CONTAINER;
class PANEL_SELECTION_FILTER;
class PROPERTIES_PANEL;
class PCB_TEXTBOX;
class PCB_TEXT;
class PCB_SHAPE;
@ -220,11 +219,7 @@ public:
APPEARANCE_CONTROLS* GetAppearancePanel() { return m_appearancePanel; }
PROPERTIES_PANEL* GetPropertiesPanel() { return m_propertiesPanel; }
void UpdateProperties();
void ToggleProperties();
void ToggleProperties() override;
void GetContextualTextVars( BOARD_ITEM* aSourceItem, const wxString& aCrossRef,
wxArrayString* aTokens );
@ -258,12 +253,10 @@ protected:
PANEL_SELECTION_FILTER* m_selectionFilterPanel;
APPEARANCE_CONTROLS* m_appearancePanel;
PROPERTIES_PANEL* m_propertiesPanel;
wxAuiNotebook* m_tabbedPanel; /// Panel with Layers and Object Inspector tabs
bool m_darkMode;
bool m_show_properties;
};
#endif

View File

@ -61,6 +61,7 @@
#include <tool/action_toolbar.h>
#include <tool/common_control.h>
#include <tool/common_tools.h>
#include <tool/properties_tool.h>
#include <tool/selection.h>
#include <tool/zoom_tool.h>
#include <tools/pcb_selection_tool.h>
@ -82,7 +83,6 @@
#include <tools/pad_tool.h>
#include <microwave/microwave_tool.h>
#include <tools/position_relative_tool.h>
#include <tools/properties_tool.h>
#include <tools/zone_filler_tool.h>
#include <tools/pcb_actions.h>
#include <router/router_tool.h>
@ -203,7 +203,6 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
m_show_layer_manager_tools = true;
m_supportsAutoSave = true;
m_probingSchToPcb = false;
m_show_properties = true;
m_show_search = false;
// We don't know what state board was in when it was last saved, so we have to
@ -304,7 +303,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
.Caption( _( "Selection Filter" ) ).PaneBorder( false )
.MinSize( 180, -1 ).BestSize( 180, -1 ) );
m_auimgr.AddPane( m_propertiesPanel, EDA_PANE().Name( wxS( "PropertiesManager" ) )
m_auimgr.AddPane( m_propertiesPanel, EDA_PANE().Name( PropertiesPaneName() )
.Left().Layer( 5 ).Caption( _( "Properties" ) )
.PaneBorder( false ).MinSize( 240, -1 ).BestSize( 300, -1 ) );
@ -327,7 +326,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
m_auimgr.GetPane( "LayersManager" ).Show( m_show_layer_manager_tools );
m_auimgr.GetPane( "SelectionFilter" ).Show( m_show_layer_manager_tools );
m_auimgr.GetPane( "PropertiesManager" ).Show( m_show_properties );
m_auimgr.GetPane( PropertiesPaneName() ).Show( GetPcbNewSettings()->m_AuiPanels.show_properties );
m_auimgr.GetPane( SearchPaneName() ).Show( m_show_search );
@ -346,7 +345,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
if( settings->m_AuiPanels.properties_panel_width > 0 && m_propertiesPanel )
{
wxAuiPaneInfo& propertiesPanel = m_auimgr.GetPane( wxS( "PropertiesManager" ) );
wxAuiPaneInfo& propertiesPanel = m_auimgr.GetPane( PropertiesPaneName() );
SetAuiPaneSize( m_auimgr, propertiesPanel,
settings->m_AuiPanels.properties_panel_width, -1 );
}
@ -1301,7 +1300,6 @@ void PCB_EDIT_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg )
if( cfg )
{
m_show_layer_manager_tools = cfg->m_AuiPanels.show_layer_manager;
m_show_properties = cfg->m_AuiPanels.show_properties;
m_show_search = cfg->m_AuiPanels.show_search;
}
}
@ -1322,7 +1320,7 @@ void PCB_EDIT_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg )
if( m_propertiesPanel )
{
cfg->m_AuiPanels.show_properties = m_show_properties;
cfg->m_AuiPanels.show_properties = m_propertiesPanel->IsShownOnScreen();
cfg->m_AuiPanels.properties_panel_width = m_propertiesPanel->GetSize().x;
cfg->m_AuiPanels.properties_splitter_proportion =
@ -2441,7 +2439,7 @@ bool PCB_EDIT_FRAME::LayerManagerShown()
bool PCB_EDIT_FRAME::PropertiesShown()
{
return m_auimgr.GetPane( wxS( "PropertiesManager" ) ).IsShown();
return m_auimgr.GetPane( PropertiesPaneName() ).IsShown();
}

View File

@ -1670,7 +1670,7 @@ void BOARD_EDITOR_CONTROL::setTransitions()
ACTIONS::updateSchematicFromPcb.MakeEvent() );
Go( &BOARD_EDITOR_CONTROL::ShowEeschema, PCB_ACTIONS::showEeschema.MakeEvent() );
Go( &BOARD_EDITOR_CONTROL::ToggleLayersManager, PCB_ACTIONS::showLayersManager.MakeEvent() );
Go( &BOARD_EDITOR_CONTROL::ToggleProperties, PCB_ACTIONS::showProperties.MakeEvent() );
Go( &BOARD_EDITOR_CONTROL::ToggleProperties, ACTIONS::showProperties.MakeEvent() );
Go( &BOARD_EDITOR_CONTROL::ToggleSearch, PCB_ACTIONS::showSearch.MakeEvent() );
Go( &BOARD_EDITOR_CONTROL::TogglePythonConsole, PCB_ACTIONS::showPythonConsole.MakeEvent() );
Go( &BOARD_EDITOR_CONTROL::RepairBoard, PCB_ACTIONS::repairBoard.MakeEvent() );

View File

@ -923,11 +923,6 @@ TOOL_ACTION PCB_ACTIONS::showLayersManager( "pcbnew.Control.showLayersManager",
_( "Show Appearance Manager" ), _( "Show/hide the appearance manager" ),
BITMAPS::layers_manager );
TOOL_ACTION PCB_ACTIONS::showProperties( "pcbnew.Control.showProperties",
AS_GLOBAL, 0, "",
_( "Show Properties Manager" ), _( "Show/hide the properties manager" ),
BITMAPS::tools );
TOOL_ACTION PCB_ACTIONS::flipBoard( "pcbnew.Control.flipBoard",
AS_GLOBAL, 0, "",
_( "Flip Board View" ), _( "View board from the opposite side" ),

View File

@ -388,7 +388,6 @@ public:
static TOOL_ACTION editLibFpInFpEditor;
static TOOL_ACTION showLayersManager;
static TOOL_ACTION showProperties;
static TOOL_ACTION showPythonConsole;
// Module editor tools