forked from mirror/nheko
parent
287b5aa4c0
commit
886edd03fb
@ -0,0 +1,80 @@ |
||||
/*
|
||||
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#pragma once |
||||
|
||||
#include <QComboBox> |
||||
#include <QFrame> |
||||
#include <QLayout> |
||||
#include <QSharedPointer> |
||||
#include <QWidget> |
||||
|
||||
class Toggle; |
||||
|
||||
constexpr int OptionMargin = 6; |
||||
constexpr int LayoutSideMargin = 300; |
||||
|
||||
class UserSettings |
||||
{ |
||||
public: |
||||
UserSettings(); |
||||
|
||||
void save(); |
||||
void load(); |
||||
void setTheme(QString theme) { theme_ = theme; } |
||||
void setTray(bool state) { isTrayEnabled_ = state; } |
||||
|
||||
QString theme() const { return !theme_.isEmpty() ? theme_ : "default"; } |
||||
bool isTrayEnabled() const { return isTrayEnabled_; } |
||||
|
||||
private: |
||||
QString theme_; |
||||
bool isTrayEnabled_; |
||||
}; |
||||
|
||||
class HorizontalLine : public QFrame |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
HorizontalLine(QWidget *parent = nullptr); |
||||
}; |
||||
|
||||
class UserSettingsPage : public QWidget |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
UserSettingsPage(QSharedPointer<UserSettings> settings, QWidget *parent = 0); |
||||
|
||||
protected: |
||||
void showEvent(QShowEvent *event) override; |
||||
|
||||
signals: |
||||
void moveBack(); |
||||
|
||||
private: |
||||
// Layouts
|
||||
QVBoxLayout *topLayout_; |
||||
QHBoxLayout *topBarLayout_; |
||||
|
||||
// Shared settings object.
|
||||
QSharedPointer<UserSettings> settings_; |
||||
|
||||
Toggle *trayToggle_; |
||||
QComboBox *themeCombo_; |
||||
}; |
@ -0,0 +1,110 @@ |
||||
#pragma once |
||||
|
||||
#include <QAbstractButton> |
||||
#include <QColor> |
||||
|
||||
class ToggleTrack; |
||||
class ToggleThumb; |
||||
|
||||
enum class Position |
||||
{ |
||||
Left, |
||||
Right |
||||
}; |
||||
|
||||
class Toggle : public QAbstractButton |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
Q_PROPERTY(QColor activeColor WRITE setActiveColor READ activeColor) |
||||
Q_PROPERTY(QColor disabledColor WRITE setDisabledColor READ disabledColor) |
||||
Q_PROPERTY(QColor inactiveColor WRITE setInactiveColor READ inactiveColor) |
||||
Q_PROPERTY(QColor trackColor WRITE setTrackColor READ trackColor) |
||||
|
||||
public: |
||||
Toggle(QWidget *parent = nullptr); |
||||
|
||||
void setState(bool isEnabled); |
||||
|
||||
void setActiveColor(const QColor &color); |
||||
void setDisabledColor(const QColor &color); |
||||
void setInactiveColor(const QColor &color); |
||||
void setTrackColor(const QColor &color); |
||||
|
||||
QColor activeColor() const { return activeColor_; }; |
||||
QColor disabledColor() const { return disabledColor_; }; |
||||
QColor inactiveColor() const { return inactiveColor_; }; |
||||
QColor trackColor() const { return trackColor_.isValid() ? trackColor_ : QColor("#eee"); }; |
||||
|
||||
QSize sizeHint() const override { return QSize(64, 48); }; |
||||
|
||||
protected: |
||||
void paintEvent(QPaintEvent *event) override; |
||||
|
||||
private: |
||||
void init(); |
||||
void setupProperties(); |
||||
|
||||
ToggleTrack *track_; |
||||
ToggleThumb *thumb_; |
||||
|
||||
QColor disabledColor_; |
||||
QColor activeColor_; |
||||
QColor inactiveColor_; |
||||
QColor trackColor_; |
||||
}; |
||||
|
||||
class ToggleThumb : public QWidget |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
Q_PROPERTY(QColor thumbColor WRITE setThumbColor READ thumbColor) |
||||
|
||||
public: |
||||
ToggleThumb(Toggle *parent); |
||||
|
||||
Position shift() const { return position_; }; |
||||
qreal offset() const { return offset_; }; |
||||
QColor thumbColor() const { return thumbColor_; }; |
||||
|
||||
void setShift(Position position); |
||||
void setThumbColor(const QColor &color) |
||||
{ |
||||
thumbColor_ = color; |
||||
update(); |
||||
}; |
||||
|
||||
protected: |
||||
bool eventFilter(QObject *obj, QEvent *event) override; |
||||
void paintEvent(QPaintEvent *event) override; |
||||
|
||||
private: |
||||
void updateOffset(); |
||||
|
||||
Toggle *const toggle_; |
||||
QColor thumbColor_; |
||||
|
||||
Position position_; |
||||
qreal offset_; |
||||
}; |
||||
|
||||
class ToggleTrack : public QWidget |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
Q_PROPERTY(QColor trackColor WRITE setTrackColor READ trackColor) |
||||
|
||||
public: |
||||
ToggleTrack(Toggle *parent); |
||||
|
||||
void setTrackColor(const QColor &color); |
||||
QColor trackColor() const { return trackColor_; }; |
||||
|
||||
protected: |
||||
bool eventFilter(QObject *obj, QEvent *event) override; |
||||
void paintEvent(QPaintEvent *event) override; |
||||
|
||||
private: |
||||
Toggle *const toggle_; |
||||
QColor trackColor_; |
||||
}; |
@ -0,0 +1,140 @@ |
||||
/*
|
||||
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#include <QComboBox> |
||||
#include <QDebug> |
||||
#include <QLabel> |
||||
#include <QPushButton> |
||||
#include <QSettings> |
||||
|
||||
#include "Config.h" |
||||
#include "FlatButton.h" |
||||
#include "UserSettingsPage.h" |
||||
#include <ToggleButton.h> |
||||
|
||||
UserSettings::UserSettings() { load(); } |
||||
|
||||
void |
||||
UserSettings::load() |
||||
{ |
||||
QSettings settings; |
||||
isTrayEnabled_ = settings.value("user/tray", true).toBool(); |
||||
theme_ = settings.value("user/theme", "default").toString(); |
||||
} |
||||
|
||||
void |
||||
UserSettings::save() |
||||
{ |
||||
QSettings settings; |
||||
settings.beginGroup("user"); |
||||
settings.setValue("tray", isTrayEnabled_); |
||||
settings.setValue("theme", theme()); |
||||
settings.endGroup(); |
||||
} |
||||
|
||||
HorizontalLine::HorizontalLine(QWidget *parent) |
||||
: QFrame{ parent } |
||||
{ |
||||
setFrameShape(QFrame::HLine); |
||||
setFrameShadow(QFrame::Sunken); |
||||
} |
||||
|
||||
UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidget *parent) |
||||
: QWidget{ parent } |
||||
, settings_{ settings } |
||||
{ |
||||
topLayout_ = new QVBoxLayout(this); |
||||
|
||||
QIcon icon; |
||||
icon.addFile(":/icons/icons/ui/angle-pointing-to-left.png"); |
||||
|
||||
auto backBtn_ = new FlatButton(this); |
||||
backBtn_->setMinimumSize(QSize(24, 24)); |
||||
backBtn_->setIcon(icon); |
||||
backBtn_->setIconSize(QSize(24, 24)); |
||||
|
||||
auto heading_ = new QLabel(tr("User Settings")); |
||||
heading_->setFont(QFont("Open Sans Bold", 22)); |
||||
|
||||
topBarLayout_ = new QHBoxLayout; |
||||
topBarLayout_->setSpacing(0); |
||||
topBarLayout_->setMargin(0); |
||||
topBarLayout_->addWidget(backBtn_, 1, Qt::AlignLeft | Qt::AlignVCenter); |
||||
topBarLayout_->addWidget(heading_, 0, Qt::AlignBottom); |
||||
topBarLayout_->addStretch(1); |
||||
|
||||
auto trayOptionLayout_ = new QHBoxLayout; |
||||
trayOptionLayout_->setContentsMargins(0, OptionMargin, 0, OptionMargin); |
||||
auto trayLabel = new QLabel(tr("Minimize to tray"), this); |
||||
trayToggle_ = new Toggle(this); |
||||
trayToggle_->setActiveColor(QColor("#38A3D8")); |
||||
trayToggle_->setInactiveColor(QColor("gray")); |
||||
trayLabel->setFont(QFont("Open Sans", 15)); |
||||
|
||||
trayOptionLayout_->addWidget(trayLabel); |
||||
trayOptionLayout_->addWidget(trayToggle_, 0, Qt::AlignBottom | Qt::AlignRight); |
||||
|
||||
auto themeOptionLayout_ = new QHBoxLayout; |
||||
themeOptionLayout_->setContentsMargins(0, OptionMargin, 0, OptionMargin); |
||||
auto themeLabel_ = new QLabel(tr("App theme"), this); |
||||
themeCombo_ = new QComboBox(this); |
||||
themeCombo_->addItem("Default"); |
||||
themeCombo_->addItem("System"); |
||||
themeLabel_->setFont(QFont("Open Sans", 15)); |
||||
|
||||
themeOptionLayout_->addWidget(themeLabel_); |
||||
themeOptionLayout_->addWidget(themeCombo_, 0, Qt::AlignBottom | Qt::AlignRight); |
||||
|
||||
auto general_ = new QLabel(tr("GENERAL"), this); |
||||
general_->setFont(QFont("Open Sans Bold", 17)); |
||||
general_->setStyleSheet("color: #5d6565"); |
||||
|
||||
auto mainLayout_ = new QVBoxLayout; |
||||
mainLayout_->setSpacing(7); |
||||
mainLayout_->setContentsMargins( |
||||
LayoutSideMargin, LayoutSideMargin / 6, LayoutSideMargin, LayoutSideMargin / 6); |
||||
mainLayout_->addWidget(general_, 1, Qt::AlignLeft | Qt::AlignVCenter); |
||||
mainLayout_->addWidget(new HorizontalLine(this)); |
||||
mainLayout_->addLayout(trayOptionLayout_); |
||||
mainLayout_->addWidget(new HorizontalLine(this)); |
||||
mainLayout_->addLayout(themeOptionLayout_); |
||||
mainLayout_->addWidget(new HorizontalLine(this)); |
||||
|
||||
topLayout_->addLayout(topBarLayout_); |
||||
topLayout_->addLayout(mainLayout_); |
||||
topLayout_->addStretch(1); |
||||
|
||||
connect(themeCombo_, |
||||
static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::activated), |
||||
[=](const QString &text) { settings_->setTheme(text.toLower()); }); |
||||
|
||||
connect(trayToggle_, &Toggle::toggled, this, [=](bool isEnabled) { |
||||
settings_->setTray(isEnabled); |
||||
}); |
||||
|
||||
connect(backBtn_, &QPushButton::clicked, this, [=]() { |
||||
settings_->save(); |
||||
emit moveBack(); |
||||
}); |
||||
} |
||||
|
||||
void |
||||
UserSettingsPage::showEvent(QShowEvent *) |
||||
{ |
||||
themeCombo_->setCurrentIndex((settings_->theme() == "default" ? 0 : 1)); |
||||
trayToggle_->setState(settings_->isTrayEnabled()); |
||||
} |
@ -0,0 +1,212 @@ |
||||
#include <QApplication> |
||||
#include <QColor> |
||||
#include <QEvent> |
||||
#include <QPainter> |
||||
|
||||
#include "ToggleButton.h" |
||||
|
||||
void |
||||
Toggle::paintEvent(QPaintEvent *event) |
||||
{ |
||||
Q_UNUSED(event); |
||||
} |
||||
|
||||
Toggle::Toggle(QWidget *parent) |
||||
: QAbstractButton{ parent } |
||||
{ |
||||
init(); |
||||
|
||||
connect(this, &QAbstractButton::toggled, this, &Toggle::setState); |
||||
} |
||||
|
||||
void |
||||
Toggle::setState(bool isEnabled) |
||||
{ |
||||
thumb_->setShift(isEnabled ? Position::Right : Position::Left); |
||||
setupProperties(); |
||||
} |
||||
|
||||
void |
||||
Toggle::init() |
||||
{ |
||||
track_ = new ToggleTrack(this); |
||||
thumb_ = new ToggleThumb(this); |
||||
|
||||
setCursor(QCursor(Qt::PointingHandCursor)); |
||||
setCheckable(true); |
||||
setChecked(false); |
||||
setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); |
||||
|
||||
setState(false); |
||||
setupProperties(); |
||||
|
||||
QCoreApplication::processEvents(); |
||||
} |
||||
|
||||
void |
||||
Toggle::setupProperties() |
||||
{ |
||||
if (isEnabled()) { |
||||
Position position = thumb_->shift(); |
||||
|
||||
thumb_->setThumbColor(trackColor()); |
||||
|
||||
if (position == Position::Left) |
||||
track_->setTrackColor(activeColor()); |
||||
else if (position == Position::Right) |
||||
track_->setTrackColor(inactiveColor()); |
||||
} |
||||
|
||||
update(); |
||||
} |
||||
|
||||
void |
||||
Toggle::setDisabledColor(const QColor &color) |
||||
{ |
||||
disabledColor_ = color; |
||||
setupProperties(); |
||||
} |
||||
|
||||
void |
||||
Toggle::setActiveColor(const QColor &color) |
||||
{ |
||||
activeColor_ = color; |
||||
setupProperties(); |
||||
} |
||||
|
||||
void |
||||
Toggle::setInactiveColor(const QColor &color) |
||||
{ |
||||
inactiveColor_ = color; |
||||
setupProperties(); |
||||
} |
||||
|
||||
void |
||||
Toggle::setTrackColor(const QColor &color) |
||||
{ |
||||
trackColor_ = color; |
||||
setupProperties(); |
||||
} |
||||
|
||||
ToggleThumb::ToggleThumb(Toggle *parent) |
||||
: QWidget{ parent } |
||||
, toggle_{ parent } |
||||
, position_{ Position::Right } |
||||
, offset_{ 0 } |
||||
{ |
||||
parent->installEventFilter(this); |
||||
} |
||||
|
||||
void |
||||
ToggleThumb::setShift(Position position) |
||||
{ |
||||
if (position_ != position) { |
||||
position_ = position; |
||||
updateOffset(); |
||||
} |
||||
} |
||||
|
||||
bool |
||||
ToggleThumb::eventFilter(QObject *obj, QEvent *event) |
||||
{ |
||||
const QEvent::Type type = event->type(); |
||||
|
||||
if (QEvent::Resize == type || QEvent::Move == type) { |
||||
setGeometry(toggle_->rect().adjusted(8, 8, -8, -8)); |
||||
updateOffset(); |
||||
} |
||||
|
||||
return QWidget::eventFilter(obj, event); |
||||
} |
||||
|
||||
void |
||||
ToggleThumb::paintEvent(QPaintEvent *event) |
||||
{ |
||||
Q_UNUSED(event) |
||||
|
||||
QPainter painter(this); |
||||
painter.setRenderHint(QPainter::Antialiasing); |
||||
|
||||
QBrush brush; |
||||
brush.setStyle(Qt::SolidPattern); |
||||
brush.setColor(toggle_->isEnabled() ? thumbColor_ : Qt::white); |
||||
|
||||
painter.setBrush(brush); |
||||
painter.setPen(Qt::NoPen); |
||||
|
||||
int s; |
||||
QRectF r; |
||||
|
||||
s = height() - 10; |
||||
r = QRectF(5 + offset_, 5, s, s); |
||||
|
||||
painter.drawEllipse(r); |
||||
|
||||
if (!toggle_->isEnabled()) { |
||||
brush.setColor(toggle_->disabledColor()); |
||||
painter.setBrush(brush); |
||||
painter.drawEllipse(r); |
||||
} |
||||
} |
||||
|
||||
void |
||||
ToggleThumb::updateOffset() |
||||
{ |
||||
const QSize s(size()); |
||||
offset_ = position_ == Position::Left ? static_cast<qreal>(s.width() - s.height()) : 0; |
||||
update(); |
||||
} |
||||
|
||||
ToggleTrack::ToggleTrack(Toggle *parent) |
||||
: QWidget{ parent } |
||||
, toggle_{ parent } |
||||
{ |
||||
Q_ASSERT(parent); |
||||
|
||||
parent->installEventFilter(this); |
||||
} |
||||
|
||||
void |
||||
ToggleTrack::setTrackColor(const QColor &color) |
||||
{ |
||||
trackColor_ = color; |
||||
update(); |
||||
} |
||||
|
||||
bool |
||||
ToggleTrack::eventFilter(QObject *obj, QEvent *event) |
||||
{ |
||||
const QEvent::Type type = event->type(); |
||||
|
||||
if (QEvent::Resize == type || QEvent::Move == type) { |
||||
setGeometry(toggle_->rect()); |
||||
} |
||||
|
||||
return QWidget::eventFilter(obj, event); |
||||
} |
||||
|
||||
void |
||||
ToggleTrack::paintEvent(QPaintEvent *event) |
||||
{ |
||||
Q_UNUSED(event) |
||||
|
||||
QPainter painter(this); |
||||
painter.setRenderHint(QPainter::Antialiasing); |
||||
|
||||
QBrush brush; |
||||
if (toggle_->isEnabled()) { |
||||
brush.setColor(trackColor_); |
||||
painter.setOpacity(0.8); |
||||
} else { |
||||
brush.setColor(toggle_->disabledColor()); |
||||
painter.setOpacity(0.6); |
||||
} |
||||
|
||||
brush.setStyle(Qt::SolidPattern); |
||||
painter.setBrush(brush); |
||||
painter.setPen(Qt::NoPen); |
||||
|
||||
const int h = height() / 2; |
||||
const QRect r(0, h / 2, width(), h); |
||||
painter.drawRoundedRect(r.adjusted(14, 4, -14, -4), h / 2 - 4, h / 2 - 4); |
||||
} |
Loading…
Reference in new issue