view src/gui/theme.cc @ 327:b5d6c27c308f

anime: refactor Anime::SeriesSeason to Season class ToLocalString has also been altered to take in both season and year because lots of locales actually treat formatting seasons differently! most notably is Russian which adds a suffix at the end to notate seasons(??)
author Paper <paper@paper.us.eu.org>
date Thu, 13 Jun 2024 01:49:18 -0400
parents 91ac90a34003
children c844f8bb87ce
line wrap: on
line source

#include "core/config.h"
#include "core/session.h"
#include "gui/theme.h"
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QStyleFactory>
#include <QTextStream>
#include <QStyle>
#include <QtGlobal>
#ifdef MACOSX
#	include "sys/osx/dark_theme.h"
#elif defined(WIN32)
#	include "sys/win32/dark_theme.h"
#else
#	ifdef GLIB
#		include "sys/glib/dark_theme.h"
#	endif
#endif

/* Weird quirks of this implementation:
 *   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
 *      on different platforms and the only way to fix it is by using Fusion
 *   3. Windows dark mode support in Qt 6.5 (with Fusion) is completely unavoidable
 */

namespace Theme {

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

Theme ThemeManager::GetTheme() const {
	return theme;
}

bool ThemeManager::IsInDarkTheme() const {
	switch (theme) {
		case Theme::Default:
#ifdef MACOSX
			if (osx::DarkThemeAvailable())
				return osx::IsInDarkTheme();
#elif defined(WIN32)
			if (win32::DarkThemeAvailable())
				return win32::IsInDarkTheme();
#else
#	ifdef GLIB
			return glib::IsInDarkTheme();
#	endif
#endif
		default: break;
	}
	return (theme == Theme::Dark);
}

void ThemeManager::SetToDarkTheme() {
	/* macOS >= 10.14 has its own global dark theme,
	   use it :) */
#ifdef MACOSX
	if (osx::DarkThemeAvailable())
		osx::SetToDarkTheme();
	else
#elif defined(WIN32)
	if (win32::DarkThemeAvailable())
		win32::SetTitleBarsToBlack(true);
#endif
		SetStyleSheet(Theme::Dark);
}

void ThemeManager::SetToLightTheme() {
#ifdef MACOSX
	if (osx::DarkThemeAvailable())
		osx::SetToLightTheme();
	else
#elif defined(WIN32)
	if (win32::DarkThemeAvailable())
		win32::SetTitleBarsToBlack(false);
#endif
		SetStyleSheet(Theme::Light);
}

Theme ThemeManager::GetCurrentOSTheme() const {
	return IsInDarkTheme() ? Theme::Dark : Theme::Light;
}

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

			QPalette pal;

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

			pal.setColor(QPalette::Active, QPalette::Button, gray.darker());
			pal.setColor(QPalette::Disabled, QPalette::ButtonText, gray);
			pal.setColor(QPalette::Disabled, QPalette::WindowText, gray);
			pal.setColor(QPalette::Disabled, QPalette::Text, gray);
			pal.setColor(QPalette::Disabled, QPalette::Light, darkGray);

			qApp->setPalette(pal);

#ifdef WIN32
			qApp->setStyleSheet([] {
				QFile f(":/dark.qss");
				if (!f.exists())
					return QStringLiteral("");
				f.open(QFile::ReadOnly | QFile::Text);
				QTextStream ts(&f);
				return ts.readAll();
			}());
#endif
			break;
		}
		default:
			/* this sucks */
			QPalette pal(QApplication::style()->standardPalette());
#ifdef WIN32 /* fuck you Qt 6 */
			pal.setColor(QPalette::Window, QColor(0xF0, 0xF0, 0xF0));
#endif
			qApp->setPalette(pal);

			qApp->setStyleSheet("");
			break;
	}
}

void ThemeManager::SetTheme(Theme theme) {
	switch (theme) {
		case Theme::Light: SetToLightTheme(); break;
		case Theme::Dark: SetToDarkTheme(); break;
		case Theme::Default:
			if (GetCurrentOSTheme() == Theme::Light)
				SetToLightTheme();
			else
				SetToDarkTheme();
			break;
	}
	this->theme = theme;
}

void ThemeManager::RepaintCurrentTheme() {
	SetTheme(theme);
}

} // namespace Theme