(UX) Add open folder button next to combo boxes

Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
This commit is contained in:
TheKodeToad 2023-07-20 11:51:44 +01:00
parent 960093700a
commit 842f08dcfc
8 changed files with 135 additions and 101 deletions

View File

@ -900,7 +900,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
return; return;
} }
applyCurrentlySelectedTheme(true); m_themeManager->applyCurrentlySelectedTheme(true);
performMainStartupAction(); performMainStartupAction();
} }
@ -942,7 +942,7 @@ bool Application::createSetupWizard()
if (!validWidgets) if (!validWidgets)
settings()->set("ApplicationTheme", QString("system")); settings()->set("ApplicationTheme", QString("system"));
applyCurrentlySelectedTheme(true); m_themeManager->applyCurrentlySelectedTheme(true);
m_setupWizard = new SetupWizard(nullptr); m_setupWizard = new SetupWizard(nullptr);
if (languageRequired) if (languageRequired)
@ -1167,31 +1167,6 @@ std::shared_ptr<JavaInstallList> Application::javalist()
return m_javalist; return m_javalist;
} }
QList<ITheme*> Application::getValidApplicationThemes()
{
return m_themeManager->getValidApplicationThemes();
}
QList<IconTheme*> Application::getValidIconThemes()
{
return m_themeManager->getValidIconThemes();
}
void Application::applyCurrentlySelectedTheme(bool initial)
{
m_themeManager->applyCurrentlySelectedTheme(initial);
}
void Application::setApplicationTheme(const QString& name)
{
m_themeManager->setApplicationTheme(name);
}
void Application::setIconTheme(const QString& name)
{
m_themeManager->setIconTheme(name);
}
QIcon Application::getThemedIcon(const QString& name) QIcon Application::getThemedIcon(const QString& name)
{ {
if(name == "logo") { if(name == "logo") {

View File

@ -119,15 +119,7 @@ public:
QIcon getThemedIcon(const QString& name); QIcon getThemedIcon(const QString& name);
void setIconTheme(const QString& name); ThemeManager* themeManager() { return m_themeManager.get(); }
void applyCurrentlySelectedTheme(bool initial = false);
QList<ITheme*> getValidApplicationThemes();
QList<IconTheme*> getValidIconThemes();
void setApplicationTheme(const QString& name);
shared_qobject_ptr<ExternalUpdater> updater() { shared_qobject_ptr<ExternalUpdater> updater() {
return m_updater; return m_updater;

View File

@ -109,7 +109,7 @@ bool openDirectory(const QString &path, bool ensureExists)
qDebug() << "Opening directory" << path; qDebug() << "Opening directory" << path;
QDir parentPath; QDir parentPath;
QDir dir(path); QDir dir(path);
if (!dir.exists()) if (ensureExists && !dir.exists())
{ {
parentPath.mkpath(dir.absolutePath()); parentPath.mkpath(dir.absolutePath());
} }

View File

@ -627,7 +627,7 @@ void MainWindow::updateThemeMenu()
themeMenu = new QMenu(this); themeMenu = new QMenu(this);
} }
auto themes = APPLICATION->getValidApplicationThemes(); auto themes = APPLICATION->themeManager()->getValidApplicationThemes();
QActionGroup* themesGroup = new QActionGroup(this); QActionGroup* themesGroup = new QActionGroup(this);
@ -641,7 +641,7 @@ void MainWindow::updateThemeMenu()
themeAction->setActionGroup(themesGroup); themeAction->setActionGroup(themesGroup);
connect(themeAction, &QAction::triggered, [theme]() { connect(themeAction, &QAction::triggered, [theme]() {
APPLICATION->setApplicationTheme(theme->id()); APPLICATION->themeManager()->setApplicationTheme(theme->id());
APPLICATION->settings()->set("ApplicationTheme", theme->id()); APPLICATION->settings()->set("ApplicationTheme", theme->id());
}); });
} }
@ -1152,12 +1152,12 @@ void MainWindow::on_actionViewCentralModsFolder_triggered()
void MainWindow::on_actionViewIconThemeFolder_triggered() void MainWindow::on_actionViewIconThemeFolder_triggered()
{ {
DesktopServices::openDirectory("iconthemes"); DesktopServices::openDirectory(APPLICATION->themeManager()->getIconThemesFolder().path());
} }
void MainWindow::on_actionViewWidgetThemeFolder_triggered() void MainWindow::on_actionViewWidgetThemeFolder_triggered()
{ {
DesktopServices::openDirectory("themes"); DesktopServices::openDirectory(APPLICATION->themeManager()->getApplicationThemesFolder().path());
} }
void MainWindow::refreshInstances() void MainWindow::refreshInstances()

View File

@ -73,13 +73,12 @@ void ThemeManager::initializeIcons()
// TODO: icon themes and instance icons do not mesh well together. Rearrange and fix discrepancies! // TODO: icon themes and instance icons do not mesh well together. Rearrange and fix discrepancies!
// set icon theme search path! // set icon theme search path!
QDir themeFolder("iconthemes"); if (!m_iconThemeFolder.mkpath("."))
if (!themeFolder.mkpath("."))
themeWarningLog() << "Couldn't create icon theme folder"; themeWarningLog() << "Couldn't create icon theme folder";
themeDebugLog() << "Icon Theme Folder Path: " << themeFolder.absolutePath(); themeDebugLog() << "Icon Theme Folder Path: " << m_iconThemeFolder.absolutePath();
auto searchPaths = QIcon::themeSearchPaths(); auto searchPaths = QIcon::themeSearchPaths();
searchPaths.append(themeFolder.path()); searchPaths.append(m_iconThemeFolder.path());
QIcon::setThemeSearchPaths(searchPaths); QIcon::setThemeSearchPaths(searchPaths);
themeDebugLog() << "<> Initializing Icon Themes"; themeDebugLog() << "<> Initializing Icon Themes";
@ -95,7 +94,7 @@ void ThemeManager::initializeIcons()
themeDebugLog() << "Loaded Built-In Icon Theme" << id; themeDebugLog() << "Loaded Built-In Icon Theme" << id;
} }
QDirIterator directoryIterator(themeFolder.path(), QDir::Dirs | QDir::NoDotAndDotDot); QDirIterator directoryIterator(m_iconThemeFolder.path(), QDir::Dirs | QDir::NoDotAndDotDot);
while (directoryIterator.hasNext()) { while (directoryIterator.hasNext()) {
QDir dir(directoryIterator.next()); QDir dir(directoryIterator.next());
IconTheme theme(dir.dirName(), dir.path()); IconTheme theme(dir.dirName(), dir.path());
@ -120,12 +119,11 @@ void ThemeManager::initializeWidgets()
// TODO: need some way to differentiate same name themes in different subdirectories (maybe smaller grey text next to theme name in // TODO: need some way to differentiate same name themes in different subdirectories (maybe smaller grey text next to theme name in
// dropdown?) // dropdown?)
QDir themeFolder("themes"); if (!m_applicationThemeFolder.mkpath("."))
if (!themeFolder.mkpath("."))
themeWarningLog() << "Couldn't create theme folder"; themeWarningLog() << "Couldn't create theme folder";
themeDebugLog() << "Theme Folder Path: " << themeFolder.absolutePath(); themeDebugLog() << "Theme Folder Path: " << m_applicationThemeFolder.absolutePath();
QDirIterator directoryIterator(themeFolder.path(), QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); QDirIterator directoryIterator(m_applicationThemeFolder.path(), QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
while (directoryIterator.hasNext()) { while (directoryIterator.hasNext()) {
QDir dir(directoryIterator.next()); QDir dir(directoryIterator.next());
QFileInfo themeJson(dir.absoluteFilePath("theme.json")); QFileInfo themeJson(dir.absoluteFilePath("theme.json"));
@ -148,16 +146,6 @@ void ThemeManager::initializeWidgets()
themeDebugLog() << "<> Widget themes initialized."; themeDebugLog() << "<> Widget themes initialized.";
} }
QList<ITheme*> ThemeManager::getValidApplicationThemes()
{
QList<ITheme*> ret;
ret.reserve(m_themes.size());
for (auto&& [id, theme] : m_themes) {
ret.append(theme.get());
}
return ret;
}
QList<IconTheme*> ThemeManager::getValidIconThemes() QList<IconTheme*> ThemeManager::getValidIconThemes()
{ {
QList<IconTheme*> ret; QList<IconTheme*> ret;
@ -168,9 +156,14 @@ QList<IconTheme*> ThemeManager::getValidIconThemes()
return ret; return ret;
} }
bool ThemeManager::isValidApplicationTheme(const QString& id) QList<ITheme*> ThemeManager::getValidApplicationThemes()
{ {
return !id.isEmpty() && m_themes.find(id) != m_themes.end(); QList<ITheme*> ret;
ret.reserve(m_themes.size());
for (auto&& [id, theme] : m_themes) {
ret.append(theme.get());
}
return ret;
} }
bool ThemeManager::isValidIconTheme(const QString& id) bool ThemeManager::isValidIconTheme(const QString& id)
@ -178,6 +171,21 @@ bool ThemeManager::isValidIconTheme(const QString& id)
return !id.isEmpty() && m_icons.find(id) != m_icons.end(); return !id.isEmpty() && m_icons.find(id) != m_icons.end();
} }
bool ThemeManager::isValidApplicationTheme(const QString& id)
{
return !id.isEmpty() && m_themes.find(id) != m_themes.end();
}
QDir ThemeManager::getIconThemesFolder()
{
return m_iconThemeFolder;
}
QDir ThemeManager::getApplicationThemesFolder()
{
return m_applicationThemeFolder;
}
void ThemeManager::setIconTheme(const QString& name) void ThemeManager::setIconTheme(const QString& name)
{ {
if (m_icons.find(name) == m_icons.end()) { if (m_icons.find(name) == m_icons.end()) {

View File

@ -37,10 +37,12 @@ class ThemeManager {
public: public:
ThemeManager(); ThemeManager();
QList<ITheme*> getValidApplicationThemes();
QList<IconTheme*> getValidIconThemes(); QList<IconTheme*> getValidIconThemes();
bool isValidApplicationTheme(const QString& id); QList<ITheme*> getValidApplicationThemes();
bool isValidIconTheme(const QString& id); bool isValidIconTheme(const QString& id);
bool isValidApplicationTheme(const QString& id);
QDir getIconThemesFolder();
QDir getApplicationThemesFolder();
void applyCurrentlySelectedTheme(bool initial = false); void applyCurrentlySelectedTheme(bool initial = false);
void setIconTheme(const QString& name); void setIconTheme(const QString& name);
void setApplicationTheme(const QString& name, bool initial = false); void setApplicationTheme(const QString& name, bool initial = false);
@ -55,6 +57,8 @@ class ThemeManager {
private: private:
std::map<QString, std::unique_ptr<ITheme>> m_themes; std::map<QString, std::unique_ptr<ITheme>> m_themes;
std::map<QString, IconTheme> m_icons; std::map<QString, IconTheme> m_icons;
QDir m_iconThemeFolder{ "iconthemes" };
QDir m_applicationThemeFolder{ "themes" };
void initializeThemes(); void initializeThemes();
QString addTheme(std::unique_ptr<ITheme> theme); QString addTheme(std::unique_ptr<ITheme> theme);

View File

@ -19,17 +19,22 @@
#include "ui_ThemeCustomizationWidget.h" #include "ui_ThemeCustomizationWidget.h"
#include "Application.h" #include "Application.h"
#include "DesktopServices.h"
#include "ui/themes/ITheme.h" #include "ui/themes/ITheme.h"
#include "ui/themes/ThemeManager.h" #include "ui/themes/ThemeManager.h"
ThemeCustomizationWidget::ThemeCustomizationWidget(QWidget *parent) : QWidget(parent), ui(new Ui::ThemeCustomizationWidget) ThemeCustomizationWidget::ThemeCustomizationWidget(QWidget* parent) : QWidget(parent), ui(new Ui::ThemeCustomizationWidget)
{ {
ui->setupUi(this); ui->setupUi(this);
loadSettings(); loadSettings();
connect(ui->iconsComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyIconTheme); connect(ui->iconsComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyIconTheme);
connect(ui->widgetStyleComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyWidgetTheme); connect(ui->widgetStyleComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&ThemeCustomizationWidget::applyWidgetTheme);
connect(ui->backgroundCatComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyCatTheme); connect(ui->backgroundCatComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyCatTheme);
connect(ui->iconsFolder, &QPushButton::clicked, this, [] { DesktopServices::openDirectory(APPLICATION->themeManager()->getIconThemesFolder().path()); });
connect(ui->widgetStyleFolder, &QPushButton::clicked, this, [] { DesktopServices::openDirectory(APPLICATION->themeManager()->getApplicationThemesFolder().path()); });
} }
ThemeCustomizationWidget::~ThemeCustomizationWidget() ThemeCustomizationWidget::~ThemeCustomizationWidget()
@ -61,40 +66,44 @@ ThemeCustomizationWidget::~ThemeCustomizationWidget()
/// } /// }
/// </summary> /// </summary>
/// <param name="features"></param> /// <param name="features"></param>
void ThemeCustomizationWidget::showFeatures(ThemeFields features) { void ThemeCustomizationWidget::showFeatures(ThemeFields features)
{
ui->iconsComboBox->setEnabled(features & ThemeFields::ICONS); ui->iconsComboBox->setEnabled(features & ThemeFields::ICONS);
ui->iconsLabel->setEnabled(features & ThemeFields::ICONS); ui->iconsLabel->setEnabled(features & ThemeFields::ICONS);
ui->widgetStyleComboBox->setEnabled(features & ThemeFields::WIDGETS); ui->widgetStyleComboBox->setEnabled(features & ThemeFields::WIDGETS);
ui->widgetThemeLabel->setEnabled(features & ThemeFields::WIDGETS); ui->widgetStyleLabel->setEnabled(features & ThemeFields::WIDGETS);
ui->backgroundCatComboBox->setEnabled(features & ThemeFields::CAT); ui->backgroundCatComboBox->setEnabled(features & ThemeFields::CAT);
ui->backgroundCatLabel->setEnabled(features & ThemeFields::CAT); ui->backgroundCatLabel->setEnabled(features & ThemeFields::CAT);
} }
void ThemeCustomizationWidget::applyIconTheme(int index) { void ThemeCustomizationWidget::applyIconTheme(int index)
{
auto settings = APPLICATION->settings(); auto settings = APPLICATION->settings();
auto originalIconTheme = settings->get("IconTheme").toString(); auto originalIconTheme = settings->get("IconTheme").toString();
auto newIconTheme = ui->iconsComboBox->currentData().toString(); auto newIconTheme = ui->iconsComboBox->currentData().toString();
if (originalIconTheme != newIconTheme) { if (originalIconTheme != newIconTheme) {
settings->set("IconTheme", newIconTheme); settings->set("IconTheme", newIconTheme);
APPLICATION->applyCurrentlySelectedTheme(); APPLICATION->themeManager()->applyCurrentlySelectedTheme();
} }
emit currentIconThemeChanged(index); emit currentIconThemeChanged(index);
} }
void ThemeCustomizationWidget::applyWidgetTheme(int index) { void ThemeCustomizationWidget::applyWidgetTheme(int index)
{
auto settings = APPLICATION->settings(); auto settings = APPLICATION->settings();
auto originalAppTheme = settings->get("ApplicationTheme").toString(); auto originalAppTheme = settings->get("ApplicationTheme").toString();
auto newAppTheme = ui->widgetStyleComboBox->currentData().toString(); auto newAppTheme = ui->widgetStyleComboBox->currentData().toString();
if (originalAppTheme != newAppTheme) { if (originalAppTheme != newAppTheme) {
settings->set("ApplicationTheme", newAppTheme); settings->set("ApplicationTheme", newAppTheme);
APPLICATION->applyCurrentlySelectedTheme(); APPLICATION->themeManager()->applyCurrentlySelectedTheme();
} }
emit currentWidgetThemeChanged(index); emit currentWidgetThemeChanged(index);
} }
void ThemeCustomizationWidget::applyCatTheme(int index) { void ThemeCustomizationWidget::applyCatTheme(int index)
{
auto settings = APPLICATION->settings(); auto settings = APPLICATION->settings();
settings->set("BackgroundCat", m_catOptions[index].first); settings->set("BackgroundCat", m_catOptions[index].first);
@ -113,7 +122,7 @@ void ThemeCustomizationWidget::loadSettings()
{ {
auto currentIconTheme = settings->get("IconTheme").toString(); auto currentIconTheme = settings->get("IconTheme").toString();
auto iconThemes = APPLICATION->getValidIconThemes(); auto iconThemes = APPLICATION->themeManager()->getValidIconThemes();
int idx = 0; int idx = 0;
for (auto iconTheme : iconThemes) { for (auto iconTheme : iconThemes) {
QIcon iconForComboBox = QIcon(iconTheme->path() + "/scalable/settings"); QIcon iconForComboBox = QIcon(iconTheme->path() + "/scalable/settings");
@ -127,7 +136,7 @@ void ThemeCustomizationWidget::loadSettings()
{ {
auto currentTheme = settings->get("ApplicationTheme").toString(); auto currentTheme = settings->get("ApplicationTheme").toString();
auto themes = APPLICATION->getValidApplicationThemes(); auto themes = APPLICATION->themeManager()->getValidApplicationThemes();
int idx = 0; int idx = 0;
for (auto& theme : themes) { for (auto& theme : themes) {
ui->widgetStyleComboBox->addItem(theme->name(), theme->id()); ui->widgetStyleComboBox->addItem(theme->name(), theme->id());

View File

@ -40,6 +40,8 @@
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<layout class="QHBoxLayout" name="iconsLayout">
<item>
<widget class="QComboBox" name="iconsComboBox"> <widget class="QComboBox" name="iconsComboBox">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -52,8 +54,26 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="iconsFolder">
<property name="toolTip">
<string>View icon themes folder.</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="viewfolder"/>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="widgetThemeLabel"> <widget class="QLabel" name="widgetStyleLabel">
<property name="text"> <property name="text">
<string>&amp;Widgets</string> <string>&amp;Widgets</string>
</property> </property>
@ -63,6 +83,8 @@
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
<layout class="QHBoxLayout" name="widgetStyleLayout">
<item>
<widget class="QComboBox" name="widgetStyleComboBox"> <widget class="QComboBox" name="widgetStyleComboBox">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -75,6 +97,24 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="widgetStyleFolder">
<property name="toolTip">
<string>View widget themes folder.</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="viewfolder"/>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="backgroundCatLabel"> <widget class="QLabel" name="backgroundCatLabel">
<property name="toolTip"> <property name="toolTip">
@ -89,7 +129,7 @@
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="catLayout">
<item> <item>
<widget class="QComboBox" name="backgroundCatComboBox"> <widget class="QComboBox" name="backgroundCatComboBox">
<property name="sizePolicy"> <property name="sizePolicy">
@ -127,6 +167,12 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<tabstops>
<tabstop>iconsComboBox</tabstop>
<tabstop>widgetStyleComboBox</tabstop>
<tabstop>backgroundCatComboBox</tabstop>
<tabstop>catInfoLabel</tabstop>
</tabstops>
<resources/> <resources/>
<connections/> <connections/>
</ui> </ui>