Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add file and color controller setting types #13669

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions res/controllers/Dummy Device Screen.hid.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,62 @@
<product protocol="hid" vendor_id="0xdead" product_id="0xbeaf" />
</devices>
</info>
<settings>
<group label="Cosmetic">
<row orientation="vertical">
<option
variable="theme"
type="enum"
label="Theme use for the screen">
<description>
The theme used for the screens
</description>
<value label="Classic" default="true">stock</value>
<value label="Advanced">advanced</value>
</option>
<option
variable="idleBackground"
type="file"
pattern="Images (*.png *.gif *.jpg)"
label="Idle deck background">
<description>
The background used for empty decks
</description>
</option>
<option
variable="accentColor"
type="color"
default="orange"
label="Accent color">
<description>
The background used for empty decks
</description>
</option>
<option
variable="deckA"
type="enum"
label="Deck A">
<value color="#FF0000" label="Red">red</value>
<value color="#FF5E00" label="Carrot">carrot</value>
<value color="#FF7800" label="Orange">orange</value>
<value color="#FF9200" label="Honey">honey</value>
<value color="#FFFF00" label="Yellow">yellow</value>
<value color="#81FF00" label="Lime">lime</value>
<value color="#00FF00" label="Green">green</value>
<value color="#00FF49" label="Aqua">aqua</value>
<value color="#00FFFF" label="Celeste">celeste</value>
<value color="#0091FF" label="Sky">sky</value>
<value color="#0000FF" label="Blue">blue</value>
<value color="#FF00FF" label="Purple">purple</value>
<value color="#FF0091" label="Fuscia">fuscia</value>
<value color="#FF0079" label="Magenta">magenta</value>
<value color="#FF477E" label="Azalea">azalea</value>
<value color="#FF4761" label="Salmon">salmon</value>
<value color="#FFFFFF" label="White">white</value>
</option>
</row>
</group>
</settings>
<controller id="DummyDevice">
<screens>
<screen identifier="main" width="480" height="360" targetFps="20" pixelType="RBGA" splashoff="500" />
Expand Down
172 changes: 167 additions & 5 deletions src/controllers/legacycontrollersettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@

#include <util/assert.h>

#include <QBoxLayout>
#include <QCheckBox>
#include <QColorDialog>
#include <QComboBox>
#include <QDoubleSpinBox>
#include <QFileDialog>
#include <QLabel>
#include <QLayout>
#include <QPainter>
#include <QPixmap>
#include <QPushButton>
#include <QSpinBox>
#include <QStringLiteral>

#include "moc_legacycontrollersettings.cpp"

Expand Down Expand Up @@ -54,6 +61,8 @@ LegacyControllerSettingBuilder::LegacyControllerSettingBuilder() {
registerType<LegacyControllerIntegerSetting>();
registerType<LegacyControllerRealSetting>();
registerType<LegacyControllerEnumSetting>();
registerType<LegacyControllerColorSetting>();
registerType<LegacyControllerFileSetting>();
}

AbstractLegacyControllerSetting::AbstractLegacyControllerSetting(const QDomElement& element) {
Expand Down Expand Up @@ -221,7 +230,15 @@ LegacyControllerEnumSetting::LegacyControllerEnumSetting(
!value.isNull();
value = value.nextSiblingElement("value")) {
QString val = value.text();
m_options.append(std::tuple<QString, QString>(val, value.attribute("label", val)));
QColor color = QColor(value.attribute("color"));
// TODO: Remove once we mandate GCC 10/Clang 16
#if defined(__cpp_aggregate_paren_init) && \
__cpp_aggregate_paren_init >= 201902L && \
!defined(_MSC_VER) // FIXME: Bug in MSVC preventing the use of this feature
m_options.emplace_back(val, value.attribute("label", val), color);
#else
m_options.emplace_back(Item{val, value.attribute("label", val), color});
#endif
if (value.hasAttribute("default")) {
m_defaultValue = pos;
}
Expand All @@ -239,8 +256,8 @@ void LegacyControllerEnumSetting::parse(const QString& in, bool* ok) {
save();

size_t pos = 0;
for (const auto& value : std::as_const(m_options)) {
if (std::get<0>(value) == in) {
for (const auto& item : std::as_const(m_options)) {
if (item.value == in) {
if (ok != nullptr) {
*ok = true;
}
Expand All @@ -255,8 +272,15 @@ void LegacyControllerEnumSetting::parse(const QString& in, bool* ok) {
QWidget* LegacyControllerEnumSetting::buildInputWidget(QWidget* pParent) {
auto* pComboBox = new QComboBox(pParent);

for (const auto& value : std::as_const(m_options)) {
pComboBox->addItem(std::get<1>(value));
for (const auto& item : std::as_const(m_options)) {
if (item.color.isValid()) {
QPixmap icon(24, 24);
QPainter painter(&icon);
painter.fillRect(0, 0, 24, 24, item.color);
pComboBox->addItem(QIcon(icon), item.label);
} else {
pComboBox->addItem(item.label);
}
}
pComboBox->setCurrentIndex(static_cast<int>(m_editedValue));

Expand All @@ -274,3 +298,141 @@ QWidget* LegacyControllerEnumSetting::buildInputWidget(QWidget* pParent) {

return pComboBox;
}

LegacyControllerColorSetting::LegacyControllerColorSetting(
const QDomElement& element)
: AbstractLegacyControllerSetting(element),
m_defaultValue(QColor(element.attribute("default"))),
m_savedValue(m_defaultValue),
m_editedValue(m_defaultValue) {
reset();
save();
}

LegacyControllerColorSetting::~LegacyControllerColorSetting() = default;

void LegacyControllerColorSetting::parse(const QString& in, bool* ok) {
if (ok != nullptr) {
*ok = false;
}
reset();
save();

m_savedValue = QColor(in);
if (ok != nullptr) {
*ok = m_editedValue.isValid();
}
if (!m_editedValue.isValid()) {
return;
}
m_editedValue = m_savedValue;
}

QWidget* LegacyControllerColorSetting::buildInputWidget(QWidget* pParent) {
auto* pPushButton = new QPushButton(tr("Change color"), pParent);

auto setColorIcon = [pPushButton](const QColor& color) {
QPixmap icon(24, 24);
QPainter painter(&icon);
painter.fillRect(0, 0, 24, 24, color);
pPushButton->setIcon(QIcon(icon));
};

connect(this,
&AbstractLegacyControllerSetting::valueReset,
pPushButton,
[this, pPushButton, setColorIcon]() {
if (m_editedValue.isValid()) {
setColorIcon(m_editedValue);
} else {
pPushButton->setIcon(QIcon());
}
});

connect(pPushButton, &QPushButton::clicked, this, [this, pPushButton, setColorIcon](bool) {
auto color = QColorDialog::getColor(m_editedValue, pPushButton, tr("Choose a new color"));
if (color.isValid()) {
m_editedValue = color;
setColorIcon(color);
emit changed();
}
});

if (m_savedValue.isValid()) {
setColorIcon(m_savedValue);
}

return pPushButton;
}

LegacyControllerFileSetting::LegacyControllerFileSetting(
const QDomElement& element)
: AbstractLegacyControllerSetting(element),
m_fileFilter(element.attribute("pattern")),
m_defaultValue(QFileInfo(element.attribute("default"))),
m_savedValue(m_defaultValue),
m_editedValue(m_defaultValue) {
reset();
save();
}
LegacyControllerFileSetting::~LegacyControllerFileSetting() = default;

void LegacyControllerFileSetting::parse(const QString& in, bool* ok) {
if (ok != nullptr) {
*ok = false;
}
reset();
save();

m_editedValue = QFileInfo(in);
if (ok != nullptr) {
*ok = m_editedValue.exists();
}
if (!m_editedValue.exists()) {
return;
}
m_savedValue = m_editedValue;
}

QWidget* LegacyControllerFileSetting::buildInputWidget(QWidget* pParent) {
auto* pWidget = new QWidget(pParent);
pWidget->setLayout(new QHBoxLayout);
auto* pPushButton = new QPushButton(tr("Browse..."), pWidget);
auto* pLabel = new QLabel(pWidget);
auto setLabelText = [pLabel](QString&& text) {
pLabel->setText(QStringLiteral("<i>%1</i>").arg(text));
};
pWidget->layout()->addWidget(pLabel);
pWidget->layout()->addWidget(pPushButton);

connect(this, &AbstractLegacyControllerSetting::valueReset, pLabel, [this, setLabelText]() {
if (m_editedValue.exists()) {
setLabelText(m_editedValue.absoluteFilePath());
} else {
setLabelText(tr("No file selected"));
}
});

connect(pPushButton,
&QPushButton::clicked,
this,
[this, pLabel, pPushButton](bool) {
auto file = QFileInfo(QFileDialog::getOpenFileName(pPushButton,
tr("Select a file"),
QString(),
m_fileFilter));
if (file.exists()) {
m_editedValue = file;
pLabel->setText(QStringLiteral("<i>%1</i>").arg(file.absoluteFilePath()));
emit changed();
}
});

if (m_savedValue.exists()) {
setLabelText(m_savedValue.absoluteFilePath());
} else {
setLabelText(tr("No file selected"));
}

return pWidget;
}
Loading
Loading