summary refs log tree commit diff
path: root/src/ui
diff options
context:
space:
mode:
authorKonstantinos Sideris <sideris.konstantin@gmail.com>2018-07-17 16:37:25 +0300
committerKonstantinos Sideris <sideris.konstantin@gmail.com>2018-07-17 16:37:25 +0300
commit0e814da91c8e041897a4c3f7e6e9234bbc7c6f7a (patch)
tree21f655d30630fe77ba48d07e4b357e2b6c6a5730 /src/ui
parentMerge pull request #372 from bebehei/notification (diff)
downloadnheko-0e814da91c8e041897a4c3f7e6e9234bbc7c6f7a.tar.xz
Move all files under src/
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/Avatar.cpp (renamed from src/ui/Avatar.cc)2
-rw-r--r--src/ui/Avatar.h47
-rw-r--r--src/ui/Badge.cpp (renamed from src/ui/Badge.cc)0
-rw-r--r--src/ui/Badge.h62
-rw-r--r--src/ui/DropShadow.h111
-rw-r--r--src/ui/FlatButton.cpp (renamed from src/ui/FlatButton.cc)0
-rw-r--r--src/ui/FlatButton.h185
-rw-r--r--src/ui/FloatingButton.cpp (renamed from src/ui/FloatingButton.cc)0
-rw-r--r--src/ui/FloatingButton.h26
-rw-r--r--src/ui/InfoMessage.cpp2
-rw-r--r--src/ui/InfoMessage.h47
-rw-r--r--src/ui/Label.cpp (renamed from src/ui/Label.cc)0
-rw-r--r--src/ui/Label.h25
-rw-r--r--src/ui/LoadingIndicator.cpp (renamed from src/ui/LoadingIndicator.cc)0
-rw-r--r--src/ui/LoadingIndicator.h38
-rw-r--r--src/ui/Menu.h32
-rw-r--r--src/ui/OverlayModal.cpp (renamed from src/ui/OverlayModal.cc)0
-rw-r--r--src/ui/OverlayModal.h45
-rw-r--r--src/ui/OverlayWidget.cpp (renamed from src/ui/OverlayWidget.cc)0
-rw-r--r--src/ui/OverlayWidget.h21
-rw-r--r--src/ui/Painter.h161
-rw-r--r--src/ui/RaisedButton.cpp (renamed from src/ui/RaisedButton.cc)0
-rw-r--r--src/ui/RaisedButton.h28
-rw-r--r--src/ui/Ripple.cpp (renamed from src/ui/Ripple.cc)0
-rw-r--r--src/ui/Ripple.h145
-rw-r--r--src/ui/RippleOverlay.cpp (renamed from src/ui/RippleOverlay.cc)0
-rw-r--r--src/ui/RippleOverlay.h57
-rw-r--r--src/ui/ScrollBar.cpp (renamed from src/ui/ScrollBar.cc)0
-rw-r--r--src/ui/ScrollBar.h54
-rw-r--r--src/ui/SnackBar.cpp (renamed from src/ui/SnackBar.cc)0
-rw-r--r--src/ui/SnackBar.h79
-rw-r--r--src/ui/TextField.cpp (renamed from src/ui/TextField.cc)0
-rw-r--r--src/ui/TextField.h174
-rw-r--r--src/ui/Theme.cpp (renamed from src/ui/Theme.cc)0
-rw-r--r--src/ui/Theme.h97
-rw-r--r--src/ui/ThemeManager.cpp (renamed from src/ui/ThemeManager.cc)0
-rw-r--r--src/ui/ThemeManager.h31
-rw-r--r--src/ui/ToggleButton.cpp (renamed from src/ui/ToggleButton.cc)0
-rw-r--r--src/ui/ToggleButton.h110
39 files changed, 1577 insertions, 2 deletions
diff --git a/src/ui/Avatar.cc b/src/ui/Avatar.cpp

index 2f10db39..4b4cd272 100644 --- a/src/ui/Avatar.cc +++ b/src/ui/Avatar.cpp
@@ -1,7 +1,7 @@ #include <QPainter> -#include "Avatar.h" #include "Utils.h" +#include "ui/Avatar.h" Avatar::Avatar(QWidget *parent) : QWidget(parent) diff --git a/src/ui/Avatar.h b/src/ui/Avatar.h new file mode 100644
index 00000000..41967af5 --- /dev/null +++ b/src/ui/Avatar.h
@@ -0,0 +1,47 @@ +#pragma once + +#include <QIcon> +#include <QImage> +#include <QPixmap> +#include <QWidget> + +#include "Theme.h" + +class Avatar : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor) + Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) + +public: + explicit Avatar(QWidget *parent = 0); + + void setBackgroundColor(const QColor &color); + void setIcon(const QIcon &icon); + void setImage(const QImage &image); + void setLetter(const QString &letter); + void setSize(int size); + void setTextColor(const QColor &color); + + QColor backgroundColor() const; + QColor textColor() const; + int size() const; + + QSize sizeHint() const override; + +protected: + void paintEvent(QPaintEvent *event) override; + +private: + void init(); + + ui::AvatarType type_; + QString letter_; + QColor background_color_; + QColor text_color_; + QIcon icon_; + QImage image_; + QPixmap pixmap_; + int size_; +}; diff --git a/src/ui/Badge.cc b/src/ui/Badge.cpp
index 6701f9b7..6701f9b7 100644 --- a/src/ui/Badge.cc +++ b/src/ui/Badge.cpp
diff --git a/src/ui/Badge.h b/src/ui/Badge.h new file mode 100644
index 00000000..fd73ad30 --- /dev/null +++ b/src/ui/Badge.h
@@ -0,0 +1,62 @@ +#pragma once + +#include <QColor> +#include <QIcon> +#include <QWidget> +#include <QtGlobal> + +#include "OverlayWidget.h" + +class Badge : public OverlayWidget +{ + Q_OBJECT + + Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor) + Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) + Q_PROPERTY(QPointF relativePosition WRITE setRelativePosition READ relativePosition) + +public: + explicit Badge(QWidget *parent = 0); + explicit Badge(const QIcon &icon, QWidget *parent = 0); + explicit Badge(const QString &text, QWidget *parent = 0); + + void setBackgroundColor(const QColor &color); + void setTextColor(const QColor &color); + void setIcon(const QIcon &icon); + void setRelativePosition(const QPointF &pos); + void setRelativePosition(qreal x, qreal y); + void setRelativeXPosition(qreal x); + void setRelativeYPosition(qreal y); + void setText(const QString &text); + void setDiameter(int diameter); + + QIcon icon() const; + QString text() const; + QColor backgroundColor() const; + QColor textColor() const; + QPointF relativePosition() const; + QSize sizeHint() const override; + qreal relativeXPosition() const; + qreal relativeYPosition() const; + + int diameter() const; + +protected: + void paintEvent(QPaintEvent *event) override; + +private: + void init(); + + QColor background_color_; + QColor text_color_; + + QIcon icon_; + QSize size_; + QString text_; + + int padding_; + int diameter_; + + qreal x_; + qreal y_; +}; diff --git a/src/ui/DropShadow.h b/src/ui/DropShadow.h new file mode 100644
index 00000000..b7ba1985 --- /dev/null +++ b/src/ui/DropShadow.h
@@ -0,0 +1,111 @@ +#pragma once + +#include <QColor> +#include <QLinearGradient> +#include <QPainter> + +class DropShadow +{ +public: + static void draw(QPainter &painter, + qint16 margin, + qreal radius, + QColor start, + QColor end, + qreal startPosition, + qreal endPosition0, + qreal endPosition1, + qreal width, + qreal height) + { + painter.setPen(Qt::NoPen); + + QLinearGradient gradient; + gradient.setColorAt(startPosition, start); + gradient.setColorAt(endPosition0, end); + + // Right + QPointF right0(width - margin, height / 2); + QPointF right1(width, height / 2); + gradient.setStart(right0); + gradient.setFinalStop(right1); + painter.setBrush(QBrush(gradient)); + painter.drawRoundRect( + QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - margin)), + 0.0, + 0.0); + + // Left + QPointF left0(margin, height / 2); + QPointF left1(0, height / 2); + gradient.setStart(left0); + gradient.setFinalStop(left1); + painter.setBrush(QBrush(gradient)); + painter.drawRoundRect( + QRectF(QPointF(margin * radius, margin), QPointF(0, height - margin)), 0.0, 0.0); + + // Top + QPointF top0(width / 2, margin); + QPointF top1(width / 2, 0); + gradient.setStart(top0); + gradient.setFinalStop(top1); + painter.setBrush(QBrush(gradient)); + painter.drawRoundRect( + QRectF(QPointF(width - margin, 0), QPointF(margin, margin)), 0.0, 0.0); + + // Bottom + QPointF bottom0(width / 2, height - margin); + QPointF bottom1(width / 2, height); + gradient.setStart(bottom0); + gradient.setFinalStop(bottom1); + painter.setBrush(QBrush(gradient)); + painter.drawRoundRect( + QRectF(QPointF(margin, height - margin), QPointF(width - margin, height)), + 0.0, + 0.0); + + // BottomRight + QPointF bottomright0(width - margin, height - margin); + QPointF bottomright1(width, height); + gradient.setStart(bottomright0); + gradient.setFinalStop(bottomright1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundRect(QRectF(bottomright0, bottomright1), 0.0, 0.0); + + // BottomLeft + QPointF bottomleft0(margin, height - margin); + QPointF bottomleft1(0, height); + gradient.setStart(bottomleft0); + gradient.setFinalStop(bottomleft1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundRect(QRectF(bottomleft0, bottomleft1), 0.0, 0.0); + + // TopLeft + QPointF topleft0(margin, margin); + QPointF topleft1(0, 0); + gradient.setStart(topleft0); + gradient.setFinalStop(topleft1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundRect(QRectF(topleft0, topleft1), 0.0, 0.0); + + // TopRight + QPointF topright0(width - margin, margin); + QPointF topright1(width, 0); + gradient.setStart(topright0); + gradient.setFinalStop(topright1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundRect(QRectF(topright0, topright1), 0.0, 0.0); + + // Widget + painter.setBrush(QBrush("#FFFFFF")); + painter.setRenderHint(QPainter::Antialiasing); + painter.drawRoundRect( + QRectF(QPointF(margin, margin), QPointF(width - margin, height - margin)), + radius, + radius); + } +}; diff --git a/src/ui/FlatButton.cc b/src/ui/FlatButton.cpp
index 45a7683e..45a7683e 100644 --- a/src/ui/FlatButton.cc +++ b/src/ui/FlatButton.cpp
diff --git a/src/ui/FlatButton.h b/src/ui/FlatButton.h new file mode 100644
index 00000000..9c2bf425 --- /dev/null +++ b/src/ui/FlatButton.h
@@ -0,0 +1,185 @@ +#pragma once + +#include <QPaintEvent> +#include <QPainter> +#include <QPushButton> +#include <QStateMachine> + +#include "Theme.h" + +class RippleOverlay; +class FlatButton; + +class FlatButtonStateMachine : public QStateMachine +{ + Q_OBJECT + + Q_PROPERTY(qreal overlayOpacity WRITE setOverlayOpacity READ overlayOpacity) + Q_PROPERTY( + qreal checkedOverlayProgress WRITE setCheckedOverlayProgress READ checkedOverlayProgress) + +public: + explicit FlatButtonStateMachine(FlatButton *parent); + ~FlatButtonStateMachine(); + + void setOverlayOpacity(qreal opacity); + void setCheckedOverlayProgress(qreal opacity); + + inline qreal overlayOpacity() const; + inline qreal checkedOverlayProgress() const; + + void startAnimations(); + void setupProperties(); + void updateCheckedStatus(); + +signals: + void buttonPressed(); + void buttonChecked(); + void buttonUnchecked(); + +protected: + bool eventFilter(QObject *watched, QEvent *event) override; + +private: + void addTransition(QObject *object, const char *signal, QState *fromState, QState *toState); + void addTransition(QObject *object, + QEvent::Type eventType, + QState *fromState, + QState *toState); + void addTransition(QAbstractTransition *transition, QState *fromState, QState *toState); + + FlatButton *const button_; + + QState *const top_level_state_; + QState *const config_state_; + QState *const checkable_state_; + QState *const checked_state_; + QState *const unchecked_state_; + QState *const neutral_state_; + QState *const neutral_focused_state_; + QState *const hovered_state_; + QState *const hovered_focused_state_; + QState *const pressed_state_; + + qreal overlay_opacity_; + qreal checked_overlay_progress_; + + bool was_checked_; +}; + +inline qreal +FlatButtonStateMachine::overlayOpacity() const +{ + return overlay_opacity_; +} + +inline qreal +FlatButtonStateMachine::checkedOverlayProgress() const +{ + return checked_overlay_progress_; +} + +class FlatButton : public QPushButton +{ + Q_OBJECT + + Q_PROPERTY(QColor foregroundColor WRITE setForegroundColor READ foregroundColor) + Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) + Q_PROPERTY(QColor overlayColor WRITE setOverlayColor READ overlayColor) + Q_PROPERTY(QColor disabledForegroundColor WRITE setDisabledForegroundColor READ + disabledForegroundColor) + Q_PROPERTY(QColor disabledBackgroundColor WRITE setDisabledBackgroundColor READ + disabledBackgroundColor) + Q_PROPERTY(qreal fontSize WRITE setFontSize READ fontSize) + +public: + explicit FlatButton(QWidget *parent = 0, + ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset); + explicit FlatButton(const QString &text, + QWidget *parent = 0, + ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset); + FlatButton(const QString &text, + ui::Role role, + QWidget *parent = 0, + ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset); + ~FlatButton(); + + void applyPreset(ui::ButtonPreset preset); + + void setBackgroundColor(const QColor &color); + void setBackgroundMode(Qt::BGMode mode); + void setBaseOpacity(qreal opacity); + void setCheckable(bool value); + void setCornerRadius(qreal radius); + void setDisabledBackgroundColor(const QColor &color); + void setDisabledForegroundColor(const QColor &color); + void setFixedRippleRadius(qreal radius); + void setFontSize(qreal size); + void setForegroundColor(const QColor &color); + void setHasFixedRippleRadius(bool value); + void setIconPlacement(ui::ButtonIconPlacement placement); + void setOverlayColor(const QColor &color); + void setOverlayStyle(ui::OverlayStyle style); + void setRippleStyle(ui::RippleStyle style); + void setRole(ui::Role role); + + QColor foregroundColor() const; + QColor backgroundColor() const; + QColor overlayColor() const; + QColor disabledForegroundColor() const; + QColor disabledBackgroundColor() const; + + qreal fontSize() const; + qreal cornerRadius() const; + qreal baseOpacity() const; + + bool hasFixedRippleRadius() const; + + ui::Role role() const; + ui::OverlayStyle overlayStyle() const; + ui::RippleStyle rippleStyle() const; + ui::ButtonIconPlacement iconPlacement() const; + + Qt::BGMode backgroundMode() const; + + QSize sizeHint() const override; + +protected: + int IconPadding = 0; + + void checkStateSet() override; + void mousePressEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void paintEvent(QPaintEvent *event) override; + + virtual void paintBackground(QPainter *painter); + virtual void paintForeground(QPainter *painter); + virtual void updateClipPath(); + + void init(); + +private: + RippleOverlay *ripple_overlay_; + FlatButtonStateMachine *state_machine_; + + ui::Role role_; + ui::RippleStyle ripple_style_; + ui::ButtonIconPlacement icon_placement_; + ui::OverlayStyle overlay_style_; + + Qt::BGMode bg_mode_; + + QColor background_color_; + QColor foreground_color_; + QColor overlay_color_; + QColor disabled_color_; + QColor disabled_background_color_; + + qreal fixed_ripple_radius_; + qreal corner_radius_; + qreal base_opacity_; + qreal font_size_; + + bool use_fixed_ripple_radius_; +}; diff --git a/src/ui/FloatingButton.cc b/src/ui/FloatingButton.cpp
index 74dcd482..74dcd482 100644 --- a/src/ui/FloatingButton.cc +++ b/src/ui/FloatingButton.cpp
diff --git a/src/ui/FloatingButton.h b/src/ui/FloatingButton.h new file mode 100644
index 00000000..91e99ebb --- /dev/null +++ b/src/ui/FloatingButton.h
@@ -0,0 +1,26 @@ +#pragma once + +#include "RaisedButton.h" + +constexpr int DIAMETER = 40; +constexpr int ICON_SIZE = 18; + +constexpr int OFFSET_X = 30; +constexpr int OFFSET_Y = 20; + +class FloatingButton : public RaisedButton +{ + Q_OBJECT + +public: + FloatingButton(const QIcon &icon, QWidget *parent = nullptr); + + QSize sizeHint() const override { return QSize(DIAMETER, DIAMETER); }; + QRect buttonGeometry() const; + +protected: + bool event(QEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event) override; + + void paintEvent(QPaintEvent *event) override; +}; diff --git a/src/ui/InfoMessage.cpp b/src/ui/InfoMessage.cpp
index b150e61b..3151bedf 100644 --- a/src/ui/InfoMessage.cpp +++ b/src/ui/InfoMessage.cpp
@@ -1,5 +1,5 @@ +#include "InfoMessage.h" #include "Config.h" -#include "InfoMessage.hpp" #include <QDateTime> #include <QPainter> diff --git a/src/ui/InfoMessage.h b/src/ui/InfoMessage.h new file mode 100644
index 00000000..58f98b0c --- /dev/null +++ b/src/ui/InfoMessage.h
@@ -0,0 +1,47 @@ +#pragma once + +#include <QColor> +#include <QDateTime> +#include <QWidget> + +class InfoMessage : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor) + Q_PROPERTY(QColor boxColor WRITE setBoxColor READ boxColor) + +public: + explicit InfoMessage(QWidget *parent = nullptr); + InfoMessage(QString msg, QWidget *parent = nullptr); + + void setTextColor(QColor color) { textColor_ = color; } + void setBoxColor(QColor color) { boxColor_ = color; } + void saveDatetime(QDateTime datetime) { datetime_ = datetime; } + + QColor textColor() const { return textColor_; } + QColor boxColor() const { return boxColor_; } + QDateTime datetime() const { return datetime_; } + +protected: + void paintEvent(QPaintEvent *event) override; + + int width_; + int height_; + + QString msg_; + QFont font_; + + QDateTime datetime_; + + QColor textColor_ = QColor("black"); + QColor boxColor_ = QColor("white"); +}; + +class DateSeparator : public InfoMessage +{ + Q_OBJECT + +public: + DateSeparator(QDateTime datetime, QWidget *parent = nullptr); +}; diff --git a/src/ui/Label.cc b/src/ui/Label.cpp
index 8bd8c54e..8bd8c54e 100644 --- a/src/ui/Label.cc +++ b/src/ui/Label.cpp
diff --git a/src/ui/Label.h b/src/ui/Label.h new file mode 100644
index 00000000..09cf27d7 --- /dev/null +++ b/src/ui/Label.h
@@ -0,0 +1,25 @@ +#pragma once + +#include <QLabel> + +class Label : public QLabel +{ + Q_OBJECT + +public: + explicit Label(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); + explicit Label(const QString &text, + QWidget *parent = Q_NULLPTR, + Qt::WindowFlags f = Qt::WindowFlags()); + +signals: + void clicked(QMouseEvent *e); + void pressed(QMouseEvent *e); + void released(QMouseEvent *e); + +protected: + void mousePressEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + + QPoint pressPosition_; +}; diff --git a/src/ui/LoadingIndicator.cc b/src/ui/LoadingIndicator.cpp
index f64151ce..f64151ce 100644 --- a/src/ui/LoadingIndicator.cc +++ b/src/ui/LoadingIndicator.cpp
diff --git a/src/ui/LoadingIndicator.h b/src/ui/LoadingIndicator.h new file mode 100644
index 00000000..bb33fe6c --- /dev/null +++ b/src/ui/LoadingIndicator.h
@@ -0,0 +1,38 @@ +#pragma once + +#include <QColor> +#include <QPaintEvent> +#include <QPainter> +#include <QTimer> +#include <QWidget> + +class LoadingIndicator : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor) + +public: + LoadingIndicator(QWidget *parent = 0); + virtual ~LoadingIndicator(); + + void paintEvent(QPaintEvent *e); + + void start(); + void stop(); + + QColor color() { return color_; } + void setColor(QColor color) { color_ = color; } + + int interval() { return interval_; } + void setInterval(int interval) { interval_ = interval; } + +private slots: + void onTimeout(); + +private: + int interval_; + int angle_; + + QColor color_; + QTimer *timer_; +}; diff --git a/src/ui/Menu.h b/src/ui/Menu.h new file mode 100644
index 00000000..4c2a3c68 --- /dev/null +++ b/src/ui/Menu.h
@@ -0,0 +1,32 @@ +#pragma once + +#include <QMenu> + +#include "Config.h" + +class Menu : public QMenu +{ +public: + Menu(QWidget *parent = nullptr) + : QMenu(parent) + { + QFont font; + font.setPixelSize(conf::fontSize); + + setFont(font); + setStyleSheet( + "QMenu { color: black; background-color: white; margin: 0px;}" + "QMenu::item {" + "color: black; padding: 7px 20px; border: 1px solid transparent;" + "margin: 2px 0px; }" + "QMenu::item:selected { color: black; background: rgba(180, 180, 180, 100); }"); + }; + +protected: + void leaveEvent(QEvent *e) + { + Q_UNUSED(e); + + hide(); + } +}; diff --git a/src/ui/OverlayModal.cc b/src/ui/OverlayModal.cpp
index 6aa16b07..6aa16b07 100644 --- a/src/ui/OverlayModal.cc +++ b/src/ui/OverlayModal.cpp
diff --git a/src/ui/OverlayModal.h b/src/ui/OverlayModal.h new file mode 100644
index 00000000..a761e3ed --- /dev/null +++ b/src/ui/OverlayModal.h
@@ -0,0 +1,45 @@ +/* + * 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 <QKeyEvent> +#include <QMouseEvent> +#include <QPaintEvent> + +#include "OverlayWidget.h" + +class OverlayModal : public OverlayWidget +{ +public: + OverlayModal(QWidget *parent, QWidget *content); + + void setColor(QColor color) { color_ = color; } + void setDismissible(bool state) { isDismissible_ = state; } + +protected: + void paintEvent(QPaintEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + +private: + QWidget *content_; + QColor color_; + + //! Decides whether or not the modal can be removed by clicking into it. + bool isDismissible_ = true; +}; diff --git a/src/ui/OverlayWidget.cc b/src/ui/OverlayWidget.cpp
index ccac0116..ccac0116 100644 --- a/src/ui/OverlayWidget.cc +++ b/src/ui/OverlayWidget.cpp
diff --git a/src/ui/OverlayWidget.h b/src/ui/OverlayWidget.h new file mode 100644
index 00000000..6662479d --- /dev/null +++ b/src/ui/OverlayWidget.h
@@ -0,0 +1,21 @@ +#pragma once + +#include <QEvent> +#include <QPainter> +#include <QStyleOption> +#include <QWidget> + +class OverlayWidget : public QWidget +{ + Q_OBJECT + +public: + explicit OverlayWidget(QWidget *parent = nullptr); + +protected: + bool event(QEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event) override; + + QRect overlayGeometry() const; + void paintEvent(QPaintEvent *event) override; +}; diff --git a/src/ui/Painter.h b/src/ui/Painter.h new file mode 100644
index 00000000..8de39651 --- /dev/null +++ b/src/ui/Painter.h
@@ -0,0 +1,161 @@ +#pragma once + +#include <QFontMetrics> +#include <QPaintDevice> +#include <QPainter> + +class Painter : public QPainter +{ +public: + explicit Painter(QPaintDevice *device) + : QPainter(device) + {} + + void drawTextLeft(int x, int y, const QString &text) + { + QFontMetrics m(fontMetrics()); + drawText(x, y + m.ascent(), text); + } + + void drawTextRight(int x, int y, int outerw, const QString &text, int textWidth = -1) + { + QFontMetrics m(fontMetrics()); + if (textWidth < 0) + textWidth = m.width(text); + drawText((outerw - x - textWidth), y + m.ascent(), text); + } + + void drawPixmapLeft(int x, int y, const QPixmap &pix, const QRect &from) + { + drawPixmap(QPoint(x, y), pix, from); + } + + void drawPixmapLeft(const QPoint &p, const QPixmap &pix, const QRect &from) + { + return drawPixmapLeft(p.x(), p.y(), pix, from); + } + + void drawPixmapLeft(int x, int y, int w, int h, const QPixmap &pix, const QRect &from) + { + drawPixmap(QRect(x, y, w, h), pix, from); + } + + void drawPixmapLeft(const QRect &r, const QPixmap &pix, const QRect &from) + { + return drawPixmapLeft(r.x(), r.y(), r.width(), r.height(), pix, from); + } + + void drawPixmapLeft(int x, int y, int outerw, const QPixmap &pix) + { + Q_UNUSED(outerw); + drawPixmap(QPoint(x, y), pix); + } + + void drawPixmapLeft(const QPoint &p, int outerw, const QPixmap &pix) + { + return drawPixmapLeft(p.x(), p.y(), outerw, pix); + } + + void drawPixmapRight(int x, int y, int outerw, const QPixmap &pix, const QRect &from) + { + drawPixmap( + QPoint((outerw - x - (from.width() / pix.devicePixelRatio())), y), pix, from); + } + + void drawPixmapRight(const QPoint &p, int outerw, const QPixmap &pix, const QRect &from) + { + return drawPixmapRight(p.x(), p.y(), outerw, pix, from); + } + void drawPixmapRight(int x, + int y, + int w, + int h, + int outerw, + const QPixmap &pix, + const QRect &from) + { + drawPixmap(QRect((outerw - x - w), y, w, h), pix, from); + } + + void drawPixmapRight(const QRect &r, int outerw, const QPixmap &pix, const QRect &from) + { + return drawPixmapRight(r.x(), r.y(), r.width(), r.height(), outerw, pix, from); + } + + void drawPixmapRight(int x, int y, int outerw, const QPixmap &pix) + { + drawPixmap(QPoint((outerw - x - (pix.width() / pix.devicePixelRatio())), y), pix); + } + + void drawPixmapRight(const QPoint &p, int outerw, const QPixmap &pix) + { + return drawPixmapRight(p.x(), p.y(), outerw, pix); + } + + void drawAvatar(const QPixmap &pix, int w, int h, int d) + { + QPainterPath pp; + pp.addEllipse((w - d) / 2, (h - d) / 2, d, d); + + QRect region((w - d) / 2, (h - d) / 2, d, d); + + setClipPath(pp); + drawPixmap(region, pix); + } + + void drawLetterAvatar(const QString &c, + const QColor &penColor, + const QColor &brushColor, + int w, + int h, + int d) + { + QRect region((w - d) / 2, (h - d) / 2, d, d); + + setPen(Qt::NoPen); + setBrush(brushColor); + + drawEllipse(region.center(), d / 2, d / 2); + + setBrush(Qt::NoBrush); + drawEllipse(region.center(), d / 2, d / 2); + + setPen(penColor); + drawText(region.translated(0, -1), Qt::AlignCenter, c); + } +}; + +class PainterHighQualityEnabler +{ +public: + PainterHighQualityEnabler(Painter &p) + : _painter(p) + { + static constexpr QPainter::RenderHint Hints[] = {QPainter::Antialiasing, + QPainter::SmoothPixmapTransform, + QPainter::TextAntialiasing, + QPainter::HighQualityAntialiasing}; + + auto hints = _painter.renderHints(); + for (const auto &hint : Hints) { + if (!(hints & hint)) + hints_ |= hint; + } + + if (hints_) + _painter.setRenderHints(hints_); + } + + ~PainterHighQualityEnabler() + { + if (hints_) + _painter.setRenderHints(hints_, false); + } + + PainterHighQualityEnabler(const PainterHighQualityEnabler &other) = delete; + PainterHighQualityEnabler &operator=(const PainterHighQualityEnabler &other) = delete; + +private: + Painter &_painter; + QPainter::RenderHints hints_ = 0; +}; diff --git a/src/ui/RaisedButton.cc b/src/ui/RaisedButton.cpp
index c519f84f..c519f84f 100644 --- a/src/ui/RaisedButton.cc +++ b/src/ui/RaisedButton.cpp
diff --git a/src/ui/RaisedButton.h b/src/ui/RaisedButton.h new file mode 100644
index 00000000..edd5ee4a --- /dev/null +++ b/src/ui/RaisedButton.h
@@ -0,0 +1,28 @@ +#pragma once + +#include <QGraphicsDropShadowEffect> +#include <QState> +#include <QStateMachine> + +#include "FlatButton.h" + +class RaisedButton : public FlatButton +{ + Q_OBJECT + +public: + explicit RaisedButton(QWidget *parent = 0); + explicit RaisedButton(const QString &text, QWidget *parent = 0); + ~RaisedButton(); + +protected: + bool event(QEvent *event) override; + +private: + void init(); + + QStateMachine *shadow_state_machine_; + QState *normal_state_; + QState *pressed_state_; + QGraphicsDropShadowEffect *effect_; +}; diff --git a/src/ui/Ripple.cc b/src/ui/Ripple.cpp
index e22c4a62..e22c4a62 100644 --- a/src/ui/Ripple.cc +++ b/src/ui/Ripple.cpp
diff --git a/src/ui/Ripple.h b/src/ui/Ripple.h new file mode 100644
index 00000000..9184f061 --- /dev/null +++ b/src/ui/Ripple.h
@@ -0,0 +1,145 @@ +#pragma once + +#include <QBrush> +#include <QEasingCurve> +#include <QParallelAnimationGroup> +#include <QPoint> +#include <QPropertyAnimation> + +class RippleOverlay; + +class Ripple : public QParallelAnimationGroup +{ + Q_OBJECT + + Q_PROPERTY(qreal radius WRITE setRadius READ radius) + Q_PROPERTY(qreal opacity WRITE setOpacity READ opacity) + +public: + explicit Ripple(const QPoint &center, QObject *parent = 0); + Ripple(const QPoint &center, RippleOverlay *overlay, QObject *parent = 0); + + inline void setOverlay(RippleOverlay *overlay); + + void setRadius(qreal radius); + void setOpacity(qreal opacity); + void setColor(const QColor &color); + void setBrush(const QBrush &brush); + + inline qreal radius() const; + inline qreal opacity() const; + inline QColor color() const; + inline QBrush brush() const; + inline QPoint center() const; + + inline QPropertyAnimation *radiusAnimation() const; + inline QPropertyAnimation *opacityAnimation() const; + + inline void setOpacityStartValue(qreal value); + inline void setOpacityEndValue(qreal value); + inline void setRadiusStartValue(qreal value); + inline void setRadiusEndValue(qreal value); + inline void setDuration(int msecs); + +protected slots: + void destroy(); + +private: + Q_DISABLE_COPY(Ripple) + + QPropertyAnimation *animate(const QByteArray &property, + const QEasingCurve &easing = QEasingCurve::OutQuad, + int duration = 800); + + void init(); + + RippleOverlay *overlay_; + + QPropertyAnimation *const radius_anim_; + QPropertyAnimation *const opacity_anim_; + + qreal radius_; + qreal opacity_; + + QPoint center_; + QBrush brush_; +}; + +inline void +Ripple::setOverlay(RippleOverlay *overlay) +{ + overlay_ = overlay; +} + +inline qreal +Ripple::radius() const +{ + return radius_; +} + +inline qreal +Ripple::opacity() const +{ + return opacity_; +} + +inline QColor +Ripple::color() const +{ + return brush_.color(); +} + +inline QBrush +Ripple::brush() const +{ + return brush_; +} + +inline QPoint +Ripple::center() const +{ + return center_; +} + +inline QPropertyAnimation * +Ripple::radiusAnimation() const +{ + return radius_anim_; +} + +inline QPropertyAnimation * +Ripple::opacityAnimation() const +{ + return opacity_anim_; +} + +inline void +Ripple::setOpacityStartValue(qreal value) +{ + opacity_anim_->setStartValue(value); +} + +inline void +Ripple::setOpacityEndValue(qreal value) +{ + opacity_anim_->setEndValue(value); +} + +inline void +Ripple::setRadiusStartValue(qreal value) +{ + radius_anim_->setStartValue(value); +} + +inline void +Ripple::setRadiusEndValue(qreal value) +{ + radius_anim_->setEndValue(value); +} + +inline void +Ripple::setDuration(int msecs) +{ + radius_anim_->setDuration(msecs); + opacity_anim_->setDuration(msecs); +} diff --git a/src/ui/RippleOverlay.cc b/src/ui/RippleOverlay.cpp
index 20e98c0f..20e98c0f 100644 --- a/src/ui/RippleOverlay.cc +++ b/src/ui/RippleOverlay.cpp
diff --git a/src/ui/RippleOverlay.h b/src/ui/RippleOverlay.h new file mode 100644
index 00000000..9ef91fbf --- /dev/null +++ b/src/ui/RippleOverlay.h
@@ -0,0 +1,57 @@ +#pragma once + +#include <QPainterPath> + +#include "OverlayWidget.h" + +class Ripple; + +class RippleOverlay : public OverlayWidget +{ + Q_OBJECT + +public: + explicit RippleOverlay(QWidget *parent = 0); + + void addRipple(Ripple *ripple); + void addRipple(const QPoint &position, qreal radius = 300); + + void removeRipple(Ripple *ripple); + + inline void setClipping(bool enable); + inline bool hasClipping() const; + + inline void setClipPath(const QPainterPath &path); + +protected: + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(RippleOverlay) + + void paintRipple(QPainter *painter, Ripple *ripple); + + QList<Ripple *> ripples_; + QPainterPath clip_path_; + bool use_clip_; +}; + +inline void +RippleOverlay::setClipping(bool enable) +{ + use_clip_ = enable; + update(); +} + +inline bool +RippleOverlay::hasClipping() const +{ + return use_clip_; +} + +inline void +RippleOverlay::setClipPath(const QPainterPath &path) +{ + clip_path_ = path; + update(); +} diff --git a/src/ui/ScrollBar.cc b/src/ui/ScrollBar.cpp
index 37218a13..37218a13 100644 --- a/src/ui/ScrollBar.cc +++ b/src/ui/ScrollBar.cpp
diff --git a/src/ui/ScrollBar.h b/src/ui/ScrollBar.h new file mode 100644
index 00000000..2b5382aa --- /dev/null +++ b/src/ui/ScrollBar.h
@@ -0,0 +1,54 @@ +/* + * 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 <QPainter> +#include <QScrollArea> +#include <QScrollBar> + +class ScrollBar : public QScrollBar +{ + Q_OBJECT + Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) + Q_PROPERTY(QColor handleColor READ handleColor WRITE setHandleColor) + +public: + ScrollBar(QScrollArea *area, QWidget *parent = nullptr); + + QColor backgroundColor() const { return bgColor_; } + void setBackgroundColor(QColor &color) { bgColor_ = color; } + + QColor handleColor() const { return handleColor_; } + void setHandleColor(QColor &color) { handleColor_ = color; } + +protected: + void paintEvent(QPaintEvent *e) override; + +private: + int roundRadius_ = 4; + int handleWidth_ = 7; + int minHandleHeight_ = 20; + + const int Padding = 4; + + QScrollArea *area_; + QRect handle_; + + QColor bgColor_ = QColor(33, 33, 33, 30); + QColor handleColor_ = QColor(0, 0, 0, 80); +}; diff --git a/src/ui/SnackBar.cc b/src/ui/SnackBar.cpp
index 43a4c85d..43a4c85d 100644 --- a/src/ui/SnackBar.cc +++ b/src/ui/SnackBar.cpp
diff --git a/src/ui/SnackBar.h b/src/ui/SnackBar.h new file mode 100644
index 00000000..eed59c87 --- /dev/null +++ b/src/ui/SnackBar.h
@@ -0,0 +1,79 @@ +#pragma once + +#include <QCoreApplication> +#include <QPaintEvent> +#include <QTimer> +#include <deque> + +#include "OverlayWidget.h" + +enum class SnackBarPosition +{ + Bottom, + Top, +}; + +class SnackBar : public OverlayWidget +{ + Q_OBJECT + +public: + explicit SnackBar(QWidget *parent); + + inline void setBackgroundColor(const QColor &color); + inline void setTextColor(const QColor &color); + inline void setPosition(SnackBarPosition pos); + +public slots: + void showMessage(const QString &msg); + +protected: + void paintEvent(QPaintEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + +private slots: + void hideMessage(); + +private: + void stopTimers(); + void start(); + + QColor bgColor_; + QColor textColor_; + + qreal bgOpacity_; + qreal offset_; + + std::deque<QString> messages_; + + QTimer showTimer_; + QTimer hideTimer_; + + int duration_; + int boxWidth_; + int boxHeight_; + int boxPadding_; + + SnackBarPosition position_; +}; + +inline void +SnackBar::setPosition(SnackBarPosition pos) +{ + position_ = pos; + update(); +} + +inline void +SnackBar::setBackgroundColor(const QColor &color) +{ + bgColor_ = color; + update(); +} + +inline void +SnackBar::setTextColor(const QColor &color) +{ + textColor_ = color; + update(); +} diff --git a/src/ui/TextField.cc b/src/ui/TextField.cpp
index 0c936e69..0c936e69 100644 --- a/src/ui/TextField.cc +++ b/src/ui/TextField.cpp
diff --git a/src/ui/TextField.h b/src/ui/TextField.h new file mode 100644
index 00000000..1675a2e0 --- /dev/null +++ b/src/ui/TextField.h
@@ -0,0 +1,174 @@ +#pragma once + +#include <QColor> +#include <QLineEdit> +#include <QPaintEvent> +#include <QPropertyAnimation> +#include <QStateMachine> +#include <QtGlobal> + +class TextField; +class TextFieldLabel; +class TextFieldStateMachine; + +class TextField : public QLineEdit +{ + Q_OBJECT + + Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor) + Q_PROPERTY(QColor inkColor WRITE setInkColor READ inkColor) + Q_PROPERTY(QColor labelColor WRITE setLabelColor READ labelColor) + Q_PROPERTY(QColor underlineColor WRITE setUnderlineColor READ underlineColor) + Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) + +public: + explicit TextField(QWidget *parent = 0); + + void setInkColor(const QColor &color); + void setBackgroundColor(const QColor &color); + void setLabel(const QString &label); + void setLabelColor(const QColor &color); + void setLabelFontSize(qreal size); + void setShowLabel(bool value); + void setTextColor(const QColor &color); + void setUnderlineColor(const QColor &color); + + QColor inkColor() const; + QColor labelColor() const; + QColor textColor() const; + QColor underlineColor() const; + QColor backgroundColor() const; + QString label() const; + bool hasLabel() const; + qreal labelFontSize() const; + +protected: + bool event(QEvent *event) override; + void paintEvent(QPaintEvent *event) override; + +private: + void init(); + + QColor ink_color_; + QColor background_color_; + QColor label_color_; + QColor text_color_; + QColor underline_color_; + QString label_text_; + TextFieldLabel *label_; + TextFieldStateMachine *state_machine_; + bool show_label_; + qreal label_font_size_; +}; + +class TextFieldLabel : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(qreal scale WRITE setScale READ scale) + Q_PROPERTY(QPointF offset WRITE setOffset READ offset) + Q_PROPERTY(QColor color WRITE setColor READ color) + +public: + TextFieldLabel(TextField *parent); + + inline void setColor(const QColor &color); + inline void setOffset(const QPointF &pos); + inline void setScale(qreal scale); + + inline QColor color() const; + inline QPointF offset() const; + inline qreal scale() const; + +protected: + void paintEvent(QPaintEvent *event) override; + +private: + TextField *const text_field_; + + QColor color_; + qreal scale_; + qreal x_; + qreal y_; +}; + +inline void +TextFieldLabel::setColor(const QColor &color) +{ + color_ = color; + update(); +} + +inline void +TextFieldLabel::setOffset(const QPointF &pos) +{ + x_ = pos.x(); + y_ = pos.y(); + update(); +} + +inline void +TextFieldLabel::setScale(qreal scale) +{ + scale_ = scale; + update(); +} + +inline QPointF +TextFieldLabel::offset() const +{ + return QPointF(x_, y_); +} +inline qreal +TextFieldLabel::scale() const +{ + return scale_; +} +inline QColor +TextFieldLabel::color() const +{ + return color_; +} + +class TextFieldStateMachine : public QStateMachine +{ + Q_OBJECT + + Q_PROPERTY(qreal progress WRITE setProgress READ progress) + +public: + TextFieldStateMachine(TextField *parent); + + inline void setProgress(qreal progress); + void setLabel(TextFieldLabel *label); + + inline qreal progress() const; + +public slots: + void setupProperties(); + +private: + QPropertyAnimation *color_anim_; + QPropertyAnimation *offset_anim_; + + QState *focused_state_; + QState *normal_state_; + + TextField *text_field_; + TextFieldLabel *label_; + + qreal progress_; +}; + +inline void +TextFieldStateMachine::setProgress(qreal progress) +{ + progress_ = progress; + text_field_->update(); +} + +inline qreal +TextFieldStateMachine::progress() const +{ + return progress_; +} diff --git a/src/ui/Theme.cc b/src/ui/Theme.cpp
index 7209864a..7209864a 100644 --- a/src/ui/Theme.cc +++ b/src/ui/Theme.cpp
diff --git a/src/ui/Theme.h b/src/ui/Theme.h new file mode 100644
index 00000000..7a0bdcb7 --- /dev/null +++ b/src/ui/Theme.h
@@ -0,0 +1,97 @@ +#pragma once + +#include <QColor> +#include <QHash> +#include <QObject> + +namespace ui { +enum class AvatarType +{ + Icon, + Image, + Letter +}; + +namespace sidebar { +static const int SmallSize = 60; +static const int NormalSize = 260; +static const int CommunitiesSidebarSize = 48; +} +// Default font size. +const int FontSize = 16; + +// Default avatar size. Width and height. +const int AvatarSize = 40; + +enum class ButtonPreset +{ + FlatPreset, + CheckablePreset +}; + +enum class RippleStyle +{ + CenteredRipple, + PositionedRipple, + NoRipple +}; + +enum class OverlayStyle +{ + NoOverlay, + TintedOverlay, + GrayOverlay +}; + +enum class Role +{ + Default, + Primary, + Secondary +}; + +enum class ButtonIconPlacement +{ + LeftIcon, + RightIcon +}; + +enum class ProgressType +{ + DeterminateProgress, + IndeterminateProgress +}; + +enum class Color +{ + Black, + BrightWhite, + FadedWhite, + MediumWhite, + DarkGreen, + LightGreen, + BrightGreen, + Gray, + Red, + Blue, + Transparent +}; + +} // namespace ui + +class Theme : public QObject +{ + Q_OBJECT +public: + explicit Theme(QObject *parent = 0); + + QColor getColor(const QString &key) const; + + void setColor(const QString &key, const QColor &color); + void setColor(const QString &key, ui::Color color); + +private: + QColor rgba(int r, int g, int b, qreal a) const; + + QHash<QString, QColor> colors_; +}; diff --git a/src/ui/ThemeManager.cc b/src/ui/ThemeManager.cpp
index 7baed1f3..7baed1f3 100644 --- a/src/ui/ThemeManager.cc +++ b/src/ui/ThemeManager.cpp
diff --git a/src/ui/ThemeManager.h b/src/ui/ThemeManager.h new file mode 100644
index 00000000..d35ff754 --- /dev/null +++ b/src/ui/ThemeManager.h
@@ -0,0 +1,31 @@ +#pragma once + +#include <QCommonStyle> + +#include "Theme.h" + +class ThemeManager : public QCommonStyle +{ + Q_OBJECT + +public: + inline static ThemeManager &instance(); + + void setTheme(Theme *theme); + QColor themeColor(const QString &key) const; + +private: + ThemeManager(); + + ThemeManager(ThemeManager const &); + void operator=(ThemeManager const &); + + Theme *theme_; +}; + +inline ThemeManager & +ThemeManager::instance() +{ + static ThemeManager instance; + return instance; +} diff --git a/src/ui/ToggleButton.cc b/src/ui/ToggleButton.cpp
index 755f528f..755f528f 100644 --- a/src/ui/ToggleButton.cc +++ b/src/ui/ToggleButton.cpp
diff --git a/src/ui/ToggleButton.h b/src/ui/ToggleButton.h new file mode 100644
index 00000000..14c3450b --- /dev/null +++ b/src/ui/ToggleButton.h
@@ -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_; +};