From 67ae1a207869628aab0a41f6c88a66479ebfc60b Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Wed, 24 May 2023 22:25:45 -0500 Subject: [PATCH] Implement dynamic Settings Manager UI --- OpenRGB.pro | 6 + SettingsManager.cpp | 10 ++ SettingsManager.h | 13 +- qt/OpenRGBDialog2/OpenRGBDialog2.cpp | 54 ++++++- qt/OpenRGBDialog2/OpenRGBDialog2.h | 3 + .../OpenRGBSettingsManagerEntry.cpp | 151 ++++++++++++++++++ .../OpenRGBSettingsManagerEntry.h | 34 ++++ .../OpenRGBSettingsManagerEntry.ui | 34 ++++ .../OpenRGBSettingsManagerPage.cpp | 43 +++++ .../OpenRGBSettingsManagerPage.h | 33 ++++ .../OpenRGBSettingsManagerPage.ui | 28 ++++ 11 files changed, 404 insertions(+), 5 deletions(-) create mode 100644 qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerEntry.cpp create mode 100644 qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerEntry.h create mode 100644 qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerEntry.ui create mode 100644 qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.cpp create mode 100644 qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.h create mode 100644 qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.ui diff --git a/OpenRGB.pro b/OpenRGB.pro index f41aa9a25..20a2d0d25 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -309,6 +309,8 @@ HEADERS += qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsEntry.h \ qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsPage.h \ qt/OpenRGBServerInfoPage/OpenRGBServerInfoPage.h \ + qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerEntry.h \ + qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.h \ qt/OpenRGBSettingsPage/OpenRGBSettingsPage.h \ qt/OpenRGBSoftwareInfoPage/OpenRGBSoftwareInfoPage.h \ qt/OpenRGBSupportedDevicesPage/OpenRGBSupportedDevicesPage.h \ @@ -912,6 +914,8 @@ SOURCES += qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsEntry.cpp \ qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsPage.cpp \ qt/OpenRGBServerInfoPage/OpenRGBServerInfoPage.cpp \ + qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerEntry.cpp \ + qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.cpp \ qt/OpenRGBSettingsPage/OpenRGBSettingsPage.cpp \ qt/OpenRGBSoftwareInfoPage/OpenRGBSoftwareInfoPage.cpp \ qt/OpenRGBSupportedDevicesPage/OpenRGBSupportedDevicesPage.cpp \ @@ -1606,6 +1610,8 @@ FORMS += qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsEntry.ui \ qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsPage.ui \ qt/OpenRGBServerInfoPage/OpenRGBServerInfoPage.ui \ + qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerEntry.ui \ + qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.ui \ qt/OpenRGBSettingsPage/OpenRGBSettingsPage.ui \ qt/OpenRGBSoftwareInfoPage/OpenRGBSoftwareInfoPage.ui \ qt/OpenRGBSupportedDevicesPage/OpenRGBSupportedDevicesPage.ui \ diff --git a/SettingsManager.cpp b/SettingsManager.cpp index 93a804101..d8abad382 100644 --- a/SettingsManager.cpp +++ b/SettingsManager.cpp @@ -110,3 +110,13 @@ void SettingsManager::SaveSettings() settings_file.close(); } } + +void SettingsManager::RegisterSettingsPrototype(std::string settings_key, json new_prototype) +{ + settings_prototype[settings_key] = new_prototype; +} + +json SettingsManager::GetSettingsPrototype() +{ + return(settings_prototype); +} diff --git a/SettingsManager.h b/SettingsManager.h index 3e1e3e849..d7b3c6cd0 100644 --- a/SettingsManager.h +++ b/SettingsManager.h @@ -19,11 +19,13 @@ using json = nlohmann::json; class SettingsManagerInterface { public: - virtual json GetSettings(std::string settings_key) = 0; - virtual void SetSettings(std::string settings_key, json new_settings) = 0; + virtual json GetSettings(std::string settings_key) = 0; + virtual void SetSettings(std::string settings_key, json new_settings) = 0; - virtual void LoadSettings(const filesystem::path& filename) = 0; - virtual void SaveSettings() = 0; + virtual void LoadSettings(const filesystem::path& filename) = 0; + virtual void SaveSettings() = 0; + + virtual void RegisterSettingsPrototype(std::string settings_key, json new_prototype) = 0; protected: virtual ~SettingsManagerInterface() {}; @@ -41,6 +43,9 @@ public: void LoadSettings(const filesystem::path& filename) override; void SaveSettings() override; + void RegisterSettingsPrototype(std::string settings_key, json new_prototype) override; + json GetSettingsPrototype(); + private: json settings_data; json settings_prototype; diff --git a/qt/OpenRGBDialog2/OpenRGBDialog2.cpp b/qt/OpenRGBDialog2/OpenRGBDialog2.cpp index df3a41170..df85c8464 100644 --- a/qt/OpenRGBDialog2/OpenRGBDialog2.cpp +++ b/qt/OpenRGBDialog2/OpenRGBDialog2.cpp @@ -167,6 +167,25 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op QIcon logo(":OpenRGB.png"); setWindowIcon(logo); + /*-----------------------------------------------------*\ + | Create UserInterface settings prototype | + \*-----------------------------------------------------*/ + json ui_settings_proto; + + ui_settings_proto["numerical_labels"]["name"] = "Numerical Labels"; + ui_settings_proto["numerical_labels"]["type"] = "boolean"; + + ui_settings_proto["disable_key_expansion"]["name"] = "Disable Key Expansion"; + ui_settings_proto["disable_key_expansion"]["type"] = "boolean"; + + ui_settings_proto["greyscale_tray_icon"]["name"] = "Greyscale Tray Icon"; + ui_settings_proto["greyscale_tray_icon"]["type"] = "boolean"; + + ui_settings_proto["minimize_on_close"]["name"] = "Minimize On Close"; + ui_settings_proto["minimize_on_close"]["type"] = "boolean"; + + settings_manager->RegisterSettingsPrototype(ui_string, ui_settings_proto); + /*-----------------------------------------------------*\ | Set window geometry from config (if available) | \*-----------------------------------------------------*/ @@ -413,6 +432,11 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op \*-----------------------------------------------------*/ AddSettingsPage(); + /*-----------------------------------------------------*\ + | Add the settings manager page | + \*-----------------------------------------------------*/ + AddSettingsManagerPage(); + /*-----------------------------------------------------*\ | Add the Supported Devices page | \*-----------------------------------------------------*/ @@ -716,6 +740,34 @@ void OpenRGBDialog2::AddSettingsPage() connect(this, SIGNAL(ProfileListChanged()), SettingsPage, SLOT(UpdateProfiles())); } +void OpenRGBDialog2::AddSettingsManagerPage() +{ + /*-----------------------------------------------------*\ + | Create the SettingsManager page | + \*-----------------------------------------------------*/ + SettingsManagerPage = new OpenRGBSettingsManagerPage(); + + ui->SettingsTabBar->addTab(SettingsManagerPage, ""); + + QString SettingsLabelString; + + if(OpenRGBThemeManager::IsDarkTheme()) + { + SettingsLabelString = "settings_dark.png"; + } + else + { + SettingsLabelString = "settings.png"; + } + + /*-----------------------------------------------------*\ + | Create the tab label | + \*-----------------------------------------------------*/ + TabLabel* SettingsTabLabel = new TabLabel(OpenRGBFont::options, tr("Settings Manager"), (char *)"Settings Manager", (char *)context); + + ui->SettingsTabBar->tabBar()->setTabButton(ui->SettingsTabBar->tabBar()->count() - 1, QTabBar::LeftSide, SettingsTabLabel); +} + void OpenRGBDialog2::AddDMXSettingsPage() { /*-----------------------------------------------------*\ @@ -853,7 +905,7 @@ void OpenRGBDialog2::AddSerialSettingsPage() \*-----------------------------------------------------*/ SerialSettingsPage = new OpenRGBSerialSettingsPage(); - ui->SettingsTabBar->addTab(SerialSettingsPage, ""); + ui->SettingsTabBar->addTab(SerialSettingsPage, ""); /*-----------------------------------------------------*\ | Create the tab label | diff --git a/qt/OpenRGBDialog2/OpenRGBDialog2.h b/qt/OpenRGBDialog2/OpenRGBDialog2.h index 907cb4653..940776d4f 100644 --- a/qt/OpenRGBDialog2/OpenRGBDialog2.h +++ b/qt/OpenRGBDialog2/OpenRGBDialog2.h @@ -18,6 +18,7 @@ #include "OpenRGBPhilipsWizSettingsPage/OpenRGBPhilipsWizSettingsPage.h" #include "OpenRGBQMKORGBSettingsPage/OpenRGBQMKORGBSettingsPage.h" #include "OpenRGBSerialSettingsPage/OpenRGBSerialSettingsPage.h" +#include "OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.h" #include "OpenRGBYeelightSettingsPage/OpenRGBYeelightSettingsPage.h" #include "OpenRGBNanoleafSettingsPage/OpenRGBNanoleafSettingsPage.h" #include "PluginManager.h" @@ -94,6 +95,7 @@ private: OpenRGBPhilipsWizSettingsPage *PhilipsWizSettingsPage; OpenRGBQMKORGBSettingsPage *QMKORGBSettingsPage; OpenRGBSerialSettingsPage *SerialSettingsPage; + OpenRGBSettingsManagerPage *SettingsManagerPage; OpenRGBYeelightSettingsPage *YeelightSettingsPage; OpenRGBNanoleafSettingsPage *NanoleafSettingsPage; @@ -114,6 +116,7 @@ private: void AddSoftwareInfoPage(); void AddSupportedDevicesPage(); void AddSettingsPage(); + void AddSettingsManagerPage(); void AddDMXSettingsPage(); void AddE131SettingsPage(); void AddElgatoKeyLightSettingsPage(); diff --git a/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerEntry.cpp b/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerEntry.cpp new file mode 100644 index 000000000..bc717086d --- /dev/null +++ b/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerEntry.cpp @@ -0,0 +1,151 @@ +#include "OpenRGBSettingsManagerEntry.h" +#include "ui_OpenRGBSettingsManagerEntry.h" +#include "ResourceManager.h" +#include "SettingsManager.h" +#include +#include +#include +#include +#include + +using namespace Ui; + +class SettingsManagerEntryPointer : public QObject +{ +public: + std::string key; + QWidget * widget; +}; + +OpenRGBSettingsManagerEntry::OpenRGBSettingsManagerEntry(std::string settings_key, json settings_proto, QWidget *parent) : + QWidget(parent), + ui(new Ui::OpenRGBSettingsManagerEntryUi) +{ + /*-----------------------------------------------------*\ + | Store settings key, prototype, and data | + \*-----------------------------------------------------*/ + key = settings_key; + proto = settings_proto; + data = ResourceManager::get()->GetSettingsManager()->GetSettings(key); + + ui->setupUi(this); + + /*-----------------------------------------------------*\ + | Set the title of the group to the settings key | + \*-----------------------------------------------------*/ + ui->SettingsGroupBox->setTitle(QString::fromStdString(key)); + + /*-----------------------------------------------------*\ + | Create a vertical layout to hold the settings controls| + \*-----------------------------------------------------*/ + QVBoxLayout* layout = new QVBoxLayout; + ui->SettingsGroupBox->setLayout(layout); + + /*-----------------------------------------------------*\ + | Set up a signal mapper to handle settings changes | + \*-----------------------------------------------------*/ + QSignalMapper* signalMapper = new QSignalMapper(this); + connect(signalMapper, SIGNAL(mapped(QObject *)), this, SLOT(onSettingChanged(QObject *))); + + /*-----------------------------------------------------*\ + | Loop through all settings in this key | + \*-----------------------------------------------------*/ + for(json::const_iterator it = proto.begin(); it != proto.end(); it++) + { + /*-------------------------------------------------*\ + | Gather information about this setting | + \*-------------------------------------------------*/ + std::string item_key = it.key(); + std::string name = proto[it.key()]["name"]; + std::string type = proto[it.key()]["type"]; + + /*-------------------------------------------------*\ + | Create widget pointer for this setting | + \*-------------------------------------------------*/ + QWidget* item; + + /*-------------------------------------------------*\ + | Create settings manager entry pointer to map | + | settings widget events to their keys | + \*-------------------------------------------------*/ + SettingsManagerEntryPointer * new_arg = new SettingsManagerEntryPointer(); + new_arg->key = it.key(); + + /*-------------------------------------------------*\ + | Create widgets for boolean settings | + \*-------------------------------------------------*/ + if(type == "boolean") + { + /*---------------------------------------------*\ + | Boolean settings use a checkbox widget | + \*---------------------------------------------*/ + item = new QCheckBox; + new_arg->widget = item; + + /*---------------------------------------------*\ + | Set the checkbox label to the setting name | + \*---------------------------------------------*/ + ((QCheckBox*)item)->setText(QString::fromStdString(name)); + + /*---------------------------------------------*\ + | Set the checkbox state based on the current | + | value of the setting | + \*---------------------------------------------*/ + if(data.contains(item_key)) + { + ((QCheckBox*)item)->setChecked(data[item_key]); + } + + /*---------------------------------------------*\ + | Connect widget to signal mapper to handle | + | changes to this setting | + \*---------------------------------------------*/ + connect(item, SIGNAL(clicked()), signalMapper, SLOT(map())); + signalMapper->setMapping(item, new_arg); + } + + /*-------------------------------------------------*\ + | Add widget to the vertical layout | + \*-------------------------------------------------*/ + layout->addWidget(item); + } +} + +OpenRGBSettingsManagerEntry::~OpenRGBSettingsManagerEntry() +{ + delete ui; +} + +void OpenRGBSettingsManagerEntry::changeEvent(QEvent *event) +{ + if(event->type() == QEvent::LanguageChange) + { + ui->retranslateUi(this); + } +} + +void OpenRGBSettingsManagerEntry::onSettingChanged(QObject * arg) +{ + /*-----------------------------------------------------*\ + | Read information from argument | + \*-----------------------------------------------------*/ + SettingsManagerEntryPointer * setting = (SettingsManagerEntryPointer *)arg; + std::string item_key = setting->key; + std::string type = proto[item_key]["type"]; + + /*-----------------------------------------------------*\ + | Handle boolean settings changes | + \*-----------------------------------------------------*/ + if(type == "boolean") + { + bool value = ((QCheckBox *)setting->widget)->isChecked(); + + data[item_key] = value; + } + + /*-----------------------------------------------------*\ + | Set and save the updated settings | + \*-----------------------------------------------------*/ + ResourceManager::get()->GetSettingsManager()->SetSettings(key, data); + ResourceManager::get()->GetSettingsManager()->SaveSettings(); +} diff --git a/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerEntry.h b/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerEntry.h new file mode 100644 index 000000000..0e20d0d2a --- /dev/null +++ b/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerEntry.h @@ -0,0 +1,34 @@ +#ifndef OPENRGBSETTINGSMANAGERENTRY_H +#define OPENRGBSETTINGSMANAGERENTRY_H + +#include "ui_OpenRGBSettingsManagerEntry.h" +#include +#include "ResourceManager.h" +#include "json.hpp" + +using json = nlohmann::json; + +namespace Ui { +class OpenRGBSettingsManagerEntry; +} + +class Ui::OpenRGBSettingsManagerEntry : public QWidget +{ + Q_OBJECT + +public: + explicit OpenRGBSettingsManagerEntry(std::string settings_key, json settings_proto, QWidget *parent = nullptr); + ~OpenRGBSettingsManagerEntry(); + Ui::OpenRGBSettingsManagerEntryUi *ui; + +private slots: + void changeEvent(QEvent *event); + void onSettingChanged(QObject * arg); + +private: + std::string key; + json data; + json proto; +}; + +#endif // OPENRGBSETTINGSMANAGERENTRY_H diff --git a/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerEntry.ui b/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerEntry.ui new file mode 100644 index 000000000..dd5d96ebd --- /dev/null +++ b/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerEntry.ui @@ -0,0 +1,34 @@ + + + OpenRGBSettingsManagerEntryUi + + + + 0 + 0 + 531 + 199 + + + + + 0 + 0 + + + + E131 settings entry + + + + + + SettingsKey + + + + + + + + diff --git a/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.cpp b/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.cpp new file mode 100644 index 000000000..487b9f3cb --- /dev/null +++ b/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.cpp @@ -0,0 +1,43 @@ +#include "OpenRGBSettingsManagerPage.h" +#include "ui_OpenRGBSettingsManagerPage.h" +#include "ResourceManager.h" +#include "SettingsManager.h" + +using namespace Ui; + +OpenRGBSettingsManagerPage::OpenRGBSettingsManagerPage(QWidget *parent) : + QWidget(parent), + ui(new Ui::OpenRGBSettingsManagerPageUi) +{ + ui->setupUi(this); + + json settings_prototype = ResourceManager::get()->GetSettingsManager()->GetSettingsPrototype(); + + for(json::const_iterator it = settings_prototype.begin(); it != settings_prototype.end(); it++) + { + OpenRGBSettingsManagerEntry* new_entry = new OpenRGBSettingsManagerEntry(it.key(), settings_prototype[it.key()]); + + entries.push_back(new_entry); + + QListWidgetItem* item = new QListWidgetItem; + + item->setSizeHint(new_entry->sizeHint()); + + ui->SettingsEntryList->addItem(item); + ui->SettingsEntryList->setItemWidget(item, new_entry); + ui->SettingsEntryList->show(); + } +} + +OpenRGBSettingsManagerPage::~OpenRGBSettingsManagerPage() +{ + delete ui; +} + +void OpenRGBSettingsManagerPage::changeEvent(QEvent *event) +{ + if(event->type() == QEvent::LanguageChange) + { + ui->retranslateUi(this); + } +} diff --git a/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.h b/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.h new file mode 100644 index 000000000..4c50d841b --- /dev/null +++ b/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.h @@ -0,0 +1,33 @@ +#ifndef OPENRGBSETTINGSMANAGERPAGE_H +#define OPENRGBSETTINGSMANAGERPAGE_H + +#include "ui_OpenRGBSettingsManagerPage.h" +#include + +#include "OpenRGBSettingsManagerEntry.h" +#include "json.hpp" + +using json = nlohmann::json; + +namespace Ui { +class OpenRGBSettingsManagerPage; +} + +class Ui::OpenRGBSettingsManagerPage : public QWidget +{ + Q_OBJECT + +public: + explicit OpenRGBSettingsManagerPage(QWidget *parent = nullptr); + ~OpenRGBSettingsManagerPage(); + +private slots: + void changeEvent(QEvent *event); + +private: + Ui::OpenRGBSettingsManagerPageUi* ui; + std::vector entries; + +}; + +#endif // OPENRGBSETTINGSMANAGERPAGE_H diff --git a/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.ui b/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.ui new file mode 100644 index 000000000..24d0a6d6d --- /dev/null +++ b/qt/OpenRGBSettingsManagerPage/OpenRGBSettingsManagerPage.ui @@ -0,0 +1,28 @@ + + + OpenRGBSettingsManagerPageUi + + + + 0 + 0 + 400 + 300 + + + + E131 settings page + + + + + + QAbstractItemView::ScrollPerPixel + + + + + + + +