From f4863cbccb726942e06b9f4803747f2fe01c20b9 Mon Sep 17 00:00:00 2001 From: fourtf Date: Wed, 24 Jan 2018 20:27:56 +0100 Subject: [PATCH] added buttons to the custom window frame --- chatterino.pro | 6 +- src/widgets/basewindow.cpp | 72 +++++++++------ src/widgets/basewindow.hpp | 14 +-- src/widgets/helper/titlebarbutton.cpp | 127 ++++++++++++++++++++++++++ src/widgets/helper/titlebarbutton.hpp | 25 +++++ src/widgets/window.cpp | 7 +- 6 files changed, 210 insertions(+), 41 deletions(-) create mode 100644 src/widgets/helper/titlebarbutton.cpp create mode 100644 src/widgets/helper/titlebarbutton.hpp diff --git a/chatterino.pro b/chatterino.pro index 59c60c58a..bd0109acc 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -167,7 +167,8 @@ SOURCES += \ src/widgets/settingspages/ignoreuserspage.cpp \ src/widgets/settingspages/ignoremessagespage.cpp \ src/widgets/settingspages/specialchannelspage.cpp \ - src/widgets/settingspages/keyboardsettingspage.cpp + src/widgets/settingspages/keyboardsettingspage.cpp \ + src/widgets/helper/titlebarbutton.cpp HEADERS += \ src/precompiled_header.hpp \ @@ -275,7 +276,8 @@ HEADERS += \ src/widgets/settingspages/ignoremessagespage.hpp \ src/widgets/settingspages/specialchannelspage.hpp \ src/widgets/settingspages/keyboardsettings.hpp \ - src/widgets/settingspages/keyboardsettingspage.hpp + src/widgets/settingspages/keyboardsettingspage.hpp \ + src/widgets/helper/titlebarbutton.hpp RESOURCES += \ resources/resources.qrc diff --git a/src/widgets/basewindow.cpp b/src/widgets/basewindow.cpp index d6ec127c4..8417c5cb8 100644 --- a/src/widgets/basewindow.cpp +++ b/src/widgets/basewindow.cpp @@ -23,7 +23,7 @@ #define WM_DPICHANGED 0x02E0 #endif -#include "widgets/helper/rippleeffectlabel.hpp" +#include "widgets/helper/titlebarbutton.hpp" namespace chatterino { namespace widgets { @@ -72,38 +72,39 @@ void BaseWindow::init() this->titleLabel = title; // buttons - RippleEffectLabel *min = new RippleEffectLabel; - min->getLabel().setText("min"); - min->setFixedSize(46, 30); - RippleEffectLabel *max = new RippleEffectLabel; - max->setFixedSize(46, 30); - max->getLabel().setText("max"); - RippleEffectLabel *exit = new RippleEffectLabel; - exit->setFixedSize(46, 30); - exit->getLabel().setText("exit"); + TitleBarButton *_minButton = new TitleBarButton; + _minButton->setFixedSize(46, 30); + _minButton->setButtonStyle(TitleBarButton::Minimize); + TitleBarButton *_maxButton = new TitleBarButton; + _maxButton->setFixedSize(46, 30); + _maxButton->setButtonStyle(TitleBarButton::Maximize); + TitleBarButton *_exitButton = new TitleBarButton; + _exitButton->setFixedSize(46, 30); + _exitButton->setButtonStyle(TitleBarButton::Close); - QObject::connect(min, &RippleEffectLabel::clicked, this, [this] { + QObject::connect(_minButton, &TitleBarButton::clicked, this, [this] { this->setWindowState(Qt::WindowMinimized | this->windowState()); }); - QObject::connect(max, &RippleEffectLabel::clicked, this, [this] { + QObject::connect(_maxButton, &TitleBarButton::clicked, this, [this] { this->setWindowState(this->windowState() == Qt::WindowMaximized ? Qt::WindowActive : Qt::WindowMaximized); }); - QObject::connect(exit, &RippleEffectLabel::clicked, this, [this] { this->close(); }); + QObject::connect(_exitButton, &TitleBarButton::clicked, this, + [this] { this->close(); }); - this->minButton = min; - this->maxButton = max; - this->exitButton = exit; + this->minButton = _minButton; + this->maxButton = _maxButton; + this->exitButton = _exitButton; - this->buttons.push_back(min); - this->buttons.push_back(max); - this->buttons.push_back(exit); + this->buttons.push_back(_minButton); + this->buttons.push_back(_maxButton); + this->buttons.push_back(_exitButton); buttonLayout->addStretch(1); - buttonLayout->addWidget(min); - buttonLayout->addWidget(max); - buttonLayout->addWidget(exit); + buttonLayout->addWidget(_minButton); + buttonLayout->addWidget(_maxButton); + buttonLayout->addWidget(_exitButton); buttonLayout->setSpacing(0); } this->layoutBase = new QWidget(this); @@ -161,23 +162,34 @@ void BaseWindow::refreshTheme() palette.setColor(QPalette::Foreground, this->themeManager.windowText); this->setPalette(palette); - for (RippleEffectLabel *label : this->buttons) { - label->setMouseEffectColor(this->themeManager.windowText); + for (RippleEffectButton *button : this->buttons) { + button->setMouseEffectColor(this->themeManager.windowText); } } -void BaseWindow::addTitleBarButton(const QString &text, std::function onClicked) +void BaseWindow::addTitleBarButton(const TitleBarButton::Style &style, + std::function onClicked) { - RippleEffectLabel *label = new RippleEffectLabel; - label->getLabel().setText(text); - this->buttons.push_back(label); - this->titlebarBox->insertWidget(2, label); - QObject::connect(label, &RippleEffectLabel::clicked, this, [onClicked] { onClicked(); }); + TitleBarButton *button = new TitleBarButton; + + this->buttons.push_back(button); + this->titlebarBox->insertWidget(2, button); + button->setButtonStyle(style); + + QObject::connect(button, &TitleBarButton::clicked, this, [onClicked] { onClicked(); }); } void BaseWindow::changeEvent(QEvent *) { TooltipWidget::getInstance()->hide(); + +#ifdef USEWINSDK + if (this->hasCustomWindowFrame()) { + this->maxButton->setButtonStyle(this->windowState() & Qt::WindowMaximized + ? TitleBarButton::Unmaximize + : TitleBarButton::Maximize); + } +#endif } void BaseWindow::leaveEvent(QEvent *) diff --git a/src/widgets/basewindow.hpp b/src/widgets/basewindow.hpp index 16e2f2a2a..2ec8e196f 100644 --- a/src/widgets/basewindow.hpp +++ b/src/widgets/basewindow.hpp @@ -1,6 +1,7 @@ #pragma once #include "basewidget.hpp" +#include "widgets/helper/titlebarbutton.hpp" #include @@ -8,7 +9,8 @@ class QHBoxLayout; namespace chatterino { namespace widgets { -class RippleEffectLabel; +class RippleEffectButton; +class TitleBarButton; class BaseWindow : public BaseWidget { @@ -20,7 +22,7 @@ public: QWidget *getLayoutContainer(); bool hasCustomWindowFrame(); - void addTitleBarButton(const QString &text, std::function onClicked); + void addTitleBarButton(const TitleBarButton::Style &style, std::function onClicked); void setStayInScreenRect(bool value); bool getStayInScreenRect() const; @@ -50,11 +52,11 @@ private: QHBoxLayout *titlebarBox; QWidget *titleLabel; - RippleEffectLabel *minButton; - RippleEffectLabel *maxButton; - RippleEffectLabel *exitButton; + TitleBarButton *minButton; + TitleBarButton *maxButton; + TitleBarButton *exitButton; QWidget *layoutBase; - std::vector buttons; + std::vector buttons; }; } // namespace widgets } // namespace chatterino diff --git a/src/widgets/helper/titlebarbutton.cpp b/src/widgets/helper/titlebarbutton.cpp new file mode 100644 index 000000000..df5326847 --- /dev/null +++ b/src/widgets/helper/titlebarbutton.cpp @@ -0,0 +1,127 @@ +#include "titlebarbutton.hpp" + +namespace chatterino { +namespace widgets { +TitleBarButton::TitleBarButton() + : RippleEffectButton(nullptr) +{ +} + +TitleBarButton::Style TitleBarButton::getButtonStyle() const +{ + return this->style; +} + +void TitleBarButton::setButtonStyle(Style _style) +{ + this->style = _style; + this->update(); +} + +void TitleBarButton::resizeEvent(QResizeEvent *) +{ + if (this->style & (Maximize | Minimize | Unmaximize | Close)) { + this->setFixedWidth(this->height() * 46 / 30); + } else { + this->setFixedWidth(this->height()); + } +} + +void TitleBarButton::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + + QColor color = "#000"; + QColor background = "#fff"; + + int xD = this->height() / 3; + int centerX = this->width() / 2; + + painter.setRenderHint(QPainter::Antialiasing, false); + + switch (this->style) { + case Minimize: { + painter.fillRect(centerX - xD / 2, xD * 3 / 2, xD, 1, color); + break; + } + case Maximize: { + painter.setPen(color); + painter.drawRect(centerX - xD / 2, xD, xD - 1, xD - 1); + break; + } + case Unmaximize: { + int xD2 = xD * 1 / 5; + int xD3 = xD * 4 / 5; + + painter.drawRect(centerX - xD / 2 + xD2, xD, xD3, xD3); + painter.fillRect(centerX - xD / 2, xD + xD2, xD3, xD3, QColor("#fff")); + painter.drawRect(centerX - xD / 2, xD + xD2, xD3, xD3); + break; + } + case Close: { + QRect rect(centerX - xD / 2, xD, xD - 1, xD - 1); + painter.setPen(QPen(color, 1)); + + painter.drawLine(rect.topLeft(), rect.bottomRight()); + painter.drawLine(rect.topRight(), rect.bottomLeft()); + break; + } + case User: { + color = QColor("#333"); + + painter.setRenderHint(QPainter::Antialiasing); + painter.setRenderHint(QPainter::HighQualityAntialiasing); + + auto a = xD / 3; + QPainterPath path; + + painter.save(); + painter.translate(3, 3); + + path.arcMoveTo(a, 4 * a, 6 * a, 6 * a, 0); + path.arcTo(a, 4 * a, 6 * a, 6 * a, 0, 180); + + painter.fillPath(path, color); + + painter.setBrush(background); + painter.drawEllipse(2 * a, 1 * a, 4 * a, 4 * a); + + painter.setBrush(color); + painter.drawEllipse(2.5 * a, 1.5 * a, 3 * a + 1, 3 * a); + painter.restore(); + + break; + } + case Settings: { + color = QColor("#333"); + painter.setRenderHint(QPainter::Antialiasing); + painter.setRenderHint(QPainter::HighQualityAntialiasing); + + painter.save(); + painter.translate(3, 3); + + auto a = xD / 3; + QPainterPath path; + + path.arcMoveTo(a, a, 6 * a, 6 * a, 0 - (360 / 32.0)); + + for (int i = 0; i < 8; i++) { + path.arcTo(a, a, 6 * a, 6 * a, i * (360 / 8.0) - (360 / 32.0), (360 / 32.0)); + path.arcTo(2 * a, 2 * a, 4 * a, 4 * a, i * (360 / 8.0) + (360 / 32.0), + (360 / 32.0)); + } + + painter.strokePath(path, color); + painter.fillPath(path, color); + + painter.setBrush(background); + painter.drawEllipse(3 * a, 3 * a, 2 * a, 2 * a); + painter.restore(); + break; + } + } + + this->fancyPaint(painter); +} +} // namespace widgets +} // namespace chatterino diff --git a/src/widgets/helper/titlebarbutton.hpp b/src/widgets/helper/titlebarbutton.hpp new file mode 100644 index 000000000..83ce40713 --- /dev/null +++ b/src/widgets/helper/titlebarbutton.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include "widgets/helper/rippleeffectbutton.hpp" + +namespace chatterino { +namespace widgets { +class TitleBarButton : public RippleEffectButton +{ +public: + enum Style { Minimize = 1, Maximize = 2, Unmaximize = 4, Close = 8, User = 16, Settings = 32 }; + + TitleBarButton(); + + Style getButtonStyle() const; + void setButtonStyle(Style style); + +protected: + virtual void paintEvent(QPaintEvent *) override; + virtual void resizeEvent(QResizeEvent *) override; + +private: + Style style; +}; +} // namespace widgets +} // namespace chatterino diff --git a/src/widgets/window.cpp b/src/widgets/window.cpp index 8c27e3d46..c7ecdb039 100644 --- a/src/widgets/window.cpp +++ b/src/widgets/window.cpp @@ -37,9 +37,10 @@ Window::Window(const QString &windowName, singletons::ThemeManager &_themeManage }); if (this->hasCustomWindowFrame()) { - this->addTitleBarButton( - "preferences", [] { singletons::WindowManager::getInstance().showSettingsDialog(); }); - this->addTitleBarButton("user", [this] { + this->addTitleBarButton(TitleBarButton::Settings, [] { + singletons::WindowManager::getInstance().showSettingsDialog(); + }); + this->addTitleBarButton(TitleBarButton::User, [this] { singletons::WindowManager::getInstance().showAccountSelectPopup(QCursor::pos()); }); }