KiCad PCB EDA Suite
Loading...
Searching...
No Matches
ee_graphic_tool.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <tool/tool_manager.h>
22
23#include <wx/msgdlg.h>
24
25#include <default_values.h>
26#include <scoped_set_reset.h>
27
29#include <eeschema_settings.h>
32#include <sch_actions.h>
33#include <sch_commit.h>
34#include <sch_edit_frame.h>
35#include <sch_line.h>
36#include <sch_shape.h>
37#include <sch_textbox.h>
38#include <schematic.h>
39#include <symbol_edit_frame.h>
48#include <view/view_controls.h>
49#include <view/view.h>
50
51
53
54
72
73
75{
77
78 const auto inDrawingArc =
79 [this]( const SELECTION& aSel )
80 {
81 return m_mode == MODE::ARC;
82 };
83
84 const auto inManagedShape = [this]( const SELECTION& aSel )
85 {
87 };
88
89 CONDITIONAL_MENU& ctxMenu = m_menu->GetMenu();
90
91 // clang-format off
92 ctxMenu.AddItem( ACTIONS::arcPosture, inDrawingArc, 200 );
93 ctxMenu.AddCheckItem( SCH_ACTIONS::drawArcCenter, inDrawingArc, 200 );
94 ctxMenu.AddCheckItem( SCH_ACTIONS::drawArcStartEndMid, inDrawingArc, 200 );
95 ctxMenu.AddCheckItem( SCH_ACTIONS::drawArcStartEndCenter, inDrawingArc, 200 );
96 ctxMenu.AddCheckItem( SCH_ACTIONS::drawArcTangent, inDrawingArc, 200 );
97 ctxMenu.AddCheckItem( SCH_ACTIONS::drawArcStartDirEnd, inDrawingArc, 200 );
98 ctxMenu.AddItem( ACTIONS::cycleArcDrawMode, inDrawingArc, 200 );
99 ctxMenu.AddItem( ACTIONS::deleteLastPoint, inManagedShape, 200 );
100 ctxMenu.AddItem( ACTIONS::finishInteractive, inManagedShape, 200 );
101 // clang-format on
102
103 return true;
104}
105
106
111
112
114{
115 if( IsSymbolEditor() )
116 {
117 const SYMBOL_EDITOR_SETTINGS* cfg = frame<SYMBOL_EDIT_FRAME>()->libeditconfig();
118
119 return schIUScale.MilsToIU( cfg ? cfg->m_Defaults.text_size : DEFAULT_TEXT_SIZE );
120 }
121
122 return getModel<SCHEMATIC>()->Settings().m_DefaultTextSize;
123}
124
125
127{
128 if( !IsSymbolEditor() )
129 return;
130
132
133 if( symFrame->GetDrawSpecificUnit() )
134 aItem.SetUnit( symFrame->GetUnit() );
135
136 if( symFrame->GetDrawSpecificBodyStyle() )
137 aItem.SetBodyStyle( symFrame->GetBodyStyle() );
138}
139
140
141void EE_GRAPHIC_TOOL::commitItem( SCH_COMMIT& aCommit, std::unique_ptr<SCH_ITEM> aItem, const wxString& aDescription )
142{
143 aItem->ClearEditFlags();
144
145 if( IsSymbolEditor() )
146 {
148 LIB_SYMBOL* symbol = symFrame->GetCurSymbol();
149
150 aCommit.Modify( symbol, frame()->GetScreen() );
151 symbol->AddDrawItem( aItem.release() );
152 aCommit.Push( aDescription );
153 symFrame->RebuildView();
154 }
155 else
156 {
157 aCommit.Add( aItem.release(), frame()->GetScreen() );
158 aCommit.Push( aDescription );
159 }
160}
161
162
164{
165 EDA_ITEM* parent = getDrawParent();
166
167 if( !parent )
168 return 0;
169
170 int defaultTextSize = getDefaultTextSize();
171 bool isTextBox = aEvent.IsAction( &SCH_ACTIONS::drawTextBox )
173 bool isLineTool = aEvent.IsAction( &SCH_ACTIONS::drawSymbolLines );
174 SHAPE_T type = isTextBox ? SHAPE_T::RECTANGLE : aEvent.Parameter<SHAPE_T>();
175
176 if( m_inDrawingTool )
177 return 0;
178
180
183 VECTOR2I cursorPos;
184
185 std::unique_ptr<SCH_SHAPE> item;
186
187 // We might be running as the same shape in another co-routine. Make sure that one
188 // gets whacked.
189 m_toolMgr->DeactivateTool();
190
192
193 TOOL_EVENT originalEvent = aEvent;
194 SCOPED_TOOL_PUSHER raii( frame(), originalEvent );
195
196 auto setCursor =
197 [&]()
198 {
199 frame()->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
200 };
201
202 auto cleanup =
203 [&] ()
204 {
206 m_view->ClearPreview();
207 item.reset();
208 };
209
210 Activate();
211
212 // Must be done after Activate() so that it gets set into the correct context
213 getViewControls()->ShowCursor( true );
214
215 // Set initial cursor
216 setCursor();
217
218 if( aEvent.HasPosition() )
219 m_toolMgr->PrimeTool( aEvent.Position() );
220
221 SCH_LAYER_ID shapeLayer = getShapeLayer();
222
223 // Main loop: keep receiving events
224 while( TOOL_EVENT* evt = Wait() )
225 {
226 setCursor();
227 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
228 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
229
230 cursorPos = grid.Align( controls->GetMousePosition(), GRID_HELPER_GRIDS::GRID_GRAPHICS );
231 controls->ForceCursorPosition( true, cursorPos );
232
233 // The tool hotkey is interpreted as a click when drawing
234 bool isSyntheticClick = item && evt->IsActivate() && evt->HasPosition() && evt->Matches( aEvent );
235
236 if( evt->IsCancelInteractive() || ( item && evt->IsAction( &ACTIONS::undo ) ) )
237 {
238 if( item )
239 cleanup();
240 else
241 break;
242 }
243 else if( evt->IsActivate() && !isSyntheticClick )
244 {
245 if( item && evt->IsMoveTool() )
246 {
247 // we're already drawing our own item; ignore the move tool
248 evt->SetPassEvent( false );
249 continue;
250 }
251
252 if( item )
253 cleanup();
254
255 if( evt->IsPointEditor() )
256 {
257 // don't exit (the point editor runs in the background)
258 continue;
259 }
260
261 if( evt->IsMoveTool() )
262 {
263 // Make sure we come back after the move tool runs
264 frame()->PushTool( originalEvent );
265 }
266
267 break;
268 }
269 else if( !item && ( evt->IsClick( BUT_LEFT )
270 || evt->IsAction( &ACTIONS::cursorClick ) ) )
271 {
273
274 if( isTextBox )
275 {
276 auto textbox = std::make_unique<SCH_TEXTBOX>( shapeLayer, 0, m_lastTextboxFillStyle );
277
278 textbox->SetTextSize( VECTOR2I( defaultTextSize, defaultTextSize ) );
279
280 // Must come after SetTextSize()
281 textbox->SetBold( m_lastTextBold );
282 textbox->SetItalic( m_lastTextItalic );
283
284 textbox->SetTextAngle( m_lastTextboxAngle );
285 textbox->SetHorizJustify( m_lastTextboxHJustify );
286 textbox->SetVertJustify( m_lastTextboxVJustify );
287 textbox->SetStroke( m_lastTextboxStroke );
288 textbox->SetFillColor( m_lastTextboxFillColor );
289 textbox->SetParent( parent );
290
291 item = std::move( textbox );
292 }
293 else
294 {
295 item = std::make_unique<SCH_SHAPE>( type, shapeLayer, 0, m_lastFillStyle );
296
297 item->SetStroke( m_lastStroke );
298 item->SetFillColor( m_lastFillColor );
299 item->SetParent( parent );
300 }
301
302 item->SetFlags( IS_NEW );
303
304 applySymbolEditorFlags( *item );
305
306 item->BeginEdit( cursorPos );
307
308 m_view->ClearPreview();
309 m_view->AddToPreview( item->Clone() );
310 }
311 else if( item && ( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT )
312 || isSyntheticClick
313 || evt->IsAction( &ACTIONS::cursorClick ) || evt->IsAction( &ACTIONS::cursorDblClick )
314 || evt->IsAction( &ACTIONS::finishInteractive ) ) )
315 {
316 bool finished = false;
317 bool closedShape = false;
318
319 if( evt->IsDblClick( BUT_LEFT )
320 || evt->IsAction( &ACTIONS::cursorDblClick )
321 || evt->IsAction( &ACTIONS::finishInteractive ) )
322 {
323 finished = true;
324 closedShape = !isLineTool;
325 }
326 else
327 {
328 finished = !item->ContinueEdit( cursorPos );
329 }
330
331 if( finished )
332 {
333 item->EndEdit( closedShape );
334 item->SetFlags( IS_NEW );
335
336 if( isTextBox )
337 {
338 SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( item.get() );
339 DIALOG_TEXT_PROPERTIES dlg( frame(), textbox );
340
341 getViewControls()->SetAutoPan( false );
342 getViewControls()->CaptureCursor( false );
343
344 // QuasiModal required for syntax help and Scintilla auto-complete
345 if( dlg.ShowQuasiModal() != wxID_OK )
346 {
347 cleanup();
348 continue;
349 }
350
351 m_lastTextBold = textbox->IsBold();
352 m_lastTextItalic = textbox->IsItalic();
353 m_lastTextboxAngle = textbox->GetTextAngle();
356 m_lastTextboxStroke = textbox->GetStroke();
359 }
360 else
361 {
362 m_lastStroke = item->GetStroke();
363 m_lastFillStyle = item->GetFillMode();
364 m_lastFillColor = item->GetFillColor();
365 }
366
367 m_selectionTool->AddItemToSel( item.get() );
368
369 SCH_COMMIT commit( m_toolMgr );
370 wxString msg = wxString::Format( _( "Draw %s" ), item->GetClass() );
371
372 commitItem( commit, std::move( item ), msg );
373 item = nullptr;
374
375 m_view->ClearPreview();
377 }
378 }
379 else if( evt->IsAction( &ACTIONS::duplicate )
380 || evt->IsAction( &SCH_ACTIONS::repeatDrawItem )
381 || evt->IsAction( &ACTIONS::paste ) )
382 {
383 if( item )
384 {
385 wxBell();
386 continue;
387 }
388
389 // Exit. The duplicate/repeat/paste will run in its own loop.
390 evt->SetPassEvent();
391 break;
392 }
393 else if( item && ( evt->IsAction( &ACTIONS::refreshPreview )
394 || evt->IsMotion() ) )
395 {
396 item->CalcEdit( cursorPos );
397 m_view->ClearPreview();
398 m_view->AddToPreview( item->Clone() );
399
400 frame()->SetMsgPanel( item.get() );
401 }
402 else if( !item && ( evt->IsDblClick( BUT_LEFT )
403 || evt->IsAction( &ACTIONS::cursorDblClick ) ) )
404 {
406 }
407 else if( evt->IsClick( BUT_RIGHT ) )
408 {
409 // Warp after context menu only if dragging...
410 if( !item )
411 m_toolMgr->VetoContextMenuMouseWarp();
412
413 m_menu->ShowContextMenu( m_selectionTool->GetSelection() );
414 }
415 else if( item && evt->IsAction( &ACTIONS::redo ) )
416 {
417 wxBell();
418 }
419 else
420 {
421 evt->SetPassEvent();
422 }
423
424 // Enable autopanning and cursor capture only when there is a shape being drawn
425 getViewControls()->SetAutoPan( item != nullptr );
426 getViewControls()->CaptureCursor( item != nullptr );
427 }
428
429 getViewControls()->SetAutoPan( false );
430 getViewControls()->CaptureCursor( false );
431 frame()->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
432 return 0;
433}
434
435
437{
438 if( m_inDrawingTool )
439 return 0;
440
441 EDA_ITEM* parent = getDrawParent();
442
443 if( !parent )
444 return 0;
445
447 SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ARC );
448
449 SCH_LAYER_ID shapeLayer = getShapeLayer();
450 std::vector<VECTOR2D> initialPts;
451
452 const auto makeNewArc =
453 [&]()
454 {
455 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC, shapeLayer, 0,
457 arc->SetStroke( m_lastStroke );
458 arc->SetFillColor( m_lastFillColor );
459 arc->SetParent( parent );
460 arc->SetFlags( IS_NEW );
461
463
464 return arc;
465 };
466
467 std::unique_ptr<SCH_SHAPE> arc = makeNewArc();
468
469 arc->SetFlags( IS_NEW );
470
471 TOOL_EVENT originalEvent = aEvent;
472 SCOPED_TOOL_PUSHER raii( m_frame, originalEvent );
473 Activate();
474
475 if( aEvent.HasPosition() )
476 initialPts.push_back( snapEventPosition( aEvent ) );
477
478 ARC_DRAW_BEHAVIOR arcBehavior( schIUScale, frame()->GetUserUnits() );
479
480 APP_SETTINGS_BASE* cfg = frame()->config();
481
482 frame()->SelectToolbarAction( SCH_ACTIONS::DrawArcForMode( StartArcDrawMode( aEvent, cfg, arcBehavior ) ) );
483
484 std::optional<ARC_TANGENT_SEED> tangentSeed;
485 VECTOR2I lastClick;
486
488
490 {
491 result = drawManagedShape( originalEvent, arc, arcBehavior, initialPts, tangentSeed, &lastClick );
492
493 tangentSeed.reset();
494
495 if( arc )
496 {
497 // The mode can change mid-draw so chain from whatever the settings hold now
499 tangentSeed = ArcTangentSeedNear( *arc, lastClick );
500
501 m_lastStroke = arc->GetStroke();
502 m_lastFillStyle = arc->GetFillMode();
503 m_lastFillColor = arc->GetFillColor();
504
505 m_selectionTool->AddItemToSel( arc.get() );
506
507 SCH_COMMIT commit( m_toolMgr );
508 commitItem( commit, std::move( arc ), _( "Draw Arc" ) );
509
511 }
512
513 arc = makeNewArc();
514 initialPts.clear();
515 }
516
517 return 0;
518}
519
520
522{
523 if( m_inDrawingTool )
524 return 0;
525
526 EDA_ITEM* parent = getDrawParent();
527
528 if( !parent )
529 return 0;
530
532 SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ELLIPSE_ARC );
533
534 SCH_LAYER_ID shapeLayer = getShapeLayer();
535 std::vector<VECTOR2D> initialPts;
536
537 const auto makeNewEllipseArc =
538 [&]()
539 {
540 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ELLIPSE_ARC, shapeLayer,
541 0, m_lastFillStyle );
542 arc->SetStroke( m_lastStroke );
543 arc->SetFillColor( m_lastFillColor );
544 arc->SetParent( parent );
545 arc->SetFlags( IS_NEW );
546
548
549 return arc;
550 };
551
552 std::unique_ptr<SCH_SHAPE> arc = makeNewEllipseArc();
553
554 TOOL_EVENT originalEvent = aEvent; // This can change out from under us when the event loop runs
555 SCOPED_TOOL_PUSHER raii( m_frame, originalEvent );
556 Activate();
557
558 if( aEvent.HasPosition() )
559 initialPts.push_back( snapEventPosition( aEvent ) );
560
561 ELLIPSE_ARC_DRAW_BEHAVIOR ellipseBehavior( schIUScale, frame()->GetUserUnits() );
562
564
566 {
567 result = drawManagedShape( originalEvent, arc, ellipseBehavior, initialPts );
568
569 if( arc )
570 {
571 m_lastStroke = arc->GetStroke();
572 m_lastFillStyle = arc->GetFillMode();
573 m_lastFillColor = arc->GetFillColor();
574
575 m_selectionTool->AddItemToSel( arc.get() );
576
577 SCH_COMMIT commit( m_toolMgr );
578 commitItem( commit, std::move( arc ), _( "Draw Elliptical Arc" ) );
579
581 }
582
583 arc = makeNewEllipseArc();
584 initialPts.clear();
585 }
586
587 return 0;
588}
589
590
592{
593 if( m_inDrawingTool )
594 return 0;
595
596 EDA_ITEM* parent = getDrawParent();
597
598 if( !parent )
599 return 0;
600
602 SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::BEZIER );
603
604 SCH_LAYER_ID shapeLayer = getShapeLayer();
605 std::vector<VECTOR2D> initialPts;
606
607 const auto makeNewBezier =
608 [&]()
609 {
610 std::unique_ptr<SCH_SHAPE> bezier = std::make_unique<SCH_SHAPE>( SHAPE_T::BEZIER, shapeLayer, 0,
612 bezier->SetStroke( m_lastStroke );
613 bezier->SetFillColor( m_lastFillColor );
614 bezier->SetParent( parent );
615 bezier->SetFlags( IS_NEW );
616
617 applySymbolEditorFlags( *bezier );
618
619 return bezier;
620 };
621
622 std::unique_ptr<SCH_SHAPE> bezier = makeNewBezier();
623
624 TOOL_EVENT originalEvent = aEvent; // This can change out from under us when the event loop runs
625 SCOPED_TOOL_PUSHER raii( m_frame, originalEvent );
626 Activate();
627
628 if( aEvent.HasPosition() )
629 initialPts.push_back( snapEventPosition( aEvent ) );
630
631 BEZIER_DRAW_BEHAVIOR bezierBehavior( schIUScale, frame()->GetUserUnits() );
632
634
636 {
637 result = drawManagedShape( originalEvent, bezier, bezierBehavior, initialPts );
638
639 if( bezier )
640 {
641 m_lastStroke = bezier->GetStroke();
642 m_lastFillStyle = bezier->GetFillMode();
643 m_lastFillColor = bezier->GetFillColor();
644
645 // Chain: next bezier starts at the end of this one
646 initialPts.clear();
647 initialPts.push_back( bezier->GetEnd() );
648
649 // If the last control arm is non-zero, mirror it for tangent continuity
650 if( bezier->GetEnd() != bezier->GetBezierC2() )
651 {
652 VECTOR2D mirroredC1 = bezier->GetEnd() - ( bezier->GetBezierC2() - bezier->GetEnd() );
653 initialPts.push_back( mirroredC1 );
654 }
655
656 m_selectionTool->AddItemToSel( bezier.get() );
657
658 SCH_COMMIT commit( m_toolMgr );
659 commitItem( commit, std::move( bezier ), _( "Draw Bezier" ) );
660
662 }
663 else
664 {
665 initialPts.clear();
666 }
667
668 bezier = makeNewBezier();
669 }
670
671 return 0;
672}
673
674
676{
678 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() );
679
680 return grid.Align( aEvent.Position(), GRID_HELPER_GRIDS::GRID_GRAPHICS );
681}
682
683
684SHAPE_DRAW_RESULT EE_GRAPHIC_TOOL::drawManagedShape( const TOOL_EVENT& aTool, std::unique_ptr<SCH_SHAPE>& aShape,
685 SHAPE_DRAW_BEHAVIOR& aBehavior,
686 const std::vector<VECTOR2D>& aInitialPts,
687 const std::optional<ARC_TANGENT_SEED>& aTangentSeed,
688 VECTOR2I* aLastClick )
689{
690 if( !aShape )
692
693 aBehavior.Reset();
694
695 SELECTION preview;
698 VECTOR2I cursorPos;
699 EDA_ITEM* parent = getDrawParent();
700
701 m_view->Add( &preview );
702 m_view->Add( &aBehavior.GetAssistant() );
703
704 auto setCursor =
705 [&]()
706 {
707 frame()->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
708 };
709
710 auto cleanup =
711 [&]()
712 {
714 preview.Clear();
715 aShape.reset();
716 };
717
718 // Clicking a graphic on the drawing layer starts a tangent arc from it instead of placing a start point
719 auto findTangentSeed =
720 [&]( const VECTOR2I& aMouse, const VECTOR2I& aPos ) -> std::optional<ARC_TANGENT_SEED>
721 {
722 const int tolerance = KiROUND( getView()->ToWorld( ARC_SEED_PICK_PIXELS ) );
723 const SCH_LAYER_ID layer = getShapeLayer();
724
725 auto seedFrom =
726 [&]( SCH_ITEM* aItem, const VECTOR2I& aPos ) -> std::optional<ARC_TANGENT_SEED>
727 {
728 if( !aItem || aItem->GetLayer() != layer )
729 return std::nullopt;
730
731 BOX2I reach = aItem->GetBoundingBox();
732
733 if( !reach.Inflate( tolerance ).Contains( aPos ) )
734 return std::nullopt;
735
736 if( SCH_SHAPE* shape = dynamic_cast<SCH_SHAPE*>( aItem ) )
737 return ArcTangentSeedAt( *shape, aPos, tolerance );
738
739 if( SCH_LINE* line = dynamic_cast<SCH_LINE*>( aItem ); line && line->IsGraphicLine() )
740 {
741 return ArcTangentSeedAt( SEG( line->GetStartPoint(), line->GetEndPoint() ), aPos,
742 tolerance );
743 }
744
745 return std::nullopt;
746 };
747
748 SNAP_RESULT snap = grid.ResolveSnap( aMouse, GRID_HELPER_GRIDS::GRID_GRAPHICS, aShape.get() );
749
750 if( std::optional<ARC_TANGENT_SEED> seed = seedFrom( grid.GetSnapped(), snap.position ) )
751 return seed;
752
753 if( IsSymbolEditor() )
754 {
756
757 if( LIB_SYMBOL* symbol = symFrame->GetCurSymbol() )
758 {
759 for( SCH_ITEM& item : symbol->GetDrawItems() )
760 {
761 bool inUnit = item.GetUnit() == ALL_UNITS
762 || item.GetUnit() == symFrame->GetUnit();
763 bool inBodyStyle = item.GetBodyStyle() == ALL_BODY_STYLES
764 || item.GetBodyStyle() == symFrame->GetBodyStyle();
765
766 if( !inUnit || !inBodyStyle )
767 continue;
768
769 if( std::optional<ARC_TANGENT_SEED> seed = seedFrom( &item, aPos ) )
770 return seed;
771 }
772 }
773
774 return std::nullopt;
775 }
776
777 for( KICAD_T type : { SCH_SHAPE_T, SCH_LINE_T } )
778 {
779 for( SCH_ITEM* item : frame()->GetScreen()->Items().Overlapping( type, aPos, tolerance ) )
780 {
781 if( std::optional<ARC_TANGENT_SEED> seed = seedFrom( item, aPos ) )
782 return seed;
783 }
784 }
785
786 return std::nullopt;
787 };
788
789 ARC_MODE_SESSION arcSession( aBehavior, frame()->config(), m_mode == MODE::ARC, aTangentSeed, findTangentSeed,
790 [&]( ARC_DRAW_MODE aMode )
791 {
792 frame()->SelectToolbarAction( SCH_ACTIONS::DrawArcForMode( aMode ) );
793 m_toolMgr->PostAction( ACTIONS::refreshPreview );
794 } );
795
796 controls->ShowCursor( true );
797 setCursor();
798
799 bool started = false;
800 bool cancelled = false;
801 bool finished = false;
802
803 m_toolMgr->PostAction( ACTIONS::refreshPreview );
804
805 // Pre-load any initial points into the behaviour, advancing the construction
806 // state machine so that the next user click adds the subsequent point.
807 // The user can still undo these points if they want to change them.
808 for( const VECTOR2D& pt : aInitialPts )
809 arcSession.PlacePoint( pt, pt );
810
811 if( !aInitialPts.empty() || aTangentSeed )
812 {
814
815 controls->SetAutoPan( true );
816 controls->CaptureCursor( true );
817
818 preview.Add( aShape.get() );
819 frame()->SetMsgPanel( aShape.get() );
820
821 started = true;
822 }
823
824 while( TOOL_EVENT* evt = Wait() )
825 {
826 setCursor();
827 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
828 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
829
830 cursorPos = grid.Align( controls->GetMousePosition(), GRID_HELPER_GRIDS::GRID_GRAPHICS );
831 controls->ForceCursorPosition( true, cursorPos );
832
833 if( evt->IsCancelInteractive() )
834 {
835 cleanup();
836
837 if( !started )
838 {
839 evt->SetPassEvent( false );
840 cancelled = true;
841 }
842
843 break;
844 }
845 else if( started && evt->IsAction( &ACTIONS::undo ) )
846 {
847 cleanup();
848 break;
849 }
850 else if( arcSession.HandleModeEvent( *evt ) )
851 {
852 // A mode switch keeps the tool running rather than restarting it
853 }
854 else if( evt->IsActivate() )
855 {
856 if( evt->IsPointEditor() )
857 {
858 // don't exit (the point editor runs in the background)
859 continue;
860 }
861
862 if( evt->IsMoveTool() )
863 {
864 // Make sure we come back after the move tool runs
865 m_frame->PushTool( aTool );
866 }
867
868 cleanup();
869 cancelled = true;
870 break;
871 }
872 else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &ACTIONS::cursorClick ) )
873 {
874 if( !started )
875 {
877
878 controls->SetAutoPan( true );
879 controls->CaptureCursor( true );
880
881 preview.Add( aShape.get() );
882 frame()->SetMsgPanel( aShape.get() );
883 started = true;
884 }
885
886 arcSession.PlacePoint( controls->GetMousePosition(), cursorPos );
887
888 if( aLastClick )
889 *aLastClick = cursorPos;
890 }
891 else if( evt->IsDblClick( BUT_LEFT )
892 || evt->IsAction( &ACTIONS::cursorDblClick )
893 || evt->IsAction( &ACTIONS::finishInteractive ) )
894 {
895 // Keep whatever we have so far, and report that we're finished.
896 if( !started )
897 cleanup();
898
899 finished = true;
900 break;
901 }
902 else if( evt->IsAction( &ACTIONS::arcPosture ) )
903 {
904 aBehavior.ToggleClockwise();
905 }
906 else if( evt->IsAction( &ACTIONS::deleteLastPoint ) || ( started && evt->IsAction( &ACTIONS::doDelete ) ) )
907 {
908 // Backspace is also doDelete's alternate hotkey, so a backup can arrive as either action
909 grid.FullReset();
910
911 arcSession.RemoveLastPoint();
912 }
913 else if( evt->IsMotion() || evt->IsAction( &ACTIONS::refreshPreview ) )
914 {
915 aBehavior.SetCursorPosition( cursorPos );
916 }
917 else if( evt->IsClick( BUT_RIGHT ) )
918 {
919 if( !aShape )
920 m_toolMgr->VetoContextMenuMouseWarp();
921
922 m_menu->ShowContextMenu( m_selectionTool->GetSelection() );
923 }
924 else if( evt->IsAction( &ACTIONS::updateUnits ) )
925 {
926 aBehavior.SetUnits( frame()->GetUserUnits() );
927 m_view->Update( &aBehavior.GetAssistant() );
928 evt->SetPassEvent();
929 }
930 else if( started && evt->IsAction( &ACTIONS::redo ) )
931 {
932 wxBell();
933 }
934 else
935 {
936 evt->SetPassEvent();
937 }
938
939 if( aBehavior.IsComplete() )
940 {
941 break;
942 }
943 else if( aBehavior.HasGeometryChanged() )
944 {
945 aBehavior.ApplyToShape( *aShape );
946 m_view->Update( &preview );
947 m_view->Update( &aBehavior.GetAssistant() );
948 aBehavior.ClearGeometryChanged();
949
950 if( started )
951 frame()->SetMsgPanel( aShape.get() );
952 else
953 frame()->SetMsgPanel( parent );
954 }
955 }
956
957 preview.Remove( aShape.get() );
958 m_view->Remove( &aBehavior.GetAssistant() );
959 m_view->Remove( &preview );
960
961 if( !started )
962 frame()->SetMsgPanel( parent );
963
964 controls->SetAutoPan( false );
965 controls->CaptureCursor( false );
966 controls->ForceCursorPosition( false );
967 frame()->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
968
969 if( cancelled )
970 {
971 aShape.reset();
973 }
974
976}
977
978
980{
981 if( m_inDrawingTool )
982 return 0;
983
984 EDA_ITEM* parent = getDrawParent();
985
986 if( !parent )
987 return 0;
988
989 if( IsSymbolEditor() )
990 {
992
993 if( !symFrame->IsSymbolGraphicallyEditable() )
994 return 0;
995 }
996
998
1000
1001 // Set filename on drag-and-drop
1002 if( aEvent.HasParameter() )
1003 dlg.SetFilenameOverride( *aEvent.Parameter<wxString*>() );
1004
1005 int dlgResult = dlg.ShowModal();
1006
1007 std::list<std::unique_ptr<EDA_ITEM>>& list = dlg.GetImportedItems();
1008
1009 if( dlgResult != wxID_OK )
1010 return 0;
1011
1012 // Ensure the list is not empty:
1013 if( list.empty() )
1014 {
1015 wxMessageBox( _( "No graphic items found in file." ) );
1016 return 0;
1017 }
1018
1020
1022 std::vector<SCH_ITEM*> newItems;
1023 std::vector<SCH_ITEM*> selectedItems;
1024 SCH_SELECTION preview;
1025 SCH_COMMIT commit( m_toolMgr );
1026
1027 auto commitImport =
1028 [&]( const std::vector<SCH_ITEM*>& aItems )
1029 {
1030 if( IsSymbolEditor() )
1031 {
1032 LIB_SYMBOL* symbol = static_cast<LIB_SYMBOL*>( parent );
1033 commit.Modify( symbol, frame()->GetScreen() );
1034
1035 for( SCH_ITEM* item : aItems )
1036 {
1037 symbol->AddDrawItem( item );
1038 item->ClearEditFlags();
1039 }
1040 }
1041 else
1042 {
1043 for( SCH_ITEM* item : aItems )
1044 commit.Add( item, frame()->GetScreen() );
1045 }
1046
1047 commit.Push( _( "Import Graphic" ) );
1048
1049 if( IsSymbolEditor() )
1050 frame<SYMBOL_EDIT_FRAME>()->RebuildView();
1051 };
1052
1053 for( std::unique_ptr<EDA_ITEM>& ptr : list )
1054 {
1055 EDA_ITEM* eda_item = ptr.release();
1056 SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( eda_item );
1057
1058 wxCHECK2_MSG( item, continue, wxString::Format( "Bad item type: ", eda_item->Type() ) );
1059
1060 newItems.push_back( item );
1061 selectedItems.push_back( item );
1062 preview.Add( item );
1063 }
1064
1065 if( !dlg.IsPlacementInteractive() )
1066 {
1067 commitImport( newItems );
1068 return 0;
1069 }
1070
1071 m_view->Add( &preview );
1072
1073 m_toolMgr->RunAction( ACTIONS::selectionClear );
1074
1075 EDA_ITEMS selItems( selectedItems.begin(), selectedItems.end() );
1076 m_toolMgr->RunAction<EDA_ITEMS*>( ACTIONS::selectItems, &selItems );
1077
1078 SCOPED_TOOL_PUSHER raii( frame(), aEvent );
1079
1080 auto setCursor =
1081 [&]()
1082 {
1083 frame()->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING );
1084 };
1085
1086 Activate();
1087 controls->ShowCursor( true );
1088 controls->ForceCursorPosition( false );
1089 setCursor();
1090
1092
1093 VECTOR2I cursorPos = controls->GetCursorPosition( !aEvent.DisableGridSnapping() );
1094 VECTOR2I delta = cursorPos;
1095 VECTOR2I currentOffset;
1096
1097 for( SCH_ITEM* item : selectedItems )
1098 item->Move( delta );
1099
1100 currentOffset += delta;
1101 m_view->Update( &preview );
1102
1103 // Main loop: keep receiving events
1104 while( TOOL_EVENT* evt = Wait() )
1105 {
1106 setCursor();
1107
1108 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
1109 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
1110
1111 cursorPos = grid.Align( controls->GetMousePosition(), GRID_GRAPHICS );
1112 controls->ForceCursorPosition( true, cursorPos );
1113
1114 if( evt->IsCancelInteractive() || evt->IsActivate() )
1115 {
1116 m_toolMgr->RunAction( ACTIONS::selectionClear );
1117
1118 for( SCH_ITEM* item : newItems )
1119 delete item;
1120
1121 break;
1122 }
1123 else if( evt->IsMotion() || evt->IsAction( &ACTIONS::refreshPreview ) )
1124 {
1125 delta = cursorPos - currentOffset;
1126
1127 for( SCH_ITEM* item : selectedItems )
1128 item->Move( delta );
1129
1130 currentOffset += delta;
1131 m_view->Update( &preview );
1132 }
1133 else if( evt->IsClick( BUT_RIGHT ) )
1134 {
1135 m_menu->ShowContextMenu( m_selectionTool->GetSelection() );
1136 }
1137 else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT )
1138 || evt->IsAction( &ACTIONS::cursorClick ) || evt->IsAction( &ACTIONS::cursorDblClick ) )
1139 {
1140 commitImport( newItems );
1141 break;
1142 }
1143 else
1144 {
1145 evt->SetPassEvent();
1146 }
1147 }
1148
1149 preview.Clear();
1150 m_view->Remove( &preview );
1151
1152 frame()->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
1153 controls->ForceCursorPosition( false );
1154
1155 return 0;
1156}
1157
1158
1160{
1161 // clang-format off
1180 // clang-format on
1181}
ARC_DRAW_MODE
Construction sequence used when interactively drawing a circular arc.
@ TANGENT
End only; start and departure direction come from a tangent seed.
ARC_DRAW_MODE StartArcDrawMode(const TOOL_EVENT &aEvent, APP_SETTINGS_BASE *aSettings, SHAPE_DRAW_BEHAVIOR &aBehavior)
Pick the mode a Draw Arc action starts in and apply it to aBehavior.
std::optional< ARC_TANGENT_SEED > ArcTangentSeedNear(const EDA_SHAPE &aShape, const VECTOR2I &aNear)
Seed the next tangent arc from whichever endpoint of aShape lies nearest aNear.
std::optional< ARC_TANGENT_SEED > ArcTangentSeedAt(const SEG &aSegment, const VECTOR2I &aPoint, int aTolerance)
Tangent seed for a point on or near a segment, arc or Bezier shape.
constexpr int ARC_SEED_PICK_PIXELS
Screen distance in pixels within which a click picks a graphic to start a tangent arc from.
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:130
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:982
static TOOL_ACTION paste
Definition actions.h:76
static TOOL_ACTION cancelInteractive
Definition actions.h:68
static TOOL_ACTION arcPosture
Definition actions.h:268
static TOOL_ACTION updateUnits
Definition actions.h:203
static TOOL_ACTION deleteLastPoint
Definition actions.h:270
static TOOL_ACTION cursorDblClick
Definition actions.h:177
static TOOL_ACTION undo
Definition actions.h:71
static TOOL_ACTION duplicate
Definition actions.h:80
static TOOL_ACTION cycleArcDrawMode
Definition actions.h:269
static TOOL_ACTION activatePointEditor
Definition actions.h:267
static TOOL_ACTION doDelete
Definition actions.h:81
static TOOL_ACTION cursorClick
Definition actions.h:176
static TOOL_ACTION redo
Definition actions.h:72
static TOOL_ACTION selectionClear
Clear the current selection.
Definition actions.h:220
static TOOL_ACTION refreshPreview
Definition actions.h:155
static TOOL_ACTION finishInteractive
Definition actions.h:69
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
Definition actions.h:228
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
ARC_DRAW_MODE m_ArcDrawMode
Construction sequence last used by the arc drawing tool in this application.
Interactive arc drawing behaviour.
Arc drawing mode and tangent seed bookkeeping for one pass of an editor's managed-shape draw loop.
Interactive bezier drawing behaviour: start -> control1 -> end -> control2.
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:553
constexpr bool Contains(const Vec &aPoint) const
Definition box2.h:165
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
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Definition commit.h:74
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.
void AddCheckItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Add a checked menu entry to run a TOOL_ACTION on selected items.
void SetFilenameOverride(const wxString &aFilenameOverride)
Set the filename override to be applied in TransferDataToWindow.
std::list< std::unique_ptr< EDA_ITEM > > & GetImportedItems()
int ShowModal() override
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:98
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition eda_item.cpp:270
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
FILL_T GetFillMode() const
Definition eda_shape.h:148
COLOR4D GetFillColor() const
Definition eda_shape.h:159
bool IsItalic() const
Definition eda_text.h:200
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:239
virtual EDA_ANGLE GetTextAngle() const
Definition eda_text.h:178
bool IsBold() const
Definition eda_text.h:215
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition eda_text.h:242
bool Init() override
Init() is called once upon a registration of the tool.
COLOR4D m_lastTextboxFillColor
void applySymbolEditorFlags(SCH_ITEM &aItem) const
When in the symbol editor, apply unit and body-style restrictions to aItem according to the current d...
int getDefaultTextSize() const
Return the default text size (in IU) for the active editor.
int DrawEllipseArc(const TOOL_EVENT &aEvent)
STROKE_PARAMS m_lastStroke
SHAPE_DRAW_RESULT drawManagedShape(const TOOL_EVENT &aTool, std::unique_ptr< SCH_SHAPE > &aShape, SHAPE_DRAW_BEHAVIOR &aBehavior, const std::vector< VECTOR2D > &aInitialPts, const std::optional< ARC_TANGENT_SEED > &aTangentSeed=std::nullopt, VECTOR2I *aLastClick=nullptr)
Run the interactive drawing event loop for any shape driven by a SHAPE_DRAW_BEHAVIOR (arcs,...
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
GR_TEXT_H_ALIGN_T m_lastTextboxHJustify
GR_TEXT_V_ALIGN_T m_lastTextboxVJustify
int DrawArc(const TOOL_EVENT &aEvent)
void commitItem(SCH_COMMIT &aCommit, std::unique_ptr< SCH_ITEM > aItem, const wxString &aDescription)
Commit a completed item.
EDA_ANGLE m_lastTextboxAngle
VECTOR2I snapEventPosition(const TOOL_EVENT &aEvent)
Snap a tool event's position the way a click is snapped.
int DrawBezier(const TOOL_EVENT &aEvent)
int DrawShape(const TOOL_EVENT &aEvent)
STROKE_PARAMS m_lastTextboxStroke
FILL_T m_lastTextboxFillStyle
int ImportGraphics(const TOOL_EVENT &aEvent)
SCH_LAYER_ID getShapeLayer() const
The layer to use for new shapes in the current editor.
Interactive elliptical-arc drawing behaviour: bbox corner 1 -> bbox corner 2 -> start angle -> end an...
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
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.
Define a library symbol object.
Definition lib_symbol.h:114
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
static TOOL_ACTION drawArcCenter
static TOOL_ACTION drawArcStartEndCenter
static TOOL_ACTION drawEllipseArc
static TOOL_ACTION drawTextBox
Definition sch_actions.h:99
static TOOL_ACTION drawArc
static TOOL_ACTION drawSymbolLines
static TOOL_ACTION drawSymbolTextBox
static TOOL_ACTION properties
static TOOL_ACTION ddImportGraphics
static TOOL_ACTION drawRectangle
static TOOL_ACTION drawEllipse
static TOOL_ACTION drawCircle
static TOOL_ACTION importGraphics
static TOOL_ACTION drawArcTangent
static TOOL_ACTION drawBezier
static TOOL_ACTION drawSymbolPolygon
static TOOL_ACTION drawPolygon
static TOOL_ACTION drawArcStartDirEnd
static TOOL_ACTION drawArcStartEndMid
static TOOL_ACTION repeatDrawItem
static const TOOL_ACTION & DrawArcForMode(ARC_DRAW_MODE aMode)
Tool action that starts the arc tool in the given mode.
A shim class between EDA_DRAW_FRAME and several derived classes: SYMBOL_EDIT_FRAME,...
Commit for the schematic and symbol editors.
Definition sch_commit.h:54
void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:170
virtual void SetBodyStyle(int aBodyStyle)
Definition sch_item.h:252
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition sch_item.h:353
virtual void SetUnit(int aUnit)
Definition sch_item.h:242
Segment description base class to describe items which have 2 end points (track, wire,...
Definition sch_line.h:39
bool IsGraphicLine() const
Return if the line is a graphic (non electrical line)
STROKE_PARAMS GetStroke() const override
Definition sch_shape.h:57
bool Init() override
Init() is called once upon a registration of the tool.
SCH_TOOL_BASE(const std::string &aName)
SCH_SELECTION_TOOL * m_selectionTool
RAII class that sets an value at construction and resets it to the original value at destruction.
Definition seg.h:38
virtual void Add(EDA_ITEM *aItem)
A null aItem is ignored; the selection never holds null members.
Definition selection.cpp:38
virtual void Remove(EDA_ITEM *aItem)
Definition selection.cpp:60
virtual void Clear() override
Remove all the stored items from the group.
Definition selection.h:97
Abstract interface for interactive shape-drawing behaviours.
virtual void Reset()=0
Reset the behaviour to its initial state for chained object creation loops.
virtual bool IsComplete() const =0
True when all points have been locked in.
virtual void SetCursorPosition(const VECTOR2I &aPosition)=0
Preview the cursor position without advancing state.
virtual void SetUnits(EDA_UNITS aUnits)=0
Forward a units change to the assistant overlay.
virtual bool HasGeometryChanged() const =0
True if the geometry changed since the last call to ClearGeometryChanged().
virtual EDA_ITEM & GetAssistant()=0
Return the visual assistant overlay item.
virtual void ClearGeometryChanged()=0
Reset the geometry-changed flag (call after updating the preview).
virtual void ApplyToShape(EDA_SHAPE &aShape) const =0
Transfer the current geometry to an EDA_SHAPE.
virtual void ToggleClockwise()
Flip arc direction (applies only when the shape has such a concept of directionality,...
The symbol library editor main window.
bool GetDrawSpecificUnit() const
bool GetDrawSpecificBodyStyle() const
LIB_SYMBOL * GetCurSymbol() const
Return the current symbol being edited or NULL if none selected.
bool IsSymbolGraphicallyEditable() const
Test if a symbol is loaded and can be edited graphically.
SCH_BASE_FRAME * getModel() const
Definition tool_base.h:195
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 HasPosition() const
Returns if it this event has a valid position (true for mouse events and context-menu or hotkey-based...
Definition tool_event.h:256
bool DisableGridSnapping() const
Definition tool_event.h:367
bool HasParameter() const
Definition tool_event.h:460
const VECTOR2D Position() const
Return mouse cursor position in world coordinates.
Definition tool_event.h:289
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
T Parameter() const
Return a parameter assigned to the event.
Definition tool_event.h:484
void Go(int(SCH_BASE_FRAME::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
std::unique_ptr< TOOL_MENU > m_menu
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
@ MOVING
Definition cursors.h:44
@ ARROW
Definition cursors.h:42
@ PENCIL
Definition cursors.h:48
#define DEFAULT_TEXT_SIZE
The default text size in mils. (can be changed in preference menu)
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:448
FILL_T
Definition eda_fill.h:29
@ NO_FILL
Definition eda_fill.h:30
#define IS_NEW
New item, just created.
SHAPE_T
Definition eda_shape.h:54
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Definition eda_shape.h:57
@ ELLIPSE_ARC
Definition eda_shape.h:63
SCOPED_SET_RESET< EE_GRAPHIC_TOOL::MODE > SCOPED_DRAW_MODE
@ GRID_GRAPHICS
Definition grid_helper.h:63
SCH_LAYER_ID
Eeschema drawing layers.
Definition layer_ids.h:471
@ LAYER_DEVICE
Definition layer_ids.h:488
@ LAYER_NOTES
Definition layer_ids.h:489
std::vector< EDA_ITEM * > EDA_ITEMS
SHAPE_DRAW_RESULT
Outcome of an interactive shape drawing loop, telling the caller how to continue.
@ NEXT_SHAPE
Commit the shape, if any, and start drawing another.
@ FINISHED
The user finished; commit the shape, if any, and stop drawing.
@ CANCELLED
The user cancelled; nothing to commit, stop drawing.
LINE_STYLE
Dashed line types.
VECTOR2I position
#define ALL_UNITS
Definition symbol.h:150
#define ALL_BODY_STYLES
Definition symbol.h:151
wxString result
Test unit parsing edge cases and error handling.
int delta
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_V_ALIGN_TOP
@ MD_SHIFT
Definition tool_event.h:139
@ BUT_LEFT
Definition tool_event.h:128
@ BUT_RIGHT
Definition tool_event.h:129
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:70
@ SCH_LINE_T
Definition typeinfo.h:159
@ SCH_SHAPE_T
Definition typeinfo.h:145
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708
VECTOR2< double > VECTOR2D
Definition vector2d.h:707