Implement dynamic Settings Manager UI

This commit is contained in:
Adam Honse
2023-05-24 22:25:45 -05:00
parent d4b2d3c381
commit 67ae1a2078
11 changed files with 404 additions and 5 deletions

View File

@@ -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 \

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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 |

View File

@@ -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();

View File

@@ -0,0 +1,151 @@
#include "OpenRGBSettingsManagerEntry.h"
#include "ui_OpenRGBSettingsManagerEntry.h"
#include "ResourceManager.h"
#include "SettingsManager.h"
#include <QLabel>
#include <QSignalMapper>
#include <QVBoxLayout>
#include <QListWidget>
#include <QCheckBox>
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();
}

View File

@@ -0,0 +1,34 @@
#ifndef OPENRGBSETTINGSMANAGERENTRY_H
#define OPENRGBSETTINGSMANAGERENTRY_H
#include "ui_OpenRGBSettingsManagerEntry.h"
#include <QWidget>
#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

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OpenRGBSettingsManagerEntryUi</class>
<widget class="QWidget" name="OpenRGBSettingsManagerEntryUi">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>531</width>
<height>199</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>E131 settings entry</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="SettingsGroupBox">
<property name="title">
<string>SettingsKey</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -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);
}
}

View File

@@ -0,0 +1,33 @@
#ifndef OPENRGBSETTINGSMANAGERPAGE_H
#define OPENRGBSETTINGSMANAGERPAGE_H
#include "ui_OpenRGBSettingsManagerPage.h"
#include <QWidget>
#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<OpenRGBSettingsManagerEntry*> entries;
};
#endif // OPENRGBSETTINGSMANAGERPAGE_H

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OpenRGBSettingsManagerPageUi</class>
<widget class="QWidget" name="OpenRGBSettingsManagerPageUi">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>E131 settings page</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QListWidget" name="SettingsEntryList">
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>