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