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, see <https://www.gnu.org/licenses/>.
19 */
20
21#include "sch_point_editor.h"
22
23#include <algorithm>
24#include <ee_grid_helper.h>
25#include <tool/tool_manager.h>
26#include <sch_commit.h>
27#include <view/view_controls.h>
29#include <geometry/seg.h>
33#include <tools/sch_actions.h>
35#include <sch_edit_frame.h>
36#include <sch_line.h>
37#include <sch_bitmap.h>
38#include <sch_sheet.h>
39#include <sch_textbox.h>
40#include <sch_table.h>
41#include <sch_sheet_pin.h>
43#include <sch_no_connect.h>
44
45
53
54
55// Few constants to avoid using bare numbers for point indices
60
61
66
67
72
73
78
79
84
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
105 for( SCH_ITEM* test : m_screen.Items().OfType( SCH_LINE_T ) )
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 bool UpdatePoints( EDIT_POINTS& aPoints ) override
138 {
139 aPoints.Point( LINE_START ).SetPosition( m_line.GetStartPoint() );
140 aPoints.Point( LINE_END ).SetPosition( m_line.GetEndPoint() );
141 return true;
142 }
143
144 void UpdateItem( const EDIT_POINT& aEditedPoints, EDIT_POINTS& aPoints, COMMIT& aCommit,
145 std::vector<EDA_ITEM*>& aUpdatedItems ) override
146 {
147 m_line.SetStartPoint( aPoints.Point( LINE_START ).GetPosition() );
148 m_line.SetEndPoint( aPoints.Point( LINE_END ).GetPosition() );
149
150 std::pair<EDA_ITEM*, int> connected = aPoints.Point( LINE_START ).GetConnected();
151
152 if( connected.first )
153 {
154 aCommit.Modify( connected.first, &m_screen );
155 aUpdatedItems.push_back( connected.first );
156
157 if( connected.second == STARTPOINT )
158 static_cast<SCH_LINE*>( connected.first )->SetStartPoint( m_line.GetStartPoint() );
159 else if( connected.second == ENDPOINT )
160 static_cast<SCH_LINE*>( connected.first )->SetEndPoint( m_line.GetStartPoint() );
161 }
162
163 connected = aPoints.Point( LINE_END ).GetConnected();
164
165 if( connected.first )
166 {
167 aCommit.Modify( connected.first, &m_screen );
168 aUpdatedItems.push_back( connected.first );
169
170 if( connected.second == STARTPOINT )
171 static_cast<SCH_LINE*>( connected.first )->SetStartPoint( m_line.GetEndPoint() );
172 else if( connected.second == ENDPOINT )
173 static_cast<SCH_LINE*>( connected.first )->SetEndPoint( m_line.GetEndPoint() );
174 }
175 }
176
177private:
180};
181
183{
184public:
186 m_bitmap( aBitmap )
187 {}
188
189 void MakePoints( EDIT_POINTS& aPoints ) override
190 {
191 const REFERENCE_IMAGE& refImage = m_bitmap.GetReferenceImage();
192 const VECTOR2I topLeft = refImage.GetPosition() - refImage.GetSize() / 2;
193 const VECTOR2I botRight = refImage.GetPosition() + refImage.GetSize() / 2;
194
195 aPoints.AddPoint( topLeft );
196 aPoints.AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
197 aPoints.AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
198 aPoints.AddPoint( botRight );
199
200 aPoints.AddPoint( refImage.GetPosition() + refImage.GetTransformOriginOffset() );
201 }
202
203 bool UpdatePoints( EDIT_POINTS& aPoints ) override
204 {
205 const REFERENCE_IMAGE& refImage = m_bitmap.GetReferenceImage();
206 const VECTOR2I topLeft = refImage.GetPosition() - refImage.GetSize() / 2;
207 const VECTOR2I botRight = refImage.GetPosition() + refImage.GetSize() / 2;
208
209 aPoints.Point( RECT_TOPLEFT ).SetPosition( topLeft );
210 aPoints.Point( RECT_TOPRIGHT ).SetPosition( botRight.x, topLeft.y );
211 aPoints.Point( RECT_BOTLEFT ).SetPosition( topLeft.x, botRight.y );
212 aPoints.Point( RECT_BOTRIGHT ).SetPosition( botRight );
213
214 aPoints.Point( REFIMG_ORIGIN ).SetPosition( refImage.GetPosition() + refImage.GetTransformOriginOffset() );
215 return true;
216 }
217
218 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
219 std::vector<EDA_ITEM*>& aUpdatedItems ) override
220 {
221 REFERENCE_IMAGE& refImg = m_bitmap.GetReferenceImage();
222 const VECTOR2I topLeft = aPoints.Point( RECT_TOPLEFT ).GetPosition();
223 const VECTOR2I topRight = aPoints.Point( RECT_TOPRIGHT ).GetPosition();
224 const VECTOR2I botLeft = aPoints.Point( RECT_BOTLEFT ).GetPosition();
225 const VECTOR2I botRight = aPoints.Point( RECT_BOTRIGHT ).GetPosition();
226 const VECTOR2I xfrmOrigin = aPoints.Point( REFIMG_ORIGIN ).GetPosition();
227
228 if( isModified( aEditedPoint, aPoints.Point( REFIMG_ORIGIN ) ) )
229 {
230 // Moving the transform origin
231 // As the other points didn't move, we can get the image extent from them
232 const VECTOR2I newOffset = xfrmOrigin - ( topLeft + botRight ) / 2;
233 refImg.SetTransformOriginOffset( newOffset );
234 }
235 else
236 {
237 const VECTOR2I oldOrigin = refImg.GetPosition() + refImg.GetTransformOriginOffset();
238 const VECTOR2I oldSize = refImg.GetSize();
239 const VECTOR2I pos = refImg.GetPosition();
240
241 OPT_VECTOR2I newCorner;
242 VECTOR2I oldCorner = pos;
243
244 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) ) )
245 {
246 newCorner = topLeft;
247 oldCorner -= oldSize / 2;
248 }
249 else if( isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) ) )
250 {
251 newCorner = topRight;
252 oldCorner -= VECTOR2I( -oldSize.x, oldSize.y ) / 2;
253 }
254 else if( isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
255 {
256 newCorner = botLeft;
257 oldCorner -= VECTOR2I( oldSize.x, -oldSize.y ) / 2;
258 }
259 else if( isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) ) )
260 {
261 newCorner = botRight;
262 oldCorner += oldSize / 2;
263 }
264
265 if( newCorner )
266 {
267 // Turn in the respective vectors from the origin
268 *newCorner -= xfrmOrigin;
269 oldCorner -= oldOrigin;
270
271 // If we tried to cross the origin, clamp it to stop it
272 if( sign( newCorner->x ) != sign( oldCorner.x )
273 || sign( newCorner->y ) != sign( oldCorner.y ) )
274 {
275 *newCorner = VECTOR2I( 0, 0 );
276 }
277
278 const double newLength = newCorner->EuclideanNorm();
279 const double oldLength = oldCorner.EuclideanNorm();
280
281 double ratio = oldLength > 0 ? ( newLength / oldLength ) : 1.0;
282
283 // Clamp the scaling to a minimum of 50 mils
284 VECTOR2I newSize = oldSize * ratio;
285 double newWidth = std::max( newSize.x, EDA_UNIT_UTILS::Mils2IU( schIUScale, 50 ) );
286 double newHeight = std::max( newSize.y, EDA_UNIT_UTILS::Mils2IU( schIUScale, 50 ) );
287 ratio = std::min( newWidth / oldSize.x, newHeight / oldSize.y );
288
289 // Also handles the origin offset
290 refImg.SetImageScale( refImg.GetImageScale() * ratio );
291 }
292 }
293 aUpdatedItems.push_back( &m_bitmap );
294 }
295
296private:
298};
299
300
302{
303public:
306 m_cell( aCell ),
307 m_screen( aScreen )
308 {
309 }
310
311 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
312 std::vector<EDA_ITEM*>& aUpdatedItems ) override
313 {
314 SCH_TABLE& table = static_cast<SCH_TABLE&>( *m_cell.GetParent() );
315 bool rotated = !m_cell.GetTextAngle().IsHorizontal();
316
317 aCommit.Modify( &table, &m_screen );
318 aUpdatedItems.push_back( &table );
319
320 if( rotated )
321 {
322 if( isModified( aEditedPoint, aPoints.Point( ROW_HEIGHT ) ) )
323 {
324 m_cell.SetEnd( VECTOR2I( m_cell.GetEndX(), aPoints.Point( ROW_HEIGHT ).GetY() ) );
325
326 int colWidth = std::abs( m_cell.GetRectangleHeight() );
327
328 for( int ii = 0; ii < m_cell.GetColSpan() - 1; ++ii )
329 colWidth -= table.GetColWidth( m_cell.GetColumn() + ii );
330
331 table.SetColWidth( m_cell.GetColumn() + m_cell.GetColSpan() - 1, colWidth );
332 }
333 else if( isModified( aEditedPoint, aPoints.Point( COL_WIDTH ) ) )
334 {
335 m_cell.SetEnd( VECTOR2I( aPoints.Point( COL_WIDTH ).GetX(), m_cell.GetEndY() ) );
336
337 int rowHeight = m_cell.GetRectangleWidth();
338
339 for( int ii = 0; ii < m_cell.GetRowSpan() - 1; ++ii )
340 rowHeight -= table.GetRowHeight( m_cell.GetRow() + ii );
341
342 table.SetRowHeight( m_cell.GetRow() + m_cell.GetRowSpan() - 1, rowHeight );
343 }
344 }
345 else
346 {
347 if( isModified( aEditedPoint, aPoints.Point( COL_WIDTH ) ) )
348 {
349 m_cell.SetEnd( VECTOR2I( aPoints.Point( COL_WIDTH ).GetX(), m_cell.GetEndY() ) );
350
351 int colWidth = m_cell.GetRectangleWidth();
352
353 for( int ii = 0; ii < m_cell.GetColSpan() - 1; ++ii )
354 colWidth -= table.GetColWidth( m_cell.GetColumn() + ii );
355
356 table.SetColWidth( m_cell.GetColumn() + m_cell.GetColSpan() - 1, colWidth );
357 }
358 else if( isModified( aEditedPoint, aPoints.Point( ROW_HEIGHT ) ) )
359 {
360 m_cell.SetEnd( VECTOR2I( m_cell.GetEndX(), aPoints.Point( ROW_HEIGHT ).GetY() ) );
361
362 int rowHeight = m_cell.GetRectangleHeight();
363
364 for( int ii = 0; ii < m_cell.GetRowSpan() - 1; ++ii )
365 rowHeight -= table.GetRowHeight( m_cell.GetRow() + ii );
366
367 table.SetRowHeight( m_cell.GetRow() + m_cell.GetRowSpan() - 1, rowHeight );
368 }
369 }
370
371 table.Normalize();
372 }
373
374private:
377};
378
379
381{
382public:
384 m_rect( aRect ),
385 m_frame( aFrame )
386 {
387 }
388
389 static void MakePoints( SCH_SHAPE& aRect, EDIT_POINTS& aPoints )
390 {
391 VECTOR2I topLeft = aRect.GetPosition();
392 VECTOR2I botRight = aRect.GetEnd();
393
394 aPoints.AddPoint( topLeft );
395 aPoints.AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
396 aPoints.AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
397 aPoints.AddPoint( botRight );
398 aPoints.AddPoint( aRect.GetCenter() );
399 aPoints.AddPoint( VECTOR2I( botRight.x - aRect.GetCornerRadius(), topLeft.y ) );
400 aPoints.Point( RECT_RADIUS ).SetDrawCircle();
401
402 aPoints.AddLine( aPoints.Point( RECT_TOPLEFT ), aPoints.Point( RECT_TOPRIGHT ) );
403 aPoints.Line( RECT_TOP ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_TOP ) ) );
404 aPoints.AddLine( aPoints.Point( RECT_TOPRIGHT ), aPoints.Point( RECT_BOTRIGHT ) );
405 aPoints.Line( RECT_RIGHT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_RIGHT ) ) );
406 aPoints.AddLine( aPoints.Point( RECT_BOTRIGHT ), aPoints.Point( RECT_BOTLEFT ) );
407 aPoints.Line( RECT_BOT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_BOT ) ) );
408 aPoints.AddLine( aPoints.Point( RECT_BOTLEFT ), aPoints.Point( RECT_TOPLEFT ) );
409 aPoints.Line( RECT_LEFT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_LEFT ) ) );
410 }
411
412 static void UpdatePoints( SCH_SHAPE& aRect, EDIT_POINTS& aPoints )
413 {
414 VECTOR2I topLeft = aRect.GetPosition();
415 VECTOR2I botRight = aRect.GetEnd();
416
417 aPoints.Point( RECT_TOPLEFT ).SetPosition( topLeft );
418 aPoints.Point( RECT_RADIUS ).SetPosition( VECTOR2I( botRight.x - aRect.GetCornerRadius(), topLeft.y ) );
419 aPoints.Point( RECT_TOPRIGHT ).SetPosition( VECTOR2I( botRight.x, topLeft.y ) );
420 aPoints.Point( RECT_BOTLEFT ).SetPosition( VECTOR2I( topLeft.x, botRight.y ) );
421 aPoints.Point( RECT_BOTRIGHT ).SetPosition( botRight );
422 aPoints.Point( RECT_CENTER ).SetPosition( aRect.GetCenter() );
423 }
424
435 static void PinEditedCorner( const EDIT_POINT& aEditedPoint, const EDIT_POINTS& aPoints,
436 int minWidth, int minHeight, VECTOR2I& topLeft, VECTOR2I& topRight,
437 VECTOR2I& botLeft, VECTOR2I& botRight )
438 {
439 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) ) )
440 {
441 // pin edited point within opposite corner
442 topLeft.x = std::min( topLeft.x, botRight.x - minWidth );
443 topLeft.y = std::min( topLeft.y, botRight.y - minHeight );
444
445 // push edited point edges to adjacent corners
446 topRight.y = topLeft.y;
447 botLeft.x = topLeft.x;
448 }
449 else if( isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) ) )
450 {
451 // pin edited point within opposite corner
452 topRight.x = std::max( topRight.x, botLeft.x + minWidth );
453 topRight.y = std::min( topRight.y, botLeft.y - minHeight );
454
455 // push edited point edges to adjacent corners
456 topLeft.y = topRight.y;
457 botRight.x = topRight.x;
458 }
459 else if( isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
460 {
461 // pin edited point within opposite corner
462 botLeft.x = std::min( botLeft.x, topRight.x - minWidth );
463 botLeft.y = std::max( botLeft.y, topRight.y + minHeight );
464
465 // push edited point edges to adjacent corners
466 botRight.y = botLeft.y;
467 topLeft.x = botLeft.x;
468 }
469 else if( isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) ) )
470 {
471 // pin edited point within opposite corner
472 botRight.x = std::max( botRight.x, topLeft.x + minWidth );
473 botRight.y = std::max( botRight.y, topLeft.y + minHeight );
474
475 // push edited point edges to adjacent corners
476 botLeft.y = botRight.y;
477 topRight.x = botRight.x;
478 }
479 else if( isModified( aEditedPoint, aPoints.Line( RECT_TOP ) ) )
480 {
481 topLeft.y = std::min( topLeft.y, botRight.y - minHeight );
482 }
483 else if( isModified( aEditedPoint, aPoints.Line( RECT_LEFT ) ) )
484 {
485 topLeft.x = std::min( topLeft.x, botRight.x - minWidth );
486 }
487 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
488 {
489 botRight.y = std::max( botRight.y, topLeft.y + minHeight );
490 }
491 else if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
492 {
493 botRight.x = std::max( botRight.x, topLeft.x + minWidth );
494 }
495 }
496
497 static void UpdateItem( SCH_SHAPE& aRect, const EDIT_POINT& aEditedPoint,
498 EDIT_POINTS& aPoints, const VECTOR2I& aMinSize = { 0, 0 } )
499 {
500 VECTOR2I topLeft = aPoints.Point( RECT_TOPLEFT ).GetPosition();
501 VECTOR2I topRight = aPoints.Point( RECT_TOPRIGHT ).GetPosition();
502 VECTOR2I botLeft = aPoints.Point( RECT_BOTLEFT ).GetPosition();
503 VECTOR2I botRight = aPoints.Point( RECT_BOTRIGHT ).GetPosition();
504
505 int minWidth = std::max( schIUScale.MilsToIU( 1 ), aMinSize.x );
506 int minHeight = std::max( schIUScale.MilsToIU( 1 ), aMinSize.y );
507
508 PinEditedCorner( aEditedPoint, aPoints, minWidth, minHeight,
509 topLeft, topRight, botLeft, botRight );
510
511 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) )
512 || isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) )
513 || isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) )
514 || isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
515 {
516 aRect.SetPosition( topLeft );
517 aRect.SetEnd( botRight );
518 }
519 else if( isModified( aEditedPoint, aPoints.Line( RECT_TOP ) ) )
520 {
521 aRect.SetStartY( topLeft.y );
522 }
523 else if( isModified( aEditedPoint, aPoints.Line( RECT_LEFT ) ) )
524 {
525 aRect.SetStartX( topLeft.x );
526 }
527 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
528 {
529 aRect.SetEndY( botRight.y );
530 }
531 else if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
532 {
533 aRect.SetEndX( botRight.x );
534 }
535
536 for( unsigned i = 0; i < aPoints.LinesSize(); ++i )
537 {
538 if( !isModified( aEditedPoint, aPoints.Line( i ) ) )
539 {
540 aPoints.Line( i ).SetConstraint( new EC_PERPLINE( aPoints.Line( i ) ) );
541 }
542 }
543 }
544
545 void MakePoints( EDIT_POINTS& aPoints ) override
546 {
547 m_rect.Normalize();
548 MakePoints( m_rect, aPoints );
549 }
550
551 bool UpdatePoints( EDIT_POINTS& aPoints ) override
552 {
553 m_rect.Normalize();
554 UpdatePoints( m_rect, aPoints );
555 return true;
556 }
557
558 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
559 std::vector<EDA_ITEM*>& aUpdatedItems ) override
560 {
561 VECTOR2I topLeft = aPoints.Point( RECT_TOPLEFT ).GetPosition();
562 VECTOR2I topRight = aPoints.Point( RECT_TOPRIGHT ).GetPosition();
563 VECTOR2I botLeft = aPoints.Point( RECT_BOTLEFT ).GetPosition();
564 VECTOR2I botRight = aPoints.Point( RECT_BOTRIGHT ).GetPosition();
565
566 PinEditedCorner( aEditedPoint, aPoints, schIUScale.MilsToIU( 1 ), schIUScale.MilsToIU( 1 ),
567 topLeft, topRight, botLeft, botRight );
568
569 const BOX2I oldBox = BOX2I::ByCorners( m_rect.GetStart(), m_rect.GetEnd() );
570 std::vector<SEG> oldSegs;
571 std::vector<VECTOR2I> moveVecs;
572
573 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) )
574 || isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) )
575 || isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) )
576 || isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
577 {
578 // Corner drags don't update pins. Not only is it an escape hatch to avoid
579 // moving pins, it also avoids tricky problems when the pins "fall off"
580 // the ends of one of the two segments and get either left behind or
581 // "swept up" into the corner.
582 m_rect.SetPosition( topLeft );
583 m_rect.SetEnd( botRight );
584 }
585 else if( isModified( aEditedPoint, aPoints.Point( RECT_CENTER ) ) )
586 {
587 VECTOR2I moveVec = aPoints.Point( RECT_CENTER ).GetPosition() - oldBox.GetCenter();
588 m_rect.Move( moveVec );
589 }
590 else if( isModified( aEditedPoint, aPoints.Point( RECT_RADIUS ) ) )
591 {
592 int width = std::abs( botRight.x - topLeft.x );
593 int height = std::abs( botRight.y - topLeft.y );
594 int maxRadius = std::min( width, height ) / 2;
595 int x = aPoints.Point( RECT_RADIUS ).GetX();
596 x = std::clamp( x, botRight.x - maxRadius, botRight.x );
597 aPoints.Point( RECT_RADIUS ).SetPosition( VECTOR2I( x, topLeft.y ) );
598 m_rect.SetCornerRadius( botRight.x - x );
599 }
600 else if( isModified( aEditedPoint, aPoints.Line( RECT_TOP ) ) )
601 {
603 moveVecs.emplace_back( 0, topLeft.y - oldBox.GetTop() );
604 m_rect.SetStartY( topLeft.y );
605 }
606 else if( isModified( aEditedPoint, aPoints.Line( RECT_LEFT ) ) )
607 {
609 moveVecs.emplace_back( topLeft.x - oldBox.GetLeft(), 0 );
610 m_rect.SetStartX( topLeft.x );
611 }
612 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
613 {
615 moveVecs.emplace_back( 0, botRight.y - oldBox.GetBottom() );
616 m_rect.SetEndY( botRight.y );
617 }
618 else if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
619 {
621 moveVecs.emplace_back( botRight.x - oldBox.GetRight(), 0 );
622 m_rect.SetEndX( botRight.x );
623 }
624
625 dragPinsOnEdge( oldSegs, moveVecs, m_rect.GetUnit(), aCommit, aUpdatedItems );
626
627 for( unsigned i = 0; i < aPoints.LinesSize(); ++i )
628 {
629 if( !isModified( aEditedPoint, aPoints.Line( i ) ) )
630 {
631 aPoints.Line( i ).SetConstraint( new EC_PERPLINE( aPoints.Line( i ) ) );
632 }
633 }
634 }
635
636private:
637 void dragPinsOnEdge( const std::vector<SEG>& aOldEdges, const std::vector<VECTOR2I>& aMoveVecs,
638 int aEdgeUnit, COMMIT& aCommit, std::vector<EDA_ITEM*>& aUpdatedItems ) const
639 {
640 wxCHECK( aOldEdges.size() == aMoveVecs.size(), /* void */ );
641
642 // This only make sense in the symbol editor
643 if( !m_frame.IsType( FRAME_SCH_SYMBOL_EDITOR ) )
644 return;
645
647
648 // And only if the setting is enabled
649 if( !editor.GetSettings()->m_dragPinsAlongWithEdges )
650 return;
651
652 // Adjuting pins on a different unit to a unit-limited shape
653 // seems suspect.
654 wxCHECK( aEdgeUnit == 0 || aEdgeUnit == editor.GetUnit(), /* void */ );
655
656 /*
657 * Get a list of pins on a line segment
658 */
659 const auto getPinsOnSeg =
660 []( LIB_SYMBOL& aSymbol, int aUnit, const SEG& aSeg,
661 bool aIncludeEnds ) -> std::vector<SCH_PIN*>
662 {
663 std::vector<SCH_PIN*> pins;
664
665 for( SCH_PIN* pin : aSymbol.GetGraphicalPins( aUnit, 0 ) )
666 {
667 // Figure out if the pin "connects" to the line
668 const VECTOR2I pinRootPos = pin->GetPinRoot();
669
670 if( aSeg.Contains( pinRootPos ) )
671 {
672 if( aIncludeEnds || ( pinRootPos != aSeg.A && pinRootPos != aSeg.B ) )
673 {
674 pins.push_back( pin );
675 }
676 }
677 }
678
679 return pins;
680 };
681
682 LIB_SYMBOL* const symbol = editor.GetCurSymbol();
683
684 for( std::size_t i = 0; i < aOldEdges.size(); ++i )
685 {
686 if( aMoveVecs[i] == VECTOR2I( 0, 0 ) || !symbol )
687 continue;
688
689 const std::vector<SCH_PIN*> pins = getPinsOnSeg( *symbol, aEdgeUnit, aOldEdges[i], false );
690
691 for( SCH_PIN* pin : pins )
692 {
693 aCommit.Modify( pin, editor.GetScreen() );
694 aUpdatedItems.push_back( pin );
695
696 // Move the pin
697 pin->Move( aMoveVecs[i] );
698 }
699 }
700 }
701
702private:
705};
706
707
709{
710public:
712 m_textbox( aTextbox )
713 {}
714
715 void MakePoints( EDIT_POINTS& aPoints ) override
716 {
717 m_textbox.Normalize();
719 }
720
721 bool UpdatePoints( EDIT_POINTS& aPoints ) override
722 {
723 // point editor works only with rectangles having width and height > 0
724 // Some symbols can have rectangles with width or height < 0
725 // So normalize the size:
726 m_textbox.Normalize();
728 return true;
729 }
730
731 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
732 std::vector<EDA_ITEM*>& aUpdatedItems ) override
733 {
734 m_textbox.ClearBoundingBoxCache();
735 VECTOR2I minSize = m_textbox.GetMinSize();
736
738 m_textbox.ClearRenderCache();
739 }
740
741private:
743};
744
745
747{
748public:
750 m_sheet( aSheet ),
751 m_screen( aScreen )
752 {
753 m_noConnects = m_sheet.GetNoConnects();
754
755 // Find all wires connected to sheet pins and store their connections
756 for( SCH_SHEET_PIN* pin : m_sheet.GetPins() )
757 {
758 VECTOR2I pinPos = pin->GetPosition();
759
760 for( SCH_ITEM* item : m_screen.Items().Overlapping( SCH_LINE_T, pinPos ) )
761 {
762 SCH_LINE* line = static_cast<SCH_LINE*>( item );
763
764 if( !line->IsWire() && !line->IsBus() )
765 continue;
766
767 if( line->GetStartPoint() == pinPos )
768 m_connectedWires.push_back( { pin, line, STARTPOINT } );
769 else if( line->GetEndPoint() == pinPos )
770 m_connectedWires.push_back( { pin, line, ENDPOINT } );
771 }
772 }
773 }
774
775 void MakePoints( EDIT_POINTS& aPoints ) override
776 {
777 VECTOR2I topLeft = m_sheet.GetPosition();
778 VECTOR2I botRight = m_sheet.GetPosition() + m_sheet.GetSize();
779
780 aPoints.AddPoint( topLeft );
781 aPoints.AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
782 aPoints.AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
783 aPoints.AddPoint( botRight );
784
785 aPoints.AddLine( aPoints.Point( RECT_TOPLEFT ), aPoints.Point( RECT_TOPRIGHT ) );
786 aPoints.Line( RECT_TOP ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_TOP ) ) );
787 aPoints.AddLine( aPoints.Point( RECT_TOPRIGHT ), aPoints.Point( RECT_BOTRIGHT ) );
788 aPoints.Line( RECT_RIGHT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_RIGHT ) ) );
789 aPoints.AddLine( aPoints.Point( RECT_BOTRIGHT ), aPoints.Point( RECT_BOTLEFT ) );
790 aPoints.Line( RECT_BOT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_BOT ) ) );
791 aPoints.AddLine( aPoints.Point( RECT_BOTLEFT ), aPoints.Point( RECT_TOPLEFT ) );
792 aPoints.Line( RECT_LEFT ).SetConstraint( new EC_PERPLINE( aPoints.Line( RECT_LEFT ) ) );
793 }
794
795 bool UpdatePoints( EDIT_POINTS& aPoints ) override
796 {
797 VECTOR2I topLeft = m_sheet.GetPosition();
798 VECTOR2I botRight = m_sheet.GetPosition() + m_sheet.GetSize();
799
800 aPoints.Point( RECT_TOPLEFT ).SetPosition( topLeft );
801 aPoints.Point( RECT_TOPRIGHT ).SetPosition( botRight.x, topLeft.y );
802 aPoints.Point( RECT_BOTLEFT ).SetPosition( topLeft.x, botRight.y );
803 aPoints.Point( RECT_BOTRIGHT ).SetPosition( botRight );
804 return true;
805 }
806
807 void UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
808 std::vector<EDA_ITEM*>& aUpdatedItems ) override
809 {
810 VECTOR2I topLeft = aPoints.Point( RECT_TOPLEFT ).GetPosition();
811 VECTOR2I topRight = aPoints.Point( RECT_TOPRIGHT ).GetPosition();
812 VECTOR2I botLeft = aPoints.Point( RECT_BOTLEFT ).GetPosition();
813 VECTOR2I botRight = aPoints.Point( RECT_BOTRIGHT ).GetPosition();
814 VECTOR2I sheetNewPos = m_sheet.GetPosition();
815 VECTOR2I sheetNewSize = m_sheet.GetSize();
816
817 bool editedTopRight = isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) );
818 bool editedBotLeft = isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) );
819 bool editedBotRight = isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) );
820
821 if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
822 editedTopRight = true;
823 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
824 editedBotLeft = true;
825
827 aEditedPoint, aPoints, m_sheet.GetMinWidth( editedTopRight || editedBotRight ),
828 m_sheet.GetMinHeight( editedBotLeft || editedBotRight ), topLeft, topRight, botLeft,
829 botRight );
830
831 if( isModified( aEditedPoint, aPoints.Point( RECT_TOPLEFT ) )
832 || isModified( aEditedPoint, aPoints.Point( RECT_TOPRIGHT ) )
833 || isModified( aEditedPoint, aPoints.Point( RECT_BOTRIGHT ) )
834 || isModified( aEditedPoint, aPoints.Point( RECT_BOTLEFT ) ) )
835 {
836 sheetNewPos = topLeft;
837 sheetNewSize = VECTOR2I( botRight.x - topLeft.x, botRight.y - topLeft.y );
838 }
839 else if( isModified( aEditedPoint, aPoints.Line( RECT_TOP ) ) )
840 {
841 sheetNewPos = VECTOR2I( m_sheet.GetPosition().x, topLeft.y );
842 sheetNewSize = VECTOR2I( m_sheet.GetSize().x, botRight.y - topLeft.y );
843 }
844 else if( isModified( aEditedPoint, aPoints.Line( RECT_LEFT ) ) )
845 {
846 sheetNewPos = VECTOR2I( topLeft.x, m_sheet.GetPosition().y );
847 sheetNewSize = VECTOR2I( botRight.x - topLeft.x, m_sheet.GetSize().y );
848 }
849 else if( isModified( aEditedPoint, aPoints.Line( RECT_BOT ) ) )
850 {
851 sheetNewSize = VECTOR2I( m_sheet.GetSize().x, botRight.y - topLeft.y );
852 }
853 else if( isModified( aEditedPoint, aPoints.Line( RECT_RIGHT ) ) )
854 {
855 sheetNewSize = VECTOR2I( botRight.x - topLeft.x, m_sheet.GetSize().y );
856 }
857
858 for( unsigned i = 0; i < aPoints.LinesSize(); ++i )
859 {
860 if( !isModified( aEditedPoint, aPoints.Line( i ) ) )
861 {
862 aPoints.Line( i ).SetConstraint( new EC_PERPLINE( aPoints.Line( i ) ) );
863 }
864 }
865
866 if( m_sheet.GetPosition() != sheetNewPos )
867 m_sheet.SetPositionIgnoringPins( sheetNewPos );
868
869 if( m_sheet.GetSize() != sheetNewSize )
870 m_sheet.Resize( sheetNewSize );
871
872 // Update no-connects to follow their sheet pins
873 for( auto& [sheetPin, noConnect] : m_noConnects )
874 {
875 if( noConnect->GetPosition() != sheetPin->GetTextPos() )
876 {
877 aCommit.Modify( noConnect, &m_screen );
878 noConnect->SetPosition( sheetPin->GetTextPos() );
879 aUpdatedItems.push_back( noConnect );
880 }
881 }
882
883 // Update connected wires to follow their sheet pins
884 for( auto& [pin, line, endpoint] : m_connectedWires )
885 {
886 VECTOR2I newPinPos = pin->GetPosition();
887 bool needsUpdate = false;
888
889 if( endpoint == STARTPOINT && line->GetStartPoint() != newPinPos )
890 needsUpdate = true;
891 else if( endpoint == ENDPOINT && line->GetEndPoint() != newPinPos )
892 needsUpdate = true;
893
894 if( needsUpdate )
895 {
896 aCommit.Modify( line, &m_screen );
897
898 if( endpoint == STARTPOINT )
899 line->SetStartPoint( newPinPos );
900 else
901 line->SetEndPoint( newPinPos );
902
903 aUpdatedItems.push_back( line );
904 }
905 }
906 }
907
908private:
911 std::map<SCH_SHEET_PIN*, SCH_NO_CONNECT*> m_noConnects;
912 std::vector<std::tuple<SCH_SHEET_PIN*, SCH_LINE*, int>> m_connectedWires;
913};
914
915
917{
918 m_editBehavior = nullptr;
919 m_editPoints = std::make_shared<EDIT_POINTS>( aItem );
920
921 if( !aItem )
922 return;
923
924 // Generate list of edit points based on the item type
925 switch( aItem->Type() )
926 {
927 case SCH_SHAPE_T:
928 {
929 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem );
930
931 switch( shape->GetShape() )
932 {
933 case SHAPE_T::ARC:
934 // EDA_ARC_POINT_EDIT_BEHAVIOR holds a reference to m_arcEditMode, so the
935 // persisted value must be synced from settings before the behavior is built.
936 if( m_isSymbolEditor )
937 {
938 if( SYMBOL_EDITOR_SETTINGS* cfg = m_frame->libeditconfig() )
939 m_arcEditMode = cfg->m_ArcEditMode;
940 }
941 else if( EESCHEMA_SETTINGS* cfg = m_frame->eeconfig() )
942 {
943 m_arcEditMode = cfg->m_Drawing.arc_edit_mode;
944 }
945
946 m_editBehavior = std::make_unique<EDA_ARC_POINT_EDIT_BEHAVIOR>(
948 break;
949 case SHAPE_T::CIRCLE:
950 m_editBehavior = std::make_unique<EDA_CIRCLE_POINT_EDIT_BEHAVIOR>( *shape );
951 break;
953 m_editBehavior = std::make_unique<RECTANGLE_POINT_EDIT_BEHAVIOR>( *shape, *m_frame );
954 break;
955 case SHAPE_T::POLY:
956 m_editBehavior = std::make_unique<EDA_POLYGON_POINT_EDIT_BEHAVIOR>( *shape );
957 break;
958 case SHAPE_T::BEZIER:
959 {
960 int maxError = schIUScale.mmToIU( ARC_LOW_DEF_MM );
961
962 if( SCHEMATIC* schematic = shape->Schematic() )
963 maxError = schematic->Settings().m_MaxError;
964
965 m_editBehavior = std::make_unique<EDA_BEZIER_POINT_EDIT_BEHAVIOR>( *shape, maxError );
966 break;
967 }
968 case SHAPE_T::ELLIPSE:
969 case SHAPE_T::ELLIPSE_ARC: m_editBehavior = std::make_unique<EDA_ELLIPSE_POINT_EDIT_BEHAVIOR>( *shape ); break;
970 default:
972 }
973
974 break;
975 }
976 case SCH_RULE_AREA_T:
977 {
978 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem );
979 // Implemented directly as a polygon
980 m_editBehavior = std::make_unique<EDA_POLYGON_POINT_EDIT_BEHAVIOR>( *shape );
981 break;
982 }
983 case SCH_TEXTBOX_T:
984 {
985 SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( aItem );
986 m_editBehavior = std::make_unique<TEXTBOX_POINT_EDIT_BEHAVIOR>( *textbox );
987 break;
988 }
989 case SCH_TABLECELL_T:
990 {
991 SCH_TABLECELL* cell = static_cast<SCH_TABLECELL*>( aItem );
992 m_editBehavior = std::make_unique<SCH_TABLECELL_POINT_EDIT_BEHAVIOR>( *cell, *m_frame->GetScreen() );
993 break;
994 }
995 case SCH_SHEET_T:
996 {
997 SCH_SHEET& sheet = static_cast<SCH_SHEET&>( *aItem );
998 m_editBehavior = std::make_unique<SHEET_POINT_EDIT_BEHAVIOR>( sheet, *m_frame->GetScreen() );
999 break;
1000 }
1001 case SCH_BITMAP_T:
1002 {
1003 SCH_BITMAP& bitmap = static_cast<SCH_BITMAP&>( *aItem );
1004 m_editBehavior = std::make_unique<BITMAP_POINT_EDIT_BEHAVIOR>( bitmap );
1005 break;
1006 }
1007 case SCH_LINE_T:
1008 {
1009 SCH_LINE& line = static_cast<SCH_LINE&>( *aItem );
1010 m_editBehavior = std::make_unique<LINE_POINT_EDIT_BEHAVIOR>( line, *m_frame->GetScreen() );
1011 break;
1012 }
1013 default:
1014 {
1015 m_editPoints.reset();
1016 break;
1017 }
1018 }
1019
1020 // If we got a behavior, generate the points
1021 if( m_editBehavior )
1022 {
1023 wxCHECK( m_editPoints, /* void */ );
1024 m_editBehavior->MakePoints( *m_editPoints );
1025 }
1026}
1027
1028
1036
1037
1039{
1040 SCH_TOOL_BASE::Reset( aReason );
1041
1042 if( KIGFX::VIEW* view = getView() )
1043 {
1044 if( m_angleItem )
1045 view->Remove( m_angleItem.get() );
1046
1047 if( m_editPoints )
1048 view->Remove( m_editPoints.get() );
1049 }
1050
1051 m_angleItem.reset();
1052 m_editPoints.reset();
1053 m_editedPoint = nullptr;
1054}
1055
1056
1058{
1059 using S_C = SELECTION_CONDITIONS;
1060
1062
1063 const auto addCornerCondition = [&]( const SELECTION& aSelection ) -> bool
1064 {
1065 return SCH_POINT_EDITOR::addCornerCondition( aSelection );
1066 };
1067
1068 const auto removeCornerCondition = [&]( const SELECTION& aSelection ) -> bool
1069 {
1070 return SCH_POINT_EDITOR::removeCornerCondition( aSelection );
1071 };
1072
1073 const auto arcIsEdited = [&]( const SELECTION& aSelection ) -> bool
1074 {
1075 const EDA_ITEM* item = aSelection.Front();
1076 return ( item != nullptr ) && ( item->Type() == SCH_SHAPE_T )
1077 && static_cast<const SCH_SHAPE*>( item )->GetShape() == SHAPE_T::ARC;
1078 };
1079
1080 auto& menu = m_selectionTool->GetToolMenu().GetMenu();
1081
1082 // clang-format off
1085 menu.AddItem( ACTIONS::cycleArcEditMode, S_C::Count( 1 ) && arcIsEdited );
1086 // clang-format on
1087
1088 return true;
1089}
1090
1091
1093{
1094 setEditedPoint( nullptr );
1095
1096 return 0;
1097}
1098
1099
1101{
1102 EDIT_POINT* point = m_editedPoint;
1103
1104 if( !m_editPoints )
1105 {
1106 point = nullptr;
1107 }
1108 else if( aEvent.IsMotion() )
1109 {
1110 point = m_editPoints->FindPoint( aEvent.Position(), getView() );
1111 }
1112 else if( aEvent.IsDrag( BUT_LEFT ) )
1113 {
1114 point = m_editPoints->FindPoint( aEvent.DragOrigin(), getView() );
1115 }
1116 else
1117 {
1118 point = m_editPoints->FindPoint( getViewControls()->GetCursorPosition( false ), getView() );
1119 }
1120
1121 if( m_editedPoint != point )
1122 setEditedPoint( point );
1123}
1124
1125
1127{
1128 if( !m_selectionTool )
1129 return 0;
1130
1131 if( m_inPointEditor )
1132 return 0;
1133
1135
1136 if( m_isSymbolEditor )
1137 {
1139
1140 if( !editor->IsSymbolEditable() || editor->IsSymbolAlias() )
1141 return 0;
1142 }
1143
1144 const SCH_SELECTION& selection = m_selectionTool->GetSelection();
1145
1146 if( selection.Size() != 1 || !selection.Front()->IsType( pointEditorTypes ) )
1147 return 0;
1148
1149 // Wait till drawing tool is done
1150 if( selection.Front()->IsNew() )
1151 return 0;
1152
1153 Activate();
1154
1157 VECTOR2I cursorPos;
1158 KIGFX::VIEW* view = getView();
1159 EDA_ITEM* item = selection.Front();
1160 SCH_COMMIT commit( m_toolMgr );
1161
1162 controls->ShowCursor( true );
1163
1164 makePointsAndBehavior( item );
1165 m_angleItem = std::make_unique<KIGFX::PREVIEW::ANGLE_ITEM>( m_editPoints );
1166 view->Add( m_editPoints.get() );
1167 view->Add( m_angleItem.get() );
1168 setEditedPoint( nullptr );
1169 updateEditedPoint( aEvent );
1170 bool inDrag = false;
1171
1172 // Main loop: keep receiving events
1173 while( TOOL_EVENT* evt = Wait() )
1174 {
1175 if( grid )
1176 {
1177 grid->SetSnap( !evt->Modifier( MD_SHIFT ) );
1178 grid->SetUseGrid( getView()->GetGAL()->GetGridSnapping()
1179 && !evt->DisableGridSnapping() );
1180 }
1181 else
1182 {
1183 // This check is based on the assumption that the grid object must be valid.
1184 // If this assumption is wrong, please fix the code above.
1185 wxCHECK( false, 0 );
1186 }
1187
1188 if( !m_editPoints || evt->IsSelectionEvent() )
1189 break;
1190
1191 if ( !inDrag )
1192 updateEditedPoint( *evt );
1193
1194 if( evt->IsDrag( BUT_LEFT ) && m_editedPoint )
1195 {
1196 if( !inDrag )
1197 {
1198 commit.Modify( m_editPoints->GetParent(), m_frame->GetScreen() );
1199
1200 if( SCH_SHAPE* shape = dynamic_cast<SCH_SHAPE*>( item ) )
1201 {
1202 shape->SetFlags( IS_MOVING );
1203 shape->SetHatchingDirty();
1204 shape->UpdateHatching();
1205 }
1206
1207 inDrag = true;
1208 }
1209
1210 bool snap = !evt->DisableGridSnapping();
1211
1212 cursorPos = grid->Align( controls->GetMousePosition(),
1214 controls->ForceCursorPosition( true, cursorPos );
1215
1216 m_editedPoint->SetPosition( controls->GetCursorPosition( snap ) );
1217
1218 updateParentItem( snap, commit );
1219 updatePoints();
1220 }
1221 else if( inDrag && evt->IsMouseUp( BUT_LEFT ) )
1222 {
1223 if( !commit.Empty() )
1224 commit.Push( _( "Move Point" ) );
1225
1226 controls->SetAutoPan( false );
1227
1228 if( SCH_SHAPE* shape = dynamic_cast<SCH_SHAPE*>( item ) )
1229 {
1230 shape->ClearFlags( IS_MOVING );
1231 shape->SetHatchingDirty();
1232 shape->UpdateHatching();
1233 }
1234
1235 inDrag = false;
1236 }
1237 else if( evt->IsCancelInteractive() || evt->IsActivate() )
1238 {
1239 if( inDrag ) // Restore the last change
1240 {
1241 // Currently we are manually managing the lifetime of the grid
1242 // helpers because there is a bug in the tool stack that adds
1243 // the point editor again when commit.Revert() rebuilds the selection.
1244 // We remove this grid here so the its destructor is called before it
1245 // is added again.
1246 if( grid )
1247 {
1248 delete grid;
1249 grid = nullptr;
1250 }
1251
1252 commit.Revert();
1253 inDrag = false;
1254 break;
1255 }
1256 else if( evt->IsCancelInteractive() )
1257 {
1258 break;
1259 }
1260
1261 if( evt->IsActivate() )
1262 break;
1263 }
1264 else
1265 {
1266 evt->SetPassEvent();
1267 }
1268
1269 controls->SetAutoPan( inDrag );
1270 controls->CaptureCursor( inDrag );
1271 }
1272
1273 if( SCH_SHAPE* shape = dynamic_cast<SCH_SHAPE*>( item ) )
1274 {
1275 shape->ClearFlags( IS_MOVING );
1276 shape->SetHatchingDirty();
1277 shape->UpdateHatching();
1278 }
1279
1280 controls->SetAutoPan( false );
1281 controls->CaptureCursor( false );
1282 setEditedPoint( nullptr );
1283
1284 if( m_editPoints )
1285 {
1286 view->Remove( m_editPoints.get() );
1287 view->Remove( m_angleItem.get() );
1288
1289 m_editPoints.reset();
1290 m_angleItem.reset();
1291 m_frame->GetCanvas()->Refresh();
1292 }
1293
1294 delete grid;
1295
1296 return 0;
1297}
1298
1299
1300void SCH_POINT_EDITOR::updateParentItem( bool aSnapToGrid, SCH_COMMIT& aCommit ) const
1301{
1302 EDA_ITEM* item = m_editPoints->GetParent();
1303
1304 if( !item )
1305 return;
1306
1307 if( !m_editBehavior )
1308 return;
1309
1310 std::vector<EDA_ITEM*> updatedItems;
1311 m_editBehavior->UpdateItem( *m_editedPoint, *m_editPoints, aCommit, updatedItems );
1312
1313 for( EDA_ITEM* updatedItem : updatedItems )
1314 updateItem( updatedItem, true );
1315
1316 m_frame->SetMsgPanel( item );
1317}
1318
1319
1321{
1322 if( !m_editPoints || !m_editBehavior )
1323 return;
1324
1325 // Careful; the unit and/or body style may have changed out from under us, meaning the item is no
1326 // longer present on the canvas.
1327 if( m_isSymbolEditor )
1328 {
1330 SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( m_editPoints->GetParent() );
1331
1332 if( ( item && item->GetUnit() != 0 && item->GetUnit() != editor->GetUnit() )
1333 || ( item && item->GetBodyStyle() != 0 && item->GetBodyStyle() != editor->GetBodyStyle() ) )
1334 {
1335 getView()->Remove( m_editPoints.get() );
1336 getView()->Remove( m_angleItem.get() );
1337 m_editPoints.reset();
1338 m_angleItem.reset();
1339 return;
1340 }
1341 }
1342
1343 m_editBehavior->UpdatePoints( *m_editPoints );
1344 getView()->Update( m_editPoints.get() );
1345 getView()->Update( m_angleItem.get() );
1346}
1347
1348
1350{
1352
1353 if( aPoint )
1354 {
1355 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
1356 controls->ForceCursorPosition( true, aPoint->GetPosition() );
1357 controls->ShowCursor( true );
1358 }
1359 else
1360 {
1361 if( m_frame->ToolStackIsEmpty() )
1362 controls->ShowCursor( false );
1363
1364 controls->ForceCursorPosition( false );
1365 }
1366
1367 m_editedPoint = aPoint;
1368}
1369
1370
1372{
1373 if( !m_editPoints || !m_editedPoint || !m_editPoints->GetParent()->IsType( { SCH_SHAPE_T, SCH_RULE_AREA_T } ) )
1374 return false;
1375
1376 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1377
1378 if( shape->GetPolyShape().IsEmpty() )
1379 return false;
1380
1381 SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
1382
1383 if( m_editPoints->GetParent()->Type() == SCH_SHAPE_T && poly.GetPointCount() <= 2 )
1384 return false;
1385 if( m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T && poly.GetPointCount() <= 3 )
1386 return false;
1387
1388 for( const VECTOR2I& pt : poly.CPoints() )
1389 {
1390 if( pt == m_editedPoint->GetPosition() )
1391 return true;
1392 }
1393
1394 return false;
1395}
1396
1397
1399{
1400 if( !m_editPoints || !m_editPoints->GetParent()->IsType( { SCH_SHAPE_T, SCH_RULE_AREA_T } ) )
1401 return false;
1402
1403 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1404
1405 if( shape->GetShape() != SHAPE_T::POLY )
1406 return false;
1407
1408 VECTOR2I cursorPos = getViewControls()->GetCursorPosition( false );
1409 double threshold = getView()->ToWorld( EDIT_POINT::POINT_SIZE );
1410
1411 return shape->HitTest( cursorPos, (int) threshold );
1412}
1413
1414
1416{
1417 if( !m_editPoints || !m_editPoints->GetParent()->IsType( { SCH_SHAPE_T, SCH_RULE_AREA_T } ) )
1418 return 0;
1419
1420 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1421 SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
1422 SCH_COMMIT commit( m_toolMgr );
1423
1424 commit.Modify( shape, m_frame->GetScreen() );
1425
1427 int currentMinDistance = INT_MAX;
1428 int closestLineStart = 0;
1429 unsigned numPoints = poly.GetPointCount();
1430
1431 if( !shape->IsClosed() )
1432 numPoints -= 1;
1433
1434 for( unsigned i = 0; i < numPoints; ++i )
1435 {
1436 SEG seg = poly.GetSegment( i );
1437 int distance = seg.Distance( cursor );
1438
1439 if( distance < currentMinDistance )
1440 {
1441 currentMinDistance = distance;
1442 closestLineStart = i;
1443 }
1444 }
1445
1446 poly.Insert( closestLineStart + 1, cursor );
1447
1448 updateItem( shape, true );
1449 updatePoints();
1450
1451 commit.Push( _( "Add Corner" ) );
1452 return 0;
1453}
1454
1455
1457{
1458 if( !m_editPoints || !m_editedPoint || !m_editPoints->GetParent()->IsType( { SCH_SHAPE_T, SCH_RULE_AREA_T } ) )
1459 return 0;
1460
1461 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
1462 SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
1463 SCH_COMMIT commit( m_toolMgr );
1464
1465 if( m_editPoints->GetParent()->Type() == SCH_SHAPE_T && poly.GetPointCount() <= 2 )
1466 return 0;
1467 if( m_editPoints->GetParent()->Type() == SCH_RULE_AREA_T && poly.GetPointCount() <= 3 )
1468 return 0;
1469
1470 commit.Modify( shape, m_frame->GetScreen() );
1471
1472 int idx = getEditedPointIndex();
1473 int last = (int) poly.GetPointCount() - 1;
1474
1475 if( idx == 0 && poly.GetPoint( 0 ) == poly.GetPoint( last ) )
1476 {
1477 poly.Remove( idx );
1478 poly.SetPoint( last-1, poly.GetPoint( 0 ) );
1479 }
1480 else
1481 {
1482 poly.Remove( idx );
1483 }
1484
1485 shape->SetHatchingDirty();
1486
1487 setEditedPoint( nullptr );
1488
1489 updateItem( shape, true );
1490 updatePoints();
1491
1492 commit.Push( _( "Remove Corner" ) );
1493 return 0;
1494}
1495
1496
1498{
1499 // The Symbol Editor uses SYMBOL_EDITOR_SETTINGS, not EESCHEMA_SETTINGS, so eeconfig()
1500 // returns nullptr there. Dispatch on frame type to read/write the right settings store.
1501 EESCHEMA_SETTINGS* schCfg = m_isSymbolEditor ? nullptr : m_frame->eeconfig();
1502 SYMBOL_EDITOR_SETTINGS* symCfg = m_isSymbolEditor ? m_frame->libeditconfig() : nullptr;
1503
1504 if( aEvent.Matches( ACTIONS::cycleArcEditMode.MakeEvent() ) )
1505 {
1506 if( schCfg )
1508 else if( symCfg )
1509 m_arcEditMode = symCfg->m_ArcEditMode;
1510
1512 }
1513 else
1514 {
1516 }
1517
1518 if( schCfg )
1520 else if( symCfg )
1521 symCfg->m_ArcEditMode = m_arcEditMode;
1522
1523 return 0;
1524}
1525
1526
1528{
1529 updatePoints();
1530 return 0;
1531}
1532
1533
ARC_EDIT_MODE
Settings for arc editing.
@ KEEP_CENTER_ADJUST_ANGLE_RADIUS
When editing endpoints, the angle and radius are adjusted.
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:123
constexpr double ARC_LOW_DEF_MM
Definition base_units.h:127
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
static TOOL_ACTION cycleArcEditMode
Definition actions.h:268
static TOOL_ACTION pointEditorArcKeepCenter
Definition actions.h:269
static TOOL_ACTION pointEditorArcKeepRadius
Definition actions.h:271
static TOOL_ACTION activatePointEditor
Definition actions.h:267
static TOOL_ACTION pointEditorArcKeepEndpoint
Definition actions.h:270
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.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
BITMAP_POINT_EDIT_BEHAVIOR(SCH_BITMAP &aBitmap)
static constexpr BOX2< VECTOR2I > ByCorners(const VECTOR2I &aCorner1, const VECTOR2I &aCorner2)
Definition box2.h:66
constexpr const Vec GetCenter() const
Definition box2.h:226
constexpr coord_type GetLeft() const
Definition box2.h:224
constexpr coord_type GetRight() const
Definition box2.h:213
constexpr coord_type GetTop() const
Definition box2.h:225
constexpr coord_type GetBottom() const
Definition box2.h:218
Represent a set of changes (additions, deletions or modifications) of a data model (e....
Definition commit.h:68
bool Empty() const
Definition commit.h:134
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:102
EDIT_CONSTRAINT for a EDIT_LINE, that constrains the line to move perpendicular to the line itself.
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:96
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:108
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
Definition eda_item.h:202
bool IsNew() const
Definition eda_item.h:129
virtual void SetEnd(const VECTOR2I &aEnd)
Definition eda_shape.h:244
void SetStartX(int x)
Definition eda_shape.h:208
void SetEndY(int aY)
Definition eda_shape.h:251
void SetStartY(int y)
Definition eda_shape.h:201
SHAPE_POLY_SET & GetPolyShape()
SHAPE_T GetShape() const
Definition eda_shape.h:185
void SetEndX(int aX)
Definition eda_shape.h:258
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:240
bool IsClosed() const
wxString SHAPE_T_asString() const
void SetHatchingDirty()
Definition eda_shape.h:163
int GetCornerRadius() const
void SetConstraint(EDIT_CONSTRAINT< EDIT_LINE > *aConstraint)
Set a constraint for and EDIT_POINT.
EDIT_POINTS is a VIEW_ITEM that manages EDIT_POINTs and EDIT_LINEs and draws them.
void AddPoint(const EDIT_POINT &aPoint)
Add an EDIT_POINT.
EDIT_LINE & Line(unsigned int aIndex)
unsigned int LinesSize() const
Return number of stored EDIT_LINEs.
EDIT_POINT & Point(unsigned int aIndex)
void AddLine(const EDIT_LINE &aLine)
Adds an EDIT_LINE.
Represent a single point that can be used for modifying items.
Definition edit_points.h:44
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:76
int GetY() const
Return Y coordinate of an EDIT_POINT.
Definition edit_points.h:92
static const int POINT_SIZE
Single point size in pixels.
virtual void SetPosition(const VECTOR2I &aPosition)
Set new coordinates for an EDIT_POINT.
virtual VECTOR2I GetPosition() const
Return coordinates of an EDIT_POINT.
Definition edit_points.h:68
int GetX() const
Return X coordinate of an EDIT_POINT.
Definition edit_points.h:84
void SetDrawCircle(bool aDrawCircle=true)
static const TOOL_EVENT ClearedEvent
Definition actions.h:343
static const TOOL_EVENT SelectedEvent
Definition actions.h:341
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition actions.h:348
static const TOOL_EVENT PointSelectedEvent
Definition actions.h:340
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:63
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition view.cpp:300
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition view.cpp:404
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:1835
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:534
Define a library symbol object.
Definition lib_symbol.h:79
std::vector< const SCH_PIN * > GetGraphicalPins(int aUnit=0, int aBodyStyle=0) const
Graphical pins: Return schematic pin objects as drawn (unexpanded), filtered by unit/body.
bool 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, const VECTOR2I &aMinSize={ 0, 0 })
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
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
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:90
static TOOL_ACTION pointEditorAddCorner
static TOOL_ACTION pointEditorRemoveCorner
A shim class between EDA_DRAW_FRAME and several derived classes: SYMBOL_EDIT_FRAME,...
Object to handle a bitmap image that can be inserted in a schematic.
Definition sch_bitmap.h:36
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
virtual void Revert() override
Revert the commit by restoring the modified items state.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:162
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition sch_item.cpp:268
int GetBodyStyle() const
Definition sch_item.h:242
int GetUnit() const
Definition sch_item.h:233
Segment description base class to describe items which have 2 end points (track, wire,...
Definition sch_line.h:38
VECTOR2I GetEndPoint() const
Definition sch_line.h:144
VECTOR2I GetStartPoint() const
Definition sch_line.h:135
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
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.
std::unique_ptr< KIGFX::PREVIEW::ANGLE_ITEM > m_angleItem
Current item-specific edit behavior.
int changeArcEditMode(const TOOL_EVENT &aEvent)
int removeCorner(const TOOL_EVENT &aEvent)
int addCorner(const TOOL_EVENT &aEvent)
TOOL_ACTION handlers.
void SetPosition(const VECTOR2I &aPos) override
Definition sch_shape.h:85
VECTOR2I GetCenter() const
Definition sch_shape.h:92
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
VECTOR2I GetPosition() const override
Definition sch_shape.h:84
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:44
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.
void updateItem(EDA_ITEM *aItem, bool aUpdateRTree) const
bool Init() override
Init() is called once upon a registration of the tool.
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
SCH_TOOL_BASE(const std::string &aName)
SCH_SELECTION_TOOL * m_selectionTool
Definition seg.h:38
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition seg.cpp:698
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:173
int Size() const
Returns the number of selected parts.
Definition selection.h:117
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.
SHEET_POINT_EDIT_BEHAVIOR(SCH_SHEET &aSheet, 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.
std::vector< std::tuple< SCH_SHEET_PIN *, SCH_LINE *, int > > m_connectedWires
std::map< SCH_SHEET_PIN *, SCH_NO_CONNECT * > m_noConnects
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
The symbol library editor main window.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
TEXTBOX_POINT_EDIT_BEHAVIOR(SCH_TEXTBOX &aTextbox)
SCH_BASE_FRAME * getEditFrame() const
Definition tool_base.h:182
KIGFX::VIEW_CONTROLS * getViewControls() const
Definition tool_base.cpp:40
KIGFX::VIEW * getView() const
Definition tool_base.cpp:34
Generic, UI-independent tool event.
Definition tool_event.h:167
bool DisableGridSnapping() const
Definition tool_event.h:367
bool Matches(const TOOL_EVENT &aEvent) const
Test whether two events match in terms of category & action or command.
Definition tool_event.h:388
const VECTOR2D Position() const
Return mouse cursor position in world coordinates.
Definition tool_event.h:289
bool IsDrag(int aButtonMask=BUT_ANY) const
Definition tool_event.h:311
const VECTOR2D DragOrigin() const
Return the point where dragging has started.
Definition tool_event.h:295
T Parameter() const
Return a parameter assigned to the event.
Definition tool_event.h:469
bool IsMotion() const
Definition tool_event.h:326
void Go(int(SCH_BASE_FRAME::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition vector2d.h:279
@ ARROW
Definition cursors.h:42
const int minSize
Push and Shove router track width and via size dialog.
#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.
@ ELLIPSE
Definition eda_shape.h:52
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Definition eda_shape.h:47
@ ELLIPSE_ARC
Definition eda_shape.h:53
@ FRAME_SCH_SYMBOL_EDITOR
Definition frame_type.h:31
@ GRID_GRAPHICS
Definition grid_helper.h:48
@ LAYER_NOTES
Definition layer_ids.h:465
#define UNIMPLEMENTED_FOR(type)
Definition macros.h:92
constexpr int Mils2IU(const EDA_IU_SCALE &aIuScale, int mils)
Definition eda_units.h:171
std::vector< SEG > GetSegsInDirection(const BOX2I &aBox, DIRECTION_45::Directions aDir)
Get the segments of a box that are in the given direction.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:400
@ RECT_RIGHT
@ RECT_LEFT
@ RECT_CENTER
@ RECT_RADIUS
ARC_EDIT_MODE IncrementArcEditMode(ARC_EDIT_MODE aMode)
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
SCH_CONDITIONS S_C
RECTANGLE_POINTS
@ RECT_BOTLEFT
@ RECT_TOPLEFT
@ RECT_TOPRIGHT
@ RECT_CENTER
@ RECT_BOTRIGHT
@ RECT_RADIUS
RECTANGLE_LINES
@ RECT_RIGHT
@ RECT_LEFT
@ RECT_BOT
@ RECT_TOP
TABLECELL_POINTS
@ ROW_HEIGHT
@ COL_WIDTH
static const std::vector< KICAD_T > pointEditorTypes
@ LINE_START
@ LINE_END
REFIMAGE_POINTS
@ REFIMG_ORIGIN
@ ARC_START
@ ARC_END
@ ARC_CENTER
std::optional< VECTOR2I > OPT_VECTOR2I
Definition seg.h:35
Utility functions for working with shapes.
KIBIS_PIN * pin
std::vector< std::vector< std::string > > table
@ MD_SHIFT
Definition tool_event.h:139
@ BUT_LEFT
Definition tool_event.h:128
@ SCH_LINE_T
Definition typeinfo.h:160
@ SCH_TABLECELL_T
Definition typeinfo.h:163
@ SCH_SHEET_T
Definition typeinfo.h:172
@ SCH_SHAPE_T
Definition typeinfo.h:146
@ SCH_RULE_AREA_T
Definition typeinfo.h:167
@ SCH_ITEM_LOCATE_GRAPHIC_LINE_T
Definition typeinfo.h:185
@ SCH_BITMAP_T
Definition typeinfo.h:161
@ SCH_TEXTBOX_T
Definition typeinfo.h:149
constexpr int sign(T val)
Definition util.h:141
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683