KiCad PCB EDA Suite
Loading...
Searching...
No Matches
ee_point_editor.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2019 CERN
5 * Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <functional>
26using namespace std::placeholders;
27
28#include "ee_point_editor.h"
29#include <ee_grid_helper.h>
30#include <tool/tool_manager.h>
31#include <sch_commit.h>
32#include <view/view_controls.h>
34#include <geometry/seg.h>
35#include <tools/ee_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>
43#include <sch_tablecell.h>
44#include <sch_shape.h>
45#include <sch_sheet_pin.h>
46#include <symbol_edit_frame.h>
47#include <lib_shape.h>
48#include <lib_textbox.h>
49
50
51// Few constants to avoid using bare numbers for point indices
53{
55};
56
57
59{
61};
62
63
65{
67};
68
69
71{
73};
74
76{
78};
79
81{
83};
84
85
87{
92};
93
94
96{
97public:
98 static std::shared_ptr<EDIT_POINTS> Make( EDA_ITEM* aItem, SCH_BASE_FRAME* frame )
99 {
100 std::shared_ptr<EDIT_POINTS> points = std::make_shared<EDIT_POINTS>( aItem );
101
102 if( !aItem )
103 return points;
104
105 // Generate list of edit points based on the item type
106 switch( aItem->Type() )
107 {
108 case LIB_SHAPE_T:
109 {
110 LIB_SHAPE* shape = static_cast<LIB_SHAPE*>( aItem );
111
112 switch( shape->GetShape() )
113 {
114 case SHAPE_T::ARC:
115 points->AddPoint( mapCoords( shape->GetPosition() ) );
116 points->AddPoint( mapCoords( shape->GetStart() ) );
117 points->AddPoint( mapCoords( shape->GetEnd() ) );
118 break;
119
120 case SHAPE_T::CIRCLE:
121 points->AddPoint( mapCoords( shape->GetPosition() ) );
122 points->AddPoint( mapCoords( shape->GetEnd() ) );
123 break;
124
125 case SHAPE_T::RECTANGLE:
126 {
127 shape->Normalize();
128
129 VECTOR2I topLeft = mapCoords( shape->GetPosition() );
130 VECTOR2I botRight = mapCoords( shape->GetEnd() );
131
132 points->AddPoint( topLeft );
133 points->AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
134 points->AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
135 points->AddPoint( botRight );
136
137 points->AddLine( points->Point( RECT_TOPLEFT ), points->Point( RECT_TOPRIGHT ) );
138 points->Line( RECT_TOP ).SetConstraint( new EC_PERPLINE( points->Line( RECT_TOP ) ) );
139 points->AddLine( points->Point( RECT_TOPRIGHT ), points->Point( RECT_BOTRIGHT ) );
140 points->Line( RECT_RIGHT ).SetConstraint( new EC_PERPLINE( points->Line( RECT_RIGHT ) ) );
141 points->AddLine( points->Point( RECT_BOTRIGHT ), points->Point( RECT_BOTLEFT ) );
142 points->Line( RECT_BOT ).SetConstraint( new EC_PERPLINE( points->Line( RECT_BOT ) ) );
143 points->AddLine( points->Point( RECT_BOTLEFT ), points->Point( RECT_TOPLEFT ) );
144 points->Line( RECT_LEFT ).SetConstraint( new EC_PERPLINE( points->Line( RECT_LEFT ) ) );
145
146 break;
147 }
148
149 case SHAPE_T::POLY:
150 for( const VECTOR2I& pt : shape->GetPolyShape().Outline( 0 ).CPoints() )
151 points->AddPoint( mapCoords( pt ) );
152
153 break;
154
155 case SHAPE_T::BEZIER:
156 points->AddPoint( mapCoords( shape->GetStart() ) );
157 points->AddPoint( mapCoords( shape->GetBezierC1() ) );
158 points->AddPoint( mapCoords( shape->GetBezierC2() ) );
159 points->AddPoint( mapCoords( shape->GetEnd() ) );
160 break;
161
162 default:
164 }
165
166 break;
167 }
168
169 case LIB_TEXTBOX_T:
170 {
171 LIB_TEXTBOX* textBox = static_cast<LIB_TEXTBOX*>( aItem );
172
173 textBox->Normalize();
174
175 VECTOR2I topLeft = mapCoords( textBox->GetPosition() );
176 VECTOR2I botRight = mapCoords( textBox->GetEnd() );
177
178 points->AddPoint( topLeft );
179 points->AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
180 points->AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
181 points->AddPoint( botRight );
182
183 points->AddLine( points->Point( RECT_TOPLEFT ), points->Point( RECT_TOPRIGHT ) );
184 points->Line( RECT_TOP ).SetConstraint( new EC_PERPLINE( points->Line( RECT_TOP ) ) );
185 points->AddLine( points->Point( RECT_TOPRIGHT ), points->Point( RECT_BOTRIGHT ) );
186 points->Line( RECT_RIGHT ).SetConstraint( new EC_PERPLINE( points->Line( RECT_RIGHT ) ) );
187 points->AddLine( points->Point( RECT_BOTRIGHT ), points->Point( RECT_BOTLEFT ) );
188 points->Line( RECT_BOT ).SetConstraint( new EC_PERPLINE( points->Line( RECT_BOT ) ) );
189 points->AddLine( points->Point( RECT_BOTLEFT ), points->Point( RECT_TOPLEFT ) );
190 points->Line( RECT_LEFT ).SetConstraint( new EC_PERPLINE( points->Line( RECT_LEFT ) ) );
191
192 break;
193 }
194
195 case SCH_SHAPE_T:
196 {
197 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem );
198
199 switch( shape->GetShape() )
200 {
201 case SHAPE_T::ARC:
202 points->AddPoint( shape->GetPosition() );
203 points->AddPoint( shape->GetStart() );
204 points->AddPoint( shape->GetEnd() );
205 break;
206
207 case SHAPE_T::CIRCLE:
208 points->AddPoint( shape->GetPosition() );
209 points->AddPoint( shape->GetEnd() );
210 break;
211
212 case SHAPE_T::RECTANGLE:
213 {
214 shape->Normalize();
215
216 VECTOR2I topLeft = shape->GetPosition();
217 VECTOR2I botRight = shape->GetEnd();
218
219 points->AddPoint( topLeft );
220 points->AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
221 points->AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
222 points->AddPoint( botRight );
223
224 points->AddLine( points->Point( RECT_TOPLEFT ), points->Point( RECT_TOPRIGHT ) );
225 points->Line( RECT_TOP ).SetConstraint( new EC_PERPLINE( points->Line( RECT_TOP ) ) );
226 points->AddLine( points->Point( RECT_TOPRIGHT ), points->Point( RECT_BOTRIGHT ) );
227 points->Line( RECT_RIGHT ).SetConstraint( new EC_PERPLINE( points->Line( RECT_RIGHT ) ) );
228 points->AddLine( points->Point( RECT_BOTRIGHT ), points->Point( RECT_BOTLEFT ) );
229 points->Line( RECT_BOT ).SetConstraint( new EC_PERPLINE( points->Line( RECT_BOT ) ) );
230 points->AddLine( points->Point( RECT_BOTLEFT ), points->Point( RECT_TOPLEFT ) );
231 points->Line( RECT_LEFT ).SetConstraint( new EC_PERPLINE( points->Line( RECT_LEFT ) ) );
232
233 break;
234 }
235
236 case SHAPE_T::POLY:
237 for( const VECTOR2I& pt : shape->GetPolyShape().Outline( 0 ).CPoints() )
238 points->AddPoint( pt );
239
240 break;
241
242 case SHAPE_T::BEZIER:
243 points->AddPoint( shape->GetStart() );
244 points->AddPoint( shape->GetBezierC1() );
245 points->AddPoint( shape->GetBezierC2() );
246 points->AddPoint( shape->GetEnd() );
247 break;
248
249 default:
251 }
252
253 break;
254 }
255
256 case SCH_TEXTBOX_T:
257 {
258 SCH_TEXTBOX* textBox = static_cast<SCH_TEXTBOX*>( aItem );
259
260 textBox->Normalize();
261
262 VECTOR2I topLeft = textBox->GetPosition();
263 VECTOR2I botRight = textBox->GetEnd();
264
265 points->AddPoint( topLeft );
266 points->AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
267 points->AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
268 points->AddPoint( botRight );
269
270 points->AddLine( points->Point( RECT_TOPLEFT ), points->Point( RECT_TOPRIGHT ) );
271 points->Line( RECT_TOP ).SetConstraint( new EC_PERPLINE( points->Line( RECT_TOP ) ) );
272 points->AddLine( points->Point( RECT_TOPRIGHT ), points->Point( RECT_BOTRIGHT ) );
273 points->Line( RECT_RIGHT ).SetConstraint( new EC_PERPLINE( points->Line( RECT_RIGHT ) ) );
274 points->AddLine( points->Point( RECT_BOTRIGHT ), points->Point( RECT_BOTLEFT ) );
275 points->Line( RECT_BOT ).SetConstraint( new EC_PERPLINE( points->Line( RECT_BOT ) ) );
276 points->AddLine( points->Point( RECT_BOTLEFT ), points->Point( RECT_TOPLEFT ) );
277 points->Line( RECT_LEFT ).SetConstraint( new EC_PERPLINE( points->Line( RECT_LEFT ) ) );
278
279 break;
280 }
281
282 case SCH_TABLECELL_T:
283 {
284 SCH_TABLECELL* cell = static_cast<SCH_TABLECELL*>( aItem );
285 points->AddPoint( cell->GetEnd() - VECTOR2I( 0, cell->GetRectangleHeight() / 2 ) );
286 points->AddPoint( cell->GetEnd() - VECTOR2I( cell->GetRectangleWidth() / 2, 0 ) );
287 break;
288 }
289
290 case SCH_SHEET_T:
291 {
292 SCH_SHEET* sheet = (SCH_SHEET*) aItem;
293 VECTOR2I topLeft = sheet->GetPosition();
294 VECTOR2I botRight = sheet->GetPosition() + sheet->GetSize();
295
296 points->AddPoint( topLeft );
297 points->AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
298 points->AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
299 points->AddPoint( botRight );
300
301 points->AddLine( points->Point( RECT_TOPLEFT ), points->Point( RECT_TOPRIGHT ) );
302 points->Line( RECT_TOP ).SetConstraint( new EC_PERPLINE( points->Line( RECT_TOP ) ) );
303 points->AddLine( points->Point( RECT_TOPRIGHT ), points->Point( RECT_BOTRIGHT ) );
304 points->Line( RECT_RIGHT ).SetConstraint( new EC_PERPLINE( points->Line( RECT_RIGHT ) ) );
305 points->AddLine( points->Point( RECT_BOTRIGHT ), points->Point( RECT_BOTLEFT ) );
306 points->Line( RECT_BOT ).SetConstraint( new EC_PERPLINE( points->Line( RECT_BOT ) ) );
307 points->AddLine( points->Point( RECT_BOTLEFT ), points->Point( RECT_TOPLEFT ) );
308 points->Line( RECT_LEFT ).SetConstraint( new EC_PERPLINE( points->Line( RECT_LEFT ) ) );
309
310 break;
311 }
312
313 case SCH_BITMAP_T:
314 {
315 SCH_BITMAP* bitmap = (SCH_BITMAP*) aItem;
316 VECTOR2I topLeft = bitmap->GetPosition() - bitmap->GetSize() / 2;
317 VECTOR2I botRight = bitmap->GetPosition() + bitmap->GetSize() / 2;
318
319 points->AddPoint( topLeft );
320 points->AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
321 points->AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
322 points->AddPoint( botRight );
323 break;
324 }
325
326 case SCH_LINE_T:
327 {
328 SCH_LINE* line = (SCH_LINE*) aItem;
329 std::pair<EDA_ITEM*, int> connectedStart = { nullptr, STARTPOINT };
330 std::pair<EDA_ITEM*, int> connectedEnd = { nullptr, STARTPOINT };
331
332 for( SCH_ITEM* test : frame->GetScreen()->Items().OfType( SCH_LINE_T ) )
333 {
334 if( test->GetLayer() != LAYER_NOTES )
335 continue;
336
337 if( test == aItem )
338 continue;
339
340 SCH_LINE* testLine = static_cast<SCH_LINE*>( test );
341
342 if( testLine->GetStartPoint() == line->GetStartPoint() )
343 {
344 connectedStart = { testLine, STARTPOINT };
345 }
346 else if( testLine->GetEndPoint() == line->GetStartPoint() )
347 {
348 connectedStart = { testLine, ENDPOINT };
349 }
350 else if( testLine->GetStartPoint() == line->GetEndPoint() )
351 {
352 connectedEnd = { testLine, STARTPOINT };
353 }
354 else if( testLine->GetEndPoint() == line->GetEndPoint() )
355 {
356 connectedEnd = { testLine, ENDPOINT };
357 }
358 }
359
360 points->AddPoint( line->GetStartPoint(), connectedStart );
361 points->AddPoint( line->GetEndPoint(), connectedEnd );
362 break;
363 }
364
365 default:
366 points.reset();
367 break;
368 }
369
370 return points;
371 }
372
373private:
375};
376
377
379 EE_TOOL_BASE<SCH_BASE_FRAME>( "eeschema.PointEditor" ),
380 m_editedPoint( nullptr ),
381 m_inPointEditor( false )
382{
383}
384
385
387{
388 EE_TOOL_BASE::Reset( aReason );
389
390 m_editPoints.reset();
391 m_editedPoint = nullptr;
392}
393
394
396{
398
399 auto& menu = m_selectionTool->GetToolMenu().GetMenu();
401 std::bind( &EE_POINT_EDITOR::addCornerCondition, this, _1 ) );
403 std::bind( &EE_POINT_EDITOR::removeCornerCondition, this, _1 ) );
404
405 return true;
406}
407
408
410{
411 setEditedPoint( nullptr );
412
413 return 0;
414}
415
416
418{
419 EDIT_POINT* point = m_editedPoint;
420
421 if( !m_editPoints )
422 {
423 point = nullptr;
424 }
425 else if( aEvent.IsMotion() )
426 {
427 point = m_editPoints->FindPoint( aEvent.Position(), getView() );
428 }
429 else if( aEvent.IsDrag( BUT_LEFT ) )
430 {
431 point = m_editPoints->FindPoint( aEvent.DragOrigin(), getView() );
432 }
433 else
434 {
435 point = m_editPoints->FindPoint( getViewControls()->GetCursorPosition( false ), getView() );
436 }
437
438 if( m_editedPoint != point )
439 setEditedPoint( point );
440}
441
442
444{
445 if( !m_selectionTool )
446 return 0;
447
448 if( m_inPointEditor )
449 return 0;
450
452
453 if( m_isSymbolEditor )
454 {
455 SYMBOL_EDIT_FRAME* editor = getEditFrame<SYMBOL_EDIT_FRAME>();
456
457 if( !editor->IsSymbolEditable() || editor->IsSymbolAlias() )
458 return 0;
459 }
460
461 const EE_SELECTION& selection = m_selectionTool->GetSelection();
462
463 if( selection.Size() != 1 || !selection.Front()->IsType( { LIB_SHAPE_T, SCH_SHAPE_T,
464 LIB_TEXTBOX_T, SCH_TEXTBOX_T,
465 SCH_TABLECELL_T,
466 SCH_SHEET_T,
467 SCH_ITEM_LOCATE_GRAPHIC_LINE_T,
468 SCH_BITMAP_T } ) )
469 {
470 return 0;
471 }
472
473 // Wait till drawing tool is done
474 if( selection.Front()->IsNew() )
475 return 0;
476
477 Activate();
478
481 VECTOR2I cursorPos;
482 KIGFX::VIEW* view = getView();
483 EDA_ITEM* item = selection.Front();
484 SCH_COMMIT commit( m_toolMgr );
485
486 controls->ShowCursor( true );
487
489 view->Add( m_editPoints.get() );
490 setEditedPoint( nullptr );
491 updateEditedPoint( aEvent );
492 bool inDrag = false;
493
494 // Main loop: keep receiving events
495 while( TOOL_EVENT* evt = Wait() )
496 {
497 if( grid )
498 {
499 grid->SetSnap( !evt->Modifier( MD_SHIFT ) );
500 grid->SetUseGrid( getView()->GetGAL()->GetGridSnapping()
501 && !evt->DisableGridSnapping() );
502 }
503 else
504 {
505 // This check is based on the assumption that the grid object must be valid.
506 // If this assumption is wrong, please fix the code above.
507 wxCHECK( false, 0 );
508 }
509
510 if( !m_editPoints || evt->IsSelectionEvent() )
511 break;
512
513 if ( !inDrag )
514 updateEditedPoint( *evt );
515
516 if( evt->IsDrag( BUT_LEFT ) && m_editedPoint )
517 {
518 if( !inDrag )
519 {
520 commit.Modify( m_editPoints->GetParent(), m_frame->GetScreen() );
521
522 if( m_editPoints->GetParent()->Type() == SCH_LINE_T )
523 {
524 std::pair<EDA_ITEM*, int> connected = m_editPoints->Point( LINE_START ).GetConnected();
525
526 if( connected.first )
527 commit.Modify( connected.first, m_frame->GetScreen() );
528
529 connected = m_editPoints->Point( LINE_END ).GetConnected();
530
531 if( connected.first )
532 commit.Modify( connected.first, m_frame->GetScreen() );
533 }
534 else if( m_editPoints->GetParent()->Type() == SCH_TABLECELL_T )
535 {
536 SCH_TABLECELL* cell = static_cast<SCH_TABLECELL*>( m_editPoints->GetParent() );
537 SCH_TABLE* table = static_cast<SCH_TABLE*>( cell->GetParent() );
538
539 commit.Modify( table, m_frame->GetScreen() );
540 }
541
542 inDrag = true;
543 }
544
545 bool snap = !evt->DisableGridSnapping();
546
547 cursorPos =
548 grid->Align( controls->GetMousePosition(), GRID_HELPER_GRIDS::GRID_GRAPHICS );
549 controls->ForceCursorPosition( true, cursorPos );
550
551 m_editedPoint->SetPosition( controls->GetCursorPosition( snap ) );
552
553 updateParentItem( snap );
554 updatePoints();
555 }
556 else if( inDrag && evt->IsMouseUp( BUT_LEFT ) )
557 {
558 if( !commit.Empty() )
559 commit.Push( _( "Move Point" ) );
560
561 controls->SetAutoPan( false );
562 inDrag = false;
563 }
564 else if( evt->IsCancelInteractive() || evt->IsActivate() )
565 {
566 if( inDrag ) // Restore the last change
567 {
568 // Currently we are manually managing the lifetime of the grid
569 // helpers because there is a bug in the tool stack that adds
570 // the point editor again when commit.Revert() rebuilds the selection.
571 // We remove this grid here so the its destructor is called before it
572 // is added again.
573 if( grid )
574 {
575 delete grid;
576 grid = nullptr;
577 }
578
579 commit.Revert();
580 inDrag = false;
581 break;
582 }
583 else if( evt->IsCancelInteractive() )
584 {
585 break;
586 }
587
588 if( evt->IsActivate() )
589 break;
590 }
591 else
592 {
593 evt->SetPassEvent();
594 }
595
596 controls->SetAutoPan( inDrag );
597 controls->CaptureCursor( inDrag );
598 }
599
600 controls->SetAutoPan( false );
601 controls->CaptureCursor( false );
602 setEditedPoint( nullptr );
603
604 if( m_editPoints )
605 {
606 view->Remove( m_editPoints.get() );
607
608 m_editPoints.reset();
610 }
611
612 delete grid;
613
614 return 0;
615}
616
627void EE_POINT_EDITOR::pinEditedCorner( int minWidth, int minHeight, VECTOR2I& topLeft,
628 VECTOR2I& topRight, VECTOR2I& botLeft, VECTOR2I& botRight,
629 EE_GRID_HELPER* aGrid ) const
630{
631 if( isModified( m_editPoints->Point( RECT_TOPLEFT ) ) )
632 {
633 // pin edited point within opposite corner
634 topLeft.x = std::min( topLeft.x, botRight.x - minWidth );
635 topLeft.y = std::min( topLeft.y, botRight.y - minHeight );
636
637 if( aGrid->GetSnap() )
638 topLeft = aGrid->AlignGrid( topLeft, GRID_HELPER_GRIDS::GRID_GRAPHICS );
639
640 // push edited point edges to adjacent corners
641 topRight.y = topLeft.y;
642 botLeft.x = topLeft.x;
643 }
644 else if( isModified( m_editPoints->Point( RECT_TOPRIGHT ) ) )
645 {
646 // pin edited point within opposite corner
647 topRight.x = std::max( topRight.x, botLeft.x + minWidth );
648 topRight.y = std::min( topRight.y, botLeft.y - minHeight );
649
650 if( aGrid->GetSnap() )
651 topRight = aGrid->AlignGrid( topRight, GRID_HELPER_GRIDS::GRID_GRAPHICS );
652
653 // push edited point edges to adjacent corners
654 topLeft.y = topRight.y;
655 botRight.x = topRight.x;
656 }
657 else if( isModified( m_editPoints->Point( RECT_BOTLEFT ) ) )
658 {
659 // pin edited point within opposite corner
660 botLeft.x = std::min( botLeft.x, topRight.x - minWidth );
661 botLeft.y = std::max( botLeft.y, topRight.y + minHeight );
662
663 if( aGrid->GetSnap() )
664 botLeft = aGrid->AlignGrid( botLeft, GRID_HELPER_GRIDS::GRID_GRAPHICS );
665
666 // push edited point edges to adjacent corners
667 botRight.y = botLeft.y;
668 topLeft.x = botLeft.x;
669 }
670 else if( isModified( m_editPoints->Point( RECT_BOTRIGHT ) ) )
671 {
672 // pin edited point within opposite corner
673 botRight.x = std::max( botRight.x, topLeft.x + minWidth );
674 botRight.y = std::max( botRight.y, topLeft.y + minHeight );
675
676 if( aGrid->GetSnap() )
677 botRight = aGrid->AlignGrid( botRight, GRID_HELPER_GRIDS::GRID_GRAPHICS );
678
679 // push edited point edges to adjacent corners
680 botLeft.y = botRight.y;
681 topRight.x = botRight.x;
682 }
683 else if( isModified( m_editPoints->Line( RECT_TOP ) ) )
684 {
685 topLeft.y = std::min( topLeft.y, botRight.y - minHeight );
686
687 if( aGrid->GetSnap() )
688 topLeft = aGrid->AlignGrid( topLeft, GRID_HELPER_GRIDS::GRID_GRAPHICS );
689 }
690 else if( isModified( m_editPoints->Line( RECT_LEFT ) ) )
691 {
692 topLeft.x = std::min( topLeft.x, botRight.x - minWidth );
693
694 if( aGrid->GetSnap() )
695 topLeft = aGrid->AlignGrid( topLeft, GRID_HELPER_GRIDS::GRID_GRAPHICS );
696 }
697 else if( isModified( m_editPoints->Line( RECT_BOT ) ) )
698 {
699 botRight.y = std::max( botRight.y, topLeft.y + minHeight );
700
701 if( aGrid->GetSnap() )
702 botRight = aGrid->AlignGrid( botRight, GRID_HELPER_GRIDS::GRID_GRAPHICS );
703 }
704 else if( isModified( m_editPoints->Line( RECT_RIGHT ) ) )
705 {
706 botRight.x = std::max( botRight.x, topLeft.x + minWidth );
707
708 if( aGrid->GetSnap() )
709 botRight = aGrid->AlignGrid( botRight, GRID_HELPER_GRIDS::GRID_GRAPHICS );
710 }
711}
712
713
714void EE_POINT_EDITOR::updateParentItem( bool aSnapToGrid ) const
715{
716 EDA_ITEM* item = m_editPoints->GetParent();
717
718 if( !item )
719 return;
720
721 switch( item->Type() )
722 {
723 case LIB_SHAPE_T:
724 {
725 LIB_SHAPE* shape = static_cast<LIB_SHAPE*>( item );
726
727 switch( shape->GetShape() )
728 {
729 case SHAPE_T::ARC:
731 {
732 shape->SetEditState( 4 );
733 shape->CalcEdit( mapCoords( m_editPoints->Point( ARC_CENTER ).GetPosition() ) );
734 }
735 else if( getEditedPointIndex() == ARC_START )
736 {
737 shape->SetEditState( 2 );
738 shape->CalcEdit( mapCoords( m_editPoints->Point( ARC_START ).GetPosition() ) );
739 }
740 else if( getEditedPointIndex() == ARC_END )
741 {
742 shape->SetEditState( 3 );
743 shape->CalcEdit( mapCoords( m_editPoints->Point( ARC_END ).GetPosition() ) );
744 }
745 break;
746
747 case SHAPE_T::CIRCLE:
748 shape->SetPosition( mapCoords( m_editPoints->Point( CIRC_CENTER ).GetPosition() ) );
749 shape->SetEnd( mapCoords( m_editPoints->Point( CIRC_END ).GetPosition() ) );
750 break;
751
752 case SHAPE_T::POLY:
754 shape->GetPolyShape().NewOutline();
755
756 for( unsigned i = 0; i < m_editPoints->PointsSize(); ++i )
757 {
758 VECTOR2I pt = mapCoords( m_editPoints->Point( i ).GetPosition() );
759 shape->GetPolyShape().Append( pt.x, pt.y, -1, -1, true );
760 }
761
762 break;
763
764 case SHAPE_T::RECTANGLE:
765 {
766 EE_GRID_HELPER gridHelper( m_toolMgr );
767 VECTOR2I topLeft = m_editPoints->Point( RECT_TOPLEFT ).GetPosition();
768 VECTOR2I topRight = m_editPoints->Point( RECT_TOPRIGHT ).GetPosition();
769 VECTOR2I botLeft = m_editPoints->Point( RECT_BOTLEFT ).GetPosition();
770 VECTOR2I botRight = m_editPoints->Point( RECT_BOTRIGHT ).GetPosition();
771
772 gridHelper.SetSnap( aSnapToGrid );
773
774 pinEditedCorner( schIUScale.MilsToIU( 1 ), schIUScale.MilsToIU( 1 ), topLeft, topRight,
775 botLeft, botRight, &gridHelper );
776
777 if( isModified( m_editPoints->Point( RECT_TOPLEFT ) )
780 || isModified( m_editPoints->Point( RECT_BOTLEFT ) ) )
781 {
782 shape->SetPosition( mapCoords( topLeft ) );
783 shape->SetEnd( mapCoords( botRight ) );
784 }
785 else if( isModified( m_editPoints->Line( RECT_TOP ) ) )
786 {
787 shape->SetStartY( mapCoords( topLeft ).y );
788 }
789 else if( isModified( m_editPoints->Line( RECT_LEFT ) ) )
790 {
791 shape->SetStartX( mapCoords( topLeft ).x );
792 }
793 else if( isModified( m_editPoints->Line( RECT_BOT ) ) )
794 {
795 shape->SetEndY( mapCoords( botRight ).y );
796 }
797 else if( isModified( m_editPoints->Line( RECT_RIGHT ) ) )
798 {
799 shape->SetEndX( mapCoords( botRight ).x );
800 }
801
802 for( unsigned i = 0; i < m_editPoints->LinesSize(); ++i )
803 {
804 if( !isModified( m_editPoints->Line( i ) ) )
805 {
806 m_editPoints->Line( i ).SetConstraint(
807 new EC_PERPLINE( m_editPoints->Line( i ) ) );
808 }
809 }
810
811 break;
812 }
813
814 case SHAPE_T::BEZIER:
815 shape->SetStart( mapCoords( m_editPoints->Point( BEZIER_CURVE_START ).GetPosition() ) );
816 shape->SetBezierC1( mapCoords( m_editPoints->Point( BEZIER_CURVE_CONTROL_POINT1 ).GetPosition() ) );
817 shape->SetBezierC2( mapCoords( m_editPoints->Point( BEZIER_CURVE_CONTROL_POINT2 ).GetPosition() ) );
818 shape->SetEnd( mapCoords( m_editPoints->Point( BEZIER_CURVE_END ).GetPosition() ) );
819
821 break;
822
823 default:
825 }
826
827 break;
828 }
829
830 case LIB_TEXTBOX_T:
831 {
832 LIB_TEXTBOX* textbox = static_cast<LIB_TEXTBOX*>( item );
833 EE_GRID_HELPER gridHelper( m_toolMgr );
834 VECTOR2I topLeft = m_editPoints->Point( RECT_TOPLEFT ).GetPosition();
835 VECTOR2I topRight = m_editPoints->Point( RECT_TOPRIGHT ).GetPosition();
836 VECTOR2I botLeft = m_editPoints->Point( RECT_BOTLEFT ).GetPosition();
837 VECTOR2I botRight = m_editPoints->Point( RECT_BOTRIGHT ).GetPosition();
838
839 gridHelper.SetSnap( aSnapToGrid );
840
841 pinEditedCorner( schIUScale.MilsToIU( 1 ), schIUScale.MilsToIU( 1 ), topLeft, topRight,
842 botLeft, botRight, &gridHelper );
843
844 if( isModified( m_editPoints->Point( RECT_TOPLEFT ) )
847 || isModified( m_editPoints->Point( RECT_BOTLEFT ) ) )
848 {
849 textbox->SetPosition( mapCoords( topLeft ) );
850 textbox->SetEnd( mapCoords( botRight ) );
851 }
852 else if( isModified( m_editPoints->Line( RECT_TOP ) ) )
853 {
854 textbox->SetStartY( mapCoords( topLeft ).y );
855 }
856 else if( isModified( m_editPoints->Line( RECT_LEFT ) ) )
857 {
858 textbox->SetStartX( mapCoords( topLeft ).x );
859 }
860 else if( isModified( m_editPoints->Line( RECT_BOT ) ) )
861 {
862 textbox->SetEndY( mapCoords( botRight ).y );
863 }
864 else if( isModified( m_editPoints->Line( RECT_RIGHT ) ) )
865 {
866 textbox->SetEndX( mapCoords( botRight ).x );
867 }
868
869 for( unsigned i = 0; i < m_editPoints->LinesSize(); ++i )
870 {
871 if( !isModified( m_editPoints->Line( i ) ) )
872 {
873 m_editPoints->Line( i ).SetConstraint(
874 new EC_PERPLINE( m_editPoints->Line( i ) ) );
875 }
876 }
877
878 textbox->ClearRenderCache();
879 break;
880 }
881
882 case SCH_SHAPE_T:
883 {
884 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( item );
885
886 switch( shape->GetShape() )
887 {
888 case SHAPE_T::ARC:
890 {
891 shape->SetEditState( 4 );
892 shape->CalcEdit( m_editPoints->Point( ARC_CENTER ).GetPosition() );
893 }
894 else if( getEditedPointIndex() == ARC_START )
895 {
896 shape->SetEditState( 2 );
897 shape->CalcEdit( m_editPoints->Point( ARC_START ).GetPosition() );
898 }
899 else if( getEditedPointIndex() == ARC_END )
900 {
901 shape->SetEditState( 3 );
902 shape->CalcEdit( m_editPoints->Point( ARC_END ).GetPosition() );
903 }
904 break;
905
906 case SHAPE_T::CIRCLE:
907 shape->SetPosition( m_editPoints->Point( CIRC_CENTER ).GetPosition() );
908 shape->SetEnd( m_editPoints->Point( CIRC_END ).GetPosition() );
909 break;
910
911 case SHAPE_T::POLY:
913 shape->GetPolyShape().NewOutline();
914
915 for( unsigned i = 0; i < m_editPoints->PointsSize(); ++i )
916 {
917 VECTOR2I pt = m_editPoints->Point( i ).GetPosition();
918 shape->GetPolyShape().Append( pt.x, pt.y, -1, -1, true );
919 }
920
921 break;
922
923 case SHAPE_T::RECTANGLE:
924 {
925 EE_GRID_HELPER gridHelper( m_toolMgr );
926 VECTOR2I topLeft = m_editPoints->Point( RECT_TOPLEFT ).GetPosition();
927 VECTOR2I topRight = m_editPoints->Point( RECT_TOPRIGHT ).GetPosition();
928 VECTOR2I botLeft = m_editPoints->Point( RECT_BOTLEFT ).GetPosition();
929 VECTOR2I botRight = m_editPoints->Point( RECT_BOTRIGHT ).GetPosition();
930
931 gridHelper.SetSnap( aSnapToGrid );
932
933 pinEditedCorner( schIUScale.MilsToIU( 1 ), schIUScale.MilsToIU( 1 ), topLeft, topRight,
934 botLeft, botRight, &gridHelper );
935
936 if( isModified( m_editPoints->Point( RECT_TOPLEFT ) )
939 || isModified( m_editPoints->Point( RECT_BOTLEFT ) ) )
940 {
941 shape->SetPosition( topLeft );
942 shape->SetEnd( botRight );
943 }
944 else if( isModified( m_editPoints->Line( RECT_TOP ) ) )
945 {
946 shape->SetStartY( topLeft.y );
947 }
948 else if( isModified( m_editPoints->Line( RECT_LEFT ) ) )
949 {
950 shape->SetStartX( topLeft.x );
951 }
952 else if( isModified( m_editPoints->Line( RECT_BOT ) ) )
953 {
954 shape->SetEndY( botRight.y );
955 }
956 else if( isModified( m_editPoints->Line( RECT_RIGHT ) ) )
957 {
958 shape->SetEndX( botRight.x );
959 }
960
961 for( unsigned i = 0; i < m_editPoints->LinesSize(); ++i )
962 {
963 if( !isModified( m_editPoints->Line( i ) ) )
964 {
965 m_editPoints->Line( i ).SetConstraint(
966 new EC_PERPLINE( m_editPoints->Line( i ) ) );
967 }
968 }
969
970 break;
971 }
972
973 case SHAPE_T::BEZIER:
974 shape->SetStart( m_editPoints->Point( BEZIER_CURVE_START ).GetPosition() );
975 shape->SetBezierC1( m_editPoints->Point( BEZIER_CURVE_CONTROL_POINT1 ).GetPosition() );
976 shape->SetBezierC2( m_editPoints->Point( BEZIER_CURVE_CONTROL_POINT2 ).GetPosition() );
977 shape->SetEnd( m_editPoints->Point( BEZIER_CURVE_END ).GetPosition() );
978
980 break;
981
982 default:
984 }
985
986 break;
987 }
988
989 case SCH_TEXTBOX_T:
990 {
991 SCH_TEXTBOX* textBox = static_cast<SCH_TEXTBOX*>( item );
992 EE_GRID_HELPER gridHelper( m_toolMgr );
993 VECTOR2I topLeft = m_editPoints->Point( RECT_TOPLEFT ).GetPosition();
994 VECTOR2I topRight = m_editPoints->Point( RECT_TOPRIGHT ).GetPosition();
995 VECTOR2I botLeft = m_editPoints->Point( RECT_BOTLEFT ).GetPosition();
996 VECTOR2I botRight = m_editPoints->Point( RECT_BOTRIGHT ).GetPosition();
997
998 gridHelper.SetSnap( aSnapToGrid );
999
1000 pinEditedCorner( schIUScale.MilsToIU( 1 ), schIUScale.MilsToIU( 1 ), topLeft, topRight,
1001 botLeft, botRight, &gridHelper );
1002
1003 if( isModified( m_editPoints->Point( RECT_TOPLEFT ) )
1004 || isModified( m_editPoints->Point( RECT_TOPRIGHT ) )
1005 || isModified( m_editPoints->Point( RECT_BOTRIGHT ) )
1006 || isModified( m_editPoints->Point( RECT_BOTLEFT ) ) )
1007 {
1008 textBox->SetPosition( topLeft );
1009 textBox->SetEnd( botRight );
1010 }
1011 else if( isModified( m_editPoints->Line( RECT_TOP ) ) )
1012 {
1013 textBox->SetStartY( topLeft.y );
1014 }
1015 else if( isModified( m_editPoints->Line( RECT_LEFT ) ) )
1016 {
1017 textBox->SetStartX( topLeft.x );
1018 }
1019 else if( isModified( m_editPoints->Line( RECT_BOT ) ) )
1020 {
1021 textBox->SetEndY( botRight.y );
1022 }
1023 else if( isModified( m_editPoints->Line( RECT_RIGHT ) ) )
1024 {
1025 textBox->SetEndX( botRight.x );
1026 }
1027
1028 for( unsigned i = 0; i < m_editPoints->LinesSize(); ++i )
1029 {
1030 if( !isModified( m_editPoints->Line( i ) ) )
1031 {
1032 m_editPoints->Line( i ).SetConstraint(
1033 new EC_PERPLINE( m_editPoints->Line( i ) ) );
1034 }
1035 }
1036
1037 textBox->ClearRenderCache();
1038 break;
1039 }
1040
1041 case SCH_TABLECELL_T:
1042 {
1043 SCH_TABLECELL* cell = static_cast<SCH_TABLECELL*>( item );
1044 SCH_TABLE* table = static_cast<SCH_TABLE*>( cell->GetParent() );
1045
1046 if( isModified( m_editPoints->Point( COL_WIDTH ) ) )
1047 {
1048 cell->SetEnd( VECTOR2I( m_editPoints->Point( 0 ).GetX(), cell->GetEndY() ) );
1049
1050 int colWidth = cell->GetRectangleWidth();
1051
1052 for( int ii = 0; ii < cell->GetColSpan() - 1; ++ii )
1053 colWidth -= table->GetColWidth( cell->GetColumn() + ii );
1054
1055 table->SetColWidth( cell->GetColumn() + cell->GetColSpan() - 1, colWidth );
1056 table->Normalize();
1057 }
1058 else if( isModified( m_editPoints->Point( ROW_HEIGHT ) ) )
1059 {
1060 cell->SetEnd( VECTOR2I( cell->GetEndX(), m_editPoints->Point( 1 ).GetY() ) );
1061
1062 int rowHeight = cell->GetRectangleHeight();
1063
1064 for( int ii = 0; ii < cell->GetRowSpan() - 1; ++ii )
1065 rowHeight -= table->GetRowHeight( cell->GetRow() + ii );
1066
1067 table->SetRowHeight( cell->GetRow() + cell->GetRowSpan() - 1, rowHeight );
1068 table->Normalize();
1069 }
1070
1071 break;
1072 }
1073
1074 case SCH_BITMAP_T:
1075 {
1076 EE_GRID_HELPER gridHelper( m_toolMgr );
1077 SCH_BITMAP* bitmap = (SCH_BITMAP*) item;
1078 VECTOR2I topLeft = m_editPoints->Point( RECT_TOPLEFT ).GetPosition();
1079 VECTOR2I topRight = m_editPoints->Point( RECT_TOPRIGHT ).GetPosition();
1080 VECTOR2I botLeft = m_editPoints->Point( RECT_BOTLEFT ).GetPosition();
1081 VECTOR2I botRight = m_editPoints->Point( RECT_BOTRIGHT ).GetPosition();
1082
1083 gridHelper.SetSnap( aSnapToGrid );
1084
1085 pinEditedCorner( schIUScale.MilsToIU( 50 ), schIUScale.MilsToIU( 50 ), topLeft, topRight,
1086 botLeft, botRight, &gridHelper );
1087
1088 double oldWidth = bitmap->GetSize().x;
1089 double newWidth = topRight.x - topLeft.x;
1090 double widthRatio = newWidth / oldWidth;
1091
1092 double oldHeight = bitmap->GetSize().y;
1093 double newHeight = botLeft.y - topLeft.y;
1094 double heightRatio = newHeight / oldHeight;
1095
1096 bitmap->SetImageScale( bitmap->GetImageScale() * std::min( widthRatio, heightRatio ) );
1097 break;
1098 }
1099
1100 case SCH_SHEET_T:
1101 {
1102 SCH_SHEET* sheet = (SCH_SHEET*) item;
1103 EE_GRID_HELPER gridHelper( m_toolMgr );
1104 VECTOR2I topLeft = m_editPoints->Point( RECT_TOPLEFT ).GetPosition();
1105 VECTOR2I topRight = m_editPoints->Point( RECT_TOPRIGHT ).GetPosition();
1106 VECTOR2I botLeft = m_editPoints->Point( RECT_BOTLEFT ).GetPosition();
1107 VECTOR2I botRight = m_editPoints->Point( RECT_BOTRIGHT ).GetPosition();
1108 VECTOR2I sheetNewPos = sheet->GetPosition();
1109 VECTOR2I sheetNewSize = sheet->GetSize();
1110
1111 gridHelper.SetSnap( aSnapToGrid );
1112
1113 int edited = getEditedPointIndex();
1114
1115 if( isModified( m_editPoints->Line( RECT_RIGHT ) ) )
1116 edited = RECT_TOPRIGHT;
1117 else if( isModified( m_editPoints->Line( RECT_BOT ) ) )
1118 edited = RECT_BOTLEFT;
1119
1120 gridHelper.SetSnap( aSnapToGrid );
1121
1122 pinEditedCorner( sheet->GetMinWidth( edited == RECT_TOPRIGHT || edited == RECT_BOTRIGHT ),
1123 sheet->GetMinHeight( edited == RECT_BOTLEFT || edited == RECT_BOTRIGHT ),
1124 topLeft, topRight, botLeft, botRight, &gridHelper );
1125
1126 if( isModified( m_editPoints->Point( RECT_TOPLEFT ) )
1127 || isModified( m_editPoints->Point( RECT_TOPRIGHT ) )
1128 || isModified( m_editPoints->Point( RECT_BOTRIGHT ) )
1129 || isModified( m_editPoints->Point( RECT_BOTLEFT ) ) )
1130 {
1131 sheetNewPos = topLeft;
1132 sheetNewSize = VECTOR2I( botRight.x - topLeft.x, botRight.y - topLeft.y );
1133 }
1134 else if( isModified( m_editPoints->Line( RECT_TOP ) ) )
1135 {
1136 sheetNewPos = VECTOR2I( sheet->GetPosition().x, topLeft.y );
1137 sheetNewSize = VECTOR2I( sheet->GetSize().x, botRight.y - topLeft.y );
1138 }
1139 else if( isModified( m_editPoints->Line( RECT_LEFT ) ) )
1140 {
1141 sheetNewPos = VECTOR2I( topLeft.x, sheet->GetPosition().y );
1142 sheetNewSize = VECTOR2I( botRight.x - topLeft.x, sheet->GetSize().y );
1143 }
1144 else if( isModified( m_editPoints->Line( RECT_BOT ) ) )
1145 {
1146 sheetNewSize = VECTOR2I( sheet->GetSize().x, botRight.y - topLeft.y );
1147 }
1148 else if( isModified( m_editPoints->Line( RECT_RIGHT ) ) )
1149 {
1150 sheetNewSize = VECTOR2I( botRight.x - topLeft.x, sheet->GetSize().y );
1151 }
1152
1153 for( unsigned i = 0; i < m_editPoints->LinesSize(); ++i )
1154 {
1155 if( !isModified( m_editPoints->Line( i ) ) )
1156 {
1157 m_editPoints->Line( i ).SetConstraint(
1158 new EC_PERPLINE( m_editPoints->Line( i ) ) );
1159 }
1160 }
1161
1162 if( sheet->GetPosition() != sheetNewPos )
1163 sheet->SetPositionIgnoringPins( sheetNewPos );
1164
1165 if( sheet->GetSize() != sheetNewSize )
1166 sheet->Resize( sheetNewSize );
1167
1168 break;
1169 }
1170
1171 case SCH_LINE_T:
1172 {
1173 SCH_LINE* line = (SCH_LINE*) item;
1174
1175 line->SetStartPoint( m_editPoints->Point( LINE_START ).GetPosition() );
1176 line->SetEndPoint( m_editPoints->Point( LINE_END ).GetPosition() );
1177
1178 std::pair<EDA_ITEM*, int> connected = m_editPoints->Point( LINE_START ).GetConnected();
1179
1180 if( connected.first )
1181 {
1182 if( connected.second == STARTPOINT )
1183 static_cast<SCH_LINE*>( connected.first )->SetStartPoint( line->GetStartPoint() );
1184 else if( connected.second == ENDPOINT )
1185 static_cast<SCH_LINE*>( connected.first )->SetEndPoint( line->GetStartPoint() );
1186
1187 updateItem( connected.first, true );
1188 }
1189
1190 connected = m_editPoints->Point( LINE_END ).GetConnected();
1191
1192 if( connected.first )
1193 {
1194 if( connected.second == STARTPOINT )
1195 static_cast<SCH_LINE*>( connected.first )->SetStartPoint( line->GetEndPoint() );
1196 else if( connected.second == ENDPOINT )
1197 static_cast<SCH_LINE*>( connected.first )->SetEndPoint( line->GetEndPoint() );
1198
1199 updateItem( connected.first, true );
1200 }
1201
1202 break;
1203 }
1204
1205 default:
1206 break;
1207 }
1208
1209 updateItem( item, true );
1210 m_frame->SetMsgPanel( item );
1211}
1212
1213
1215{
1216 if( !m_editPoints )
1217 return;
1218
1219 EDA_ITEM* item = m_editPoints->GetParent();
1220
1221 if( !item )
1222 return;
1223
1224 switch( item->Type() )
1225 {
1226 case LIB_SHAPE_T:
1227 {
1228 LIB_SHAPE* shape = static_cast<LIB_SHAPE*>( item );
1229
1230 switch( shape->GetShape() )
1231 {
1232 case SHAPE_T::ARC:
1233 m_editPoints->Point( ARC_CENTER ).SetPosition( mapCoords( shape->GetPosition() ) );
1234 m_editPoints->Point( ARC_START ).SetPosition( mapCoords( shape->GetStart() ) );
1235 m_editPoints->Point( ARC_END ).SetPosition( mapCoords( shape->GetEnd() ) );
1236 break;
1237
1238 case SHAPE_T::CIRCLE:
1239 m_editPoints->Point( CIRC_CENTER ).SetPosition( mapCoords( shape->GetPosition() ) );
1240 m_editPoints->Point( CIRC_END ).SetPosition( mapCoords( shape->GetEnd() ) );
1241 break;
1242
1243 case SHAPE_T::POLY:
1244 {
1245 if( (int) m_editPoints->PointsSize() != shape->GetPointCount() )
1246 {
1247 getView()->Remove( m_editPoints.get() );
1248 m_editedPoint = nullptr;
1250 getView()->Add( m_editPoints.get() );
1251 }
1252 else
1253 {
1254 int ii = 0;
1255
1256 for( const VECTOR2I& pt : shape->GetPolyShape().Outline( 0 ).CPoints() )
1257 m_editPoints->Point( ii++ ).SetPosition( mapCoords( pt ) );
1258 }
1259
1260 break;
1261 }
1262
1263 case SHAPE_T::RECTANGLE:
1264 {
1265 // point editor works only with rectangles having width and height > 0
1266 // Some symbols can have rectangles with width or height < 0
1267 // So normalize the size:
1268 BOX2I dummy;
1269 dummy.SetOrigin( mapCoords( shape->GetPosition() ) );
1270 dummy.SetEnd( mapCoords( shape->GetEnd() ) );
1271 dummy.Normalize();
1272 VECTOR2I topLeft = dummy.GetPosition();
1273 VECTOR2I botRight = dummy.GetEnd();
1274
1275 m_editPoints->Point( RECT_TOPLEFT ).SetPosition( topLeft );
1276 m_editPoints->Point( RECT_TOPRIGHT ).SetPosition( VECTOR2I( botRight.x, topLeft.y ) );
1277 m_editPoints->Point( RECT_BOTLEFT ).SetPosition( VECTOR2I( topLeft.x, botRight.y ) );
1278 m_editPoints->Point( RECT_BOTRIGHT ).SetPosition( botRight );
1279 break;
1280 }
1281
1282 case SHAPE_T::BEZIER:
1283 m_editPoints->Point( BEZIER_CURVE_START ).SetPosition( mapCoords( shape->GetStart() ) );
1284 m_editPoints->Point( BEZIER_CURVE_CONTROL_POINT1 ).SetPosition( mapCoords( shape->GetBezierC1() ) );
1285 m_editPoints->Point( BEZIER_CURVE_CONTROL_POINT2 ).SetPosition( mapCoords( shape->GetBezierC2() ) );
1286 m_editPoints->Point( BEZIER_CURVE_END ).SetPosition( mapCoords( shape->GetEnd() ) );
1287 break;
1288
1289 default:
1291 }
1292
1293 break;
1294 }
1295
1296 case LIB_TEXTBOX_T:
1297 {
1298 LIB_TEXTBOX* textbox = static_cast<LIB_TEXTBOX*>( item );
1299
1300 // point editor works only with rectangles having width and height > 0
1301 // Some symbols can have rectangles with width or height < 0
1302 // So normalize the size:
1303 BOX2I dummy;
1304 dummy.SetOrigin( mapCoords( textbox->GetPosition() ) );
1305 dummy.SetEnd( mapCoords( textbox->GetEnd() ) );
1306 dummy.Normalize();
1307 VECTOR2I topLeft = dummy.GetPosition();
1308 VECTOR2I botRight = dummy.GetEnd();
1309
1310 m_editPoints->Point( RECT_TOPLEFT ).SetPosition( topLeft );
1311 m_editPoints->Point( RECT_TOPRIGHT ).SetPosition( VECTOR2I( botRight.x, topLeft.y ) );
1312 m_editPoints->Point( RECT_BOTLEFT ).SetPosition( VECTOR2I( topLeft.x, botRight.y ) );
1313 m_editPoints->Point( RECT_BOTRIGHT ).SetPosition( botRight );
1314 break;
1315 }
1316
1317 case SCH_SHAPE_T:
1318 {
1319 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( item );
1320
1321 switch( shape->GetShape() )
1322 {
1323 case SHAPE_T::ARC:
1324 m_editPoints->Point( ARC_CENTER ).SetPosition( shape->GetPosition() );
1325 m_editPoints->Point( ARC_START ).SetPosition( shape->GetStart() );
1326 m_editPoints->Point( ARC_END ).SetPosition( shape->GetEnd() );
1327 break;
1328
1329 case SHAPE_T::CIRCLE:
1330 m_editPoints->Point( CIRC_CENTER ).SetPosition( shape->GetPosition() );
1331 m_editPoints->Point( CIRC_END ).SetPosition( shape->GetEnd() );
1332 break;
1333
1334 case SHAPE_T::POLY:
1335 {
1336 if( (int) m_editPoints->PointsSize() != shape->GetPointCount() )
1337 {
1338 getView()->Remove( m_editPoints.get() );
1339 m_editedPoint = nullptr;
1341 getView()->Add( m_editPoints.get() );
1342 }
1343 else
1344 {
1345 int ii = 0;
1346
1347 for( const VECTOR2I& pt : shape->GetPolyShape().Outline( 0 ).CPoints() )
1348 m_editPoints->Point( ii++ ).SetPosition( pt );
1349 }
1350
1351 break;
1352 }
1353
1354 case SHAPE_T::RECTANGLE:
1355 {
1356 // point editor works only with rectangles having width and height > 0
1357 // Some symbols can have rectangles with width or height < 0
1358 // So normalize the size:
1359 BOX2I dummy;
1360 dummy.SetOrigin( shape->GetPosition() );
1361 dummy.SetEnd( shape->GetEnd() );
1362 dummy.Normalize();
1363 VECTOR2I topLeft = dummy.GetPosition();
1364 VECTOR2I botRight = dummy.GetEnd();
1365
1366 m_editPoints->Point( RECT_TOPLEFT ).SetPosition( topLeft );
1367 m_editPoints->Point( RECT_TOPRIGHT ).SetPosition( VECTOR2I( botRight.x, topLeft.y ) );
1368 m_editPoints->Point( RECT_BOTLEFT ).SetPosition( VECTOR2I( topLeft.x, botRight.y ) );
1369 m_editPoints->Point( RECT_BOTRIGHT ).SetPosition( botRight );
1370 break;
1371 }
1372
1373 case SHAPE_T::BEZIER:
1374 m_editPoints->Point( BEZIER_CURVE_START ).SetPosition( shape->GetStart() );
1375 m_editPoints->Point( BEZIER_CURVE_CONTROL_POINT1 ).SetPosition( shape->GetBezierC1() );
1376 m_editPoints->Point( BEZIER_CURVE_CONTROL_POINT2 ).SetPosition( shape->GetBezierC2() );
1377 m_editPoints->Point( BEZIER_CURVE_END ).SetPosition( shape->GetEnd() );
1378 break;
1379
1380 default:
1382 }
1383
1384 break;
1385 }
1386
1387 case SCH_TEXTBOX_T:
1388 {
1389 SCH_TEXTBOX* textBox = static_cast<SCH_TEXTBOX*>( item );
1390
1391 // point editor works only with rectangles having width and height > 0
1392 // Some symbols can have rectangles with width or height < 0
1393 // So normalize the size:
1394 BOX2I dummy;
1395 dummy.SetOrigin( textBox->GetPosition() );
1396 dummy.SetEnd( textBox->GetEnd() );
1397 dummy.Normalize();
1398 VECTOR2I topLeft = dummy.GetPosition();
1399 VECTOR2I botRight = dummy.GetEnd();
1400
1401 m_editPoints->Point( RECT_TOPLEFT ).SetPosition( topLeft );
1402 m_editPoints->Point( RECT_TOPRIGHT ).SetPosition( VECTOR2I( botRight.x, topLeft.y ) );
1403 m_editPoints->Point( RECT_BOTLEFT ).SetPosition( VECTOR2I( topLeft.x, botRight.y ) );
1404 m_editPoints->Point( RECT_BOTRIGHT ).SetPosition( botRight );
1405 break;
1406 }
1407
1408 case SCH_TABLECELL_T:
1409 {
1410 SCH_TABLECELL* cell = static_cast<SCH_TABLECELL*>( item );
1411
1412 m_editPoints->Point( 0 ).SetPosition( cell->GetEndX(),
1413 cell->GetEndY() - cell->GetRectangleHeight() / 2 );
1414 m_editPoints->Point( 1 ).SetPosition( cell->GetEndX() - cell->GetRectangleWidth() / 2,
1415 cell->GetEndY() );
1416 break;
1417 }
1418
1419 case SCH_BITMAP_T:
1420 {
1421 SCH_BITMAP* bitmap = (SCH_BITMAP*) item;
1422 VECTOR2I topLeft = bitmap->GetPosition() - bitmap->GetSize() / 2;
1423 VECTOR2I botRight = bitmap->GetPosition() + bitmap->GetSize() / 2;
1424
1425 m_editPoints->Point( RECT_TOPLEFT ).SetPosition( topLeft );
1426 m_editPoints->Point( RECT_TOPRIGHT ).SetPosition( botRight.x, topLeft.y );
1427 m_editPoints->Point( RECT_BOTLEFT ).SetPosition( topLeft.x, botRight.y );
1428 m_editPoints->Point( RECT_BOTRIGHT ).SetPosition( botRight );
1429 break;
1430 }
1431
1432 case SCH_SHEET_T:
1433 {
1434 SCH_SHEET* sheet = (SCH_SHEET*) item;
1435 VECTOR2I topLeft = sheet->GetPosition();
1436 VECTOR2I botRight = sheet->GetPosition() + sheet->GetSize();
1437
1438 m_editPoints->Point( RECT_TOPLEFT ).SetPosition( topLeft );
1439 m_editPoints->Point( RECT_TOPRIGHT ).SetPosition( botRight.x, topLeft.y );
1440 m_editPoints->Point( RECT_BOTLEFT ).SetPosition( topLeft.x, botRight.y );
1441 m_editPoints->Point( RECT_BOTRIGHT ).SetPosition( botRight );
1442 break;
1443 }
1444
1445 case SCH_LINE_T:
1446 {
1447 SCH_LINE* line = (SCH_LINE*) item;
1448
1449 m_editPoints->Point( LINE_START ).SetPosition( line->GetStartPoint() );
1450 m_editPoints->Point( LINE_END ).SetPosition( line->GetEndPoint() );
1451 break;
1452 }
1453
1454 default:
1455 break;
1456 }
1457
1458 getView()->Update( m_editPoints.get() );
1459}
1460
1461
1463{
1465
1466 if( aPoint )
1467 {
1468 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
1469 controls->ForceCursorPosition( true, aPoint->GetPosition() );
1470 controls->ShowCursor( true );
1471 }
1472 else
1473 {
1474 if( m_frame->ToolStackIsEmpty() )
1475 controls->ShowCursor( false );
1476
1477 controls->ForceCursorPosition( false );
1478 }
1479
1480 m_editedPoint = aPoint;
1481}
1482
1483
1485{
1486 if( !m_editPoints || !m_editedPoint || m_editPoints->GetParent()->Type() != LIB_SHAPE_T )
1487 return false;
1488
1489 LIB_SHAPE* shape = static_cast<LIB_SHAPE*>( m_editPoints->GetParent() );
1490
1491 if( shape->GetPolyShape().IsEmpty() )
1492 return false;
1493
1494 SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
1495
1496 if( poly.GetPointCount() < 3 )
1497 return false;
1498
1499 for( const VECTOR2I& pt : poly.CPoints() )
1500 {
1501 if( pt == mapCoords( m_editedPoint->GetPosition() ) )
1502 return true;
1503 }
1504
1505 return false;
1506}
1507
1508
1510{
1511 if( !m_editPoints || m_editPoints->GetParent()->Type() != LIB_SHAPE_T )
1512 return false;
1513
1514 LIB_SHAPE* shape = static_cast<LIB_SHAPE*>( m_editPoints->GetParent() );
1515
1516 if( shape->GetShape() != SHAPE_T::POLY )
1517 return false;
1518
1519 VECTOR2I cursorPos = getViewControls()->GetCursorPosition( false );
1520 double threshold = getView()->ToWorld( EDIT_POINT::POINT_SIZE );
1521
1522 return shape->HitTest( cursorPos, (int) threshold );
1523}
1524
1525
1527{
1528 if( !m_editPoints || m_editPoints->GetParent()->Type() != LIB_SHAPE_T )
1529 return 0;
1530
1531 LIB_SHAPE* shape = static_cast<LIB_SHAPE*>( m_editPoints->GetParent() );
1532 SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
1533 SCH_COMMIT commit( m_toolMgr );
1534
1535 commit.Modify( shape, m_frame->GetScreen() );
1536
1538 VECTOR2I pos = mapCoords( cursor );
1539 int currentMinDistance = INT_MAX;
1540 int closestLineStart = 0;
1541
1542 for( unsigned i = 0; i < poly.GetPointCount() - 1; ++i )
1543 {
1544 int distance = (int) DistanceLinePoint( poly.CPoint( i ),
1545 poly.CPoint( i + 1 ), pos );
1546
1547 if( distance < currentMinDistance )
1548 {
1549 currentMinDistance = distance;
1550 closestLineStart = i;
1551 }
1552 }
1553
1554 poly.Insert( closestLineStart + 1, pos );
1555
1556 updateItem( shape, true );
1557 updatePoints();
1558
1559 commit.Push( _( "Add Corner" ) );
1560 return 0;
1561}
1562
1563
1565{
1566 if( !m_editPoints || !m_editedPoint || m_editPoints->GetParent()->Type() != LIB_SHAPE_T )
1567 return 0;
1568
1569 LIB_SHAPE* shape = static_cast<LIB_SHAPE*>( m_editPoints->GetParent() );
1570 SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
1571 SCH_COMMIT commit( m_toolMgr );
1572
1573 commit.Modify( shape, m_frame->GetScreen() );
1574
1575 if( poly.GetPointCount() < 3 )
1576 return 0;
1577
1578 poly.Remove( getEditedPointIndex() );
1579
1580 updateItem( shape, true );
1581 updatePoints();
1582
1583 commit.Push( _( "Remove Corner" ) );
1584 return 0;
1585}
1586
1587
1589{
1590 updatePoints();
1591 return 0;
1592}
1593
1594
1596{
1604}
1605
1606
VECTOR2D mapCoords(const VECTOR2D &aSource)
Definition: PS_plotter.cpp:531
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
static TOOL_ACTION activatePointEditor
Definition: actions.h:201
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:105
bool Empty() const
Returns status of an item.
Definition: commit.h:144
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Add a menu entry to run a TOOL_ACTION on selected items.
EDIT_CONSTRAINT for a EDIT_LINE, that constrains the line to move perpendicular to the line itself.
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:85
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
Definition: eda_item.h:172
EDA_ITEM * GetParent() const
Definition: eda_item.h:99
bool IsNew() const
Definition: eda_item.h:103
void SetStartX(int x)
Definition: eda_shape.h:142
const VECTOR2I & GetBezierC2() const
Definition: eda_shape.h:190
void SetBezierC2(const VECTOR2I &aPt)
Definition: eda_shape.h:189
void SetEndY(int aY)
Definition: eda_shape.h:161
void RebuildBezierToSegmentsPointsList(int aMinSegLen)
Rebuild the m_bezierPoints vertex list that approximate the Bezier curve by a list of segments.
Definition: eda_shape.cpp:473
int GetEndX() const
Definition: eda_shape.h:153
int GetRectangleWidth() const
Definition: eda_shape.cpp:162
void SetStartY(int y)
Definition: eda_shape.h:136
SHAPE_POLY_SET & GetPolyShape()
Definition: eda_shape.h:263
SHAPE_T GetShape() const
Definition: eda_shape.h:119
int GetEndY() const
Definition: eda_shape.h:152
void SetEndX(int aX)
Definition: eda_shape.h:167
int GetPointCount() const
Definition: eda_shape.cpp:1329
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:151
void SetStart(const VECTOR2I &aStart)
Definition: eda_shape.h:130
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition: eda_shape.h:126
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:155
void SetBezierC1(const VECTOR2I &aPt)
Definition: eda_shape.h:186
wxString SHAPE_T_asString() const
Definition: eda_shape.cpp:87
const VECTOR2I & GetBezierC1() const
Definition: eda_shape.h:187
int GetRectangleHeight() const
Definition: eda_shape.cpp:150
virtual int GetWidth() const
Definition: eda_shape.h:109
virtual void ClearRenderCache()
Definition: eda_text.cpp:499
static std::shared_ptr< EDIT_POINTS > Make(EDA_ITEM *aItem, SCH_BASE_FRAME *frame)
Represent a single point that can be used for modifying items.
Definition: edit_points.h:48
static const int POINT_SIZE
Definition: edit_points.h:190
virtual void SetPosition(const VECTOR2I &aPosition)
Set new coordinates for an EDIT_POINT.
Definition: edit_points.h:107
virtual VECTOR2I GetPosition() const
Return coordinates of an EDIT_POINT.
Definition: edit_points.h:71
static TOOL_ACTION pointEditorRemoveCorner
Definition: ee_actions.h:144
static TOOL_ACTION pointEditorAddCorner
Definition: ee_actions.h:143
void updatePoints()
Update which point is being edited.
bool m_inPointEditor
Currently available edit points.
int Main(const TOOL_EVENT &aEvent)
void updateEditedPoint(const TOOL_EVENT &aEvent)
Clear references to the points.
void setEditedPoint(EDIT_POINT *aPoint)
Return true if aPoint is the currently modified point.
int modifiedSelection(const TOOL_EVENT &aEvent)
bool Init() override
Init() is called once upon a registration of the tool.
EDIT_POINT * m_editedPoint
< Currently edited point, NULL if there is none.
bool addCornerCondition(const SELECTION &aSelection)
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
void pinEditedCorner(int minWidth, int minHeight, VECTOR2I &topLeft, VECTOR2I &topRight, VECTOR2I &botLeft, VECTOR2I &botRight, EE_GRID_HELPER *aGrid) const
Update the coordinates of 4 corners of a rectangle, according to constraints and the moved corner.
bool isModified(const EDIT_POINT &aPoint) const
int addCorner(const TOOL_EVENT &aEvent)
TOOL_ACTION handlers.
std::shared_ptr< EDIT_POINTS > m_editPoints
bool removeCornerCondition(const SELECTION &aSelection)
int removeCorner(const TOOL_EVENT &aEvent)
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
int getEditedPointIndex() const
int clearEditedPoints(const TOOL_EVENT &aEvent)
Set the current point being edited. NULL means none.
void updateParentItem(bool aSnapToGrid) const
< Update item's points with edit points.
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:238
EE_SELECTION & GetSelection()
A foundation class for a tool operating on a schematic or symbol.
Definition: ee_tool_base.h:48
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
Definition: ee_tool_base.h:84
void updateItem(EDA_ITEM *aItem, bool aUpdateRTree) const
Similar to getView()->Update(), but handles items that are redrawn by their parents and updating the ...
Definition: ee_tool_base.h:109
EE_SELECTION_TOOL * m_selectionTool
Definition: ee_tool_base.h:200
bool Init() override
Init() is called once upon a registration of the tool.
Definition: ee_tool_base.h:64
static const TOOL_EVENT ClearedEvent
Definition: actions.h:255
static const TOOL_EVENT SelectedEvent
Definition: actions.h:253
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:260
static const TOOL_EVENT PointSelectedEvent
Definition: actions.h:252
bool GetSnap() const
Definition: grid_helper.h:107
void SetSnap(bool aSnap)
Definition: grid_helper.h:106
virtual VECTOR2I AlignGrid(const VECTOR2I &aPoint, GRID_HELPER_GRIDS aGrid) const
Definition: grid_helper.h:65
An interface for classes handling user events controlling the view behavior such as zooming,...
virtual void CaptureCursor(bool aEnabled)
Force the cursor to stay within the drawing panel area.
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Place the cursor immediately at a given point.
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:313
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:350
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:1619
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:444
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: lib_shape.cpp:46
void AddPoint(const VECTOR2I &aPosition)
Definition: lib_shape.cpp:506
void SetEditState(int aState)
Definition: lib_shape.h:82
void SetPosition(const VECTOR2I &aPosition) override
Definition: lib_shape.h:91
void CalcEdit(const VECTOR2I &aPosition) override
Calculate the attributes of an item at aPosition when it is being edited.
Definition: lib_shape.h:79
void Normalize()
Definition: lib_shape.cpp:93
VECTOR2I GetPosition() const override
Definition: lib_shape.h:90
A shim class between EDA_DRAW_FRAME and several derived classes: SYMBOL_EDIT_FRAME,...
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
Object to handle a bitmap image that can be inserted in a schematic.
Definition: sch_bitmap.h:41
double GetImageScale() const
Definition: sch_bitmap.h:67
VECTOR2I GetPosition() const override
Definition: sch_bitmap.h:147
VECTOR2I GetSize() const
Definition: sch_bitmap.cpp:145
void SetImageScale(double aScale)
Definition: sch_bitmap.h:72
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
Definition: sch_commit.cpp:367
virtual void Revert() override
Definition: sch_commit.cpp:448
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:165
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:40
void SetStartPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:141
VECTOR2I GetEndPoint() const
Definition: sch_line.h:145
VECTOR2I GetStartPoint() const
Definition: sch_line.h:140
void SetEndPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:146
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:109
void SetPosition(const VECTOR2I &aPos) override
Definition: sch_shape.h:78
void CalcEdit(const VECTOR2I &aPosition)
Definition: sch_shape.h:84
void SetEditState(int aState)
Definition: sch_shape.h:86
void Normalize()
Definition: sch_shape.cpp:75
void AddPoint(const VECTOR2I &aPosition)
Definition: sch_shape.cpp:491
VECTOR2I GetPosition() const override
Definition: sch_shape.h:77
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:57
void SetPositionIgnoringPins(const VECTOR2I &aPosition)
Definition: sch_sheet.cpp:822
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:491
VECTOR2I GetSize() const
Definition: sch_sheet.h:112
VECTOR2I GetPosition() const override
Definition: sch_sheet.h:375
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:525
void Resize(const VECTOR2I &aSize)
Resize this sheet to aSize and adjust all of the labels accordingly.
Definition: sch_sheet.cpp:935
int GetColSpan() const
Definition: sch_tablecell.h:61
int GetRowSpan() const
Definition: sch_tablecell.h:64
int GetColumn() const
int GetRow() const
void SetRowHeight(int aRow, int aHeight)
Definition: sch_table.h:123
int GetRowHeight(int aRow) const
Definition: sch_table.h:125
void SetColWidth(int aCol, int aWidth)
Definition: sch_table.h:113
int GetColWidth(int aCol) const
Definition: sch_table.h:115
void Normalize()
Definition: sch_table.cpp:137
EDA_ITEM * Front() const
Definition: selection.h:208
int Size() const
Returns the number of selected parts.
Definition: selection.h:115
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
virtual size_t GetPointCount() const override
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
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
void RemoveAllContours()
Remove all outlines & holes (clears) the polygon set.
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
The symbol library editor main window.
bool ToolStackIsEmpty()
Definition: tools_holder.h:125
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:216
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
Generic, UI-independent tool event.
Definition: tool_event.h:167
bool DisableGridSnapping() const
Definition: tool_event.h:363
const VECTOR2D Position() const
Returns the point where dragging has started.
Definition: tool_event.h:285
bool IsDrag(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:307
const VECTOR2D DragOrigin() const
Returns information about mouse buttons state.
Definition: tool_event.h:291
bool IsMotion() const
Definition: tool_event.h:322
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
TOOL_MENU & GetToolMenu()
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Suspend execution of the tool until an event specified in aEventList arrives.
void Activate()
Run the tool.
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:44
#define _(s)
#define ENDPOINT
ends. (Used to support dragging.)
#define STARTPOINT
When a line is selected, these flags indicate which.
RECTANGLE_POINTS
@ RECT_BOTLEFT
@ RECT_TOPLEFT
@ RECT_TOPRIGHT
@ RECT_BOTRIGHT
RECTANGLE_LINES
@ RECT_RIGHT
@ RECT_LEFT
@ RECT_BOT
@ RECT_TOP
BEZIER_CURVE_POINTS
@ BEZIER_CURVE_START
@ BEZIER_CURVE_CONTROL_POINT2
@ BEZIER_CURVE_END
@ BEZIER_CURVE_CONTROL_POINT1
TABLECELL_POINTS
@ ROW_HEIGHT
@ COL_WIDTH
LINE_POINTS
@ LINE_START
@ LINE_END
ARC_POINTS
@ ARC_START
@ ARC_END
@ ARC_CENTER
CIRCLE_POINTS
@ CIRC_END
@ CIRC_CENTER
@ LAYER_NOTES
Definition: layer_ids.h:369
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:96
@ RECT_BOTLEFT
@ RECT_TOPLEFT
@ RECT_TOPRIGHT
@ RECT_BOTRIGHT
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
std::vector< FAB_LAYER_COLOR > dummy
constexpr int MilsToIU(int mils) const
Definition: base_units.h:94
@ MD_SHIFT
Definition: tool_event.h:142
@ BUT_LEFT
Definition: tool_event.h:131
double DistanceLinePoint(const VECTOR2I &linePointA, const VECTOR2I &linePointB, const VECTOR2I &referencePoint)
Compute the distance between a line and a reference point.
Definition: trigo.h:143
@ SCH_LINE_T
Definition: typeinfo.h:148
@ SCH_TABLECELL_T
Definition: typeinfo.h:154
@ LIB_TEXTBOX_T
Definition: typeinfo.h:205
@ SCH_SHEET_T
Definition: typeinfo.h:162
@ LIB_SHAPE_T
Definition: typeinfo.h:203
@ SCH_SHAPE_T
Definition: typeinfo.h:149
@ SCH_BITMAP_T
Definition: typeinfo.h:150
@ SCH_TEXTBOX_T
Definition: typeinfo.h:151
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588