committed by
Jon Evans
29 changed files with 1867 additions and 18 deletions
-
2common/CMakeLists.txt
-
282common/pg_properties.cpp
-
149common/widgets/properties_panel.cpp
-
75common/widgets/properties_panel.h
-
112include/pg_properties.h
-
2include/property.h
-
5include/validators.h
-
2pcbnew/CMakeLists.txt
-
118pcbnew/dialogs/pcb_properties_panel.cpp
-
56pcbnew/dialogs/pcb_properties_panel.h
-
1pcbnew/menubar_pcb_editor.cpp
-
15pcbnew/pcb_base_edit_frame.cpp
-
9pcbnew/pcb_base_edit_frame.h
-
21pcbnew/pcb_edit_frame.cpp
-
5pcbnew/pcb_edit_frame.h
-
708pcbnew/pcb_layer_widget.cpp
-
182pcbnew/pcb_layer_widget.h
-
1pcbnew/pcb_shape.cpp
-
3pcbnew/pcbnew_settings.cpp
-
1pcbnew/pcbnew_settings.h
-
8pcbnew/toolbars_pcb_editor.cpp
-
8pcbnew/tools/board_editor_control.cpp
-
3pcbnew/tools/board_editor_control.h
-
5pcbnew/tools/pcb_actions.cpp
-
1pcbnew/tools/pcb_actions.h
-
2pcbnew/tools/pcb_control.h
-
45pcbnew/tools/properties_tool.cpp
-
42pcbnew/tools/properties_tool.h
-
22qa/tools/pcb_test_window/CMakeLists.txt
@ -0,0 +1,282 @@ |
|||
/*
|
|||
* This program source code file is part of KICAD, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2020 CERN |
|||
* @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 <pg_properties.h>
|
|||
#include <property_mgr.h>
|
|||
#include <wx/propgrid/propgrid.h>
|
|||
#include <wx/regex.h>
|
|||
|
|||
#include <common.h>
|
|||
#include <validators.h>
|
|||
#include <convert_to_biu.h>
|
|||
#include <property.h>
|
|||
|
|||
// reg-ex describing a signed valid value with a unit
|
|||
static const wxChar REGEX_SIGNED_DISTANCE[] = wxT( "([-+]?[0-9]+[\\.?[0-9]*) *(mm|in)*" ); |
|||
static const wxChar REGEX_UNSIGNED_DISTANCE[] = wxT( "([0-9]+[\\.?[0-9]*) *(mm|in)*" ); |
|||
|
|||
wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty ) |
|||
{ |
|||
wxPGProperty* ret = nullptr; |
|||
PROPERTY_DISPLAY display = aProperty->Display(); |
|||
|
|||
switch( display ) |
|||
{ |
|||
case PROPERTY_DISPLAY::SIZE: |
|||
ret = new PGPROPERTY_SIZE(); |
|||
break; |
|||
|
|||
case PROPERTY_DISPLAY::COORD: |
|||
ret = new PGPROPERTY_COORD(); |
|||
break; |
|||
|
|||
case PROPERTY_DISPLAY::DECIDEGREE: /* fall-through */ |
|||
case PROPERTY_DISPLAY::DEGREE: |
|||
{ |
|||
auto prop = new PGPROPERTY_ANGLE(); |
|||
|
|||
if( display == PROPERTY_DISPLAY::DECIDEGREE ) |
|||
prop->SetScale( 10.0 ); |
|||
|
|||
ret = prop; |
|||
break; |
|||
} |
|||
|
|||
default: |
|||
wxFAIL; |
|||
/* fall through */ |
|||
case PROPERTY_DISPLAY::DEFAULT: |
|||
{ |
|||
// Create a corresponding wxPGProperty
|
|||
size_t typeId = aProperty->TypeHash(); |
|||
|
|||
// Enum property
|
|||
if( aProperty->HasChoices() ) |
|||
{ |
|||
// I do not know why enum property takes a non-const reference to wxPGChoices..
|
|||
ret = new wxEnumProperty( wxPG_LABEL, wxPG_LABEL, |
|||
const_cast<wxPGChoices&>( aProperty->Choices() ) ); |
|||
} |
|||
|
|||
else if( typeId == TYPE_HASH( int ) || typeId == TYPE_HASH( long ) ) |
|||
{ |
|||
ret = new wxIntProperty(); |
|||
} |
|||
|
|||
else if( typeId == TYPE_HASH( unsigned int ) || typeId == TYPE_HASH( unsigned long ) ) |
|||
{ |
|||
ret = new wxUIntProperty(); |
|||
} |
|||
|
|||
else if( typeId == TYPE_HASH( float ) || typeId == TYPE_HASH( double ) ) |
|||
{ |
|||
ret = new wxFloatProperty(); |
|||
} |
|||
|
|||
else if( typeId == TYPE_HASH( bool ) ) |
|||
{ |
|||
ret = new wxBoolProperty(); |
|||
} |
|||
|
|||
else if( typeId == TYPE_HASH( wxString ) ) |
|||
{ |
|||
ret = new wxStringProperty(); |
|||
} |
|||
|
|||
else |
|||
{ |
|||
wxFAIL_MSG( wxString::Format( "Property '" + aProperty->Name() + |
|||
"' is not supported by PGPropertyFactory" ) ); |
|||
ret = new wxPropertyCategory(); |
|||
ret->Enable( false ); |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if( ret ) |
|||
{ |
|||
ret->SetLabel( aProperty->Name() ); |
|||
ret->SetName( aProperty->Name() ); |
|||
ret->Enable( !aProperty->IsReadOnly() ); |
|||
ret->SetClientData( const_cast<PROPERTY_BASE*>( aProperty ) ); |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
|
|||
PGPROPERTY_DISTANCE::PGPROPERTY_DISTANCE( const wxString& aRegEx ) |
|||
{ |
|||
m_regExValidator.reset( new REGEX_VALIDATOR( aRegEx ) ); |
|||
} |
|||
|
|||
|
|||
PGPROPERTY_DISTANCE::~PGPROPERTY_DISTANCE() |
|||
{ |
|||
} |
|||
|
|||
|
|||
bool PGPROPERTY_DISTANCE::StringToDistance( wxVariant& aVariant, const wxString& aText, int aArgFlags ) const |
|||
{ |
|||
wxRegEx regDimension( m_regExValidator->GetRegEx(), wxRE_ICASE ); |
|||
wxASSERT( regDimension.IsValid() ); |
|||
|
|||
if( !regDimension.Matches( aText ) ) |
|||
{ |
|||
aVariant.MakeNull(); |
|||
return false; |
|||
} |
|||
|
|||
|
|||
// Get the value
|
|||
wxString valueText = regDimension.GetMatch( aText, 1 ); |
|||
double value = 0.0; |
|||
|
|||
if( !valueText.ToDouble( &value ) ) |
|||
{ |
|||
aVariant.MakeNull(); |
|||
return false; |
|||
} |
|||
|
|||
|
|||
// Determine units: use the app setting if unit is not explicitly specified
|
|||
EDA_UNITS unit; |
|||
wxString unitText = regDimension.GetMatch( aText, 2 ).Lower(); |
|||
|
|||
if( unitText == "mm" ) |
|||
unit = EDA_UNITS::MILLIMETRES; |
|||
else if( unitText == "in" ) |
|||
unit = EDA_UNITS::INCHES; |
|||
else |
|||
unit = PROPERTY_MANAGER::Instance().GetUnits(); |
|||
|
|||
|
|||
// Conversion to internal units
|
|||
long newValueIU; |
|||
|
|||
switch( unit ) |
|||
{ |
|||
case EDA_UNITS::INCHES: |
|||
newValueIU = Mils2iu( value * 1000.0 ); |
|||
break; |
|||
|
|||
case EDA_UNITS::MILLIMETRES: |
|||
newValueIU = Millimeter2iu( value ); |
|||
break; |
|||
|
|||
case EDA_UNITS::UNSCALED: |
|||
newValueIU = value; |
|||
break; |
|||
|
|||
default: |
|||
// DEGREEs are handled by PGPROPERTY_ANGLE
|
|||
wxFAIL; |
|||
break; |
|||
} |
|||
|
|||
if( aVariant.IsNull() || newValueIU != aVariant.GetLong() ) |
|||
{ |
|||
aVariant = newValueIU; |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
|
|||
wxString PGPROPERTY_DISTANCE::DistanceToString( wxVariant& aVariant, int aArgFlags ) const |
|||
{ |
|||
wxCHECK( aVariant.GetType() == wxPG_VARIANT_TYPE_LONG, wxEmptyString ); |
|||
|
|||
switch( PROPERTY_MANAGER::Instance().GetUnits() ) |
|||
{ |
|||
case EDA_UNITS::INCHES: |
|||
return wxString::Format( wxT( "%g in" ), Iu2Mils( aVariant.GetLong() ) / 1000.0 ); |
|||
|
|||
case EDA_UNITS::MILLIMETRES: |
|||
return wxString::Format( wxT( "%g mm" ), Iu2Millimeter( aVariant.GetLong() ) ); |
|||
|
|||
case EDA_UNITS::UNSCALED: |
|||
return wxString::Format( wxT( "%li" ), aVariant.GetLong() ); |
|||
|
|||
default: |
|||
// DEGREEs are handled by PGPROPERTY_ANGLE
|
|||
break; |
|||
} |
|||
|
|||
wxFAIL; |
|||
return wxEmptyString; |
|||
} |
|||
|
|||
|
|||
PGPROPERTY_SIZE::PGPROPERTY_SIZE( const wxString& aLabel, const wxString& aName, |
|||
long aValue ) |
|||
: wxUIntProperty( aLabel, aName, aValue ), PGPROPERTY_DISTANCE( REGEX_UNSIGNED_DISTANCE ) |
|||
{ |
|||
} |
|||
|
|||
|
|||
wxValidator* PGPROPERTY_SIZE::DoGetValidator() const |
|||
{ |
|||
return m_regExValidator.get(); |
|||
} |
|||
|
|||
|
|||
PGPROPERTY_COORD::PGPROPERTY_COORD( const wxString& aLabel, const wxString& aName, |
|||
long aValue ) |
|||
: wxIntProperty( aLabel, aName, aValue ), PGPROPERTY_DISTANCE( REGEX_SIGNED_DISTANCE ) |
|||
{ |
|||
} |
|||
|
|||
|
|||
wxValidator* PGPROPERTY_COORD::DoGetValidator() const |
|||
{ |
|||
return m_regExValidator.get(); |
|||
} |
|||
|
|||
|
|||
bool PGPROPERTY_ANGLE::StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags ) const |
|||
{ |
|||
double value = 0.0; |
|||
|
|||
if( !aText.ToDouble( &value ) ) |
|||
{ |
|||
aVariant.MakeNull(); |
|||
return true; |
|||
} |
|||
|
|||
value *= m_scale; |
|||
|
|||
if( aVariant.IsNull() || aVariant.GetDouble() != value ) |
|||
{ |
|||
aVariant = value; |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
|
|||
wxString PGPROPERTY_ANGLE::ValueToString( wxVariant& aVariant, int aArgFlags ) const |
|||
{ |
|||
wxCHECK( aVariant.GetType() == wxPG_VARIANT_TYPE_DOUBLE, wxEmptyString ); |
|||
return wxString::Format( wxT("%g\u00B0"), aVariant.GetDouble() / m_scale ); |
|||
} |
@ -0,0 +1,149 @@ |
|||
/*
|
|||
* This program source code file is part of KICAD, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2020 CERN |
|||
* @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 "properties_panel.h"
|
|||
#include <tool/selection.h>
|
|||
#include <eda_base_frame.h>
|
|||
#include <eda_item.h>
|
|||
|
|||
#include <algorithm>
|
|||
#include <set>
|
|||
|
|||
using namespace std; |
|||
|
|||
PROPERTIES_PANEL::PROPERTIES_PANEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame ) |
|||
: wxPanel( aParent ), m_frame( aFrame ) |
|||
{ |
|||
wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL ); |
|||
|
|||
m_grid = new wxPropertyGrid( this, wxID_ANY, wxDefaultPosition, wxSize( 300, 400 ), |
|||
wxPG_AUTO_SORT | wxPG_SPLITTER_AUTO_CENTER | wxPG_DEFAULT_STYLE ); |
|||
m_grid->SetUnspecifiedValueAppearance( wxPGCell( "<...>" ) ); |
|||
mainSizer->Add( m_grid, 1, wxALL | wxEXPAND, 5 ); |
|||
|
|||
SetSizer( mainSizer ); |
|||
Layout(); |
|||
|
|||
Connect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanged ), NULL, this ); |
|||
Connect( wxEVT_PG_CHANGING, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanging ), NULL, this ); |
|||
} |
|||
|
|||
|
|||
void PROPERTIES_PANEL::update( const SELECTION& aSelection ) |
|||
{ |
|||
m_grid->Clear(); |
|||
m_displayed.clear(); |
|||
|
|||
if( aSelection.Empty() ) |
|||
return; |
|||
|
|||
// Get all the selected types
|
|||
set<TYPE_ID> types; |
|||
|
|||
for( EDA_ITEM* item : aSelection ) |
|||
types.insert( TYPE_HASH( *item ) ); |
|||
|
|||
wxCHECK( !types.empty(), /* void */ ); |
|||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance(); |
|||
propMgr.SetUnits( m_frame->GetUserUnits() ); |
|||
|
|||
set<PROPERTY_BASE*> commonProps; |
|||
const PROPERTY_LIST& allProperties = propMgr.GetProperties( *types.begin() ); |
|||
copy( allProperties.begin(), allProperties.end(), inserter( commonProps, commonProps.begin() ) ); |
|||
|
|||
// Get all possible properties
|
|||
for( const auto& type : types ) |
|||
{ |
|||
const PROPERTY_LIST& itemProps = propMgr.GetProperties( type ); |
|||
|
|||
for( auto it = commonProps.begin(); it != commonProps.end(); /* ++it in the loop */ ) |
|||
{ |
|||
if( !binary_search( itemProps.begin(), itemProps.end(), *it ) ) |
|||
it = commonProps.erase( it ); |
|||
else |
|||
++it; |
|||
} |
|||
} |
|||
|
|||
// Find a set of properties that is common to all selected items
|
|||
for( const auto& property : commonProps ) |
|||
{ |
|||
if( !property->Available( aSelection.Front() ) ) |
|||
continue; |
|||
|
|||
// Either determine the common value for a property or "<...>" to mark multiple values
|
|||
bool first = true; |
|||
bool available = true; |
|||
wxVariant commonVal, itemVal; |
|||
|
|||
for( EDA_ITEM* item : aSelection ) |
|||
{ |
|||
wxVariant& value = first ? commonVal : itemVal; |
|||
|
|||
if( !first && !property->Available( item ) ) |
|||
{ |
|||
// there is an item that does not have this property
|
|||
available = false; |
|||
break; |
|||
} |
|||
|
|||
const wxAny& any = static_cast<EDA_ITEM*>( item )->Get( property ); |
|||
|
|||
if( !any.GetAs( &value ) ) |
|||
{ |
|||
int tmp; |
|||
|
|||
if( any.GetAs<int>( &tmp ) ) // needed to handle enums
|
|||
{ |
|||
value = wxVariant( tmp ); |
|||
} |
|||
else |
|||
{ |
|||
wxFAIL_MSG( "Could not convert wxAny to wxVariant" ); |
|||
// if it is an enum, be sure that there is a corresponding ENUM_TO_WXANY
|
|||
available = false; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if( !first && value != commonVal ) |
|||
{ |
|||
commonVal.MakeNull(); // items have different values for this property
|
|||
break; |
|||
} |
|||
|
|||
first = false; |
|||
} |
|||
|
|||
if( available ) |
|||
{ |
|||
wxPGProperty* pgProp = createPGProperty( property ); |
|||
|
|||
if( pgProp ) |
|||
{ |
|||
pgProp->SetValue( commonVal ); |
|||
m_grid->Append( pgProp ); |
|||
m_displayed.push_back( property ); |
|||
} |
|||
} |
|||
} |
|||
|
|||
m_grid->FitColumns(); |
|||
} |
@ -0,0 +1,75 @@ |
|||
/* |
|||
* This program source code file is part of KICAD, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2016 CERN |
|||
* @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 2 |
|||
* 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, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
|||
* or you may search the http://www.gnu.org website for the version 2 license, |
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
#ifndef PROPERTIES_PANEL_H |
|||
#define PROPERTIES_PANEL_H |
|||
|
|||
#include <wx/panel.h> |
|||
#include <wx/propgrid/propgrid.h> |
|||
|
|||
#include <vector> |
|||
|
|||
class EDA_BASE_FRAME; |
|||
class SELECTION; |
|||
class PROPERTY_BASE; |
|||
|
|||
class PROPERTIES_PANEL : public wxPanel |
|||
{ |
|||
public: |
|||
PROPERTIES_PANEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame ); |
|||
|
|||
virtual ~PROPERTIES_PANEL() |
|||
{ |
|||
} |
|||
|
|||
virtual void Update() override = 0; |
|||
|
|||
wxPropertyGrid* GetPropertyGrid() |
|||
{ |
|||
return m_grid; |
|||
} |
|||
|
|||
int PropertiesCount() const |
|||
{ |
|||
return m_displayed.size(); |
|||
} |
|||
|
|||
const std::vector<PROPERTY_BASE*>& Properties() const |
|||
{ |
|||
return m_displayed; |
|||
} |
|||
|
|||
protected: |
|||
virtual void update( const SELECTION& aSelection ); |
|||
virtual wxPGProperty* createPGProperty( const PROPERTY_BASE* aProperty ) const = 0; |
|||
|
|||
// Event handlers |
|||
virtual void valueChanging( wxPropertyGridEvent& aEvent ) {} |
|||
virtual void valueChanged( wxPropertyGridEvent& aEvent ) {} |
|||
|
|||
std::vector<PROPERTY_BASE*> m_displayed; |
|||
wxPropertyGrid* m_grid; |
|||
EDA_BASE_FRAME* m_frame; |
|||
}; |
|||
|
|||
#endif /* PROPERTIES_PANEL_H */ |
@ -0,0 +1,112 @@ |
|||
/* |
|||
* This program source code file is part of KICAD, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2020 CERN |
|||
* @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 PG_PROPERTIES_H |
|||
#define PG_PROPERTIES_H |
|||
|
|||
#include <wx/propgrid/propgrid.h> |
|||
#include <wx/propgrid/property.h> |
|||
#include <wx/propgrid/props.h> |
|||
#include <common.h> |
|||
|
|||
class PROPERTY_BASE; |
|||
class REGEX_VALIDATOR; |
|||
|
|||
wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty ); |
|||
|
|||
///> Customized abstract wxPGProperty class to handle coordinate/size units |
|||
class PGPROPERTY_DISTANCE |
|||
{ |
|||
public: |
|||
PGPROPERTY_DISTANCE( const wxString& aRegEx ); |
|||
virtual ~PGPROPERTY_DISTANCE() = 0; |
|||
|
|||
protected: |
|||
bool StringToDistance( wxVariant& aVariant, const wxString& aText, int aArgFlags = 0 ) const; |
|||
wxString DistanceToString( wxVariant& aVariant, int aArgFlags = 0 ) const; |
|||
|
|||
std::unique_ptr<REGEX_VALIDATOR> m_regExValidator; |
|||
}; |
|||
|
|||
|
|||
class PGPROPERTY_SIZE : public wxUIntProperty, public PGPROPERTY_DISTANCE |
|||
{ |
|||
public: |
|||
PGPROPERTY_SIZE( const wxString& aLabel = wxPG_LABEL, const wxString& aName = wxPG_LABEL, |
|||
long aValue = 0 ); |
|||
|
|||
bool StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags = 0 ) const override |
|||
{ |
|||
return StringToDistance( aVariant, aText, aArgFlags ); |
|||
} |
|||
|
|||
wxString ValueToString( wxVariant& aVariant, int aArgFlags = 0 ) const override |
|||
{ |
|||
return DistanceToString( aVariant, aArgFlags ); |
|||
} |
|||
|
|||
wxValidator* DoGetValidator() const override; |
|||
}; |
|||
|
|||
|
|||
class PGPROPERTY_COORD : public wxIntProperty, public PGPROPERTY_DISTANCE |
|||
{ |
|||
public: |
|||
PGPROPERTY_COORD( const wxString& aLabel = wxPG_LABEL, const wxString& aName = wxPG_LABEL, |
|||
long aValue = 0 ); |
|||
|
|||
bool StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags = 0 ) const override |
|||
{ |
|||
return StringToDistance( aVariant, aText, aArgFlags ); |
|||
} |
|||
|
|||
wxString ValueToString( wxVariant& aVariant, int aArgFlags = 0 ) const override |
|||
{ |
|||
return DistanceToString( aVariant, aArgFlags ); |
|||
} |
|||
|
|||
wxValidator* DoGetValidator() const override; |
|||
}; |
|||
|
|||
|
|||
///> Customized wxPGProperty class to handle angles |
|||
class PGPROPERTY_ANGLE : public wxFloatProperty |
|||
{ |
|||
public: |
|||
PGPROPERTY_ANGLE( const wxString& aLabel = wxPG_LABEL, const wxString& aName = wxPG_LABEL, |
|||
double aValue = 0 ) |
|||
: wxFloatProperty( aLabel, aName, aValue ), m_scale( 1.0 ) |
|||
{ |
|||
} |
|||
|
|||
bool StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags = 0 ) const override; |
|||
wxString ValueToString( wxVariant& aVariant, int aArgFlags = 0 ) const override; |
|||
|
|||
void SetScale( double aScale ) |
|||
{ |
|||
m_scale = aScale; |
|||
} |
|||
|
|||
protected: |
|||
///> Scale factor to convert between raw and displayed value |
|||
double m_scale; |
|||
}; |
|||
|
|||
#endif /* PG_PROPERTIES_H */ |
@ -0,0 +1,118 @@ |
|||
/*
|
|||
* This program source code file is part of KICAD, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2020 CERN |
|||
* @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 "pcb_properties_panel.h"
|
|||
|
|||
#include <pcb_edit_frame.h>
|
|||
#include <tool/tool_manager.h>
|
|||
#include <tools/pcb_selection_tool.h>
|
|||
#include <property_mgr.h>
|
|||
#include <board_commit.h>
|
|||
#include <board_connected_item.h>
|
|||
#include <pg_properties.h>
|
|||
#include <pcb_shape.h>
|
|||
|
|||
|
|||
PCB_PROPERTIES_PANEL::PCB_PROPERTIES_PANEL( wxWindow* aParent, PCB_EDIT_FRAME* aFrame ) |
|||
: PROPERTIES_PANEL( aParent, aFrame ), m_frame( aFrame ), m_propMgr( PROPERTY_MANAGER::Instance() ) |
|||
{ |
|||
m_propMgr.Rebuild(); |
|||
} |
|||
|
|||
|
|||
void PCB_PROPERTIES_PANEL::Update() |
|||
{ |
|||
PCB_SELECTION_TOOL* selectionTool = m_frame->GetToolManager()->GetTool<PCB_SELECTION_TOOL>(); |
|||
const SELECTION& selection = selectionTool->GetSelection(); |
|||
|
|||
// TODO perhaps it could be called less often? use PROPERTIES_TOOL and catch MODEL_RELOAD?
|
|||
updateLists( static_cast<PCB_EDIT_FRAME*>( m_frame )->GetBoard() ); |
|||
update( selection ); |
|||
} |
|||
|
|||
|
|||
wxPGProperty* PCB_PROPERTIES_PANEL::createPGProperty( const PROPERTY_BASE* aProperty ) const |
|||
{ |
|||
return PGPropertyFactory( aProperty ); |
|||
} |
|||
|
|||
|
|||
void PCB_PROPERTIES_PANEL::valueChanged( wxPropertyGridEvent& aEvent ) |
|||
{ |
|||
PCB_SELECTION_TOOL* selectionTool = m_frame->GetToolManager()->GetTool<PCB_SELECTION_TOOL>(); |
|||
const SELECTION& selection = selectionTool->GetSelection(); |
|||
BOARD_ITEM* firstItem = static_cast<BOARD_ITEM*>( selection.Front() ); |
|||
PROPERTY_BASE* property = m_propMgr.GetProperty( TYPE_HASH( *firstItem ), aEvent.GetPropertyName() ); |
|||
wxVariant newValue = aEvent.GetPropertyValue(); |
|||
BOARD_COMMIT changes( m_frame ); |
|||
|
|||
for( EDA_ITEM* edaItem : selection ) |
|||
{ |
|||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( edaItem ); |
|||
changes.Modify( item ); |
|||
item->Set( property, newValue ); |
|||
} |
|||
|
|||
changes.Push( _( "Change property" ) ); |
|||
m_frame->Refresh(); |
|||
} |
|||
|
|||
|
|||
void PCB_PROPERTIES_PANEL::updateLists( const BOARD* aBoard ) |
|||
{ |
|||
wxPGChoices layersAll, layersCu, layersNonCu, nets; |
|||
|
|||
// Regenerate all layers
|
|||
for( LSEQ layerSeq = aBoard->GetEnabledLayers().UIOrder(); layerSeq; ++layerSeq ) |
|||
layersAll.Add( LSET::Name( *layerSeq ), *layerSeq ); |
|||
|
|||
m_propMgr.GetProperty( TYPE_HASH( BOARD_ITEM ), _( "Layer" ) )->SetChoices( layersAll ); |
|||
|
|||
|
|||
// Regenerate non-copper layers
|
|||
for( LSEQ layerSeq = LSET( LSET::AllNonCuMask() & aBoard->GetEnabledLayers() ).UIOrder(); layerSeq; ++layerSeq ) |
|||
layersNonCu.Add( LSET::Name( *layerSeq ), *layerSeq ); |
|||
|
|||
m_propMgr.GetProperty( TYPE_HASH( PCB_SHAPE ), _( "Layer" ) )->SetChoices( layersNonCu ); |
|||
|
|||
|
|||
// Regenerate copper layers
|
|||
for( LSEQ layerSeq = LSET( LSET::AllCuMask() & aBoard->GetEnabledLayers() ).UIOrder(); layerSeq; ++layerSeq ) |
|||
layersCu.Add( LSET::Name( *layerSeq ), *layerSeq ); |
|||
|
|||
m_propMgr.GetProperty( TYPE_HASH( BOARD_CONNECTED_ITEM ), _( "Layer" ) )->SetChoices( layersCu ); |
|||
|
|||
|
|||
// Regenerate non-copper layers
|
|||
for( LSEQ layerSeq = LSET( LSET::AllNonCuMask() & aBoard->GetEnabledLayers() ).UIOrder(); layerSeq; ++layerSeq ) |
|||
layersNonCu.Add( LSET::Name( *layerSeq ), *layerSeq ); |
|||
|
|||
m_propMgr.GetProperty( TYPE_HASH( PCB_SHAPE ), _( "Layer" ) )->SetChoices( layersNonCu ); |
|||
|
|||
|
|||
// Regenerate nets
|
|||
for( const auto& netinfo : aBoard->GetNetInfo().NetsByNetcode() ) |
|||
{ |
|||
nets.Add( netinfo.second->GetNetname(), netinfo.first ); |
|||
} |
|||
|
|||
auto netProperty = m_propMgr.GetProperty( TYPE_HASH( BOARD_CONNECTED_ITEM ), _( "Net" ) ); |
|||
netProperty->SetChoices( nets ); |
|||
} |
@ -0,0 +1,56 @@ |
|||
/* |
|||
* This program source code file is part of KICAD, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2020 CERN |
|||
* @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 PCB_PROPERTIES_PANEL_H |
|||
#define PCB_PROPERTIES_PANEL_H |
|||
|
|||
#include <widgets/properties_panel.h> |
|||
|
|||
class SELECTION; |
|||
class BOARD; |
|||
class PCB_EDIT_FRAME; |
|||
class PROPERTY_MANAGER; |
|||
|
|||
class PCB_PROPERTIES_PANEL : public PROPERTIES_PANEL |
|||
{ |
|||
public: |
|||
PCB_PROPERTIES_PANEL( wxWindow* aParent, PCB_EDIT_FRAME* aFrame ); |
|||
|
|||
virtual ~PCB_PROPERTIES_PANEL() |
|||
{ |
|||
} |
|||
|
|||
void Update() override; |
|||
|
|||
protected: |
|||
wxPGProperty* createPGProperty( const PROPERTY_BASE* aProperty ) const override; |
|||
|
|||
void valueChanged( wxPropertyGridEvent& aEvent ) override; |
|||
|
|||
///> Regenerates caches storing layer and net names |
|||
void updateLists( const BOARD* aBoard ); |
|||
|
|||
PCB_EDIT_FRAME* m_frame; |
|||
PROPERTY_MANAGER& m_propMgr; |
|||
|
|||
wxPGChoices m_nets; |
|||
}; |
|||
|
|||
#endif /* PCB_PROPERTIES_PANEL_H */ |
@ -0,0 +1,708 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2004-2017 Jean-Pierre Charras, jean-pierre.charras@gpisa-lab.inpg.fr |
|||
* Copyright (C) 2010-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> |
|||
* Copyright (C) 2010-2017 KiCad Developers, see change_log.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 2 |
|||
* 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, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
|
|||
#include <class_board.h>
|
|||
#include <fctsys.h>
|
|||
#include <gal/graphics_abstraction_layer.h>
|
|||
#include <layer_widget.h>
|
|||
#include <macros.h>
|
|||
#include <menus_helpers.h>
|
|||
#include <pcb_display_options.h>
|
|||
#include <pcb_edit_frame.h>
|
|||
#include <pcb_layer_widget.h>
|
|||
#include <pcb_painter.h>
|
|||
#include <pcbnew_id.h>
|
|||
#include <pcbnew_settings.h>
|
|||
#include <pgm_base.h>
|
|||
#include <settings/color_settings.h>
|
|||
#include <tool/tool_manager.h>
|
|||
#include <view/view.h>
|
|||
#include <widgets/indicator_icon.h>
|
|||
|
|||
|
|||
/// This is a read only template that is copied and modified before adding to LAYER_WIDGET
|
|||
const LAYER_WIDGET::ROW PCB_LAYER_WIDGET::s_render_rows[] = { |
|||
|
|||
#define RR LAYER_WIDGET::ROW // Render Row abbreviation to reduce source width
|
|||
#define NOCOLOR COLOR4D::UNSPECIFIED // specify rows that do not have a color selector icon
|
|||
|
|||
// text id color tooltip
|
|||
RR( _( "Footprints Front" ), LAYER_MOD_FR, NOCOLOR, _( "Show footprints that are on board's front") ), |
|||
RR( _( "Footprints Back" ), LAYER_MOD_BK, NOCOLOR, _( "Show footprints that are on board's back") ), |
|||
RR( _( "Values" ), LAYER_MOD_VALUES, NOCOLOR, _( "Show footprint values") ), |
|||
RR( _( "Reference Designators" ),LAYER_MOD_REFERENCES, NOCOLOR, _( "Show footprint reference designators") ), |
|||
RR( _( "Footprint Text Front" ), LAYER_MOD_TEXT_FR, NOCOLOR, _( "Show footprint text on board's front" ) ), |
|||
RR( _( "Footprint Text Back" ), LAYER_MOD_TEXT_BK, NOCOLOR, _( "Show footprint text on board's back" ) ), |
|||
RR( _( "Hidden Text" ), LAYER_MOD_TEXT_INVISIBLE, WHITE, _( "Show footprint text marked as invisible" ) ), |
|||
RR( _( "Pads Front" ), LAYER_PAD_FR, WHITE, _( "Show footprint pads on board's front" ) ), |
|||
RR( _( "Pads Back" ), LAYER_PAD_BK, WHITE, _( "Show footprint pads on board's back" ) ), |
|||
RR( _( "Through Hole Pads" ), LAYER_PADS_TH, YELLOW, _( "Show through hole pads in specific color") ), |
|||
RR(), |
|||
RR( _( "Tracks" ), LAYER_TRACKS, NOCOLOR, _( "Show tracks" ) ), |
|||
RR( _( "Through Via" ), LAYER_VIA_THROUGH, WHITE, _( "Show through vias" ) ), |
|||
RR( _( "Bl/Buried Via" ), LAYER_VIA_BBLIND, WHITE, _( "Show blind or buried vias" ) ), |
|||
RR( _( "Micro Via" ), LAYER_VIA_MICROVIA, WHITE, _( "Show micro vias") ), |
|||
RR( _( "Non Plated Holes" ), LAYER_NON_PLATEDHOLES, WHITE, _( "Show non plated holes in specific color") ), |
|||
RR(), |
|||
RR( _( "Ratsnest" ), LAYER_RATSNEST, WHITE, _( "Show unconnected nets as a ratsnest") ), |
|||
RR( _( "No-Connects" ), LAYER_NO_CONNECTS, BLUE, _( "Show a marker on pads which have no net connected" ) ), |
|||
RR( _( "DRC Warnings" ), LAYER_DRC_WARNING, YELLOW, _( "DRC violations with a Warning severity" ) ), |
|||
RR( _( "DRC Errors" ), LAYER_DRC_ERROR, PURERED, _( "DRC violations with an Error severity" ) ), |
|||
RR( _( "Anchors" ), LAYER_ANCHOR, WHITE, _( "Show footprint and text origins as a cross" ) ), |
|||
RR( _( "Worksheet" ), LAYER_WORKSHEET, DARKRED, _( "Show worksheet") ), |
|||
RR( _( "Cursor" ), LAYER_CURSOR, WHITE, _( "PCB Cursor" ), true, false ), |
|||
RR( _( "Aux Items" ), LAYER_AUX_ITEMS, WHITE, _( "Auxiliary items (rulers, assistants, axes, etc.)" ), true, false ), |
|||
RR( _( "Grid" ), LAYER_GRID, WHITE, _( "Show the (x,y) grid dots" ) ), |
|||
RR( _( "Background" ), LAYER_PCB_BACKGROUND, BLACK, _( "PCB Background" ), true, false ) |
|||
}; |
|||
|
|||
static int s_allowed_in_FpEditor[] = |
|||
{ |
|||
LAYER_MOD_TEXT_INVISIBLE, |
|||
LAYER_NON_PLATEDHOLES, |
|||
LAYER_PADS_TH, |
|||
LAYER_PAD_FR, |
|||
LAYER_PAD_BK, |
|||
LAYER_MOD_VALUES, |
|||
LAYER_MOD_REFERENCES, |
|||
LAYER_CURSOR, |
|||
LAYER_AUX_ITEMS, |
|||
LAYER_GRID, |
|||
LAYER_PCB_BACKGROUND |
|||
}; |
|||
|
|||
|
|||
PCB_LAYER_WIDGET::PCB_LAYER_WIDGET( wxWindow* aParent, PCB_BASE_FRAME* aFrame, wxWindow* aFocusOwner, |
|||
bool aFpEditorMode ) : |
|||
LAYER_WIDGET( aParent, aFocusOwner ), |
|||
myframe( aFrame ) |
|||
{ |
|||
m_alwaysShowActiveCopperLayer = false; |
|||
m_fp_editor_mode = aFpEditorMode; |
|||
|
|||
// Update default tabs labels
|
|||
SetLayersManagerTabsText(); |
|||
|
|||
//-----<Popup menu>-------------------------------------------------
|
|||
// handle the popup menu over the layer window.
|
|||
m_LayerScrolledWindow->Connect( wxEVT_RIGHT_DOWN, |
|||
wxMouseEventHandler( PCB_LAYER_WIDGET::onRightDownLayers ), NULL, this ); |
|||
|
|||
// since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
|
|||
// and not m_LayerScrolledWindow->Connect()
|
|||
|
|||
Connect( ID_SHOW_ALL_COPPER_LAYERS, ID_LAST_VALUE - 1, |
|||
wxEVT_COMMAND_MENU_SELECTED, |
|||
wxCommandEventHandler( PCB_LAYER_WIDGET::onPopupSelection ), NULL, this ); |
|||
} |
|||
|
|||
|
|||
COLOR4D PCB_LAYER_WIDGET::getBackgroundLayerColor() |
|||
{ |
|||
return myframe->GetColorSettings()->GetColor( LAYER_PCB_BACKGROUND ); |
|||
} |
|||
|
|||
|
|||
bool PCB_LAYER_WIDGET::isAllowedInFpMode( int aId ) |
|||
{ |
|||
for( unsigned ii = 0; ii < arrayDim( s_allowed_in_FpEditor ); ii++ ) |
|||
if( s_allowed_in_FpEditor[ii] == aId ) |
|||
return true; |
|||
|
|||
return false; |
|||
} |
|||
|
|||
|
|||
bool PCB_LAYER_WIDGET::isLayerAllowedInFpMode( PCB_LAYER_ID aLayer ) |
|||
{ |
|||
static LSET allowed = LSET::AllTechMask(); |
|||
allowed.set( F_Cu ).set( B_Cu ); |
|||
return allowed.test( aLayer ); |
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::AddRightClickMenuItems( wxMenu& menu ) |
|||
{ |
|||
AddMenuItem( &menu, ID_SHOW_ALL_COPPER_LAYERS, |
|||
_( "Show All Copper Layers" ), |
|||
KiBitmap( select_layer_pair_xpm ) ); |
|||
AddMenuItem( &menu, ID_HIDE_ALL_COPPER_LAYERS, |
|||
_( "Hide All Copper Layers" ), |
|||
KiBitmap( show_no_copper_layers_xpm ) ); |
|||
|
|||
menu.AppendSeparator(); |
|||
|
|||
AddMenuItem( &menu, ID_HIDE_ALL_COPPER_LAYERS_BUT_ACTIVE, |
|||
_( "Hide All Copper Layers But Active" ), |
|||
KiBitmap( select_w_layer_xpm ) ); |
|||
AddMenuItem( &menu, ID_ALWAYS_HIDE_ALL_COPPER_LAYERS_BUT_ACTIVE, |
|||
_( "Always Hide All Copper Layers But Active" ), |
|||
KiBitmap( select_w_layer_xpm ) ); |
|||
|
|||
menu.AppendSeparator(); |
|||
|
|||
AddMenuItem( &menu, ID_SHOW_ALL_NON_COPPER, |
|||
_( "Show All Non Copper Layers" ), |
|||
KiBitmap( select_w_layer_xpm ) ); |
|||
AddMenuItem( &menu, ID_HIDE_ALL_NON_COPPER, |
|||
_( "Hide All Non Copper Layers" ), |
|||
KiBitmap( show_no_copper_layers_xpm ) ); |
|||
|
|||
menu.AppendSeparator(); |
|||
|
|||
AddMenuItem( &menu, ID_SHOW_ALL_LAYERS, _( "Show All Layers" ), |
|||
KiBitmap( show_all_layers_xpm ) ); |
|||
AddMenuItem( &menu, ID_SHOW_NO_LAYERS, _( "Hide All Layers" ), |
|||
KiBitmap( show_no_layers_xpm ) ); |
|||
|
|||
menu.AppendSeparator(); |
|||
|
|||
AddMenuItem( &menu, ID_SHOW_ONLY_FRONT_ASSEMBLY, _( "Show Only Front Assembly Layers" ), |
|||
KiBitmap( shape_3d_xpm ) ); |
|||
|
|||
AddMenuItem( &menu, ID_SHOW_ONLY_FRONT, _( "Show Only Front Layers" ), |
|||
KiBitmap( show_all_front_layers_xpm ) ); |
|||
|
|||
// Only show the internal layer option if internal layers are enabled
|
|||
if( myframe->GetBoard()->GetCopperLayerCount() > 2 ) |
|||
{ |
|||
AddMenuItem( &menu, ID_SHOW_ONLY_INNER, _( "Show Only Inner Layers" ), |
|||
KiBitmap( show_all_copper_layers_xpm ) ); |
|||
} |
|||
|
|||
AddMenuItem( &menu, ID_SHOW_ONLY_BACK, _( "Show Only Back Layers" ), |
|||
KiBitmap( show_all_back_layers_xpm ) ); |
|||
|
|||
AddMenuItem( &menu, ID_SHOW_ONLY_BACK_ASSEMBLY, _( "Show Only Back Assembly Layers" ), |
|||
KiBitmap( shape_3d_back_xpm ) ); |
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event ) |
|||
{ |
|||
wxMenu menu; |
|||
|
|||
AddRightClickMenuItems( menu ); |
|||
PopupMenu( &menu ); |
|||
|
|||
passOnFocus(); |
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event ) |
|||
{ |
|||
// Force the active layer to be visible
|
|||
bool forceActiveLayer = false; |
|||
|
|||
// Reset the always show property
|
|||
m_alwaysShowActiveCopperLayer = false; |
|||
|
|||
// Make a distinction between the layers we want to enable and those we
|
|||
// want to disable explictly. That way we can either or the current layerset
|
|||
// or operate on all layers.
|
|||
LSET layersToShow; |
|||
LSET layersToHide; |
|||
|
|||
switch( event.GetId() ) |
|||
{ |
|||
case ID_SHOW_NO_LAYERS: |
|||
layersToHide = LSET::AllLayersMask(); |
|||
break; |
|||
|
|||
case ID_SHOW_ALL_LAYERS: |
|||
layersToShow = LSET::AllLayersMask(); |
|||
break; |
|||
|
|||
case ID_SHOW_ALL_COPPER_LAYERS: |
|||
layersToShow = LSET::AllCuMask(); |
|||
break; |
|||
|
|||
case ID_ALWAYS_HIDE_ALL_COPPER_LAYERS_BUT_ACTIVE: |
|||
m_alwaysShowActiveCopperLayer = true; |
|||
KI_FALLTHROUGH; |
|||
|
|||
case ID_HIDE_ALL_COPPER_LAYERS_BUT_ACTIVE: |
|||
forceActiveLayer = true; |
|||
KI_FALLTHROUGH; |
|||
|
|||
case ID_HIDE_ALL_COPPER_LAYERS: |
|||
layersToHide = LSET::AllCuMask(); |
|||
break; |
|||
|
|||
case ID_HIDE_ALL_NON_COPPER: |
|||
layersToHide = LSET::AllNonCuMask(); |
|||
break; |
|||
|
|||
case ID_SHOW_ALL_NON_COPPER: |
|||
layersToShow = LSET::AllNonCuMask(); |
|||
break; |
|||
|
|||
case ID_SHOW_ONLY_FRONT_ASSEMBLY: |
|||
// Include the edgecuts layer as well as the front assembly layers and hide the other layers
|
|||
layersToShow = LSET::FrontAssembly().set( Edge_Cuts ); |
|||
layersToHide = ~layersToShow; |
|||
myframe->SetActiveLayer( F_SilkS ); |
|||
break; |
|||
|
|||
case ID_SHOW_ONLY_FRONT: |
|||
// Include the edgecuts layer as well as the front layers and hide the other layers
|
|||
layersToShow = LSET::FrontMask().set( Edge_Cuts ); |
|||
layersToHide = ~layersToShow; |
|||
break; |
|||
|
|||
case ID_SHOW_ONLY_INNER: |
|||
// Include the edgecuts layer as well as the internal layers and hide the other layers
|
|||
layersToShow = LSET::InternalCuMask().set( Edge_Cuts ); |
|||
layersToHide = ~layersToShow; |
|||
break; |
|||
|
|||
case ID_SHOW_ONLY_BACK: |
|||
// Include the edgecuts layer as well as the back layers and hide the other layers
|
|||
layersToShow = LSET::BackMask().set( Edge_Cuts ); |
|||
layersToHide = ~layersToShow; |
|||
break; |
|||
|
|||
case ID_SHOW_ONLY_BACK_ASSEMBLY: |
|||
// Include the edgecuts layer as well as the back assembly layers and hide the other layers
|
|||
layersToShow = LSET::BackAssembly().set( Edge_Cuts ); |
|||
layersToHide = ~layersToShow; |
|||
myframe->SetActiveLayer( B_SilkS ); |
|||
break; |
|||
} |
|||
|
|||
int rowCount = GetLayerRowCount(); |
|||
|
|||
for( int row = 0; row < rowCount; ++row ) |
|||
{ |
|||
wxCheckBox* cb = static_cast<wxCheckBox*>( getLayerComp( row, COLUMN_COLOR_LYR_CB ) ); |
|||
PCB_LAYER_ID layer = ToLAYER_ID( getDecodedId( cb->GetId() ) ); |
|||
|
|||
bool visible = cb->GetValue(); |
|||
|
|||
if( layersToShow.Contains( layer ) ) |
|||
visible = true; |
|||
|
|||
if( layersToHide.Contains( layer ) ) |
|||
visible = false; |
|||
|
|||
// Force the active layer in the editor to be visible
|
|||
if( forceActiveLayer && ( layer == myframe->GetActiveLayer() ) ) |
|||
visible = true; |
|||
|
|||
cb->SetValue( visible ); |
|||
OnLayerVisible( layer, visible, false ); |
|||
} |
|||
|
|||
// Refresh the drawing canvas
|
|||
myframe->GetCanvas()->Refresh(); |
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::SetLayersManagerTabsText() |
|||
{ |
|||
m_notebook->SetPageText( 0, _( "Layers" ) ); |
|||
m_notebook->SetPageText( 1, _( "Items" ) ); |
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::ReFillRender() |
|||
{ |
|||
BOARD* board = myframe->GetBoard(); |
|||
|
|||
ClearRenderRows(); |
|||
|
|||
// Add "Items" tab rows to LAYER_WIDGET, after setting color and checkbox state.
|
|||
// Because s_render_rows is created static, we must explicitly call
|
|||
// wxGetTranslation for texts which are internationalized (tool tips
|
|||
// and item names)
|
|||
for( unsigned row=0; row<arrayDim(s_render_rows); ++row ) |
|||
{ |
|||
LAYER_WIDGET::ROW renderRow = s_render_rows[row]; |
|||
|
|||
if( m_fp_editor_mode && !isAllowedInFpMode( renderRow.id ) ) |
|||
continue; |
|||
|
|||
if( !renderRow.spacer ) |
|||
{ |
|||
renderRow.tooltip = wxGetTranslation( s_render_rows[row].tooltip ); |
|||
renderRow.rowName = wxGetTranslation( s_render_rows[row].rowName ); |
|||
|
|||
if( renderRow.color != COLOR4D::UNSPECIFIED ) // does this row show a color?
|
|||
{ |
|||
// this window frame must have an established BOARD, i.e. after SetBoard()
|
|||
renderRow.color = myframe->GetColorSettings()->GetColor( |
|||
static_cast<GAL_LAYER_ID>( renderRow.id ) ); |
|||
renderRow.defaultColor = myframe->GetColorSettings()->GetDefaultColor( |
|||
static_cast<GAL_LAYER_ID>( renderRow.id ) ); |
|||
} |
|||
|
|||
if( renderRow.id == LAYER_RATSNEST ) |
|||
renderRow.state = myframe->GetDisplayOptions().m_ShowGlobalRatsnest; |
|||
else if( renderRow.id == LAYER_GRID ) |
|||
renderRow.state = myframe->IsGridVisible(); |
|||
else |
|||
renderRow.state = board->IsElementVisible( |
|||
static_cast<GAL_LAYER_ID>( renderRow.id ) ); |
|||
} |
|||
|
|||
AppendRenderRow( renderRow ); |
|||
} |
|||
|
|||
UpdateLayouts(); |
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::SyncLayerVisibilities() |
|||
{ |
|||
BOARD* board = myframe->GetBoard(); |
|||
int count = GetLayerRowCount(); |
|||
|
|||
for( int row=0; row<count; ++row ) |
|||
{ |
|||
// this utilizes more implementation knowledge than ideal, eventually
|
|||
// add member ROW getRow() or similar to base LAYER_WIDGET.
|
|||
|
|||
wxWindow* w = getLayerComp( row, COLUMN_ICON_ACTIVE ); |
|||
|
|||
PCB_LAYER_ID layerId = ToLAYER_ID( getDecodedId( w->GetId() ) ); |
|||
|
|||
// this does not fire a UI event
|
|||
setLayerCheckbox( layerId, board->IsLayerVisible( layerId ) ); |
|||
} |
|||
} |
|||
|
|||
|
|||
#define ALPHA_EPSILON 0.04
|
|||
|
|||
void PCB_LAYER_WIDGET::SyncLayerAlphaIndicators() |
|||
{ |
|||
int count = GetLayerRowCount(); |
|||
TOOL_MANAGER* mgr = myframe->GetToolManager(); |
|||
KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*>( mgr->GetView()->GetPainter() ); |
|||
KIGFX::PCB_RENDER_SETTINGS* settings = painter->GetSettings(); |
|||
|
|||
for( int row = 0; row < count; ++row ) |
|||
{ |
|||
// this utilizes more implementation knowledge than ideal, eventually
|
|||
// add member ROW getRow() or similar to base LAYER_WIDGET.
|
|||
|
|||
wxWindow* w = getLayerComp( row, COLUMN_ICON_ACTIVE ); |
|||
PCB_LAYER_ID layerId = ToLAYER_ID( getDecodedId( w->GetId() ) ); |
|||
KIGFX::COLOR4D screenColor = settings->GetLayerColor( layerId ); |
|||
|
|||
COLOR_SWATCH* swatch = static_cast<COLOR_SWATCH*>( getLayerComp( row, COLUMN_COLORBM ) ); |
|||
KIGFX::COLOR4D layerColor = swatch->GetSwatchColor(); |
|||
|
|||
INDICATOR_ICON* indicator = static_cast<INDICATOR_ICON*>( getLayerComp( row, COLUMN_ALPHA_INDICATOR ) ); |
|||
|
|||
if( std::abs( screenColor.a - layerColor.a ) > ALPHA_EPSILON ) |
|||
{ |
|||
if( screenColor.a < layerColor.a ) |
|||
indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::DOWN ); |
|||
else |
|||
indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::UP ); |
|||
} |
|||
else |
|||
indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::OFF ); |
|||
} |
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::SyncLayerColors() |
|||
{ |
|||
COLOR_SETTINGS* cs = myframe->GetColorSettings(); |
|||
|
|||
COLOR4D bg = cs->GetColor( LAYER_PCB_BACKGROUND ); |
|||
|
|||
int count = GetLayerRowCount(); |
|||
int row; |
|||
int col = 1; // bitmap button is column 1 in layers tab
|
|||
|
|||
for( row = 0; row < count; ++row ) |
|||
{ |
|||
COLOR_SWATCH* swatch = dynamic_cast<COLOR_SWATCH*>( getLayerComp( row, col ) ); |
|||
|
|||
if( swatch ) |
|||
{ |
|||
swatch->SetSwatchBackground( bg ); |
|||
swatch->SetSwatchColor( cs->GetColor( getDecodedId( swatch->GetId() ) ), false ); |
|||
} |
|||
} |
|||
|
|||
count = GetRenderRowCount(); |
|||
col = 0; // bitmap button is column 0 in render tab
|
|||
|
|||
for( row = 0; row < count; ++row ) |
|||
{ |
|||
COLOR_SWATCH* swatch = dynamic_cast<COLOR_SWATCH*>( getRenderComp( row, col ) ); |
|||
|
|||
if( swatch ) |
|||
{ |
|||
swatch->SetSwatchBackground( bg ); |
|||
swatch->SetSwatchColor( cs->GetColor( getDecodedId( swatch->GetId() ) ), false ); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::ReFill() |
|||
{ |
|||
BOARD* brd = myframe->GetBoard(); |
|||
LSET enabled = brd->GetEnabledLayers(); |
|||
|
|||
ClearLayerRows(); |
|||
|
|||
wxString dsc; |
|||
|
|||
// show all coppers first, with front on top, back on bottom, then technical layers
|
|||
for( LSEQ cu_stack = enabled.CuStack(); cu_stack; ++cu_stack ) |
|||
{ |
|||
PCB_LAYER_ID layer = *cu_stack; |
|||
|
|||
switch( layer ) |
|||
{ |
|||
case F_Cu: |
|||
dsc = _( "Front copper layer" ); |
|||
break; |
|||
|
|||
case B_Cu: |
|||
dsc = _( "Back copper layer" ); |
|||
break; |
|||
|
|||
default: |
|||
dsc = _( "Inner copper layer" ); |
|||
break; |
|||
} |
|||
|
|||
AppendLayerRow( LAYER_WIDGET::ROW( brd->GetLayerName( layer ), layer, |
|||
myframe->GetColorSettings()->GetColor( layer ), dsc, true, true, |
|||
myframe->GetColorSettings()->GetDefaultColor( layer ) ) ); |
|||
|
|||
if( m_fp_editor_mode && LSET::ForbiddenFootprintLayers().test( layer ) ) |
|||
{ |
|||
getLayerComp( GetLayerRowCount()-1, COLUMN_COLOR_LYRNAME )->Enable( false ); |
|||
getLayerComp( GetLayerRowCount()-1, COLUMN_COLORBM )->SetToolTip( wxEmptyString ); |
|||
} |
|||
} |
|||
|
|||
UpdateLayouts(); |
|||
|
|||
|
|||
// technical layers are shown in this order:
|
|||
// Because they are static, wxGetTranslation must be explicitly
|
|||
// called for tooltips.
|
|||
static const struct { |
|||
PCB_LAYER_ID layerId; |
|||
wxString tooltip; |
|||
} non_cu_seq[] = { |
|||
{ F_Adhes, _( "Adhesive on board's front" ) }, |
|||
{ B_Adhes, _( "Adhesive on board's back" ) }, |
|||
{ F_Paste, _( "Solder paste on board's front" ) }, |
|||
{ B_Paste, _( "Solder paste on board's back" ) }, |
|||
{ F_SilkS, _( "Silkscreen on board's front" ) }, |
|||
{ B_SilkS, _( "Silkscreen on board's back" ) }, |
|||
{ F_Mask, _( "Solder mask on board's front" ) }, |
|||
{ B_Mask, _( "Solder mask on board's back" ) }, |
|||
{ Dwgs_User, _( "Explanatory drawings" ) }, |
|||
{ Cmts_User, _( "Explanatory comments" ) }, |
|||
{ Eco1_User, _( "User defined meaning" ) }, |
|||
{ Eco2_User, _( "User defined meaning" ) }, |
|||
{ Edge_Cuts, _( "Board's perimeter definition" ) }, |
|||
{ Margin, _( "Board's edge setback outline" ) }, |
|||
{ F_CrtYd, _( "Footprint courtyards on board's front" ) }, |
|||
{ B_CrtYd, _( "Footprint courtyards on board's back" ) }, |
|||
{ F_Fab, _( "Footprint assembly on board's front" ) }, |
|||
{ B_Fab, _( "Footprint assembly on board's back" ) } |
|||
}; |
|||
|
|||
for( unsigned i=0; i<arrayDim( non_cu_seq ); ++i ) |
|||
{ |
|||
PCB_LAYER_ID layer = non_cu_seq[i].layerId; |
|||
|
|||
if( !enabled[layer] ) |
|||
continue; |
|||
|
|||
AppendLayerRow( LAYER_WIDGET::ROW( brd->GetLayerName( layer ), layer, |
|||
myframe->GetColorSettings()->GetColor( layer ), |
|||
wxGetTranslation( non_cu_seq[i].tooltip ), true, true, |
|||
myframe->GetColorSettings()->GetDefaultColor( layer ) ) ); |
|||
|
|||
if( m_fp_editor_mode && LSET::ForbiddenFootprintLayers().test( layer ) ) |
|||
{ |
|||
getLayerComp( GetLayerRowCount()-1, COLUMN_COLOR_LYRNAME )->Enable( false ); |
|||
getLayerComp( GetLayerRowCount()-1, COLUMN_COLORBM )->SetToolTip( wxEmptyString ); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
//-----<LAYER_WIDGET callbacks>-------------------------------------------
|
|||
|
|||
void PCB_LAYER_WIDGET::OnLayerColorChange( int aLayer, COLOR4D aColor ) |
|||
{ |
|||
COLOR_SETTINGS* cs = myframe->GetColorSettings(); |
|||
cs->SetColor( aLayer, aColor ); |
|||
|
|||
myframe->GetCanvas()->UpdateColors(); |
|||
|
|||
KIGFX::VIEW* view = myframe->GetCanvas()->GetView(); |
|||
view->UpdateLayerColor( aLayer ); |
|||
view->UpdateLayerColor( GetNetnameLayer( aLayer ) ); |
|||
|
|||
myframe->ReCreateHToolbar(); |
|||
|
|||
myframe->GetCanvas()->Refresh(); |
|||
|
|||
if( aLayer == LAYER_PCB_BACKGROUND ) |
|||
myframe->SetDrawBgColor( aColor ); |
|||
} |
|||
|
|||
|
|||
bool PCB_LAYER_WIDGET::OnLayerSelect( int aLayer ) |
|||
{ |
|||
// the layer change from the PCB_LAYER_WIDGET can be denied by returning
|
|||
// false from this function.
|
|||
PCB_LAYER_ID layer = ToLAYER_ID( aLayer ); |
|||
|
|||
if( m_fp_editor_mode && LSET::ForbiddenFootprintLayers().test( layer ) ) |
|||
return false; |
|||
|
|||
myframe->SetActiveLayer( layer ); |
|||
|
|||
bool hcm = ( myframe->GetDisplayOptions().m_ContrastModeDisplay != |
|||
HIGH_CONTRAST_MODE::NORMAL ); |
|||
|
|||
if( m_alwaysShowActiveCopperLayer ) |
|||
OnLayerSelected(); |
|||
else if( hcm ) |
|||
myframe->GetCanvas()->Refresh(); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
|
|||
bool PCB_LAYER_WIDGET::OnLayerSelected() |
|||
{ |
|||
if( !m_alwaysShowActiveCopperLayer ) |
|||
return false; |
|||
|
|||
// postprocess after an active layer selection
|
|||
// ensure active layer visible
|
|||
wxCommandEvent event; |
|||
event.SetId( ID_ALWAYS_HIDE_ALL_COPPER_LAYERS_BUT_ACTIVE ); |
|||
onPopupSelection( event ); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal ) |
|||
{ |
|||
// In other frames than board editor, the board is a dummy board.
|
|||
// so changing board settings makes sense (and works) only for the board editor frame
|
|||
if( myframe->IsType( FRAME_PCB_EDITOR ) ) |
|||
{ |
|||
BOARD* brd = myframe->GetBoard(); |
|||
|
|||
LSET visibleLayers = brd->GetVisibleLayers(); |
|||
|
|||
if( visibleLayers.test( aLayer ) != isVisible ) |
|||
{ |
|||
visibleLayers.set( aLayer, isVisible ); |
|||
brd->SetVisibleLayers( visibleLayers ); |
|||
|
|||
if( myframe->GetCanvas() ) |
|||
myframe->GetCanvas()->GetView()->SetLayerVisible( aLayer, isVisible ); |
|||
} |
|||
} |
|||
else |
|||
if( myframe->GetCanvas() ) |
|||
myframe->GetCanvas()->GetView()->SetLayerVisible( aLayer, isVisible ); |
|||
|
|||
if( isFinal ) |
|||
myframe->GetCanvas()->Refresh(); |
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::OnLayerRightClick( wxMenu& aMenu ) |
|||
{ |
|||
AddRightClickMenuItems( aMenu ); |
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::OnRenderColorChange( int aId, COLOR4D aColor ) |
|||
{ |
|||
wxASSERT( aId > GAL_LAYER_ID_START && aId < GAL_LAYER_ID_END ); |
|||
|
|||
myframe->GetColorSettings()->SetColor( aId, aColor ); |
|||
myframe->GetCanvas()->UpdateColors(); |
|||
|
|||
KIGFX::VIEW* view = myframe->GetCanvas()->GetView(); |
|||
view->MarkTargetDirty( KIGFX::TARGET_NONCACHED ); // useful to update rastnest
|
|||
view->UpdateLayerColor( aId ); |
|||
|
|||
// plated-through-holes don't have their own color; they use the background color
|
|||
if( aId == LAYER_PCB_BACKGROUND ) |
|||
view->UpdateLayerColor( LAYER_PADS_PLATEDHOLES ); |
|||
|
|||
myframe->ReCreateHToolbar(); |
|||
myframe->GetCanvas()->ForceRefresh(); |
|||
myframe->GetCanvas()->Refresh(); |
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled ) |
|||
{ |
|||
BOARD* brd = myframe->GetBoard(); |
|||
wxASSERT( aId > GAL_LAYER_ID_START && aId < GAL_LAYER_ID_END ); |
|||
|
|||
// Grid is not set through the board visibility
|
|||
if( aId == LAYER_GRID ) |
|||
myframe->SetGridVisibility( isEnabled ); |
|||
else |
|||
brd->SetElementVisibility( static_cast<GAL_LAYER_ID>( aId ), isEnabled ); |
|||
|
|||
if( aId == LAYER_RATSNEST ) |
|||
{ |
|||
// don't touch the layers. ratsnest is enabled on per-item basis.
|
|||
myframe->GetCanvas()->GetView()->MarkTargetDirty( KIGFX::TARGET_NONCACHED ); |
|||
myframe->GetCanvas()->GetView()->SetLayerVisible( aId, true ); |
|||
|
|||
if( myframe->IsType( FRAME_PCB_EDITOR ) ) |
|||
{ |
|||
PCB_DISPLAY_OPTIONS opt = myframe->GetDisplayOptions(); |
|||
opt.m_ShowGlobalRatsnest = isEnabled; |
|||
myframe->GetCanvas()->GetView()->UpdateDisplayOptions( opt ); |
|||
} |
|||
} |
|||
else if( aId != LAYER_GRID ) |
|||
myframe->GetCanvas()->GetView()->SetLayerVisible( aId, isEnabled ); |
|||
|
|||
myframe->GetCanvas()->Refresh(); |
|||
myframe->GetCanvas()->Refresh(); |
|||
} |
|||
|
|||
//-----</LAYER_WIDGET callbacks>------------------------------------------
|
@ -0,0 +1,182 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr |
|||
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> |
|||
* Copyright (C) 2010-2018 KiCad Developers, see cAUTHORS.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 2 |
|||
* 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, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
|||
* or you may search the http://www.gnu.org website for the version 2 license, |
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
|
|||
/************************************************************/ |
|||
/* pcb_layer_widget.h : header for the layers manager */ |
|||
/************************************************************/ |
|||
|
|||
#ifndef PCB_LAYER_WIDGET_H |
|||
#define PCB_LAYER_WIDGET_H |
|||
|
|||
#include <layer_widget.h> |
|||
|
|||
/** |
|||
* PCB_LAYER_WIDGET |
|||
* is here to implement the abstract functions of LAYER_WIDGET so they |
|||
* may be tied into the PCB_EDIT_FRAME's data and so we can add a popup |
|||
* menu which is specific to PCBNEW's needs. |
|||
*/ |
|||
class PCB_LAYER_WIDGET : public LAYER_WIDGET |
|||
{ |
|||
public: |
|||
|
|||
/** |
|||
* Constructor |
|||
* @param aParent is the parent window |
|||
* @param aFocusOwner is the window that should be sent the focus after |
|||
* @param aFpEditorMode false for the board editor (default), true for fp editor |
|||
* when true, some options or layers which cannot be used in editor mode are not |
|||
* displayed |
|||
*/ |
|||
PCB_LAYER_WIDGET( wxWindow* aParent, PCB_BASE_FRAME* aFrame, wxWindow* aFocusOwner, bool aFpEditorMode = false ); |
|||
|
|||
void ReFill(); |
|||
|
|||
/** |
|||
* Function ReFillRender |
|||
* rebuilds Render for instance after the config is read |
|||
*/ |
|||
void ReFillRender(); |
|||
|
|||
/** |
|||
* Function SyncLayerVisibilities |
|||
* updates each "Layer" checkbox in this layer widget according |
|||
* to each layer's current visibility determined by IsLayerVisible(), and is |
|||
* helpful immediately after loading a BOARD which may have state information in it. |
|||
*/ |
|||
void SyncLayerVisibilities(); |
|||
|
|||
/** |
|||
* Function SyncLayerAlphaIndicators |
|||
* updates each "Layer"s alpha indicator to show if the board is currently being |
|||
* rendered with more transparency or less. |
|||
*/ |
|||
void SyncLayerAlphaIndicators(); |
|||
|
|||
/** |
|||
* Updates the color for each layer and item from the active color theme |
|||
*/ |
|||
void SyncLayerColors(); |
|||
|
|||
/** |
|||
* Function SetLayersManagerTabsText |
|||
* Update the layer manager tabs labels |
|||
* Useful when changing Language or to set labels to a non default value |
|||
*/ |
|||
void SetLayersManagerTabsText(); |
|||
|
|||
//-----<implement LAYER_WIDGET abstract callback functions>----------- |
|||
void OnLayerColorChange( int aLayer, COLOR4D aColor ) override; |
|||
bool OnLayerSelect( int aLayer ) override; |
|||
void OnLayerVisible( int aLayer, bool isVisible, bool isFinal ) override; |
|||
void OnLayerRightClick( wxMenu& aMenu ) override; |
|||
void OnRenderColorChange( int aId, COLOR4D aColor ) override; |
|||
void OnRenderEnable( int aId, bool isEnabled ) override; |
|||
//-----</implement LAYER_WIDGET abstract callback functions>---------- |
|||
|
|||
/** |
|||
* Function OnLayerSelected |
|||
* ensure the active layer is visible, and other layers not visible |
|||
* when m_alwaysShowActiveLayer is true |
|||
* Otherwise do nothing. |
|||
* @return true m_alwaysShowActiveLayer is true and the canvas is refreshed, |
|||
* and false if do nothing |
|||
*/ |
|||
bool OnLayerSelected(); // postprocess after an active layer selection |
|||
// ensure active layer visible if |
|||
// m_alwaysShowActiveCopperLayer is true; |
|||
|
|||
/** |
|||
* Function addRightClickMenuItems |
|||
* add menu items to a menu that should be shown when right-clicking |
|||
* the PCB layer widget. |
|||
*/ |
|||
void AddRightClickMenuItems( wxMenu& menu ); |
|||
|
|||
|
|||
protected: |
|||
|
|||
static const LAYER_WIDGET::ROW s_render_rows[]; |
|||
bool m_alwaysShowActiveCopperLayer; // If true: Only shows the current active layer |
|||
// even if it is changed |
|||
bool m_fp_editor_mode; |
|||
|
|||
PCB_BASE_FRAME* myframe; |
|||
|
|||
// popup menu ids. |
|||
enum POPUP_ID |
|||
{ |
|||
ID_SHOW_ALL_COPPER_LAYERS = LAYER_WIDGET::ID_LAST_VALUE, |
|||
ID_HIDE_ALL_COPPER_LAYERS, |
|||
ID_HIDE_ALL_COPPER_LAYERS_BUT_ACTIVE, |
|||
ID_ALWAYS_HIDE_ALL_COPPER_LAYERS_BUT_ACTIVE, |
|||
ID_SHOW_NO_LAYERS, |
|||
ID_SHOW_ALL_LAYERS, |
|||
ID_SHOW_ONLY_FRONT, |
|||
ID_SHOW_ONLY_INNER, |
|||
ID_SHOW_ONLY_BACK, |
|||
ID_SHOW_ONLY_FRONT_ASSEMBLY, |
|||
ID_SHOW_ONLY_BACK_ASSEMBLY, |
|||
ID_HIDE_ALL_NON_COPPER, |
|||
ID_SHOW_ALL_NON_COPPER, |
|||
ID_LAST_VALUE |
|||
}; |
|||
|
|||
virtual COLOR4D getBackgroundLayerColor() override; |
|||
|
|||
/** |
|||
* Function isAllowedInFpMode |
|||
* @return true if item aId has meaning in footprint editor mode. |
|||
* and therefore is shown in render panel |
|||
*/ |
|||
bool isAllowedInFpMode( int aId ); |
|||
|
|||
/** |
|||
* Function isLayerAllowedInFpMode |
|||
* |
|||
* User layers, which are not paired, are not shown in layers manager. However a not |
|||
* listed layer can be reachable in the graphic item properties dialog. |
|||
* |
|||
* @param aLayer is the layer id to test |
|||
* @return true if PCB_LAYER_ID aLayer has meaning in footprint editor mode. |
|||
* and therefore is shown in render panel |
|||
*/ |
|||
bool isLayerAllowedInFpMode( PCB_LAYER_ID aLayer ); |
|||
|
|||
/** |
|||
* Function OnRightDownLayers |
|||
* puts up a popup menu for the layer panel. |
|||
*/ |
|||
void onRightDownLayers( wxMouseEvent& event ); |
|||
|
|||
void onPopupSelection( wxCommandEvent& event ); |
|||
|
|||
/// this is for the popup menu, the right click handler has to be installed |
|||
/// on every child control within the layer panel. |
|||
void installRightLayerClickHandler(); |
|||
}; |
|||
|
|||
#endif // PCB_LAYER_WIDGET_H |
@ -0,0 +1,45 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2020 CERN |
|||
* @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 "properties_tool.h"
|
|||
#include <pcb_properties_panel.h>
|
|||
#include <tool/actions.h>
|
|||
|
|||
|
|||
int PROPERTIES_TOOL::UpdateProperties( const TOOL_EVENT& aEvent ) |
|||
{ |
|||
PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>(); |
|||
|
|||
if( editFrame ) |
|||
editFrame->UpdateProperties(); |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
|
|||
void PROPERTIES_TOOL::setTransitions() |
|||
{ |
|||
TOOL_EVENT undoRedoPostEvt = { TC_MESSAGE, TA_UNDO_REDO_POST, AS_GLOBAL }; |
|||
Go( &PROPERTIES_TOOL::UpdateProperties, undoRedoPostEvt ); |
|||
Go( &PROPERTIES_TOOL::UpdateProperties, EVENTS::SelectedEvent ); |
|||
Go( &PROPERTIES_TOOL::UpdateProperties, EVENTS::UnselectedEvent ); |
|||
Go( &PROPERTIES_TOOL::UpdateProperties, EVENTS::ClearedEvent ); |
|||
Go( &PROPERTIES_TOOL::UpdateProperties, EVENTS::SelectedItemsModified ); |
|||
} |
@ -0,0 +1,42 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2020 CERN |
|||
* @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 PROPERTIES_TOOL_H |
|||
#define PROPERTIES_TOOL_H |
|||
|
|||
#include <tools/pcb_tool_base.h> |
|||
|
|||
/** |
|||
* Action handler for the Properties panel |
|||
*/ |
|||
class PROPERTIES_TOOL : public PCB_TOOL_BASE |
|||
{ |
|||
public: |
|||
PROPERTIES_TOOL() |
|||
: PCB_TOOL_BASE( "pcbnew.Properties" ) |
|||
{ |
|||
} |
|||
|
|||
int UpdateProperties( const TOOL_EVENT& aEvent ); |
|||
|
|||
void setTransitions() override; |
|||
}; |
|||
|
|||
#endif |
Write
Preview
Loading…
Cancel
Save
Reference in new issue