diff --git a/src/misc/settings.cpp b/src/misc/settings.cpp index c6f309c33..0770c42c8 100644 --- a/src/misc/settings.cpp +++ b/src/misc/settings.cpp @@ -154,6 +154,7 @@ void Settings::load() useNativeStyle = s.value("nativeStyle", false).toBool(); useEmoticons = s.value("useEmoticons", true).toBool(); statusChangeNotificationEnabled = s.value("statusChangeNotificationEnabled", false).toBool(); + themeColor = s.value("themeColor", 0).toInt(); style = s.value("style", "").toString(); if (style == "") // Default to Fusion if available, otherwise no style { @@ -297,6 +298,7 @@ void Settings::save(QString path) s.setValue("minimizeToTray", minimizeToTray); s.setValue("nativeStyle", useNativeStyle); s.setValue("useEmoticons", useEmoticons); + s.setValue("themeColor", themeColor); s.setValue("style", style); s.setValue("statusChangeNotificationEnabled", statusChangeNotificationEnabled); s.endGroup(); @@ -909,3 +911,13 @@ void Settings::setFauxOfflineMessaging(bool value) { fauxOfflineMessaging = value; } + +int Settings::getThemeColor() const +{ + return themeColor; +} + +void Settings::setThemeColor(const int &value) +{ + themeColor = value; +} diff --git a/src/misc/settings.h b/src/misc/settings.h index 49f60f58d..7468fe3fe 100644 --- a/src/misc/settings.h +++ b/src/misc/settings.h @@ -152,6 +152,9 @@ public: QString getSmileyPack() const; void setSmileyPack(const QString &value); + int getThemeColor() const; + void setThemeColor(const int& value); + bool isCurstomEmojiFont() const; void setCurstomEmojiFont(bool value); @@ -296,6 +299,7 @@ private: QHash friendLst; + int themeColor; signals: //void dataChanged(); diff --git a/src/misc/style.cpp b/src/misc/style.cpp index bb5f3ce39..ad6f93c7b 100644 --- a/src/misc/style.cpp +++ b/src/misc/style.cpp @@ -17,6 +17,10 @@ #include "style.h" #include "settings.h" +#include "src/widget/widget.h" +#include "ui_mainwindow.h" +#include "src/widget/genericchatroomwidget.h" + #include #include #include @@ -42,6 +46,33 @@ QString qssifyFont(QFont font) .arg(font.family()); } +// colors as defined in +// https://github.com/ItsDuke/Tox-UI/blob/master/UI%20GUIDELINES.md +static QColor palette[] = { + QColor("#6bc260"), + QColor("#cebf44"), + QColor("#c84e4e"), + QColor("#000000"), + QColor("#1c1c1c"), + QColor("#414141"), + QColor("#414141").lighter(120), + QColor("#d1d1d1"), + QColor("#ffffff"), + QColor("#ff7700"), + + // Theme colors + QColor("#1c1c1c"), + QColor("#2a2a2a"), + QColor("#414141"), + QColor("#4e4e4e"), +}; + +static QMap dict; + +QStringList Style::themeColorNames = {QObject::tr("Default"), QObject::tr("Blue"), QObject::tr("Olive"), QObject::tr("Red"), QObject::tr("Violet")}; +QList Style::themeColorColors = {QColor(), QColor("#004aa4"), QColor("#97ba00"), QColor("#c23716"), QColor("#4617b5")}; + + QString Style::getStylesheet(const QString &filename) { if (!Settings::getInstance().getUseNativeStyle()) @@ -58,27 +89,6 @@ QString Style::getStylesheet(const QString &filename) QColor Style::getColor(Style::ColorPalette entry) { - // colors as defined in - // https://github.com/ItsDuke/Tox-UI/blob/master/UI%20GUIDELINES.md - static QColor palette[] = { - QColor("#6bc260"), - QColor("#cebf44"), - QColor("#c84e4e"), - QColor("#000000"), - QColor("#1c1c1c"), - QColor("#414141"), - QColor("#414141").lighter(120), - QColor("#d1d1d1"), - QColor("#ffffff"), - QColor("#ff7700"), - - // Theme colors - QColor("#1c1c1c"), - QColor("#2a2a2a"), - QColor("#414141"), - QColor("#4e4e4e"), - }; - return palette[entry]; } @@ -104,32 +114,35 @@ QFont Style::getFont(Style::Font font) QString Style::resolve(QString qss) { - static QMap dict = { - // colors - {"@green", getColor(Green).name()}, - {"@yellow", getColor(Yellow).name()}, - {"@red", getColor(Red).name()}, - {"@black", getColor(Black).name()}, - {"@darkGrey", getColor(DarkGrey).name()}, - {"@mediumGrey", getColor(MediumGrey).name()}, - {"@mediumGreyLight", getColor(MediumGreyLight).name()}, - {"@lightGrey", getColor(LightGrey).name()}, - {"@white", getColor(White).name()}, - {"@orange", getColor(Orange).name()}, - {"@themeDark", getColor(ThemeDark).name()}, - {"@themeMediumDark", getColor(ThemeMediumDark).name()}, - {"@themeMedium", getColor(ThemeMedium).name()}, - {"@themeLight", getColor(ThemeLight).name()}, + if (dict.isEmpty()) + { + dict = { + // colors + {"@green", Style::getColor(Style::Green).name()}, + {"@yellow", Style::getColor(Style::Yellow).name()}, + {"@red", Style::getColor(Style::Red).name()}, + {"@black", Style::getColor(Style::Black).name()}, + {"@darkGrey", Style::getColor(Style::DarkGrey).name()}, + {"@mediumGrey", Style::getColor(Style::MediumGrey).name()}, + {"@mediumGreyLight", Style::getColor(Style::MediumGreyLight).name()}, + {"@lightGrey", Style::getColor(Style::LightGrey).name()}, + {"@white", Style::getColor(Style::White).name()}, + {"@orange", Style::getColor(Style::Orange).name()}, + {"@themeDark", Style::getColor(Style::ThemeDark).name()}, + {"@themeMediumDark", Style::getColor(Style::ThemeMediumDark).name()}, + {"@themeMedium", Style::getColor(Style::ThemeMedium).name()}, + {"@themeLight", Style::getColor(Style::ThemeLight).name()}, - // fonts - {"@extraBig", qssifyFont(getFont(ExtraBig))}, - {"@big", qssifyFont(getFont(Big))}, - {"@bigBold", qssifyFont(getFont(BigBold))}, - {"@medium", qssifyFont(getFont(Medium))}, - {"@mediumBold", qssifyFont(getFont(MediumBold))}, - {"@small", qssifyFont(getFont(Small))}, - {"@smallLight", qssifyFont(getFont(SmallLight))}, - }; + // fonts + {"@extraBig", qssifyFont(Style::getFont(Style::ExtraBig))}, + {"@big", qssifyFont(Style::getFont(Style::Big))}, + {"@bigBold", qssifyFont(Style::getFont(Style::BigBold))}, + {"@medium", qssifyFont(Style::getFont(Style::Medium))}, + {"@mediumBold", qssifyFont(Style::getFont(Style::MediumBold))}, + {"@small", qssifyFont(Style::getFont(Style::Small))}, + {"@smallLight", qssifyFont(Style::getFont(Style::SmallLight))}, + }; + } for (const QString& key : dict.keys()) { @@ -154,3 +167,42 @@ void Style::repolish(QWidget *w) } } } + +void Style::setThemeColor(int color) +{ + if (color < 0 || color >= themeColorColors.size()) + setThemeColor(QColor()); + else + setThemeColor(themeColorColors[color]); +} + +void Style::setThemeColor(QColor color) +{ + if (!color.isValid()) + { + // Reset to default + palette[ThemeDark] = QColor("#1c1c1c"); + palette[ThemeMediumDark] = QColor("#2a2a2a"); + palette[ThemeMedium] = QColor("#414141"); + palette[ThemeLight] = QColor("#4e4e4e"); + } + else + { + palette[ThemeDark] = color.darker(155); + palette[ThemeMediumDark] = color.darker(135); + palette[ThemeMedium] = color.darker(120); + palette[ThemeLight] = color.lighter(110); + } + + dict["@themeDark"] = getColor(ThemeDark).name(); + dict["@themeMediumDark"] = getColor(ThemeMediumDark).name(); + dict["@themeMedium"] = getColor(ThemeMedium).name(); + dict["@themeLight"] = getColor(ThemeLight).name(); + + applyTheme(); +} + +void Style::applyTheme() +{ + Widget::getInstance()->reloadTheme(); +} diff --git a/src/misc/style.h b/src/misc/style.h index 33800d9e4..87412387c 100644 --- a/src/misc/style.h +++ b/src/misc/style.h @@ -60,6 +60,15 @@ public: static QFont getFont(Font font); static QString resolve(QString qss); static void repolish(QWidget* w); + static void setThemeColor(int color); + static void setThemeColor(QColor color); ///< Pass an invalid QColor to reset to defaults + static void applyTheme(); ///< Reloads some CCS + + static QStringList themeColorNames; + static QList themeColorColors; + +signals: + void themeChanged(); private: Style(); diff --git a/src/widget/form/settings/generalform.cpp b/src/widget/form/settings/generalform.cpp index a4c305a16..0d513d165 100644 --- a/src/widget/form/settings/generalform.cpp +++ b/src/widget/form/settings/generalform.cpp @@ -21,6 +21,7 @@ #include "src/misc/settings.h" #include "src/misc/smileypack.h" #include "src/core.h" +#include "src/misc/style.h" #include #include #include @@ -77,6 +78,10 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) : else bodyUI->styleBrowser->setCurrentText(tr("None")); + for (QString color : Style::themeColorNames) + bodyUI->themeColorCBox->addItem(color); + bodyUI->themeColorCBox->setCurrentIndex(Settings::getInstance().getThemeColor()); + bodyUI->emoticonSize->setValue(Settings::getInstance().getEmojiFontPointSize()); QStringList timestamps; @@ -119,6 +124,7 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) : connect(bodyUI->useEmoticons, &QCheckBox::stateChanged, this, &GeneralForm::onUseEmoticonsChange); connect(bodyUI->smileyPackBrowser, SIGNAL(currentIndexChanged(int)), this, SLOT(onSmileyBrowserIndexChanged(int))); connect(bodyUI->styleBrowser, SIGNAL(currentTextChanged(QString)), this, SLOT(onStyleSelected(QString))); + connect(bodyUI->themeColorCBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onThemeColorChanged(int))); connect(bodyUI->emoticonSize, SIGNAL(editingFinished()), this, SLOT(onEmoticonSizeChanged())); connect(bodyUI->timestamp, SIGNAL(currentIndexChanged(int)), this, SLOT(onTimestampSelected(int))); //connection @@ -314,3 +320,10 @@ void GeneralForm::onFauxOfflineMessaging() { Settings::getInstance().setFauxOfflineMessaging(bodyUI->cbFauxOfflineMessaging->isChecked()); } + +void GeneralForm::onThemeColorChanged(int) +{ + int index = bodyUI->themeColorCBox->currentIndex(); + Settings::getInstance().setThemeColor(index); + Style::setThemeColor(index); +} diff --git a/src/widget/form/settings/generalform.h b/src/widget/form/settings/generalform.h index 6f902a523..ec41fb0ad 100644 --- a/src/widget/form/settings/generalform.h +++ b/src/widget/form/settings/generalform.h @@ -55,6 +55,7 @@ private slots: void onCheckUpdateChanged(); void onSetShowInFront(); void onFauxOfflineMessaging(); + void onThemeColorChanged(int); private: Ui::GeneralSettings *bodyUI; diff --git a/src/widget/form/settings/generalsettings.ui b/src/widget/form/settings/generalsettings.ui index b0bf7d38d..f74e805e4 100644 --- a/src/widget/form/settings/generalsettings.ui +++ b/src/widget/form/settings/generalsettings.ui @@ -39,8 +39,8 @@ 0 0 - 583 - 748 + 524 + 726 @@ -197,6 +197,9 @@ Set to 0 to disable + + true + minutes @@ -206,9 +209,6 @@ 2147483647 - - true - @@ -251,8 +251,14 @@ - + + + + 0 + 232 + + Theme @@ -363,6 +369,27 @@ + + + + + + Theme color + + + + + + + + 0 + 0 + + + + + + diff --git a/src/widget/genericchatroomwidget.cpp b/src/widget/genericchatroomwidget.cpp index 4a4e7198d..ef5cf5df9 100644 --- a/src/widget/genericchatroomwidget.cpp +++ b/src/widget/genericchatroomwidget.cpp @@ -97,3 +97,8 @@ void GenericChatroomWidget::mouseReleaseEvent(QMouseEvent*) { emit chatroomWidgetClicked(this); } + +void GenericChatroomWidget::reloadTheme() +{ + setStyleSheet(Style::getStylesheet(":/ui/chatroomWidgets/genericChatroomWidget.css")); +} diff --git a/src/widget/genericchatroomwidget.h b/src/widget/genericchatroomwidget.h index 1dd6d8250..333ef109c 100644 --- a/src/widget/genericchatroomwidget.h +++ b/src/widget/genericchatroomwidget.h @@ -51,6 +51,8 @@ public: QString getName() const; QString getStatusMsg() const; + void reloadTheme(); + signals: void chatroomWidgetClicked(GenericChatroomWidget* widget); @@ -63,6 +65,8 @@ protected: MaskablePixmapWidget* avatar; QLabel statusPic; CroppingLabel *nameLabel, *statusMessageLabel; + + friend class Style; ///< To update our stylesheets }; #endif // GENERICCHATROOMWIDGET_H diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 850565953..c7d28daf5 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -173,6 +173,9 @@ void Widget::init() // Disable some widgets until we're connected to the DHT ui->statusButton->setEnabled(false); + Style::setThemeColor(Settings::getInstance().getThemeColor()); + Style::applyTheme(); + idleTimer = new QTimer(); idleTimer->setSingleShot(true); int mins = Settings::getInstance().getAutoAwayTime(); @@ -1186,3 +1189,17 @@ void Widget::clearAllReceipts() f->getChatForm()->clearReciepts(); } } + +void Widget::reloadTheme() +{ + ui->tooliconsZone->setStyleSheet(Style::resolve("QPushButton{background-color:@themeDark;border:none;}QPushButton:hover{background-color:@themeMediumDark;border:none;}")); + ui->statusPanel->setStyleSheet(Style::getStylesheet(":/ui/window/statusPanel.css")); + ui->friendList->setStyleSheet(Style::getStylesheet(":ui/friendList/friendList.css")); + ui->statusButton->setStyleSheet(Style::getStylesheet(":ui/statusButton/statusButton.css")); + + for (Friend* f : FriendList::getAllFriends()) + f->getFriendWidget()->reloadTheme(); + + for (Group* g : GroupList::groupList) + g->widget->reloadTheme(); +} diff --git a/src/widget/widget.h b/src/widget/widget.h index 09a6814a6..fc4bac241 100644 --- a/src/widget/widget.h +++ b/src/widget/widget.h @@ -75,6 +75,8 @@ public: void clearAllReceipts(); + void reloadTheme(); + public slots: void onSettingsClicked(); diff --git a/ui/statusButton/menu_indicator.png b/ui/statusButton/menu_indicator.png index 0015b5d08..92abefa55 100644 Binary files a/ui/statusButton/menu_indicator.png and b/ui/statusButton/menu_indicator.png differ diff --git a/ui/statusButton/statusButton.css b/ui/statusButton/statusButton.css index ca9891713..78b8a364a 100644 --- a/ui/statusButton/statusButton.css +++ b/ui/statusButton/statusButton.css @@ -1,7 +1,7 @@ QPushButton { background: none; - background-color: rgb(65,65,65); + background-color: @themeMediumDark; border: none; border-radius: 6px; width: 20px; @@ -30,18 +30,18 @@ QPushButton#offline QPushButton:default { - background-color: rgb(65,65,65); + background-color: @themeMediumDark; } /*Bugged in Qt, but it's probably better to leave enabled so that users can tell it's clickable*/ QPushButton:hover { - background-color: rgb(75,75,75); + background-color: @themeMedium; } QPushButton:pressed { - background-color: rgb(55,55,55); + background-color: @themeMediumDark; } QPushButton:focus { diff --git a/ui/window/statusPanel.css b/ui/window/statusPanel.css index c9b8249e0..2c9b77d7a 100644 --- a/ui/window/statusPanel.css +++ b/ui/window/statusPanel.css @@ -1,7 +1,7 @@ QLineEdit { background: none; - background-color: @mediumGrey; + background-color: @themeMedium; color: white; border: 0px; border-radius: 6px; @@ -25,7 +25,7 @@ QLineEdit #statusPanel > #statusHead > #statusButton { background: none; - background-color: @mediumGrey; + background-color: @themeMedium; border: none; border-radius: 6px; width: 20px; @@ -55,12 +55,12 @@ QLineEdit /*Bugged in Qt, but it's probably better to leave enabled so that users can tell it's clickable*/ #statusPanel > #statusHead > #statusButton:hover { - background-color: @mediumGreyLight; + background-color: @themeLight; } #statusPanel > #statusHead > #statusButton:pressed { - background-color: @mediumGrey; + background-color: @themeMedium; } #statusPanel > #statusHead > #statusButton:focus {