76 void BindCtrls(
size_t aFrom,
size_t aTo, std::function<
void()> aCb )
81 for(
size_t i = aFrom; i <= aTo; ++i )
84 [aCb]( wxCommandEvent& aEvent )
97 virtual bool Validate( wxArrayString& aErrs )
const {
return true; }
111 return static_cast<int>(
m_boundCtrls[aIndex].m_Binder->GetValue() );
129 m_boundCtrls[aIndex].m_Binder->ChangeAngleValue( aValue );
169 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
191 bool Validate( wxArrayString& aErrs )
const override
198 aErrs.push_back(
_(
"Rectangle cannot be zero-sized." ) );
311 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
439 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
455 bool Validate( wxArrayString& aErrs )
const override
461 aErrs.push_back(
_(
"Arc angle must be greater than 0" ) );
469 if( start == mid || mid ==
end || start ==
end )
471 aErrs.push_back(
_(
"Arc must have 3 distinct points" ) );
482 if( max_offset >= ( std::numeric_limits<VECTOR2I::coord_type>::max() / 2.0 )
483 || center_i == start || center_i ==
end )
485 aErrs.push_back( wxString::Format(
_(
"Invalid Arc with radius %f and angle %f." ),
571 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
593 bool Validate( wxArrayString& aErrs )
const override
597 aErrs.push_back(
_(
"Radius must be greater than 0" ) );
668 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
678 bool Validate( wxArrayString& aErrs )
const override
682 aErrs.push_back(
_(
"Major radius must be greater than 0" ) );
688 aErrs.push_back(
_(
"Minor radius must be greater than 0" ) );
746 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
756 bool Validate( wxArrayString& aErrs )
const override
760 aErrs.push_back(
_(
"Major radius must be greater than 0" ) );
766 aErrs.push_back(
_(
"Minor radius must be greater than 0" ) );
830 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
931 const wxString& aName,
bool aRelative, std::vector<BOUND_CONTROL>& aBoundCtrls )
936 wxWindow* parent = aSizer.GetContainingWindow();
938 wxStaticText* titleLabel =
new wxStaticText( parent, wxID_ANY, aName );
939 aSizer.Add( titleLabel, wxGBPosition( row, col ), wxGBSpan( 1, 3 ),
940 wxALIGN_CENTER_VERTICAL | wxALIGN_CENTER_HORIZONTAL | wxALL | wxEXPAND );
943 for(
size_t coord = 0; coord < 2; ++coord )
945 wxStaticText* label =
new wxStaticText( parent, wxID_ANY, coord == 0 ?
_(
"X:" ) :
_(
"Y:" ) );
946 aSizer.Add( label, wxGBPosition( row, col ), wxDefaultSpan,
947 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT, col > 0 ? 20 : 5 );
949 wxTextCtrl* ctrl =
new wxTextCtrl( parent, wxID_ANY,
"" );
950 aSizer.Add( ctrl, wxGBPosition( row, col + 1 ), wxDefaultSpan,
951 wxEXPAND | wxALIGN_CENTER_VERTICAL, 5 );
953 wxStaticText* units =
new wxStaticText( parent, wxID_ANY,
_(
"mm" ) );
954 aSizer.Add( units, wxGBPosition( row, col + 2 ), wxDefaultSpan,
955 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 );
957 auto binder = std::make_unique<UNIT_BINDER>( &aFrame, label, ctrl, units );
964 aBoundCtrls.push_back(
BOUND_CONTROL{ std::move( binder ), ctrl } );
968 if( !aSizer.IsColGrowable( col + 1 ) )
969 aSizer.AddGrowableCol( col + 1 );
975 bool aIsAngle, std::vector<BOUND_CONTROL>& aBoundCtrls )
978 wxWindow* parent = aSizer.GetContainingWindow();
980 wxStaticText* label =
new wxStaticText( parent, wxID_ANY, aName + wxS(
":" ) );
981 aSizer.Add( label, wxGBPosition( row, col ), wxDefaultSpan,
982 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT, col > 0 ? 20 : 5 );
984 wxTextCtrl* ctrl =
new wxTextCtrl( parent, wxID_ANY );
985 aSizer.Add( ctrl, wxGBPosition( row, col + 1 ), wxDefaultSpan,
986 wxEXPAND | wxALIGN_CENTER_VERTICAL, 5 );
988 wxStaticText* units =
new wxStaticText( parent, wxID_ANY,
_(
"mm" ) );
989 aSizer.Add( units, wxGBPosition( row, col + 2 ), wxDefaultSpan,
990 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 );
992 auto binder = std::make_unique<UNIT_BINDER>( &aFrame, label, ctrl, units );
993 binder->SetCoordType( aCoordType );
997 binder->SetPrecision( 4 );
1001 aBoundCtrls.push_back(
BOUND_CONTROL{ std::move( binder ), ctrl } );
1003 if( !aSizer.IsColGrowable( col + 1 ) )
1004 aSizer.AddGrowableCol( col + 1 );
1020 SetTitle( wxString::Format( GetTitle(),
m_item->GetFriendlyName() ) );
1028 std::set<int> shownPages;
1030 const auto showPage =
1031 [&]( wxSizer& aMainSizer,
bool aSelect = false )
1034 wxWindow* page = aMainSizer.GetContainingWindow();
1039 shownPages.insert( pageIdx );
1045 switch(
m_item->GetShape() )
1180 wxFAIL_MSG(
"Undefined shape" );
1187 if( shownPages.count( i ) == 0 )
1224 for(
const auto& [ lineStyle, lineStyleDesc ] :
lineTypeNames )
1255 wxCHECK_RET( aShape, wxT(
"ShowGraphicItemPropertiesDialog() error: NULL item" ) );
1326 int style =
static_cast<int>(
m_item->GetStroke().GetLineStyle() );
1337 if(
m_item->GetLocalSolderMaskMargin().has_value() )
1344 int net =
m_item->GetNetCode();
1360 return DIALOG_SHAPE_PROPERTIES_BASE::TransferDataToWindow();
1366 if( !DIALOG_SHAPE_PROPERTIES_BASE::TransferDataFromWindow() )
1377 bool pushCommit = (
m_item->GetEditFlags() == 0 );
1386 bool wasLocked =
m_item->IsLocked();
1402 m_item->SetLineStyle( it->first );
1409 m_item->SetLocalSolderMaskMargin( {} );
1413 m_item->RebuildBezierToSegmentsPointsList(
m_item->GetMaxError() );
1415 if(
m_item->IsOnCopperLayer() )
1418 m_item->SetNetCode( -1 );
1421 commit.Push(
_(
"Edit Shape Properties" ) );
1427 if( wasLocked !=
m_item->IsLocked() )
1436 wxArrayString errors;
1438 if( !DIALOG_SHAPE_PROPERTIES_BASE::Validate() )
1445 switch(
m_item->GetShape() )
1449 errors.Add(
_(
"Line width must be greater than zero." ) );
1454 errors.Add(
_(
"Line width must be greater than zero for an unfilled circle." ) );
1461 errors.Add(
_(
"Line width must be greater than zero for an unfilled rectangle." ) );
1468 errors.Add(
_(
"Corner radius must be less than or equal to half the smaller side." ) );
1477 errors.Add(
_(
"Line width must be greater than zero for an unfilled polygon." ) );
1483 errors.Add(
_(
"Line width must be greater than zero." ) );
1489 errors.Add(
_(
"Line width must be greater than zero for an unfilled curve." ) );
1495 errors.Add(
_(
"Line width must be greater than zero for an unfilled ellipse." ) );
1501 errors.Add(
_(
"Line width must be greater than zero." ) );
1510 if( errors.GetCount() )
1517 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
void SetEllipseRotation(const EDA_ANGLE &aA)
int GetEllipseMinorRadius() const
const VECTOR2I & GetBezierC2() const
const VECTOR2I & GetEllipseCenter() const
void SetBezierC2(const VECTOR2I &aPt)
void SetCenter(const VECTOR2I &aCenter)
void SetEllipseCenter(const VECTOR2I &aPt)
EDA_ANGLE GetEllipseEndAngle() const
int GetEllipseMajorRadius() const
void SetEllipseStartAngle(const EDA_ANGLE &aA)
EDA_ANGLE GetEllipseRotation() const
void SetEllipseEndAngle(const EDA_ANGLE &aA)
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
void SetStart(const VECTOR2I &aStart)
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
EDA_ANGLE GetEllipseStartAngle() const
void SetEnd(const VECTOR2I &aEnd)
void SetBezierC1(const VECTOR2I &aPt)
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
const VECTOR2I & GetBezierC1() const
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
void SetEllipseMajorRadius(int aR)
int GetCornerRadius() const
void SetEllipseMinorRadius(int aR)
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.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
STROKE_PARAMS GetStroke() const override
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
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