KiCad PCB EDA Suite
Loading...
Searching...
No Matches
point_editor_behavior.h
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
20
21#pragma once
22
23#include <wx/debug.h>
24
25#include <base_units.h>
27#include <eda_shape.h>
28#include <tool/edit_points.h>
29#include <view/view_controls.h>
30
31class COMMIT;
32class SHAPE_POLY_SET;
33
42{
43public:
44 virtual ~POINT_EDIT_BEHAVIOR() = default;
45
52 virtual void MakePoints( EDIT_POINTS& aPoints ) = 0;
53
68 virtual bool UpdatePoints( EDIT_POINTS& aPoints ) = 0;
69
79 virtual void FinalizeItem( EDIT_POINTS& aPoints, COMMIT& aCommit ) {};
80
96 virtual void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
97 std::vector<EDA_ITEM*>& aUpdatedItems ) = 0;
98
106 virtual OPT_VECTOR2I Get45DegreeConstrainer( const EDIT_POINT& aEditedPoint,
107 EDIT_POINTS& aPoints ) const
108 {
109 // By default, no constrainer is defined and the caller must decide
110 return std::nullopt;
111 }
112
113protected:
117 static bool isModified( const EDIT_POINT& aEditedPoint, const EDIT_POINT& aPoint )
118 {
119 return &aEditedPoint == &aPoint;
120 }
121};
122
123// Helper macros to check the number of points in the edit points object
124// Still a bug, but at least it won't segfault if the number of points is wrong
125#define CHECK_POINT_COUNT( aPoints, aExpected ) \
126 wxCHECK( aPoints.PointsSize() == aExpected, /* void */ )
127#define CHECK_POINT_COUNT_GE( aPoints, aExpected ) \
128 wxCHECK( aPoints.PointsSize() >= aExpected, /* void */ )
129
130
139{
140public:
142 m_polygon( aPolygon )
143 {}
144
148 static void BuildForPolyOutline( EDIT_POINTS& aPoints, const SHAPE_POLY_SET& aOutline );
149
155 static void UpdatePointsFromOutline( const SHAPE_POLY_SET& aOutline, EDIT_POINTS& aPoints );
156
160 static void UpdateOutlineFromPoints( SHAPE_POLY_SET& aOutline, const EDIT_POINT& aEditedPoint,
161 EDIT_POINTS& aPoints );
162
163 void MakePoints( EDIT_POINTS& aPoints ) override
164 {
165 BuildForPolyOutline( aPoints, m_polygon );
166 }
167
168 bool UpdatePoints( EDIT_POINTS& aPoints ) override
169 {
171 return true;
172 }
173
174 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
175 std::vector<EDA_ITEM*>& aUpdatedItems ) override
176 {
177 UpdateOutlineFromPoints( m_polygon, aEditedPoint, aPoints );
178 }
179
180 void FinalizeItem( EDIT_POINTS& aPoints, COMMIT& aCommit ) override;
181
182private:
184};
185
186
195{
196public:
198 m_shape( aPolygon )
199 {
200 wxASSERT( aPolygon.GetShape() == SHAPE_T::POLY );
201 }
202
203 void MakePoints( EDIT_POINTS& aPoints ) override
204 {
206 }
207
208 bool UpdatePoints( EDIT_POINTS& aPoints ) override
209 {
210 // Normalize can fold the polygon into a rectangle, which needs a different editor
211 if( m_shape.GetShape() != SHAPE_T::POLY )
212 return false;
213
215 return true;
216 }
217
218 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
219 std::vector<EDA_ITEM*>& aUpdatedItems ) override
220 {
222 m_shape.GetPolyShape(), aEditedPoint, aPoints );
223 }
224
225 void FinalizeItem( EDIT_POINTS& aPoints, COMMIT& aCommit ) override
226 {
227 m_shape.GetPolyShape().RemoveNullSegments();
228 }
229
230private:
232};
233
234
239{
240public:
242 m_segment( aSegment )
243 {
244 wxASSERT( aSegment.GetShape() == SHAPE_T::SEGMENT );
245 }
246
247 void MakePoints( EDIT_POINTS& aPoints ) override;
248
249 bool UpdatePoints( EDIT_POINTS& aPoints ) override;
250
251 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
252 std::vector<EDA_ITEM*>& aUpdatedItems ) override;
253
255 EDIT_POINTS& aPoints ) const override;
256
257protected:
265
266private:
268};
269
270
275{
276public:
278 m_circle( aCircle )
279 {
280 wxASSERT( aCircle.GetShape() == SHAPE_T::CIRCLE );
281 }
282
283 void MakePoints( EDIT_POINTS& aPoints ) override;
284
285 bool UpdatePoints( EDIT_POINTS& aPoints ) override;
286
287 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
288 std::vector<EDA_ITEM*>& aUpdatedItems ) override;
289
291 EDIT_POINTS& aPoints ) const override;
292
293protected:
301
302private:
304};
305
306
311{
312public:
313 EDA_BEZIER_POINT_EDIT_BEHAVIOR( EDA_SHAPE& aBezier, int aMaxError ) :
314 m_bezier( aBezier ),
315 m_maxError( aMaxError )
316 {
317 wxASSERT( aBezier.GetShape() == SHAPE_T::BEZIER );
318 }
319
320 void MakePoints( EDIT_POINTS& aPoints ) override;
321
322 bool UpdatePoints( EDIT_POINTS& aPoints ) override;
323
324 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
325 std::vector<EDA_ITEM*>& aUpdatedItems ) override;
326
327protected:
337
338private:
341};
342
343
357{
358public:
360 m_ellipse( aEllipse )
361 {
362 wxASSERT( aEllipse.GetShape() == SHAPE_T::ELLIPSE || aEllipse.GetShape() == SHAPE_T::ELLIPSE_ARC );
363 }
364
365 void MakePoints( EDIT_POINTS& aPoints ) override;
366
367 bool UpdatePoints( EDIT_POINTS& aPoints ) override;
368
369 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
370 std::vector<EDA_ITEM*>& aUpdatedItems ) override;
371
372protected:
384
385private:
387
389 VECTOR2I evaluateAt( const EDA_ANGLE& aTheta ) const;
390
392 EDA_ANGLE parametricAngleOf( const VECTOR2I& aWorldPt ) const;
393};
394
395
404{
405public:
407 m_cell( aCell )
408 {
409 // Point editor only supports cardinally-rotated table cells.
410 wxASSERT( aCell.GetShape() == SHAPE_T::RECTANGLE );
411 }
412
413 void MakePoints( EDIT_POINTS& aPoints ) override;
414
415 bool UpdatePoints( EDIT_POINTS& aPoints ) override;
416
417protected:
425
426private:
428};
429
430
435{
436public:
437 EDA_ARC_POINT_EDIT_BEHAVIOR( EDA_SHAPE& aArc, const ARC_EDIT_MODE& aArcEditMode,
438 KIGFX::VIEW_CONTROLS& aViewContols,
439 const EDA_IU_SCALE& aIuScale );
440
441 void MakePoints( EDIT_POINTS& aPoints ) override;
442
443 bool UpdatePoints( EDIT_POINTS& aPoints ) override;
444
445 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
446 std::vector<EDA_ITEM*>& aUpdatedItems ) override;
447
448 OPT_VECTOR2I Get45DegreeConstrainer( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints ) const override;
449
450private:
458
460 // The arc edit mode, which is injected from the editor
463 // IU scale of the owning editor, used to derive the minimum arc radius
465};
466
467
469
470
471namespace KI_ARC_EDIT
472{
479void EditArcEndpointKeepCenter( EDA_SHAPE& aArc, const VECTOR2I& aCenter, const VECTOR2I& aStart,
480 const VECTOR2I& aMid, const VECTOR2I& aEnd, const VECTOR2I& aCursor,
481 const EDA_IU_SCALE& aIuScale );
482
487void EditArcMidKeepCenter( EDA_SHAPE& aArc, const VECTOR2I& aCenter, const VECTOR2I& aStart,
488 const VECTOR2I& aMid, const VECTOR2I& aEnd, const VECTOR2I& aCursor,
489 const EDA_IU_SCALE& aIuScale );
490} // namespace KI_ARC_EDIT
ARC_EDIT_MODE
Settings for arc editing.
Represent a set of changes (additions, deletions or modifications) of a data model (e....
Definition commit.h:68
EDA_ARC_POINT_EDIT_BEHAVIOR(EDA_SHAPE &aArc, const ARC_EDIT_MODE &aArcEditMode, KIGFX::VIEW_CONTROLS &aViewContols, const EDA_IU_SCALE &aIuScale)
const ARC_EDIT_MODE & m_arcEditMode
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
OPT_VECTOR2I Get45DegreeConstrainer(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints) const override
Get the 45-degree constrainer for the item, when the given point is moved.
KIGFX::VIEW_CONTROLS & m_viewControls
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
EDA_BEZIER_POINT_EDIT_BEHAVIOR(EDA_SHAPE &aBezier, int aMaxError)
OPT_VECTOR2I Get45DegreeConstrainer(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints) const override
Get the 45-degree constrainer for the item, when the given point is moved.
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
EDA_CIRCLE_POINT_EDIT_BEHAVIOR(EDA_SHAPE &aCircle)
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
EDA_ANGLE parametricAngleOf(const VECTOR2I &aWorldPt) const
Inverse: the parametric angle of a world-space point relative to this ellipse.
EDA_ELLIPSE_POINT_EDIT_BEHAVIOR(EDA_SHAPE &aEllipse)
VECTOR2I evaluateAt(const EDA_ANGLE &aTheta) const
World-space point on the ellipse at the given parametric angle.
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
void FinalizeItem(EDIT_POINTS &aPoints, COMMIT &aCommit) override
Finalize the edit operation.
EDA_POLYGON_POINT_EDIT_BEHAVIOR(EDA_SHAPE &aPolygon)
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
OPT_VECTOR2I Get45DegreeConstrainer(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints) const override
Get the 45-degree constrainer for the item, when the given point is moved.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
EDA_SEGMENT_POINT_EDIT_BEHAVIOR(EDA_SHAPE &aSegment)
SHAPE_T GetShape() const
Definition eda_shape.h:175
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
EDIT_POINTS is a VIEW_ITEM that manages EDIT_POINTs and EDIT_LINEs and draws them.
Represent a single point that can be used for modifying items.
Definition edit_points.h:44
An interface for classes handling user events controlling the view behavior such as zooming,...
A helper class interface to manage the edit points for a single item.
virtual bool UpdatePoints(EDIT_POINTS &aPoints)=0
Update the list of the edit points for the item.
virtual OPT_VECTOR2I Get45DegreeConstrainer(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints) const
Get the 45-degree constrainer for the item, when the given point is moved.
virtual void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems)=0
Update the item with the new positions of the edit points.
virtual ~POINT_EDIT_BEHAVIOR()=default
virtual void FinalizeItem(EDIT_POINTS &aPoints, COMMIT &aCommit)
Finalize the edit operation.
virtual void MakePoints(EDIT_POINTS &aPoints)=0
Construct the initial set of edit points for the item and append to the given list.
static bool isModified(const EDIT_POINT &aEditedPoint, const EDIT_POINT &aPoint)
Checks if two points are the same instance - which means the point is being edited.
static void UpdateOutlineFromPoints(SHAPE_POLY_SET &aOutline, const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints)
Update the polygon outline with the new positions of the edit points.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
static void UpdatePointsFromOutline(const SHAPE_POLY_SET &aOutline, EDIT_POINTS &aPoints)
Update the edit points with the current polygon outline.
void FinalizeItem(EDIT_POINTS &aPoints, COMMIT &aCommit) override
Finalize the edit operation.
POLYGON_POINT_EDIT_BEHAVIOR(SHAPE_POLY_SET &aPolygon)
static void BuildForPolyOutline(EDIT_POINTS &aPoints, const SHAPE_POLY_SET &aOutline)
Build the edit points for the given polygon outline.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
Represent a set of closed polygons.
@ ELLIPSE
Definition eda_shape.h:62
@ SEGMENT
Definition eda_shape.h:56
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Definition eda_shape.h:57
@ ELLIPSE_ARC
Definition eda_shape.h:63
void EditArcEndpointKeepCenter(EDA_SHAPE &aArc, const VECTOR2I &aCenter, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, const VECTOR2I &aCursor, const EDA_IU_SCALE &aIuScale)
Move an arc endpoint around the existing center, pulling the opposite endpoint along to keep the radi...
void EditArcMidKeepCenter(EDA_SHAPE &aArc, const VECTOR2I &aCenter, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, const VECTOR2I &aCursor, const EDA_IU_SCALE &aIuScale)
Move the mid point of an arc while keeping the center, rotating the endpoints onto the new radius.
ARC_EDIT_MODE IncrementArcEditMode(ARC_EDIT_MODE aMode)
std::optional< VECTOR2I > OPT_VECTOR2I
Definition seg.h:35
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683