From 1d7ce510f7cbd4a279e6340d038b37cd5e2dbc63 Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Fri, 14 Jul 2023 19:25:17 +0200 Subject: [PATCH] Add SwitchButton Simple switch toogle button widget based on https://github.com/KDAB/kdabtv/blob/master/Styling-Qt-Widgets/toggleswitch.h --- CMakeLists.txt | 2 + src/utils/switch-button.cpp | 102 ++++++++++++++++++++++++++++++++++++ src/utils/switch-button.hpp | 37 +++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 src/utils/switch-button.cpp create mode 100644 src/utils/switch-button.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d230339d..058d1e36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -302,6 +302,8 @@ target_sources( src/utils/string-list.hpp src/utils/striped-frame.cpp src/utils/striped-frame.hpp + src/utils/switch-button.cpp + src/utils/switch-button.hpp src/utils/sync-helper.cpp src/utils/sync-helper.hpp src/utils/transition-selection.cpp diff --git a/src/utils/switch-button.cpp b/src/utils/switch-button.cpp new file mode 100644 index 00000000..dd1bfd50 --- /dev/null +++ b/src/utils/switch-button.cpp @@ -0,0 +1,102 @@ +#include "switch-button.hpp" + +#include +#include +#include + +namespace advss { + +static const int s_height = 20; +static const int s_innerMargin = 4; +static const int s_handleSize = s_height - s_innerMargin * 2; +static const int s_width = s_handleSize * 2 + s_innerMargin * 2; + +SwitchButton::SwitchButton(QWidget *parent) : QWidget{parent} +{ + setSizePolicy({QSizePolicy::Fixed, QSizePolicy::Fixed}); + setFocusPolicy(Qt::TabFocus); + setAttribute(Qt::WA_Hover); +} + +void SwitchButton::setChecked(bool checked) +{ + if (_checked == checked) { + return; + } + _checked = checked; + emit toggled(checked); + update(); +} + +bool SwitchButton::isChecked() const +{ + return _checked; +} + +void SwitchButton::toggle() +{ + setChecked(!_checked); +} + +QSize SwitchButton::sizeHint() const +{ + return QSize(s_width, s_height); +} + +void SwitchButton::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + QPalette pal = palette(); + + if (!isEnabled()) { + painter.setPen(pal.color(QPalette::Midlight)); + painter.setOpacity(0.5); + } else if (_mouseDown) { + painter.setPen(pal.color(QPalette::Light)); + } else if (underMouse() || hasFocus()) { + painter.setPen(QPen(pal.brush(QPalette::Highlight), 1)); + } else { + painter.setPen(pal.color(QPalette::Midlight)); + } + + if (_checked) { + painter.setBrush(pal.color(QPalette::Button)); + } + const qreal radius = height() / 2; + painter.drawRoundedRect(QRectF(rect()).adjusted(0.5, 0.5, -0.5, -0.5), + radius, radius); + + // Now draw the handle + QRect valueRect = rect().adjusted(s_innerMargin, s_innerMargin, + -s_innerMargin, -s_innerMargin); + valueRect.setWidth(valueRect.height()); + + if (_checked) { + valueRect.moveLeft(width() / 2); + } + painter.setBrush(pal.color(QPalette::Base)); + painter.drawEllipse(valueRect); +} + +void SwitchButton::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + _mouseDown = true; + } else { + event->ignore(); + } +} + +void SwitchButton::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton && _mouseDown) { + _mouseDown = false; + toggle(); + emit checked(_checked); + } else { + event->ignore(); + } +} + +} // namespace advss diff --git a/src/utils/switch-button.hpp b/src/utils/switch-button.hpp new file mode 100644 index 00000000..9e1e7400 --- /dev/null +++ b/src/utils/switch-button.hpp @@ -0,0 +1,37 @@ +#pragma once +#include + +namespace advss { + +/* +Simple switch toogle button widget +Based on https://github.com/KDAB/kdabtv/blob/master/Styling-Qt-Widgets/toggleswitch.h +*/ +class SwitchButton : public QWidget { + Q_OBJECT + +public: + explicit SwitchButton(QWidget *parent = nullptr); + + void setChecked(bool checked); + bool isChecked() const; + + void toggle(); + + QSize sizeHint() const override; + +signals: + void checked(bool checked); // by user + void toggled(bool checked); // by user or by program + +protected: + void paintEvent(QPaintEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + +private: + bool _checked = false; + bool _mouseDown = false; +}; + +} // namespace advss