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 (C) 2019-2023 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 = []( LIB_SYMBOL& aSymbol, int aUnit, const SEG& aSeg,
695 bool aIncludeEnds ) -> std::vector<SCH_PIN*>
696 {
697 // const BOX2I segBox = BOX2I::ByCorners( aSeg.A, aSeg.B ).GetInflated( 1 );
698 // const EE_RTREE& rtree = m_frame->GetScreen()->Items().Overlapping( SCH_PIN_T, segBox );
699
700 std::vector<SCH_PIN*> pins;
701
702 for( SCH_PIN* pin : aSymbol.GetPins( aUnit ) )
703 {
704 // Figure out if the pin "connects" to the line
705 const VECTOR2I pinRootPos = pin->GetPinRoot();
706
707 if( aSeg.Contains( pinRootPos ) )
708 {
709 if( aIncludeEnds || ( pinRootPos != aSeg.A && pinRootPos != aSeg.B ) )
710 {
711 pins.push_back( pin );
712 }
713 }
714 }
715
716 return pins;
717 };
718
719 LIB_SYMBOL* const symbol = editor.GetCurSymbol();
720
721 for( std::size_t i = 0; i < aOldEdges.size(); ++i )
722 {
723 if( aMoveVecs[i] == VECTOR2I( 0, 0 ) || !symbol )
724 continue;
725
726 const std::vector<SCH_PIN*> pins =
727 getPinsOnSeg( *symbol, aEdgeUnit, aOldEdges[i], false );
728
729 for( SCH_PIN* pin : pins )
730 {
731 aCommit.Modify( pin );
732 aUpdatedItems.push_back( pin );
733
734 // Move the pin
735 pin->Move( aMoveVecs[i] );
736 }
737 }
738 }
739
742};
743
744
746{
747public:
749
750 void MakePoints( EDIT_POINTS& aPoints ) override
751 {
754 }
755
756 void UpdatePoints( EDIT_POINTS& aPoints ) override
757 {
758 // point editor works only with rectangles having width and height > 0
759 // Some symbols can have rectangles with width or height < 0
760 // So normalize the size:
763 }
764
765 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
766 std::vector<EDA_ITEM*>& aUpdatedItems ) override
767 {
770 }
771
772private:
774};
775
776
778{
779public:
781
782 void MakePoints( EDIT_POINTS& aPoints ) override
783 {
784 VECTOR2I topLeft = m_sheet.GetPosition();
785 VECTOR2I botRight = m_sheet.GetPosition() + m_sheet.GetSize();
786
787 aPoints.AddPoint( topLeft );
788 aPoints.AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
789 aPoints.AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
790 aPoints.AddPoint( botRight );
791
792 aPoints.AddLine( aPoints.Point( RECT_TOPLEFT ), aPoints.Point( RECT_TOPRIGHT ) );
793 aPoints.Line( RECT_TOP ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_TOP ) ) );
794 aPoints.AddLine( aPoints.Point( RECT_TOPRIGHT ), aPoints.Point( RECT_BOTRIGHT ) );
795 aPoints.Line( RECT_RIGHT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_RIGHT ) ) );
796 aPoints.AddLine( aPoints.Point( RECT_BOTRIGHT ), aPoints.Point( RECT_BOTLEFT ) );
797 aPoints.Line( RECT_BOT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_BOT ) ) );
798 aPoints.AddLine( aPoints.Point( RECT_BOTLEFT ), aPoints.Point( RECT_TOPLEFT ) );
799 aPoints.Line( RECT_LEFT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_LEFT ) ) );
800 }
801
802 void UpdatePoints( EDIT_POINTS& aPoints ) override
803 {
804 VECTOR2I topLeft = m_sheet.GetPosition();
805 VECTOR2I botRight = m_sheet.GetPosition() + m_sheet.GetSize();
806
807 aPoints.Point( RECT_TOPLEFT ).SetPosition( topLeft );
808 aPoints.Point( RECT_TOPRIGHT ).SetPosition( botRight.x, topLeft.y );
809 aPoints.Point( RECT_BOTLEFT ).SetPosition( topLeft.x, botRight.y );
810 aPoints.Point( RECT_BOTRIGHT ).SetPosition( botRight );
811 }
812
813 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
814 std::vector<EDA_ITEM*>& aUpdatedItems ) override
815 {
816 VECTOR2I topLeft = aPoints.Point( RECT_TOPLEFT ).GetPosition();
817 VECTOR2I topRight = aPoints.Point( RECT_TOPRIGHT ).GetPosition();
818 VECTOR2I botLeft = aPoints.Point( RECT_BOTLEFT ).GetPosition();
819 VECTOR2I botRight = aPoints.Point( RECT_BOTRIGHT ).GetPosition();
820 VECTOR2I sheetNewPos = m_sheet.GetPosition();
821 VECTOR2I sheetNewSize = m_sheet.GetSize();
822
823 bool editedTopRight = isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) );
824 bool editedBotLeft = isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) );
825 bool editedBotRight = isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) );
826
827 if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
828 editedTopRight = true;
829 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
830 editedBotLeft = true;
831
833 aEditedPoint, aPoints, m_sheet.GetMinWidth( editedTopRight || editedBotRight ),
834 m_sheet.GetMinHeight( editedBotLeft || editedBotRight ), topLeft, topRight, botLeft,
835 botRight );
836
837 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) )
838 || isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) )
839 || isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) )
840 || isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
841 {
842 sheetNewPos = topLeft;
843 sheetNewSize = VECTOR2I( botRight.x - topLeft.x, botRight.y - topLeft.y );
844 }
845 else if( isModified( aEditedPoint, aPoints.Line( RECT_TOP ) ) )
846 {
847 sheetNewPos = VECTOR2I( m_sheet.GetPosition().x, topLeft.y );
848 sheetNewSize = VECTOR2I( m_sheet.GetSize().x, botRight.y - topLeft.y );
849 }
850 else if( isModified( aEditedPoint, aPoints.Line( RECT_LEFT ) ) )
851 {
852 sheetNewPos = VECTOR2I( topLeft.x, m_sheet.GetPosition().y );
853 sheetNewSize = VECTOR2I( botRight.x - topLeft.x, m_sheet.GetSize().y );
854 }
855 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
856 {
857 sheetNewSize = VECTOR2I( m_sheet.GetSize().x, botRight.y - topLeft.y );
858 }
859 else if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
860 {
861 sheetNewSize = VECTOR2I( botRight.x - topLeft.x, m_sheet.GetSize().y );
862 }
863
864 for( unsigned i = 0; i < aPoints.LinesSize(); ++i )
865 {
866 if( !isModified( aEditedPoint, aPoints.Line( i ) ) )
867 {
868 aPoints.Line( i ).SetConstraint( new EC_PERPLINE( aPoints.Line( i ) ) );
869 }
870 }
871
872 if( m_sheet.GetPosition() != sheetNewPos )
873 m_sheet.SetPositionIgnoringPins( sheetNewPos );
874
875 if( m_sheet.GetSize() != sheetNewSize )
876 m_sheet.Resize( sheetNewSize );
877 }
878
879private:
881};
882
883
885{
886 m_editBehavior = nullptr;
887 m_editPoints = std::make_shared<EDIT_POINTS>( aItem );
888
889 if( !aItem )
890 return;
891
892 // Generate list of edit points based on the item type
893 switch( aItem->Type() )
894 {
895 case SCH_SHAPE_T:
896 {
897 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem );
898
899 switch( shape->GetShape() )
900 {
901 case SHAPE_T::ARC:
902 m_editBehavior = std::make_unique<ARC_POINT_EDIT_BEHAVIOR>( *shape );
903 break;
904 case SHAPE_T::CIRCLE:
905 m_editBehavior = std::make_unique<EDA_CIRCLE_POINT_EDIT_BEHAVIOR>( *shape );
906 break;
907 case SHAPE_T::RECTANGLE:
908 m_editBehavior = std::make_unique<RECTANGLE_POINT_EDIT_BEHAVIOR>( *shape, *m_frame );
909 break;
910 case SHAPE_T::POLY:
911 m_editBehavior = std::make_unique<EDA_POLYGON_POINT_EDIT_BEHAVIOR>( *shape );
912 break;
913 case SHAPE_T::BEZIER:
914 m_editBehavior = std::make_unique<EDA_BEZIER_POINT_EDIT_BEHAVIOR>( *shape );
915 break;
916 default:
918 }
919
920 break;
921 }
922 case SCH_RULE_AREA_T:
923 {
924 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem );
925 // Implemented directly as a polygon
926 m_editBehavior = std::make_unique<EDA_POLYGON_POINT_EDIT_BEHAVIOR>( *shape );
927 break;
928 }
929 case SCH_TEXTBOX_T:
930 {
931 SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( aItem );
932 m_editBehavior = std::make_unique<TEXTBOX_POINT_EDIT_BEHAVIOR>( *textbox );
933 break;
934 }
935 case SCH_TABLECELL_T:
936 {
937 SCH_TABLECELL* cell = static_cast<SCH_TABLECELL*>( aItem );
938 m_editBehavior = std::make_unique<SCH_TABLECELL_POINT_EDIT_BEHAVIOR>( *cell, *m_frame->GetScreen() );
939 break;
940 }
941 case SCH_SHEET_T:
942 {
943 SCH_SHEET& sheet = static_cast<SCH_SHEET&>( *aItem );
944 m_editBehavior = std::make_unique<SHEET_POINT_EDIT_BEHAVIOR>( sheet );
945 break;
946 }
947 case SCH_BITMAP_T:
948 {
949 SCH_BITMAP& bitmap = static_cast<SCH_BITMAP&>( *aItem );
950 m_editBehavior = std::make_unique<BITMAP_POINT_EDIT_BEHAVIOR>( bitmap );
951 break;
952 }
953 case SCH_LINE_T:
954 {
955 SCH_LINE& line = static_cast<SCH_LINE&>( *aItem );
956 m_editBehavior = std::make_unique<LINE_POINT_EDIT_BEHAVIOR>( line, *m_frame->GetScreen() );
957 break;
958 }
959 default:
960 {
961 m_editPoints.reset();
962 break;
963 }
964 }
965
966 // If we got a behavior, generate the points
967 if( m_editBehavior )
968 {
969 wxCHECK( m_editPoints, /* void */ );
970 m_editBehavior->MakePoints( *m_editPoints );
971 }
972}
973
974
976 EE_TOOL_BASE<SCH_BASE_FRAME>( "eeschema.PointEditor" ),
977 m_editedPoint( nullptr ),
978 m_inPointEditor( false )
979{
980}
981
982
984{
985 EE_TOOL_BASE::Reset( aReason );
986
987 m_editPoints.reset();
988 m_editedPoint = nullptr;
989}
990
991
993{
995
996 auto& menu = m_selectionTool->GetToolMenu().GetMenu();
998 std::bind( &EE_POINT_EDITOR::addCornerCondition, this, _1 ) );
1000 std::bind( &EE_POINT_EDITOR::removeCornerCondition, this, _1 ) );
1001
1002 return true;
1003}
1004
1005
1007{
1008 setEditedPoint( nullptr );
1009
1010 return 0;
1011}
1012
1013
1015{
1016 EDIT_POINT* point = m_editedPoint;
1017
1018 if( !m_editPoints )
1019 {
1020 point = nullptr;
1021 }
1022 else if( aEvent.IsMotion() )
1023 {
1024 point = m_editPoints->FindPoint( aEvent.Position(), getView() );
1025 }
1026 else if( aEvent.IsDrag( BUT_LEFT ) )
1027 {
1028 point = m_editPoints->FindPoint( aEvent.DragOrigin(), getView() );
1029 }
1030 else
1031 {
1032 point = m_editPoints->FindPoint( getViewControls()->GetCursorPosition( false ), getView() );
1033 }
1034
1035 if( m_editedPoint != point )
1036 setEditedPoint( point );
1037}
1038
1039
1041{
1042 if( !m_selectionTool )
1043 return 0;
1044
1045 if( m_inPointEditor )
1046 return 0;
1047
1049
1050 if( m_isSymbolEditor )
1051 {
1052 SYMBOL_EDIT_FRAME* editor = getEditFrame<SYMBOL_EDIT_FRAME>();
1053
1054 if( !editor->IsSymbolEditable() || editor->IsSymbolAlias() )
1055 return 0;
1056 }
1057
1058 const EE_SELECTION& selection = m_selectionTool->GetSelection();
1059
1060 if( selection.Size() != 1 || !selection.Front()->IsType( pointEditorTypes ) )
1061 {
1062 return 0;
1063 }
1064
1065 // Wait till drawing tool is done
1066 if( selection.Front()->IsNew() )
1067 return 0;
1068
1069 Activate();
1070
1073 VECTOR2I cursorPos;
1074 KIGFX::VIEW* view = getView();
1075 EDA_ITEM* item = selection.Front();
1076 SCH_COMMIT commit( m_toolMgr );
1077
1078 controls->ShowCursor( true );
1079
1080 makePointsAndBehavior( item );
1081 view->Add( m_editPoints.get() );
1082 setEditedPoint( nullptr );
1083 updateEditedPoint( aEvent );
1084 bool inDrag = false;
1085
1086 // Main loop: keep receiving events
1087 while( TOOL_EVENT* evt = Wait() )
1088 {
1089 if( grid )
1090 {
1091 grid->SetSnap( !evt->Modifier( MD_SHIFT ) );
1092 grid->SetUseGrid( getView()->GetGAL()->GetGridSnapping()
1093 && !evt->DisableGridSnapping() );
1094 }
1095 else
1096 {
1097 // This check is based on the assumption that the grid object must be valid.
1098 // If this assumption is wrong, please fix the code above.
1099 wxCHECK( false, 0 );
1100 }
1101
1102 if( !m_editPoints || evt->IsSelectionEvent() )
1103 break;
1104
1105 if ( !inDrag )
1106 updateEditedPoint( *evt );
1107
1108 if( evt->IsDrag( BUT_LEFT ) && m_editedPoint )
1109 {
1110 if( !inDrag )
1111 {
1112 commit.Modify( m_editPoints->GetParent(), m_frame->GetScreen() );
1113 inDrag = true;
1114 }
1115
1116 bool snap = !evt->DisableGridSnapping();
1117
1118 cursorPos = grid->Align( controls->GetMousePosition(),
1119 GRID_HELPER_GRIDS::GRID_GRAPHICS );
1120 controls->ForceCursorPosition( true, cursorPos );
1121
1122 m_editedPoint->SetPosition( controls->GetCursorPosition( snap ) );
1123
1124 updateParentItem( snap, commit );
1125 updatePoints();
1126 }
1127 else if( inDrag && evt->IsMouseUp( BUT_LEFT ) )
1128 {
1129 if( !commit.Empty() )
1130 commit.Push( _( "Move Point" ) );
1131
1132 controls->SetAutoPan( false );
1133 inDrag = false;
1134 }
1135 else if( evt->IsCancelInteractive() || evt->IsActivate() )
1136 {
1137 if( inDrag ) // Restore the last change
1138 {
1139 // Currently we are manually managing the lifetime of the grid
1140 // helpers because there is a bug in the tool stack that adds
1141 // the point editor again when commit.Revert() rebuilds the selection.
1142 // We remove this grid here so the its destructor is called before it
1143 // is added again.
1144 if( grid )
1145 {
1146 delete grid;
1147 grid = nullptr;
1148 }
1149
1150 commit.Revert();
1151 inDrag = false;
1152 break;
1153 }
1154 else if( evt->IsCancelInteractive() )
1155 {
1156 break;
1157 }
1158
1159 if( evt->IsActivate() )
1160 break;
1161 }
1162 else
1163 {
1164 evt->SetPassEvent();
1165 }
1166
1167 controls->SetAutoPan( inDrag );
1168 controls->CaptureCursor( inDrag );
1169 }
1170
1171 controls->SetAutoPan( false );
1172 controls->CaptureCursor( false );
1173 setEditedPoint( nullptr );
1174
1175 if( m_editPoints )
1176 {
1177 view->Remove( m_editPoints.get() );
1178
1179 m_editPoints.reset();
1181 }
1182
1183 delete grid;
1184
1185 return 0;
1186}
1187
1188
1189void EE_POINT_EDITOR::updateParentItem( bool aSnapToGrid, SCH_COMMIT& aCommit ) const
1190{
1191 EDA_ITEM* item = m_editPoints->GetParent();
1192
1193 if( !item )
1194 return;
1195
1196 if( !m_editBehavior )
1197 return;
1198
1199 std::vector<EDA_ITEM*> updatedItems;
1200 m_editBehavior->UpdateItem( *m_editedPoint, *m_editPoints, aCommit, updatedItems );
1201
1202 for( EDA_ITEM* updatedItem : updatedItems )
1203 updateItem( updatedItem, true );
1204
1205 m_frame->SetMsgPanel( item );
1206}
1207
1208
1210{
1211 if( !m_editPoints || !m_editBehavior )
1212 return;
1213
1214 m_editBehavior->UpdatePoints( *m_editPoints );
1215 getView()->Update( m_editPoints.get() );
1216}
1217
1218
1220{
1222
1223 if( aPoint )
1224 {
1225 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
1226 controls->ForceCursorPosition( true, aPoint->GetPosition() );
1227 controls->ShowCursor( true );
1228 }
1229 else
1230 {
1231 if( m_frame->ToolStackIsEmpty() )
1232 controls->ShowCursor( false );
1233
1234 controls->ForceCursorPosition( false );
1235 }
1236
1237 m_editedPoint = aPoint;
1238}
1239
1240
1242{
1243 bool isRuleArea = false;
1244
1245 if( m_editPoints )
1246 isRuleArea = m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T;
1247
1249 || !( m_editPoints->GetParent()->Type() == SCH_SHAPE_T || isRuleArea ) )
1250 {
1251 return false;
1252 }
1253
1254 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1255
1256 if( shape->GetPolyShape().IsEmpty() )
1257 return false;
1258
1259 SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
1260
1261 if( m_editPoints->GetParent()->Type() == SCH_SHAPE_T && poly.GetPointCount() <= 2 )
1262 return false;
1263 if( m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T && poly.GetPointCount() <= 3 )
1264 return false;
1265
1266 for( const VECTOR2I& pt : poly.CPoints() )
1267 {
1268 if( pt == m_editedPoint->GetPosition() )
1269 return true;
1270 }
1271
1272 return false;
1273}
1274
1275
1277{
1278 if( !m_editPoints
1279 || !( m_editPoints->GetParent()->Type() == SCH_SHAPE_T
1280 || m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T ) )
1281 {
1282 return false;
1283 }
1284
1285 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1286
1287 if( shape->GetShape() != SHAPE_T::POLY )
1288 return false;
1289
1290 VECTOR2I cursorPos = getViewControls()->GetCursorPosition( false );
1291 double threshold = getView()->ToWorld( EDIT_POINT::POINT_SIZE );
1292
1293 return shape->HitTest( cursorPos, (int) threshold );
1294}
1295
1296
1298{
1299 if( !m_editPoints
1300 || !( m_editPoints->GetParent()->Type() == SCH_SHAPE_T
1301 || m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T ) )
1302 return 0;
1303
1304 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1305 SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
1306 SCH_COMMIT commit( m_toolMgr );
1307
1308 commit.Modify( shape, m_frame->GetScreen() );
1309
1311 int currentMinDistance = INT_MAX;
1312 int closestLineStart = 0;
1313 unsigned numPoints = poly.GetPointCount();
1314
1315 if( !shape->IsClosed() )
1316 numPoints -= 1;
1317
1318 for( unsigned i = 0; i < numPoints; ++i )
1319 {
1320 SEG seg = poly.GetSegment( i );
1321 int distance = seg.Distance( cursor );
1322
1323 if( distance < currentMinDistance )
1324 {
1325 currentMinDistance = distance;
1326 closestLineStart = i;
1327 }
1328 }
1329
1330 poly.Insert( closestLineStart + 1, cursor );
1331
1332 updateItem( shape, true );
1333 updatePoints();
1334
1335 commit.Push( _( "Add Corner" ) );
1336 return 0;
1337}
1338
1339
1341{
1343 || !m_editPoints->GetParent()->IsType( { SCH_SHAPE_T, SCH_RULE_AREA_T } ) )
1344 {
1345 return 0;
1346 }
1347
1348 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1349 SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
1350 SCH_COMMIT commit( m_toolMgr );
1351
1352 if( m_editPoints->GetParent()->Type() == SCH_SHAPE_T && poly.GetPointCount() <= 2 )
1353 return 0;
1354 if( m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T && poly.GetPointCount() <= 3 )
1355 return 0;
1356
1357 commit.Modify( shape, m_frame->GetScreen() );
1358
1359 int idx = getEditedPointIndex();
1360 int last = (int) poly.GetPointCount() - 1;
1361
1362 if( idx == 0 && poly.GetPoint( 0 ) == poly.GetPoint( last ) )
1363 {
1364 poly.Remove( idx );
1365 poly.SetPoint( last-1, poly.GetPoint( 0 ) );
1366 }
1367 else
1368 {
1369 poly.Remove( idx );
1370 }
1371
1372 setEditedPoint( nullptr );
1373
1374 updateItem( shape, true );
1375 updatePoints();
1376
1377 commit.Push( _( "Remove Corner" ) );
1378 return 0;
1379}
1380
1381
1383{
1384 updatePoints();
1385 return 0;
1386}
1387
1388
1390{
1398}
1399
1400
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)
Create an undo entry for an item that has been already modified.
Definition: commit.h:105
bool Empty() const
Returns status of an item.
Definition: commit.h:144
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:417
void SetStartY(int y)
Definition: eda_shape.h:147
SHAPE_POLY_SET & GetPolyShape()
Definition: eda_shape.h:286
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:498
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:404
"Standard" table-cell editing behavior.
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:134
virtual void ClearRenderCache()
Definition: eda_text.cpp:631
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
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:68
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:299
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:334
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:1669
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:459
Define a library symbol object.
Definition: lib_symbol.h:78
std::vector< SCH_PIN * > GetPins(int aUnit=0, int aBodyStyle=0) const
Return a list of pin object pointers from the draw item list.
Definition: lib_symbol.cpp:822
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
Revert the commit by restoring the modified items state.
Definition: sch_commit.cpp:432
virtual void Revert() override
Definition: sch_commit.cpp:510
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:166
int GetUnit() const
Definition: sch_item.h:229
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:71
void Move(const VECTOR2I &aOffset) override
Move the item by aMoveVector to a new position.
Definition: sch_shape.cpp:69
void SetEditState(int aState)
Definition: sch_shape.h:79
VECTOR2I GetCenter() const
Definition: sch_shape.h:73
void Normalize()
Definition: sch_shape.cpp:75
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:114
void CalcEdit(const VECTOR2I &aPosition) override
Calculate the attributes of an item at aPosition when it is being edited.
Definition: sch_shape.h:77
VECTOR2I GetPosition() const override
Definition: sch_shape.h:70
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:548
VECTOR2I GetSize() const
Definition: sch_sheet.h:112
VECTOR2I GetPosition() const override
Definition: sch_sheet.h:400
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:582
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:42
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:218
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
Generic, UI-independent tool event.
Definition: tool_event.h:167
bool DisableGridSnapping() const
Definition: tool_event.h:363
const VECTOR2D Position() const
Returns the point where dragging has started.
Definition: tool_event.h:285
bool IsDrag(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:307
const VECTOR2D DragOrigin() const
Returns information about mouse buttons state.
Definition: tool_event.h:291
bool IsMotion() const
Definition: tool_event.h:322
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:371
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:96
constexpr int Mils2IU(const EDA_IU_SCALE &aIuScale, int mils)
Definition: eda_units.h:157
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:142
@ BUT_LEFT
Definition: tool_event.h:131
@ 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:691