KiCad PCB EDA Suite
Loading...
Searching...
No Matches
action_toolbar.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 CHANGELOG.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 <algorithm>
26#include <advanced_config.h>
27#include <bitmaps.h>
28#include <bitmap_store.h>
29#include <eda_draw_frame.h>
30#include <functional>
31#include <kiplatform/ui.h>
32#include <math/util.h>
33#include <memory>
34#include <pgm_base.h>
36#include <trace_helpers.h>
37#include <tool/action_toolbar.h>
38#include <tool/actions.h>
39#include <tool/tool_action.h>
40#include <tool/tool_event.h>
42#include <tool/tool_manager.h>
47
48#include <wx/log.h>
49#include <wx/popupwin.h>
50#include <wx/renderer.h>
51#include <wx/sizer.h>
52#include <wx/dcclient.h>
53#include <wx/settings.h>
54
55// Needed to handle adding the plugins to the toolbar
56// TODO (ISM): This should be better abstracted away from the toolbars
57#include <python_scripting.h>
59
60
61ACTION_GROUP::ACTION_GROUP( const std::string_view& aName )
62{
63 m_name = aName;
65 m_defaultAction = nullptr;
66}
67
68
69ACTION_GROUP::ACTION_GROUP( const std::string_view& aName,
70 const std::vector<const TOOL_ACTION*>& aActions )
71{
72 m_name = aName;
74
75 SetActions( aActions );
76}
77
78
79void ACTION_GROUP::SetActions( const std::vector<const TOOL_ACTION*>& aActions )
80{
81 wxASSERT_MSG( aActions.size() > 0, wxS( "Action groups must have at least one action" ) );
82
83 // The default action is just the first action in the vector
84 m_actions = aActions;
86}
87
89{
91}
92
93
95{
96 bool valid = std::any_of( m_actions.begin(), m_actions.end(),
97 [&]( const TOOL_ACTION* aAction ) -> bool
98 {
99 // For some reason, we can't compare the actions directly
100 return aAction->GetId() == aDefault.GetId();
101 } );
102
103 wxASSERT_MSG( valid, wxS( "Action must be present in a group to be the default" ) );
104
105 m_defaultAction = &aDefault;
106}
107
108
109#define PALETTE_BORDER FromDIP( 4 ) // The border around the palette buttons on all sides
110#define BUTTON_BORDER FromDIP( 1 ) // The border on the sides of the buttons that touch other buttons
111
112
113ACTION_TOOLBAR_PALETTE::ACTION_TOOLBAR_PALETTE( wxWindow* aParent, bool aVertical ) :
114 wxPopupTransientWindow( aParent, wxBORDER_NONE ),
115 m_group( nullptr ),
116 m_isVertical( aVertical ),
117 m_panel( nullptr ),
118 m_mainSizer( nullptr ),
119 m_buttonSizer( nullptr )
120{
121 m_panel = new wxPanel( this, wxID_ANY );
122 m_panel->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
123
124 // This sizer holds the buttons for the actions
125 m_buttonSizer = new wxBoxSizer( aVertical ? wxVERTICAL : wxHORIZONTAL );
126
127 // This sizer holds the other sizer, so that a consistent border is present on all sides
128 m_mainSizer = new wxBoxSizer( aVertical ? wxVERTICAL : wxHORIZONTAL );
129 m_mainSizer->Add( m_buttonSizer, wxSizerFlags().Border( wxALL, PALETTE_BORDER ) );
130
131 m_panel->SetSizer( m_mainSizer );
132
133 Connect( wxEVT_CHAR_HOOK, wxCharEventHandler( ACTION_TOOLBAR_PALETTE::onCharHook ), nullptr, this );
134}
135
136
138{
140 wxBitmapBundle normalBmp = KiBitmapBundleDef( aAction.GetIcon(), iconSize );
141 int paddingDip = ( ToDIP( m_buttonSize.GetWidth() ) - iconSize ) / 2;
142
143 BITMAP_BUTTON* button = new BITMAP_BUTTON( m_panel, aAction.GetUIId() );
144
145 button->SetIsToolbarButton();
146 button->SetBitmap( normalBmp );
147 button->SetDisabledBitmap( KiDisabledBitmapBundleDef( aAction.GetIcon(), iconSize ) );
148 button->SetPadding( paddingDip );
149 button->SetToolTip( aAction.GetButtonTooltip() );
150 button->AcceptDragInAsClick();
151 button->SetBitmapCentered();
152
153 m_buttons[aAction.GetUIId()] = button;
154
155 if( m_isVertical )
156 m_buttonSizer->Add( button, wxSizerFlags().Border( wxTOP | wxBOTTOM, BUTTON_BORDER ) );
157 else
158 m_buttonSizer->Add( button, wxSizerFlags().Border( wxLEFT | wxRIGHT, BUTTON_BORDER ) );
159
160 m_buttonSizer->Layout();
161}
162
163
164void ACTION_TOOLBAR_PALETTE::EnableAction( const TOOL_ACTION& aAction, bool aEnable )
165{
166 auto it = m_buttons.find( aAction.GetUIId() );
167
168 if( it != m_buttons.end() )
169 it->second->Enable( aEnable );
170}
171
172
173void ACTION_TOOLBAR_PALETTE::CheckAction( const TOOL_ACTION& aAction, bool aCheck )
174{
175 auto it = m_buttons.find( aAction.GetUIId() );
176
177 if( it != m_buttons.end() )
178 it->second->Check( aCheck );
179}
180
181
182void ACTION_TOOLBAR_PALETTE::Popup( wxWindow* aFocus )
183{
184 m_mainSizer->Fit( m_panel );
185 SetClientSize( m_panel->GetSize() );
186
187 wxPopupTransientWindow::Popup( aFocus );
188}
189
190
191void ACTION_TOOLBAR_PALETTE::onCharHook( wxKeyEvent& aEvent )
192{
193 // Allow the escape key to dismiss this popup
194 if( aEvent.GetKeyCode() == WXK_ESCAPE )
195 Dismiss();
196 else
197 aEvent.Skip();
198}
199
200
201ACTION_TOOLBAR::ACTION_TOOLBAR( EDA_BASE_FRAME* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
202 long style ) :
203 wxAuiToolBar( parent, id, pos, size, style ),
204 m_parent( parent ),
205 m_paletteTimer( nullptr ),
206 m_auiManager( nullptr ),
207 m_toolManager( parent->GetToolManager() ),
208 m_palette( nullptr )
209{
210 m_paletteTimer = new wxTimer( this );
211
212 SetArtProvider( new WX_AUI_TOOLBAR_ART );
213
214 Connect( wxEVT_COMMAND_TOOL_CLICKED, wxAuiToolBarEventHandler( ACTION_TOOLBAR::onToolEvent ), nullptr, this );
215 Connect( wxEVT_AUITOOLBAR_RIGHT_CLICK, wxAuiToolBarEventHandler( ACTION_TOOLBAR::onRightClick ), nullptr, this );
216 Connect( wxEVT_AUITOOLBAR_BEGIN_DRAG, wxAuiToolBarEventHandler( ACTION_TOOLBAR::onItemDrag ), nullptr, this );
217 Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( ACTION_TOOLBAR::onMouseClick ), nullptr, this );
218 Connect( wxEVT_LEFT_UP, wxMouseEventHandler( ACTION_TOOLBAR::onMouseClick ), nullptr, this );
219 Connect( m_paletteTimer->GetId(), wxEVT_TIMER, wxTimerEventHandler( ACTION_TOOLBAR::onTimerDone ), nullptr, this );
220
221 Bind( wxEVT_SIZE,
222 [&]( wxSizeEvent& aEvent )
223 {
224 CallAfter(
225 [&]()
226 {
227 SetOverflowVisible( !GetToolBarFits() );
228 } );
229
230 aEvent.Skip();
231 } );
232
233 Bind( wxEVT_SYS_COLOUR_CHANGED, wxSysColourChangedEventHandler( ACTION_TOOLBAR::onThemeChanged ), this );
234
235 Bind( wxEVT_DPI_CHANGED,
236 [&]( wxDPIChangedEvent& aEvent )
237 {
238#ifdef __WXMSW__
239 // Update values which are normally only initialized in wxAuiToolBar::Create
240 // FromDIP is no-op on backends other than wxMSW
241 m_toolPacking = FromDIP( 2 );
242 m_toolBorderPadding = FromDIP( 3 );
243
244 wxSize margin_lt = FromDIP( wxSize( 5, 5 ) );
245 wxSize margin_rb = FromDIP( wxSize( 2, 2 ) );
246 SetMargins( margin_lt.x, margin_lt.y, margin_rb.x, margin_rb.y );
247#endif
248
249 aEvent.Skip();
250 } );
251}
252
253
255{
256 Disconnect( wxEVT_COMMAND_TOOL_CLICKED, wxAuiToolBarEventHandler( ACTION_TOOLBAR::onToolEvent ), nullptr, this );
257 Disconnect( wxEVT_AUITOOLBAR_RIGHT_CLICK, wxAuiToolBarEventHandler( ACTION_TOOLBAR::onRightClick ), nullptr, this );
258 Disconnect( wxEVT_AUITOOLBAR_BEGIN_DRAG, wxAuiToolBarEventHandler( ACTION_TOOLBAR::onItemDrag ), nullptr, this );
259 Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( ACTION_TOOLBAR::onMouseClick ), nullptr, this );
260 Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( ACTION_TOOLBAR::onMouseClick ), nullptr, this );
261 Disconnect( m_paletteTimer->GetId(), wxEVT_TIMER, wxTimerEventHandler( ACTION_TOOLBAR::onTimerDone ), nullptr,
262 this );
263
264 Unbind( wxEVT_SYS_COLOUR_CHANGED, wxSysColourChangedEventHandler( ACTION_TOOLBAR::onThemeChanged ), this );
265
266 delete m_paletteTimer;
267
268 // Clear all the maps keeping track of our items on the toolbar
269 m_toolMenus.clear();
270 m_actionGroups.clear();
271 m_toolCancellable.clear();
272 m_toolKinds.clear();
273 m_toolActions.clear();
274}
275
276
277std::list<ACTION_TOOLBAR_CONTROL*> ACTION_TOOLBAR::GetCustomControlList( FRAME_T aContext )
278{
279 std::list<ACTION_TOOLBAR_CONTROL*> controls;
280
282 {
283 if( control->SupportedFor( aContext ) )
284 controls.push_back( control );
285 }
286
287 return controls;
288}
289
290
292{
293 wxASSERT( GetParent() );
294
295 std::map<std::string, std::string> currentGroupItems;
296
297 for( const auto& [id, group] : m_actionGroups )
298 {
299 if( m_toolActions[group->GetUIId()] )
300 currentGroupItems[group->GetName()] = m_toolActions[group->GetUIId()]->GetName();
301 }
302
303 // Remove existing tools
304 ClearToolbar();
305
306 std::vector<TOOLBAR_ITEM> items = aConfig.GetToolbarItems();
307
308 // Add all the items to the toolbar
309 for( auto& item : items )
310 {
311 switch( item.m_Type )
312 {
314 AddScaledSeparator( GetParent() );
315 break;
316
318 AddSpacer( item.m_Size );
319 break;
320
322 {
323 // Add a group of items to the toolbar
324 std::string groupName = item.m_GroupName.ToStdString();
325 std::vector<const TOOL_ACTION*> tools;
326 const TOOL_ACTION* defaultTool = nullptr;
327
328 for( TOOLBAR_ITEM& groupItem : item.m_GroupItems )
329 {
330 switch( groupItem.m_Type )
331 {
336 wxFAIL_MSG( wxT( "Unsupported group item type" ) );
337 continue;
338
340 TOOL_ACTION* grpAction = m_toolManager->GetActionManager()->FindAction( groupItem.m_ActionName );
341
342 if( !grpAction )
343 {
344 wxFAIL_MSG( wxString::Format( wxT( "Unable to find group tool %s" ), groupItem.m_ActionName ) );
345 continue;
346 }
347
348 tools.push_back( grpAction );
349
350 if( currentGroupItems[groupName] == groupItem.m_ActionName )
351 defaultTool = grpAction;
352 }
353 }
354
355 std::unique_ptr<ACTION_GROUP> group = std::make_unique<ACTION_GROUP>( groupName, tools );
356
357 if( defaultTool )
358 group->SetDefaultAction( *defaultTool );
359
360 AddGroup( std::move( group ) );
361
362 // Look up and attach context menu if one is registered for this group
363 auto menuFactory = TOOLBAR_CONTEXT_MENU_REGISTRY::GetGroupMenuFactory( groupName );
364
365 if( menuFactory && m_toolManager )
366 {
367 // Register the menu for each action in the group
368 for( const TOOL_ACTION* grpAction : tools )
369 AddToolContextMenu( *grpAction, menuFactory( m_toolManager ) );
370 }
371
372 break;
373 }
374
376 {
377 // Add a custom control to the toolbar
378 EDA_BASE_FRAME* frame = static_cast<EDA_BASE_FRAME*>( GetParent() );
379 ACTION_TOOLBAR_CONTROL_FACTORY* factory = frame->GetCustomToolbarControlFactory( item.m_ControlName );
380
381 if( !factory )
382 {
383 wxFAIL_MSG( wxString::Format( wxT( "Unable to find control factory for %s" ), item.m_ControlName ) );
384 continue;
385 }
386
387 // The factory functions are responsible for adding the controls to the toolbar themselves
388 (*factory)( this );
389 break;
390 }
391
393 {
394 TOOL_ACTION* action = m_toolManager->GetActionManager()->FindAction( item.m_ActionName );
395
396 if( !action )
397 {
398 wxFAIL_MSG( wxString::Format( wxT( "Unable to find toolbar tool %s" ), item.m_ActionName ) );
399 continue;
400 }
401
402 Add( *action );
403
404 // Look up and attach context menu if one is registered for this action
405 auto factory = TOOLBAR_CONTEXT_MENU_REGISTRY::GetMenuFactory( item.m_ActionName );
406
407 if( factory && m_toolManager )
408 AddToolContextMenu( *action, factory( m_toolManager ) );
409
410 break;
411 }
412 }
413 }
414
415 // Apply the configuration
416 KiRealize();
417}
418
419
420void ACTION_TOOLBAR::DoSetToolTipText( const wxString& aTip )
421{
422 // We use \t in short description to align accelerators in wxMenuItem
423 // But they should be converted when displaying tooltips
424 wxString tip = aTip;
425 tip.Replace( "\t", " " );
426
427 wxAuiToolBar::DoSetToolTipText( tip );
428}
429
430
431void ACTION_TOOLBAR::Add( const TOOL_ACTION& aAction )
432{
433 wxASSERT_MSG( !aAction.CheckToolbarState( TOOLBAR_STATE::HIDDEN ),
434 wxString::Format( "Attempting to add hidden action %s to the toolbar", aAction.GetName() ) );
435
436 bool isToggleEntry = aAction.CheckToolbarState( TOOLBAR_STATE::TOGGLE );
437 bool isCancellable = aAction.CheckToolbarState( TOOLBAR_STATE::CANCEL );
438
439 Add( aAction, isToggleEntry, isCancellable );
440}
441
442
443void ACTION_TOOLBAR::Add( const TOOL_ACTION& aAction, bool aIsToggleEntry, bool aIsCancellable )
444{
445 wxASSERT( GetParent() );
446 wxASSERT_MSG( !( aIsCancellable && !aIsToggleEntry ),
447 wxS( "aIsCancellable requires aIsToggleEntry" ) );
448
449 int toolId = aAction.GetUIId();
451
452 AddTool( toolId, wxEmptyString,
453 KiBitmapBundleDef( aAction.GetIcon(), iconSize ),
454 KiDisabledBitmapBundleDef( aAction.GetIcon(), iconSize ),
455 aIsToggleEntry ? wxITEM_CHECK : wxITEM_NORMAL,
456 aAction.GetButtonTooltip(), wxEmptyString, nullptr );
457
458 m_toolKinds[ toolId ] = aIsToggleEntry;
459 m_toolActions[ toolId ] = &aAction;
460 m_toolCancellable[ toolId ] = aIsCancellable;
461}
462
463
465{
466 int toolId = aAction.GetUIId();
468
469 AddTool( toolId, wxEmptyString,
470 KiBitmapBundleDef( aAction.GetIcon(), iconSize ),
471 KiDisabledBitmapBundleDef( aAction.GetIcon(), iconSize ),
472 wxITEM_NORMAL, aAction.GetButtonTooltip(), wxEmptyString, nullptr );
473
474 m_toolKinds[ toolId ] = false;
475 m_toolActions[ toolId ] = &aAction;
476}
477
478
479void ACTION_TOOLBAR::AddScaledSeparator( wxWindow* aWindow )
480{
481 int scale = KiIconScale( aWindow );
482
483 if( scale > 4 )
484 AddSpacer( 16 * ( scale - 4 ) / 4 );
485
486 AddSeparator();
487
488 if( scale > 4 )
489 AddSpacer( 16 * ( scale - 4 ) / 4 );
490}
491
492
493void ACTION_TOOLBAR::Add( wxControl* aControl, const wxString& aLabel )
494{
495 wxASSERT( aControl );
496 m_controlIDs.push_back( aControl->GetId() );
497 AddControl( aControl, aLabel );
498}
499
500
501void ACTION_TOOLBAR::AddToolContextMenu( const TOOL_ACTION& aAction, std::unique_ptr<ACTION_MENU> aMenu )
502{
503 int toolId = aAction.GetUIId();
504
505 m_toolMenus[toolId] = std::move( aMenu );
506}
507
508
509void ACTION_TOOLBAR::AddGroup( std::unique_ptr<ACTION_GROUP> aGroup )
510{
511 int groupId = aGroup->GetUIId();
512 const TOOL_ACTION* defaultAction = aGroup->GetDefaultAction();
514
515 wxASSERT( GetParent() );
516 wxASSERT( defaultAction );
517
518 // Turn this into a toggle entry if any one of the actions is a toggle entry
519 bool isToggleEntry = false;
520
521 for( const auto& act : aGroup->GetActions() )
522 isToggleEntry |= act->CheckToolbarState( TOOLBAR_STATE::TOGGLE );
523
524
525 m_toolKinds[ groupId ] = isToggleEntry;
526 m_toolActions[ groupId ] = defaultAction;
527 m_actionGroups[ groupId ] = std::move( aGroup );
528
529 // Add the main toolbar item representing the group
530 AddTool( groupId, wxEmptyString,
531 KiBitmapBundleDef( defaultAction->GetIcon(), iconSize ),
532 KiDisabledBitmapBundleDef( defaultAction->GetIcon(), iconSize ),
533 isToggleEntry ? wxITEM_CHECK : wxITEM_NORMAL, wxEmptyString, wxEmptyString, nullptr );
534
535 // Select the default action
536 doSelectAction( m_actionGroups[ groupId ].get(), *defaultAction );
537}
538
539
541{
542 bool valid = std::any_of( aGroup->m_actions.begin(), aGroup->m_actions.end(),
543 [&]( const TOOL_ACTION* action2 ) -> bool
544 {
545 // For some reason, we can't compare the actions directly
546 return aAction.GetId() == action2->GetId();
547 } );
548
549 if( valid )
550 doSelectAction( aGroup, aAction );
551}
552
553
555{
556 // Find the group that contains this action and select it
557 for( auto& [id, groupPtr] : m_actionGroups )
558 {
559 ACTION_GROUP* group = groupPtr.get();
560
561 bool inGroup = std::any_of( group->m_actions.begin(), group->m_actions.end(),
562 [&]( const TOOL_ACTION* action2 )
563 {
564 return aAction.GetId() == action2->GetId();
565 } );
566
567 if( inGroup )
568 {
569 doSelectAction( group, aAction );
570 break;
571 }
572 }
573}
574
575
577{
578 wxASSERT( GetParent() );
579
580 int groupId = aGroup->GetUIId();
581
582 wxAuiToolBarItem* item = FindTool( groupId );
583
584 if( !item )
585 return;
586
588
589 // Update the item information
590 item->SetShortHelp( aAction.GetButtonTooltip() );
591 item->SetBitmap( KiBitmapBundleDef( aAction.GetIcon(), iconSize ) );
592 item->SetDisabledBitmap( KiDisabledBitmapBundleDef( aAction.GetIcon(), iconSize ) );
593
594 // Register a new handler with the new UI conditions
595 if( m_toolManager )
596 {
597 m_toolManager->GetToolHolder()->UnregisterUIUpdateHandler( groupId );
598
599 const ACTION_CONDITIONS* cond = m_toolManager->GetActionManager()->GetCondition( aAction );
600
601 // Register the new UI condition to control this entry
602 if( cond )
603 {
604 m_toolManager->GetToolHolder()->RegisterUIUpdateHandler( groupId, *cond );
605 }
606 else
607 {
608 wxLogTrace( kicadTraceToolStack, wxString::Format( "No UI condition for action %s",
609 aAction.GetName() ) );
610 }
611 }
612
613 // Update the currently selected action
614 m_toolActions[ groupId ] = &aAction;
615
616 Refresh();
617}
618
619
621{
622 for( int id : m_controlIDs )
623 UpdateControlWidth( id );
624}
625
626
628{
629 wxAuiToolBarItem* item = FindTool( aID );
630 wxASSERT_MSG( item, wxString::Format( "No toolbar item found for ID %d", aID ) );
631
632 // The control on the toolbar is stored inside the window field of the item
633 wxControl* control = dynamic_cast<wxControl*>( item->GetWindow() );
634 wxASSERT_MSG( control, wxString::Format( "No control located in toolbar item with ID %d", aID ) );
635
636 // Update the size the item has stored using the best size of the control
637 control->InvalidateBestSize();
638 wxSize bestSize = control->GetBestSize();
639 item->SetMinSize( bestSize );
640
641 // Update the sizer item sizes
642 // This is a bit convoluted because there are actually 2 sizers that need to be updated:
643 // 1. The main sizer that is used for the entire toolbar (this sizer item can be found in the
644 // toolbar item)
645 if( wxSizerItem* szrItem = item->GetSizerItem() )
646 szrItem->SetMinSize( bestSize );
647
648 // 2. The controls have a second sizer that allows for padding above/below the control with
649 // stretch space, so we also need to update the sizer item for the control in that sizer with
650 // the new size. We let wx do the search for us, since SetItemMinSize is recursive and will
651 // locate the control on that sizer.
652 if( m_sizer )
653 {
654 m_sizer->SetItemMinSize( control, bestSize );
655
656 // Now actually update the toolbar with the new sizes
657 m_sizer->Layout();
658 }
659}
660
661
663{
664 // Clear all the maps keeping track of our items on the toolbar
665 m_toolMenus.clear();
666 m_actionGroups.clear();
667 m_toolCancellable.clear();
668 m_toolKinds.clear();
669 m_toolActions.clear();
670
671 for( int id : m_controlIDs )
672 {
673 m_parent->ClearToolbarControl( id );
674 DestroyTool( id );
675 }
676
677 m_controlIDs.clear();
678
679 // Remove the actual tools from the toolbar
680 Clear();
681}
682
683
684void ACTION_TOOLBAR::SetToolBitmap( const TOOL_ACTION& aAction, const wxBitmapBundle& aBitmap )
685{
686 int toolId = aAction.GetUIId();
687
688 // Set the disabled bitmap: we use the disabled bitmap version of aBitmap.
689 wxAuiToolBarItem* tb_item = wxAuiToolBar::FindTool( toolId );
690
691 if( !tb_item )
692 return;
693
694 wxBitmap bm = aBitmap.GetBitmapFor( this );
695
696 tb_item->SetBitmap( aBitmap );
697 tb_item->SetDisabledBitmap( bm.ConvertToDisabled( KIPLATFORM::UI::IsDarkTheme() ? 70 : 255 ) );
698}
699
700
701void ACTION_TOOLBAR::Toggle( const TOOL_ACTION& aAction, bool aState )
702{
703 int toolId = aAction.GetUIId();
704
705 if( m_toolKinds[ toolId ] )
706 ToggleTool( toolId, aState );
707 else
708 EnableTool( toolId, aState );
709}
710
711
712void ACTION_TOOLBAR::Toggle( const TOOL_ACTION& aAction, bool aEnabled, bool aChecked )
713{
714 int toolId = aAction.GetUIId();
715
716 EnableTool( toolId, aEnabled );
717 ToggleTool( toolId, aEnabled && aChecked );
718}
719
720
721void ACTION_TOOLBAR::onToolEvent( wxAuiToolBarEvent& aEvent )
722{
723 int id = aEvent.GetId();
724 wxEventType type = aEvent.GetEventType();
725 OPT_TOOL_EVENT evt;
726
727 bool handled = false;
728
729 if( m_toolManager && type == wxEVT_COMMAND_TOOL_CLICKED && id >= TOOL_ACTION::GetBaseUIId() )
730 {
731 const auto actionIt = m_toolActions.find( id );
732
733 // The toolbar item is toggled before the event is sent, so we check for it not being
734 // toggled to see if it was toggled originally
735 if( m_toolCancellable[id] && !GetToolToggled( id ) )
736 {
737 // Send a cancel event
738 m_toolManager->CancelTool();
739 handled = true;
740 }
741 else if( actionIt != m_toolActions.end() )
742 {
743 // Dispatch a tool event
744 evt = actionIt->second->MakeEvent();
745 evt->SetHasPosition( false );
746 m_toolManager->ProcessEvent( *evt );
747 m_toolManager->GetToolHolder()->RefreshCanvas();
748 handled = true;
749 }
750 }
751
752 // Skip the event if we don't handle it
753 if( !handled )
754 aEvent.Skip();
755}
756
757
758void ACTION_TOOLBAR::onRightClick( wxAuiToolBarEvent& aEvent )
759{
760 int toolId = aEvent.GetToolId();
761
762 // This means the event was not on a button
763 if( toolId == -1 )
764 return;
765
766 // Ensure that the ID maps to a proper tool ID. If right-clicked on a group item, this is needed
767 // to get the ID of the currently selected action, since the event's ID is that of the group.
768 const auto actionIt = m_toolActions.find( toolId );
769
770 if( actionIt != m_toolActions.end() )
771 toolId = actionIt->second->GetUIId();
772
773 // Find the menu for the action
774 const auto menuIt = m_toolMenus.find( toolId );
775
776 if( menuIt == m_toolMenus.end() )
777 return;
778
779 // Update and show the menu
780 std::unique_ptr<ACTION_MENU>& owningMenu = menuIt->second;
781
782 // Get the actual menu pointer to show it
783 ACTION_MENU* menu = owningMenu.get();
784 SELECTION dummySel;
785
786 if( CONDITIONAL_MENU* condMenu = dynamic_cast<CONDITIONAL_MENU*>( menu ) )
787 condMenu->Evaluate( dummySel );
788
789 menu->UpdateAll();
790 PopupMenu( menu );
791
792 // Remove hovered item when the menu closes, otherwise it remains hovered even if the
793 // mouse is not on the toolbar
794 SetHoverItem( nullptr );
795}
796
797
798// The time (in milliseconds) between pressing the left mouse button and opening the palette
799#define PALETTE_OPEN_DELAY 500
800
801
802void ACTION_TOOLBAR::onMouseClick( wxMouseEvent& aEvent )
803{
804 wxAuiToolBarItem* item = FindToolByPosition( aEvent.GetX(), aEvent.GetY() );
805
806 if( item )
807 {
808 // Ensure there is no active palette
809 if( m_palette )
810 {
811 m_palette->Hide();
812 m_palette->Destroy();
813 m_palette = nullptr;
814 }
815
816 // Start the popup conditions if it is a left mouse click and the tool clicked is a group
817 if( aEvent.LeftDown() && ( m_actionGroups.find( item->GetId() ) != m_actionGroups.end() ) )
819
820 // Clear the popup conditions if it is a left up, because that implies a click happened
821 if( aEvent.LeftUp() )
822 m_paletteTimer->Stop();
823 }
824
825 // Skip the event so wx can continue processing the mouse event
826 aEvent.Skip();
827}
828
829
830void ACTION_TOOLBAR::onItemDrag( wxAuiToolBarEvent& aEvent )
831{
832 int toolId = aEvent.GetToolId();
833
834 if( m_actionGroups.find( toolId ) != m_actionGroups.end() )
835 {
836 wxAuiToolBarItem* item = FindTool( toolId );
837
838 // Use call after because opening the palette from a mouse handler
839 // creates a weird mouse state that causes problems on OSX.
840 CallAfter( &ACTION_TOOLBAR::popupPalette, item );
841
842 // Don't skip this event since we are handling it
843 return;
844 }
845
846 // Skip since we don't care about it
847 aEvent.Skip();
848}
849
850
851void ACTION_TOOLBAR::onTimerDone( wxTimerEvent& aEvent )
852{
853 // We need to search for the tool using the client coordinates
854 wxPoint mousePos = ScreenToClient( KIPLATFORM::UI::GetMousePosition() );
855
856 wxAuiToolBarItem* item = FindToolByPosition( mousePos.x, mousePos.y );
857
858 if( item )
859 popupPalette( item );
860}
861
862
863void ACTION_TOOLBAR::onPaletteEvent( wxCommandEvent& aEvent )
864{
865 if( !m_palette )
866 return;
867
868 OPT_TOOL_EVENT evt;
869 ACTION_GROUP* group = m_palette->GetGroup();
870
871 // Find the action corresponding to the button press
872 auto actionIt = std::find_if( group->GetActions().begin(), group->GetActions().end(),
873 [&]( const TOOL_ACTION* aAction )
874 {
875 return aAction->GetUIId() == aEvent.GetId();
876 } );
877
878 if( actionIt != group->GetActions().end() )
879 {
880 const TOOL_ACTION* action = *actionIt;
881
882 // Dispatch a tool event
883 evt = action->MakeEvent();
884 evt->SetHasPosition( false );
885 m_toolManager->ProcessEvent( *evt );
886 m_toolManager->GetToolHolder()->RefreshCanvas();
887
888 // Update the main toolbar item with the selected action
889 doSelectAction( group, *action );
890 }
891
892 // Hide the palette
893 m_palette->Hide();
894 m_palette->Destroy();
895 m_palette = nullptr;
896}
897
898
899void ACTION_TOOLBAR::popupPalette( wxAuiToolBarItem* aItem )
900{
901 // Clear all popup conditions
902 m_paletteTimer->Stop();
903
904 wxWindow* toolParent = dynamic_cast<wxWindow*>( m_toolManager->GetToolHolder() );
905
906 wxCHECK( GetParent() && m_auiManager && toolParent, /* void */ );
907
908 // Ensure the item we are using for the palette has a group associated with it.
909 const auto it = m_actionGroups.find( aItem->GetId() );
910
911 if( it == m_actionGroups.end() )
912 return;
913
914 ACTION_GROUP* group = it->second.get();
915
916 wxAuiPaneInfo& pane = m_auiManager->GetPane( this );
917
918 // We use the size of the toolbar items for our palette buttons
919 wxRect toolRect = GetToolRect( aItem->GetId() );
920
921 // The position for the palette window must be in screen coordinates
922 wxPoint pos( ClientToScreen( toolRect.GetPosition() ) );
923
924 // True for vertical buttons, false for horizontal
925 bool dir = true;
926 size_t numActions = group->m_actions.size();
927
928 // The size of the palette in the long dimension
929 int paletteLongDim = ( 2 * PALETTE_BORDER ) // The border on all sides of the buttons
930 + ( BUTTON_BORDER ) // The border on the start of the buttons
931 + ( numActions * BUTTON_BORDER ) // The other button borders
932 + ( numActions * toolRect.GetHeight() ); // The size of the buttons
933
934 // Determine the position of the top left corner of the palette window
935 switch( pane.dock_direction )
936 {
937 case wxAUI_DOCK_TOP:
938 // Top toolbars need to shift the palette window down by the toolbar padding
939 dir = true; // Buttons are vertical in the palette
940 pos = ClientToScreen( toolRect.GetBottomLeft() );
941 pos += wxPoint( -PALETTE_BORDER, // Shift left to align the button edges
942 m_bottomPadding ); // Shift down to move away from the toolbar
943 break;
944
945 case wxAUI_DOCK_BOTTOM:
946 // Bottom toolbars need to shift the palette window up by its height (all buttons +
947 // border + toolbar padding)
948 dir = true; // Buttons are vertical in the palette
949 pos = ClientToScreen( toolRect.GetTopLeft() );
950 pos += wxPoint( -PALETTE_BORDER, // Shift left to align the button
951 // Shift up by the entire length of the palette.
952 -( paletteLongDim + m_topPadding ) );
953 break;
954
955 case wxAUI_DOCK_LEFT:
956 // Left toolbars need to shift the palette window up by the toolbar padding
957 dir = false; // Buttons are horizontal in the palette
958 pos = ClientToScreen( toolRect.GetTopRight() );
959 pos += wxPoint( m_rightPadding, // Shift right to move away from the toolbar
960 -( PALETTE_BORDER ) ); // Shift up to align the button tops
961 break;
962
963 case wxAUI_DOCK_RIGHT:
964 // Right toolbars need to shift the palette window left by its width (all buttons +
965 // border + toolbar padding)
966 dir = false; // Buttons are horizontal in the palette
967 pos = ClientToScreen( toolRect.GetTopLeft() );
968
969 // Shift left by the entire length of the palette.
970 pos += wxPoint( -( paletteLongDim + m_leftPadding ),
971 -( PALETTE_BORDER ) ); // Shift up to align the button
972 break;
973 }
974
975 m_palette = new ACTION_TOOLBAR_PALETTE( GetParent(), dir );
976
977 // We handle the button events in the toolbar class, so connect the right handler
978 m_palette->SetGroup( group );
979 m_palette->SetButtonSize( toolRect );
980 m_palette->Connect( wxEVT_BUTTON, wxCommandEventHandler( ACTION_TOOLBAR::onPaletteEvent ), nullptr, this );
981
982
983 // Add the actions in the group to the palette and update their enabled state
984 // We purposely don't check items in the palette
985 for( const TOOL_ACTION* action : group->m_actions )
986 {
987 wxUpdateUIEvent evt( action->GetUIId() );
988
989 toolParent->ProcessWindowEvent( evt );
990
991 m_palette->AddAction( *action );
992
993 if( evt.GetSetEnabled() )
994 m_palette->EnableAction( *action, evt.GetEnabled() );
995 }
996
997 // Release the mouse to ensure the first click will be recognized in the palette
998 ReleaseMouse();
999
1000 m_palette->SetPosition( pos );
1001 m_palette->Popup();
1002
1003 // Clear the mouse state on the toolbar because otherwise wxWidgets gets confused
1004 // and won't properly display any highlighted items after the palette is closed.
1005 // (This is the equivalent of calling the DoResetMouseState() private function)
1006 RefreshOverflowState();
1007 SetHoverItem( nullptr );
1008 SetPressedItem( nullptr );
1009
1010 m_dragging = false;
1011 m_tipItem = nullptr;
1012 m_actionPos = wxPoint( -1, -1 );
1013 m_actionItem = nullptr;
1014}
1015
1016
1017void ACTION_TOOLBAR::OnCustomRender(wxDC& aDc, const wxAuiToolBarItem& aItem, const wxRect& aRect )
1018{
1019 auto it = m_actionGroups.find( aItem.GetId() );
1020
1021 if( it == m_actionGroups.end() )
1022 return;
1023
1024 // Choose the color to draw the triangle
1025 wxColour clr;
1026
1027 if( aItem.GetState() & wxAUI_BUTTON_STATE_DISABLED )
1028 clr = wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT );
1029 else
1030 clr = wxSystemSettings::GetColour( wxSYS_COLOUR_BTNTEXT );
1031
1032 // Must set both the pen (for the outline) and the brush (for the polygon fill)
1033 aDc.SetPen( wxPen( clr ) );
1034 aDc.SetBrush( wxBrush( clr ) );
1035
1036 // Make the side length of the triangle approximately 1/5th of the bitmap
1037 int sideLength = KiROUND( aRect.height / 5.0 );
1038
1039 // This will create a triangle with its point at the bottom right corner,
1040 // and its other two corners along the right and bottom sides
1041 wxPoint btmRight = aRect.GetBottomRight();
1042 wxPoint topCorner( btmRight.x, btmRight.y - sideLength );
1043 wxPoint btmCorner( btmRight.x - sideLength, btmRight.y );
1044
1045 wxPointList points;
1046 points.Append( &btmRight );
1047 points.Append( &topCorner );
1048 points.Append( &btmCorner );
1049
1050 aDc.DrawPolygon( &points );
1051}
1052
1053
1055{
1056#if wxCHECK_VERSION( 3, 3, 0 )
1057 return Realize();
1058#else
1059 wxClientDC dc( this );
1060
1061 if( !dc.IsOk() )
1062 return false;
1063
1064 // calculate hint sizes for both horizontal and vertical
1065 // in the order that leaves toolbar in correct final state
1066
1067 // however, skip calculating alternate orientations if we don't need them due to window style
1068 bool retval = true;
1069
1070 if( m_orientation == wxHORIZONTAL )
1071 {
1072 if( !( GetWindowStyle() & wxAUI_TB_HORIZONTAL ) )
1073 {
1074 m_vertHintSize = GetSize();
1075 retval = RealizeHelper( dc, false );
1076 }
1077
1078 if( retval && RealizeHelper( dc, true ) )
1079 m_horzHintSize = GetSize();
1080 else
1081 retval = false;
1082 }
1083 else
1084 {
1085 if( !( GetWindowStyle() & wxAUI_TB_VERTICAL ) )
1086 {
1087 m_horzHintSize = GetSize();
1088 retval = RealizeHelper( dc, true );
1089 }
1090
1091 if( retval && RealizeHelper( dc, false ) )
1092 m_vertHintSize = GetSize();
1093 else
1094 retval = false;
1095 }
1096
1097 Refresh( false );
1098 return retval;
1099#endif
1100}
1101
1102
1103void ACTION_TOOLBAR::onThemeChanged( wxSysColourChangedEvent &aEvent )
1104{
1107
1108 aEvent.Skip();
1109}
1110
1111
1113{
1115
1116 for( const std::pair<int, const TOOL_ACTION*> pair : m_toolActions )
1117 {
1118 wxAuiToolBarItem* tool = FindTool( pair.first );
1119
1120 tool->SetBitmap( KiBitmapBundleDef( pair.second->GetIcon(), iconSize ) );
1121 tool->SetDisabledBitmap( KiDisabledBitmapBundleDef( pair.second->GetIcon(), iconSize ) );
1122 }
1123
1124 Refresh();
1125}
1126
1127/*
1128 * Common controls for the toolbar
1129 */
1131 _( "Grid selector" ),
1132 _( "Grid Selection box" ),
1133 { FRAME_SCH,
1140 FRAME_PL_EDITOR } );
1141
1142
1144 _( "Zoom selector" ),
1145 _( "Zoom Selection box" ),
1146 { FRAME_SCH,
1154 FRAME_PL_EDITOR } );
1155
1157 _( "IPC/Scripting plugins" ),
1158 _( "Region to hold the IPC/Scripting action buttons" ),
1159 { FRAME_SCH,
1160 FRAME_PCB_EDITOR } );
1161
1163 _( "Layer selector" ),
1164 _( "Control to select the layer" ),
1168 FRAME_GERBER } );
1169
1171 _( "Symbol unit selector" ),
1172 _( "Displays the current unit" ),
1174 FRAME_SCH_VIEWER } );
1175
1177 _( "Symbol body style selector" ),
1178 _( "Displays the current body style" ),
1180 FRAME_SCH_VIEWER } );
1181
1183 _( "Override locks" ),
1184 _( "Allow moving of locked items with the mouse" ),
1185 { FRAME_PCB_EDITOR } );
#define PALETTE_BORDER
#define PALETTE_OPEN_DELAY
#define BUTTON_BORDER
std::function< void(ACTION_TOOLBAR *)> ACTION_TOOLBAR_CONTROL_FACTORY
Type for the function signature that is used to add custom controls to the toolbar.
wxBitmapBundle KiBitmapBundleDef(BITMAPS aBitmap, int aDefHeight)
Constructs and returns a bitmap bundle for the given icon ID, with the default bitmap size being aDef...
Definition bitmap.cpp:116
int KiIconScale(wxWindow *aWindow)
Return the automatic scale factor that would be used for a given window by KiScaledBitmap and KiScale...
Definition bitmap.cpp:134
BITMAP_STORE * GetBitmapStore()
Definition bitmap.cpp:92
KICOMMON_API wxBitmapBundle KiDisabledBitmapBundleDef(BITMAPS aBitmap, int aDefHeight)
Definition bitmap.cpp:128
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:990
A group of actions that will be displayed together on a toolbar palette.
void SetDefaultAction(const TOOL_ACTION &aDefault)
Set the default action to use when first creating the toolbar palette icon.
ACTION_GROUP(const std::string_view &aName)
std::vector< const TOOL_ACTION * > m_actions
void SetActions(const std::vector< const TOOL_ACTION * > &aActions)
Set the actions contained in this group.
int GetUIId() const
Get the ID used in the UI to reference this group.
int m_id
< The action ID for this action group
const TOOL_ACTION * m_defaultAction
The actions that compose the group. Non-owning.
std::string m_name
The default action to display on the toolbar item.
static int MakeActionId(const std::string &aActionName)
Generate an unique ID from for an action with given name.
Define the structure of a menu based on ACTIONs.
Definition action_menu.h:47
void UpdateAll()
Run update handlers for the menu and its submenus.
static ACTION_TOOLBAR_CONTROL gridSelect
static ACTION_TOOLBAR_CONTROL overrideLocks
static ACTION_TOOLBAR_CONTROL layerSelector
static ACTION_TOOLBAR_CONTROL zoomSelect
static ACTION_TOOLBAR_CONTROL unitSelector
static ACTION_TOOLBAR_CONTROL ipcScripting
static ACTION_TOOLBAR_CONTROL bodyStyleSelector
Class to hold basic information about controls that can be added to the toolbars.
A popup window that contains a row of toolbar-like buttons for the user to choose from.
void CheckAction(const TOOL_ACTION &aAction, bool aCheck=true)
Check/Toggle the button for an action on the palette.
void onCharHook(wxKeyEvent &aEvent)
wxBoxSizer * m_buttonSizer
The buttons that act as the toolbar on the palette.
void AddAction(const TOOL_ACTION &aAction)
Add an action to the palette.
ACTION_TOOLBAR_PALETTE(wxWindow *aParent, bool aVertical)
Create the palette.
wxRect m_buttonSize
True if the palette uses vertical buttons, false for horizontal buttons.
void EnableAction(const TOOL_ACTION &aAction, bool aEnable=true)
Enable the button for an action on the palette.
ACTION_GROUP * m_group
The size each button on the toolbar should be.
std::map< int, BITMAP_BUTTON * > m_buttons
void Popup(wxWindow *aFocus=nullptr) override
Popup this window.
void RefreshBitmaps()
Reload all the bitmaps for the tools (e.g.
void SetToolBitmap(const TOOL_ACTION &aAction, const wxBitmapBundle &aBitmap)
Updates the bitmap of a particular tool.
void OnCustomRender(wxDC &aDc, const wxAuiToolBarItem &aItem, const wxRect &aRect) override
void onTimerDone(wxTimerEvent &aEvent)
void doSelectAction(ACTION_GROUP *aGroup, const TOOL_ACTION &aAction)
Update a group toolbar item to look like a specific action.
void onMouseClick(wxMouseEvent &aEvent)
Handler for when a drag event occurs on an item.
void AddButton(const TOOL_ACTION &aAction)
Add a large button such as used in the KiCad Manager Frame's launch bar.
wxAuiManager * m_auiManager
void UpdateControlWidth(int aID)
Update the toolbar item width of a control using its best size.
ACTION_TOOLBAR(EDA_BASE_FRAME *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxAUI_TB_DEFAULT_STYLE)
void Toggle(const TOOL_ACTION &aAction, bool aState)
Apply the default toggle action.
void SelectAction(ACTION_GROUP *aGroup, const TOOL_ACTION &aAction)
Select an action inside a group.
void Add(const TOOL_ACTION &aAction)
Add a TOOL_ACTION-based button to the toolbar.
static std::list< ACTION_TOOLBAR_CONTROL * > & GetAllCustomControls()
Get the list of custom controls that could be used on toolbars.
void onPaletteEvent(wxCommandEvent &aEvent)
Handle the palette timer triggering.
void onRightClick(wxAuiToolBarEvent &aEvent)
Handle the button select inside the palette.
wxTimer * m_paletteTimer
std::map< int, std::unique_ptr< ACTION_MENU > > m_toolMenus
void onToolEvent(wxAuiToolBarEvent &aEvent)
Handle a right-click on a menu item.
void onItemDrag(wxAuiToolBarEvent &aEvent)
The default tool event handler.
std::map< int, bool > m_toolKinds
static std::list< ACTION_TOOLBAR_CONTROL * > GetCustomControlList(FRAME_T aContext)
Get the list of custom controls that could be used on a particular frame type.
std::map< int, std::unique_ptr< ACTION_GROUP > > m_actionGroups
void AddGroup(std::unique_ptr< ACTION_GROUP > aGroup)
Add a set of actions to a toolbar as a group.
void AddToolContextMenu(const TOOL_ACTION &aAction, std::unique_ptr< ACTION_MENU > aMenu)
Add a context menu to a specific tool item on the toolbar.
void DoSetToolTipText(const wxString &aTip) override
std::map< int, bool > m_toolCancellable
void AddScaledSeparator(wxWindow *aWindow)
Add a separator that introduces space on either side to not squash the tools when scaled.
bool KiRealize()
Use this over Realize() to avoid a rendering glitch with fixed orientation toolbars.
void popupPalette(wxAuiToolBarItem *aItem)
Popup the ACTION_TOOLBAR_PALETTE associated with the ACTION_GROUP of the given toolbar item.
virtual ~ACTION_TOOLBAR()
ACTION_TOOLBAR_PALETTE * m_palette
std::vector< int > m_controlIDs
IDs for all the control items in this toolbar.
void onThemeChanged(wxSysColourChangedEvent &aEvent)
Render the triangle in the lower-right corner that represents that an action palette is available for...
EDA_BASE_FRAME * m_parent
std::map< int, const TOOL_ACTION * > m_toolActions
void ClearToolbar()
Clear the toolbar and remove all associated menus.
void UpdateControlWidths()
Update the width of all wxControl tools on thsi toolbar.
void ApplyConfiguration(const TOOLBAR_CONFIGURATION &aConfig)
Replace the contents of this toolbar with the configuration given in aConfig.
TOOL_MANAGER * m_toolManager
A bitmap button widget that behaves like an AUI toolbar item's button when it is drawn.
void AcceptDragInAsClick(bool aAcceptDragIn=true)
Accept mouse-up as click even if mouse-down happened outside of the control.
void SetDisabledBitmap(const wxBitmapBundle &aBmp)
Set the bitmap shown when the button is disabled.
void SetBitmapCentered(bool aCentered=true)
void SetIsToolbarButton(bool aIsToolbar=true)
void SetPadding(int aPaddingDIP)
Set the amount of padding present on each side of the bitmap.
void SetBitmap(const wxBitmapBundle &aBmp)
Set the bitmap shown when the button is enabled.
void ThemeChanged()
Notifies the store that the icon theme has been changed by the user, so caches must be invalidated.
APPEARANCE m_Appearance
The base frame for deriving all KiCad main window classes.
ACTION_TOOLBAR_CONTROL_FACTORY * GetCustomToolbarControlFactory(const std::string &aName)
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:535
std::vector< TOOLBAR_ITEM > GetToolbarItems() const
static MENU_FACTORY GetMenuFactory(const std::string &aActionName)
Get the menu factory for an action, if one is registered.
static MENU_FACTORY GetGroupMenuFactory(const std::string &aGroupName)
Get the menu factory for a group, if one is registered.
std::vector< TOOLBAR_ITEM > m_GroupItems
std::string m_ActionName
TOOLBAR_ITEM_TYPE m_Type
Represent a single user action.
static int GetBaseUIId()
Get the base value used to offset the user interface IDs for the actions.
BITMAPS GetIcon() const
Return an icon associated with the action.
const std::string & GetName() const
Return name of the action.
bool CheckToolbarState(TOOLBAR_STATE aState) const
Check if a specific toolbar state is required for this action.
TOOL_EVENT MakeEvent() const
Return the event associated with the action (i.e.
wxString GetButtonTooltip() const
int GetUIId() const
Get the unique ID for this action in the user interface system.
void SetHasPosition(bool aHasPosition)
Definition tool_event.h:261
#define _(s)
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition frame_type.h:33
@ FRAME_PCB_EDITOR
Definition frame_type.h:42
@ FRAME_SCH_SYMBOL_EDITOR
Definition frame_type.h:35
@ FRAME_FOOTPRINT_VIEWER
Definition frame_type.h:45
@ FRAME_SCH_VIEWER
Definition frame_type.h:36
@ FRAME_SCH
Definition frame_type.h:34
@ FRAME_PL_EDITOR
Definition frame_type.h:59
@ FRAME_FOOTPRINT_EDITOR
Definition frame_type.h:43
@ FRAME_GERBER
Definition frame_type.h:57
@ FRAME_PCB_DISPLAY3D
Definition frame_type.h:47
const wxChar *const kicadTraceToolStack
Flag to enable tracing of the tool handling stack.
wxPoint GetMousePosition()
Returns the mouse position in screen coordinates.
Definition wxgtk/ui.cpp:706
bool IsDarkTheme()
Determine if the desktop interface is currently using a dark theme or a light theme.
Definition wxgtk/ui.cpp:49
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
const int scale
Functors that can be used to figure out how the action controls should be displayed in the UI and if ...
@ TOGGLE
Action is a toggle button on the toolbar.
Definition tool_action.h:64
@ CANCEL
Action can be cancelled by clicking the toolbar button again.
Definition tool_action.h:65
@ HIDDEN
Action is hidden from the toolbar.
Definition tool_action.h:63
std::optional< TOOL_EVENT > OPT_TOOL_EVENT
Definition tool_event.h:641
wxLogTrace helper definitions.