KiCad PCB EDA Suite
Loading...
Searching...
No Matches
ee_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 "ee_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/ee_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 ), m_screen( aScreen )
99 {
100 }
101
102 void MakePoints( EDIT_POINTS& aPoints ) override
103 {
104 std::pair<EDA_ITEM*, int> connectedStart = { nullptr, STARTPOINT };
105 std::pair<EDA_ITEM*, int> connectedEnd = { nullptr, STARTPOINT };
106
108 {
109 if( test->GetLayer() != LAYER_NOTES )
110 continue;
111
112 if( test == &m_line )
113 continue;
114
115 SCH_LINE* testLine = static_cast<SCH_LINE*>( test );
116
117 if( testLine->GetStartPoint() == m_line.GetStartPoint() )
118 {
119 connectedStart = { testLine, STARTPOINT };
120 }
121 else if( testLine->GetEndPoint() == m_line.GetStartPoint() )
122 {
123 connectedStart = { testLine, ENDPOINT };
124 }
125 else if( testLine->GetStartPoint() == m_line.GetEndPoint() )
126 {
127 connectedEnd = { testLine, STARTPOINT };
128 }
129 else if( testLine->GetEndPoint() == m_line.GetEndPoint() )
130 {
131 connectedEnd = { testLine, ENDPOINT };
132 }
133 }
134
135 aPoints.AddPoint( m_line.GetStartPoint(), connectedStart );
136 aPoints.AddPoint( m_line.GetEndPoint(), connectedEnd );
137 }
138
139 void UpdatePoints( EDIT_POINTS& aPoints ) override
140 {
143 }
144
145 void UpdateItem( const EDIT_POINT& aEditedPoints, EDIT_POINTS& aPoints, COMMIT& aCommit,
146 std::vector<EDA_ITEM*>& aUpdatedItems ) override
147 {
150
151 std::pair<EDA_ITEM*, int> connected = aPoints.Point( LINE_START ).GetConnected();
152
153 if( connected.first )
154 {
155 aCommit.Modify( connected.first, &m_screen );
156 aUpdatedItems.push_back( connected.first );
157
158 if( connected.second == STARTPOINT )
159 static_cast<SCH_LINE*>( connected.first )->SetStartPoint( m_line.GetStartPoint() );
160 else if( connected.second == ENDPOINT )
161 static_cast<SCH_LINE*>( connected.first )->SetEndPoint( m_line.GetStartPoint() );
162 }
163
164 connected = aPoints.Point( LINE_END ).GetConnected();
165
166 if( connected.first )
167 {
168 aCommit.Modify( connected.first, &m_screen );
169 aUpdatedItems.push_back( connected.first );
170
171 if( connected.second == STARTPOINT )
172 static_cast<SCH_LINE*>( connected.first )->SetStartPoint( m_line.GetEndPoint() );
173 else if( connected.second == ENDPOINT )
174 static_cast<SCH_LINE*>( connected.first )->SetEndPoint( m_line.GetEndPoint() );
175 }
176 }
177
178private:
181};
182
183
185{
186public:
188 m_arc( aArc )
189 {
190 wxASSERT( m_arc.GetShape() == SHAPE_T::ARC );
191 }
192
193 void MakePoints( EDIT_POINTS& aPoints ) override
194 {
195 aPoints.AddPoint( m_arc.GetStart() );
196 aPoints.AddPoint( m_arc.GetEnd() );
197 aPoints.AddPoint( m_arc.GetPosition() );
198
199 aPoints.AddIndicatorLine( aPoints.Point( ARC_CENTER ), aPoints.Point( ARC_START ) );
200 aPoints.AddIndicatorLine( aPoints.Point( ARC_CENTER ), aPoints.Point( ARC_END ) );
201 }
202
203 void UpdatePoints( EDIT_POINTS& aPoints ) override
204 {
205 aPoints.Point( ARC_START ).SetPosition( m_arc.GetStart() );
206 aPoints.Point( ARC_END ).SetPosition( m_arc.GetEnd() );
208 }
209
210 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
211 std::vector<EDA_ITEM*>& aUpdatedItems ) override
212 {
213 if( isModified( aEditedPoint, aPoints.Point( ARC_START ) ) )
214
215 {
216 m_arc.SetEditState( 2 );
217 m_arc.CalcEdit( aPoints.Point( ARC_START ).GetPosition() );
218 }
219 else if( isModified( aEditedPoint, aPoints.Point( ARC_END ) ) )
220 {
221 m_arc.SetEditState( 3 );
222 m_arc.CalcEdit( aPoints.Point( ARC_END ).GetPosition() );
223 }
224 else if( isModified( aEditedPoint, aPoints.Point( ARC_CENTER ) ) )
225 {
226 m_arc.SetEditState( 4 );
227 m_arc.CalcEdit( aPoints.Point( ARC_CENTER ).GetPosition() );
228 }
229
230 aUpdatedItems.push_back( &m_arc );
231 }
232private:
234};
235
236
238{
239public:
241
242 void MakePoints( EDIT_POINTS& aPoints ) override
243 {
244 const REFERENCE_IMAGE& refImage = m_bitmap.GetReferenceImage();
245 const VECTOR2I topLeft = refImage.GetPosition() - refImage.GetSize() / 2;
246 const VECTOR2I botRight = refImage.GetPosition() + refImage.GetSize() / 2;
247
248 aPoints.AddPoint( topLeft );
249 aPoints.AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
250 aPoints.AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
251 aPoints.AddPoint( botRight );
252
253 aPoints.AddPoint( refImage.GetPosition() + refImage.GetTransformOriginOffset() );
254 }
255
256 void UpdatePoints( EDIT_POINTS& aPoints ) override
257 {
258 const REFERENCE_IMAGE& refImage = m_bitmap.GetReferenceImage();
259 const VECTOR2I topLeft = refImage.GetPosition() - refImage.GetSize() / 2;
260 const VECTOR2I botRight = refImage.GetPosition() + refImage.GetSize() / 2;
261
262 aPoints.Point( RECT_TOPLEFT ).SetPosition( topLeft );
263 aPoints.Point( RECT_TOPRIGHT ).SetPosition( botRight.x, topLeft.y );
264 aPoints.Point( RECT_BOTLEFT ).SetPosition( topLeft.x, botRight.y );
265 aPoints.Point( RECT_BOTRIGHT ).SetPosition( botRight );
266
267 aPoints.Point( REFIMG_ORIGIN )
268 .SetPosition( refImage.GetPosition() + refImage.GetTransformOriginOffset() );
269 }
270
271 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
272 std::vector<EDA_ITEM*>& aUpdatedItems ) override
273 {
275 const VECTOR2I topLeft = aPoints.Point( RECT_TOPLEFT ).GetPosition();
276 const VECTOR2I topRight = aPoints.Point( RECT_TOPRIGHT ).GetPosition();
277 const VECTOR2I botLeft = aPoints.Point( RECT_BOTLEFT ).GetPosition();
278 const VECTOR2I botRight = aPoints.Point( RECT_BOTRIGHT ).GetPosition();
279 const VECTOR2I xfrmOrigin = aPoints.Point( REFIMG_ORIGIN ).GetPosition();
280
281 if( isModified( aEditedPoint, aPoints.Point( REFIMG_ORIGIN ) ) )
282 {
283 // Moving the transform origin
284 // As the other points didn't move, we can get the image extent from them
285 const VECTOR2I newOffset = xfrmOrigin - ( topLeft + botRight ) / 2;
286 refImg.SetTransformOriginOffset( newOffset );
287 }
288 else
289 {
290 const VECTOR2I oldOrigin = refImg.GetPosition() + refImg.GetTransformOriginOffset();
291 const VECTOR2I oldSize = refImg.GetSize();
292 const VECTOR2I pos = refImg.GetPosition();
293
294 OPT_VECTOR2I newCorner;
295 VECTOR2I oldCorner = pos;
296
297 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) ) )
298 {
299 newCorner = topLeft;
300 oldCorner -= oldSize / 2;
301 }
302 else if( isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) ) )
303 {
304 newCorner = topRight;
305 oldCorner -= VECTOR2I( -oldSize.x, oldSize.y ) / 2;
306 }
307 else if( isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
308 {
309 newCorner = botLeft;
310 oldCorner -= VECTOR2I( oldSize.x, -oldSize.y ) / 2;
311 }
312 else if( isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) ) )
313 {
314 newCorner = botRight;
315 oldCorner += oldSize / 2;
316 }
317
318 if( newCorner )
319 {
320 // Turn in the respective vectors from the origin
321 *newCorner -= xfrmOrigin;
322 oldCorner -= oldOrigin;
323
324 // If we tried to cross the origin, clamp it to stop it
325 if( sign( newCorner->x ) != sign( oldCorner.x )
326 || sign( newCorner->y ) != sign( oldCorner.y ) )
327 {
328 *newCorner = VECTOR2I( 0, 0 );
329 }
330
331 const double newLength = newCorner->EuclideanNorm();
332 const double oldLength = oldCorner.EuclideanNorm();
333
334 double ratio = oldLength > 0 ? ( newLength / oldLength ) : 1.0;
335
336 // Clamp the scaling to a minimum of 50 mils
337 VECTOR2I newSize = oldSize * ratio;
338 double newWidth = std::max( newSize.x, EDA_UNIT_UTILS::Mils2IU( schIUScale, 50 ) );
339 double newHeight = std::max( newSize.y, EDA_UNIT_UTILS::Mils2IU( schIUScale, 50 ) );
340 ratio = std::min( newWidth / oldSize.x, newHeight / oldSize.y );
341
342 // Also handles the origin offset
343 refImg.SetImageScale( refImg.GetImageScale() * ratio );
344 }
345 }
346 aUpdatedItems.push_back( &m_bitmap );
347 }
348
349private:
351};
352
353
355{
356public:
359 m_cell( aCell ),
360 m_screen( aScreen )
361 {
362 }
363
364 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
365 std::vector<EDA_ITEM*>& aUpdatedItems ) override
366 {
367 SCH_TABLE& table = static_cast<SCH_TABLE&>( *m_cell.GetParent() );
368 bool rotated = !m_cell.GetTextAngle().IsHorizontal();
369
370 aCommit.Modify( &table, &m_screen );
371 aUpdatedItems.push_back( &table );
372
373 if( rotated )
374 {
375 if( isModified( aEditedPoint, aPoints.Point( ROW_HEIGHT ) ) )
376 {
377 m_cell.SetEnd( VECTOR2I( m_cell.GetEndX(), aPoints.Point( ROW_HEIGHT ).GetY() ) );
378
379 int colWidth = std::abs( m_cell.GetRectangleHeight() );
380
381 for( int ii = 0; ii < m_cell.GetColSpan() - 1; ++ii )
382 colWidth -= table.GetColWidth( m_cell.GetColumn() + ii );
383
384 table.SetColWidth( m_cell.GetColumn() + m_cell.GetColSpan() - 1, colWidth );
385 }
386 else if( isModified( aEditedPoint, aPoints.Point( COL_WIDTH ) ) )
387 {
388 m_cell.SetEnd( VECTOR2I( aPoints.Point( COL_WIDTH ).GetX(), m_cell.GetEndY() ) );
389
390 int rowHeight = m_cell.GetRectangleWidth();
391
392 for( int ii = 0; ii < m_cell.GetRowSpan() - 1; ++ii )
393 rowHeight -= table.GetRowHeight( m_cell.GetRow() + ii );
394
395 table.SetRowHeight( m_cell.GetRow() + m_cell.GetRowSpan() - 1, rowHeight );
396 }
397 }
398 else
399 {
400 if( isModified( aEditedPoint, aPoints.Point( COL_WIDTH ) ) )
401 {
402 m_cell.SetEnd( VECTOR2I( aPoints.Point( COL_WIDTH ).GetX(), m_cell.GetEndY() ) );
403
404 int colWidth = m_cell.GetRectangleWidth();
405
406 for( int ii = 0; ii < m_cell.GetColSpan() - 1; ++ii )
407 colWidth -= table.GetColWidth( m_cell.GetColumn() + ii );
408
409 table.SetColWidth( m_cell.GetColumn() + m_cell.GetColSpan() - 1, colWidth );
410 }
411 else if( isModified( aEditedPoint, aPoints.Point( ROW_HEIGHT ) ) )
412 {
413 m_cell.SetEnd( VECTOR2I( m_cell.GetEndX(), aPoints.Point( ROW_HEIGHT ).GetY() ) );
414
415 int rowHeight = m_cell.GetRectangleHeight();
416
417 for( int ii = 0; ii < m_cell.GetRowSpan() - 1; ++ii )
418 rowHeight -= table.GetRowHeight( m_cell.GetRow() + ii );
419
420 table.SetRowHeight( m_cell.GetRow() + m_cell.GetRowSpan() - 1, rowHeight );
421 }
422 }
423
424 table.Normalize();
425 }
426
427private:
430};
431
432
434{
435public:
437 m_rect( aRect ), m_frame( aFrame )
438 {
439 }
440
441 static void MakePoints( SCH_SHAPE& aRect, EDIT_POINTS& aPoints )
442 {
443 VECTOR2I topLeft = aRect.GetPosition();
444 VECTOR2I botRight = aRect.GetEnd();
445
446 aPoints.AddPoint( topLeft );
447 aPoints.AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
448 aPoints.AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
449 aPoints.AddPoint( botRight );
450 aPoints.AddPoint( aRect.GetCenter() );
451
452 aPoints.AddLine( aPoints.Point( RECT_TOPLEFT ), aPoints.Point( RECT_TOPRIGHT ) );
453 aPoints.Line( RECT_TOP ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_TOP ) ) );
454 aPoints.AddLine( aPoints.Point( RECT_TOPRIGHT ), aPoints.Point( RECT_BOTRIGHT ) );
455 aPoints.Line( RECT_RIGHT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_RIGHT ) ) );
456 aPoints.AddLine( aPoints.Point( RECT_BOTRIGHT ), aPoints.Point( RECT_BOTLEFT ) );
457 aPoints.Line( RECT_BOT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_BOT ) ) );
458 aPoints.AddLine( aPoints.Point( RECT_BOTLEFT ), aPoints.Point( RECT_TOPLEFT ) );
459 aPoints.Line( RECT_LEFT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_LEFT ) ) );
460 }
461
462 static void UpdatePoints( SCH_SHAPE& aRect, EDIT_POINTS& aPoints )
463 {
464 VECTOR2I topLeft = aRect.GetPosition();
465 VECTOR2I botRight = aRect.GetEnd();
466
467 aPoints.Point( RECT_TOPLEFT ).SetPosition( topLeft );
468 aPoints.Point( RECT_TOPRIGHT ).SetPosition( VECTOR2I( botRight.x, topLeft.y ) );
469 aPoints.Point( RECT_BOTLEFT ).SetPosition( VECTOR2I( topLeft.x, botRight.y ) );
470 aPoints.Point( RECT_BOTRIGHT ).SetPosition( botRight );
471 aPoints.Point( RECT_CENTER ).SetPosition( aRect.GetCenter() );
472 }
473
484 static void PinEditedCorner( const EDIT_POINT& aEditedPoint, const EDIT_POINTS& aPoints,
485 int minWidth, int minHeight, VECTOR2I& topLeft, VECTOR2I& topRight,
486 VECTOR2I& botLeft, VECTOR2I& botRight )
487 {
488 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) ) )
489 {
490 // pin edited point within opposite corner
491 topLeft.x = std::min( topLeft.x, botRight.x - minWidth );
492 topLeft.y = std::min( topLeft.y, botRight.y - minHeight );
493
494 // push edited point edges to adjacent corners
495 topRight.y = topLeft.y;
496 botLeft.x = topLeft.x;
497 }
498 else if( isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) ) )
499 {
500 // pin edited point within opposite corner
501 topRight.x = std::max( topRight.x, botLeft.x + minWidth );
502 topRight.y = std::min( topRight.y, botLeft.y - minHeight );
503
504 // push edited point edges to adjacent corners
505 topLeft.y = topRight.y;
506 botRight.x = topRight.x;
507 }
508 else if( isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
509 {
510 // pin edited point within opposite corner
511 botLeft.x = std::min( botLeft.x, topRight.x - minWidth );
512 botLeft.y = std::max( botLeft.y, topRight.y + minHeight );
513
514 // push edited point edges to adjacent corners
515 botRight.y = botLeft.y;
516 topLeft.x = botLeft.x;
517 }
518 else if( isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) ) )
519 {
520 // pin edited point within opposite corner
521 botRight.x = std::max( botRight.x, topLeft.x + minWidth );
522 botRight.y = std::max( botRight.y, topLeft.y + minHeight );
523
524 // push edited point edges to adjacent corners
525 botLeft.y = botRight.y;
526 topRight.x = botRight.x;
527 }
528 else if( isModified( aEditedPoint, aPoints.Line( RECT_TOP ) ) )
529 {
530 topLeft.y = std::min( topLeft.y, botRight.y - minHeight );
531 }
532 else if( isModified( aEditedPoint, aPoints.Line( RECT_LEFT ) ) )
533 {
534 topLeft.x = std::min( topLeft.x, botRight.x - minWidth );
535 }
536 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
537 {
538 botRight.y = std::max( botRight.y, topLeft.y + minHeight );
539 }
540 else if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
541 {
542 botRight.x = std::max( botRight.x, topLeft.x + minWidth );
543 }
544 }
545
546 static void UpdateItem( SCH_SHAPE& aRect, const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints )
547 {
548 VECTOR2I topLeft = aPoints.Point( RECT_TOPLEFT ).GetPosition();
549 VECTOR2I topRight = aPoints.Point( RECT_TOPRIGHT ).GetPosition();
550 VECTOR2I botLeft = aPoints.Point( RECT_BOTLEFT ).GetPosition();
551 VECTOR2I botRight = aPoints.Point( RECT_BOTRIGHT ).GetPosition();
552
553 PinEditedCorner( aEditedPoint, aPoints, schIUScale.MilsToIU( 1 ), schIUScale.MilsToIU( 1 ),
554 topLeft, topRight, botLeft, botRight );
555
556 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) )
557 || isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) )
558 || isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) )
559 || isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
560 {
561 aRect.SetPosition( topLeft );
562 aRect.SetEnd( botRight );
563 }
564 else if( isModified( aEditedPoint, aPoints.Line( RECT_TOP ) ) )
565 {
566 aRect.SetStartY( topLeft.y );
567 }
568 else if( isModified( aEditedPoint, aPoints.Line( RECT_LEFT ) ) )
569 {
570 aRect.SetStartX( topLeft.x );
571 }
572 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
573 {
574 aRect.SetEndY( botRight.y );
575 }
576 else if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
577 {
578 aRect.SetEndX( botRight.x );
579 }
580
581 for( unsigned i = 0; i < aPoints.LinesSize(); ++i )
582 {
583 if( !isModified( aEditedPoint, aPoints.Line( i ) ) )
584 {
585 aPoints.Line( i ).SetConstraint( new EC_PERPLINE( aPoints.Line( i ) ) );
586 }
587 }
588 }
589
590 void MakePoints( EDIT_POINTS& aPoints ) override
591 {
593 MakePoints( m_rect, aPoints );
594 }
595
596 void UpdatePoints( EDIT_POINTS& aPoints ) override
597 {
599 UpdatePoints( m_rect, aPoints );
600 }
601
602 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
603 std::vector<EDA_ITEM*>& aUpdatedItems ) override
604 {
605 VECTOR2I topLeft = aPoints.Point( RECT_TOPLEFT ).GetPosition();
606 VECTOR2I topRight = aPoints.Point( RECT_TOPRIGHT ).GetPosition();
607 VECTOR2I botLeft = aPoints.Point( RECT_BOTLEFT ).GetPosition();
608 VECTOR2I botRight = aPoints.Point( RECT_BOTRIGHT ).GetPosition();
609
610 PinEditedCorner( aEditedPoint, aPoints, schIUScale.MilsToIU( 1 ), schIUScale.MilsToIU( 1 ),
611 topLeft, topRight, botLeft, botRight );
612
613 const BOX2I oldBox = BOX2I::ByCorners( m_rect.GetStart(), m_rect.GetEnd() );
614 std::vector<SEG> oldSegs;
615 std::vector<VECTOR2I> moveVecs;
616
617 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) )
618 || isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) )
619 || isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) )
620 || isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
621 {
622 // Corner drags don't update pins. Not only is it an escape hatch to avoid
623 // moving pins, it also avoids tricky problems when the pins "fall off"
624 // the ends of one of the two segments and get either left behind or
625 // "swept up" into the corner.
626 m_rect.SetPosition( topLeft );
627 m_rect.SetEnd( botRight );
628 }
629 else if( isModified( aEditedPoint, aPoints.Point( RECT_CENTER ) ) )
630 {
631 VECTOR2I moveVec = aPoints.Point( RECT_CENTER ).GetPosition() - oldBox.GetCenter();
632 m_rect.Move( moveVec );
633 }
634 else if( isModified( aEditedPoint, aPoints.Line( RECT_TOP ) ) )
635 {
637 moveVecs.emplace_back( 0, topLeft.y - oldBox.GetTop() );
638 m_rect.SetStartY( topLeft.y );
639 }
640 else if( isModified( aEditedPoint, aPoints.Line( RECT_LEFT ) ) )
641 {
643 moveVecs.emplace_back( topLeft.x - oldBox.GetLeft(), 0 );
644 m_rect.SetStartX( topLeft.x );
645 }
646 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
647 {
649 moveVecs.emplace_back( 0, botRight.y - oldBox.GetBottom() );
650 m_rect.SetEndY( botRight.y );
651 }
652 else if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
653 {
655 moveVecs.emplace_back( botRight.x - oldBox.GetRight(), 0 );
656 m_rect.SetEndX( botRight.x );
657 }
658
659 dragPinsOnEdge( oldSegs, moveVecs, m_rect.GetUnit(), aCommit, aUpdatedItems );
660
661 for( unsigned i = 0; i < aPoints.LinesSize(); ++i )
662 {
663 if( !isModified( aEditedPoint, aPoints.Line( i ) ) )
664 {
665 aPoints.Line( i ).SetConstraint( new EC_PERPLINE( aPoints.Line( i ) ) );
666 }
667 }
668 }
669
670private:
671 void dragPinsOnEdge( const std::vector<SEG>& aOldEdges, const std::vector<VECTOR2I>& aMoveVecs,
672 int aEdgeUnit, COMMIT& aCommit,
673 std::vector<EDA_ITEM*>& aUpdatedItems ) const
674 {
675 wxCHECK( aOldEdges.size() == aMoveVecs.size(), /* void */ );
676
677 // This only make sense in the symbol editor
679 return;
680
682
683 // And only if the setting is enabled
684 if( !editor.GetSettings()->m_dragPinsAlongWithEdges )
685 return;
686
687 // Adjuting pins on a different unit to a unit-limited shape
688 // seems suspect.
689 wxCHECK( aEdgeUnit == 0 || aEdgeUnit == editor.GetUnit(), /* void */ );
690
691 /*
692 * Get a list of pins on a line segment
693 */
694 const auto getPinsOnSeg =
695 []( LIB_SYMBOL& aSymbol, int aUnit, const SEG& aSeg,
696 bool aIncludeEnds ) -> std::vector<SCH_PIN*>
697 {
698 std::vector<SCH_PIN*> pins;
699
700 for( SCH_PIN* pin : aSymbol.GetPins( aUnit, 0 ) )
701 {
702 // Figure out if the pin "connects" to the line
703 const VECTOR2I pinRootPos = pin->GetPinRoot();
704
705 if( aSeg.Contains( pinRootPos ) )
706 {
707 if( aIncludeEnds || ( pinRootPos != aSeg.A && pinRootPos != aSeg.B ) )
708 {
709 pins.push_back( pin );
710 }
711 }
712 }
713
714 return pins;
715 };
716
717 LIB_SYMBOL* const symbol = editor.GetCurSymbol();
718
719 for( std::size_t i = 0; i < aOldEdges.size(); ++i )
720 {
721 if( aMoveVecs[i] == VECTOR2I( 0, 0 ) || !symbol )
722 continue;
723
724 const std::vector<SCH_PIN*> pins = getPinsOnSeg( *symbol, aEdgeUnit, aOldEdges[i],
725 false );
726
727 for( SCH_PIN* pin : pins )
728 {
729 aCommit.Modify( pin );
730 aUpdatedItems.push_back( pin );
731
732 // Move the pin
733 pin->Move( aMoveVecs[i] );
734 }
735 }
736 }
737
738private:
741};
742
743
745{
746public:
748
749 void MakePoints( EDIT_POINTS& aPoints ) override
750 {
753 }
754
755 void UpdatePoints( EDIT_POINTS& aPoints ) override
756 {
757 // point editor works only with rectangles having width and height > 0
758 // Some symbols can have rectangles with width or height < 0
759 // So normalize the size:
762 }
763
764 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
765 std::vector<EDA_ITEM*>& aUpdatedItems ) override
766 {
769 }
770
771private:
773};
774
775
777{
778public:
780
781 void MakePoints( EDIT_POINTS& aPoints ) override
782 {
783 VECTOR2I topLeft = m_sheet.GetPosition();
784 VECTOR2I botRight = m_sheet.GetPosition() + m_sheet.GetSize();
785
786 aPoints.AddPoint( topLeft );
787 aPoints.AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
788 aPoints.AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
789 aPoints.AddPoint( botRight );
790
791 aPoints.AddLine( aPoints.Point( RECT_TOPLEFT ), aPoints.Point( RECT_TOPRIGHT ) );
792 aPoints.Line( RECT_TOP ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_TOP ) ) );
793 aPoints.AddLine( aPoints.Point( RECT_TOPRIGHT ), aPoints.Point( RECT_BOTRIGHT ) );
794 aPoints.Line( RECT_RIGHT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_RIGHT ) ) );
795 aPoints.AddLine( aPoints.Point( RECT_BOTRIGHT ), aPoints.Point( RECT_BOTLEFT ) );
796 aPoints.Line( RECT_BOT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_BOT ) ) );
797 aPoints.AddLine( aPoints.Point( RECT_BOTLEFT ), aPoints.Point( RECT_TOPLEFT ) );
798 aPoints.Line( RECT_LEFT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_LEFT ) ) );
799 }
800
801 void UpdatePoints( EDIT_POINTS& aPoints ) override
802 {
803 VECTOR2I topLeft = m_sheet.GetPosition();
804 VECTOR2I botRight = m_sheet.GetPosition() + m_sheet.GetSize();
805
806 aPoints.Point( RECT_TOPLEFT ).SetPosition( topLeft );
807 aPoints.Point( RECT_TOPRIGHT ).SetPosition( botRight.x, topLeft.y );
808 aPoints.Point( RECT_BOTLEFT ).SetPosition( topLeft.x, botRight.y );
809 aPoints.Point( RECT_BOTRIGHT ).SetPosition( botRight );
810 }
811
812 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
813 std::vector<EDA_ITEM*>& aUpdatedItems ) override
814 {
815 VECTOR2I topLeft = aPoints.Point( RECT_TOPLEFT ).GetPosition();
816 VECTOR2I topRight = aPoints.Point( RECT_TOPRIGHT ).GetPosition();
817 VECTOR2I botLeft = aPoints.Point( RECT_BOTLEFT ).GetPosition();
818 VECTOR2I botRight = aPoints.Point( RECT_BOTRIGHT ).GetPosition();
819 VECTOR2I sheetNewPos = m_sheet.GetPosition();
820 VECTOR2I sheetNewSize = m_sheet.GetSize();
821
822 bool editedTopRight = isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) );
823 bool editedBotLeft = isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) );
824 bool editedBotRight = isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) );
825
826 if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
827 editedTopRight = true;
828 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
829 editedBotLeft = true;
830
832 aEditedPoint, aPoints, m_sheet.GetMinWidth( editedTopRight || editedBotRight ),
833 m_sheet.GetMinHeight( editedBotLeft || editedBotRight ), topLeft, topRight, botLeft,
834 botRight );
835
836 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) )
837 || isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) )
838 || isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) )
839 || isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
840 {
841 sheetNewPos = topLeft;
842 sheetNewSize = VECTOR2I( botRight.x - topLeft.x, botRight.y - topLeft.y );
843 }
844 else if( isModified( aEditedPoint, aPoints.Line( RECT_TOP ) ) )
845 {
846 sheetNewPos = VECTOR2I( m_sheet.GetPosition().x, topLeft.y );
847 sheetNewSize = VECTOR2I( m_sheet.GetSize().x, botRight.y - topLeft.y );
848 }
849 else if( isModified( aEditedPoint, aPoints.Line( RECT_LEFT ) ) )
850 {
851 sheetNewPos = VECTOR2I( topLeft.x, m_sheet.GetPosition().y );
852 sheetNewSize = VECTOR2I( botRight.x - topLeft.x, m_sheet.GetSize().y );
853 }
854 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
855 {
856 sheetNewSize = VECTOR2I( m_sheet.GetSize().x, botRight.y - topLeft.y );
857 }
858 else if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
859 {
860 sheetNewSize = VECTOR2I( botRight.x - topLeft.x, m_sheet.GetSize().y );
861 }
862
863 for( unsigned i = 0; i < aPoints.LinesSize(); ++i )
864 {
865 if( !isModified( aEditedPoint, aPoints.Line( i ) ) )
866 {
867 aPoints.Line( i ).SetConstraint( new EC_PERPLINE( aPoints.Line( i ) ) );
868 }
869 }
870
871 if( m_sheet.GetPosition() != sheetNewPos )
872 m_sheet.SetPositionIgnoringPins( sheetNewPos );
873
874 if( m_sheet.GetSize() != sheetNewSize )
875 m_sheet.Resize( sheetNewSize );
876 }
877
878private:
880};
881
882
884{
885 m_editBehavior = nullptr;
886 m_editPoints = std::make_shared<EDIT_POINTS>( aItem );
887
888 if( !aItem )
889 return;
890
891 // Generate list of edit points based on the item type
892 switch( aItem->Type() )
893 {
894 case SCH_SHAPE_T:
895 {
896 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem );
897
898 switch( shape->GetShape() )
899 {
900 case SHAPE_T::ARC:
901 m_editBehavior = std::make_unique<ARC_POINT_EDIT_BEHAVIOR>( *shape );
902 break;
903 case SHAPE_T::CIRCLE:
904 m_editBehavior = std::make_unique<EDA_CIRCLE_POINT_EDIT_BEHAVIOR>( *shape );
905 break;
906 case SHAPE_T::RECTANGLE:
907 m_editBehavior = std::make_unique<RECTANGLE_POINT_EDIT_BEHAVIOR>( *shape, *m_frame );
908 break;
909 case SHAPE_T::POLY:
910 m_editBehavior = std::make_unique<EDA_POLYGON_POINT_EDIT_BEHAVIOR>( *shape );
911 break;
912 case SHAPE_T::BEZIER:
913 m_editBehavior = std::make_unique<EDA_BEZIER_POINT_EDIT_BEHAVIOR>( *shape );
914 break;
915 default:
917 }
918
919 break;
920 }
921 case SCH_RULE_AREA_T:
922 {
923 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem );
924 // Implemented directly as a polygon
925 m_editBehavior = std::make_unique<EDA_POLYGON_POINT_EDIT_BEHAVIOR>( *shape );
926 break;
927 }
928 case SCH_TEXTBOX_T:
929 {
930 SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( aItem );
931 m_editBehavior = std::make_unique<TEXTBOX_POINT_EDIT_BEHAVIOR>( *textbox );
932 break;
933 }
934 case SCH_TABLECELL_T:
935 {
936 SCH_TABLECELL* cell = static_cast<SCH_TABLECELL*>( aItem );
937 m_editBehavior = std::make_unique<SCH_TABLECELL_POINT_EDIT_BEHAVIOR>( *cell, *m_frame->GetScreen() );
938 break;
939 }
940 case SCH_SHEET_T:
941 {
942 SCH_SHEET& sheet = static_cast<SCH_SHEET&>( *aItem );
943 m_editBehavior = std::make_unique<SHEET_POINT_EDIT_BEHAVIOR>( sheet );
944 break;
945 }
946 case SCH_BITMAP_T:
947 {
948 SCH_BITMAP& bitmap = static_cast<SCH_BITMAP&>( *aItem );
949 m_editBehavior = std::make_unique<BITMAP_POINT_EDIT_BEHAVIOR>( bitmap );
950 break;
951 }
952 case SCH_LINE_T:
953 {
954 SCH_LINE& line = static_cast<SCH_LINE&>( *aItem );
955 m_editBehavior = std::make_unique<LINE_POINT_EDIT_BEHAVIOR>( line, *m_frame->GetScreen() );
956 break;
957 }
958 default:
959 {
960 m_editPoints.reset();
961 break;
962 }
963 }
964
965 // If we got a behavior, generate the points
966 if( m_editBehavior )
967 {
968 wxCHECK( m_editPoints, /* void */ );
969 m_editBehavior->MakePoints( *m_editPoints );
970 }
971}
972
973
975 EE_TOOL_BASE<SCH_BASE_FRAME>( "eeschema.PointEditor" ),
976 m_editedPoint( nullptr ),
977 m_inPointEditor( false )
978{
979}
980
981
983{
984 EE_TOOL_BASE::Reset( aReason );
985
986 m_editPoints.reset();
987 m_editedPoint = nullptr;
988}
989
990
992{
994
995 auto& menu = m_selectionTool->GetToolMenu().GetMenu();
997 std::bind( &EE_POINT_EDITOR::addCornerCondition, this, _1 ) );
999 std::bind( &EE_POINT_EDITOR::removeCornerCondition, this, _1 ) );
1000
1001 return true;
1002}
1003
1004
1006{
1007 setEditedPoint( nullptr );
1008
1009 return 0;
1010}
1011
1012
1014{
1015 EDIT_POINT* point = m_editedPoint;
1016
1017 if( !m_editPoints )
1018 {
1019 point = nullptr;
1020 }
1021 else if( aEvent.IsMotion() )
1022 {
1023 point = m_editPoints->FindPoint( aEvent.Position(), getView() );
1024 }
1025 else if( aEvent.IsDrag( BUT_LEFT ) )
1026 {
1027 point = m_editPoints->FindPoint( aEvent.DragOrigin(), getView() );
1028 }
1029 else
1030 {
1031 point = m_editPoints->FindPoint( getViewControls()->GetCursorPosition( false ), getView() );
1032 }
1033
1034 if( m_editedPoint != point )
1035 setEditedPoint( point );
1036}
1037
1038
1040{
1041 if( !m_selectionTool )
1042 return 0;
1043
1044 if( m_inPointEditor )
1045 return 0;
1046
1048
1049 if( m_isSymbolEditor )
1050 {
1051 SYMBOL_EDIT_FRAME* editor = getEditFrame<SYMBOL_EDIT_FRAME>();
1052
1053 if( !editor->IsSymbolEditable() || editor->IsSymbolAlias() )
1054 return 0;
1055 }
1056
1057 const EE_SELECTION& selection = m_selectionTool->GetSelection();
1058
1059 if( selection.Size() != 1 || !selection.Front()->IsType( pointEditorTypes ) )
1060 {
1061 return 0;
1062 }
1063
1064 // Wait till drawing tool is done
1065 if( selection.Front()->IsNew() )
1066 return 0;
1067
1068 Activate();
1069
1072 VECTOR2I cursorPos;
1073 KIGFX::VIEW* view = getView();
1074 EDA_ITEM* item = selection.Front();
1075 SCH_COMMIT commit( m_toolMgr );
1076
1077 controls->ShowCursor( true );
1078
1079 makePointsAndBehavior( item );
1080 view->Add( m_editPoints.get() );
1081 setEditedPoint( nullptr );
1082 updateEditedPoint( aEvent );
1083 bool inDrag = false;
1084
1085 // Main loop: keep receiving events
1086 while( TOOL_EVENT* evt = Wait() )
1087 {
1088 if( grid )
1089 {
1090 grid->SetSnap( !evt->Modifier( MD_SHIFT ) );
1091 grid->SetUseGrid( getView()->GetGAL()->GetGridSnapping()
1092 && !evt->DisableGridSnapping() );
1093 }
1094 else
1095 {
1096 // This check is based on the assumption that the grid object must be valid.
1097 // If this assumption is wrong, please fix the code above.
1098 wxCHECK( false, 0 );
1099 }
1100
1101 if( !m_editPoints || evt->IsSelectionEvent() )
1102 break;
1103
1104 if ( !inDrag )
1105 updateEditedPoint( *evt );
1106
1107 if( evt->IsDrag( BUT_LEFT ) && m_editedPoint )
1108 {
1109 if( !inDrag )
1110 {
1111 commit.Modify( m_editPoints->GetParent(), m_frame->GetScreen() );
1112 inDrag = true;
1113 }
1114
1115 bool snap = !evt->DisableGridSnapping();
1116
1117 cursorPos = grid->Align( controls->GetMousePosition(),
1118 GRID_HELPER_GRIDS::GRID_GRAPHICS );
1119 controls->ForceCursorPosition( true, cursorPos );
1120
1121 m_editedPoint->SetPosition( controls->GetCursorPosition( snap ) );
1122
1123 updateParentItem( snap, commit );
1124 updatePoints();
1125 }
1126 else if( inDrag && evt->IsMouseUp( BUT_LEFT ) )
1127 {
1128 if( !commit.Empty() )
1129 commit.Push( _( "Move Point" ) );
1130
1131 controls->SetAutoPan( false );
1132 inDrag = false;
1133 }
1134 else if( evt->IsCancelInteractive() || evt->IsActivate() )
1135 {
1136 if( inDrag ) // Restore the last change
1137 {
1138 // Currently we are manually managing the lifetime of the grid
1139 // helpers because there is a bug in the tool stack that adds
1140 // the point editor again when commit.Revert() rebuilds the selection.
1141 // We remove this grid here so the its destructor is called before it
1142 // is added again.
1143 if( grid )
1144 {
1145 delete grid;
1146 grid = nullptr;
1147 }
1148
1149 commit.Revert();
1150 inDrag = false;
1151 break;
1152 }
1153 else if( evt->IsCancelInteractive() )
1154 {
1155 break;
1156 }
1157
1158 if( evt->IsActivate() )
1159 break;
1160 }
1161 else
1162 {
1163 evt->SetPassEvent();
1164 }
1165
1166 controls->SetAutoPan( inDrag );
1167 controls->CaptureCursor( inDrag );
1168 }
1169
1170 controls->SetAutoPan( false );
1171 controls->CaptureCursor( false );
1172 setEditedPoint( nullptr );
1173
1174 if( m_editPoints )
1175 {
1176 view->Remove( m_editPoints.get() );
1177
1178 m_editPoints.reset();
1180 }
1181
1182 delete grid;
1183
1184 return 0;
1185}
1186
1187
1188void EE_POINT_EDITOR::updateParentItem( bool aSnapToGrid, SCH_COMMIT& aCommit ) const
1189{
1190 EDA_ITEM* item = m_editPoints->GetParent();
1191
1192 if( !item )
1193 return;
1194
1195 if( !m_editBehavior )
1196 return;
1197
1198 std::vector<EDA_ITEM*> updatedItems;
1199 m_editBehavior->UpdateItem( *m_editedPoint, *m_editPoints, aCommit, updatedItems );
1200
1201 for( EDA_ITEM* updatedItem : updatedItems )
1202 updateItem( updatedItem, true );
1203
1204 m_frame->SetMsgPanel( item );
1205}
1206
1207
1209{
1210 if( !m_editPoints || !m_editBehavior )
1211 return;
1212
1213 m_editBehavior->UpdatePoints( *m_editPoints );
1214 getView()->Update( m_editPoints.get() );
1215}
1216
1217
1219{
1221
1222 if( aPoint )
1223 {
1224 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
1225 controls->ForceCursorPosition( true, aPoint->GetPosition() );
1226 controls->ShowCursor( true );
1227 }
1228 else
1229 {
1230 if( m_frame->ToolStackIsEmpty() )
1231 controls->ShowCursor( false );
1232
1233 controls->ForceCursorPosition( false );
1234 }
1235
1236 m_editedPoint = aPoint;
1237}
1238
1239
1241{
1242 bool isRuleArea = false;
1243
1244 if( m_editPoints )
1245 isRuleArea = m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T;
1246
1248 || !( m_editPoints->GetParent()->Type() == SCH_SHAPE_T || isRuleArea ) )
1249 {
1250 return false;
1251 }
1252
1253 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1254
1255 if( shape->GetPolyShape().IsEmpty() )
1256 return false;
1257
1258 SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
1259
1260 if( m_editPoints->GetParent()->Type() == SCH_SHAPE_T && poly.GetPointCount() <= 2 )
1261 return false;
1262 if( m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T && poly.GetPointCount() <= 3 )
1263 return false;
1264
1265 for( const VECTOR2I& pt : poly.CPoints() )
1266 {
1267 if( pt == m_editedPoint->GetPosition() )
1268 return true;
1269 }
1270
1271 return false;
1272}
1273
1274
1276{
1277 if( !m_editPoints
1278 || !( m_editPoints->GetParent()->Type() == SCH_SHAPE_T
1279 || m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T ) )
1280 {
1281 return false;
1282 }
1283
1284 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1285
1286 if( shape->GetShape() != SHAPE_T::POLY )
1287 return false;
1288
1289 VECTOR2I cursorPos = getViewControls()->GetCursorPosition( false );
1290 double threshold = getView()->ToWorld( EDIT_POINT::POINT_SIZE );
1291
1292 return shape->HitTest( cursorPos, (int) threshold );
1293}
1294
1295
1297{
1298 if( !m_editPoints
1299 || !( m_editPoints->GetParent()->Type() == SCH_SHAPE_T
1300 || m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T ) )
1301 return 0;
1302
1303 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1304 SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
1305 SCH_COMMIT commit( m_toolMgr );
1306
1307 commit.Modify( shape, m_frame->GetScreen() );
1308
1310 int currentMinDistance = INT_MAX;
1311 int closestLineStart = 0;
1312 unsigned numPoints = poly.GetPointCount();
1313
1314 if( !shape->IsClosed() )
1315 numPoints -= 1;
1316
1317 for( unsigned i = 0; i < numPoints; ++i )
1318 {
1319 SEG seg = poly.GetSegment( i );
1320 int distance = seg.Distance( cursor );
1321
1322 if( distance < currentMinDistance )
1323 {
1324 currentMinDistance = distance;
1325 closestLineStart = i;
1326 }
1327 }
1328
1329 poly.Insert( closestLineStart + 1, cursor );
1330
1331 updateItem( shape, true );
1332 updatePoints();
1333
1334 commit.Push( _( "Add Corner" ) );
1335 return 0;
1336}
1337
1338
1340{
1342 || !m_editPoints->GetParent()->IsType( { SCH_SHAPE_T, SCH_RULE_AREA_T } ) )
1343 {
1344 return 0;
1345 }
1346
1347 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1348 SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
1349 SCH_COMMIT commit( m_toolMgr );
1350
1351 if( m_editPoints->GetParent()->Type() == SCH_SHAPE_T && poly.GetPointCount() <= 2 )
1352 return 0;
1353 if( m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T && poly.GetPointCount() <= 3 )
1354 return 0;
1355
1356 commit.Modify( shape, m_frame->GetScreen() );
1357
1358 int idx = getEditedPointIndex();
1359 int last = (int) poly.GetPointCount() - 1;
1360
1361 if( idx == 0 && poly.GetPoint( 0 ) == poly.GetPoint( last ) )
1362 {
1363 poly.Remove( idx );
1364 poly.SetPoint( last-1, poly.GetPoint( 0 ) );
1365 }
1366 else
1367 {
1368 poly.Remove( idx );
1369 }
1370
1371 setEditedPoint( nullptr );
1372
1373 updateItem( shape, true );
1374 updatePoints();
1375
1376 commit.Push( _( "Remove Corner" ) );
1377 return 0;
1378}
1379
1380
1382{
1383 updatePoints();
1384 return 0;
1385}
1386
1387
1389{
1397}
1398
1399
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
static TOOL_ACTION activatePointEditor
Definition: actions.h:221
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:176
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:153
void SetEndY(int aY)
Definition: eda_shape.h:184
int GetEndX() const
Definition: eda_shape.h:176
int GetRectangleWidth() const
Definition: eda_shape.cpp:419
void SetStartY(int y)
Definition: eda_shape.h:147
SHAPE_POLY_SET & GetPolyShape()
Definition: eda_shape.h:291
SHAPE_T GetShape() const
Definition: eda_shape.h:132
int GetEndY() const
Definition: eda_shape.h:175
void SetEndX(int aX)
Definition: eda_shape.h:190
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:174
bool IsClosed() const
Definition: eda_shape.cpp:505
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition: eda_shape.h:137
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:178
wxString SHAPE_T_asString() const
Definition: eda_shape.cpp:340
int GetRectangleHeight() const
Definition: eda_shape.cpp:405
"Standard" table-cell editing behavior.
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:134
virtual void ClearRenderCache()
Definition: eda_text.cpp:649
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
static TOOL_ACTION pointEditorRemoveCorner
Definition: ee_actions.h:153
static TOOL_ACTION pointEditorAddCorner
Definition: ee_actions.h:152
void updatePoints()
Update which point is being edited.
bool m_inPointEditor
Currently available edit points.
void updateParentItem(bool aSnapToGrid, SCH_COMMIT &aCommit) const
< Update item's points with edit points.
int Main(const TOOL_EVENT &aEvent)
void makePointsAndBehavior(EDA_ITEM *aItem)
Currently edited point, NULL if there is none.
std::unique_ptr< POINT_EDIT_BEHAVIOR > m_editBehavior
void updateEditedPoint(const TOOL_EVENT &aEvent)
Clear references to the points.
void setEditedPoint(EDIT_POINT *aPoint)
Return true if aPoint is the currently modified point.
int modifiedSelection(const TOOL_EVENT &aEvent)
bool Init() override
Init() is called once upon a registration of the tool.
EDIT_POINT * m_editedPoint
Re-entrancy guards.
bool addCornerCondition(const SELECTION &aSelection)
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
int addCorner(const TOOL_EVENT &aEvent)
TOOL_ACTION handlers.
std::shared_ptr< EDIT_POINTS > m_editPoints
Current item-specific edit behavior.
bool removeCornerCondition(const SELECTION &aSelection)
int removeCorner(const TOOL_EVENT &aEvent)
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
int getEditedPointIndex() const
int clearEditedPoints(const TOOL_EVENT &aEvent)
Set the current point being edited. NULL means none.
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:238
EE_SELECTION & GetSelection()
A foundation class for a tool operating on a schematic or symbol.
Definition: ee_tool_base.h:48
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
Definition: ee_tool_base.h:84
void updateItem(EDA_ITEM *aItem, bool aUpdateRTree) const
Similar to getView()->Update(), but handles items that are redrawn by their parents and updating the ...
Definition: ee_tool_base.h:109
EE_SELECTION_TOOL * m_selectionTool
Definition: ee_tool_base.h:200
bool Init() override
Init() is called once upon a registration of the tool.
Definition: ee_tool_base.h:64
static const TOOL_EVENT ClearedEvent
Definition: actions.h:294
static const TOOL_EVENT SelectedEvent
Definition: actions.h:292
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:299
static const TOOL_EVENT PointSelectedEvent
Definition: actions.h:291
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:84
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:851
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.
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:432
virtual void Revert() override
Revert the commit by restoring the modified items state.
Definition: sch_commit.cpp:510
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:230
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:137
VECTOR2I GetEndPoint() const
Definition: sch_line.h:141
VECTOR2I GetStartPoint() const
Definition: sch_line.h:136
void SetEndPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:142
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:108
void SetPosition(const VECTOR2I &aPos) override
Definition: sch_shape.h:73
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:81
VECTOR2I GetCenter() const
Definition: sch_shape.h:75
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:79
VECTOR2I GetPosition() const override
Definition: sch_shape.h:72
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:57
void SetPositionIgnoringPins(const VECTOR2I &aPosition)
Definition: sch_sheet.cpp:893
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:547
VECTOR2I GetSize() const
Definition: sch_sheet.h:111
VECTOR2I GetPosition() const override
Definition: sch_sheet.h:399
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:581
void Resize(const VECTOR2I &aSize)
Resize this sheet to aSize and adjust all of the labels accordingly.
Definition: sch_sheet.cpp:1006
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
void SetRowHeight(int aRow, int aHeight)
Definition: sch_table.h:122
int GetRowHeight(int aRow) const
Definition: sch_table.h:124
void SetColWidth(int aCol, int aWidth)
Definition: sch_table.h:112
int GetColWidth(int aCol) const
Definition: sch_table.h:114
void Normalize()
Definition: sch_table.cpp:149
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.
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
@ FRAME_SCH_SYMBOL_EDITOR
Definition: frame_type.h:35
@ LAYER_NOTES
Definition: layer_ids.h:419
#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)
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