Skip to content

Commit 3575e77

Browse files
committed
Created an option to control wether or not InterSpec will transition to the "dark" color theme when the OS does.
Previously there was no indication to the user that they had to create and select a custom color theme in order to prevent InterSpec from applying the OS color scheme.
1 parent 95b10b0 commit 3575e77

File tree

6 files changed

+81
-42
lines changed

6 files changed

+81
-42
lines changed

InterSpec_resources/static_text/color_theme_dialog_help.xml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ This tool allows you to customize colors on the spectrum and time charts, as wel
1414
icon; you can also upload <em>JSON</em> color themes by using the &quot;<b>Upload...</b>&quot; button at the bottom of the tool. The <em>JSON</em>
1515
representation is convienient if you would like to use the same color theme on multiple devices.
1616
</p>
17-
17+
<p>
18+
When the '<em>Auto apply "Dark" from OS</em>' checkbox is checked, then whenever the operating system transitions into its "dark" color scheme, then <b>InterSpec</b> will automatically apply the default "<em>Dark</em>" color theme; when the operating system goes back to its default or "light" theme, then your selected color theme will be applied, or if you havent selected a color theme, the "Default" color theme will be used.
19+
There is currently no way to customize the auto-applied dark theme.
20+
</p>
1821

1922
<div style="width: 100%">
2023
<img align="left" src="InterSpec_resources/static_text/images/color_theme_dialog_top.png" class="imageBorder" style="width:55%; margin-top: 10px; "/>
@@ -38,7 +41,7 @@ This tool allows you to customize colors on the spectrum and time charts, as wel
3841

3942

4043
<div style="width: 100%">
41-
<img align="left" src="InterSpec_resources/static_text/images/color_theme_dialog_reflines.svg" class="imageBorder" style="width:55%; margin-top: 10px; "/>
44+
<img align="left" src="InterSpec_resources/static_text/images/color_theme_dialog_reflines.png" class="imageBorder" style="width:55%; margin-top: 10px; "/>
4245

4346
<span style="float:right; width: 44%">
4447
<ul>
Loading

data/default_preferences.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,5 @@
4545
<pref name="RefLineShowPrev" type="Boolean">true</pref>
4646
<pref name="RefLineShowAssoc" type="Boolean">true</pref>
4747
<pref name="ShowMapDataWarning" type="Boolean">true</pref>
48+
<pref name="AutoDarkFromOs" type="Boolean">true</pref>
4849
</preferences>

js/InterSpec.js

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -395,28 +395,43 @@ function()
395395

396396

397397
//Requires {macOS 10.14, iOS 13.0, iPadOS 13.0, Windows 10} and {Chrome 76, Safari 12.1, Firefox 67}
398+
398399
WT_DECLARE_WT_MEMBER
399-
(SetupOsColorThemeChangeJs, Wt::JavaScriptFunction, "SetupOsColorThemeChangeJs",
400+
(DetectOsColorThemeJs, Wt::JavaScriptFunction, "DetectOsColorThemeJs",
400401
function(id)
401402
{
402403
try
403404
{
404-
var darkQ = window.matchMedia('(prefers-color-scheme: dark)');
405-
var lightQ = window.matchMedia('(prefers-color-scheme: light)');
406-
var noPrefQ = window.matchMedia('(prefers-color-scheme: no-preference)');
407-
var isSupported = darkQ.matches || lightQ.matches || noPrefQ.matches;
408-
409-
if( !isSupported )
410-
throw 'no-support';
405+
const darkQ = window.matchMedia('(prefers-color-scheme: dark)');
406+
const lightQ = window.matchMedia('(prefers-color-scheme: light)');
407+
const noPrefQ = window.matchMedia('(prefers-color-scheme: no-preference)');
411408

412409
if( darkQ.matches )
413410
Wt.emit( id, {name: 'OsColorThemeChange' }, 'dark' );
414-
415-
if( lightQ.matches )
411+
else if( lightQ.matches )
416412
Wt.emit( id, {name: 'OsColorThemeChange' }, 'light' );
417-
418-
if( noPrefQ.matches )
413+
else if( noPrefQ.matches )
419414
Wt.emit( id, {name: 'OsColorThemeChange' }, 'no-preference' );
415+
else
416+
throw 'no-support';
417+
}catch(error)
418+
{
419+
Wt.emit( id, {name: 'OsColorThemeChange' }, 'no-support' );
420+
}
421+
});
422+
423+
WT_DECLARE_WT_MEMBER
424+
(SetupOsColorThemeChangeJs, Wt::JavaScriptFunction, "SetupOsColorThemeChangeJs",
425+
function(id)
426+
{
427+
try
428+
{
429+
const darkQ = window.matchMedia('(prefers-color-scheme: dark)');
430+
const lightQ = window.matchMedia('(prefers-color-scheme: light)');
431+
const noPrefQ = window.matchMedia('(prefers-color-scheme: no-preference)');
432+
433+
if( !darkQ.matches && !lightQ.matches && !noPrefQ.matches )
434+
console.warn( 'No matches for color scheme found.' );
420435

421436
darkQ.addListener( function(e){
422437
if( e && e.matches )
@@ -435,7 +450,7 @@ function(id)
435450

436451
}catch(error)
437452
{
438-
Wt.emit( id, {name: 'OsColorThemeChange' }, 'no-support' );
453+
console.warn( 'Color theme not supported:', error );
439454
}
440455
}
441456
);

src/ColorThemeWindow.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <Wt/WText>
3030
#include <Wt/WAnchor>
3131
#include <Wt/WServer>
32+
#include <Wt/WCheckBox>
3233
#include <Wt/WResource>
3334
#include <Wt/WMenuItem>
3435
#include <Wt/WFileUpload>
@@ -254,6 +255,13 @@ m_apply( nullptr )
254255
WContainerWidget *foot = footer();
255256
AuxWindow::addHelpInFooter( foot, "color-theme-dialog" );
256257

258+
WCheckBox *autoDarkCb = new WCheckBox( "Auto apply \"Dark\" from OS", foot );
259+
autoDarkCb->setFloatSide( Wt::Side::Left );
260+
autoDarkCb->setToolTip( "Apply the \"Dark\" color theme automatically according to"
261+
" the operating systems current value, or when it transisitions." );
262+
263+
InterSpecUser::associateWidget(m_interspec->m_user, "AutoDarkFromOs", autoDarkCb, m_interspec);
264+
257265
m_save = new WPushButton( "Save", foot );
258266
m_apply = new WPushButton( "Apply", foot );
259267
m_save->setHiddenKeepsGeometry( true );

src/InterSpec.cpp

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3876,45 +3876,41 @@ void InterSpec::osThemeChange( std::string name )
38763876
return;
38773877
}
38783878

3879+
//TODO: if( name == "no-support" ), then should hide widgets associated with "AutoDarkFromOs"
3880+
38793881
try
38803882
{
3881-
const int colorThemIndex = m_user->preferenceValue<int>("ColorThemeIndex", this);
3882-
if( colorThemIndex >= 0 )
3883-
return;
3883+
const bool autoDark = InterSpecUser::preferenceValue<bool>( "AutoDarkFromOs", this );
38843884

3885-
const auto oldTheme = ColorTheme::PredefinedColorTheme(-colorThemIndex);
3886-
3887-
if( oldTheme != ColorTheme::PredefinedColorTheme::DefaultColorTheme )
3888-
return;
3889-
3890-
std::unique_ptr<ColorTheme> theme;
3891-
3892-
if( name == "dark" )
3885+
if( autoDark && (name == "dark") )
38933886
{
38943887
//Check to see if we already have dark applied
38953888
if( m_colorTheme && SpecUtils::icontains( m_colorTheme->theme_name.toUTF8(), "Dark") )
38963889
return;
38973890

3898-
cout << "Will set to dark" << endl;
3899-
theme = ColorTheme::predefinedTheme( ColorTheme::PredefinedColorTheme::DarkColorTheme );
3900-
}else if( name == "light" || name == "default" || name == "no-preference" || name == "no-support" )
3891+
cout << "Will set to dark color theme" << endl;
3892+
unique_ptr<ColorTheme> theme = ColorTheme::predefinedTheme( ColorTheme::PredefinedColorTheme::DarkColorTheme );
3893+
assert( theme );
3894+
if( theme )
3895+
applyColorTheme( make_shared<ColorTheme>(*theme) );
3896+
}else if( !autoDark || name == "light" || name == "default" || name == "no-preference" || name == "no-support" )
39013897
{
3902-
//Check to see if we already have light applied
3903-
if (m_colorTheme && SpecUtils::icontains(m_colorTheme->theme_name.toUTF8(), "Default"))
3898+
if( m_colorTheme
3899+
&& (m_colorTheme->dbIndex < 0)
3900+
&& (ColorTheme::PredefinedColorTheme(-m_colorTheme->dbIndex) == ColorTheme::PredefinedColorTheme::DarkColorTheme) )
39043901
{
3905-
cout << "Already have light color theme applied." << endl;
3906-
return;
3902+
cout << "Will set to default or user specified color theme, from \"Dark\"." << endl;
3903+
3904+
m_colorTheme = nullptr;
3905+
applyColorTheme( nullptr );
3906+
}else
3907+
{
3908+
cout << "Current theme is not \"Dark\", so not setting color theme." << endl;
39073909
}
3908-
3909-
cout << "Will set to default" << endl;
3910-
theme = ColorTheme::predefinedTheme( ColorTheme::PredefinedColorTheme::DefaultColorTheme );
39113910
}
3912-
3913-
if( theme )
3914-
applyColorTheme( make_shared<ColorTheme>(*theme) );
3915-
}catch(...)
3911+
}catch( std::exception &e )
39163912
{
3917-
cerr << "InterSpec::osThemeChange() caught exception - not doing anything" << endl;
3913+
cerr << "InterSpec::osThemeChange() caught exception - not doing anything:" << e.what() << endl;
39183914
}
39193915

39203916
cout << "Done applying color theme" << endl;
@@ -6947,6 +6943,20 @@ void InterSpec::addAboutMenu( Wt::WWidget *parent )
69476943
InterSpecUser::associateWidget( m_user, "TabletUseDesktopMenus", checkbox, this );
69486944
}//if( is tablet )
69496945

6946+
WCheckBox *autoDarkCb = new WCheckBox( " Auto apply \"Dark\" theme" );
6947+
item = subPopup->addWidget( autoDarkCb );
6948+
HelpSystem::attachToolTipOn( item, "Applies the \"Dark\" color theme automatically according to"
6949+
" the operating systems current value, or when it transisitions.",
6950+
true, HelpSystem::ToolTipPosition::Right );
6951+
InterSpecUser::associateWidget( m_user, "AutoDarkFromOs", autoDarkCb, this );
6952+
6953+
InterSpecUser::addCallbackWhenChanged( m_user, "AutoDarkFromOs", std::bind([](){
6954+
InterSpec *viewer = InterSpec::instance();
6955+
if( viewer )
6956+
viewer->doJavaScript( "try{ Wt.WT.DetectOsColorThemeJs('" + viewer->id() + "'); }"
6957+
"catch(e){ console.error('Error with DetectOsColorThemeJs:',e); }" );
6958+
}) );
6959+
69506960
item = subPopup->addMenuItem("Color Themes...");
69516961
item->triggered().connect(boost::bind(&InterSpec::showColorThemeWindow, this));
69526962

@@ -8800,12 +8810,14 @@ std::set<int> InterSpec::validForegroundSamples() const
88008810
#if( APPLY_OS_COLOR_THEME_FROM_JS && !BUILD_AS_OSX_APP && !IOS && !BUILD_AS_ELECTRON_APP )
88018811
void InterSpec::initOsColorThemeChangeDetect()
88028812
{
8803-
m_osColorThemeChange.reset( new JSignal<std::string>( this, "OsColorThemeChange", true ) );
8813+
m_osColorThemeChange.reset( new JSignal<std::string>( this, "OsColorThemeChange", false ) );
88048814
m_osColorThemeChange->connect( boost::bind( &InterSpec::osThemeChange, this,
88058815
boost::placeholders::_1 ) );
88068816

8817+
LOAD_JAVASCRIPT(wApp, "js/InterSpec.js", "InterSpec", wtjsDetectOsColorThemeJs);
88078818
LOAD_JAVASCRIPT(wApp, "js/InterSpec.js", "InterSpec", wtjsSetupOsColorThemeChangeJs);
88088819

8820+
doJavaScript( "Wt.WT.DetectOsColorThemeJs('" + id() + "')" );
88098821
doJavaScript( "Wt.WT.SetupOsColorThemeChangeJs('" + id() + "')" );
88108822
}//void initOsColorThemeChangeDetect()
88118823
#endif

0 commit comments

Comments
 (0)