67#include <wx/combobox.h>
93 void setter(
void* obj, wxAny& v )
override
97 if( !v.GetAs( &value ) )
103 wxString variantName;
108 if( !variantName.IsEmpty() )
123 footprint->
Add( newField );
132 wxAny
getter(
const void* obj )
const override
139 wxString variantName;
146 if( !variantName.IsEmpty() )
151 return wxAny(
text );
175 wxPGWindowList
CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
const wxPoint& aPos,
176 const wxSize& aSize )
const override
191 editor->SetNetInfo( &board->GetNetInfo() );
198 editor->Bind( FILTERED_ITEM_SELECTED,
199 [=]( wxCommandEvent& aEvt )
201 auto& choices =
const_cast<wxPGChoices&
>( aProperty->GetChoices() );
202 wxString netname =
editor->GetSelectedNetname();
204 if( choices.Index( netname ) == wxNOT_FOUND )
205 choices.Add( netname,
editor->GetSelectedNetcode() );
207 wxVariant val(
editor->GetSelectedNetcode() );
208 aGrid->ChangePropertyValue( aProperty, val );
214 void UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl )
const override
218 if( aProperty->IsValueUnspecified() )
219 editor->SetIndeterminate();
221 editor->SetSelectedNetcode( (
int) aProperty->GetValue().GetLong() );
232 aVariant =
static_cast<long>(
editor->GetSelectedNetcode() );
236 bool OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aWindow, wxEvent& aEvent )
const override
287 wxPGWindowList
CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
const wxPoint& aPos,
288 const wxSize& aSize )
const override
292 wxComboBox*
editor =
new wxComboBox( aGrid->GetPanel(), wxID_ANY, wxEmptyString, aPos, aSize, 0,
nullptr,
293 wxCB_DROPDOWN | wxTE_PROCESS_ENTER );
302 std::shared_ptr<bool> popupShown = std::make_shared<bool>(
false );
304 [
this, aGrid, aProperty]()
309 wxVariant val(
static_cast<long>(
m_unitBinder->GetValue() ) );
310 aGrid->ChangePropertyValue( aProperty, val );
313 editor->Bind( wxEVT_COMBOBOX_DROPDOWN,
314 [popupShown]( wxCommandEvent& aEvent )
320 editor->Bind( wxEVT_COMBOBOX,
321 [commitValue, popupShown]( wxCommandEvent& aEvent )
330 editor->Bind( wxEVT_COMBOBOX_CLOSEUP,
331 [aGrid, popupShown]( wxCommandEvent& aEvent )
333 aGrid->CallAfter( [popupShown]()
341 editor->Bind( wxEVT_CHAR_HOOK,
342 [commitValue, popupShown]( wxKeyEvent& aEvent )
346 if( ( aEvent.GetKeyCode() == WXK_RETURN
347 || aEvent.GetKeyCode() == WXK_NUMPAD_ENTER )
357 editor->Bind( wxEVT_KILL_FOCUS,
358 [commitValue, popupShown]( wxFocusEvent& aEvent )
367 return wxPGWindowList(
editor,
nullptr );
370 void UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl )
const override
375 wxComboBox*
editor =
dynamic_cast<wxComboBox*
>( aCtrl );
378 if( aProperty->IsValueUnspecified() )
381 m_unitBinder->ChangeValue( aProperty->GetValue().GetLong() );
389 wxComboBox*
editor =
dynamic_cast<wxComboBox*
>( aCtrl );
390 wxCHECK_MSG(
editor,
false,
"PG_TRACK_WIDTH_EDITOR requires a combo box!" );
399 bool changed = aVariant.IsNull() ||
result != aVariant.GetLong();
407 bool OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aWindow, wxEvent& aEvent )
const override
415 std::vector<long long int> trackWidths;
418 for(
unsigned ii = 1; ii <
m_frame->GetDesignSettings().m_TrackWidthList.size(); ++ii )
419 trackWidths.push_back(
m_frame->GetDesignSettings().m_TrackWidthList[ii] );
425 for(
unsigned ii = 0; ii < aEditor->GetCount(); ++ii )
426 aEditor->SetString( ii, aEditor->GetString( ii ) + wxS(
" " ) + unitLabel );
569 if(
FOOTPRINT* footprint = board->GetFirstFootprint() )
571 aFallbackSelection.
Clear();
572 aFallbackSelection.
Add( footprint );
573 return aFallbackSelection;
587 return selection.
Empty() ? nullptr : selection.
Front();
634 wxCHECK2( field,
continue );
640 const wxString groupFields =
_HKI(
"Fields" );
671 const wxPGChoices& canonicalLayers = aProperty->
Choices();
672 wxArrayString boardLayerNames;
673 wxArrayInt boardLayerIDs;
675 for(
int ii = 0; ii < (int) aProperty->
Choices().GetCount(); ++ii )
677 int layer = canonicalLayers.GetValue( ii );
679 boardLayerNames.push_back(
m_frame->GetBoard()->GetLayerName(
ToLAYER_ID( layer ) ) );
680 boardLayerIDs.push_back( canonicalLayers.GetValue( ii ) );
686 [&](
int aValue ) -> wxColour
691 ret->SetLabel( wxGetTranslation( aProperty->
Name() ) );
692 ret->SetName( aProperty->
Name() );
693 ret->SetHelpString( wxGetTranslation( aProperty->
Name() ) );
694 ret->SetClientData(
const_cast<PROPERTY_BASE*
>( aProperty ) );
723 wxCHECK_MSG( firstItem,
nullptr, wxT(
"getPropertyFromEvent for a property with nothing selected!") );
726 wxCHECK_MSG( property,
nullptr, wxT(
"getPropertyFromEvent for a property not found on the selected item!" ) );
740 wxCHECK( property, );
743 wxVariant newValue = aEvent.GetPropertyValue();
745 if(
VALIDATOR_RESULT validationFailure = property->Validate( newValue.GetAny(), item ) )
747 wxString errorMsg = wxString::Format( wxS(
"%s: %s" ), wxGetTranslation( property->Name() ),
748 validationFailure->get()->Format(
m_frame ) );
749 m_frame->ShowInfoBarError( errorMsg );
756 const wxString propName = aEvent.GetPropertyName();
758 if( propName ==
_HKI(
"Scale X" ) || propName ==
_HKI(
"Scale Y" ) )
760 const double newScale = newValue.GetDouble();
763 if( !std::isfinite( newScale ) || newScale <= 0.0 )
765 m_frame->ShowInfoBarError(
_(
"Scale must be a positive number." ) );
770 if( newScale != 1.0 )
776 for(
EDA_ITEM* edaItem : selection )
796 wxString msg = wxString::Format(
_(
"%d footprint(s) in the selection have pads. Scaling changes "
797 "the drawn pad positions but not the physical part. Continue?" ),
801 [
this, msg, propName, newValue]()
803 if( wxMessageBox( msg,
_(
"Scale footprint with pads?" ), wxYES_NO | wxICON_WARNING,
this )
823 wxPGProperty* pgProp =
m_grid->GetPropertyByName( aPropName );
829 wxPropertyGridEvent evt( wxEVT_PG_CHANGED );
830 evt.SetEventObject(
m_grid );
831 evt.SetProperty( pgProp );
832 evt.SetPropertyValue( aValue );
848 wxVariant newValue = aEvent.GetPropertyValue();
856 const wxString propName = aEvent.GetPropertyName();
857 const bool isScaleX = ( propName ==
_HKI(
"Scale X" ) );
858 const bool isScaleY = ( propName ==
_HKI(
"Scale Y" ) );
859 int fpInSelection = 0;
862 if( isScaleX || isScaleY )
864 for(
EDA_ITEM* edaItem : selection )
869 selectionBBox.
Merge(
static_cast<FOOTPRINT*
>( edaItem )->GetBoundingBox() );
874 const bool useSelectionCenter = fpInSelection > 1;
878 std::vector<PCB_CONSTRAINT*> drivingConstraints;
880 for(
EDA_ITEM* edaItem : selection )
882 if( !edaItem->IsBOARD_ITEM() )
887 wxCHECK( property, );
899 && !
m_frame->GetPcbNewSettings()->m_AllowFreePads
900 && ( aEvent.GetPropertyName() ==
_HKI(
"Position X" )
901 || aEvent.GetPropertyName() ==
_HKI(
"Position Y" ) ) )
911 if( aEvent.GetPropertyName() ==
_HKI(
"Position X" ) )
912 newPos.
x = (int) newValue.GetLong();
914 newPos.
y = (int) newValue.GetLong();
932 wxString variantName;
937 if( !variantName.IsEmpty() )
939 if( propName ==
_HKI(
"Do not Populate" )
940 || propName ==
_HKI(
"Exclude From Bill of Materials" )
941 || propName ==
_HKI(
"Exclude From Position Files" ) )
946 variant = footprint->
AddVariant( variantName );
950 bool boolValue = newValue.GetBool();
952 if( propName ==
_HKI(
"Do not Populate" ) )
953 variant->
SetDNP( boolValue );
954 else if( propName ==
_HKI(
"Exclude From Bill of Materials" ) )
956 else if( propName ==
_HKI(
"Exclude From Position Files" ) )
968 double newScale = newValue.GetDouble();
969 double relSx = isScaleX ? newScale / fp->
GetScaleX() : 1.0;
970 double relSy = isScaleY ? newScale / fp->
GetScaleY() : 1.0;
983 if( propName ==
_HKI(
"Value Mode" ) )
988 std::optional<int> length;
994 if( existing && existing->
GetValue() )
1001 std::optional<wxString> overrideText;
1007 board, dim, mode, length, overrideText,
1013 drivingConstraints.push_back( driving );
1023 newValue.GetString() );
1029 changes.
Modify( driving );
1030 driving->SetValue(
KiROUND( iu ) );
1031 drivingConstraints.push_back( driving );
1039 item->
Set( property, newValue );
1042 changes.
Push(
_(
"Edit Properties" ) );
1048 std::vector<PCB_SHAPE*> shapes;
1049 EDIT_TOOL::collectConstraintShapes( selection, shapes );
1050 constraintTool->SolveAfterEdit( shapes );
1055 if( !drivingConstraints.empty() )
1064 solveCommit.Modify( aItem );
1068 if( !solveCommit.
Empty() )
1078 if( aEvent.GetPropertyName() ==
_HKI(
"Locked" ) )
1087 wxPGChoices layersAll;
1088 wxPGChoices layersCu;
1114 std::vector<std::pair<wxString, int>> netNames;
1118 netNames.emplace_back(
UnescapeString( netInfo->GetNetname() ), netCode );
1120 std::sort( netNames.begin(), netNames.end(),
1121 [](
const auto& a,
const auto& b )
1123 return a.first.CmpNoCase( b.first ) < 0;
1126 for(
const auto& [ netName, netCode ] : netNames )
1127 nets.Add( netName, netCode );
1130 netProperty->SetChoices( nets );
1133 tuningNet->SetChoices( nets );
1143 const wxString& propName = aProperty->
Name();
1144 wxString variantName;
1149 if( propName ==
_HKI(
"Do not Populate" ) )
1154 else if( propName ==
_HKI(
"Exclude From Bill of Materials" ) )
1159 else if( propName ==
_HKI(
"Exclude From Position Files" ) )
constexpr EDA_IU_SCALE pcbIUScale
CONSTRAINT_DIAGNOSIS ApplyConstraintImmediately(BOARD *aBoard, const PCB_CONSTRAINT *aConstraint, std::vector< PCB_SHAPE * > *aModified, const std::function< void(BOARD_ITEM *)> &aBeforeModify, const std::set< KIID > &aFixedShapes)
Solve a just-created constraint's cluster so the geometry snaps to satisfy it (SolidWorks-style),...
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
BOARD_ITEM_CONTAINER * GetParent() const
Information pertinent to a Pcbnew printed circuit board.
const NETINFO_LIST & GetNetInfo() const
wxString GetCurrentVariant() const
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr const Vec GetCenter() const
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
A base class for most all the KiCad significant classes used in schematics and boards.
KICAD_T Type() const
Returns the type of object.
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual void SetText(const wxString &aText)
static const TOOL_EVENT SelectedEvent
Class that other classes need to inherit from, in order to be inspectable.
bool Set(PROPERTY_BASE *aProperty, wxAny &aValue, bool aNotify=true)
bool IsBOARD_ITEM() const
LSET is a set of PCB_LAYER_IDs.
LSEQ UIOrder() const
Return the copper, technical and user layers in the order shown in layer widget.
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
const NETCODES_MAP & NetsByNetcode() const
Return the netcode map, at least for python.
Common, abstract interface for edit frames.
A geometric constraint between board items (issue #2329).
std::optional< double > GetValue() const
EDA_UNITS GetUnits() const
DIM_VALUE_MODE GetValueMode() const
Value mode from board state via DimensionValueMode.
int GetMeasuredValue() const
wxString GetValueText() const
bool GetOverrideTextEnabled() const
PCB_BASE_EDIT_FRAME * m_frame
PG_NET_SELECTOR_EDITOR * m_netSelectorEditorInstance
void valueChanged(wxPropertyGridEvent &aEvent) override
PG_UNIT_EDITOR * m_unitEditorInstance
PG_RATIO_EDITOR * m_ratioEditorInstance
wxPGProperty * createPGProperty(const PROPERTY_BASE *aProperty) const override
void UpdateData() override
void rebuildProperties(const SELECTION &aSelection) override
Generates the property grid for a given selection of items.
PCB_PROPERTIES_PANEL(wxWindow *aParent, PCB_BASE_EDIT_FRAME *aFrame)
bool m_scaleConfirmPending
const SELECTION & getSelection(SELECTION &aFallbackSelection)
Get the current selection from the selection tool.
EDA_ITEM * getFrontItem()
Get the front item of the current selection.
virtual ~PCB_PROPERTIES_PANEL()
static std::set< wxString > m_currentFieldNames
PROPERTY_BASE * getPropertyFromEvent(const wxPropertyGridEvent &aEvent) const
PROPERTY_MANAGER & m_propMgr
PG_URL_EDITOR * m_urlEditorInstance
void AfterCommit() override
PG_CHECKBOX_EDITOR * m_checkboxEditorInstance
void applyConfirmedScale(const wxString &aPropName, const wxVariant &aValue)
Regenerates caches storing layer and net names.
void updateLists(const BOARD *aBoard)
void valueChanging(wxPropertyGridEvent &aEvent) override
bool getItemValue(EDA_ITEM *aItem, PROPERTY_BASE *aProperty, wxVariant &aValue) override
Utility to fetch a property value and convert to wxVariant Precondition: aItem is known to have prope...
PG_TRACK_WIDTH_EDITOR * m_trackWidthEditorInstance
PG_FPID_EDITOR * m_fpEditorInstance
static const wxString EDITOR_NAME
static wxString BuildEditorName(EDA_DRAW_FRAME *aFrame)
wxPGWindowList CreateControls(wxPropertyGrid *aGrid, wxPGProperty *aProperty, const wxPoint &aPos, const wxSize &aSize) const override
bool OnEvent(wxPropertyGrid *aGrid, wxPGProperty *aProperty, wxWindow *aWindow, wxEvent &aEvent) const override
void UpdateControl(wxPGProperty *aProperty, wxWindow *aCtrl) const override
wxString GetName() const override
bool GetValueFromControl(wxVariant &aVariant, wxPGProperty *aProperty, wxWindow *aCtrl) const override
static const wxString EDITOR_NAME
PG_NET_SELECTOR_EDITOR()=default
static const wxString EDITOR_NAME
std::unique_ptr< PROPERTY_EDITOR_UNIT_BINDER > m_unitBinder
void UpdateControl(wxPGProperty *aProperty, wxWindow *aCtrl) const override
void UpdateFrame(PCB_BASE_EDIT_FRAME *aFrame)
wxString GetName() const override
PG_TRACK_WIDTH_EDITOR(PCB_BASE_EDIT_FRAME *aFrame)
static const wxString EDITOR_NAME
PCB_BASE_EDIT_FRAME * m_frame
void setTrackWidthOptions(wxComboBox *aEditor) const
wxPGWindowList CreateControls(wxPropertyGrid *aGrid, wxPGProperty *aProperty, const wxPoint &aPos, const wxSize &aSize) const override
bool GetValueFromControl(wxVariant &aVariant, wxPGProperty *aProperty, wxWindow *aCtrl) const override
static wxString BuildEditorName(PCB_BASE_EDIT_FRAME *aFrame)
bool OnEvent(wxPropertyGrid *aGrid, wxPGProperty *aProperty, wxWindow *aWindow, wxEvent &aEvent) const override
static wxString BuildEditorName(EDA_DRAW_FRAME *aFrame)
static wxString BuildEditorName(EDA_DRAW_FRAME *aFrame)
PROPERTIES_PANEL(wxWindow *aParent, EDA_BASE_FRAME *aFrame)
int m_SuppressGridChangeEvents
virtual bool getItemValue(EDA_ITEM *aItem, PROPERTY_BASE *aProperty, wxVariant &aValue)
Utility to fetch a property value and convert to wxVariant Precondition: aItem is known to have prope...
virtual void rebuildProperties(const SELECTION &aSelection)
Generates the property grid for a given selection of items.
virtual size_t TypeHash() const =0
Return type-id of the property type.
PROPERTY_BASE(const wxString &aName, PROPERTY_DISPLAY aDisplay=PT_DEFAULT, ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType=ORIGIN_TRANSFORMS::NOT_A_COORD)
< Used to generate unique IDs. Must come up front so it's initialized before ctor.
virtual bool HasChoices() const
Return true if this PROPERTY has a limited set of possible values.
virtual bool Writeable(INSPECTABLE *aObject) const
const wxString & Name() const
virtual const wxPGChoices & Choices() const
Return a limited set of possible values (e.g.
virtual size_t OwnerHash() const =0
Return type-id of the Owner class.
Provide class metadata.Helper macro to map type hashes to names.
virtual void Add(EDA_ITEM *aItem)
A null aItem is ignored; the selection never holds null members.
virtual void Clear() override
Remove all the stored items from the group.
bool Empty() const
Checks if there is anything selected.
PCB_CONSTRAINT * FindDimensionLengthConstraint(BOARD *aBoard, const PCB_DIMENSION_BASE *aDimension)
Self FIXED_LENGTH constraint whose members are exactly aDimension START and END or nullptr the drivin...
PCB_CONSTRAINT * SetDimensionValueMode(BOARD *aBoard, PCB_DIMENSION_BASE *aDimension, DIM_VALUE_MODE aMode, std::optional< int > aDrivingLengthIU, const std::optional< wxString > &aOverrideText, const std::function< void(BOARD_ITEM *)> &aBeforeModify, const std::function< void(BOARD_ITEM *)> &aStageAdd, const std::function< void(BOARD_ITEM *)> &aBeforeRemove)
Apply a value mode transition to aDimension Driving creates or updates the driving length with aDrivi...
DIM_VALUE_MODE
Mode a value bearing dimension value is in Driven mirrors measured geometry Driving forces geometry t...
PCB_LAYER_ID
A quick note on layer IDs:
PCB_LAYER_ID ToLAYER_ID(int aLayer)
KICOMMON_API double DoubleValueFromString(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Convert aTextValue to a double.
KICOMMON_API wxString GetLabel(EDA_UNITS aUnits, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Get the units string for a given units type.
static const wxString MISSING_FIELD_SENTINEL
wxPGProperty * PGPropertyFactory(const PROPERTY_BASE *aProperty, EDA_DRAW_FRAME *aFrame)
Customized abstract wxPGProperty class to handle coordinate/size units.
APIIMPORT wxPGGlobalVarsClass * wxPGGlobalVars
std::optional< std::unique_ptr< VALIDATION_ERROR > > VALIDATOR_RESULT
Null optional means validation succeeded.
static const wxString MISSING_FIELD_SENTINEL
wxString UnescapeString(const wxString &aSource)
@ USER
The field ID hasn't been set yet; field is invalid.
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ DATASHEET
name of datasheet
wxString GetCanonicalFieldName(FIELD_T aFieldType)
wxString result
Test unit parsing edge cases and error handling.
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
Functions to provide common constants and other functions to assist in making a consistent UI.
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
VECTOR2< int32_t > VECTOR2I