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 );
447 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
469 bool Validate( wxArrayString& aErrs )
const override
475 aErrs.push_back(
_(
"Arc angle must be greater than 0" ) );
481 aErrs.push_back(
_(
"Radius must be greater than 0" ) );
489 if( start == mid || mid ==
end )
491 aErrs.push_back(
_(
"Arc must have at least 2 distinct points" ) );
498 const double radius = (
center - start ).EuclideanNorm();
502 if( max_offset >= ( std::numeric_limits<VECTOR2I::coord_type>::max() / 2.0 ) || center_i == start
505 aErrs.push_back( wxString::Format(
_(
"Invalid Arc with radius %f and angle %f." ),
586 EDA_ANGLE sweep = ( end_angle - start_angle ).Normalize();
637 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
659 bool Validate( wxArrayString& aErrs )
const override
663 aErrs.push_back(
_(
"Radius must be greater than 0" ) );
734 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
744 bool Validate( wxArrayString& aErrs )
const override
748 aErrs.push_back(
_(
"Major radius must be greater than 0" ) );
754 aErrs.push_back(
_(
"Minor radius must be greater than 0" ) );
812 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
822 bool Validate( wxArrayString& aErrs )
const override
826 aErrs.push_back(
_(
"Major radius must be greater than 0" ) );
832 aErrs.push_back(
_(
"Minor radius must be greater than 0" ) );
896 wxASSERT( aBoundCtrls.size() ==
NUM_CTRLS );
1034 wxCHECK_RET(
m_upperSizer, wxT(
"Shape properties dialog has no upper sizer" ) );
1038 wxGridBagSizer* gbSizerEndings =
new wxGridBagSizer( 3, 0 );
1039 gbSizerEndings->SetFlexibleDirection( wxBOTH );
1040 gbSizerEndings->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
1044 gbSizerEndings->Add(
m_startShapeLabel, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL | wxRIGHT,
1047 m_startShapeChoice =
new wxBitmapComboBox(
this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0,
1048 nullptr, wxCB_READONLY );
1049 gbSizerEndings->Add(
m_startShapeChoice, wxGBPosition( 0, 1 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL | wxEXPAND,
1054 gbSizerEndings->Add(
m_endShapeLabel, wxGBPosition( 0, 4 ), wxGBSpan( 1, 1 ),
1055 wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5 );
1057 m_endShapeChoice =
new wxBitmapComboBox(
this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0,
1058 nullptr, wxCB_READONLY );
1059 gbSizerEndings->Add(
m_endShapeChoice, wxGBPosition( 0, 5 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL | wxEXPAND,
1062 auto addEndingValue = [&](
int aRow,
int aCol,
const wxString& aLabel, wxStaticText*& aLabelCtrl,
1063 wxTextCtrl*& aValueCtrl, wxStaticText*& aUnitsCtrl,
int aFlags )
1065 aLabelCtrl =
new wxStaticText(
this, wxID_ANY, aLabel );
1066 aLabelCtrl->Wrap( -1 );
1067 gbSizerEndings->Add( aLabelCtrl, wxGBPosition( aRow, aCol ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL | aFlags,
1070 aValueCtrl =
new wxTextCtrl(
this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1, -1 ), 0 );
1071 gbSizerEndings->Add( aValueCtrl, wxGBPosition( aRow, aCol + 1 ), wxGBSpan( 1, 1 ),
1072 wxALIGN_CENTER_VERTICAL | wxEXPAND, 5 );
1074 aUnitsCtrl =
new wxStaticText(
this, wxID_ANY,
_(
"unit" ) );
1075 aUnitsCtrl->Wrap( -1 );
1076 aUnitsCtrl->SetMinSize( wxSize( 60, -1 ) );
1077 gbSizerEndings->Add( aUnitsCtrl, wxGBPosition( aRow, aCol + 2 ), wxGBSpan( 1, 1 ),
1078 wxALIGN_CENTER_VERTICAL | wxLEFT, 3 );
1090 gbSizerEndings->AddGrowableCol( 1 );
1091 gbSizerEndings->AddGrowableCol( 5 );
1101 wxColour fg = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
1102 wxColour bg = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
1103 wxSize iconSize( 80, 24 );
1117 for(
const auto& item : shapeItems )
1148 SetTitle( wxString::Format( GetTitle(),
m_item->GetFriendlyName() ) );
1158 std::set<int> shownPages;
1160 const auto showPage =
1161 [&]( wxSizer& aMainSizer,
bool aSelect = false )
1164 wxWindow* page = aMainSizer.GetContainingWindow();
1169 shownPages.insert( pageIdx );
1175 switch(
m_item->GetShape() )
1301 wxFAIL_MSG(
"Undefined shape" );
1308 if( shownPages.count( i ) == 0 )
1345 for(
const auto& [ lineStyle, lineStyleDesc ] :
lineTypeNames )
1377 m_endingsHelpLabel->SetLabel( wxString::Format(
_(
"Shape sizes of 0 = auto (%g\u00d7 line width)." ),
1389 wxCHECK_RET( aShape, wxT(
"ShowGraphicItemPropertiesDialog() error: NULL item" ) );
1460 int style =
static_cast<int>(
m_item->GetStroke().GetLineStyle() );
1471 if(
m_item->GetLocalSolderMaskMargin().has_value() )
1478 int net =
m_item->GetNetCode();
1507 return DIALOG_SHAPE_PROPERTIES_BASE::TransferDataToWindow();
1513 if( !DIALOG_SHAPE_PROPERTIES_BASE::TransferDataFromWindow() )
1524 bool pushCommit = (
m_item->GetEditFlags() == 0 );
1533 bool wasLocked =
m_item->IsLocked();
1549 m_item->SetLineStyle( it->first );
1556 m_item->SetLocalSolderMaskMargin( {} );
1592 m_item->RebuildBezierToSegmentsPointsList(
m_item->GetMaxError() );
1594 if(
m_item->IsOnCopperLayer() )
1597 m_item->SetNetCode( -1 );
1600 commit.Push(
_(
"Edit Shape Properties" ) );
1606 if( wasLocked !=
m_item->IsLocked() )
1615 wxArrayString errors;
1617 if( !DIALOG_SHAPE_PROPERTIES_BASE::Validate() )
1624 switch(
m_item->GetShape() )
1628 errors.Add(
_(
"Line width must be greater than zero." ) );
1633 errors.Add(
_(
"Line width must be greater than zero for an unfilled circle." ) );
1640 errors.Add(
_(
"Line width must be greater than zero for an unfilled rectangle." ) );
1647 errors.Add(
_(
"Corner radius must be less than or equal to half the smaller side." ) );
1656 errors.Add(
_(
"Line width must be greater than zero for an unfilled polygon." ) );
1662 errors.Add(
_(
"Line width must be greater than zero." ) );
1668 errors.Add(
_(
"Line width must be greater than zero for an unfilled curve." ) );
1674 errors.Add(
_(
"Line width must be greater than zero for an unfilled ellipse." ) );
1680 errors.Add(
_(
"Line width must be greater than zero." ) );
1689 if( errors.GetCount() )
1696 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
wxBoxSizer * m_upperSizer
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
wxGridBagSizer * m_gbsArcByCRAA
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)
std::unique_ptr< UNIT_BINDER > m_endWidth
wxBitmapComboBox * m_startShapeChoice
std::unique_ptr< UNIT_BINDER > m_startWidth
PCB_BASE_EDIT_FRAME * m_parent
wxStaticText * m_endShapeLabel
UNIT_BINDER m_cornerRadius
void createLineEndingControls(SCH_BASE_FRAME *aParent)
wxBoxSizer * m_endingsSizer
wxBitmapComboBox * m_endShapeChoice
wxStaticText * m_endWidthUnits
DIALOG_SHAPE_PROPERTIES(SCH_BASE_FRAME *aParent, SCH_SHAPE *aShape)
UNIT_BINDER m_solderMaskMargin
std::unique_ptr< UNIT_BINDER > m_startStrokeWidth
std::unique_ptr< UNIT_BINDER > m_startLength
wxTextCtrl * m_startWidthCtrl
std::unique_ptr< UNIT_BINDER > m_endLength
std::unique_ptr< GEOM_SYNCER > m_geomSync
bool TransferDataToWindow() override
wxTextCtrl * m_endLengthCtrl
void onCornerRadius(wxCommandEvent &event) override
wxStaticText * m_startWidthUnits
~DIALOG_SHAPE_PROPERTIES() override=default
wxStaticText * m_endStrokeWidthUnits
wxStaticText * m_endWidthLabel
wxTextCtrl * m_startStrokeWidthCtrl
wxStaticText * m_startStrokeWidthLabel
wxStaticText * m_endStrokeWidthLabel
wxStaticText * m_startLengthUnits
void onRoundedRectChanged(wxCommandEvent &event) override
std::unique_ptr< UNIT_BINDER > m_endStrokeWidth
wxStaticText * m_startStrokeWidthUnits
std::vector< BOUND_CONTROL > m_boundCtrls
wxTextCtrl * m_endStrokeWidthCtrl
wxStaticText * m_endLengthUnits
void onLayerSelection(wxCommandEvent &event) override
wxTextCtrl * m_endWidthCtrl
void onTechLayersChanged(wxCommandEvent &event) override
wxStaticText * m_startLengthLabel
wxStaticText * m_endLengthLabel
bool TransferDataFromWindow() override
wxStaticText * m_startShapeLabel
wxTextCtrl * m_startLengthCtrl
wxStaticText * m_startWidthLabel
wxStaticText * m_endingsHelpLabel
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...
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.
static constexpr double DEFAULT_RATIO_LENGTH
static const int s_defaultChoiceCount
static const LINE_ENDING_STYLE s_defaultChoiceOrder[]
Dropdown display order for line ending style choosers.
static int StyleToChoiceIndex(LINE_ENDING_STYLE aStyle)
Return the dropdown index for the given style, or 0 (NONE) if not found.
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
static constexpr EDA_ANGLE ANGLE_360
#define IN_EDIT
Item currently edited.
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
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)
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.
LINE_ENDING_STYLE
Line ending styles for graphic lines, arcs, and beziers.
wxBitmap MakeLineEndingBitmap(LINE_ENDING_STYLE aStyle, const wxSize &aSize, const wxColour &aForeground, const wxColour &aBackground, wxWindow *aWindow, bool aShapeOnRight)
Generate a DPI-aware bitmap icon showing a line ending style.
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 std::map< SHAPE_T, int > s_lastTabForShape
static bool isOpenShape(SHAPE_T aShape)
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.
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