72 void BindCtrls(
size_t aFrom,
size_t aTo, std::function<
void()> aCb )
77 for(
size_t i = aFrom; i <= aTo; ++i )
80 [aCb]( wxCommandEvent& aEvent )
93 virtual bool Validate( wxArrayString& aErrs )
const {
return true; }
98 wxTextCtrl*
GetCtrl(
size_t aIndex )
const
107 return static_cast<int>(
m_boundCtrls[aIndex].m_Binder->GetValue() );
125 m_boundCtrls[aIndex].m_Binder->ChangeAngleValue( aValue );
165 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
187 bool Validate( wxArrayString& aErrs )
const override
194 aErrs.push_back(
_(
"Rectangle cannot be zero-sized." ) );
307 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
435 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
451 bool Validate( wxArrayString& aErrs )
const override
457 aErrs.push_back(
_(
"Arc angle must be greater than 0" ) );
465 if( start == mid || mid ==
end || start ==
end )
467 aErrs.push_back(
_(
"Arc must have 3 distinct points" ) );
478 if( max_offset >= ( std::numeric_limits<VECTOR2I::coord_type>::max() / 2.0 )
479 || center_i == start || center_i ==
end )
481 aErrs.push_back( wxString::Format(
_(
"Invalid Arc with radius %f and angle %f." ),
567 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
589 bool Validate( wxArrayString& aErrs )
const override
593 aErrs.push_back(
_(
"Radius must be greater than 0" ) );
664 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
674 bool Validate( wxArrayString& aErrs )
const override
678 aErrs.push_back(
_(
"Major radius must be greater than 0" ) );
684 aErrs.push_back(
_(
"Minor radius must be greater than 0" ) );
742 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
752 bool Validate( wxArrayString& aErrs )
const override
756 aErrs.push_back(
_(
"Major radius must be greater than 0" ) );
762 aErrs.push_back(
_(
"Minor radius must be greater than 0" ) );
826 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
927 const wxString& aName,
bool aRelative, std::vector<BOUND_CONTROL>& aBoundCtrls )
932 wxWindow* parent = aSizer.GetContainingWindow();
934 wxStaticText* titleLabel =
new wxStaticText( parent, wxID_ANY, aName );
935 aSizer.Add( titleLabel, wxGBPosition( row, col ), wxGBSpan( 1, 3 ),
936 wxALIGN_CENTER_VERTICAL | wxALIGN_CENTER_HORIZONTAL | wxALL | wxEXPAND );
939 for(
size_t coord = 0; coord < 2; ++coord )
941 wxStaticText* label =
new wxStaticText( parent, wxID_ANY, coord == 0 ?
_(
"X:" ) :
_(
"Y:" ) );
942 aSizer.Add( label, wxGBPosition( row, col ), wxDefaultSpan,
943 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT, col > 0 ? 20 : 5 );
945 wxTextCtrl* ctrl =
new wxTextCtrl( parent, wxID_ANY,
"" );
946 aSizer.Add( ctrl, wxGBPosition( row, col + 1 ), wxDefaultSpan,
947 wxEXPAND | wxALIGN_CENTER_VERTICAL, 5 );
949 wxStaticText* units =
new wxStaticText( parent, wxID_ANY,
_(
"mm" ) );
950 aSizer.Add( units, wxGBPosition( row, col + 2 ), wxDefaultSpan,
951 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 );
953 auto binder = std::make_unique<UNIT_BINDER>( &aFrame, label, ctrl, units );
960 aBoundCtrls.push_back(
BOUND_CONTROL{ std::move( binder ), ctrl } );
964 if( !aSizer.IsColGrowable( col + 1 ) )
965 aSizer.AddGrowableCol( col + 1 );
971 bool aIsAngle, std::vector<BOUND_CONTROL>& aBoundCtrls )
974 wxWindow* parent = aSizer.GetContainingWindow();
976 wxStaticText* label =
new wxStaticText( parent, wxID_ANY, aName + wxS(
":" ) );
977 aSizer.Add( label, wxGBPosition( row, col ), wxDefaultSpan,
978 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT, col > 0 ? 20 : 5 );
980 wxTextCtrl* ctrl =
new wxTextCtrl( parent, wxID_ANY );
981 aSizer.Add( ctrl, wxGBPosition( row, col + 1 ), wxDefaultSpan,
982 wxEXPAND | wxALIGN_CENTER_VERTICAL, 5 );
984 wxStaticText* units =
new wxStaticText( parent, wxID_ANY,
_(
"mm" ) );
985 aSizer.Add( units, wxGBPosition( row, col + 2 ), wxDefaultSpan,
986 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 );
988 auto binder = std::make_unique<UNIT_BINDER>( &aFrame, label, ctrl, units );
989 binder->SetCoordType( aCoordType );
993 binder->SetPrecision( 4 );
997 aBoundCtrls.push_back(
BOUND_CONTROL{ std::move( binder ), ctrl } );
999 if( !aSizer.IsColGrowable( col + 1 ) )
1000 aSizer.AddGrowableCol( col + 1 );
1016 SetTitle( wxString::Format( GetTitle(),
m_item->GetFriendlyName() ) );
1024 std::set<int> shownPages;
1026 const auto showPage =
1027 [&]( wxSizer& aMainSizer,
bool aSelect = false )
1030 wxWindow* page = aMainSizer.GetContainingWindow();
1035 shownPages.insert( pageIdx );
1041 switch(
m_item->GetShape() )
1176 wxFAIL_MSG(
"Undefined shape" );
1183 if( shownPages.count( i ) == 0 )
1220 for(
const auto& [ lineStyle, lineStyleDesc ] :
lineTypeNames )
1251 wxCHECK_RET( aShape, wxT(
"ShowGraphicItemPropertiesDialog() error: NULL item" ) );
1322 int style =
static_cast<int>(
m_item->GetStroke().GetLineStyle() );
1333 if(
m_item->GetLocalSolderMaskMargin().has_value() )
1340 int net =
m_item->GetNetCode();
1356 return DIALOG_SHAPE_PROPERTIES_BASE::TransferDataToWindow();
1362 if( !DIALOG_SHAPE_PROPERTIES_BASE::TransferDataFromWindow() )
1373 bool pushCommit = (
m_item->GetEditFlags() == 0 );
1382 bool wasLocked =
m_item->IsLocked();
1398 m_item->SetLineStyle( it->first );
1405 m_item->SetLocalSolderMaskMargin( {} );
1409 m_item->RebuildBezierToSegmentsPointsList(
m_item->GetMaxError() );
1411 if(
m_item->IsOnCopperLayer() )
1414 m_item->SetNetCode( -1 );
1417 commit.Push(
_(
"Edit Shape Properties" ) );
1423 if( wasLocked !=
m_item->IsLocked() )
1432 wxArrayString errors;
1434 if( !DIALOG_SHAPE_PROPERTIES_BASE::Validate() )
1441 switch(
m_item->GetShape() )
1445 errors.Add(
_(
"Line width must be greater than zero." ) );
1450 errors.Add(
_(
"Line width must be greater than zero for an unfilled circle." ) );
1457 errors.Add(
_(
"Line width must be greater than zero for an unfilled rectangle." ) );
1464 errors.Add(
_(
"Corner radius must be less than or equal to half the smaller side." ) );
1473 errors.Add(
_(
"Line width must be greater than zero for an unfilled polygon." ) );
1479 errors.Add(
_(
"Line width must be greater than zero." ) );
1485 errors.Add(
_(
"Line width must be greater than zero for an unfilled curve." ) );
1491 errors.Add(
_(
"Line width must be greater than zero for an unfilled ellipse." ) );
1497 errors.Add(
_(
"Line width must be greater than zero." ) );
1506 if( errors.GetCount() )
1513 return errors.GetCount() == 0;
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
ARC_GEOM_SYNCER(PCB_SHAPE &aShape, std::vector< BOUND_CONTROL > &aBoundCtrls)
void updateAll() override
bool Validate(wxArrayString &aErrs) const override
BEZIER_GEOM_SYNCER(PCB_SHAPE &aShape, std::vector< BOUND_CONTROL > &aBoundCtrls)
void updateAll() override
bool IsLocked() const override
const NETINFO_LIST & GetNetInfo() const
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
void OnCenterPointChange()
bool Validate(wxArrayString &aErrs) const override
void updateCenterRadius()
CIRCLE_GEOM_SYNCER(PCB_SHAPE &aShape, std::vector< BOUND_CONTROL > &aBoundCtrls)
void updateAll() override
void OnCenterRadiusChange()
Class DIALOG_SHAPE_PROPERTIES_BASE.
wxGridBagSizer * m_gbsBezier
wxGridBagSizer * m_gbsEllipse
wxGridBagSizer * m_gbsRectangleByCorners
wxGridBagSizer * m_gbsCircleCenterRadius
wxCheckBox * m_cbRoundRect
wxCheckBox * m_hasSolderMask
wxGridBagSizer * m_gbsRectangleByCenterSize
wxGridBagSizer * m_gbsCircleCenterPoint
wxTextCtrl * m_cornerRadiusCtrl
wxGridBagSizer * m_gbsLineByStartMid
NET_SELECTOR * m_netSelector
wxGridBagSizer * m_gbsEllipseArc
wxTextCtrl * m_thicknessCtrl
wxGridBagSizer * m_gbsLineByEnds
wxStaticText * m_netLabel
wxStaticText * m_solderMaskMarginUnit
wxGridBagSizer * m_gbsRectangleByCornerSize
wxStaticText * m_thicknessUnits
PCB_LAYER_BOX_SELECTOR * m_LayerSelectionCtrl
wxTextCtrl * m_solderMaskMarginCtrl
wxNotebook * m_notebookShapeDefs
wxStaticText * m_techLayersLabel
wxStaticText * m_cornerRadiusUnits
wxStaticText * m_solderMaskMarginLabel
wxGridBagSizer * m_gbsLineByLengthAngle
wxBitmapComboBox * m_lineStyleCombo
wxStaticText * m_thicknessLabel
wxGridBagSizer * m_gbsArcByCSA
wxGridBagSizer * m_gbsArcBySME
wxStaticText * m_fillLabel
wxStaticText * m_cornerRadiusLabel
DIALOG_SHAPE_PROPERTIES_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("%s Properties"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
PCB_BASE_EDIT_FRAME * m_parent
UNIT_BINDER m_cornerRadius
DIALOG_SHAPE_PROPERTIES(SCH_BASE_FRAME *aParent, SCH_SHAPE *aShape)
UNIT_BINDER m_solderMaskMargin
std::unique_ptr< GEOM_SYNCER > m_geomSync
bool TransferDataToWindow() override
void onCornerRadius(wxCommandEvent &event) override
~DIALOG_SHAPE_PROPERTIES() override=default
void onRoundedRectChanged(wxCommandEvent &event) override
std::vector< BOUND_CONTROL > m_boundCtrls
void onLayerSelection(wxCommandEvent &event) override
void onTechLayersChanged(wxCommandEvent &event) override
bool TransferDataFromWindow() override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
The base class for create windows for drawing purpose.
UI_FILL_MODE GetFillModeProp() const
int GetEllipseMinorRadius() const
const VECTOR2I & GetBezierC2() const
const VECTOR2I & GetEllipseCenter() const
void SetCenter(const VECTOR2I &aCenter)
EDA_ANGLE GetEllipseEndAngle() const
int GetEllipseMajorRadius() const
EDA_ANGLE GetEllipseRotation() const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
EDA_ANGLE GetEllipseStartAngle() const
const VECTOR2I & GetBezierC1() const
int GetCornerRadius() const
VECTOR2I GetArcMid() const
void updateAll() override
ELLIPSE_ARC_GEOM_SYNCER(PCB_SHAPE &aShape, std::vector< BOUND_CONTROL > &aBoundCtrls)
bool Validate(wxArrayString &aErrs) const override
bool Validate(wxArrayString &aErrs) const override
void updateAll() override
ELLIPSE_GEOM_SYNCER(PCB_SHAPE &aShape, std::vector< BOUND_CONTROL > &aBoundCtrls)
static const TOOL_EVENT SelectedEvent
void ChangeValue(size_t aIndex, int aValue)
wxTextCtrl * GetCtrl(size_t aIndex) const
EDA_ANGLE GetAngleValue(size_t aIndex) const
void BindCtrls(size_t aFrom, size_t aTo, std::function< void()> aCb)
void SetShape(PCB_SHAPE &aShape)
virtual void updateAll()=0
int GetIntValue(size_t aIndex) const
virtual bool Validate(wxArrayString &aErrs) const
const PCB_SHAPE & GetShape() const
void ChangeAngleValue(size_t aIndex, const EDA_ANGLE &aValue)
std::vector< BOUND_CONTROL > & m_boundCtrls
GEOM_SYNCER(PCB_SHAPE &aShape, std::vector< BOUND_CONTROL > &aBoundCtrls)
void ListSet(const wxString &aList)
Add a list of items.
void updateStartMidpoint()
LINE_GEOM_SYNCER(PCB_SHAPE &aShape, std::vector< BOUND_CONTROL > &aBoundCtrls)
void OnStartMidpointChange()
void updateAll() override
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllLayersMask()
Common, abstract interface for edit frames.
void ShowGraphicItemPropertiesDialog(PCB_SHAPE *aShape)
virtual PCB_LAYER_ID GetActiveLayer() const
The main frame for Pcbnew.
void SetEllipseCenter(const VECTOR2I &aPt) override
void SetBezierC1(const VECTOR2I &aPt) override
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
void SetEllipseStartAngle(const EDA_ANGLE &aA) override
void SetEllipseEndAngle(const EDA_ANGLE &aA) override
void SetEnd(const VECTOR2I &aEnd) override
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
void SetEllipseRotation(const EDA_ANGLE &aA) override
void SetEllipseMinorRadius(int aR) override
STROKE_PARAMS GetStroke() const override
void SetStart(const VECTOR2I &aStart) override
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
void SetBezierC2(const VECTOR2I &aPt) override
void SetEllipseMajorRadius(int aR) override
Class that keeps a rectangle's various fields all up to date.
void updateAll() override
bool Validate(wxArrayString &aErrs) const override
void OnCenterSizeChange()
int GetRectangleWidth() const
RECTANGLE_GEOM_SYNCER(PCB_SHAPE &aShape, std::vector< BOUND_CONTROL > &aBoundCtrls)
void OnCornerSizeChange()
int GetRectangleHeight() const
virtual void ChangeValue(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion WITHOUT trigger...
double Distance(const VECTOR2< extended_type > &aVector) const
Compute the distance between two vectors.
static constexpr EDA_ANGLE ANGLE_0
#define IN_EDIT
Item currently edited.
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
bool IsExternalCopperLayer(int aLayerId)
Test whether a layer is an external (F_Cu or B_Cu) copper layer.
PCB_LAYER_ID ToLAYER_ID(int aLayer)
This file contains miscellaneous commonly used macros and functions.
#define UNIMPLEMENTED_FOR(type)
KICOMMON_API wxFont GetSmallInfoFont(wxWindow *aWindow)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
static void AddXYPointToSizer(EDA_DRAW_FRAME &aFrame, wxGridBagSizer &aSizer, int row, int col, const wxString &aName, bool aRelative, std::vector< BOUND_CONTROL > &aBoundCtrls)
void AddFieldToSizer(EDA_DRAW_FRAME &aFrame, wxGridBagSizer &aSizer, int row, int col, const wxString &aName, ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType, bool aIsAngle, std::vector< BOUND_CONTROL > &aBoundCtrls)
static std::map< SHAPE_T, int > s_lastTabForShape
static bool isCopper(const PNS::ITEM *aItem)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
const std::map< LINE_STYLE, struct LINE_STYLE_DESC > lineTypeNames
Conversion map between LINE_STYLE values and style names displayed.
std::unique_ptr< UNIT_BINDER > m_Binder
VECTOR2I GetRotated(const VECTOR2I &aVector, const EDA_ANGLE &aAngle)
Return a new VECTOR2I that is the result of rotating aVector by aAngle.
const VECTOR2I CalcArcCenter(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Determine the center of an arc or circle given three points on its circumference.
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D