Allow customizing foreground color of status icons
This commit is contained in:
parent
0e7cc8ba9b
commit
96ed888e20
|
@ -8,10 +8,28 @@
|
|||
namespace Data {
|
||||
|
||||
/*!
|
||||
* \brief Generates the SVG code for the Syncthing icon with the specified colors and status emblem.
|
||||
* \brief Generates the SVG code for the Syncthing icon with the specified \a colors and status emblem.
|
||||
*/
|
||||
QByteArray makeSyncthingIcon(const GradientColor &gradientColor, StatusEmblem statusEmblem)
|
||||
QByteArray makeSyncthingIcon(const StatusIconColorSet &colors, StatusEmblem statusEmblem)
|
||||
{
|
||||
// serialize colors
|
||||
auto gradientStartColor = colors.backgroundStart.name(QColor::HexRgb);
|
||||
auto gradientEndColor = colors.backgroundEnd.name(QColor::HexRgb);
|
||||
if (colors.backgroundStart.alphaF() < 1.0) {
|
||||
gradientStartColor += QStringLiteral(";stop-opacity:") + QString::number(colors.backgroundStart.alphaF());
|
||||
}
|
||||
if (colors.backgroundEnd.alphaF() < 1.0) {
|
||||
gradientEndColor += QStringLiteral(";stop-opacity:") + QString::number(colors.backgroundEnd.alphaF());
|
||||
}
|
||||
auto fillColor = colors.foreground.name(QColor::HexRgb);
|
||||
auto strokeColor = fillColor;
|
||||
if (colors.foreground.alphaF() < 1.0) {
|
||||
const auto alpha = QString::number(colors.foreground.alphaF());
|
||||
fillColor += QStringLiteral(";fill-opacity:") + alpha;
|
||||
strokeColor += QStringLiteral(";stroke-opacity:") + alpha;
|
||||
}
|
||||
|
||||
// make SVG document
|
||||
// clang-format off
|
||||
static const QString emblems[] = {
|
||||
QString(),
|
||||
|
@ -60,21 +78,13 @@ QByteArray makeSyncthingIcon(const GradientColor &gradientColor, StatusEmblem st
|
|||
),
|
||||
};
|
||||
const auto &emblemData = emblems[static_cast<int>(statusEmblem)];
|
||||
auto gradientStart = gradientColor.start.name(QColor::HexRgb);
|
||||
auto gradientEnd = gradientColor.end.name(QColor::HexRgb);
|
||||
if (gradientColor.start.alphaF() < 1.0) {
|
||||
gradientStart += QStringLiteral(";stop-opacity:") + QString::number(gradientColor.start.alphaF());
|
||||
}
|
||||
if (gradientColor.end.alphaF() < 1.0) {
|
||||
gradientEnd += QStringLiteral(";stop-opacity:") + QString::number(gradientColor.end.alphaF());
|
||||
}
|
||||
return (QStringLiteral(
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
|
||||
"<svg xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\">"
|
||||
"<defs>"
|
||||
"<linearGradient id=\"grad\" gradientUnits=\"userSpaceOnUse\" x1=\"8\" y1=\"0\" x2=\"8\" y2=\"16\">"
|
||||
"<stop offset=\"0\" style=\"stop-color:") % gradientStart % QStringLiteral("\"/>"
|
||||
"<stop offset=\"1\" style=\"stop-color:") % gradientEnd % QStringLiteral("\"/>"
|
||||
"<stop offset=\"0\" style=\"stop-color:") % gradientStartColor % QStringLiteral("\"/>"
|
||||
"<stop offset=\"1\" style=\"stop-color:") % gradientEndColor % QStringLiteral("\"/>"
|
||||
"</linearGradient>"
|
||||
"<mask id=\"bitemask\" maskUnits=\"userSpaceOnUse\">"
|
||||
"<g>"
|
||||
|
@ -85,14 +95,14 @@ QByteArray makeSyncthingIcon(const GradientColor &gradientColor, StatusEmblem st
|
|||
"</defs>"
|
||||
"<g id=\"syncthing-logo\" mask=\"url(#bitemask)\">"
|
||||
"<circle id=\"outer\" cx=\"8\" cy=\"8\" r=\"8\" style=\"fill:url(#grad)\"/>"
|
||||
"<circle id=\"inner\" cx=\"8\" cy=\"7.9727402\" r=\"5.9557071\" style=\"fill:none;stroke:#ffffff;stroke-width:0.81771719\"/>"
|
||||
"<line id=\"arm-l\" x1=\"9.1993189\" y1=\"8.776825\" x2=\"2.262351\" y2=\"9.4173737\" style=\"stroke:#ffffff;stroke-width:0.81771719\"/>"
|
||||
"<line id=\"arm-tr\" x1=\"9.1993189\" y1=\"8.776825\" x2=\"13.301533\" y2=\"5.3696747\" style=\"stroke:#ffffff;stroke-width:0.81771719\"/>"
|
||||
"<line id=\"arm-br\" x1=\"9.1993189\" y1=\"8.776825\" x2=\"11.788756\" y2=\"12.51107\" style=\"stroke:#ffffff;stroke-width:0.81771719\"/>"
|
||||
"<circle id=\"node-c\" cx=\"9.1993189\" cy=\"8.776825\" r=\"1.22\" style=\"fill:#ffffff\"/>"
|
||||
"<circle id=\"node-l\" cx=\"2.262351\" cy=\"9.4173737\" r=\"1.22\" style=\"fill:#ffffff\"/>"
|
||||
"<circle id=\"node-tr\" cx=\"13.301533\" cy=\"5.3696747\" r=\"1.22\" style=\"fill:#ffffff\"/>"
|
||||
"<circle id=\"node-br\" cx=\"11.788756\" cy=\"12.51107\" r=\"1.22\" style=\"fill:#ffffff\"/>"
|
||||
"<circle id=\"inner\" cx=\"8\" cy=\"7.9727402\" r=\"5.9557071\" style=\"fill:none;stroke:") % strokeColor % QStringLiteral(";stroke-width:0.81771719\"/>"
|
||||
"<line id=\"arm-l\" x1=\"9.1993189\" y1=\"8.776825\" x2=\"2.262351\" y2=\"9.4173737\" style=\"stroke:") % strokeColor % QStringLiteral(";stroke-width:0.81771719\"/>"
|
||||
"<line id=\"arm-tr\" x1=\"9.1993189\" y1=\"8.776825\" x2=\"13.301533\" y2=\"5.3696747\" style=\"stroke:") % strokeColor % QStringLiteral(";stroke-width:0.81771719\"/>"
|
||||
"<line id=\"arm-br\" x1=\"9.1993189\" y1=\"8.776825\" x2=\"11.788756\" y2=\"12.51107\" style=\"stroke:") % strokeColor % QStringLiteral(";stroke-width:0.81771719\"/>"
|
||||
"<circle id=\"node-c\" cx=\"9.1993189\" cy=\"8.776825\" r=\"1.22\" style=\"fill:") % fillColor % QStringLiteral("\"/>"
|
||||
"<circle id=\"node-l\" cx=\"2.262351\" cy=\"9.4173737\" r=\"1.22\" style=\"fill:") % fillColor % QStringLiteral("\"/>"
|
||||
"<circle id=\"node-tr\" cx=\"13.301533\" cy=\"5.3696747\" r=\"1.22\" style=\"fill:") % fillColor % QStringLiteral("\"/>"
|
||||
"<circle id=\"node-br\" cx=\"11.788756\" cy=\"12.51107\" r=\"1.22\" style=\"fill:") % fillColor % QStringLiteral("\"/>"
|
||||
"</g>") %
|
||||
(emblemData.isEmpty() ? QString() : emblemData) % QStringLiteral(
|
||||
"</svg>"
|
||||
|
@ -165,14 +175,14 @@ QByteArray loadFontAwesomeIcon(const QString &iconName, const QColor &color, boo
|
|||
}
|
||||
|
||||
StatusIconSettings::StatusIconSettings()
|
||||
: defaultColor({ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8") })
|
||||
, errorColor({ QStringLiteral("#DB3C26"), QStringLiteral("#C80828") })
|
||||
, warningColor({ QStringLiteral("#c9ce3b"), QStringLiteral("#ebb83b") })
|
||||
, idleColor({ QStringLiteral("#2D9D69"), QStringLiteral("#2D9D69") })
|
||||
, scanningColor({ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8") })
|
||||
, synchronizingColor({ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8") })
|
||||
, pausedColor({ QStringLiteral("#A9A9A9"), QStringLiteral("#58656C") })
|
||||
, disconnectedColor({ QStringLiteral("#A9A9A9"), QStringLiteral("#58656C") })
|
||||
: defaultColor({ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8"), QStringLiteral("#FFFFFF") })
|
||||
, errorColor({ QStringLiteral("#DB3C26"), QStringLiteral("#C80828"), QStringLiteral("#FFFFFF") })
|
||||
, warningColor({ QStringLiteral("#c9ce3b"), QStringLiteral("#ebb83b"), QStringLiteral("#FFFFFF") })
|
||||
, idleColor({ QStringLiteral("#2D9D69"), QStringLiteral("#2D9D69"), QStringLiteral("#FFFFFF") })
|
||||
, scanningColor({ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8"), QStringLiteral("#FFFFFF") })
|
||||
, synchronizingColor({ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8"), QStringLiteral("#FFFFFF") })
|
||||
, pausedColor({ QStringLiteral("#A9A9A9"), QStringLiteral("#58656C"), QStringLiteral("#FFFFFF") })
|
||||
, disconnectedColor({ QStringLiteral("#A9A9A9"), QStringLiteral("#58656C"), QStringLiteral("#FFFFFF") })
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -202,8 +212,11 @@ StatusIconSettings::StatusIconSettings(const QString &str)
|
|||
}
|
||||
const auto colors = parts[index].split(QChar(','));
|
||||
if (colors.size() >= 2) {
|
||||
field->start = colors[0].toString();
|
||||
field->end = colors[1].toString();
|
||||
field->backgroundStart = colors[0].toString();
|
||||
field->backgroundEnd = colors[1].toString();
|
||||
}
|
||||
if (colors.size() >= 3) {
|
||||
field->foreground = colors[2].toString();
|
||||
}
|
||||
++index;
|
||||
}
|
||||
|
@ -218,7 +231,8 @@ QString StatusIconSettings::toString() const
|
|||
if (!res.isEmpty()) {
|
||||
res += QChar(';');
|
||||
}
|
||||
res += field->start.name(QColor::HexArgb) % QChar(',') % field->end.name(QColor::HexArgb);
|
||||
res += field->backgroundStart.name(QColor::HexArgb) % QChar(',') % field->backgroundEnd.name(QColor::HexArgb) % QChar(',')
|
||||
% field->foreground.name(QColor::HexArgb);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -22,35 +22,39 @@ enum class StatusEmblem {
|
|||
Add,
|
||||
};
|
||||
|
||||
struct GradientColor {
|
||||
GradientColor(const QColor &start, const QColor &end);
|
||||
GradientColor(QColor &&start, QColor &&end);
|
||||
GradientColor(const QString &start, const QString &end);
|
||||
struct StatusIconColorSet {
|
||||
StatusIconColorSet(const QColor &backgroundStart, const QColor &backgroundEnd, const QColor &foreground);
|
||||
StatusIconColorSet(QColor &&backgroundStart, QColor &&backgroundEnd, QColor &&foreground);
|
||||
StatusIconColorSet(const QString &backgroundStart, const QString &backgroundEnd, const QString &foreground);
|
||||
|
||||
QColor start;
|
||||
QColor end;
|
||||
QColor backgroundStart;
|
||||
QColor backgroundEnd;
|
||||
QColor foreground;
|
||||
};
|
||||
|
||||
inline GradientColor::GradientColor(const QColor &start, const QColor &end)
|
||||
: start(start)
|
||||
, end(end)
|
||||
inline StatusIconColorSet::StatusIconColorSet(const QColor &backgroundStart, const QColor &backgroundEnd, const QColor &foreground)
|
||||
: backgroundStart(backgroundStart)
|
||||
, backgroundEnd(backgroundEnd)
|
||||
, foreground(foreground)
|
||||
{
|
||||
}
|
||||
|
||||
inline GradientColor::GradientColor(QColor &&start, QColor &&end)
|
||||
: start(start)
|
||||
, end(end)
|
||||
inline StatusIconColorSet::StatusIconColorSet(QColor &&backgroundStart, QColor &&backgroundEnd, QColor &&foreground)
|
||||
: backgroundStart(backgroundStart)
|
||||
, backgroundEnd(backgroundEnd)
|
||||
, foreground(foreground)
|
||||
{
|
||||
}
|
||||
|
||||
inline GradientColor::GradientColor(const QString &start, const QString &end)
|
||||
: start(start)
|
||||
, end(end)
|
||||
inline StatusIconColorSet::StatusIconColorSet(const QString &backgroundStart, const QString &backgroundEnd, const QString &foreground)
|
||||
: backgroundStart(backgroundStart)
|
||||
, backgroundEnd(backgroundEnd)
|
||||
, foreground(foreground)
|
||||
{
|
||||
}
|
||||
|
||||
QByteArray LIB_SYNCTHING_MODEL_EXPORT makeSyncthingIcon(
|
||||
const GradientColor &gradientColor = GradientColor{ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8") },
|
||||
const StatusIconColorSet &colors = StatusIconColorSet{ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8"), QStringLiteral("#FFFFFF") },
|
||||
StatusEmblem statusEmblem = StatusEmblem::None);
|
||||
QPixmap LIB_SYNCTHING_MODEL_EXPORT renderSvgImage(const QString &path, const QSize &size = QSize(128, 128), int margin = 0);
|
||||
QPixmap LIB_SYNCTHING_MODEL_EXPORT renderSvgImage(const QByteArray &contents, const QSize &size = QSize(128, 128), int margin = 0);
|
||||
|
@ -60,21 +64,21 @@ struct LIB_SYNCTHING_MODEL_EXPORT StatusIconSettings {
|
|||
explicit StatusIconSettings();
|
||||
explicit StatusIconSettings(const QString &str);
|
||||
|
||||
GradientColor defaultColor;
|
||||
GradientColor errorColor;
|
||||
GradientColor warningColor;
|
||||
GradientColor idleColor;
|
||||
GradientColor scanningColor;
|
||||
GradientColor synchronizingColor;
|
||||
GradientColor pausedColor;
|
||||
GradientColor disconnectedColor;
|
||||
StatusIconColorSet defaultColor;
|
||||
StatusIconColorSet errorColor;
|
||||
StatusIconColorSet warningColor;
|
||||
StatusIconColorSet idleColor;
|
||||
StatusIconColorSet scanningColor;
|
||||
StatusIconColorSet synchronizingColor;
|
||||
StatusIconColorSet pausedColor;
|
||||
StatusIconColorSet disconnectedColor;
|
||||
|
||||
static constexpr auto distinguishableColorCount = 8;
|
||||
|
||||
struct ColorMapping {
|
||||
QString colorName;
|
||||
StatusEmblem defaultEmblem;
|
||||
GradientColor &setting;
|
||||
StatusIconColorSet &setting;
|
||||
};
|
||||
std::vector<ColorMapping> colorMapping();
|
||||
QString toString() const;
|
||||
|
|
|
@ -2,14 +2,6 @@
|
|||
<ui version="4.0">
|
||||
<class>QtGui::IconsOptionPage</class>
|
||||
<widget class="QWidget" name="QtGui::IconsOptionPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>538</width>
|
||||
<height>167</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Icons</string>
|
||||
</property>
|
||||
|
@ -19,17 +11,17 @@
|
|||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="statusColorsGroupBox">
|
||||
<widget class="QGroupBox" name="statusIconsGroupBox">
|
||||
<property name="title">
|
||||
<string>Status colors</string>
|
||||
<string>Status icons</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="color1Label">
|
||||
<widget class="QLabel" name="bgColor1Label">
|
||||
<property name="text">
|
||||
<string>Color 1</string>
|
||||
<string>Background color 1</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
|
@ -37,16 +29,16 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="color2Label">
|
||||
<widget class="QLabel" name="bgColor2Label">
|
||||
<property name="text">
|
||||
<string>Color 2</string>
|
||||
<string>Background color 2</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<item row="0" column="4">
|
||||
<widget class="QLabel" name="previewLabel">
|
||||
<property name="text">
|
||||
<string>Preview</string>
|
||||
|
@ -59,6 +51,16 @@
|
|||
<item row="1" column="0">
|
||||
<widget class="QWidget" name="widget" native="true"/>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="foregroundColorLabel">
|
||||
<property name="text">
|
||||
<string>Foreground color</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -508,40 +508,47 @@ QWidget *IconsOptionPage::setupWidget()
|
|||
|
||||
// populate form for status icon colors
|
||||
auto *const gridLayout = ui()->gridLayout;
|
||||
auto *const statusColorsGroupBox = ui()->statusColorsGroupBox;
|
||||
auto *const statusIconsGroupBox = ui()->statusIconsGroupBox;
|
||||
int index = 0;
|
||||
for (auto &colorMapping : m_settings.colorMapping()) {
|
||||
// populate widgets array
|
||||
auto &widgetsForColor = m_widgets[index++] = {
|
||||
{
|
||||
new Widgets::ColorButton(statusColorsGroupBox),
|
||||
new Widgets::ColorButton(statusColorsGroupBox),
|
||||
new Widgets::ColorButton(statusIconsGroupBox),
|
||||
new Widgets::ColorButton(statusIconsGroupBox),
|
||||
new Widgets::ColorButton(statusIconsGroupBox),
|
||||
},
|
||||
new QLabel(statusColorsGroupBox),
|
||||
new QLabel(statusIconsGroupBox),
|
||||
&colorMapping.setting,
|
||||
colorMapping.defaultEmblem,
|
||||
};
|
||||
|
||||
// add label for color name
|
||||
gridLayout->addWidget(new QLabel(colorMapping.colorName, statusColorsGroupBox), index, 0, Qt::AlignRight | Qt::AlignVCenter);
|
||||
gridLayout->addWidget(new QLabel(colorMapping.colorName, statusIconsGroupBox), index, 0, Qt::AlignRight | Qt::AlignVCenter);
|
||||
|
||||
// setup preview
|
||||
gridLayout->addWidget(widgetsForColor.previewLabel, index, 3, Qt::AlignCenter);
|
||||
gridLayout->addWidget(widgetsForColor.previewLabel, index, 4, Qt::AlignCenter);
|
||||
const auto updatePreview = [&widgetsForColor] {
|
||||
widgetsForColor.previewLabel->setPixmap(
|
||||
renderSvgImage(makeSyncthingIcon(GradientColor{ widgetsForColor.colorButtons[0]->color(), widgetsForColor.colorButtons[1]->color() },
|
||||
widgetsForColor.statusEmblem),
|
||||
QSize(32, 32)));
|
||||
widgetsForColor.previewLabel->setPixmap(renderSvgImage(makeSyncthingIcon(
|
||||
StatusIconColorSet{
|
||||
widgetsForColor.colorButtons[0]->color(),
|
||||
widgetsForColor.colorButtons[1]->color(),
|
||||
widgetsForColor.colorButtons[2]->color(),
|
||||
},
|
||||
widgetsForColor.statusEmblem),
|
||||
QSize(32, 32)));
|
||||
};
|
||||
for (const auto &colorButton : widgetsForColor.colorButtons) {
|
||||
QObject::connect(colorButton, &Widgets::ColorButton::colorChanged, updatePreview);
|
||||
}
|
||||
|
||||
// setup color buttons
|
||||
widgetsForColor.colorButtons[0]->setColor(colorMapping.setting.start);
|
||||
widgetsForColor.colorButtons[1]->setColor(colorMapping.setting.end);
|
||||
widgetsForColor.colorButtons[0]->setColor(colorMapping.setting.backgroundStart);
|
||||
widgetsForColor.colorButtons[1]->setColor(colorMapping.setting.backgroundEnd);
|
||||
widgetsForColor.colorButtons[2]->setColor(colorMapping.setting.foreground);
|
||||
gridLayout->addWidget(widgetsForColor.colorButtons[0], index, 1);
|
||||
gridLayout->addWidget(widgetsForColor.colorButtons[1], index, 2);
|
||||
gridLayout->addWidget(widgetsForColor.colorButtons[2], index, 3);
|
||||
|
||||
if (index >= StatusIconSettings::distinguishableColorCount) {
|
||||
break;
|
||||
|
@ -561,7 +568,11 @@ QWidget *IconsOptionPage::setupWidget()
|
|||
bool IconsOptionPage::apply()
|
||||
{
|
||||
for (auto &widgetsForColor : m_widgets) {
|
||||
*widgetsForColor.setting = GradientColor{ widgetsForColor.colorButtons[0]->color(), widgetsForColor.colorButtons[1]->color() };
|
||||
*widgetsForColor.setting = StatusIconColorSet{
|
||||
widgetsForColor.colorButtons[0]->color(),
|
||||
widgetsForColor.colorButtons[1]->color(),
|
||||
widgetsForColor.colorButtons[2]->color(),
|
||||
};
|
||||
}
|
||||
values().statusIcons = m_settings;
|
||||
return true;
|
||||
|
@ -570,8 +581,9 @@ bool IconsOptionPage::apply()
|
|||
void IconsOptionPage::update()
|
||||
{
|
||||
for (auto &widgetsForColor : m_widgets) {
|
||||
widgetsForColor.colorButtons[0]->setColor(widgetsForColor.setting->start);
|
||||
widgetsForColor.colorButtons[1]->setColor(widgetsForColor.setting->end);
|
||||
widgetsForColor.colorButtons[0]->setColor(widgetsForColor.setting->backgroundStart);
|
||||
widgetsForColor.colorButtons[1]->setColor(widgetsForColor.setting->backgroundEnd);
|
||||
widgetsForColor.colorButtons[2]->setColor(widgetsForColor.setting->foreground);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,9 +84,9 @@ private:
|
|||
void update();
|
||||
Data::StatusIconSettings m_settings;
|
||||
struct {
|
||||
Widgets::ColorButton *colorButtons[2] = {};
|
||||
Widgets::ColorButton *colorButtons[3] = {};
|
||||
QLabel *previewLabel = nullptr;
|
||||
Data::GradientColor *setting = nullptr;
|
||||
Data::StatusIconColorSet *setting = nullptr;
|
||||
Data::StatusEmblem statusEmblem = Data::StatusEmblem::None;
|
||||
} m_widgets[Data::StatusIconSettings::distinguishableColorCount];
|
||||
END_DECLARE_OPTION_PAGE
|
||||
|
|
Loading…
Reference in New Issue