Add dummy settings menu

This commit is contained in:
Konstantinos Sideris 2017-11-02 00:41:13 +02:00
parent 287b5aa4c0
commit 886edd03fb
11 changed files with 581 additions and 6 deletions

View file

@ -153,6 +153,7 @@ set(SRC_FILES
src/RoomMessages.cc src/RoomMessages.cc
src/RoomState.cc src/RoomState.cc
src/SideBarActions.cc src/SideBarActions.cc
src/UserSettingsPage.cc
src/Splitter.cc src/Splitter.cc
src/Sync.cc src/Sync.cc
src/TextInputWidget.cc src/TextInputWidget.cc
@ -181,6 +182,7 @@ set(SRC_FILES
src/ui/RippleOverlay.cc src/ui/RippleOverlay.cc
src/ui/OverlayWidget.cc src/ui/OverlayWidget.cc
src/ui/TextField.cc src/ui/TextField.cc
src/ui/ToggleButton.cc
src/ui/Theme.cc src/ui/Theme.cc
src/ui/ThemeManager.cc src/ui/ThemeManager.cc
) )
@ -239,6 +241,7 @@ qt5_wrap_cpp(MOC_HEADERS
include/RoomInfoListItem.h include/RoomInfoListItem.h
include/RoomList.h include/RoomList.h
include/SideBarActions.h include/SideBarActions.h
include/UserSettingsPage.h
include/Splitter.h include/Splitter.h
include/TextInputWidget.h include/TextInputWidget.h
include/TimelineItem.h include/TimelineItem.h
@ -262,6 +265,7 @@ qt5_wrap_cpp(MOC_HEADERS
include/ui/Ripple.h include/ui/Ripple.h
include/ui/RippleOverlay.h include/ui/RippleOverlay.h
include/ui/TextField.h include/ui/TextField.h
include/ui/ToggleButton.h
include/ui/Theme.h include/ui/Theme.h
include/ui/ThemeManager.h include/ui/ThemeManager.h
) )

View file

@ -68,6 +68,7 @@ signals:
void unreadMessages(int count); void unreadMessages(int count);
void showNotification(const QString &msg); void showNotification(const QString &msg);
void showLoginPage(const QString &msg); void showLoginPage(const QString &msg);
void showUserSettingsPage();
private slots: private slots:
void showUnreadMessageNotification(int count); void showUnreadMessageNotification(int count);

View file

@ -30,6 +30,8 @@ class OverlayModal;
class RegisterPage; class RegisterPage;
class SnackBar; class SnackBar;
class TrayIcon; class TrayIcon;
class UserSettingsPage;
class UserSettings;
class WelcomePage; class WelcomePage;
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
@ -59,6 +61,7 @@ private slots:
// Show the register page in the main window. // Show the register page in the main window.
void showRegisterPage(); void showRegisterPage();
void showUserSettingsPage();
// Show the chat page and start communicating with the given access token. // Show the chat page and start communicating with the given access token.
void showChatPage(QString user_id, QString home_server, QString token); void showChatPage(QString user_id, QString home_server, QString token);
@ -85,6 +88,8 @@ private:
// The main chat area. // The main chat area.
ChatPage *chat_page_; ChatPage *chat_page_;
UserSettingsPage *userSettingsPage_;
QSharedPointer<UserSettings> userSettings_;
// Used to hide undefined states between page transitions. // Used to hide undefined states between page transitions.
QSharedPointer<OverlayModal> progressModal_; QSharedPointer<OverlayModal> progressModal_;

View file

@ -14,6 +14,9 @@ public:
SideBarActions(QWidget *parent = nullptr); SideBarActions(QWidget *parent = nullptr);
~SideBarActions(); ~SideBarActions();
signals:
void showSettings();
protected: protected:
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent *event) override;

View file

@ -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_;
};

110
include/ui/ToggleButton.h Normal file
View file

@ -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_;
};

View file

@ -75,6 +75,8 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent)
sideBarMainLayout_->setMargin(0); sideBarMainLayout_->setMargin(0);
sidebarActions_ = new SideBarActions(this); sidebarActions_ = new SideBarActions(this);
connect(
sidebarActions_, &SideBarActions::showSettings, this, &ChatPage::showUserSettingsPage);
sideBarLayout_->addLayout(sideBarTopLayout_); sideBarLayout_->addLayout(sideBarTopLayout_);
sideBarLayout_->addLayout(sideBarMainLayout_); sideBarLayout_->addLayout(sideBarMainLayout_);

View file

@ -31,6 +31,7 @@
#include "RegisterPage.h" #include "RegisterPage.h"
#include "SnackBar.h" #include "SnackBar.h"
#include "TrayIcon.h" #include "TrayIcon.h"
#include "UserSettingsPage.h"
#include "WelcomePage.h" #include "WelcomePage.h"
MainWindow *MainWindow::instance_ = nullptr; MainWindow *MainWindow::instance_ = nullptr;
@ -54,13 +55,15 @@ MainWindow::MainWindow(QWidget *parent)
font.setStyleStrategy(QFont::PreferAntialias); font.setStyleStrategy(QFont::PreferAntialias);
setFont(font); setFont(font);
client_ = QSharedPointer<MatrixClient>(new MatrixClient("matrix.org")); client_ = QSharedPointer<MatrixClient>(new MatrixClient("matrix.org"));
trayIcon_ = new TrayIcon(":/logos/nheko-32.png", this); userSettings_ = QSharedPointer<UserSettings>(new UserSettings);
trayIcon_ = new TrayIcon(":/logos/nheko-32.png", this);
welcome_page_ = new WelcomePage(this); welcome_page_ = new WelcomePage(this);
login_page_ = new LoginPage(client_, this); login_page_ = new LoginPage(client_, this);
register_page_ = new RegisterPage(client_, this); register_page_ = new RegisterPage(client_, this);
chat_page_ = new ChatPage(client_, this); chat_page_ = new ChatPage(client_, this);
userSettingsPage_ = new UserSettingsPage(userSettings_, this);
// Initialize sliding widget manager. // Initialize sliding widget manager.
pageStack_ = new QStackedWidget(this); pageStack_ = new QStackedWidget(this);
@ -68,6 +71,7 @@ MainWindow::MainWindow(QWidget *parent)
pageStack_->addWidget(login_page_); pageStack_->addWidget(login_page_);
pageStack_->addWidget(register_page_); pageStack_->addWidget(register_page_);
pageStack_->addWidget(chat_page_); pageStack_->addWidget(chat_page_);
pageStack_->addWidget(userSettingsPage_);
setCentralWidget(pageStack_); setCentralWidget(pageStack_);
@ -86,12 +90,18 @@ MainWindow::MainWindow(QWidget *parent)
showLoginPage(); showLoginPage();
}); });
connect(userSettingsPage_, &UserSettingsPage::moveBack, this, [=]() {
pageStack_->setCurrentWidget(chat_page_);
});
connect(trayIcon_, connect(trayIcon_,
SIGNAL(activated(QSystemTrayIcon::ActivationReason)), SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
this, this,
SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
connect(chat_page_, SIGNAL(contentLoaded()), this, SLOT(removeOverlayProgressBar())); connect(chat_page_, SIGNAL(contentLoaded()), this, SLOT(removeOverlayProgressBar()));
connect(
chat_page_, &ChatPage::showUserSettingsPage, this, &MainWindow::showUserSettingsPage);
connect(client_.data(), connect(client_.data(),
SIGNAL(loginSuccess(QString, QString, QString)), SIGNAL(loginSuccess(QString, QString, QString)),
@ -234,6 +244,12 @@ MainWindow::showRegisterPage()
pageStack_->setCurrentWidget(register_page_); pageStack_->setCurrentWidget(register_page_);
} }
void
MainWindow::showUserSettingsPage()
{
pageStack_->setCurrentWidget(userSettingsPage_);
}
void void
MainWindow::closeEvent(QCloseEvent *event) MainWindow::closeEvent(QCloseEvent *event)
{ {

View file

@ -45,6 +45,8 @@ SideBarActions::SideBarActions(QWidget *parent)
layout_->addWidget(createRoomBtn_); layout_->addWidget(createRoomBtn_);
layout_->addWidget(joinRoomBtn_); layout_->addWidget(joinRoomBtn_);
layout_->addWidget(settingsBtn_); layout_->addWidget(settingsBtn_);
connect(settingsBtn_, &QPushButton::clicked, this, &SideBarActions::showSettings);
} }
SideBarActions::~SideBarActions() {} SideBarActions::~SideBarActions() {}

140
src/UserSettingsPage.cc Normal file
View file

@ -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());
}

212
src/ui/ToggleButton.cc Normal file
View file

@ -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);
}