75 void BindCtrls(
size_t aFrom,
size_t aTo, std::function<
void()> aCb )
80 for(
size_t i = aFrom; i <= aTo; ++i )
83 [aCb]( wxCommandEvent& aEvent )
96 virtual bool Validate( wxArrayString& aErrs )
const {
return true; }
110 return static_cast<int>(
m_boundCtrls[aIndex].m_Binder->GetValue() );
128 m_boundCtrls[aIndex].m_Binder->ChangeAngleValue( aValue );
168 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
190 bool Validate( wxArrayString& aErrs )
const override
197 aErrs.push_back(
_(
"Rectangle cannot be zero-sized." ) );
306 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
434 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
450 bool Validate( wxArrayString& aErrs )
const override
456 aErrs.push_back(
_(
"Arc angle must be greater than 0" ) );
464 if( start == mid || mid ==
end || start ==
end )
466 aErrs.push_back(
_(
"Arc must have 3 distinct points" ) );
477 if( max_offset >= ( std::numeric_limits<VECTOR2I::coord_type>::max() / 2.0 )
478 || center_i == start || center_i ==
end )
480 aErrs.push_back( wxString::Format(
_(
"Invalid Arc with radius %f and angle %f." ),
566 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
588 bool Validate( wxArrayString& aErrs )
const override
592 aErrs.push_back(
_(
"Radius must be greater than 0" ) );
663 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
673 bool Validate( wxArrayString& aErrs )
const override
677 aErrs.push_back(
_(
"Major radius must be greater than 0" ) );
683 aErrs.push_back(
_(
"Minor radius must be greater than 0" ) );
741 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
751 bool Validate( wxArrayString& aErrs )
const override
755 aErrs.push_back(
_(
"Major radius must be greater than 0" ) );
761 aErrs.push_back(
_(
"Minor radius must be greater than 0" ) );
825 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
926 const wxString& aName,
bool aRelative, std::vector<BOUND_CONTROL>& aBoundCtrls )
931 wxWindow* parent = aSizer.GetContainingWindow();
933 wxStaticText* titleLabel =
new wxStaticText( parent, wxID_ANY, aName );
934 aSizer.Add( titleLabel, wxGBPosition( row, col ), wxGBSpan( 1, 3 ),
935 wxALIGN_CENTER_VERTICAL | wxALIGN_CENTER_HORIZONTAL | wxALL | wxEXPAND );
938 for(
size_t coord = 0; coord < 2; ++coord )
940 wxStaticText* label =
new wxStaticText( parent, wxID_ANY, coord == 0 ?
_(
"X:" ) :
_(
"Y:" ) );
941 aSizer.Add( label, wxGBPosition( row, col ), wxDefaultSpan,
942 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT, col > 0 ? 20 : 5 );
944 wxTextCtrl* ctrl =
new wxTextCtrl( parent, wxID_ANY,
"" );
945 aSizer.Add( ctrl, wxGBPosition( row, col + 1 ), wxDefaultSpan,
946 wxEXPAND | wxALIGN_CENTER_VERTICAL, 5 );
948 wxStaticText* units =
new wxStaticText( parent, wxID_ANY,
_(
"mm" ) );
949 aSizer.Add( units, wxGBPosition( row, col + 2 ), wxDefaultSpan,
950 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 );
952 auto binder = std::make_unique<UNIT_BINDER>( &aFrame, label, ctrl, units );
959 aBoundCtrls.push_back(
BOUND_CONTROL{ std::move( binder ), ctrl } );
963 if( !aSizer.IsColGrowable( col + 1 ) )
964 aSizer.AddGrowableCol( col + 1 );
970 bool aIsAngle, std::vector<BOUND_CONTROL>& aBoundCtrls )
973 wxWindow* parent = aSizer.GetContainingWindow();
975 wxStaticText* label =
new wxStaticText( parent, wxID_ANY, aName + wxS(
":" ) );
976 aSizer.Add( label, wxGBPosition( row, col ), wxDefaultSpan,
977 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT, col > 0 ? 20 : 5 );
979 wxTextCtrl* ctrl =
new wxTextCtrl( parent, wxID_ANY );
980 aSizer.Add( ctrl, wxGBPosition( row, col + 1 ), wxDefaultSpan,
981 wxEXPAND | wxALIGN_CENTER_VERTICAL, 5 );
983 wxStaticText* units =
new wxStaticText( parent, wxID_ANY,
_(
"mm" ) );
984 aSizer.Add( units, wxGBPosition( row, col + 2 ), wxDefaultSpan,
985 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 );
987 auto binder = std::make_unique<UNIT_BINDER>( &aFrame, label, ctrl, units );
988 binder->SetCoordType( aCoordType );
992 binder->SetPrecision( 4 );
996 aBoundCtrls.push_back(
BOUND_CONTROL{ std::move( binder ), ctrl } );
998 if( !aSizer.IsColGrowable( col + 1 ) )
999 aSizer.AddGrowableCol( col + 1 );
1015 SetTitle( wxString::Format( GetTitle(),
m_item->GetFriendlyName() ) );
1023 std::set<int> shownPages;
1025 const auto showPage =
1026 [&]( wxSizer& aMainSizer,
bool aSelect = false )
1029 wxWindow* page = aMainSizer.GetContainingWindow();
1034 shownPages.insert( pageIdx );
1040 switch(
m_item->GetShape() )
1175 wxFAIL_MSG(
"Undefined shape" );
1182 if( shownPages.count( i ) == 0 )
1219 for(
const auto& [ lineStyle, lineStyleDesc ] :
lineTypeNames )
1250 wxCHECK_RET( aShape, wxT(
"ShowGraphicItemPropertiesDialog() error: NULL item" ) );
1321 int style =
static_cast<int>(
m_item->GetStroke().GetLineStyle() );
1332 if(
m_item->GetLocalSolderMaskMargin().has_value() )
1339 int net =
m_item->GetNetCode();
1355 return DIALOG_SHAPE_PROPERTIES_BASE::TransferDataToWindow();
1361 if( !DIALOG_SHAPE_PROPERTIES_BASE::TransferDataFromWindow() )
1372 bool pushCommit = (
m_item->GetEditFlags() == 0 );
1381 bool wasLocked =
m_item->IsLocked();
1397 m_item->SetLineStyle( it->first );
1404 m_item->SetLocalSolderMaskMargin( {} );
1408 m_item->RebuildBezierToSegmentsPointsList(
m_item->GetMaxError() );
1410 if(
m_item->IsOnCopperLayer() )
1413 m_item->SetNetCode( -1 );
1416 commit.Push(
_(
"Edit Shape Properties" ) );
1422 if( wasLocked !=
m_item->IsLocked() )
1431 wxArrayString errors;
1433 if( !DIALOG_SHAPE_PROPERTIES_BASE::Validate() )
1440 switch(
m_item->GetShape() )
1444 errors.Add(
_(
"Line width must be greater than zero." ) );
1449 errors.Add(
_(
"Line width must be greater than zero for an unfilled circle." ) );
1456 errors.Add(
_(
"Line width must be greater than zero for an unfilled rectangle." ) );
1458 int shortSide = std::min(
m_item->GetRectangleWidth(),
m_item->GetRectangleHeight() );
1462 errors.Add(
_(
"Corner radius must be less than or equal to half the smaller side." ) );
1471 errors.Add(
_(
"Line width must be greater than zero for an unfilled polygon." ) );
1477 errors.Add(
_(
"Line width must be greater than zero." ) );
1483 errors.Add(
_(
"Line width must be greater than zero for an unfilled curve." ) );
1489 errors.Add(
_(
"Line width must be greater than zero for an unfilled ellipse." ) );
1495 errors.Add(
_(
"Line width must be greater than zero." ) );
1504 if( errors.GetCount() )
1511 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.
void updateAll() override
bool Validate(wxArrayString &aErrs) const override
void OnCenterSizeChange()
RECTANGLE_GEOM_SYNCER(PCB_SHAPE &aShape, std::vector< BOUND_CONTROL > &aBoundCtrls)
void OnCornerSizeChange()
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