Add icon theme selection behind advanced config flag

This commit is contained in:
Jon Evans 2021-03-09 17:47:24 -05:00
parent 18037e2f65
commit 405fa183b2
15 changed files with 444 additions and 26 deletions

View File

@ -151,6 +151,8 @@ static const wxChar HotkeysDumper[] = wxT( "HotkeysDumper" );
static const wxChar DrawBoundingBoxes[] = wxT( "DrawBoundingBoxes" );
static const wxChar AllowDarkMode[] = wxT( "AllowDarkMode" );
} // namespace KEYS
@ -252,6 +254,7 @@ ADVANCED_CFG::ADVANCED_CFG()
m_SmallDrillMarkSize = 0.35;
m_HotkeysDumper = false;
m_DrawBoundingBoxes = false;
m_AllowDarkMode = false;
loadFromConfigFile();
}
@ -342,6 +345,9 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::DrawBoundingBoxes,
&m_DrawBoundingBoxes, false ) );
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::AllowDarkMode,
&m_AllowDarkMode, false ) );
wxConfigLoadSetups( &aCfg, configParams );
for( PARAM_CFG* param : configParams )

View File

@ -85,7 +85,12 @@ namespace std {
}
BITMAP_STORE* GetStore()
static std::unordered_map<SCALED_BITMAP_ID, wxBitmap> s_ScaledBitmapCache;
static std::mutex s_BitmapCacheMutex;
BITMAP_STORE* GetBitmapStore()
{
if( !s_BitmapStore )
{
@ -99,7 +104,7 @@ BITMAP_STORE* GetStore()
wxBitmap KiBitmap( BITMAPS aBitmap )
{
return GetStore()->GetBitmap( aBitmap );
return GetBitmapStore()->GetBitmap( aBitmap );
}
@ -143,32 +148,37 @@ static int get_scale_factor( wxWindow* aWindow )
wxBitmap KiScaledBitmap( BITMAPS aBitmap, wxWindow* aWindow, int aHeight )
{
// Bitmap conversions are cached because they can be slow.
static std::unordered_map<SCALED_BITMAP_ID, wxBitmap> bitmap_cache;
static std::mutex bitmap_cache_mutex;
const int scale = get_scale_factor( aWindow );
SCALED_BITMAP_ID id = { static_cast<BITMAPS>( aBitmap ), scale };
std::lock_guard<std::mutex> guard( bitmap_cache_mutex );
auto it = bitmap_cache.find( id );
std::lock_guard<std::mutex> guard( s_BitmapCacheMutex );
auto it = s_ScaledBitmapCache.find( id );
if( it != bitmap_cache.end() )
if( it != s_ScaledBitmapCache.end() )
{
return it->second;
}
else
{
wxBitmap bitmap = GetStore()->GetBitmapScaled( aBitmap, scale, aHeight );
return bitmap_cache.emplace( id, bitmap ).first->second;
wxBitmap bitmap = GetBitmapStore()->GetBitmapScaled( aBitmap, scale, aHeight );
return s_ScaledBitmapCache.emplace( id, bitmap ).first->second;
}
}
void ClearScaledBitmapCache()
{
std::lock_guard<std::mutex> guard( s_BitmapCacheMutex );
s_ScaledBitmapCache.clear();
}
wxBitmap KiScaledBitmap( const wxBitmap& aBitmap, wxWindow* aWindow )
{
const int scale = get_scale_factor( aWindow );
if( scale == 4)
if( scale == 4 )
{
return wxBitmap( aBitmap );
}
@ -185,7 +195,7 @@ wxBitmap KiScaledBitmap( const wxBitmap& aBitmap, wxWindow* aWindow )
wxBitmap* KiBitmapNew( BITMAPS aBitmap )
{
wxBitmap* bitmap = new wxBitmap( GetStore()->GetBitmap( aBitmap ) );
wxBitmap* bitmap = new wxBitmap( GetBitmapStore()->GetBitmap( aBitmap ) );
return bitmap;
}

View File

@ -23,12 +23,15 @@
#include <wx/mstream.h>
#include <wx/stdpaths.h>
#include <advanced_config.h>
#include <asset_archive.h>
#include <bitmaps.h>
#include <bitmap_store.h>
#include <bitmaps/bitmap_info.h>
#include <kiplatform/ui.h>
#include <paths.h>
#include <pgm_base.h>
#include <settings/common_settings.h>
/// A question-mark icon shown when we can't find a given bitmap in the archive
@ -102,9 +105,9 @@ BITMAP_STORE::BITMAP_STORE()
m_archive = std::make_unique<ASSET_ARCHIVE>( path.GetFullPath() );
m_theme = KIPLATFORM::UI::IsDarkTheme() ? wxT( "dark" ) : wxT( "light" );
buildBitmapInfoCache();
ThemeChanged();
}
@ -158,9 +161,31 @@ wxImage BITMAP_STORE::getImage( BITMAPS aBitmapId, int aHeight )
}
void BITMAP_STORE::ThemeChanged()
bool BITMAP_STORE::ThemeChanged()
{
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
wxString oldTheme = m_theme;
if( ADVANCED_CFG::GetCfg().m_AllowDarkMode )
{
switch( settings->m_Appearance.icon_theme )
{
case ICON_THEME::LIGHT: m_theme = wxT( "light" ); break;
case ICON_THEME::DARK: m_theme = wxT( "dark" ); break;
case ICON_THEME::AUTO:
m_theme = KIPLATFORM::UI::IsDarkTheme() ? wxT( "dark" ) : wxT( "light" );
break;
}
}
else
{
m_theme = wxT( "light" );
}
m_bitmapNameCache.clear();
return !oldTheme.IsSameAs( m_theme );
}

View File

@ -23,6 +23,7 @@
#include <dialogs/panel_common_settings.h>
#include <advanced_config.h>
#include <bitmaps.h>
#include <dialog_shim.h>
#include <gal/dpi_scaling.h>
@ -71,6 +72,14 @@ PANEL_COMMON_SETTINGS::PANEL_COMMON_SETTINGS( DIALOG_SHIM* aDialog, wxWindow* aP
m_antialiasingFallbackLabel->Show( false );
#endif
if( !ADVANCED_CFG::GetCfg().m_AllowDarkMode )
{
m_rbIconThemeLight->Hide();
m_rbIconThemeDark->Hide();
m_rbIconThemeAuto->Hide();
m_stIconTheme->Hide();
}
m_textEditorBtn->SetBitmap( KiBitmap( BITMAPS::small_folder ) );
m_pdfViewerBtn->SetBitmap( KiBitmap( BITMAPS::small_folder ) );
@ -123,6 +132,13 @@ bool PANEL_COMMON_SETTINGS::TransferDataFromWindow()
dpi.SetDpiConfig( m_canvasScaleAuto->GetValue(), m_canvasScaleCtrl->GetValue() );
}
if( m_rbIconThemeLight->GetValue() )
commonSettings->m_Appearance.icon_theme = ICON_THEME::LIGHT;
else if( m_rbIconThemeDark->GetValue() )
commonSettings->m_Appearance.icon_theme = ICON_THEME::DARK;
else if( m_rbIconThemeAuto->GetValue() )
commonSettings->m_Appearance.icon_theme = ICON_THEME::AUTO;
commonSettings->m_Appearance.use_icons_in_menus = m_checkBoxIconsInMenus->GetValue();
commonSettings->m_Input.immediate_actions = !m_NonImmediateActions->GetValue();
@ -199,6 +215,13 @@ void PANEL_COMMON_SETTINGS::applySettingsToPanel( COMMON_SETTINGS& aSettings )
m_canvasScaleAuto->SetValue( dpi.GetCanvasIsAutoScaled() );
}
switch( aSettings.m_Appearance.icon_theme )
{
case ICON_THEME::LIGHT: m_rbIconThemeLight->SetValue( true ); break;
case ICON_THEME::DARK: m_rbIconThemeDark->SetValue( true ); break;
case ICON_THEME::AUTO: m_rbIconThemeAuto->SetValue( true ); break;
}
m_checkBoxIconsInMenus->SetValue( aSettings.m_Appearance.use_icons_in_menus );
m_warpMouseOnMove->SetValue( aSettings.m_Input.warp_mouse_on_move );

View File

@ -181,7 +181,27 @@ PANEL_COMMON_SETTINGS_BASE::PANEL_COMMON_SETTINGS_BASE( wxWindow* parent, wxWind
gbSizer4->Add( m_canvasScaleAuto, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT|wxLEFT, 15 );
m_checkBoxIconsInMenus = new wxCheckBox( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("Show icons in menus"), wxDefaultPosition, wxDefaultSize, 0 );
gbSizer4->Add( m_checkBoxIconsInMenus, wxGBPosition( 2, 0 ), wxGBSpan( 1, 3 ), wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT, 5 );
gbSizer4->Add( m_checkBoxIconsInMenus, wxGBPosition( 2, 0 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT, 5 );
m_stIconTheme = new wxStaticText( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("Icon theme:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stIconTheme->Wrap( -1 );
gbSizer4->Add( m_stIconTheme, wxGBPosition( 3, 0 ), wxGBSpan( 1, 3 ), wxLEFT|wxRIGHT, 5 );
m_rbIconThemeLight = new wxRadioButton( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("Light"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
m_rbIconThemeLight->SetToolTip( _("Use icons designed for light window backgrounds") );
gbSizer4->Add( m_rbIconThemeLight, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxLEFT|wxRIGHT, 5 );
m_rbIconThemeDark = new wxRadioButton( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("Dark"), wxDefaultPosition, wxDefaultSize, 0 );
m_rbIconThemeDark->SetToolTip( _("Use icons designed for dark window backgrounds") );
gbSizer4->Add( m_rbIconThemeDark, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), wxLEFT|wxRIGHT, 5 );
m_rbIconThemeAuto = new wxRadioButton( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("Automatic"), wxDefaultPosition, wxDefaultSize, 0 );
m_rbIconThemeAuto->SetValue( true );
m_rbIconThemeAuto->SetToolTip( _("Automatically choose light or dark icons based on the system color theme") );
gbSizer4->Add( m_rbIconThemeAuto, wxGBPosition( 4, 2 ), wxGBSpan( 1, 1 ), wxLEFT|wxRIGHT, 5 );
gbSizer4->AddGrowableCol( 1 );

View File

@ -1824,7 +1824,7 @@
</object>
<object class="gbsizeritem" expanded="1">
<property name="border">5</property>
<property name="colspan">3</property>
<property name="colspan">2</property>
<property name="column">0</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT</property>
<property name="row">2</property>
@ -1889,6 +1889,271 @@
<property name="window_style"></property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<property name="border">5</property>
<property name="colspan">3</property>
<property name="column">0</property>
<property name="flag">wxLEFT|wxRIGHT</property>
<property name="row">3</property>
<property name="rowspan">1</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Icon theme:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_stIconTheme</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">0</property>
<property name="flag">wxLEFT|wxRIGHT</property>
<property name="row">4</property>
<property name="rowspan">1</property>
<object class="wxRadioButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Light</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_rbIconThemeLight</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxRB_GROUP</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Use icons designed for light window backgrounds</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value">0</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">1</property>
<property name="flag">wxLEFT|wxRIGHT</property>
<property name="row">4</property>
<property name="rowspan">1</property>
<object class="wxRadioButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Dark</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_rbIconThemeDark</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Use icons designed for dark window backgrounds</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value">0</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">2</property>
<property name="flag">wxLEFT|wxRIGHT</property>
<property name="row">4</property>
<property name="rowspan">1</property>
<object class="wxRadioButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Automatic</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_rbIconThemeAuto</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Automatically choose light or dark icons based on the system color theme</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value">1</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
</object>
</object>
</object>

View File

@ -67,6 +67,10 @@ class PANEL_COMMON_SETTINGS_BASE : public RESETTABLE_PANEL
wxSpinCtrlDouble* m_canvasScaleCtrl;
wxCheckBox* m_canvasScaleAuto;
wxCheckBox* m_checkBoxIconsInMenus;
wxStaticText* m_stIconTheme;
wxRadioButton* m_rbIconThemeLight;
wxRadioButton* m_rbIconThemeDark;
wxRadioButton* m_rbIconThemeAuto;
wxCheckBox* m_warpMouseOnMove;
wxCheckBox* m_NonImmediateActions;
wxCheckBox* m_cbBackupEnabled;

View File

@ -24,6 +24,7 @@
*/
#include <bitmaps.h>
#include <bitmap_store.h>
#include <dialog_shim.h>
#include <dialogs/panel_common_settings.h>
#include <dialogs/panel_mouse_settings.h>
@ -41,6 +42,7 @@
#include <project/project_local_settings.h>
#include <tool/action_manager.h>
#include <tool/action_menu.h>
#include <tool/action_toolbar.h>
#include <tool/actions.h>
#include <tool/common_control.h>
#include <tool/tool_manager.h>
@ -53,6 +55,7 @@
#include <wx/stdpaths.h>
#include <wx/string.h>
#include <kiplatform/app.h>
#include <kiplatform/ui.h>
#include <functional>
@ -446,6 +449,19 @@ void EDA_BASE_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVars
m_fileHistory->SetMaxFiles( (unsigned) std::max( 0, historySize ) );
}
if( GetBitmapStore()->ThemeChanged() )
{
ClearScaledBitmapCache();
wxAuiPaneInfoArray panes = m_auimgr.GetAllPanes();
for( size_t i = 0; i < panes.GetCount(); ++i )
{
if( ACTION_TOOLBAR* toolbar = dynamic_cast<ACTION_TOOLBAR*>( panes[i].window ) )
toolbar->RefreshBitmaps();
}
}
if( GetMenuBar() )
{
// For icons in menus, icon scaling & hotkeys

View File

@ -68,6 +68,9 @@ COMMON_SETTINGS::COMMON_SETTINGS() :
m_params.emplace_back( new PARAM<int>( "appearance.icon_scale",
&m_Appearance.icon_scale, 0 ) );
m_params.emplace_back( new PARAM_ENUM<ICON_THEME>( "appearance.icon_theme",
&m_Appearance.icon_theme, ICON_THEME::AUTO, ICON_THEME::LIGHT, ICON_THEME::AUTO ) );
m_params.emplace_back( new PARAM<bool>( "appearance.use_icons_in_menus",
&m_Appearance.use_icons_in_menus, defaultUseIconsInMenus ) );

View File

@ -23,6 +23,7 @@
*/
#include <algorithm>
#include <advanced_config.h>
#include <bitmaps.h>
#include <eda_draw_frame.h>
#include <functional>
@ -170,14 +171,13 @@ ACTION_TOOLBAR::ACTION_TOOLBAR( EDA_BASE_FRAME* parent, wxWindowID id, const wxP
{
m_paletteTimer = new wxTimer( this );
// Enable this once dark icon switching is available. Without dark theme icons, this just
// makes things (even) harder to see
#ifdef NOTYET
#if !wxCHECK_VERSION( 3, 1, 0 )
// Custom art provider makes dark mode work on wx < 3.1
WX_AUI_TOOLBAR_ART* newArt = new WX_AUI_TOOLBAR_ART();
SetArtProvider( newArt );
#endif
if( ADVANCED_CFG::GetCfg().m_AllowDarkMode )
{
WX_AUI_TOOLBAR_ART* newArt = new WX_AUI_TOOLBAR_ART();
SetArtProvider( newArt );
}
#endif
Connect( wxEVT_COMMAND_TOOL_CLICKED, wxAuiToolBarEventHandler( ACTION_TOOLBAR::onToolEvent ),
@ -759,3 +759,19 @@ bool ACTION_TOOLBAR::KiRealize()
Refresh( false );
return retval;
}
void ACTION_TOOLBAR::RefreshBitmaps()
{
for( const std::pair<int, const TOOL_ACTION*> pair : m_toolActions )
{
wxAuiToolBarItem* tool = FindTool( pair.first );
wxBitmap bmp = KiScaledBitmap( pair.second->GetIcon(), GetParent() );
tool->SetBitmap( bmp );
tool->SetDisabledBitmap( bmp.ConvertToDisabled() );
}
Refresh();
}

View File

@ -160,6 +160,11 @@ public:
*/
bool m_DrawBoundingBoxes;
/**
* Enable detection of dark mode and automatic switch to dark-mode icon theme
*/
bool m_AllowDarkMode;
private:
ADVANCED_CFG();

View File

@ -26,6 +26,7 @@
#include <bitmaps/bitmap_info.h>
class ASSET_ARCHIVE;
class wxImage;
namespace std
@ -72,8 +73,11 @@ public:
/**
* Notifies the store that the icon theme has been changed by the user, so caches must be
* invalidated.
* @return true if the new theme is different than what was previously in use
*/
void ThemeChanged();
bool ThemeChanged();
bool IsDarkTheme() const { return m_theme == wxT( "dark" ); }
private:

View File

@ -33,11 +33,14 @@ class wxBitmap; // only to define wxBitmap
class EDA_DRAW_FRAME;
class wxWindow;
struct BITMAP_OPAQUE;
class BITMAP_STORE;
enum class BITMAPS : unsigned int;
#include <wx/gdicmn.h> // wxBitmapType
BITMAP_STORE* GetBitmapStore();
/**
* Construct a wxBitmap from an image identifier
* Returns the image from the active theme if the image has multiple theme variants.
@ -50,6 +53,11 @@ wxBitmap KiBitmap( BITMAPS aBitmap );
*/
wxBitmap KiBitmap( const BITMAP_OPAQUE* aBitmap );
/**
* Wipes out the scaled bitmap cache so that the icon theme can be changed.
* TODO: move scaling system into BITMAP_STORE so this global doesn't need to exist
*/
void ClearScaledBitmapCache();
/**
* Construct a wxBitmap from a memory record, scaling it if device DPI demands it.

View File

@ -35,15 +35,23 @@ enum class MOUSE_DRAG_ACTION
NONE
};
enum class ICON_THEME
{
LIGHT,
DARK,
AUTO
};
class COMMON_SETTINGS : public JSON_SETTINGS
{
public:
struct APPEARANCE
{
double canvas_scale;
int icon_scale;
bool use_icons_in_menus;
double canvas_scale;
int icon_scale;
ICON_THEME icon_theme;
bool use_icons_in_menus;
};
struct AUTO_BACKUP

View File

@ -284,6 +284,11 @@ public:
*/
bool KiRealize();
/**
* Reload all the bitmaps for the tools (e.g. when switching icon themes)
*/
void RefreshBitmaps();
static constexpr bool TOGGLE = true;
static constexpr bool CANCEL = true;