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