KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_point_editor.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 (C) 2019 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include "sch_point_editor.h"
26
27#include <functional>
28using namespace std::placeholders;
29
30#include <ee_grid_helper.h>
31#include <tool/tool_manager.h>
32#include <sch_commit.h>
33#include <view/view_controls.h>
35#include <geometry/seg.h>
38#include <tools/sch_actions.h>
40#include <sch_edit_frame.h>
41#include <sch_line.h>
42#include <sch_bitmap.h>
43#include <sch_sheet.h>
44#include <sch_textbox.h>
45#include <sch_table.h>
47
48
49static const std::vector<KICAD_T> pointEditorTypes = { SCH_SHAPE_T,
56
57
58// Few constants to avoid using bare numbers for point indices
60{
62};
63
64
66{
68};
69
70
72{
74};
75
76
78{
80};
81
82
84{
86};
87
89{
91};
92
93
95{
96public:
98 m_line( aLine ),
99 m_screen( aScreen )
100 {
101 }
102
103 void MakePoints( EDIT_POINTS& aPoints ) override
104 {
105 std::pair<EDA_ITEM*, int> connectedStart = { nullptr, STARTPOINT };
106 std::pair<EDA_ITEM*, int> connectedEnd = { nullptr, STARTPOINT };
107
109 {
110 if( test->GetLayer() != LAYER_NOTES )
111 continue;
112
113 if( test == &m_line )
114 continue;
115
116 SCH_LINE* testLine = static_cast<SCH_LINE*>( test );
117
118 if( testLine->GetStartPoint() == m_line.GetStartPoint() )
119 {
120 connectedStart = { testLine, STARTPOINT };
121 }
122 else if( testLine->GetEndPoint() == m_line.GetStartPoint() )
123 {
124 connectedStart = { testLine, ENDPOINT };
125 }
126 else if( testLine->GetStartPoint() == m_line.GetEndPoint() )
127 {
128 connectedEnd = { testLine, STARTPOINT };
129 }
130 else if( testLine->GetEndPoint() == m_line.GetEndPoint() )
131 {
132 connectedEnd = { testLine, ENDPOINT };
133 }
134 }
135
136 aPoints.AddPoint( m_line.GetStartPoint(), connectedStart );
137 aPoints.AddPoint( m_line.GetEndPoint(), connectedEnd );
138 }
139
140 void UpdatePoints( EDIT_POINTS& aPoints ) override
141 {
144 }
145
146 void UpdateItem( const EDIT_POINT& aEditedPoints, EDIT_POINTS& aPoints, COMMIT& aCommit,
147 std::vector<EDA_ITEM*>& aUpdatedItems ) override
148 {
151
152 std::pair<EDA_ITEM*, int> connected = aPoints.Point( LINE_START ).GetConnected();
153
154 if( connected.first )
155 {
156 aCommit.Modify( connected.first, &m_screen );
157 aUpdatedItems.push_back( connected.first );
158
159 if( connected.second == STARTPOINT )
160 static_cast<SCH_LINE*>( connected.first )->SetStartPoint( m_line.GetStartPoint() );
161 else if( connected.second == ENDPOINT )
162 static_cast<SCH_LINE*>( connected.first )->SetEndPoint( m_line.GetStartPoint() );
163 }
164
165 connected = aPoints.Point( LINE_END ).GetConnected();
166
167 if( connected.first )
168 {
169 aCommit.Modify( connected.first, &m_screen );
170 aUpdatedItems.push_back( connected.first );
171
172 if( connected.second == STARTPOINT )
173 static_cast<SCH_LINE*>( connected.first )->SetStartPoint( m_line.GetEndPoint() );
174 else if( connected.second == ENDPOINT )
175 static_cast<SCH_LINE*>( connected.first )->SetEndPoint( m_line.GetEndPoint() );
176 }
177 }
178
179private:
182};
183
184
186{
187public:
189 m_arc( aArc )
190 {
191 wxASSERT( m_arc.GetShape() == SHAPE_T::ARC );
192 }
193
194 void MakePoints( EDIT_POINTS& aPoints ) override
195 {
196 aPoints.AddPoint( m_arc.GetStart() );
197 aPoints.AddPoint( m_arc.GetEnd() );
198 aPoints.AddPoint( m_arc.GetPosition() );
199
200 aPoints.AddIndicatorLine( aPoints.Point( ARC_CENTER ), aPoints.Point( ARC_START ) );
201 aPoints.AddIndicatorLine( aPoints.Point( ARC_CENTER ), aPoints.Point( ARC_END ) );
202 }
203
204 void UpdatePoints( EDIT_POINTS& aPoints ) override
205 {
206 aPoints.Point( ARC_START ).SetPosition( m_arc.GetStart() );
207 aPoints.Point( ARC_END ).SetPosition( m_arc.GetEnd() );
209 }
210
211 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
212 std::vector<EDA_ITEM*>& aUpdatedItems ) override
213 {
214 if( isModified( aEditedPoint, aPoints.Point( ARC_START ) ) )
215
216 {
217 m_arc.SetEditState( 2 );
218 m_arc.CalcEdit( aPoints.Point( ARC_START ).GetPosition() );
219 }
220 else if( isModified( aEditedPoint, aPoints.Point( ARC_END ) ) )
221 {
222 m_arc.SetEditState( 3 );
223 m_arc.CalcEdit( aPoints.Point( ARC_END ).GetPosition() );
224 }
225 else if( isModified( aEditedPoint, aPoints.Point( ARC_CENTER ) ) )
226 {
227 m_arc.SetEditState( 4 );
228 m_arc.CalcEdit( aPoints.Point( ARC_CENTER ).GetPosition() );
229 }
230
231 aUpdatedItems.push_back( &m_arc );
232 }
233private:
235};
236
237
239{
240public:
242 m_bitmap( aBitmap )
243 {}
244
245 void MakePoints( EDIT_POINTS& aPoints ) override
246 {
247 const REFERENCE_IMAGE& refImage = m_bitmap.GetReferenceImage();
248 const VECTOR2I topLeft = refImage.GetPosition() - refImage.GetSize() / 2;
249 const VECTOR2I botRight = refImage.GetPosition() + refImage.GetSize() / 2;
250
251 aPoints.AddPoint( topLeft );
252 aPoints.AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
253 aPoints.AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
254 aPoints.AddPoint( botRight );
255
256 aPoints.AddPoint( refImage.GetPosition() + refImage.GetTransformOriginOffset() );
257 }
258
259 void UpdatePoints( EDIT_POINTS& aPoints ) override
260 {
261 const REFERENCE_IMAGE& refImage = m_bitmap.GetReferenceImage();
262 const VECTOR2I topLeft = refImage.GetPosition() - refImage.GetSize() / 2;
263 const VECTOR2I botRight = refImage.GetPosition() + refImage.GetSize() / 2;
264
265 aPoints.Point( RECT_TOPLEFT ).SetPosition( topLeft );
266 aPoints.Point( RECT_TOPRIGHT ).SetPosition( botRight.x, topLeft.y );
267 aPoints.Point( RECT_BOTLEFT ).SetPosition( topLeft.x, botRight.y );
268 aPoints.Point( RECT_BOTRIGHT ).SetPosition( botRight );
269
270 aPoints.Point( REFIMG_ORIGIN )
271 .SetPosition( refImage.GetPosition() + refImage.GetTransformOriginOffset() );
272 }
273
274 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
275 std::vector<EDA_ITEM*>& aUpdatedItems ) override
276 {
278 const VECTOR2I topLeft = aPoints.Point( RECT_TOPLEFT ).GetPosition();
279 const VECTOR2I topRight = aPoints.Point( RECT_TOPRIGHT ).GetPosition();
280 const VECTOR2I botLeft = aPoints.Point( RECT_BOTLEFT ).GetPosition();
281 const VECTOR2I botRight = aPoints.Point( RECT_BOTRIGHT ).GetPosition();
282 const VECTOR2I xfrmOrigin = aPoints.Point( REFIMG_ORIGIN ).GetPosition();
283
284 if( isModified( aEditedPoint, aPoints.Point( REFIMG_ORIGIN ) ) )
285 {
286 // Moving the transform origin
287 // As the other points didn't move, we can get the image extent from them
288 const VECTOR2I newOffset = xfrmOrigin - ( topLeft + botRight ) / 2;
289 refImg.SetTransformOriginOffset( newOffset );
290 }
291 else
292 {
293 const VECTOR2I oldOrigin = refImg.GetPosition() + refImg.GetTransformOriginOffset();
294 const VECTOR2I oldSize = refImg.GetSize();
295 const VECTOR2I pos = refImg.GetPosition();
296
297 OPT_VECTOR2I newCorner;
298 VECTOR2I oldCorner = pos;
299
300 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) ) )
301 {
302 newCorner = topLeft;
303 oldCorner -= oldSize / 2;
304 }
305 else if( isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) ) )
306 {
307 newCorner = topRight;
308 oldCorner -= VECTOR2I( -oldSize.x, oldSize.y ) / 2;
309 }
310 else if( isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
311 {
312 newCorner = botLeft;
313 oldCorner -= VECTOR2I( oldSize.x, -oldSize.y ) / 2;
314 }
315 else if( isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) ) )
316 {
317 newCorner = botRight;
318 oldCorner += oldSize / 2;
319 }
320
321 if( newCorner )
322 {
323 // Turn in the respective vectors from the origin
324 *newCorner -= xfrmOrigin;
325 oldCorner -= oldOrigin;
326
327 // If we tried to cross the origin, clamp it to stop it
328 if( sign( newCorner->x ) != sign( oldCorner.x )
329 || sign( newCorner->y ) != sign( oldCorner.y ) )
330 {
331 *newCorner = VECTOR2I( 0, 0 );
332 }
333
334 const double newLength = newCorner->EuclideanNorm();
335 const double oldLength = oldCorner.EuclideanNorm();
336
337 double ratio = oldLength > 0 ? ( newLength / oldLength ) : 1.0;
338
339 // Clamp the scaling to a minimum of 50 mils
340 VECTOR2I newSize = oldSize * ratio;
341 double newWidth = std::max( newSize.x, EDA_UNIT_UTILS::Mils2IU( schIUScale, 50 ) );
342 double newHeight = std::max( newSize.y, EDA_UNIT_UTILS::Mils2IU( schIUScale, 50 ) );
343 ratio = std::min( newWidth / oldSize.x, newHeight / oldSize.y );
344
345 // Also handles the origin offset
346 refImg.SetImageScale( refImg.GetImageScale() * ratio );
347 }
348 }
349 aUpdatedItems.push_back( &m_bitmap );
350 }
351
352private:
354};
355
356
358{
359public:
362 m_cell( aCell ),
363 m_screen( aScreen )
364 {
365 }
366
367 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
368 std::vector<EDA_ITEM*>& aUpdatedItems ) override
369 {
370 SCH_TABLE& table = static_cast<SCH_TABLE&>( *m_cell.GetParent() );
371 bool rotated = !m_cell.GetTextAngle().IsHorizontal();
372
373 aCommit.Modify( &table, &m_screen );
374 aUpdatedItems.push_back( &table );
375
376 if( rotated )
377 {
378 if( isModified( aEditedPoint, aPoints.Point( ROW_HEIGHT ) ) )
379 {
380 m_cell.SetEnd( VECTOR2I( m_cell.GetEndX(), aPoints.Point( ROW_HEIGHT ).GetY() ) );
381
382 int colWidth = std::abs( m_cell.GetRectangleHeight() );
383
384 for( int ii = 0; ii < m_cell.GetColSpan() - 1; ++ii )
385 colWidth -= table.GetColWidth( m_cell.GetColumn() + ii );
386
387 table.SetColWidth( m_cell.GetColumn() + m_cell.GetColSpan() - 1, colWidth );
388 }
389 else if( isModified( aEditedPoint, aPoints.Point( COL_WIDTH ) ) )
390 {
391 m_cell.SetEnd( VECTOR2I( aPoints.Point( COL_WIDTH ).GetX(), m_cell.GetEndY() ) );
392
393 int rowHeight = m_cell.GetRectangleWidth();
394
395 for( int ii = 0; ii < m_cell.GetRowSpan() - 1; ++ii )
396 rowHeight -= table.GetRowHeight( m_cell.GetRow() + ii );
397
398 table.SetRowHeight( m_cell.GetRow() + m_cell.GetRowSpan() - 1, rowHeight );
399 }
400 }
401 else
402 {
403 if( isModified( aEditedPoint, aPoints.Point( COL_WIDTH ) ) )
404 {
405 m_cell.SetEnd( VECTOR2I( aPoints.Point( COL_WIDTH ).GetX(), m_cell.GetEndY() ) );
406
407 int colWidth = m_cell.GetRectangleWidth();
408
409 for( int ii = 0; ii < m_cell.GetColSpan() - 1; ++ii )
410 colWidth -= table.GetColWidth( m_cell.GetColumn() + ii );
411
412 table.SetColWidth( m_cell.GetColumn() + m_cell.GetColSpan() - 1, colWidth );
413 }
414 else if( isModified( aEditedPoint, aPoints.Point( ROW_HEIGHT ) ) )
415 {
416 m_cell.SetEnd( VECTOR2I( m_cell.GetEndX(), aPoints.Point( ROW_HEIGHT ).GetY() ) );
417
418 int rowHeight = m_cell.GetRectangleHeight();
419
420 for( int ii = 0; ii < m_cell.GetRowSpan() - 1; ++ii )
421 rowHeight -= table.GetRowHeight( m_cell.GetRow() + ii );
422
423 table.SetRowHeight( m_cell.GetRow() + m_cell.GetRowSpan() - 1, rowHeight );
424 }
425 }
426
427 table.Normalize();
428 }
429
430private:
433};
434
435
437{
438public:
440 m_rect( aRect ),
441 m_frame( aFrame )
442 {
443 }
444
445 static void MakePoints( SCH_SHAPE& aRect, EDIT_POINTS& aPoints )
446 {
447 VECTOR2I topLeft = aRect.GetPosition();
448 VECTOR2I botRight = aRect.GetEnd();
449
450 aPoints.AddPoint( topLeft );
451 aPoints.AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
452 aPoints.AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
453 aPoints.AddPoint( botRight );
454 aPoints.AddPoint( aRect.GetCenter() );
455
456 aPoints.AddLine( aPoints.Point( RECT_TOPLEFT ), aPoints.Point( RECT_TOPRIGHT ) );
457 aPoints.Line( RECT_TOP ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_TOP ) ) );
458 aPoints.AddLine( aPoints.Point( RECT_TOPRIGHT ), aPoints.Point( RECT_BOTRIGHT ) );
459 aPoints.Line( RECT_RIGHT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_RIGHT ) ) );
460 aPoints.AddLine( aPoints.Point( RECT_BOTRIGHT ), aPoints.Point( RECT_BOTLEFT ) );
461 aPoints.Line( RECT_BOT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_BOT ) ) );
462 aPoints.AddLine( aPoints.Point( RECT_BOTLEFT ), aPoints.Point( RECT_TOPLEFT ) );
463 aPoints.Line( RECT_LEFT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_LEFT ) ) );
464 }
465
466 static void UpdatePoints( SCH_SHAPE& aRect, EDIT_POINTS& aPoints )
467 {
468 VECTOR2I topLeft = aRect.GetPosition();
469 VECTOR2I botRight = aRect.GetEnd();
470
471 aPoints.Point( RECT_TOPLEFT ).SetPosition( topLeft );
472 aPoints.Point( RECT_TOPRIGHT ).SetPosition( VECTOR2I( botRight.x, topLeft.y ) );
473 aPoints.Point( RECT_BOTLEFT ).SetPosition( VECTOR2I( topLeft.x, botRight.y ) );
474 aPoints.Point( RECT_BOTRIGHT ).SetPosition( botRight );
475 aPoints.Point( RECT_CENTER ).SetPosition( aRect.GetCenter() );
476 }
477
488 static void PinEditedCorner( const EDIT_POINT& aEditedPoint, const EDIT_POINTS& aPoints,
489 int minWidth, int minHeight, VECTOR2I& topLeft, VECTOR2I& topRight,
490 VECTOR2I& botLeft, VECTOR2I& botRight )
491 {
492 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) ) )
493 {
494 // pin edited point within opposite corner
495 topLeft.x = std::min( topLeft.x, botRight.x - minWidth );
496 topLeft.y = std::min( topLeft.y, botRight.y - minHeight );
497
498 // push edited point edges to adjacent corners
499 topRight.y = topLeft.y;
500 botLeft.x = topLeft.x;
501 }
502 else if( isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) ) )
503 {
504 // pin edited point within opposite corner
505 topRight.x = std::max( topRight.x, botLeft.x + minWidth );
506 topRight.y = std::min( topRight.y, botLeft.y - minHeight );
507
508 // push edited point edges to adjacent corners
509 topLeft.y = topRight.y;
510 botRight.x = topRight.x;
511 }
512 else if( isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
513 {
514 // pin edited point within opposite corner
515 botLeft.x = std::min( botLeft.x, topRight.x - minWidth );
516 botLeft.y = std::max( botLeft.y, topRight.y + minHeight );
517
518 // push edited point edges to adjacent corners
519 botRight.y = botLeft.y;
520 topLeft.x = botLeft.x;
521 }
522 else if( isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) ) )
523 {
524 // pin edited point within opposite corner
525 botRight.x = std::max( botRight.x, topLeft.x + minWidth );
526 botRight.y = std::max( botRight.y, topLeft.y + minHeight );
527
528 // push edited point edges to adjacent corners
529 botLeft.y = botRight.y;
530 topRight.x = botRight.x;
531 }
532 else if( isModified( aEditedPoint, aPoints.Line( RECT_TOP ) ) )
533 {
534 topLeft.y = std::min( topLeft.y, botRight.y - minHeight );
535 }
536 else if( isModified( aEditedPoint, aPoints.Line( RECT_LEFT ) ) )
537 {
538 topLeft.x = std::min( topLeft.x, botRight.x - minWidth );
539 }
540 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
541 {
542 botRight.y = std::max( botRight.y, topLeft.y + minHeight );
543 }
544 else if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
545 {
546 botRight.x = std::max( botRight.x, topLeft.x + minWidth );
547 }
548 }
549
550 static void UpdateItem( SCH_SHAPE& aRect, const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints )
551 {
552 VECTOR2I topLeft = aPoints.Point( RECT_TOPLEFT ).GetPosition();
553 VECTOR2I topRight = aPoints.Point( RECT_TOPRIGHT ).GetPosition();
554 VECTOR2I botLeft = aPoints.Point( RECT_BOTLEFT ).GetPosition();
555 VECTOR2I botRight = aPoints.Point( RECT_BOTRIGHT ).GetPosition();
556
557 PinEditedCorner( aEditedPoint, aPoints, schIUScale.MilsToIU( 1 ), schIUScale.MilsToIU( 1 ),
558 topLeft, topRight, botLeft, botRight );
559
560 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) )
561 || isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) )
562 || isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) )
563 || isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
564 {
565 aRect.SetPosition( topLeft );
566 aRect.SetEnd( botRight );
567 }
568 else if( isModified( aEditedPoint, aPoints.Line( RECT_TOP ) ) )
569 {
570 aRect.SetStartY( topLeft.y );
571 }
572 else if( isModified( aEditedPoint, aPoints.Line( RECT_LEFT ) ) )
573 {
574 aRect.SetStartX( topLeft.x );
575 }
576 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
577 {
578 aRect.SetEndY( botRight.y );
579 }
580 else if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
581 {
582 aRect.SetEndX( botRight.x );
583 }
584
585 for( unsigned i = 0; i < aPoints.LinesSize(); ++i )
586 {
587 if( !isModified( aEditedPoint, aPoints.Line( i ) ) )
588 {
589 aPoints.Line( i ).SetConstraint( new EC_PERPLINE( aPoints.Line( i ) ) );
590 }
591 }
592 }
593
594 void MakePoints( EDIT_POINTS& aPoints ) override
595 {
597 MakePoints( m_rect, aPoints );
598 }
599
600 void UpdatePoints( EDIT_POINTS& aPoints ) override
601 {
603 UpdatePoints( m_rect, aPoints );
604 }
605
606 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
607 std::vector<EDA_ITEM*>& aUpdatedItems ) override
608 {
609 VECTOR2I topLeft = aPoints.Point( RECT_TOPLEFT ).GetPosition();
610 VECTOR2I topRight = aPoints.Point( RECT_TOPRIGHT ).GetPosition();
611 VECTOR2I botLeft = aPoints.Point( RECT_BOTLEFT ).GetPosition();
612 VECTOR2I botRight = aPoints.Point( RECT_BOTRIGHT ).GetPosition();
613
614 PinEditedCorner( aEditedPoint, aPoints, schIUScale.MilsToIU( 1 ), schIUScale.MilsToIU( 1 ),
615 topLeft, topRight, botLeft, botRight );
616
617 const BOX2I oldBox = BOX2I::ByCorners( m_rect.GetStart(), m_rect.GetEnd() );
618 std::vector<SEG> oldSegs;
619 std::vector<VECTOR2I> moveVecs;
620
621 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) )
622 || isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) )
623 || isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) )
624 || isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
625 {
626 // Corner drags don't update pins. Not only is it an escape hatch to avoid
627 // moving pins, it also avoids tricky problems when the pins "fall off"
628 // the ends of one of the two segments and get either left behind or
629 // "swept up" into the corner.
630 m_rect.SetPosition( topLeft );
631 m_rect.SetEnd( botRight );
632 }
633 else if( isModified( aEditedPoint, aPoints.Point( RECT_CENTER ) ) )
634 {
635 VECTOR2I moveVec = aPoints.Point( RECT_CENTER ).GetPosition() - oldBox.GetCenter();
636 m_rect.Move( moveVec );
637 }
638 else if( isModified( aEditedPoint, aPoints.Line( RECT_TOP ) ) )
639 {
641 moveVecs.emplace_back( 0, topLeft.y - oldBox.GetTop() );
642 m_rect.SetStartY( topLeft.y );
643 }
644 else if( isModified( aEditedPoint, aPoints.Line( RECT_LEFT ) ) )
645 {
647 moveVecs.emplace_back( topLeft.x - oldBox.GetLeft(), 0 );
648 m_rect.SetStartX( topLeft.x );
649 }
650 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
651 {
653 moveVecs.emplace_back( 0, botRight.y - oldBox.GetBottom() );
654 m_rect.SetEndY( botRight.y );
655 }
656 else if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
657 {
659 moveVecs.emplace_back( botRight.x - oldBox.GetRight(), 0 );
660 m_rect.SetEndX( botRight.x );
661 }
662
663 dragPinsOnEdge( oldSegs, moveVecs, m_rect.GetUnit(), aCommit, aUpdatedItems );
664
665 for( unsigned i = 0; i < aPoints.LinesSize(); ++i )
666 {
667 if( !isModified( aEditedPoint, aPoints.Line( i ) ) )
668 {
669 aPoints.Line( i ).SetConstraint( new EC_PERPLINE( aPoints.Line( i ) ) );
670 }
671 }
672 }
673
674private:
675 void dragPinsOnEdge( const std::vector<SEG>& aOldEdges, const std::vector<VECTOR2I>& aMoveVecs,
676 int aEdgeUnit, COMMIT& aCommit,
677 std::vector<EDA_ITEM*>& aUpdatedItems ) const
678 {
679 wxCHECK( aOldEdges.size() == aMoveVecs.size(), /* void */ );
680
681 // This only make sense in the symbol editor
683 return;
684
686
687 // And only if the setting is enabled
688 if( !editor.GetSettings()->m_dragPinsAlongWithEdges )
689 return;
690
691 // Adjuting pins on a different unit to a unit-limited shape
692 // seems suspect.
693 wxCHECK( aEdgeUnit == 0 || aEdgeUnit == editor.GetUnit(), /* void */ );
694
695 /*
696 * Get a list of pins on a line segment
697 */
698 const auto getPinsOnSeg =
699 []( LIB_SYMBOL& aSymbol, int aUnit, const SEG& aSeg,
700 bool aIncludeEnds ) -> std::vector<SCH_PIN*>
701 {
702 std::vector<SCH_PIN*> pins;
703
704 for( SCH_PIN* pin : aSymbol.GetPins( aUnit, 0 ) )
705 {
706 // Figure out if the pin "connects" to the line
707 const VECTOR2I pinRootPos = pin->GetPinRoot();
708
709 if( aSeg.Contains( pinRootPos ) )
710 {
711 if( aIncludeEnds || ( pinRootPos != aSeg.A && pinRootPos != aSeg.B ) )
712 {
713 pins.push_back( pin );
714 }
715 }
716 }
717
718 return pins;
719 };
720
721 LIB_SYMBOL* const symbol = editor.GetCurSymbol();
722
723 for( std::size_t i = 0; i < aOldEdges.size(); ++i )
724 {
725 if( aMoveVecs[i] == VECTOR2I( 0, 0 ) || !symbol )
726 continue;
727
728 const std::vector<SCH_PIN*> pins = getPinsOnSeg( *symbol, aEdgeUnit, aOldEdges[i],
729 false );
730
731 for( SCH_PIN* pin : pins )
732 {
733 aCommit.Modify( pin );
734 aUpdatedItems.push_back( pin );
735
736 // Move the pin
737 pin->Move( aMoveVecs[i] );
738 }
739 }
740 }
741
742private:
745};
746
747
749{
750public:
752 m_textbox( aTextbox )
753 {}
754
755 void MakePoints( EDIT_POINTS& aPoints ) override
756 {
759 }
760
761 void UpdatePoints( EDIT_POINTS& aPoints ) override
762 {
763 // point editor works only with rectangles having width and height > 0
764 // Some symbols can have rectangles with width or height < 0
765 // So normalize the size:
768 }
769
770 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
771 std::vector<EDA_ITEM*>& aUpdatedItems ) override
772 {
775 }
776
777private:
779};
780
781
783{
784public:
786 m_sheet( aSheet )
787 {}
788
789 void MakePoints( EDIT_POINTS& aPoints ) override
790 {
791 VECTOR2I topLeft = m_sheet.GetPosition();
792 VECTOR2I botRight = m_sheet.GetPosition() + m_sheet.GetSize();
793
794 aPoints.AddPoint( topLeft );
795 aPoints.AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
796 aPoints.AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
797 aPoints.AddPoint( botRight );
798
799 aPoints.AddLine( aPoints.Point( RECT_TOPLEFT ), aPoints.Point( RECT_TOPRIGHT ) );
800 aPoints.Line( RECT_TOP ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_TOP ) ) );
801 aPoints.AddLine( aPoints.Point( RECT_TOPRIGHT ), aPoints.Point( RECT_BOTRIGHT ) );
802 aPoints.Line( RECT_RIGHT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_RIGHT ) ) );
803 aPoints.AddLine( aPoints.Point( RECT_BOTRIGHT ), aPoints.Point( RECT_BOTLEFT ) );
804 aPoints.Line( RECT_BOT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_BOT ) ) );
805 aPoints.AddLine( aPoints.Point( RECT_BOTLEFT ), aPoints.Point( RECT_TOPLEFT ) );
806 aPoints.Line( RECT_LEFT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_LEFT ) ) );
807 }
808
809 void UpdatePoints( EDIT_POINTS& aPoints ) override
810 {
811 VECTOR2I topLeft = m_sheet.GetPosition();
812 VECTOR2I botRight = m_sheet.GetPosition() + m_sheet.GetSize();
813
814 aPoints.Point( RECT_TOPLEFT ).SetPosition( topLeft );
815 aPoints.Point( RECT_TOPRIGHT ).SetPosition( botRight.x, topLeft.y );
816 aPoints.Point( RECT_BOTLEFT ).SetPosition( topLeft.x, botRight.y );
817 aPoints.Point( RECT_BOTRIGHT ).SetPosition( botRight );
818 }
819
820 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
821 std::vector<EDA_ITEM*>& aUpdatedItems ) override
822 {
823 VECTOR2I topLeft = aPoints.Point( RECT_TOPLEFT ).GetPosition();
824 VECTOR2I topRight = aPoints.Point( RECT_TOPRIGHT ).GetPosition();
825 VECTOR2I botLeft = aPoints.Point( RECT_BOTLEFT ).GetPosition();
826 VECTOR2I botRight = aPoints.Point( RECT_BOTRIGHT ).GetPosition();
827 VECTOR2I sheetNewPos = m_sheet.GetPosition();
828 VECTOR2I sheetNewSize = m_sheet.GetSize();
829
830 bool editedTopRight = isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) );
831 bool editedBotLeft = isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) );
832 bool editedBotRight = isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) );
833
834 if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
835 editedTopRight = true;
836 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
837 editedBotLeft = true;
838
840 aEditedPoint, aPoints, m_sheet.GetMinWidth( editedTopRight || editedBotRight ),
841 m_sheet.GetMinHeight( editedBotLeft || editedBotRight ), topLeft, topRight, botLeft,
842 botRight );
843
844 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) )
845 || isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) )
846 || isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) )
847 || isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
848 {
849 sheetNewPos = topLeft;
850 sheetNewSize = VECTOR2I( botRight.x - topLeft.x, botRight.y - topLeft.y );
851 }
852 else if( isModified( aEditedPoint, aPoints.Line( RECT_TOP ) ) )
853 {
854 sheetNewPos = VECTOR2I( m_sheet.GetPosition().x, topLeft.y );
855 sheetNewSize = VECTOR2I( m_sheet.GetSize().x, botRight.y - topLeft.y );
856 }
857 else if( isModified( aEditedPoint, aPoints.Line( RECT_LEFT ) ) )
858 {
859 sheetNewPos = VECTOR2I( topLeft.x, m_sheet.GetPosition().y );
860 sheetNewSize = VECTOR2I( botRight.x - topLeft.x, m_sheet.GetSize().y );
861 }
862 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
863 {
864 sheetNewSize = VECTOR2I( m_sheet.GetSize().x, botRight.y - topLeft.y );
865 }
866 else if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
867 {
868 sheetNewSize = VECTOR2I( botRight.x - topLeft.x, m_sheet.GetSize().y );
869 }
870
871 for( unsigned i = 0; i < aPoints.LinesSize(); ++i )
872 {
873 if( !isModified( aEditedPoint, aPoints.Line( i ) ) )
874 {
875 aPoints.Line( i ).SetConstraint( new EC_PERPLINE( aPoints.Line( i ) ) );
876 }
877 }
878
879 if( m_sheet.GetPosition() != sheetNewPos )
880 m_sheet.SetPositionIgnoringPins( sheetNewPos );
881
882 if( m_sheet.GetSize() != sheetNewSize )
883 m_sheet.Resize( sheetNewSize );
884 }
885
886private:
888};
889
890
892{
893 m_editBehavior = nullptr;
894 m_editPoints = std::make_shared<EDIT_POINTS>( aItem );
895
896 if( !aItem )
897 return;
898
899 // Generate list of edit points based on the item type
900 switch( aItem->Type() )
901 {
902 case SCH_SHAPE_T:
903 {
904 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem );
905
906 switch( shape->GetShape() )
907 {
908 case SHAPE_T::ARC:
909 m_editBehavior = std::make_unique<ARC_POINT_EDIT_BEHAVIOR>( *shape );
910 break;
911 case SHAPE_T::CIRCLE:
912 m_editBehavior = std::make_unique<EDA_CIRCLE_POINT_EDIT_BEHAVIOR>( *shape );
913 break;
914 case SHAPE_T::RECTANGLE:
915 m_editBehavior = std::make_unique<RECTANGLE_POINT_EDIT_BEHAVIOR>( *shape, *m_frame );
916 break;
917 case SHAPE_T::POLY:
918 m_editBehavior = std::make_unique<EDA_POLYGON_POINT_EDIT_BEHAVIOR>( *shape );
919 break;
920 case SHAPE_T::BEZIER:
921 m_editBehavior = std::make_unique<EDA_BEZIER_POINT_EDIT_BEHAVIOR>( *shape );
922 break;
923 default:
925 }
926
927 break;
928 }
929 case SCH_RULE_AREA_T:
930 {
931 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem );
932 // Implemented directly as a polygon
933 m_editBehavior = std::make_unique<EDA_POLYGON_POINT_EDIT_BEHAVIOR>( *shape );
934 break;
935 }
936 case SCH_TEXTBOX_T:
937 {
938 SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( aItem );
939 m_editBehavior = std::make_unique<TEXTBOX_POINT_EDIT_BEHAVIOR>( *textbox );
940 break;
941 }
942 case SCH_TABLECELL_T:
943 {
944 SCH_TABLECELL* cell = static_cast<SCH_TABLECELL*>( aItem );
945 m_editBehavior = std::make_unique<SCH_TABLECELL_POINT_EDIT_BEHAVIOR>( *cell, *m_frame->GetScreen() );
946 break;
947 }
948 case SCH_SHEET_T:
949 {
950 SCH_SHEET& sheet = static_cast<SCH_SHEET&>( *aItem );
951 m_editBehavior = std::make_unique<SHEET_POINT_EDIT_BEHAVIOR>( sheet );
952 break;
953 }
954 case SCH_BITMAP_T:
955 {
956 SCH_BITMAP& bitmap = static_cast<SCH_BITMAP&>( *aItem );
957 m_editBehavior = std::make_unique<BITMAP_POINT_EDIT_BEHAVIOR>( bitmap );
958 break;
959 }
960 case SCH_LINE_T:
961 {
962 SCH_LINE& line = static_cast<SCH_LINE&>( *aItem );
963 m_editBehavior = std::make_unique<LINE_POINT_EDIT_BEHAVIOR>( line, *m_frame->GetScreen() );
964 break;
965 }
966 default:
967 {
968 m_editPoints.reset();
969 break;
970 }
971 }
972
973 // If we got a behavior, generate the points
974 if( m_editBehavior )
975 {
976 wxCHECK( m_editPoints, /* void */ );
977 m_editBehavior->MakePoints( *m_editPoints );
978 }
979}
980
981
983 SCH_TOOL_BASE<SCH_BASE_FRAME>( "eeschema.PointEditor" ),
984 m_editedPoint( nullptr ),
985 m_inPointEditor( false )
986{
987}
988
989
991{
992 SCH_TOOL_BASE::Reset( aReason );
993
994 m_editPoints.reset();
995 m_editedPoint = nullptr;
996}
997
998
1000{
1002
1003 auto& menu = m_selectionTool->GetToolMenu().GetMenu();
1005 std::bind( &SCH_POINT_EDITOR::addCornerCondition, this, _1 ) );
1007 std::bind( &SCH_POINT_EDITOR::removeCornerCondition, this, _1 ) );
1008
1009 return true;
1010}
1011
1012
1014{
1015 setEditedPoint( nullptr );
1016
1017 return 0;
1018}
1019
1020
1022{
1023 EDIT_POINT* point = m_editedPoint;
1024
1025 if( !m_editPoints )
1026 {
1027 point = nullptr;
1028 }
1029 else if( aEvent.IsMotion() )
1030 {
1031 point = m_editPoints->FindPoint( aEvent.Position(), getView() );
1032 }
1033 else if( aEvent.IsDrag( BUT_LEFT ) )
1034 {
1035 point = m_editPoints->FindPoint( aEvent.DragOrigin(), getView() );
1036 }
1037 else
1038 {
1039 point = m_editPoints->FindPoint( getViewControls()->GetCursorPosition( false ), getView() );
1040 }
1041
1042 if( m_editedPoint != point )
1043 setEditedPoint( point );
1044}
1045
1046
1048{
1049 if( !m_selectionTool )
1050 return 0;
1051
1052 if( m_inPointEditor )
1053 return 0;
1054
1056
1057 if( m_isSymbolEditor )
1058 {
1059 SYMBOL_EDIT_FRAME* editor = getEditFrame<SYMBOL_EDIT_FRAME>();
1060
1061 if( !editor->IsSymbolEditable() || editor->IsSymbolAlias() )
1062 return 0;
1063 }
1064
1065 const SCH_SELECTION& selection = m_selectionTool->GetSelection();
1066
1067 if( selection.Size() != 1 || !selection.Front()->IsType( pointEditorTypes ) )
1068 return 0;
1069
1070 // Wait till drawing tool is done
1071 if( selection.Front()->IsNew() )
1072 return 0;
1073
1074 Activate();
1075
1078 VECTOR2I cursorPos;
1079 KIGFX::VIEW* view = getView();
1080 EDA_ITEM* item = selection.Front();
1081 SCH_COMMIT commit( m_toolMgr );
1082
1083 controls->ShowCursor( true );
1084
1085 makePointsAndBehavior( item );
1086 view->Add( m_editPoints.get() );
1087 setEditedPoint( nullptr );
1088 updateEditedPoint( aEvent );
1089 bool inDrag = false;
1090
1091 // Main loop: keep receiving events
1092 while( TOOL_EVENT* evt = Wait() )
1093 {
1094 if( grid )
1095 {
1096 grid->SetSnap( !evt->Modifier( MD_SHIFT ) );
1097 grid->SetUseGrid( getView()->GetGAL()->GetGridSnapping()
1098 && !evt->DisableGridSnapping() );
1099 }
1100 else
1101 {
1102 // This check is based on the assumption that the grid object must be valid.
1103 // If this assumption is wrong, please fix the code above.
1104 wxCHECK( false, 0 );
1105 }
1106
1107 if( !m_editPoints || evt->IsSelectionEvent() )
1108 break;
1109
1110 if ( !inDrag )
1111 updateEditedPoint( *evt );
1112
1113 if( evt->IsDrag( BUT_LEFT ) && m_editedPoint )
1114 {
1115 if( !inDrag )
1116 {
1117 commit.Modify( m_editPoints->GetParent(), m_frame->GetScreen() );
1118 inDrag = true;
1119 }
1120
1121 bool snap = !evt->DisableGridSnapping();
1122
1123 cursorPos = grid->Align( controls->GetMousePosition(),
1124 GRID_HELPER_GRIDS::GRID_GRAPHICS );
1125 controls->ForceCursorPosition( true, cursorPos );
1126
1127 m_editedPoint->SetPosition( controls->GetCursorPosition( snap ) );
1128
1129 updateParentItem( snap, commit );
1130 updatePoints();
1131 }
1132 else if( inDrag && evt->IsMouseUp( BUT_LEFT ) )
1133 {
1134 if( !commit.Empty() )
1135 commit.Push( _( "Move Point" ) );
1136
1137 controls->SetAutoPan( false );
1138 inDrag = false;
1139 }
1140 else if( evt->IsCancelInteractive() || evt->IsActivate() )
1141 {
1142 if( inDrag ) // Restore the last change
1143 {
1144 // Currently we are manually managing the lifetime of the grid
1145 // helpers because there is a bug in the tool stack that adds
1146 // the point editor again when commit.Revert() rebuilds the selection.
1147 // We remove this grid here so the its destructor is called before it
1148 // is added again.
1149 if( grid )
1150 {
1151 delete grid;
1152 grid = nullptr;
1153 }
1154
1155 commit.Revert();
1156 inDrag = false;
1157 break;
1158 }
1159 else if( evt->IsCancelInteractive() )
1160 {
1161 break;
1162 }
1163
1164 if( evt->IsActivate() )
1165 break;
1166 }
1167 else
1168 {
1169 evt->SetPassEvent();
1170 }
1171
1172 controls->SetAutoPan( inDrag );
1173 controls->CaptureCursor( inDrag );
1174 }
1175
1176 controls->SetAutoPan( false );
1177 controls->CaptureCursor( false );
1178 setEditedPoint( nullptr );
1179
1180 if( m_editPoints )
1181 {
1182 view->Remove( m_editPoints.get() );
1183
1184 m_editPoints.reset();
1186 }
1187
1188 delete grid;
1189
1190 return 0;
1191}
1192
1193
1194void SCH_POINT_EDITOR::updateParentItem( bool aSnapToGrid, SCH_COMMIT& aCommit ) const
1195{
1196 EDA_ITEM* item = m_editPoints->GetParent();
1197
1198 if( !item )
1199 return;
1200
1201 if( !m_editBehavior )
1202 return;
1203
1204 std::vector<EDA_ITEM*> updatedItems;
1205 m_editBehavior->UpdateItem( *m_editedPoint, *m_editPoints, aCommit, updatedItems );
1206
1207 for( EDA_ITEM* updatedItem : updatedItems )
1208 updateItem( updatedItem, true );
1209
1210 m_frame->SetMsgPanel( item );
1211}
1212
1213
1215{
1216 if( !m_editPoints || !m_editBehavior )
1217 return;
1218
1219 m_editBehavior->UpdatePoints( *m_editPoints );
1220 getView()->Update( m_editPoints.get() );
1221}
1222
1223
1225{
1227
1228 if( aPoint )
1229 {
1230 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
1231 controls->ForceCursorPosition( true, aPoint->GetPosition() );
1232 controls->ShowCursor( true );
1233 }
1234 else
1235 {
1236 if( m_frame->ToolStackIsEmpty() )
1237 controls->ShowCursor( false );
1238
1239 controls->ForceCursorPosition( false );
1240 }
1241
1242 m_editedPoint = aPoint;
1243}
1244
1245
1247{
1248 bool isRuleArea = false;
1249
1250 if( m_editPoints )
1251 isRuleArea = m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T;
1252
1254 || !( m_editPoints->GetParent()->Type() == SCH_SHAPE_T || isRuleArea ) )
1255 {
1256 return false;
1257 }
1258
1259 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1260
1261 if( shape->GetPolyShape().IsEmpty() )
1262 return false;
1263
1264 SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
1265
1266 if( m_editPoints->GetParent()->Type() == SCH_SHAPE_T && poly.GetPointCount() <= 2 )
1267 return false;
1268 if( m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T && poly.GetPointCount() <= 3 )
1269 return false;
1270
1271 for( const VECTOR2I& pt : poly.CPoints() )
1272 {
1273 if( pt == m_editedPoint->GetPosition() )
1274 return true;
1275 }
1276
1277 return false;
1278}
1279
1280
1282{
1283 if( !m_editPoints
1284 || !( m_editPoints->GetParent()->Type() == SCH_SHAPE_T
1285 || m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T ) )
1286 {
1287 return false;
1288 }
1289
1290 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1291
1292 if( shape->GetShape() != SHAPE_T::POLY )
1293 return false;
1294
1295 VECTOR2I cursorPos = getViewControls()->GetCursorPosition( false );
1296 double threshold = getView()->ToWorld( EDIT_POINT::POINT_SIZE );
1297
1298 return shape->HitTest( cursorPos, (int) threshold );
1299}
1300
1301
1303{
1304 if( !m_editPoints
1305 || !( m_editPoints->GetParent()->Type() == SCH_SHAPE_T
1306 || m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T ) )
1307 {
1308 return 0;
1309 }
1310
1311 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1312 SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
1313 SCH_COMMIT commit( m_toolMgr );
1314
1315 commit.Modify( shape, m_frame->GetScreen() );
1316
1318 int currentMinDistance = INT_MAX;
1319 int closestLineStart = 0;
1320 unsigned numPoints = poly.GetPointCount();
1321
1322 if( !shape->IsClosed() )
1323 numPoints -= 1;
1324
1325 for( unsigned i = 0; i < numPoints; ++i )
1326 {
1327 SEG seg = poly.GetSegment( i );
1328 int distance = seg.Distance( cursor );
1329
1330 if( distance < currentMinDistance )
1331 {
1332 currentMinDistance = distance;
1333 closestLineStart = i;
1334 }
1335 }
1336
1337 poly.Insert( closestLineStart + 1, cursor );
1338
1339 updateItem( shape, true );
1340 updatePoints();
1341
1342 commit.Push( _( "Add Corner" ) );
1343 return 0;
1344}
1345
1346
1348{
1350 || !m_editPoints->GetParent()->IsType( { SCH_SHAPE_T, SCH_RULE_AREA_T } ) )
1351 {
1352 return 0;
1353 }
1354
1355 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1356 SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
1357 SCH_COMMIT commit( m_toolMgr );
1358
1359 if( m_editPoints->GetParent()->Type() == SCH_SHAPE_T && poly.GetPointCount() <= 2 )
1360 return 0;
1361 if( m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T && poly.GetPointCount() <= 3 )
1362 return 0;
1363
1364 commit.Modify( shape, m_frame->GetScreen() );
1365
1366 int idx = getEditedPointIndex();
1367 int last = (int) poly.GetPointCount() - 1;
1368
1369 if( idx == 0 && poly.GetPoint( 0 ) == poly.GetPoint( last ) )
1370 {
1371 poly.Remove( idx );
1372 poly.SetPoint( last-1, poly.GetPoint( 0 ) );
1373 }
1374 else
1375 {
1376 poly.Remove( idx );
1377 }
1378
1379 shape->SetHatchingDirty();
1380
1381 setEditedPoint( nullptr );
1382
1383 updateItem( shape, true );
1384 updatePoints();
1385
1386 commit.Push( _( "Remove Corner" ) );
1387 return 0;
1388}
1389
1390
1392{
1393 updatePoints();
1394 return 0;
1395}
1396
1397
1399{
1407}
1408
1409
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
static TOOL_ACTION activatePointEditor
Definition: actions.h:225
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
ARC_POINT_EDIT_BEHAVIOR(SCH_SHAPE &aArc)
void 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.
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.
BITMAP_POINT_EDIT_BEHAVIOR(SCH_BITMAP &aBitmap)
void UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
static constexpr BOX2< VECTOR2I > ByCorners(const VECTOR2I &aCorner1, const VECTOR2I &aCorner2)
Definition: box2.h:70
constexpr const Vec GetCenter() const
Definition: box2.h:230
constexpr coord_type GetLeft() const
Definition: box2.h:228
constexpr coord_type GetRight() const
Definition: box2.h:217
constexpr coord_type GetTop() const
Definition: box2.h:229
constexpr coord_type GetBottom() const
Definition: box2.h:222
Represent a set of changes (additions, deletions or modifications) of a data model (e....
Definition: commit.h:74
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Modify a given item in the model.
Definition: commit.h:108
bool Empty() const
Definition: commit.h:150
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Add a menu entry to run a TOOL_ACTION on selected items.
EDIT_CONSTRAINT for a EDIT_LINE, that constrains the line to move perpendicular to the line itself.
bool IsHorizontal() const
Definition: eda_angle.h:138
bool IsType(FRAME_T aType) const
The base class for create windows for drawing purpose.
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:89
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:101
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
Definition: eda_item.h:174
EDA_ITEM * GetParent() const
Definition: eda_item.h:103
bool IsNew() const
Definition: eda_item.h:107
void SetStartX(int x)
Definition: eda_shape.h:191
void SetEndY(int aY)
Definition: eda_shape.h:226
int GetEndX() const
Definition: eda_shape.h:217
int GetRectangleWidth() const
Definition: eda_shape.cpp:419
void SetStartY(int y)
Definition: eda_shape.h:184
SHAPE_POLY_SET & GetPolyShape()
Definition: eda_shape.h:336
SHAPE_T GetShape() const
Definition: eda_shape.h:168
int GetEndY() const
Definition: eda_shape.h:216
void SetEndX(int aX)
Definition: eda_shape.h:233
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:215
bool IsClosed() const
Definition: eda_shape.cpp:505
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition: eda_shape.h:173
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:219
wxString SHAPE_T_asString() const
Definition: eda_shape.cpp:340
int GetRectangleHeight() const
Definition: eda_shape.cpp:405
void SetHatchingDirty()
Definition: eda_shape.h:147
"Standard" table-cell editing behavior.
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:134
virtual void ClearRenderCache()
Definition: eda_text.cpp:651
void SetConstraint(EDIT_CONSTRAINT< EDIT_LINE > *aConstraint)
Set a constraint for and EDIT_POINT.
Definition: edit_points.h:267
EDIT_POINTS is a VIEW_ITEM that manages EDIT_POINTs and EDIT_LINEs and draws them.
Definition: edit_points.h:353
void AddPoint(const EDIT_POINT &aPoint)
Add an EDIT_POINT.
Definition: edit_points.h:390
EDIT_LINE & Line(unsigned int aIndex)
Definition: edit_points.h:521
void AddIndicatorLine(EDIT_POINT &aOrigin, EDIT_POINT &aEnd)
Adds an EDIT_LINE that is shown as an indicator, rather than an editable line (no center point drag,...
Definition: edit_points.h:434
unsigned int LinesSize() const
Return number of stored EDIT_LINEs.
Definition: edit_points.h:542
EDIT_POINT & Point(unsigned int aIndex)
Definition: edit_points.h:511
void AddLine(const EDIT_LINE &aLine)
Adds an EDIT_LINE.
Definition: edit_points.h:410
Represent a single point that can be used for modifying items.
Definition: edit_points.h:48
virtual std::pair< EDA_ITEM *, int > GetConnected() const
Return a connected item record comprising an EDA_ITEM* and a STARTPOINT/ENDPOINT flag.
Definition: edit_points.h:79
int GetY() const
Return Y coordinate of an EDIT_POINT.
Definition: edit_points.h:95
static const int POINT_SIZE
Single point size in pixels.
Definition: edit_points.h:190
virtual void SetPosition(const VECTOR2I &aPosition)
Set new coordinates for an EDIT_POINT.
Definition: edit_points.h:107
virtual VECTOR2I GetPosition() const
Return coordinates of an EDIT_POINT.
Definition: edit_points.h:71
int GetX() const
Return X coordinate of an EDIT_POINT.
Definition: edit_points.h:87
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:241
static const TOOL_EVENT ClearedEvent
Definition: actions.h:298
static const TOOL_EVENT SelectedEvent
Definition: actions.h:296
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:303
static const TOOL_EVENT PointSelectedEvent
Definition: actions.h:295
An interface for classes handling user events controlling the view behavior such as zooming,...
virtual void CaptureCursor(bool aEnabled)
Force the cursor to stay within the drawing panel area.
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Place the cursor immediately at a given point.
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:67
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:297
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:332
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1673
VECTOR2D ToWorld(const VECTOR2D &aCoord, bool aAbsolute=true) const
Converts a screen space point/vector to a point/vector in world space coordinates.
Definition: view.cpp:457
Define a library symbol object.
Definition: lib_symbol.h:85
std::vector< SCH_PIN * > GetPins(int aUnit, int aBodyStyle) const
Return a list of pin object pointers from the draw item list.
Definition: lib_symbol.cpp:790
void UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
void UpdateItem(const EDIT_POINT &aEditedPoints, 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.
LINE_POINT_EDIT_BEHAVIOR(SCH_LINE &aLine, SCH_SCREEN &aScreen)
A helper class interface to manage the edit points for a single item.
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 UpdateItem(SCH_SHAPE &aRect, const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints)
static void UpdatePoints(SCH_SHAPE &aRect, EDIT_POINTS &aPoints)
static void PinEditedCorner(const EDIT_POINT &aEditedPoint, const EDIT_POINTS &aPoints, int minWidth, int minHeight, VECTOR2I &topLeft, VECTOR2I &topRight, VECTOR2I &botLeft, VECTOR2I &botRight)
Update the coordinates of 4 corners of a rectangle, according to constraints and the moved corner.
static void MakePoints(SCH_SHAPE &aRect, EDIT_POINTS &aPoints)
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.
RECTANGLE_POINT_EDIT_BEHAVIOR(SCH_SHAPE &aRect, EDA_DRAW_FRAME &aFrame)
void dragPinsOnEdge(const std::vector< SEG > &aOldEdges, const std::vector< VECTOR2I > &aMoveVecs, int aEdgeUnit, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) const
void UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
A REFERENCE_IMAGE is a wrapper around a BITMAP_IMAGE that is displayed in an editor as a reference fo...
void SetTransformOriginOffset(const VECTOR2I &aCenter)
VECTOR2I GetTransformOriginOffset() const
Get the center of scaling, etc, relative to the image center (GetPosition()).
VECTOR2I GetPosition() const
VECTOR2I GetSize() const
double GetImageScale() const
void SetImageScale(double aScale)
Set the image "zoom" value.
static TOOL_ACTION pointEditorAddCorner
Definition: sch_actions.h:153
static TOOL_ACTION pointEditorRemoveCorner
Definition: sch_actions.h:154
A shim class between EDA_DRAW_FRAME and several derived classes: SYMBOL_EDIT_FRAME,...
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
Object to handle a bitmap image that can be inserted in a schematic.
Definition: sch_bitmap.h:40
REFERENCE_IMAGE & GetReferenceImage()
Definition: sch_bitmap.h:51
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
Definition: sch_commit.cpp:433
virtual void Revert() override
Revert the commit by restoring the modified items state.
Definition: sch_commit.cpp:511
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:167
int GetUnit() const
Definition: sch_item.h:233
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:41
void SetStartPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:139
VECTOR2I GetEndPoint() const
Definition: sch_line.h:143
VECTOR2I GetStartPoint() const
Definition: sch_line.h:138
void SetEndPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:144
void updatePoints()
Update which point is being edited.
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
void setEditedPoint(EDIT_POINT *aPoint)
Return true if aPoint is the currently modified point.
bool Init() override
Init() is called once upon a registration of the tool.
void updateParentItem(bool aSnapToGrid, SCH_COMMIT &aCommit) const
< Update item's points with edit points.
void updateEditedPoint(const TOOL_EVENT &aEvent)
Clear references to the points.
bool addCornerCondition(const SELECTION &aSelection)
std::unique_ptr< POINT_EDIT_BEHAVIOR > m_editBehavior
EDIT_POINT * m_editedPoint
Re-entrancy guards.
int modifiedSelection(const TOOL_EVENT &aEvent)
int Main(const TOOL_EVENT &aEvent)
int getEditedPointIndex() const
std::shared_ptr< EDIT_POINTS > m_editPoints
Current item-specific edit behavior.
int clearEditedPoints(const TOOL_EVENT &aEvent)
Set the current point being edited. NULL means none.
bool removeCornerCondition(const SELECTION &aSelection)
bool m_inPointEditor
Currently available edit points.
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
void makePointsAndBehavior(EDA_ITEM *aItem)
Currently edited point, NULL if there is none.
int removeCorner(const TOOL_EVENT &aEvent)
int addCorner(const TOOL_EVENT &aEvent)
TOOL_ACTION handlers.
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition: sch_screen.h:111
SCH_SELECTION & GetSelection()
void SetPosition(const VECTOR2I &aPos) override
Definition: sch_shape.h:84
void Move(const VECTOR2I &aOffset) override
Move the item by aMoveVector to a new position.
Definition: sch_shape.cpp:80
void SetEditState(int aState)
Definition: sch_shape.h:92
VECTOR2I GetCenter() const
Definition: sch_shape.h:86
void Normalize()
Definition: sch_shape.cpp:86
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: sch_shape.cpp:125
void CalcEdit(const VECTOR2I &aPosition) override
Calculate the attributes of an item at aPosition when it is being edited.
Definition: sch_shape.h:90
VECTOR2I GetPosition() const override
Definition: sch_shape.h:83
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:47
void SetPositionIgnoringPins(const VECTOR2I &aPosition)
Definition: sch_sheet.cpp:883
int GetMinWidth(bool aFromLeft) const
Return the minimum width of the sheet based on the widths of the sheet pin text.
Definition: sch_sheet.cpp:519
VECTOR2I GetSize() const
Definition: sch_sheet.h:118
VECTOR2I GetPosition() const override
Definition: sch_sheet.h:415
int GetMinHeight(bool aFromTop) const
Return the minimum height that the sheet can be resized based on the sheet pin positions.
Definition: sch_sheet.cpp:553
void Resize(const VECTOR2I &aSize)
Resize this sheet to aSize and adjust all of the labels accordingly.
Definition: sch_sheet.cpp:996
SCH_TABLECELL_POINT_EDIT_BEHAVIOR(SCH_TABLECELL &aCell, SCH_SCREEN &aScreen)
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.
int GetColSpan() const
Definition: sch_tablecell.h:61
int GetRowSpan() const
Definition: sch_tablecell.h:64
int GetColumn() const
int GetRow() const
A foundation class for a tool operating on a schematic or symbol.
Definition: sch_tool_base.h:48
void updateItem(EDA_ITEM *aItem, bool aUpdateRTree) const
Similar to getView()->Update(), but handles items that are redrawn by their parents and updating the ...
bool Init() override
Init() is called once upon a registration of the tool.
Definition: sch_tool_base.h:64
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
Definition: sch_tool_base.h:84
SCH_SELECTION_TOOL * m_selectionTool
Definition: seg.h:42
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.cpp:388
EDA_ITEM * Front() const
Definition: selection.h:172
int Size() const
Returns the number of selected parts.
Definition: selection.h:116
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
virtual const VECTOR2I GetPoint(int aIndex) const override
void SetPoint(int aIndex, const VECTOR2I &aPos)
Move a point to a specific location.
virtual size_t GetPointCount() const override
virtual const SEG GetSegment(int aIndex) const override
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.
void Insert(size_t aVertex, const VECTOR2I &aP)
const std::vector< VECTOR2I > & CPoints() const
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
void UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
SHEET_POINT_EDIT_BEHAVIOR(SCH_SHEET &aSheet)
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.
The symbol library editor main window.
A textbox is edited as a rectnagle when it is orthogonally aligned.
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 UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
TEXTBOX_POINT_EDIT_BEHAVIOR(SCH_TEXTBOX &aTextbox)
bool ToolStackIsEmpty()
Definition: tools_holder.h:125
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:44
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:220
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:38
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
Generic, UI-independent tool event.
Definition: tool_event.h:168
bool DisableGridSnapping() const
Definition: tool_event.h:368
const VECTOR2D Position() const
Return mouse cursor position in world coordinates.
Definition: tool_event.h:290
bool IsDrag(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:312
const VECTOR2D DragOrigin() const
Return the point where dragging has started.
Definition: tool_event.h:296
bool IsMotion() const
Definition: tool_event.h:327
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
TOOL_MENU & GetToolMenu()
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Suspend execution of the tool until an event specified in aEventList arrives.
void Activate()
Run the tool.
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:44
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:283
#define _(s)
#define ENDPOINT
ends. (Used to support dragging.)
#define STARTPOINT
When a line is selected, these flags indicate which.
@ FRAME_SCH_SYMBOL_EDITOR
Definition: frame_type.h:35
@ LAYER_NOTES
Definition: layer_ids.h:456
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:96
constexpr int Mils2IU(const EDA_IU_SCALE &aIuScale, int mils)
Definition: eda_units.h:159
std::vector< SEG > GetSegsInDirection(const BOX2I &aBox, DIRECTION_45::Directions aDir)
Get the segments of a box that are in the given direction.
Definition: shape_utils.cpp:93
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:390
@ RECT_RIGHT
@ RECT_LEFT
@ RECT_BOT
@ RECT_TOP
@ RECT_CENTER
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
RECTANGLE_POINTS
@ RECT_BOTLEFT
@ RECT_TOPLEFT
@ RECT_TOPRIGHT
@ RECT_CENTER
@ RECT_BOTRIGHT
RECTANGLE_LINES
@ RECT_RIGHT
@ RECT_LEFT
@ RECT_BOT
@ RECT_TOP
TABLECELL_POINTS
@ ROW_HEIGHT
@ COL_WIDTH
static const std::vector< KICAD_T > pointEditorTypes
LINE_POINTS
@ LINE_START
@ LINE_END
REFIMAGE_POINTS
@ REFIMG_ORIGIN
ARC_POINTS
@ ARC_START
@ ARC_END
@ ARC_CENTER
std::optional< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:39
Utility functions for working with shapes.
constexpr int MilsToIU(int mils) const
Definition: base_units.h:93
@ MD_SHIFT
Definition: tool_event.h:143
@ BUT_LEFT
Definition: tool_event.h:132
@ SCH_LINE_T
Definition: typeinfo.h:163
@ SCH_TABLECELL_T
Definition: typeinfo.h:166
@ SCH_SHEET_T
Definition: typeinfo.h:174
@ SCH_SHAPE_T
Definition: typeinfo.h:149
@ SCH_RULE_AREA_T
Definition: typeinfo.h:170
@ SCH_ITEM_LOCATE_GRAPHIC_LINE_T
Definition: typeinfo.h:187
@ SCH_BITMAP_T
Definition: typeinfo.h:164
@ SCH_TEXTBOX_T
Definition: typeinfo.h:152
constexpr int sign(T val)
Definition: util.h:159
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695