KiCad PCB EDA Suite
Loading...
Searching...
No Matches
symbol_editor_drawing_tools.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2019 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <sch_actions.h>
22#include <optional>
23#include <symbol_edit_frame.h>
24#include <widgets/wx_infobar.h>
25#include <sch_commit.h>
30#include <dialogs/dialog_text_properties.h>
31#include <sch_shape.h>
32#include <sch_textbox.h>
33#include <pgm_base.h>
34#include <view/view_controls.h>
37#include <string_utils.h>
38#include <wx/msgdlg.h>
40
41
43
44
61
62
64{
66
67 auto isDrawingCondition =
68 [] ( const SELECTION& aSel )
69 {
70 SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aSel.Front() );
71 return item && item->IsNew();
72 };
73
74 m_menu->GetMenu().AddItem( ACTIONS::finishInteractive, isDrawingCondition, 2 );
75
76 return true;
77}
78
79
81{
82 KICAD_T type = aEvent.Parameter<KICAD_T>();
85 : nullptr;
86
88 return 0;
89
91
94 VECTOR2I cursorPos;
95 bool ignorePrimePosition = false;
96 SCH_ITEM* item = nullptr;
97 bool isText = aEvent.IsAction( &SCH_ACTIONS::placeSymbolText );
98 COMMON_SETTINGS* common_settings = Pgm().GetCommonSettings();
99
101
102 m_frame->PushTool( aEvent );
103
104 auto setCursor =
105 [&]()
106 {
107 if( item )
108 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PLACE );
109 else if( isText )
110 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::TEXT );
111 else
112 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
113 };
114
115 auto cleanup =
116 [&] ()
117 {
119 m_view->ClearPreview();
120 delete item;
121 item = nullptr;
122 };
123
124 Activate();
125 // Must be done after Activate() so that it gets set into the correct context
126 controls->ShowCursor( true );
127 // Set initial cursor
128 setCursor();
129
130 if( aEvent.HasPosition() )
131 {
132 m_toolMgr->PrimeTool( aEvent.Position() );
133 }
134 else if( common_settings->m_Input.immediate_actions && !aEvent.IsReactivate() )
135 {
136 m_toolMgr->PrimeTool( { 0, 0 } );
137 ignorePrimePosition = true;
138 }
139
140 SCH_COMMIT commit( m_toolMgr );
141
142 // Main loop: keep receiving events
143 while( TOOL_EVENT* evt = Wait() )
144 {
145 setCursor();
146 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
147 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
148
149 cursorPos = grid.Align( controls->GetMousePosition(), grid.GetItemGrid( item ) );
150 controls->ForceCursorPosition( true, cursorPos );
151
152 // The tool hotkey is interpreted as a click when drawing
153 bool isSyntheticClick = item && evt->IsActivate() && evt->HasPosition()
154 && evt->Matches( aEvent );
155
156 if( evt->IsCancelInteractive() )
157 {
158 m_frame->GetInfoBar()->Dismiss();
159
160 if( item )
161 {
162 cleanup();
163 }
164 else
165 {
166 m_frame->PopTool( aEvent );
167 break;
168 }
169 }
170 else if( evt->IsActivate() && !isSyntheticClick )
171 {
172 if( item && evt->IsMoveTool() )
173 {
174 // we're already moving our own item; ignore the move tool
175 evt->SetPassEvent( false );
176 continue;
177 }
178
179 if( item )
180 {
181 m_frame->ShowInfoBarMsg( _( "Press <ESC> to cancel item creation." ) );
182 evt->SetPassEvent( false );
183 continue;
184 }
185
186 if( evt->IsPointEditor() )
187 {
188 // don't exit (the point editor runs in the background)
189 }
190 else if( evt->IsMoveTool() )
191 {
192 break;
193 }
194 else
195 {
196 m_frame->PopTool( aEvent );
197 break;
198 }
199 }
200 else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) || isSyntheticClick )
201 {
202 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
203
204 if( !symbol )
205 continue;
206
207 // First click creates...
208 if( !item )
209 {
211
212 switch( type )
213 {
214 case SCH_PIN_T:
215 item = pinTool->CreatePin( cursorPos, symbol );
216
217 if( item )
218 g_lastPin = item->m_Uuid;
219
220 break;
221
222 case SCH_TEXT_T:
223 {
224 SCH_TEXT* text = new SCH_TEXT( cursorPos, wxEmptyString, LAYER_DEVICE );
225
226 text->SetParent( symbol );
227
229 text->SetUnit( m_frame->GetUnit() );
230
232 text->SetBodyStyle( m_frame->GetBodyStyle() );
233
234 if( cfg )
235 {
236 text->SetTextSize( VECTOR2I( schIUScale.MilsToIU( cfg->m_Defaults.text_size ),
237 schIUScale.MilsToIU( cfg->m_Defaults.text_size ) ) );
238 }
239
240 text->SetTextAngle( m_lastTextAngle );
241
243
244 if( dlg.ShowModal() != wxID_OK || NoPrintableChars( text->GetText() ) )
245 delete text;
246 else
247 item = text;
248
249 break;
250 }
251
252 default:
253 wxFAIL_MSG( "TwoClickPlace(): unknown type" );
254 }
255
256 // If we started with a hotkey which has a position then warp back to that.
257 // Otherwise update to the current mouse position pinned inside the autoscroll
258 // boundaries.
259 if( evt->IsPrime() && !ignorePrimePosition )
260 {
261 cursorPos = grid.Align( evt->Position(), grid.GetItemGrid( item ) );
262 getViewControls()->WarpMouseCursor( cursorPos, true );
263 }
264 else
265 {
267 cursorPos = grid.Align( getViewControls()->GetMousePosition(), grid.GetItemGrid( item ) );
268 }
269
270 if( item )
271 {
272 item->SetPosition( VECTOR2I( cursorPos.x, -cursorPos.y ) );
273
274 item->SetFlags( IS_NEW | IS_MOVING );
275 m_view->ClearPreview();
276 m_view->AddToPreview( item, false );
277 m_selectionTool->AddItemToSel( item );
278
279 // update the cursor so it looks correct before another event
280 setCursor();
281 }
282
283 if( m_frame->GetMoveWarpsCursor() )
284 controls->SetCursorPosition( cursorPos, false );
285
286 m_toolMgr->PostAction( ACTIONS::refreshPreview );
287 }
288 // ... and second click places:
289 else
290 {
291 commit.Modify( symbol, m_frame->GetScreen() );
292
293 switch( item->Type() )
294 {
295 case SCH_PIN_T:
296 pinTool->PlacePin( &commit, static_cast<SCH_PIN*>( item ) );
297 item->ClearEditFlags();
298 commit.Push( _( "Place Pin" ) );
299 break;
300
301 case SCH_TEXT_T:
302 symbol->AddDrawItem( static_cast<SCH_TEXT*>( item ) );
303 item->ClearEditFlags();
304 commit.Push( _( "Draw Text" ) );
305 break;
306
307 default:
308 wxFAIL_MSG( "TwoClickPlace(): unknown type" );
309 }
310
311 item = nullptr;
312 m_view->ClearPreview();
313 m_frame->RebuildView();
314 }
315 }
316 else if( evt->IsClick( BUT_RIGHT ) )
317 {
318 // Warp after context menu only if dragging...
319 if( !item )
320 m_toolMgr->VetoContextMenuMouseWarp();
321
322 m_menu->ShowContextMenu( m_selectionTool->GetSelection() );
323 }
324 else if( evt->IsAction( &ACTIONS::increment ) )
325 {
326 if( evt->HasParameter() )
327 m_toolMgr->RunSynchronousAction( ACTIONS::increment, &commit, evt->Parameter<ACTIONS::INCREMENT>() );
328 else
329 m_toolMgr->RunSynchronousAction( ACTIONS::increment, &commit, ACTIONS::INCREMENT { 1, 0 } );
330 }
331 else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
332 {
333 item->SetPosition( VECTOR2I( cursorPos.x, cursorPos.y ) );
334 m_view->ClearPreview();
335 m_view->AddToPreview( item, false );
336 }
337 else
338 {
339 evt->SetPassEvent();
340 }
341
342 // Enable autopanning and cursor capture only when there is an item to be placed
343 controls->SetAutoPan( item != nullptr );
344 controls->CaptureCursor( item != nullptr );
345 }
346
347 controls->SetAutoPan( false );
348 controls->CaptureCursor( false );
349 controls->ForceCursorPosition( false );
350 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
351 return 0;
352}
353
354
356{
357 SHAPE_T requestedShape = aEvent.Parameter<SHAPE_T>();
358
359 return doDrawShape( aEvent, requestedShape );
360}
361
362
364{
365 return doDrawShape( aEvent, std::nullopt /* Draw text box */ );
366}
367
368
369int SYMBOL_EDITOR_DRAWING_TOOLS::doDrawShape( const TOOL_EVENT& aEvent, std::optional<SHAPE_T> aDrawingShape )
370{
371 bool isTextBox = !aDrawingShape.has_value();
372 SHAPE_T toolType = aDrawingShape.value_or( SHAPE_T::SEGMENT );
373
377 VECTOR2I cursorPos;
378 SHAPE_T shapeType = toolType == SHAPE_T::SEGMENT ? SHAPE_T::POLY : toolType;
379 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
380 SCH_SHAPE* item = nullptr;
381 wxString description;
382
383 if( m_inDrawShape )
384 return 0;
385
387
388 // We might be running as the same shape in another co-routine. Make sure that one
389 // gets whacked.
390 m_toolMgr->DeactivateTool();
391
393
394 m_frame->PushTool( aEvent );
395
396 auto setCursor =
397 [&]()
398 {
399 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
400 };
401
402 auto cleanup =
403 [&] ()
404 {
406 m_view->ClearPreview();
407 delete item;
408 item = nullptr;
409 };
410
411 Activate();
412 // Must be done after Activate() so that it gets set into the correct context
413 controls->ShowCursor( true );
414 // Set initial cursor
415 setCursor();
416
417 if( aEvent.HasPosition() )
418 m_toolMgr->PrimeTool( aEvent.Position() );
419
420 // Main loop: keep receiving events
421 while( TOOL_EVENT* evt = Wait() )
422 {
423 setCursor();
424 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
425 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
426
427 cursorPos = grid.Align( controls->GetMousePosition(), grid.GetItemGrid( item ) );
428 controls->ForceCursorPosition( true, cursorPos );
429
430 // The tool hotkey is interpreted as a click when drawing
431 bool isSyntheticClick = item && evt->IsActivate() && evt->HasPosition()
432 && evt->Matches( aEvent );
433
434 if( evt->IsCancelInteractive() )
435 {
436 if( item )
437 {
438 cleanup();
439 }
440 else
441 {
442 m_frame->PopTool( aEvent );
443 break;
444 }
445 }
446 else if( evt->IsActivate() && !isSyntheticClick )
447 {
448 if( item )
449 cleanup();
450
451 if( evt->IsPointEditor() )
452 {
453 // don't exit (the point editor runs in the background)
454 }
455 else if( evt->IsMoveTool() )
456 {
457 // leave ourselves on the stack so we come back after the move
458 break;
459 }
460 else
461 {
462 m_frame->PopTool( aEvent );
463 break;
464 }
465 }
466 else if( evt->IsClick( BUT_LEFT ) && !item )
467 {
468 // Update in case the symbol was changed while the tool was running
469 symbol = m_frame->GetCurSymbol();
470
471 if( !symbol )
472 continue;
473
475
476 int lineWidth = schIUScale.MilsToIU( cfg ? cfg->m_Defaults.line_width : DEFAULT_LINE_WIDTH_MILS );
477
478 if( isTextBox )
479 {
480 SCH_TEXTBOX* textbox = new SCH_TEXTBOX( LAYER_DEVICE, lineWidth, m_lastFillStyle );
481
482 textbox->SetParent( symbol );
483
484 if( cfg )
485 {
486 textbox->SetTextSize( VECTOR2I( schIUScale.MilsToIU( cfg->m_Defaults.text_size ),
487 schIUScale.MilsToIU( cfg->m_Defaults.text_size ) ) );
488 }
489
490 // Must be after SetTextSize()
491 textbox->SetBold( m_lastTextBold );
492 textbox->SetItalic( m_lastTextItalic );
493
494 textbox->SetTextAngle( m_lastTextAngle );
496
497 item = textbox;
498 description = _( "Add Text Box" );
499 }
500 else
501 {
502 item = new SCH_SHAPE( shapeType, LAYER_DEVICE, lineWidth, m_lastFillStyle );
503 item->SetParent( symbol );
504 description = wxString::Format( _( "Add %s" ), item->GetFriendlyName() );
505 }
506
507 item->SetStroke( m_lastStroke );
509
510 item->SetFlags( IS_NEW );
511 item->BeginEdit( cursorPos );
512
514 item->SetUnit( m_frame->GetUnit() );
515
517 item->SetBodyStyle( m_frame->GetBodyStyle() );
518
519 m_selectionTool->AddItemToSel( item );
520 }
521 else if( item && ( evt->IsClick( BUT_LEFT )
522 || evt->IsDblClick( BUT_LEFT )
523 || isSyntheticClick
524 || evt->IsAction( &ACTIONS::finishInteractive ) ) )
525 {
526 if( symbol != m_frame->GetCurSymbol() )
527 {
528 symbol = m_frame->GetCurSymbol();
529 item->SetParent( symbol );
530 }
531
532 if( evt->IsDblClick( BUT_LEFT ) || evt->IsAction( &ACTIONS::finishInteractive )
533 || !item->ContinueEdit( VECTOR2I( cursorPos.x, cursorPos.y ) ) )
534 {
535 if( toolType == SHAPE_T::POLY )
536 {
537 item->CalcEdit( item->GetPosition() ); // Close shape
538 item->EndEdit( true );
539 }
540 else
541 {
542 item->EndEdit();
543 }
544
545 item->ClearEditFlags();
546
547 if( isTextBox )
548 {
549 SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( item );
550 DIALOG_TEXT_PROPERTIES dlg( m_frame, static_cast<SCH_TEXTBOX*>( item ) );
551
552 // QuasiModal required for syntax help and Scintilla auto-complete
553 if( dlg.ShowQuasiModal() != wxID_OK )
554 {
555 cleanup();
556 continue;
557 }
558
559 m_lastTextBold = textbox->IsBold();
560 m_lastTextItalic = textbox->IsItalic();
561 m_lastTextAngle = textbox->GetTextAngle();
562 m_lastTextJust = textbox->GetHorizJustify();
563 }
564
565 m_lastStroke = item->GetStroke();
568
569 m_view->ClearPreview();
570
571 SCH_COMMIT commit( m_toolMgr );
572 commit.Modify( symbol, m_frame->GetScreen() );
573
574 symbol->AddDrawItem( item );
575 item = nullptr;
576
577 commit.Push( description );
578 m_frame->RebuildView();
580 }
581 }
582 else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
583 {
584 item->CalcEdit( cursorPos );
585 m_view->ClearPreview();
586 m_view->AddToPreview( item->Clone() );
587 }
588 else if( evt->IsDblClick( BUT_LEFT ) && !item )
589 {
591 }
592 else if( evt->IsClick( BUT_RIGHT ) )
593 {
594 // Warp after context menu only if dragging...
595 if( !item )
596 m_toolMgr->VetoContextMenuMouseWarp();
597
598 m_menu->ShowContextMenu( m_selectionTool->GetSelection() );
599 }
600 else
601 {
602 evt->SetPassEvent();
603 }
604
605 // Enable autopanning and cursor capture only when there is a shape being drawn
606 controls->SetAutoPan( item != nullptr );
607 controls->CaptureCursor( item != nullptr );
608 }
609
610 controls->SetAutoPan( false );
611 controls->CaptureCursor( false );
612 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
613 return 0;
614}
615
616
618{
619 if( m_inPlaceAnchor )
620 return 0;
621
623
624 m_frame->PushTool( aEvent );
625
626 auto setCursor =
627 [&]()
628 {
629 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::BULLSEYE );
630 };
631
632 Activate();
633 // Must be done after Activate() so that it gets set into the correct context
634 getViewControls()->ShowCursor( true );
635 // Set initial cursor
636 setCursor();
637
638 // Main loop: keep receiving events
639 while( TOOL_EVENT* evt = Wait() )
640 {
641 setCursor();
642
643 if( evt->IsCancelInteractive() )
644 {
645 m_frame->PopTool( aEvent );
646 break;
647 }
648 else if( evt->IsActivate() )
649 {
650 m_frame->PopTool( aEvent );
651 break;
652 }
653 else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
654 {
655 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
656
657 if( !symbol )
658 continue;
659
660 VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() );
661
662 symbol->Move( -cursorPos );
663
664 // Refresh the view without changing the viewport
665 m_view->SetCenter( m_view->GetCenter() + cursorPos );
666 m_view->RecacheAllItems();
667 m_frame->OnModify();
668 }
669 else if( evt->IsClick( BUT_RIGHT ) )
670 {
671 m_menu->ShowContextMenu( m_selectionTool->GetSelection() );
672 }
673 else
674 {
675 evt->SetPassEvent();
676 }
677 }
678
679 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
680 return 0;
681}
682
683
685{
686 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
687
688 if( !symbol )
689 return 0;
690
691 // Note: PlaceImportedGraphics() will convert PCB_SHAPE_T and PCB_TEXT_T to footprint
692 // items if needed
694 int dlgResult = dlg.ShowModal();
695
696 std::list<std::unique_ptr<EDA_ITEM>>& list = dlg.GetImportedItems();
697
698 if( dlgResult != wxID_OK )
699 return 0;
700
701 // Ensure the list is not empty:
702 if( list.empty() )
703 {
704 wxMessageBox( _( "No graphic items found in file." ) );
705 return 0;
706 }
707
709
711 std::vector<SCH_ITEM*> newItems; // all new items, including group
712 std::vector<SCH_ITEM*> selectedItems; // the group, or newItems if no group
713 SCH_SELECTION preview;
714 SCH_COMMIT commit( m_toolMgr );
715
716 for( std::unique_ptr<EDA_ITEM>& ptr : list )
717 {
718 SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( ptr.get() );
719 wxCHECK2( item, continue );
720
721 newItems.push_back( item );
722 selectedItems.push_back( item );
723 preview.Add( item );
724
725 ptr.release();
726 }
727
728 if( !dlg.IsPlacementInteractive() )
729 {
730 commit.Modify( symbol, m_frame->GetScreen() );
731
732 // Place the imported drawings
733 for( SCH_ITEM* item : newItems )
734 {
735 symbol->AddDrawItem( item );
736 item->ClearEditFlags();
737 }
738
739 commit.Push( _( "Import Graphic" ) );
740 m_frame->RebuildView();
741
742 return 0;
743 }
744
745 m_view->Add( &preview );
746
747 // Clear the current selection then select the drawings so that edit tools work on them
749
750 EDA_ITEMS selItems( selectedItems.begin(), selectedItems.end() );
751 m_toolMgr->RunAction<EDA_ITEMS*>( ACTIONS::selectItems, &selItems );
752
753 m_frame->PushTool( aEvent );
754
755 auto setCursor = [&]()
756 {
757 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING );
758 };
759
760 Activate();
761 // Must be done after Activate() so that it gets set into the correct context
762 controls->ShowCursor( true );
763 controls->ForceCursorPosition( false );
764 // Set initial cursor
765 setCursor();
766
767 //SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::DXF );
769
770 // Now move the new items to the current cursor position:
771 VECTOR2I cursorPos = controls->GetCursorPosition( !aEvent.DisableGridSnapping() );
772 VECTOR2I delta = cursorPos;
773 VECTOR2I currentOffset;
774
775 for( SCH_ITEM* item : selectedItems )
776 item->Move( delta );
777
778 currentOffset += delta;
779
780 m_view->Update( &preview );
781
782 // Main loop: keep receiving events
783 while( TOOL_EVENT* evt = Wait() )
784 {
785 setCursor();
786
787 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
788 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
789
790 cursorPos = grid.Align( controls->GetMousePosition(), GRID_GRAPHICS );
791 controls->ForceCursorPosition( true, cursorPos );
792
793 if( evt->IsCancelInteractive() || evt->IsActivate() )
794 {
796
797 for( SCH_ITEM* item : newItems )
798 delete item;
799
800 break;
801 }
802 else if( evt->IsMotion() )
803 {
804 delta = cursorPos - currentOffset;
805
806 for( SCH_ITEM* item : selectedItems )
807 item->Move( delta );
808
809 currentOffset += delta;
810
811 m_view->Update( &preview );
812 }
813 else if( evt->IsClick( BUT_RIGHT ) )
814 {
815 m_menu->ShowContextMenu( m_selectionTool->GetSelection() );
816 }
817 else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
818 {
819 commit.Modify( symbol, m_frame->GetScreen() );
820
821 // Place the imported drawings
822 for( SCH_ITEM* item : newItems )
823 {
824 symbol->AddDrawItem( item );
825 item->ClearEditFlags();
826 }
827
828 commit.Push( _( "Import Graphic" ) );
829 break; // This is a one-shot command, not a tool
830 }
831 else
832 {
833 evt->SetPassEvent();
834 }
835 }
836
837 preview.Clear();
838 m_view->Remove( &preview );
839
840 m_frame->RebuildView();
841
842 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
843 controls->ForceCursorPosition( false );
844
845 m_frame->PopTool( aEvent );
846
847 return 0;
848}
849
850
852{
854 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
855 SCH_PIN* sourcePin = nullptr;
856
857 if( !symbol )
858 return 0;
859
860 for( SCH_PIN* test : symbol->GetPins() )
861 {
862 if( test->m_Uuid == g_lastPin )
863 {
864 sourcePin = test;
865 break;
866 }
867 }
868
869 if( sourcePin )
870 {
871 SCH_PIN* pin = pinTool->RepeatPin( sourcePin );
872
873 if( pin )
874 g_lastPin = pin->m_Uuid;
875
877
878 if( pin )
879 m_toolMgr->RunAction<EDA_ITEM*>( ACTIONS::selectItem, pin );
880 }
881
882 return 0;
883}
884
885
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:123
static TOOL_ACTION cancelInteractive
Definition actions.h:68
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
Definition actions.h:223
static TOOL_ACTION activatePointEditor
Definition actions.h:267
static TOOL_ACTION increment
Definition actions.h:90
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
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
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:96
virtual void ClearEditFlags()
Definition eda_item.h:166
virtual void SetPosition(const VECTOR2I &aPos)
Definition eda_item.h:283
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition eda_item.h:152
const KIID m_Uuid
Definition eda_item.h:531
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:108
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition eda_item.h:416
virtual wxString GetFriendlyName() const
Definition eda_item.cpp:426
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:89
bool IsNew() const
Definition eda_item.h:129
FILL_T GetFillMode() const
Definition eda_shape.h:158
void SetFillColor(const COLOR4D &aColor)
Definition eda_shape.h:170
COLOR4D GetFillColor() const
Definition eda_shape.h:169
bool IsItalic() const
Definition eda_text.h:190
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition eda_text.cpp:532
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:221
virtual EDA_ANGLE GetTextAngle() const
Definition eda_text.h:168
void SetBold(bool aBold)
Set the text to be bold - this will also update the font if needed.
Definition eda_text.cpp:330
bool IsBold() const
Definition eda_text.h:205
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition eda_text.cpp:294
void SetItalic(bool aItalic)
Set the text to be italic - this will also update the font if needed.
Definition eda_text.cpp:302
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition eda_text.cpp:404
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.
virtual void WarpMouseCursor(const VECTOR2D &aPosition, bool aWorldCoordinates=false, bool aWarpView=false)=0
If enabled (.
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 SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true, bool aTriggeredByArrows=false, long aArrowCommand=0)=0
Move cursor to the requested position expressed in world coordinates.
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
virtual void PinCursorInsideNonAutoscrollArea(bool aWarpMouseCursor)=0
Definition kiid.h:44
Define a library symbol object.
Definition lib_symbol.h:79
void Move(const VECTOR2I &aOffset) override
Move the symbol aOffset.
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:528
static TOOL_ACTION drawEllipseArc
Definition sch_actions.h:94
static TOOL_ACTION drawArc
Definition sch_actions.h:95
static TOOL_ACTION drawSymbolLines
static TOOL_ACTION placeSymbolPin
static TOOL_ACTION drawSymbolTextBox
static TOOL_ACTION properties
static TOOL_ACTION drawRectangle
Definition sch_actions.h:91
static TOOL_ACTION drawEllipse
Definition sch_actions.h:93
static TOOL_ACTION drawCircle
Definition sch_actions.h:92
static TOOL_ACTION importGraphics
static TOOL_ACTION drawBezier
Definition sch_actions.h:96
static TOOL_ACTION drawSymbolPolygon
static TOOL_ACTION placeSymbolAnchor
static TOOL_ACTION placeSymbolText
static TOOL_ACTION repeatDrawItem
virtual void Push(const wxString &aMessage=wxT("A commit"), 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:162
virtual void SetBodyStyle(int aBodyStyle)
Definition sch_item.h:241
virtual void SetUnit(int aUnit)
Definition sch_item.h:232
void BeginEdit(const VECTOR2I &aStartPoint) override
Begin drawing a symbol library draw item at aPosition.
Definition sch_shape.h:94
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition sch_shape.cpp:49
void EndEdit(bool aClosed=false) override
End an object editing action.
Definition sch_shape.h:97
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition sch_shape.cpp:98
bool ContinueEdit(const VECTOR2I &aPosition) override
Continue an edit in progress at aPosition.
Definition sch_shape.h:95
void CalcEdit(const VECTOR2I &aPosition) override
Calculate the attributes of an item at aPosition when it is being edited.
Definition sch_shape.h:96
STROKE_PARAMS GetStroke() const override
Definition sch_shape.h:57
VECTOR2I GetPosition() const override
Definition sch_shape.h:84
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
virtual void Add(EDA_ITEM *aItem)
Definition selection.cpp:38
virtual void Clear() override
Remove all the stored items from the group.
Definition selection.h:94
int PlaceAnchor(const TOOL_EVENT &aEvent)
bool Init() override
Init() is called once upon a registration of the tool.
bool m_drawSpecificUnit
Re-entrancy guards.
int RepeatDrawItem(const TOOL_EVENT &aEvent)
int doDrawShape(const TOOL_EVENT &aEvent, std::optional< SHAPE_T > aDrawingShape)
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
int ImportGraphics(const TOOL_EVENT &aEvent)
int DrawShape(const TOOL_EVENT &aEvent)
int DrawSymbolTextBox(const TOOL_EVENT &aEvent)
int TwoClickPlace(const TOOL_EVENT &aEvent)
SCH_PIN * RepeatPin(const SCH_PIN *aSourcePin)
SCH_PIN * CreatePin(const VECTOR2I &aPosition, LIB_SYMBOL *aSymbol)
bool PlacePin(SCH_COMMIT *aCommit, SCH_PIN *aPin)
The symbol library editor main window.
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
const VECTOR2D Position() const
Return mouse cursor position in world coordinates.
Definition tool_event.h:289
bool IsReactivate() const
Control whether the tool is first being pushed to the stack or being reactivated after a pause.
Definition tool_event.h:269
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:469
void Go(int(SYMBOL_EDIT_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))
@ PLACE
Definition cursors.h:94
@ MOVING
Definition cursors.h:44
@ ARROW
Definition cursors.h:42
@ BULLSEYE
Definition cursors.h:54
@ PENCIL
Definition cursors.h:48
#define DEFAULT_LINE_WIDTH_MILS
The default wire width in mils. (can be changed in preference menu)
#define _(s)
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition eda_angle.h:407
#define IS_NEW
New item, just created.
#define IS_MOVING
Item being moved.
SHAPE_T
Definition eda_shape.h:44
@ SEGMENT
Definition eda_shape.h:46
FILL_T
Definition eda_shape.h:59
@ NO_FILL
Definition eda_shape.h:60
@ GRID_GRAPHICS
Definition grid_helper.h:48
@ LAYER_DEVICE
Definition layer_ids.h:464
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
std::vector< EDA_ITEM * > EDA_ITEMS
T * GetAppSettings(const char *aFilename)
bool NoPrintableChars(const wxString &aString)
Return true if the string is empty or contains only whitespace.
LINE_STYLE
Dashed line types.
KIBIS_PIN * pin
int delta
@ GR_TEXT_H_ALIGN_LEFT
@ 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:71
@ SCH_TEXT_T
Definition typeinfo.h:148
@ SCH_PIN_T
Definition typeinfo.h:150
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683