Implement DarkMode for the Appearances Palette.

Fixes https://gitlab.com/kicad/code/kicad/issues/11734
This commit is contained in:
Jeff Young 2022-11-06 00:34:13 +00:00
parent a03799c61e
commit b385a4b60a
8 changed files with 101 additions and 58 deletions

View File

@ -293,3 +293,11 @@ void COLOR_SWATCH::GetNewSwatchColor()
} }
} }
} }
void COLOR_SWATCH::OnDarkModeToggle()
{
m_checkerboardBg = m_parent->GetBackgroundColour();
wxBitmap bm = MakeBitmap( m_color, m_background, m_size, m_checkerboardSize, m_checkerboardBg );
m_swatch->SetBitmap( bm );
}

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2018-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2018-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -114,6 +114,11 @@ void GRID_CELL_COLOR_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC&
} }
void GRID_CELL_COLOR_RENDERER::OnDarkModeToggle()
{
m_checkerboardBg = m_parent->GetBackgroundColour();
}
//-------- Custom wxGridCellEditors ---------------------------------------------------- //-------- Custom wxGridCellEditors ----------------------------------------------------
// //

View File

@ -124,6 +124,9 @@ public:
/// Registers a handler for when the user tries to interact with a read-only swatch /// Registers a handler for when the user tries to interact with a read-only swatch
void SetReadOnlyCallback( std::function<void()> aCallback ) { m_readOnlyCallback = aCallback; } void SetReadOnlyCallback( std::function<void()> aCallback ) { m_readOnlyCallback = aCallback; }
/// Respond to a change in the OS's DarkMode setting.
void OnDarkModeToggle();
static wxBitmap MakeBitmap( const KIGFX::COLOR4D& aColor, const KIGFX::COLOR4D& aBackground, static wxBitmap MakeBitmap( const KIGFX::COLOR4D& aColor, const KIGFX::COLOR4D& aBackground,
const wxSize& aSize, const wxSize& aCheckerboardSize, const wxSize& aSize, const wxSize& aCheckerboardSize,
const KIGFX::COLOR4D& aCheckerboardBackground ); const KIGFX::COLOR4D& aCheckerboardBackground );

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2018-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -48,15 +48,15 @@ public:
void Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC, const wxRect& aRect, int aRow, void Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC, const wxRect& aRect, int aRow,
int aCol, bool isSelected ) override; int aCol, bool isSelected ) override;
void OnDarkModeToggle();
private: private:
wxWindow* m_parent; wxWindow* m_parent;
KIGFX::COLOR4D m_background; KIGFX::COLOR4D m_background;
wxSize m_size; wxSize m_size;
wxSize m_checkerboardSize; wxSize m_checkerboardSize;
KIGFX::COLOR4D m_checkerboardBg; KIGFX::COLOR4D m_checkerboardBg;
}; };

View File

@ -24,11 +24,11 @@
*/ */
#include <kiface_base.h> #include <kiface_base.h>
#include <kiplatform/ui.h>
#include <pcb_base_edit_frame.h> #include <pcb_base_edit_frame.h>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
#include <tools/pcb_actions.h> #include <tools/pcb_actions.h>
#include <tools/pcb_selection_tool.h> #include <tools/pcb_selection_tool.h>
#include <pcbnew_settings.h>
#include <pgm_base.h> #include <pgm_base.h>
#include <board.h> #include <board.h>
#include <board_design_settings.h> #include <board_design_settings.h>
@ -37,7 +37,6 @@
#include <project.h> #include <project.h>
#include <settings/color_settings.h> #include <settings/color_settings.h>
#include <settings/settings_manager.h> #include <settings/settings_manager.h>
#include <tools/pcb_actions.h>
#include <widgets/appearance_controls.h> #include <widgets/appearance_controls.h>
#include <dialogs/eda_view_switcher.h> #include <dialogs/eda_view_switcher.h>
#include <pcb_properties_panel.h> #include <pcb_properties_panel.h>
@ -56,6 +55,8 @@ PCB_BASE_EDIT_FRAME::PCB_BASE_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent,
m_propertiesPanel( nullptr ), m_propertiesPanel( nullptr ),
m_tabbedPanel( nullptr ) m_tabbedPanel( nullptr )
{ {
m_darkMode = KIPLATFORM::UI::IsDarkTheme();
Bind( wxEVT_IDLE, Bind( wxEVT_IDLE,
[this]( wxIdleEvent& aEvent ) [this]( wxIdleEvent& aEvent )
{ {
@ -68,6 +69,12 @@ PCB_BASE_EDIT_FRAME::PCB_BASE_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent,
if( selTool ) if( selTool )
selTool->OnIdle( aEvent ); selTool->OnIdle( aEvent );
} }
if( m_darkMode != KIPLATFORM::UI::IsDarkTheme() )
{
onDarkModeToggle();
m_darkMode = KIPLATFORM::UI::IsDarkTheme();
}
} ); } );
} }
@ -309,6 +316,12 @@ void PCB_BASE_EDIT_FRAME::handleActivateEvent( wxActivateEvent& aEvent )
} }
void PCB_BASE_EDIT_FRAME::onDarkModeToggle()
{
m_appearancePanel->OnDarkModeToggle();
}
void PCB_BASE_EDIT_FRAME::UpdateProperties() void PCB_BASE_EDIT_FRAME::UpdateProperties()
{ {
if( !m_propertiesPanel || !m_propertiesPanel->IsShownOnScreen() ) if( !m_propertiesPanel || !m_propertiesPanel->IsShownOnScreen() )

View File

@ -241,6 +241,8 @@ protected:
void unitsChangeRefresh() override; void unitsChangeRefresh() override;
virtual void onDarkModeToggle();
protected: protected:
bool m_undoRedoBlocked; bool m_undoRedoBlocked;
@ -248,8 +250,9 @@ protected:
APPEARANCE_CONTROLS* m_appearancePanel; APPEARANCE_CONTROLS* m_appearancePanel;
PROPERTIES_PANEL* m_propertiesPanel; PROPERTIES_PANEL* m_propertiesPanel;
/// Panel with Layers and Object Inspector tabs wxAuiNotebook* m_tabbedPanel; /// Panel with Layers and Object Inspector tabs
wxAuiNotebook* m_tabbedPanel;
bool m_darkMode;
}; };
#endif #endif

View File

@ -538,7 +538,6 @@ APPEARANCE_CONTROLS::APPEARANCE_CONTROLS( PCB_BASE_FRAME* aParent, wxWindow* aFo
m_netsGrid->RegisterDataType( wxT( "bool" ), m_toggleGridRenderer, new wxGridCellBoolEditor ); m_netsGrid->RegisterDataType( wxT( "bool" ), m_toggleGridRenderer, new wxGridCellBoolEditor );
// TODO(JE) Update background color of swatch renderer when theme changes
m_netsGrid->RegisterDataType( wxT( "COLOR4D" ), m_netsGrid->RegisterDataType( wxT( "COLOR4D" ),
new GRID_CELL_COLOR_RENDERER( m_frame, SWATCH_SMALL ), new GRID_CELL_COLOR_RENDERER( m_frame, SWATCH_SMALL ),
new GRID_CELL_COLOR_SELECTOR( m_frame, m_netsGrid ) ); new GRID_CELL_COLOR_SELECTOR( m_frame, m_netsGrid ) );
@ -1154,6 +1153,38 @@ void APPEARANCE_CONTROLS::OnColorThemeChanged()
} }
void APPEARANCE_CONTROLS::OnDarkModeToggle()
{
// This is essentially a list of hacks because DarkMode isn't yet implemented inside
// wxWidgets.
//
// The individual wxPanels, COLOR_SWATCHes and GRID_CELL_COLOR_RENDERERs should really be
// overriding some virtual method or responding to some wxWidgets event so that the parent
// doesn't have to know what it contains. But, that's not where we are, so... :shrug:
m_layerPanelColour = m_panelLayers->GetBackgroundColour().ChangeLightness( 110 );
for( wxSizerItem* child : m_layersOuterSizer->GetChildren() )
{
if( child && child->GetWindow() )
child->GetWindow()->SetBackgroundColour( m_layerPanelColour );
}
// Easier than calling OnDarkModeToggle on all the GRID_CELL_COLOR_RENDERERs:
m_netsGrid->RegisterDataType( wxT( "COLOR4D" ),
new GRID_CELL_COLOR_RENDERER( m_frame, SWATCH_SMALL ),
new GRID_CELL_COLOR_SELECTOR( m_frame, m_netsGrid ) );
for( const std::pair<const wxString, APPEARANCE_SETTING*>& pair : m_netclassSettingsMap )
{
if( pair.second->ctl_color )
pair.second->ctl_color->OnDarkModeToggle();
}
OnLayerChanged(); // Update selected highlighting
}
void APPEARANCE_CONTROLS::OnLayerChanged() void APPEARANCE_CONTROLS::OnLayerChanged()
{ {
for( const std::unique_ptr<APPEARANCE_SETTING>& setting : m_layerSettings ) for( const std::unique_ptr<APPEARANCE_SETTING>& setting : m_layerSettings )
@ -1247,13 +1278,9 @@ void APPEARANCE_CONTROLS::setVisibleLayers( LSET aLayers )
[]( KIGFX::VIEW_ITEM* aItem ) -> bool []( KIGFX::VIEW_ITEM* aItem ) -> bool
{ {
if( PCB_VIA* via = dynamic_cast<PCB_VIA*>( aItem ) ) if( PCB_VIA* via = dynamic_cast<PCB_VIA*>( aItem ) )
{
return via->GetRemoveUnconnected(); return via->GetRemoveUnconnected();
}
else if( PAD* pad = dynamic_cast<PAD*>( aItem ) ) else if( PAD* pad = dynamic_cast<PAD*>( aItem ) )
{
return pad->GetRemoveUnconnected(); return pad->GetRemoveUnconnected();
}
return false; return false;
} ); } );
@ -1954,7 +1981,7 @@ void APPEARANCE_CONTROLS::syncColorsAndVisibility()
void APPEARANCE_CONTROLS::onLayerLeftClick( wxMouseEvent& aEvent ) void APPEARANCE_CONTROLS::onLayerLeftClick( wxMouseEvent& aEvent )
{ {
auto eventSource = static_cast<wxWindow*>( aEvent.GetEventObject() ); wxWindow* eventSource = static_cast<wxWindow*>( aEvent.GetEventObject() );
PCB_LAYER_ID layer = ToLAYER_ID( eventSource->GetId() ); PCB_LAYER_ID layer = ToLAYER_ID( eventSource->GetId() );
@ -2094,8 +2121,8 @@ void APPEARANCE_CONTROLS::rebuildObjects()
sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL, 0 ); sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL, 0 );
aSetting->ctl_color = swatch; aSetting->ctl_color = swatch;
swatch->Bind( COLOR_SWATCH_CHANGED, swatch->Bind( COLOR_SWATCH_CHANGED, &APPEARANCE_CONTROLS::OnColorSwatchChanged,
&APPEARANCE_CONTROLS::OnColorSwatchChanged, this ); this );
swatch->SetReadOnlyCallback( std::bind( &APPEARANCE_CONTROLS::onReadOnlySwatch, swatch->SetReadOnlyCallback( std::bind( &APPEARANCE_CONTROLS::onReadOnlySwatch,
this ) ); this ) );
@ -2345,31 +2372,31 @@ void APPEARANCE_CONTROLS::rebuildNets()
if( !isDefaultClass) if( !isDefaultClass)
{ {
menu.Append( new wxMenuItem( &menu, ID_SET_NET_COLOR, menu.Append( new wxMenuItem( &menu, ID_SET_NET_COLOR,
_( "Set Netclass Color" ), wxEmptyString, _( "Set Netclass Color" ),
wxITEM_NORMAL ) ); wxEmptyString, wxITEM_NORMAL ) );
} }
menu.Append( new wxMenuItem( &menu, ID_HIGHLIGHT_NET, menu.Append( new wxMenuItem( &menu, ID_HIGHLIGHT_NET,
wxString::Format( _( "Highlight Nets in %s" ), wxString::Format( _( "Highlight Nets in %s" ),
escapedName ), escapedName ),
wxEmptyString, wxITEM_NORMAL ) ); wxEmptyString, wxITEM_NORMAL ) );
menu.Append( new wxMenuItem( &menu, ID_SELECT_NET, menu.Append( new wxMenuItem( &menu, ID_SELECT_NET,
wxString::Format( _( "Select Tracks and Vias in %s" ), wxString::Format( _( "Select Tracks and Vias in %s" ),
escapedName ), escapedName ),
wxEmptyString, wxITEM_NORMAL ) ); wxEmptyString, wxITEM_NORMAL ) );
menu.Append( new wxMenuItem( &menu, ID_DESELECT_NET, menu.Append( new wxMenuItem( &menu, ID_DESELECT_NET,
wxString::Format( _( "Unselect Tracks and Vias in %s" ), wxString::Format( _( "Unselect Tracks and Vias in %s" ),
escapedName ), escapedName ),
wxEmptyString, wxITEM_NORMAL ) ); wxEmptyString, wxITEM_NORMAL ) );
menu.AppendSeparator(); menu.AppendSeparator();
menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_NETS, menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_NETS,
_( "Show All Netclasses" ), wxEmptyString, _( "Show All Netclasses" ), wxEmptyString,
wxITEM_NORMAL ) ); wxITEM_NORMAL ) );
menu.Append( new wxMenuItem( &menu, ID_HIDE_OTHER_NETS, menu.Append( new wxMenuItem( &menu, ID_HIDE_OTHER_NETS,
_( "Hide All Other Netclasses" ), wxEmptyString, _( "Hide All Other Netclasses" ), wxEmptyString,
wxITEM_NORMAL ) ); wxITEM_NORMAL ) );
menu.Bind( wxEVT_COMMAND_MENU_SELECTED, menu.Bind( wxEVT_COMMAND_MENU_SELECTED,
&APPEARANCE_CONTROLS::onNetclassContextMenu, this ); &APPEARANCE_CONTROLS::onNetclassContextMenu, this );
@ -2513,7 +2540,9 @@ void APPEARANCE_CONTROLS::syncLayerPresetSelection()
m_cbLayerPresets->SetStringSelection( text ); m_cbLayerPresets->SetStringSelection( text );
} }
else else
{
m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
}
m_currentPreset = static_cast<LAYER_PRESET*>( m_currentPreset = static_cast<LAYER_PRESET*>(
m_cbLayerPresets->GetClientData( m_cbLayerPresets->GetSelection() ) ); m_cbLayerPresets->GetClientData( m_cbLayerPresets->GetSelection() ) );

View File

@ -205,22 +205,19 @@ public:
void OnBoardChanged(); void OnBoardChanged();
void OnBoardNetSettingsChanged( BOARD& aBoard ) override; void OnBoardNetSettingsChanged( BOARD& aBoard ) override;
void OnBoardItemAdded( BOARD& aBoard, BOARD_ITEM* aItem ) override; void OnBoardItemAdded( BOARD& aBoard, BOARD_ITEM* aItem ) override;
void OnBoardItemsAdded( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems ) override; void OnBoardItemsAdded( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems ) override;
void OnBoardItemRemoved( BOARD& aBoard, BOARD_ITEM* aItem ) override; void OnBoardItemRemoved( BOARD& aBoard, BOARD_ITEM* aItem ) override;
void OnBoardItemsRemoved( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems ) override; void OnBoardItemsRemoved( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems ) override;
void OnBoardItemChanged( BOARD& aBoard, BOARD_ITEM* aItem ) override; void OnBoardItemChanged( BOARD& aBoard, BOARD_ITEM* aItem ) override;
void OnBoardItemsChanged( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems ) override; void OnBoardItemsChanged( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems ) override;
///< Update the colors on all the widgets from the new chosen color theme. ///< Update the colors on all the widgets from the new chosen color theme.
void OnColorThemeChanged(); void OnColorThemeChanged();
///< Respond to change in OS's DarkMode
void OnDarkModeToggle();
///< Update the widget when the active board layer is changed. ///< Update the widget when the active board layer is changed.
void OnLayerChanged(); void OnLayerChanged();
@ -252,10 +249,7 @@ public:
return wxEmptyString; return wxEmptyString;
} }
const wxArrayString& GetLayerPresetsMRU() const wxArrayString& GetLayerPresetsMRU() { return m_presetMRU; }
{
return m_presetMRU;
}
///< Return a list of viewports created by the user. ///< Return a list of viewports created by the user.
std::vector<VIEWPORT> GetUserViewports() const; std::vector<VIEWPORT> GetUserViewports() const;
@ -267,10 +261,7 @@ public:
void ApplyViewport( const VIEWPORT& aPreset ); void ApplyViewport( const VIEWPORT& aPreset );
const wxArrayString& GetViewportsMRU() const wxArrayString& GetViewportsMRU() { return m_viewportMRU; }
{
return m_viewportMRU;
}
void OnColorSwatchChanged( wxCommandEvent& aEvent ); void OnColorSwatchChanged( wxCommandEvent& aEvent );
@ -289,17 +280,11 @@ public:
protected: protected:
void OnNotebookPageChanged( wxNotebookEvent& event ) override; void OnNotebookPageChanged( wxNotebookEvent& event ) override;
void OnSetFocus( wxFocusEvent& aEvent ) override; void OnSetFocus( wxFocusEvent& aEvent ) override;
void OnSize( wxSizeEvent& aEvent ) override; void OnSize( wxSizeEvent& aEvent ) override;
void OnNetGridClick( wxGridEvent& event ) override; void OnNetGridClick( wxGridEvent& event ) override;
void OnNetGridDoubleClick( wxGridEvent& event ) override; void OnNetGridDoubleClick( wxGridEvent& event ) override;
void OnNetGridRightClick( wxGridEvent& event ) override; void OnNetGridRightClick( wxGridEvent& event ) override;
void OnNetGridMouseEvent( wxMouseEvent& aEvent ); void OnNetGridMouseEvent( wxMouseEvent& aEvent );
private: private:
@ -404,16 +389,13 @@ private:
wxGridCellCoords m_hoveredCell; wxGridCellCoords m_hoveredCell;
std::vector<std::unique_ptr<APPEARANCE_SETTING>> m_layerSettings; std::vector<std::unique_ptr<APPEARANCE_SETTING>> m_layerSettings;
std::map<PCB_LAYER_ID, APPEARANCE_SETTING*> m_layerSettingsMap;
std::map<PCB_LAYER_ID, APPEARANCE_SETTING*> m_layerSettingsMap;
std::vector<std::unique_ptr<APPEARANCE_SETTING>> m_objectSettings; std::vector<std::unique_ptr<APPEARANCE_SETTING>> m_objectSettings;
std::map<GAL_LAYER_ID, APPEARANCE_SETTING*> m_objectSettingsMap;
std::map<GAL_LAYER_ID, APPEARANCE_SETTING*> m_objectSettingsMap;
std::vector<std::unique_ptr<APPEARANCE_SETTING>> m_netclassSettings; std::vector<std::unique_ptr<APPEARANCE_SETTING>> m_netclassSettings;
std::map<wxString, APPEARANCE_SETTING*> m_netclassSettingsMap;
std::map<wxString, APPEARANCE_SETTING*> m_netclassSettingsMap;
// TODO(JE) Move preset storage to the PCB_CONTROL tool // TODO(JE) Move preset storage to the PCB_CONTROL tool
@ -426,7 +408,7 @@ private:
VIEWPORT* m_lastSelectedViewport; VIEWPORT* m_lastSelectedViewport;
wxArrayString m_viewportMRU; wxArrayString m_viewportMRU;
wxMenu* m_layerContextMenu; wxMenu* m_layerContextMenu;
/// Stores wxIDs for each netclass for control event mapping /// Stores wxIDs for each netclass for control event mapping
std::map<int, wxString> m_netclassIdMap; std::map<int, wxString> m_netclassIdMap;