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.
*
* 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
* 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 ----------------------------------------------------
//

View File

@ -124,6 +124,9 @@ public:
/// Registers a handler for when the user tries to interact with a read-only swatch
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,
const wxSize& aSize, const wxSize& aCheckerboardSize,
const KIGFX::COLOR4D& aCheckerboardBackground );

View File

@ -1,7 +1,7 @@
/*
* 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
* 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,
int aCol, bool isSelected ) override;
void OnDarkModeToggle();
private:
wxWindow* m_parent;
KIGFX::COLOR4D m_background;
wxSize m_size;
wxSize m_checkerboardSize;
KIGFX::COLOR4D m_checkerboardBg;
};

View File

@ -24,11 +24,11 @@
*/
#include <kiface_base.h>
#include <kiplatform/ui.h>
#include <pcb_base_edit_frame.h>
#include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <tools/pcb_selection_tool.h>
#include <pcbnew_settings.h>
#include <pgm_base.h>
#include <board.h>
#include <board_design_settings.h>
@ -37,7 +37,6 @@
#include <project.h>
#include <settings/color_settings.h>
#include <settings/settings_manager.h>
#include <tools/pcb_actions.h>
#include <widgets/appearance_controls.h>
#include <dialogs/eda_view_switcher.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_tabbedPanel( nullptr )
{
m_darkMode = KIPLATFORM::UI::IsDarkTheme();
Bind( wxEVT_IDLE,
[this]( wxIdleEvent& aEvent )
{
@ -68,6 +69,12 @@ PCB_BASE_EDIT_FRAME::PCB_BASE_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent,
if( selTool )
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()
{
if( !m_propertiesPanel || !m_propertiesPanel->IsShownOnScreen() )

View File

@ -241,6 +241,8 @@ protected:
void unitsChangeRefresh() override;
virtual void onDarkModeToggle();
protected:
bool m_undoRedoBlocked;
@ -248,8 +250,9 @@ protected:
APPEARANCE_CONTROLS* m_appearancePanel;
PROPERTIES_PANEL* m_propertiesPanel;
/// Panel with Layers and Object Inspector tabs
wxAuiNotebook* m_tabbedPanel;
wxAuiNotebook* m_tabbedPanel; /// Panel with Layers and Object Inspector tabs
bool m_darkMode;
};
#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 );
// TODO(JE) Update background color of swatch renderer when theme changes
m_netsGrid->RegisterDataType( wxT( "COLOR4D" ),
new GRID_CELL_COLOR_RENDERER( m_frame, SWATCH_SMALL ),
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()
{
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
{
if( PCB_VIA* via = dynamic_cast<PCB_VIA*>( aItem ) )
{
return via->GetRemoveUnconnected();
}
else if( PAD* pad = dynamic_cast<PAD*>( aItem ) )
{
return pad->GetRemoveUnconnected();
}
return false;
} );
@ -1954,7 +1981,7 @@ void APPEARANCE_CONTROLS::syncColorsAndVisibility()
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() );
@ -2094,8 +2121,8 @@ void APPEARANCE_CONTROLS::rebuildObjects()
sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL, 0 );
aSetting->ctl_color = swatch;
swatch->Bind( COLOR_SWATCH_CHANGED,
&APPEARANCE_CONTROLS::OnColorSwatchChanged, this );
swatch->Bind( COLOR_SWATCH_CHANGED, &APPEARANCE_CONTROLS::OnColorSwatchChanged,
this );
swatch->SetReadOnlyCallback( std::bind( &APPEARANCE_CONTROLS::onReadOnlySwatch,
this ) );
@ -2345,31 +2372,31 @@ void APPEARANCE_CONTROLS::rebuildNets()
if( !isDefaultClass)
{
menu.Append( new wxMenuItem( &menu, ID_SET_NET_COLOR,
_( "Set Netclass Color" ), wxEmptyString,
wxITEM_NORMAL ) );
_( "Set Netclass Color" ),
wxEmptyString, wxITEM_NORMAL ) );
}
menu.Append( new wxMenuItem( &menu, ID_HIGHLIGHT_NET,
wxString::Format( _( "Highlight Nets in %s" ),
escapedName ),
wxEmptyString, wxITEM_NORMAL ) );
wxString::Format( _( "Highlight Nets in %s" ),
escapedName ),
wxEmptyString, wxITEM_NORMAL ) );
menu.Append( new wxMenuItem( &menu, ID_SELECT_NET,
wxString::Format( _( "Select Tracks and Vias in %s" ),
escapedName ),
wxEmptyString, wxITEM_NORMAL ) );
wxString::Format( _( "Select Tracks and Vias in %s" ),
escapedName ),
wxEmptyString, wxITEM_NORMAL ) );
menu.Append( new wxMenuItem( &menu, ID_DESELECT_NET,
wxString::Format( _( "Unselect Tracks and Vias in %s" ),
escapedName ),
wxEmptyString, wxITEM_NORMAL ) );
wxString::Format( _( "Unselect Tracks and Vias in %s" ),
escapedName ),
wxEmptyString, wxITEM_NORMAL ) );
menu.AppendSeparator();
menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_NETS,
_( "Show All Netclasses" ), wxEmptyString,
wxITEM_NORMAL ) );
_( "Show All Netclasses" ), wxEmptyString,
wxITEM_NORMAL ) );
menu.Append( new wxMenuItem( &menu, ID_HIDE_OTHER_NETS,
_( "Hide All Other Netclasses" ), wxEmptyString,
wxITEM_NORMAL ) );
_( "Hide All Other Netclasses" ), wxEmptyString,
wxITEM_NORMAL ) );
menu.Bind( wxEVT_COMMAND_MENU_SELECTED,
&APPEARANCE_CONTROLS::onNetclassContextMenu, this );
@ -2513,7 +2540,9 @@ void APPEARANCE_CONTROLS::syncLayerPresetSelection()
m_cbLayerPresets->SetStringSelection( text );
}
else
{
m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
}
m_currentPreset = static_cast<LAYER_PRESET*>(
m_cbLayerPresets->GetClientData( m_cbLayerPresets->GetSelection() ) );

View File

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