WIP: Properties GUI
This commit is contained in:
parent
95fd58b25a
commit
f6f6ebd5f9
|
@ -189,6 +189,7 @@ set( COMMON_WIDGET_SRCS
|
|||
widgets/number_badge.cpp
|
||||
widgets/paged_dialog.cpp
|
||||
widgets/progress_reporter_base.cpp
|
||||
widgets/properties_panel.cpp
|
||||
widgets/split_button.cpp
|
||||
widgets/stepped_slider.cpp
|
||||
widgets/text_ctrl_eval.cpp
|
||||
|
@ -498,6 +499,7 @@ set( PCB_COMMON_SRCS
|
|||
fp_lib_table.cpp
|
||||
hash_eda.cpp
|
||||
page_info.cpp
|
||||
pg_properties.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_base_frame.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_expr_evaluator.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/board_commit.cpp
|
||||
|
|
|
@ -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 */
|
|
@ -177,7 +177,6 @@ private:
|
|||
|
||||
public:
|
||||
PROPERTY_BASE( const wxString& aName, PROPERTY_DISPLAY aDisplay = DEFAULT ) :
|
||||
m_id( 0 ),
|
||||
m_name( aName ),
|
||||
m_display( aDisplay ),
|
||||
m_availFunc( [](INSPECTABLE*)->bool { return true; } )
|
||||
|
@ -281,7 +280,6 @@ protected:
|
|||
virtual wxAny getter( void* aObject ) const = 0;
|
||||
|
||||
private:
|
||||
const size_t m_id;
|
||||
const wxString m_name;
|
||||
const PROPERTY_DISPLAY m_display;
|
||||
|
||||
|
|
|
@ -149,6 +149,11 @@ public:
|
|||
|
||||
bool Validate( wxWindow* aParent ) override;
|
||||
|
||||
const wxString& GetRegEx() const
|
||||
{
|
||||
return m_regExString;
|
||||
}
|
||||
|
||||
protected:
|
||||
///< Compiles and stores a regular expression
|
||||
void compileRegEx( const wxString& aRegEx, int aFlags );
|
||||
|
|
|
@ -183,6 +183,7 @@ set( PCBNEW_DIALOGS
|
|||
dialogs/panel_setup_text_and_graphics_base.cpp
|
||||
dialogs/panel_setup_tracks_and_vias.cpp
|
||||
dialogs/panel_setup_tracks_and_vias_base.cpp
|
||||
dialogs/pcb_properties_panel.cpp
|
||||
footprint_wizard.cpp
|
||||
footprint_wizard_frame.cpp
|
||||
footprint_wizard_frame_functions.cpp
|
||||
|
@ -355,6 +356,7 @@ 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
|
||||
|
|
|
@ -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 */
|
|
@ -228,6 +228,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
|
|||
ACTION_MENU* viewMenu = new ACTION_MENU( false, selTool );
|
||||
|
||||
viewMenu->Add( PCB_ACTIONS::showLayersManager, ACTION_MENU::CHECK );
|
||||
viewMenu->Add( PCB_ACTIONS::showProperties , ACTION_MENU::CHECK );
|
||||
viewMenu->Add( ACTIONS::showFootprintBrowser );
|
||||
viewMenu->Add( ACTIONS::show3DViewer );
|
||||
|
||||
|
|
|
@ -37,8 +37,10 @@
|
|||
#include <project.h>
|
||||
#include <settings/color_settings.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <widgets/appearance_controls.h>
|
||||
#include <dialogs/eda_view_switcher.h>
|
||||
#include <pcb_properties_panel.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <collectors.h>
|
||||
|
||||
|
@ -50,7 +52,9 @@ PCB_BASE_EDIT_FRAME::PCB_BASE_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent,
|
|||
PCB_BASE_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ),
|
||||
m_undoRedoBlocked( false ),
|
||||
m_selectionFilterPanel( nullptr ),
|
||||
m_appearancePanel( nullptr )
|
||||
m_appearancePanel( nullptr ),
|
||||
m_propertiesPanel( nullptr ),
|
||||
m_tabbedPanel( nullptr )
|
||||
{
|
||||
Bind( wxEVT_IDLE,
|
||||
[this]( wxIdleEvent& aEvent )
|
||||
|
@ -256,6 +260,7 @@ void PCB_BASE_EDIT_FRAME::unitsChangeRefresh()
|
|||
}
|
||||
|
||||
ReCreateAuxiliaryToolbar();
|
||||
UpdateProperties();
|
||||
}
|
||||
|
||||
|
||||
|
@ -303,3 +308,11 @@ void PCB_BASE_EDIT_FRAME::handleActivateEvent( wxActivateEvent& aEvent )
|
|||
}
|
||||
|
||||
|
||||
void PCB_BASE_EDIT_FRAME::UpdateProperties()
|
||||
{
|
||||
if( !m_propertiesPanel || !m_propertiesPanel->IsShownOnScreen() )
|
||||
return;
|
||||
|
||||
m_propertiesPanel->Update();
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
class APPEARANCE_CONTROLS;
|
||||
class BOARD_ITEM_CONTAINER;
|
||||
class PANEL_SELECTION_FILTER;
|
||||
class PROPERTIES_PANEL;
|
||||
|
||||
/**
|
||||
* Common, abstract interface for edit frames.
|
||||
|
@ -214,6 +215,10 @@ public:
|
|||
|
||||
APPEARANCE_CONTROLS* GetAppearancePanel() { return m_appearancePanel; }
|
||||
|
||||
PROPERTIES_PANEL* GetPropertiesPanel() { return m_propertiesPanel; }
|
||||
|
||||
void UpdateProperties();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Prompts a user to select global or project library tables
|
||||
|
@ -241,6 +246,10 @@ protected:
|
|||
|
||||
PANEL_SELECTION_FILTER* m_selectionFilterPanel;
|
||||
APPEARANCE_CONTROLS* m_appearancePanel;
|
||||
PROPERTIES_PANEL* m_propertiesPanel;
|
||||
|
||||
/// Panel with Layers and Object Inspector tabs
|
||||
wxAuiNotebook* m_tabbedPanel;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <dialog_find.h>
|
||||
#include <dialog_footprint_properties.h>
|
||||
#include <dialogs/dialog_exchange_footprints.h>
|
||||
#include <pcb_properties_panel.h>
|
||||
#include <dialog_board_setup.h>
|
||||
#include <invoke_pcb_dialog.h>
|
||||
#include <board.h>
|
||||
|
@ -81,6 +82,7 @@
|
|||
#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>
|
||||
|
@ -188,6 +190,7 @@ 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;
|
||||
|
||||
// We don't know what state board was in when it was last saved, so we have to
|
||||
// assume dirty
|
||||
|
@ -207,7 +210,6 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
|||
EDA_DRAW_PANEL_GAL::GAL_FALLBACK );
|
||||
|
||||
SetCanvas( canvas );
|
||||
|
||||
SetBoard( new BOARD() );
|
||||
|
||||
wxIcon icon;
|
||||
|
@ -222,6 +224,12 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
|||
|
||||
SetIcons( icon_bundle );
|
||||
|
||||
m_tabbedPanel = new wxAuiNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
|
||||
wxAUI_NB_BOTTOM | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE |
|
||||
wxAUI_NB_SCROLL_BUTTONS );
|
||||
|
||||
m_propertiesPanel = new PCB_PROPERTIES_PANEL( m_tabbedPanel, this );
|
||||
|
||||
// LoadSettings() *after* creating m_LayersManager, because LoadSettings()
|
||||
// initialize parameters in m_LayersManager
|
||||
LoadSettings( config() );
|
||||
|
@ -281,6 +289,11 @@ 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_tabbedPanel, // TODO check
|
||||
EDA_PANE().Palette().Name( "TabbedPanel" ).Right().Layer( 3 )
|
||||
.PaneBorder( false ).MinSize( 300, -1 )
|
||||
.TopDockable( false ).BottomDockable( false ) );
|
||||
|
||||
// Center
|
||||
m_auimgr.AddPane( GetCanvas(), EDA_PANE().Canvas().Name( "DrawFrame" )
|
||||
.Center() );
|
||||
|
@ -566,6 +579,7 @@ void PCB_EDIT_FRAME::setupTools()
|
|||
m_toolManager->RegisterTool( new CONVERT_TOOL );
|
||||
m_toolManager->RegisterTool( new GROUP_TOOL );
|
||||
m_toolManager->RegisterTool( new SCRIPTING_TOOL );
|
||||
m_toolManager->RegisterTool( new PROPERTIES_TOOL );
|
||||
m_toolManager->InitTools();
|
||||
|
||||
for( TOOL_BASE* tool : m_toolManager->Tools() )
|
||||
|
@ -1006,7 +1020,10 @@ void PCB_EDIT_FRAME::doCloseWindow()
|
|||
// on some platforms (Windows) that generate useless redraw of items in
|
||||
// the Layer Manager
|
||||
if( m_show_layer_manager_tools )
|
||||
{
|
||||
m_auimgr.GetPane( "LayersManager" ).Show( false );
|
||||
m_auimgr.GetPane( "TabbedPanel" ).Show( false );
|
||||
}
|
||||
|
||||
// Unlink the old project if needed
|
||||
GetBoard()->ClearProject();
|
||||
|
@ -1100,6 +1117,7 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1116,6 +1134,7 @@ void PCB_EDIT_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg )
|
|||
cfg->m_AuiPanels.show_layer_manager = m_show_layer_manager_tools;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -148,7 +148,10 @@ public:
|
|||
|
||||
// User interface update command event handlers.
|
||||
void OnUpdateLayerSelectBox( wxUpdateUIEvent& aEvent );
|
||||
|
||||
bool LayerManagerShown();
|
||||
bool PropertiesShown();
|
||||
|
||||
void OnUpdateSelectViaSize( wxUpdateUIEvent& aEvent );
|
||||
void OnUpdateSelectTrackWidth( wxUpdateUIEvent& aEvent );
|
||||
void OnUpdateSelectAutoWidth( wxUpdateUIEvent& aEvent );
|
||||
|
@ -294,6 +297,7 @@ public:
|
|||
void PrepareLayerIndicator( bool aForceRebuild = false );
|
||||
|
||||
void ToggleLayersManager();
|
||||
void ToggleProperties();
|
||||
|
||||
/**
|
||||
* Create an ASCII footprint position file.
|
||||
|
@ -805,6 +809,7 @@ public:
|
|||
wxChoice* m_SelViaSizeBox; // a choice box to display and select current via diameter
|
||||
|
||||
bool m_show_layer_manager_tools;
|
||||
bool m_show_properties;
|
||||
|
||||
bool m_ZoneFillsDirty; // Board has been modified since last zone fill.
|
||||
|
||||
|
|
|
@ -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
|
|
@ -321,4 +321,3 @@ static struct PCB_SHAPE_DESC
|
|||
propMgr.InheritsAfter( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ) );
|
||||
}
|
||||
} _PCB_SHAPE_DESC;
|
||||
|
||||
|
|
|
@ -95,6 +95,9 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS()
|
|||
m_params.emplace_back( new PARAM<int>( "aui.appearance_panel_tab",
|
||||
&m_AuiPanels.appearance_panel_tab, 0, 0, 2 ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "aui.show_properties",
|
||||
&m_AuiPanels.show_properties, true ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<int>( "footprint_chooser.width",
|
||||
&m_FootprintChooser.width, -1 ) );
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@ public:
|
|||
int appearance_panel_tab;
|
||||
int right_panel_width;
|
||||
bool show_layer_manager;
|
||||
bool show_properties;
|
||||
};
|
||||
|
||||
struct DIALOG_CLEANUP
|
||||
|
|
|
@ -378,6 +378,7 @@ void PCB_EDIT_FRAME::ReCreateOptToolbar()
|
|||
// Tools to show/hide toolbars:
|
||||
m_optionsToolBar->AddScaledSeparator( this );
|
||||
m_optionsToolBar->Add( PCB_ACTIONS::showLayersManager, ACTION_TOOLBAR::TOGGLE );
|
||||
m_optionsToolBar->Add( PCB_ACTIONS::showProperties, ACTION_TOOLBAR::TOGGLE );
|
||||
|
||||
PCB_SELECTION_TOOL* selTool = m_toolManager->GetTool<PCB_SELECTION_TOOL>();
|
||||
std::unique_ptr<ACTION_MENU> gridMenu = std::make_unique<ACTION_MENU>( false, selTool );
|
||||
|
@ -780,6 +781,13 @@ void PCB_EDIT_FRAME::ToggleLayersManager()
|
|||
}
|
||||
|
||||
|
||||
void PCB_EDIT_FRAME::ToggleProperties()
|
||||
{
|
||||
m_show_properties = !m_show_properties;
|
||||
m_auimgr.Update();
|
||||
}
|
||||
|
||||
|
||||
void PCB_EDIT_FRAME::OnUpdateSelectTrackWidth( wxUpdateUIEvent& aEvent )
|
||||
{
|
||||
if( aEvent.GetId() == ID_AUX_TOOLBAR_PCB_TRACK_WIDTH )
|
||||
|
|
|
@ -669,6 +669,13 @@ int BOARD_EDITOR_CONTROL::ToggleLayersManager( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int BOARD_EDITOR_CONTROL::ToggleProperties( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
getEditFrame<PCB_EDIT_FRAME>()->ToggleProperties();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int BOARD_EDITOR_CONTROL::TogglePythonConsole( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_frame->ScriptingConsoleEnableDisable();
|
||||
|
@ -1571,6 +1578,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::TogglePythonConsole, PCB_ACTIONS::showPythonConsole.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::RepairBoard, PCB_ACTIONS::repairBoard.MakeEvent() );
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2014 CERN
|
||||
* Copyright (C) 2014-2020 CERN
|
||||
* Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
|
@ -77,6 +77,7 @@ public:
|
|||
int UpdateSchematicFromPCB( const TOOL_EVENT& aEvent );
|
||||
int ShowEeschema( const TOOL_EVENT& aEvent );
|
||||
int ToggleLayersManager( const TOOL_EVENT& aEvent );
|
||||
int ToggleProperties( const TOOL_EVENT& aEvent );
|
||||
int TogglePythonConsole( const TOOL_EVENT& aEvent );
|
||||
|
||||
// Track & via size control
|
||||
|
|
|
@ -819,6 +819,11 @@ 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" ), _( "Show/hide the properties panel" ),
|
||||
BITMAPS::tools );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::flipBoard( "pcbnew.Control.flipBoard",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Flip Board View" ), _( "View board from the opposite side" ),
|
||||
|
|
|
@ -355,6 +355,7 @@ public:
|
|||
static TOOL_ACTION editLibFpInFpEditor;
|
||||
|
||||
static TOOL_ACTION showLayersManager;
|
||||
static TOOL_ACTION showProperties;
|
||||
static TOOL_ACTION showPythonConsole;
|
||||
|
||||
// Module editor tools
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2014-2016 CERN
|
||||
* Copyright (C) 2014-2020 CERN
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
|
|
|
@ -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
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# This program source code file is part of KiCad, a free EDA CAD application.
|
||||
#
|
||||
# Copyright (C) 2017 CERN
|
||||
# Copyright (C) 2017-2020 CERN
|
||||
# @author Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
|
@ -22,23 +22,23 @@
|
|||
# or you may write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
find_package(Boost COMPONENTS unit_test_framework REQUIRED)
|
||||
find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml stc REQUIRED )
|
||||
find_package( Boost COMPONENTS unit_test_framework REQUIRED )
|
||||
find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml propgrid stc REQUIRED )
|
||||
|
||||
add_definitions(-DBOOST_TEST_DYN_LINK -DPCBNEW)
|
||||
|
||||
add_dependencies( pnsrouter pcbcommon ${PCBNEW_IO_LIBRARIES} )
|
||||
|
||||
add_executable(test_window WIN32
|
||||
test.cpp
|
||||
${CMAKE_SOURCE_DIR}/qa/qa_utils/pcb_test_frame.cpp
|
||||
${CMAKE_SOURCE_DIR}/qa/qa_utils/mocks.cpp
|
||||
test.cpp
|
||||
${CMAKE_SOURCE_DIR}/qa/qa_utils/pcb_test_frame.cpp
|
||||
${CMAKE_SOURCE_DIR}/qa/qa_utils/mocks.cpp
|
||||
|
||||
${CMAKE_SOURCE_DIR}/common/base_units.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/tools/pcb_tool_base.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/tools/pcbnew_selection.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/tools/selection_tool.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/tools/tool_event_utils.cpp
|
||||
${CMAKE_SOURCE_DIR}/common/base_units.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/tools/pcb_tool_base.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/tools/pcbnew_selection.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/tools/selection_tool.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/tools/tool_event_utils.cpp
|
||||
)
|
||||
|
||||
include_directories( BEFORE ${INC_BEFORE} )
|
||||
|
|
Loading…
Reference in New Issue