view src/gui/theme.cc @ 104:27455104ea37

about: switch to using HTML it's still generated at runtime, but only once now
author Paper <mrpapersonic@gmail.com>
date Sun, 05 Nov 2023 02:35:27 -0500
parents b315f3759c56
children 6d8da6e64d61
line wrap: on
line source

#include "core/config.h"
#include "core/session.h"
#include <QApplication>
#include <QFile>
#include <QDebug>
#include <QTextStream>
#include <QStyleFactory>
#ifdef MACOSX
#	include "sys/osx/dark_theme.h"
#else
#	include "sys/win32/dark_theme.h"
#endif

/* This is, believe it or not, one of the hardest things I've implemented :/
     1. Dark mode stuff in Qt changes a lot and Qt 5 and Qt 6 are massively different
     2. Some widgets, i.e. QTabWidget, QTabBar, etc., just completely IGNORE the QPalette setting
     3. I don't want to use the Fusion style on every single platform
     4. Windows dark mode support in Qt 6.5 (with Fusion) is completely unavoidable
        (not a joke btw, it's retarded)
   These three already make it really hard, but along with that, I don't even remember if
   OS X dark mode support even works still; I remember the background of some of the widgets
   would refuse to update for whatever reason. */

namespace Theme {

Theme::Theme(Themes theme) {
	this->theme = theme;
}

Themes Theme::GetTheme() {
	return theme;
}

bool Theme::IsInDarkMode() {
	if (theme != Themes::OS)
		return (theme == Themes::DARK);
#ifdef MACOSX
	if (osx::DarkThemeAvailable())
		return osx::IsInDarkTheme();
#elif defined(WIN32)
	if (win32::DarkThemeAvailable())
		return win32::IsInDarkTheme();
#endif
	return (theme == Themes::DARK);
}

void Theme::SetToDarkTheme() {
	/* macOS >= 10.14 has its own global dark theme,
	   use it :) */
#if MACOSX
	if (osx::DarkThemeAvailable())
		osx::SetToDarkTheme();
	else
#endif
		SetStyleSheet(Themes::DARK);
}

void Theme::SetToLightTheme() {
#if MACOSX
	if (osx::DarkThemeAvailable())
		osx::SetToLightTheme();
	else
#endif
		SetStyleSheet(Themes::LIGHT);
}

Themes Theme::GetCurrentOSTheme() {
#if MACOSX
	if (osx::DarkThemeAvailable())
		return osx::IsInDarkTheme() ? Themes::DARK : Themes::LIGHT;
#elif defined(WIN32)
	if (win32::DarkThemeAvailable())
		return win32::IsInDarkTheme() ? Themes::DARK : Themes::LIGHT;
#endif
	/* Currently OS detection only supports Windows and macOS.
	   Please don't be shy if you're willing to port it to other OSes
	   (or desktop environments, or window managers) */
	return Themes::LIGHT;
}

/* this function is private, and should stay that way */
void Theme::SetStyleSheet(Themes theme) {
	switch (theme) {
		case Themes::DARK: {
			QColor darkGray(53, 53, 53);
			QColor gray(128, 128, 128);
			QColor black(25, 25, 25);
			QColor blue(42, 130, 218);

			QPalette darkPalette;
			darkPalette.setColor(QPalette::Window, darkGray);
			darkPalette.setColor(QPalette::WindowText, Qt::white);
			darkPalette.setColor(QPalette::Base, black);
			darkPalette.setColor(QPalette::AlternateBase, darkGray);
			darkPalette.setColor(QPalette::ToolTipBase, blue);
			darkPalette.setColor(QPalette::ToolTipText, Qt::white);
			darkPalette.setColor(QPalette::Text, Qt::white);
			darkPalette.setColor(QPalette::Button, darkGray);
			darkPalette.setColor(QPalette::ButtonText, Qt::white);
			darkPalette.setColor(QPalette::Link, blue);
			darkPalette.setColor(QPalette::Highlight, blue);
			darkPalette.setColor(QPalette::HighlightedText, Qt::black);

			darkPalette.setColor(QPalette::Active, QPalette::Button, gray.darker());
			darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray);
			darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, gray);
			darkPalette.setColor(QPalette::Disabled, QPalette::Text, gray);
			darkPalette.setColor(QPalette::Disabled, QPalette::Light, darkGray);
			qApp->setPalette(darkPalette);
			break;
		}
		default:
			qApp->setPalette(QApplication::style()->standardPalette());
			break;
	}
}

void Theme::SetTheme(Themes theme) {
	switch (theme) {
		case Themes::LIGHT:
			SetToLightTheme();
			break;
		case Themes::DARK:
			SetToDarkTheme();
			break;
		case Themes::OS:
			if (GetCurrentOSTheme() == Themes::LIGHT)
				SetToLightTheme();
			else
				SetToDarkTheme();
			break;
	}
	this->theme = theme;
}

} // namespace DarkTheme