KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_constraint_value.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21
22#include <confirm.h>
23#include <pcb_base_frame.h>
24#include <board.h>
25#include <board_commit.h>
26#include <pcb_shape.h>
28#include <widgets/unit_binder.h>
29
30
32 double aValue, bool aDriving ) :
34 m_type( aType ),
36{
37 if( m_isAngle )
38 m_valueLabel->SetLabel( _( "Angle:" ) );
39
40 m_drivingCtrl->SetValue( aDriving );
41
43
44 if( m_isAngle )
45 {
47 m_valueBinder->SetAngleValue( EDA_ANGLE( aValue, DEGREES_T ) );
48 }
49 else
50 {
51 m_valueBinder->SetValue( static_cast<long long int>( aValue ) );
52 }
53
54 m_drivingCtrl->Bind( wxEVT_CHECKBOX, [this]( wxCommandEvent& ) { updateValueEnabled(); } );
56
58}
59
60
62{
63 // A reference dimension reports the measured geometry, so its value cannot be typed.
64 bool driving = m_drivingCtrl->GetValue();
65
66 m_valueCtrl->Enable( driving );
67 m_valueUnits->Enable( driving );
68}
69
70
75
76
78{
79 if( m_isAngle )
80 return m_valueBinder->GetAngleValue().AsDegrees();
81
82 return static_cast<double>( m_valueBinder->GetValue() );
83}
84
85
87{
88 return m_drivingCtrl->GetValue();
89}
90
91
93{
94 const bool driving = GetDriving();
95
96 if( m_isAngle && driving )
97 {
99 {
100 // An arc's swept angle spans a full turn, but 0 and 360 are degenerate.
101 double degrees = m_valueBinder->GetAngleValue().AsDegrees();
102
103 if( degrees <= 0.0 || degrees >= 360.0 )
104 {
105 DisplayError( this, _( "Enter an arc angle between 0 and 360 degrees." ) );
106 return false;
107 }
108 }
109 // A corner angle is undirected, so only [0, 180] is meaningful.
110 else if( !m_valueBinder->Validate( 0.0, 180.0, EDA_UNITS::DEGREES ) )
111 {
112 return false;
113 }
114 }
115
116 // A zero or negative driving length or radius is degenerate geometry the solver can only
117 // fail on, so refuse it at entry like the angle ranges above.
118 if( !m_isAngle && driving && m_valueBinder->GetValue() <= 0 )
119 {
120 DisplayError( this, _( "Enter a value greater than zero." ) );
121 return false;
122 }
123
124 return DIALOG_CONSTRAINT_VALUE_BASE::TransferDataFromWindow();
125}
126
127
128bool EditConstraintValue( PCB_BASE_FRAME* aFrame, PCB_CONSTRAINT* aConstraint, BOARD_COMMIT& aCommit )
129{
130 if( !aConstraint || !aConstraint->HasValue() )
131 return false;
132
133 DIALOG_CONSTRAINT_VALUE dlg( aFrame, aConstraint->GetConstraintType(), *aConstraint->GetValue(),
134 aConstraint->IsDriving() );
135
136 if( dlg.ShowModal() != wxID_OK )
137 return false;
138
139 aCommit.Modify( aConstraint );
140 aConstraint->SetValue( dlg.GetConstraintValue() );
141 aConstraint->SetDriving( dlg.GetDriving() );
142
143 // Snap the geometry to the new value in the same commit, the way creation does -- otherwise a
144 // driving length/radius/angle change is stored but the shapes keep their old size.
145 ApplyConstraintImmediately( aFrame->GetBoard(), aConstraint, nullptr,
146 [&]( BOARD_ITEM* aItem ) { aCommit.Modify( aItem ); } );
147
148 aCommit.Push( _( "Edit Geometric Constraint" ) );
149 return true;
150}
CONSTRAINT_DIAGNOSIS ApplyConstraintImmediately(BOARD *aBoard, const PCB_CONSTRAINT *aConstraint, std::vector< PCB_SHAPE * > *aModified, const std::function< void(BOARD_ITEM *)> &aBeforeModify)
Solve a just-created constraint's cluster so the geometry snaps to satisfy it (SolidWorks-style),...
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:83
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition commit.h:102
DIALOG_CONSTRAINT_VALUE_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Constraint Value"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE)
Value entry for a dimensional geometric constraint (issue #2329): a UNIT_BINDER for the length (or an...
bool GetDriving() const
True if the constraint should drive (lock) the geometry; false for a reference dimension.
DIALOG_CONSTRAINT_VALUE(PCB_BASE_FRAME *aParent, PCB_CONSTRAINT_TYPE aType, double aValue, bool aDriving)
double GetConstraintValue()
The entered value, in IU for a length/radius or in degrees for an angle.
bool TransferDataFromWindow() override
Veto an angle outside the closed [0, 180] degree corner-angle range.
void updateValueEnabled()
A reference (non-driving) constraint only measures, so its value is read-only.
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
int ShowModal() override
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
BOARD * GetBoard() const
A geometric constraint between board items (issue #2329).
std::optional< double > GetValue() const
bool IsDriving() const
A driving constraint forces its value; a reference (non-driving) one only measures it.
PCB_CONSTRAINT_TYPE GetConstraintType() const
bool HasValue() const
void SetValue(std::optional< double > aValue)
void SetDriving(bool aDriving)
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition confirm.cpp:192
This file is part of the common library.
bool EditConstraintValue(PCB_BASE_FRAME *aFrame, PCB_CONSTRAINT *aConstraint, BOARD_COMMIT &aCommit)
Show the value dialog for a valued constraint and stage the change in aCommit (the caller pushes).
#define _(s)
@ DEGREES_T
Definition eda_angle.h:31
bool ConstraintValueIsLength(PCB_CONSTRAINT_TYPE aType)
True if this type's value is a length in IU (serialized in mm); false for an angle in degrees.
PCB_CONSTRAINT_TYPE
The geometric relationship a PCB_CONSTRAINT enforces between its members.
@ ARC_ANGLE
An arc has a driving or reference swept-angle value.