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 m_toolKinds[ groupId ] = isToggleEntry;
525 m_toolActions[ groupId ] = defaultAction;
526 m_actionGroups[ groupId ] = std::move( aGroup );
527
528 // Add the main toolbar item representing the group
529 AddTool( groupId, wxEmptyString,
530 KiBitmapBundleDef( defaultAction->GetIcon(), iconSize ),
531 KiDisabledBitmapBundleDef( defaultAction->GetIcon(), iconSize ),
532 isToggleEntry ? wxITEM_CHECK : wxITEM_NORMAL, wxEmptyString, wxEmptyString, nullptr );
533
534 // Select the default action
535 doSelectAction( m_actionGroups[ groupId ].get(), *defaultAction );
536}
537
538
540{
541 bool valid = std::any_of( aGroup->m_actions.begin(), aGroup->m_actions.end(),
542 [&]( const TOOL_ACTION* action2 ) -> bool
543 {
544 // For some reason, we can't compare the actions directly
545 return aAction.GetId() == action2->GetId();
546 } );
547
548 if( valid )
549 doSelectAction( aGroup, aAction );
550}
551
552
554{
555 // Find the group that contains this action and select it
556 for( auto& [id, groupPtr] : m_actionGroups )
557 {
558 ACTION_GROUP* group = groupPtr.get();
559
560 bool inGroup = std::any_of( group->m_actions.begin(), group->m_actions.end(),
561 [&]( const TOOL_ACTION* action2 )
562 {
563 return aAction.GetId() == action2->GetId();
564 } );
565
566 if( inGroup )
567 {
568 doSelectAction( group, aAction );
569 break;
570 }
571 }
572}
573
574
576{
577 wxASSERT( GetParent() );
578
579 int groupId = aGroup->GetUIId();
580
581 wxAuiToolBarItem* item = FindTool( groupId );
582
583 if( !item )
584 return;
585
587
588 // Update the item information
589 item->SetShortHelp( aAction.GetButtonTooltip() );
590 item->SetBitmap( KiBitmapBundleDef( aAction.GetIcon(), iconSize ) );
591 item->SetDisabledBitmap( KiDisabledBitmapBundleDef( aAction.GetIcon(), iconSize ) );
592
593 // Register a new handler with the new UI conditions
594 if( m_toolManager )
595 {
596 m_toolManager->GetToolHolder()->UnregisterUIUpdateHandler( groupId );
597
598 const ACTION_CONDITIONS* cond = m_toolManager->GetActionManager()->GetCondition( aAction );
599
600 // Register the new UI condition to control this entry
601 if( cond )
602 {
603 m_toolManager->GetToolHolder()->RegisterUIUpdateHandler( groupId, *cond );
604 }
605 else
606 {
607 wxLogTrace( kicadTraceToolStack, wxString::Format( "No UI condition for action %s",
608 aAction.GetName() ) );
609 }
610 }
611
612 // Update the currently selected action
613 m_toolActions[ groupId ] = &aAction;
614
615 Refresh();
616}
617
618
620{
621 for( int id : m_controlIDs )
622 UpdateControlWidth( id );
623}
624
625
627{
628 wxAuiToolBarItem* item = FindTool( aID );
629 wxASSERT_MSG( item, wxString::Format( "No toolbar item found for ID %d", aID ) );
630
631 // The control on the toolbar is stored inside the window field of the item
632 wxControl* control = dynamic_cast<wxControl*>( item->GetWindow() );
633 wxASSERT_MSG( control, wxString::Format( "No control located in toolbar item with ID %d", aID ) );
634
635 // Update the size the item has stored using the best size of the control
636 control->InvalidateBestSize();
637 wxSize bestSize = control->GetBestSize();
638 item->SetMinSize( bestSize );
639
640 // Update the sizer item sizes
641 // This is a bit convoluted because there are actually 2 sizers that need to be updated:
642 // 1. The main sizer that is used for the entire toolbar (this sizer item can be found in the
643 // toolbar item)
644 if( wxSizerItem* szrItem = item->GetSizerItem() )
645 szrItem->SetMinSize( bestSize );
646
647 // 2. The controls have a second sizer that allows for padding above/below the control with
648 // stretch space, so we also need to update the sizer item for the control in that sizer with
649 // the new size. We let wx do the search for us, since SetItemMinSize is recursive and will
650 // locate the control on that sizer.
651 if( m_sizer )
652 {
653 m_sizer->SetItemMinSize( control, bestSize );
654
655 // Now actually update the toolbar with the new sizes
656 m_sizer->Layout();
657 }
658}
659
660
662{
663 // Clear all the maps keeping track of our items on the toolbar
664 m_toolMenus.clear();
665 m_actionGroups.clear();
666 m_toolCancellable.clear();
667 m_toolKinds.clear();
668 m_toolActions.clear();
669
670 for( int id : m_controlIDs )
671 {
672 m_parent->ClearToolbarControl( id );
673 DestroyTool( id );
674 }
675
676 m_controlIDs.clear();
677
678 // Remove the actual tools from the toolbar
679 Clear();
680}
681
682
683void ACTION_TOOLBAR::SetToolBitmap( const TOOL_ACTION& aAction, const wxBitmapBundle& aBitmap )
684{
685 int toolId = aAction.GetUIId();
686
687 // Set the disabled bitmap: we use the disabled bitmap version of aBitmap.
688 wxAuiToolBarItem* tb_item = wxAuiToolBar::FindTool( toolId );
689
690 if( !tb_item )
691 return;
692
693 wxBitmap bm = aBitmap.GetBitmapFor( this );
694
695 tb_item->SetBitmap( aBitmap );
696 tb_item->SetDisabledBitmap( bm.ConvertToDisabled( KIPLATFORM::UI::IsDarkTheme() ? 70 : 255 ) );
697}
698
699
700void ACTION_TOOLBAR::Toggle( const TOOL_ACTION& aAction, bool aState )
701{
702 int toolId = aAction.GetUIId();
703
704 if( m_toolKinds[ toolId ] )
705 ToggleTool( toolId, aState );
706 else
707 EnableTool( toolId, aState );
708}
709
710
711void ACTION_TOOLBAR::Toggle( const TOOL_ACTION& aAction, bool aEnabled, bool aChecked )
712{
713 int toolId = aAction.GetUIId();
714
715 EnableTool( toolId, aEnabled );
716 ToggleTool( toolId, aEnabled && aChecked );
717}
718
719
720void ACTION_TOOLBAR::onToolEvent( wxAuiToolBarEvent& aEvent )
721{
722 int id = aEvent.GetId();
723 wxEventType type = aEvent.GetEventType();
724 OPT_TOOL_EVENT evt;
725
726 bool handled = false;
727
728 if( m_toolManager && type == wxEVT_COMMAND_TOOL_CLICKED )
729 {
730 const auto actionIt = m_toolActions.find( id );
731 const auto cancelIt = m_toolCancellable.find( id );
732 const auto groupIt = m_actionGroups.find( id );
733
734 // Determine if the tool is actually cancellable
735 bool isCancellable = ( cancelIt != m_toolCancellable.end() ) ? cancelIt->second : false;
736
737 // The toolbar item is toggled before the event is sent, so we check for it not being
738 // toggled to see if it was toggled originally
739 if( isCancellable && !GetToolToggled( id ) )
740 {
741 // Send a cancel event
742 m_toolManager->CancelTool();
743 handled = true;
744 }
745 else if( groupIt != m_actionGroups.end()
746 && std::none_of( groupIt->second->GetActions().begin(),
747 groupIt->second->GetActions().end(),
748 []( const TOOL_ACTION* a )
749 {
750 return a->IsActivation();
751 } ) )
752 {
753 // For non-tool toggle groups (units, crosshair, line modes), cycle to the next
754 // action on click. Tool groups (route track, etc.) fall through and just dispatch
755 // the currently displayed action.
756 ACTION_GROUP* group = groupIt->second.get();
757 const std::vector<const TOOL_ACTION*>& actions = group->GetActions();
758 const TOOL_ACTION* current = actionIt->second;
759
760 const TOOL_ACTION* next = actions[0];
761
762 for( size_t i = 0; i < actions.size(); ++i )
763 {
764 if( actions[i]->GetId() == current->GetId() )
765 {
766 next = actions[( i + 1 ) % actions.size()];
767 break;
768 }
769 }
770
771 evt = next->MakeEvent();
772 evt->SetHasPosition( false );
773 m_toolManager->ProcessEvent( *evt );
774 m_toolManager->GetToolHolder()->RefreshCanvas();
775
777 handled = true;
778 }
779 else if( actionIt != m_toolActions.end() )
780 {
781 // Dispatch a tool event
782 evt = actionIt->second->MakeEvent();
783 evt->SetHasPosition( false );
784 m_toolManager->ProcessEvent( *evt );
785 m_toolManager->GetToolHolder()->RefreshCanvas();
786 handled = true;
787 }
788 }
789
790 // Skip the event if we don't handle it
791 if( !handled )
792 aEvent.Skip();
793}
794
795
796void ACTION_TOOLBAR::onRightClick( wxAuiToolBarEvent& aEvent )
797{
798 int toolId = aEvent.GetToolId();
799
800 // This means the event was not on a button
801 if( toolId == -1 )
802 return;
803
804 // Ensure that the ID maps to a proper tool ID. If right-clicked on a group item, this is needed
805 // to get the ID of the currently selected action, since the event's ID is that of the group.
806 const auto actionIt = m_toolActions.find( toolId );
807
808 if( actionIt != m_toolActions.end() )
809 toolId = actionIt->second->GetUIId();
810
811 // Find the menu for the action
812 const auto menuIt = m_toolMenus.find( toolId );
813
814 if( menuIt == m_toolMenus.end() )
815 return;
816
817 // Update and show the menu
818 std::unique_ptr<ACTION_MENU>& owningMenu = menuIt->second;
819
820 // Get the actual menu pointer to show it
821 ACTION_MENU* menu = owningMenu.get();
822 SELECTION dummySel;
823
824 if( CONDITIONAL_MENU* condMenu = dynamic_cast<CONDITIONAL_MENU*>( menu ) )
825 condMenu->Evaluate( dummySel );
826
827 menu->UpdateAll();
828 PopupMenu( menu );
829
830 // Remove hovered item when the menu closes, otherwise it remains hovered even if the
831 // mouse is not on the toolbar
832 SetHoverItem( nullptr );
833}
834
835
836// The time (in milliseconds) between pressing the left mouse button and opening the palette
837#define PALETTE_OPEN_DELAY 500
838
839
840void ACTION_TOOLBAR::onMouseClick( wxMouseEvent& aEvent )
841{
842 wxAuiToolBarItem* item = FindToolByPosition( aEvent.GetX(), aEvent.GetY() );
843
844 if( item )
845 {
846 // Ensure there is no active palette
847 if( m_palette )
848 {
849 m_palette->Hide();
850 m_palette->Destroy();
851 m_palette = nullptr;
852 }
853
854 // Start the popup conditions if it is a left mouse click and the tool clicked is a group
855 if( aEvent.LeftDown() && ( m_actionGroups.find( item->GetId() ) != m_actionGroups.end() ) )
857
858 // Clear the popup conditions if it is a left up, because that implies a click happened
859 if( aEvent.LeftUp() )
860 m_paletteTimer->Stop();
861 }
862
863 // Skip the event so wx can continue processing the mouse event
864 aEvent.Skip();
865}
866
867
868void ACTION_TOOLBAR::onItemDrag( wxAuiToolBarEvent& aEvent )
869{
870 int toolId = aEvent.GetToolId();
871
872 if( m_actionGroups.find( toolId ) != m_actionGroups.end() )
873 {
874 wxAuiToolBarItem* item = FindTool( toolId );
875
876 // Use call after because opening the palette from a mouse handler
877 // creates a weird mouse state that causes problems on OSX.
878 CallAfter( &ACTION_TOOLBAR::popupPalette, item );
879
880 // Don't skip this event since we are handling it
881 return;
882 }
883
884 // Skip since we don't care about it
885 aEvent.Skip();
886}
887
888
889void ACTION_TOOLBAR::onTimerDone( wxTimerEvent& aEvent )
890{
891 // We need to search for the tool using the client coordinates
892 wxPoint mousePos = ScreenToClient( KIPLATFORM::UI::GetMousePosition() );
893
894 wxAuiToolBarItem* item = FindToolByPosition( mousePos.x, mousePos.y );
895
896 if( item )
897 popupPalette( item );
898}
899
900
901void ACTION_TOOLBAR::onPaletteEvent( wxCommandEvent& aEvent )
902{
903 if( !m_palette )
904 return;
905
906 OPT_TOOL_EVENT evt;
907 ACTION_GROUP* group = m_palette->GetGroup();
908
909 // Find the action corresponding to the button press
910 auto actionIt = std::find_if( group->GetActions().begin(), group->GetActions().end(),
911 [&]( const TOOL_ACTION* aAction )
912 {
913 return aAction->GetUIId() == aEvent.GetId();
914 } );
915
916 if( actionIt != group->GetActions().end() )
917 {
918 const TOOL_ACTION* action = *actionIt;
919
920 // Dispatch a tool event
921 evt = action->MakeEvent();
922 evt->SetHasPosition( false );
923 m_toolManager->ProcessEvent( *evt );
924 m_toolManager->GetToolHolder()->RefreshCanvas();
925
926 // Update the main toolbar item with the selected action
927 doSelectAction( group, *action );
928 }
929
930 // Hide the palette
931 m_palette->Hide();
932 m_palette->Destroy();
933 m_palette = nullptr;
934}
935
936
937void ACTION_TOOLBAR::popupPalette( wxAuiToolBarItem* aItem )
938{
939 // Clear all popup conditions
940 m_paletteTimer->Stop();
941
942 wxWindow* toolParent = dynamic_cast<wxWindow*>( m_toolManager->GetToolHolder() );
943
944 wxCHECK( GetParent() && m_auiManager && toolParent, /* void */ );
945
946 // Ensure the item we are using for the palette has a group associated with it.
947 const auto it = m_actionGroups.find( aItem->GetId() );
948
949 if( it == m_actionGroups.end() )
950 return;
951
952 ACTION_GROUP* group = it->second.get();
953
954 wxAuiPaneInfo& pane = m_auiManager->GetPane( this );
955
956 // We use the size of the toolbar items for our palette buttons
957 wxRect toolRect = GetToolRect( aItem->GetId() );
958
959 // The position for the palette window must be in screen coordinates
960 wxPoint pos( ClientToScreen( toolRect.GetPosition() ) );
961
962 // True for vertical buttons, false for horizontal
963 bool dir = true;
964 size_t numActions = group->m_actions.size();
965
966 // The size of the palette in the long dimension
967 int paletteLongDim = ( 2 * PALETTE_BORDER ) // The border on all sides of the buttons
968 + ( BUTTON_BORDER ) // The border on the start of the buttons
969 + ( numActions * BUTTON_BORDER ) // The other button borders
970 + ( numActions * toolRect.GetHeight() ); // The size of the buttons
971
972 // Determine the position of the top left corner of the palette window
973 switch( pane.dock_direction )
974 {
975 case wxAUI_DOCK_TOP:
976 // Top toolbars need to shift the palette window down by the toolbar padding
977 dir = true; // Buttons are vertical in the palette
978 pos = ClientToScreen( toolRect.GetBottomLeft() );
979 pos += wxPoint( -PALETTE_BORDER, // Shift left to align the button edges
980 m_bottomPadding ); // Shift down to move away from the toolbar
981 break;
982
983 case wxAUI_DOCK_BOTTOM:
984 // Bottom toolbars need to shift the palette window up by its height (all buttons +
985 // border + toolbar padding)
986 dir = true; // Buttons are vertical in the palette
987 pos = ClientToScreen( toolRect.GetTopLeft() );
988 pos += wxPoint( -PALETTE_BORDER, // Shift left to align the button
989 // Shift up by the entire length of the palette.
990 -( paletteLongDim + m_topPadding ) );
991 break;
992
993 case wxAUI_DOCK_LEFT:
994 // Left toolbars need to shift the palette window up by the toolbar padding
995 dir = false; // Buttons are horizontal in the palette
996 pos = ClientToScreen( toolRect.GetTopRight() );
997 pos += wxPoint( m_rightPadding, // Shift right to move away from the toolbar
998 -( PALETTE_BORDER ) ); // Shift up to align the button tops
999 break;
1000
1001 case wxAUI_DOCK_RIGHT:
1002 // Right toolbars need to shift the palette window left by its width (all buttons +
1003 // border + toolbar padding)
1004 dir = false; // Buttons are horizontal in the palette
1005 pos = ClientToScreen( toolRect.GetTopLeft() );
1006
1007 // Shift left by the entire length of the palette.
1008 pos += wxPoint( -( paletteLongDim + m_leftPadding ),
1009 -( PALETTE_BORDER ) ); // Shift up to align the button
1010 break;
1011 }
1012
1013 m_palette = new ACTION_TOOLBAR_PALETTE( GetParent(), dir );
1014
1015 // We handle the button events in the toolbar class, so connect the right handler
1016 m_palette->SetGroup( group );
1017 m_palette->SetButtonSize( toolRect );
1018 m_palette->Connect( wxEVT_BUTTON, wxCommandEventHandler( ACTION_TOOLBAR::onPaletteEvent ), nullptr, this );
1019
1020
1021 // Add the actions in the group to the palette and update their enabled state
1022 // We purposely don't check items in the palette
1023 for( const TOOL_ACTION* action : group->m_actions )
1024 {
1025 wxUpdateUIEvent evt( action->GetUIId() );
1026
1027 toolParent->ProcessWindowEvent( evt );
1028
1029 m_palette->AddAction( *action );
1030
1031 if( evt.GetSetEnabled() )
1032 m_palette->EnableAction( *action, evt.GetEnabled() );
1033 }
1034
1035 // Release the mouse to ensure the first click will be recognized in the palette
1036 if( HasCapture() )
1037 ReleaseMouse();
1038
1039 m_palette->SetPosition( pos );
1040 m_palette->Popup();
1041
1042 // Clear the mouse state on the toolbar because otherwise wxWidgets gets confused
1043 // and won't properly display any highlighted items after the palette is closed.
1044 // (This is the equivalent of calling the DoResetMouseState() private function)
1045 RefreshOverflowState();
1046 SetHoverItem( nullptr );
1047 SetPressedItem( nullptr );
1048
1049 m_dragging = false;
1050 m_tipItem = nullptr;
1051 m_actionPos = wxPoint( -1, -1 );
1052 m_actionItem = nullptr;
1053}
1054
1055
1056void ACTION_TOOLBAR::OnCustomRender(wxDC& aDc, const wxAuiToolBarItem& aItem, const wxRect& aRect )
1057{
1058 auto it = m_actionGroups.find( aItem.GetId() );
1059
1060 if( it == m_actionGroups.end() )
1061 return;
1062
1063 // Choose the color to draw the triangle
1064 wxColour clr;
1065
1066 if( aItem.GetState() & wxAUI_BUTTON_STATE_DISABLED )
1067 clr = wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT );
1068 else
1069 clr = wxSystemSettings::GetColour( wxSYS_COLOUR_BTNTEXT );
1070
1071 // Must set both the pen (for the outline) and the brush (for the polygon fill)
1072 aDc.SetPen( wxPen( clr ) );
1073 aDc.SetBrush( wxBrush( clr ) );
1074
1075 // Make the side length of the triangle approximately 1/5th of the bitmap
1076 int sideLength = KiROUND( aRect.height / 5.0 );
1077
1078 // This will create a triangle with its point at the bottom right corner,
1079 // and its other two corners along the right and bottom sides
1080 wxPoint btmRight = aRect.GetBottomRight();
1081 wxPoint topCorner( btmRight.x, btmRight.y - sideLength );
1082 wxPoint btmCorner( btmRight.x - sideLength, btmRight.y );
1083
1084 wxPointList points;
1085 points.Append( &btmRight );
1086 points.Append( &topCorner );
1087 points.Append( &btmCorner );
1088
1089 aDc.DrawPolygon( &points );
1090}
1091
1092
1094{
1095#if wxCHECK_VERSION( 3, 3, 0 )
1096 return Realize();
1097#else
1098 wxClientDC dc( this );
1099
1100 if( !dc.IsOk() )
1101 return false;
1102
1103 // calculate hint sizes for both horizontal and vertical
1104 // in the order that leaves toolbar in correct final state
1105
1106 // however, skip calculating alternate orientations if we don't need them due to window style
1107 bool retval = true;
1108
1109 if( m_orientation == wxHORIZONTAL )
1110 {
1111 if( !( GetWindowStyle() & wxAUI_TB_HORIZONTAL ) )
1112 {
1113 m_vertHintSize = GetSize();
1114 retval = RealizeHelper( dc, false );
1115 }
1116
1117 if( retval && RealizeHelper( dc, true ) )
1118 m_horzHintSize = GetSize();
1119 else
1120 retval = false;
1121 }
1122 else
1123 {
1124 if( !( GetWindowStyle() & wxAUI_TB_VERTICAL ) )
1125 {
1126 m_horzHintSize = GetSize();
1127 retval = RealizeHelper( dc, true );
1128 }
1129
1130 if( retval && RealizeHelper( dc, false ) )
1131 m_vertHintSize = GetSize();
1132 else
1133 retval = false;
1134 }
1135
1136 Refresh( false );
1137 return retval;
1138#endif
1139}
1140
1141
1142void ACTION_TOOLBAR::onThemeChanged( wxSysColourChangedEvent &aEvent )
1143{
1146
1147 aEvent.Skip();
1148}
1149
1150
1152{
1154
1155 for( const std::pair<int, const TOOL_ACTION*> pair : m_toolActions )
1156 {
1157 wxAuiToolBarItem* tool = FindTool( pair.first );
1158
1159 tool->SetBitmap( KiBitmapBundleDef( pair.second->GetIcon(), iconSize ) );
1160 tool->SetDisabledBitmap( KiDisabledBitmapBundleDef( pair.second->GetIcon(), iconSize ) );
1161 }
1162
1163 Refresh();
1164}
1165
1166/*
1167 * Common controls for the toolbar
1168 */
1170 _( "Grid selector" ),
1171 _( "Grid Selection box" ),
1172 { FRAME_SCH,
1179 FRAME_PL_EDITOR } );
1180
1181
1183 _( "Zoom selector" ),
1184 _( "Zoom Selection box" ),
1185 { FRAME_SCH,
1193 FRAME_PL_EDITOR } );
1194
1196 _( "IPC/Scripting plugins" ),
1197 _( "Region to hold the IPC/Scripting action buttons" ),
1198 { FRAME_SCH,
1199 FRAME_PCB_EDITOR } );
1200
1202 _( "Layer selector" ),
1203 _( "Control to select the layer" ),
1207 FRAME_GERBER } );
1208
1210 _( "Symbol unit selector" ),
1211 _( "Displays the current unit" ),
1213 FRAME_SCH_VIEWER } );
1214
1216 _( "Symbol body style selector" ),
1217 _( "Displays the current body style" ),
1219 FRAME_SCH_VIEWER } );
1220
1222 _( "Override locks" ),
1223 _( "Allow moving of locked items with the mouse" ),
1224 { 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:547
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
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
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.