Add support mode for dark mode to SCINTILLA_TRICKS.

Also removes the return value from the BITMAP_STORE's themeChanged
method as it will provide the wrong answer for the second frame it's
called on.

Also hooked up ACTION_TOOLBAR, the app launcher, and the project tree
to the wx event for system color changes so they change on the fly.

Fixes https://gitlab.com/kicad/code/kicad/issues/6026
This commit is contained in:
Jeff Young 2021-09-13 23:30:22 +01:00
parent ab46aba5c9
commit 7a993c0211
14 changed files with 153 additions and 50 deletions

View File

@ -164,11 +164,10 @@ wxImage BITMAP_STORE::getImage( BITMAPS aBitmapId, int aHeight )
}
bool BITMAP_STORE::ThemeChanged()
void BITMAP_STORE::ThemeChanged()
{
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
wxString oldTheme = m_theme;
wxString oldTheme = m_theme;
if( settings )
{
@ -186,9 +185,8 @@ bool BITMAP_STORE::ThemeChanged()
m_theme = wxT( "light" );
}
m_bitmapNameCache.clear();
return !oldTheme.IsSameAs( m_theme );
if( !oldTheme.IsSameAs( m_theme ) )
m_bitmapNameCache.clear();
}

View File

@ -481,10 +481,8 @@ void EDA_BASE_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVars
m_fileHistory->SetMaxFiles( (unsigned) std::max( 0, historySize ) );
}
if( GetBitmapStore()->ThemeChanged() )
{
ThemeChanged();
}
GetBitmapStore()->ThemeChanged();
ThemeChanged();
if( GetMenuBar() )
{
@ -1236,8 +1234,8 @@ wxSize EDA_BASE_FRAME::GetWindowSize()
void EDA_BASE_FRAME::HandleSystemColorChange()
{
// Update the icon theme when the system theme changes and update the toolbars
if( GetBitmapStore()->ThemeChanged() )
ThemeChanged();
GetBitmapStore()->ThemeChanged();
ThemeChanged();
// This isn't handled by ThemeChanged()
if( GetMenuBar() )

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2020-2021 KiCad Developers, see change_log.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
@ -46,32 +46,7 @@ SCINTILLA_TRICKS::SCINTILLA_TRICKS( wxStyledTextCtrl* aScintilla, const wxString
m_te->SetScrollWidth( 1 );
m_te->SetScrollWidthTracking( true );
if( !m_singleLine )
{
// Set a monospace font with a tab width of 4. This is the closest we can get to having
// Scintilla mimic the stroke font's tab positioning.
wxFont fixedFont = KIUI::GetMonospacedUIFont();
for( size_t i = 0; i < wxSTC_STYLE_MAX; ++i )
m_te->StyleSetFont( i, fixedFont );
m_te->StyleClearAll(); // Addresses a bug in wx3.0 where styles are not correctly set
m_te->SetTabWidth( 4 );
}
// Set up the brace highlighting
wxColour highlight = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
wxColour highlightText = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
unsigned char r = highlight.Red();
unsigned char g = highlight.Green();
unsigned char b = highlight.Blue();
wxColour::MakeGrey( &r, &g, &b );
highlight.Set( r, g, b );
m_te->StyleSetForeground( wxSTC_STYLE_BRACELIGHT, highlightText );
m_te->StyleSetBackground( wxSTC_STYLE_BRACELIGHT, highlight );
m_te->StyleSetForeground( wxSTC_STYLE_BRACEBAD, *wxRED );
setupStyles();
// Set up autocomplete
m_te->AutoCompSetIgnoreCase( true );
@ -83,6 +58,57 @@ SCINTILLA_TRICKS::SCINTILLA_TRICKS( wxStyledTextCtrl* aScintilla, const wxString
// Dispatch command-keys in Scintilla control.
m_te->Bind( wxEVT_CHAR_HOOK, &SCINTILLA_TRICKS::onCharHook, this );
m_te->Bind( wxEVT_SYS_COLOUR_CHANGED,
wxSysColourChangedEventHandler( SCINTILLA_TRICKS::onThemeChanged ), this );
}
void SCINTILLA_TRICKS::onThemeChanged( wxSysColourChangedEvent &aEvent )
{
setupStyles();
aEvent.Skip();
}
void SCINTILLA_TRICKS::setupStyles()
{
wxTextCtrl dummy( m_te->GetParent(), wxID_ANY );
wxColour foreground = dummy.GetForegroundColour();
wxColour background = dummy.GetBackgroundColour();
wxColour highlight = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
wxColour highlightText = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
m_te->StyleSetForeground( wxSTC_STYLE_DEFAULT, foreground );
m_te->StyleSetBackground( wxSTC_STYLE_DEFAULT, background );
m_te->StyleClearAll();
m_te->SetSelForeground( true, highlightText );
m_te->SetSelBackground( true, highlight );
if( !m_singleLine )
{
// Set a monospace font with a tab width of 4. This is the closest we can get to having
// Scintilla mimic the stroke font's tab positioning.
wxFont fixedFont = KIUI::GetMonospacedUIFont();
for( size_t i = 0; i < wxSTC_STYLE_MAX; ++i )
m_te->StyleSetFont( i, fixedFont );
m_te->SetTabWidth( 4 );
}
// Set up the brace highlighting
unsigned char r = highlight.Red();
unsigned char g = highlight.Green();
unsigned char b = highlight.Blue();
wxColour::MakeGrey( &r, &g, &b );
highlight.Set( r, g, b );
m_te->StyleSetForeground( wxSTC_STYLE_BRACELIGHT, highlightText );
m_te->StyleSetBackground( wxSTC_STYLE_BRACELIGHT, highlight );
m_te->StyleSetForeground( wxSTC_STYLE_BRACEBAD, *wxRED );
}
@ -258,6 +284,11 @@ void SCINTILLA_TRICKS::onCharHook( wxKeyEvent& aEvent )
m_te->HomeWrap();
}
#endif
else if( aEvent.GetKeyCode() == WXK_SPECIAL20 )
{
// Proxy for a wxSysColourChangedEvent
setupStyles();
}
else
{
aEvent.Skip();

View File

@ -25,6 +25,7 @@
#include <algorithm>
#include <advanced_config.h>
#include <bitmaps.h>
#include <bitmap_store.h>
#include <eda_draw_frame.h>
#include <functional>
#include <kiplatform/ui.h>
@ -207,6 +208,9 @@ ACTION_TOOLBAR::ACTION_TOOLBAR( EDA_BASE_FRAME* parent, wxWindowID id, const wxP
Connect( wxEVT_LEFT_UP, wxMouseEventHandler( ACTION_TOOLBAR::onMouseClick ), nullptr, this );
Connect( m_paletteTimer->GetId(), wxEVT_TIMER,
wxTimerEventHandler( ACTION_TOOLBAR::onTimerDone ), nullptr, this );
Bind( wxEVT_SYS_COLOUR_CHANGED,
wxSysColourChangedEventHandler( ACTION_TOOLBAR::onThemeChanged ), this );
}
@ -822,6 +826,15 @@ bool ACTION_TOOLBAR::KiRealize()
}
void ACTION_TOOLBAR::onThemeChanged( wxSysColourChangedEvent &aEvent )
{
GetBitmapStore()->ThemeChanged();
RefreshBitmaps();
aEvent.Skip();
}
void ACTION_TOOLBAR::RefreshBitmaps()
{
for( const std::pair<int, const TOOL_ACTION*> pair : m_toolActions )

View File

@ -73,9 +73,8 @@ 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
*/
bool ThemeChanged();
void ThemeChanged();
bool IsDarkTheme() const { return m_theme == wxT( "dark" ); }

View File

@ -41,10 +41,13 @@ public:
void DoAutocomplete( const wxString& aPartial, const wxArrayString& aTokens );
protected:
void setupStyles();
int firstNonWhitespace( int aLine, int* aWhitespaceCount = nullptr );
void onCharHook( wxKeyEvent& aEvent );
void onScintillaUpdateUI( wxStyledTextEvent& aEvent );
void onThemeChanged( wxSysColourChangedEvent &aEvent );
protected:
wxStyledTextCtrl* m_te;

View File

@ -330,6 +330,8 @@ protected:
///< Handle the palette timer triggering
void onTimerDone( wxTimerEvent& aEvent );
void onThemeChanged( wxSysColourChangedEvent &aEvent );
///< Render the triangle in the lower-right corner that represents that an action palette
///< is available for an item
void OnCustomRender( wxDC& aDc, const wxAuiToolBarItem& aItem, const wxRect& aRect ) override;

View File

@ -18,6 +18,7 @@
*/
#include <bitmaps.h>
#include <bitmap_store.h>
#include <kicad_manager_frame.h>
#include <tool/tool_manager.h>
#include <tools/kicad_manager_actions.h>
@ -32,6 +33,9 @@ PANEL_KICAD_LAUNCHER::PANEL_KICAD_LAUNCHER( wxWindow* aParent ) :
{
m_toolManager = static_cast<KICAD_MANAGER_FRAME*>( aParent )->GetToolManager();
CreateLaunchers();
Bind( wxEVT_SYS_COLOUR_CHANGED,
wxSysColourChangedEventHandler( PANEL_KICAD_LAUNCHER::onThemeChanged ), this );
}
@ -144,3 +148,14 @@ void PANEL_KICAD_LAUNCHER::CreateLaunchers()
Layout();
}
void PANEL_KICAD_LAUNCHER::onThemeChanged( wxSysColourChangedEvent &aEvent )
{
GetBitmapStore()->ThemeChanged();
CreateLaunchers();
aEvent.Skip();
}

View File

@ -34,9 +34,10 @@ public:
void CreateLaunchers();
private:
void onThemeChanged( wxSysColourChangedEvent &aEvent );
private:
TOOL_MANAGER* m_toolManager;
};

View File

@ -44,13 +44,28 @@ IMPLEMENT_ABSTRACT_CLASS( PROJECT_TREE, wxTreeCtrl )
PROJECT_TREE::PROJECT_TREE( PROJECT_TREE_PANE* parent ) :
wxTreeCtrl( parent, ID_PROJECT_TREE, wxDefaultPosition, wxDefaultSize,
PLATFORM_STYLE | wxTR_HAS_BUTTONS | wxTR_MULTIPLE, wxDefaultValidator,
wxT( "EDATreeCtrl" ) )
wxT( "EDATreeCtrl" ) ),
m_imageList( nullptr )
{
m_projectTreePane = parent;
// Make sure the GUI font scales properly on GTK
SetFont( KIUI::GetControlFont( this ) );
LoadIcons();
}
PROJECT_TREE::~PROJECT_TREE()
{
delete m_imageList;
}
void PROJECT_TREE::LoadIcons()
{
delete m_imageList;
// icons size is not know (depending on they are built)
// so get it:
wxSize iconsize;
@ -93,12 +108,6 @@ PROJECT_TREE::PROJECT_TREE( PROJECT_TREE_PANE* parent ) :
}
PROJECT_TREE::~PROJECT_TREE()
{
delete m_imageList;
}
int PROJECT_TREE::OnCompareItems( const wxTreeItemId& item1, const wxTreeItemId& item2 )
{
PROJECT_TREE_ITEM* myitem1 = (PROJECT_TREE_ITEM*) GetItemData( item1 );

View File

@ -49,6 +49,8 @@ public:
PROJECT_TREE( PROJECT_TREE_PANE* parent );
~PROJECT_TREE();
void LoadIcons();
private:
/* overridden sort function */
int OnCompareItems( const wxTreeItemId& item1, const wxTreeItemId& item2 ) override;

View File

@ -32,6 +32,7 @@
#include <wx/textdlg.h>
#include <bitmaps.h>
#include <bitmap_store.h>
#include <gestfich.h>
#include <macros.h>
#include <menus_helpers.h>
@ -146,6 +147,9 @@ PROJECT_TREE_PANE::PROJECT_TREE_PANE( KICAD_MANAGER_FRAME* parent ) :
Connect( wxEVT_FSWATCHER,
wxFileSystemWatcherEventHandler( PROJECT_TREE_PANE::onFileSystemEvent ) );
Bind( wxEVT_SYS_COLOUR_CHANGED,
wxSysColourChangedEventHandler( PROJECT_TREE_PANE::onThemeChanged ), this );
/*
* Filtering is now inverted: the filters are actually used to _enable_ support
* for a given file type.
@ -1297,7 +1301,19 @@ void PROJECT_TREE_PANE::EmptyTreePrj()
}
void PROJECT_TREE_PANE::onThemeChanged( wxSysColourChangedEvent &aEvent )
{
GetBitmapStore()->ThemeChanged();
m_TreeProject->LoadIcons();
m_TreeProject->Refresh();
aEvent.Skip();
}
void KICAD_MANAGER_FRAME::OnChangeWatchedPaths( wxCommandEvent& aEvent )
{
m_leftWin->FileWatcherReset();
}

View File

@ -189,6 +189,8 @@ private:
*/
void onFileSystemEvent( wxFileSystemWatcherEvent& event );
void onThemeChanged( wxSysColourChangedEvent &aEvent );
public:
KICAD_MANAGER_FRAME* m_Parent;
PROJECT_TREE* m_TreeProject;

View File

@ -25,13 +25,27 @@
#include <wx/nonownedwnd.h>
#include <wx/toplevel.h>
#include <wx/button.h>
#include <wx/window.h>
#include <wx/settings.h>
bool KIPLATFORM::UI::IsDarkTheme()
{
// Disabled for now because it appears that the wxWidgets event goes out before the
// NSAppearance name has been updated
#ifdef NOTYET
// It appears the wxWidgets event goes out before the NSAppearance name has been updated
NSString *appearanceName = [[NSAppearance currentAppearance] name];
return !![appearanceName containsString:@"Dark"];
#else
wxColour bg = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
// Weighted W3C formula
double brightness = ( bg.Red() / 255.0 ) * 0.299 +
( bg.Green() / 255.0 ) * 0.587 +
( bg.Blue() / 255.0 ) * 0.117;
return brightness < 0.5;
#endif
}