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