diff --git a/src/ChatPage.cc b/src/ChatPage.cc
index d81b64fb..e32b288a 100644
--- a/src/ChatPage.cc
+++ b/src/ChatPage.cc
@@ -75,6 +75,8 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent)
sideBarMainLayout_->setMargin(0);
sidebarActions_ = new SideBarActions(this);
+ connect(
+ sidebarActions_, &SideBarActions::showSettings, this, &ChatPage::showUserSettingsPage);
sideBarLayout_->addLayout(sideBarTopLayout_);
sideBarLayout_->addLayout(sideBarMainLayout_);
diff --git a/src/MainWindow.cc b/src/MainWindow.cc
index 92388ae4..5c188903 100644
--- a/src/MainWindow.cc
+++ b/src/MainWindow.cc
@@ -31,6 +31,7 @@
#include "RegisterPage.h"
#include "SnackBar.h"
#include "TrayIcon.h"
+#include "UserSettingsPage.h"
#include "WelcomePage.h"
MainWindow *MainWindow::instance_ = nullptr;
@@ -54,13 +55,15 @@ MainWindow::MainWindow(QWidget *parent)
font.setStyleStrategy(QFont::PreferAntialias);
setFont(font);
- client_ = QSharedPointer<MatrixClient>(new MatrixClient("matrix.org"));
- trayIcon_ = new TrayIcon(":/logos/nheko-32.png", this);
+ client_ = QSharedPointer<MatrixClient>(new MatrixClient("matrix.org"));
+ userSettings_ = QSharedPointer<UserSettings>(new UserSettings);
+ trayIcon_ = new TrayIcon(":/logos/nheko-32.png", this);
- welcome_page_ = new WelcomePage(this);
- login_page_ = new LoginPage(client_, this);
- register_page_ = new RegisterPage(client_, this);
- chat_page_ = new ChatPage(client_, this);
+ welcome_page_ = new WelcomePage(this);
+ login_page_ = new LoginPage(client_, this);
+ register_page_ = new RegisterPage(client_, this);
+ chat_page_ = new ChatPage(client_, this);
+ userSettingsPage_ = new UserSettingsPage(userSettings_, this);
// Initialize sliding widget manager.
pageStack_ = new QStackedWidget(this);
@@ -68,6 +71,7 @@ MainWindow::MainWindow(QWidget *parent)
pageStack_->addWidget(login_page_);
pageStack_->addWidget(register_page_);
pageStack_->addWidget(chat_page_);
+ pageStack_->addWidget(userSettingsPage_);
setCentralWidget(pageStack_);
@@ -86,12 +90,18 @@ MainWindow::MainWindow(QWidget *parent)
showLoginPage();
});
+ connect(userSettingsPage_, &UserSettingsPage::moveBack, this, [=]() {
+ pageStack_->setCurrentWidget(chat_page_);
+ });
+
connect(trayIcon_,
SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
this,
SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
connect(chat_page_, SIGNAL(contentLoaded()), this, SLOT(removeOverlayProgressBar()));
+ connect(
+ chat_page_, &ChatPage::showUserSettingsPage, this, &MainWindow::showUserSettingsPage);
connect(client_.data(),
SIGNAL(loginSuccess(QString, QString, QString)),
@@ -235,6 +245,12 @@ MainWindow::showRegisterPage()
}
void
+MainWindow::showUserSettingsPage()
+{
+ pageStack_->setCurrentWidget(userSettingsPage_);
+}
+
+void
MainWindow::closeEvent(QCloseEvent *event)
{
if (isVisible()) {
diff --git a/src/SideBarActions.cc b/src/SideBarActions.cc
index 1484bd00..3898eb22 100644
--- a/src/SideBarActions.cc
+++ b/src/SideBarActions.cc
@@ -45,6 +45,8 @@ SideBarActions::SideBarActions(QWidget *parent)
layout_->addWidget(createRoomBtn_);
layout_->addWidget(joinRoomBtn_);
layout_->addWidget(settingsBtn_);
+
+ connect(settingsBtn_, &QPushButton::clicked, this, &SideBarActions::showSettings);
}
SideBarActions::~SideBarActions() {}
diff --git a/src/UserSettingsPage.cc b/src/UserSettingsPage.cc
new file mode 100644
index 00000000..ff4714f5
--- /dev/null
+++ b/src/UserSettingsPage.cc
@@ -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());
+}
diff --git a/src/ui/ToggleButton.cc b/src/ui/ToggleButton.cc
new file mode 100644
index 00000000..8054bfe7
--- /dev/null
+++ b/src/ui/ToggleButton.cc
@@ -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);
+}
|