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