From 463a1f194511940453f24b851df993793fa86cab Mon Sep 17 00:00:00 2001 From: fourtf Date: Tue, 8 May 2018 15:12:04 +0200 Subject: [PATCH] added new overlay for splits when you hold alt that does nothing yet --- chatterino.pro | 6 +- resources/images/split/splitdown.png | Bin 0 -> 793 bytes resources/images/split/splitleft.png | Bin 0 -> 812 bytes resources/images/split/splitmove.png | Bin 0 -> 1241 bytes resources/images/split/splitright.png | Bin 0 -> 811 bytes resources/images/split/splitup.png | Bin 0 -> 793 bytes resources/resources.qrc | 5 + src/singletons/resourcemanager.cpp | 6 + src/singletons/resourcemanager.hpp | 8 ++ src/widgets/basewidget.cpp | 2 +- src/widgets/helper/splitoverlay.cpp | 152 ++++++++++++++++++++++++++ src/widgets/helper/splitoverlay.hpp | 40 +++++++ src/widgets/split.cpp | 48 +++++++- src/widgets/split.hpp | 13 ++- src/widgets/window.cpp | 6 +- 15 files changed, 274 insertions(+), 12 deletions(-) create mode 100644 resources/images/split/splitdown.png create mode 100644 resources/images/split/splitleft.png create mode 100644 resources/images/split/splitmove.png create mode 100644 resources/images/split/splitright.png create mode 100644 resources/images/split/splitup.png create mode 100644 src/widgets/helper/splitoverlay.cpp create mode 100644 src/widgets/helper/splitoverlay.hpp diff --git a/chatterino.pro b/chatterino.pro index bf3578cb0..6800fb8a2 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -194,7 +194,8 @@ SOURCES += \ src/widgets/helper/editablemodelview.cpp \ src/controllers/accounts/accountcontroller.cpp \ src/controllers/accounts/accountmodel.cpp \ - src/controllers/accounts/account.cpp + src/controllers/accounts/account.cpp \ + src/widgets/helper/splitoverlay.cpp HEADERS += \ src/precompiled_header.hpp \ @@ -336,7 +337,8 @@ HEADERS += \ src/controllers/accounts/accountcontroller.hpp \ src/controllers/accounts/accountmodel.hpp \ src/controllers/accounts/account.hpp \ - src/util/sharedptrelementless.hpp + src/util/sharedptrelementless.hpp \ + src/widgets/helper/splitoverlay.hpp RESOURCES += \ resources/resources.qrc diff --git a/resources/images/split/splitdown.png b/resources/images/split/splitdown.png new file mode 100644 index 0000000000000000000000000000000000000000..3891ca3987cf9dcf52055670823088c1dd67bff8 GIT binary patch literal 793 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoEa{HEjtmSN`?>!lvI6;>1s;*b z3=DjSK$uZf!>a)(C|TkfQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QBXJq(MA#*AN1Jg85 z7srr_xVKXsv!nw=j?{dPTlC#`w*<>iO&-0^Z&_3>9E<|3hTet0t7f|`urQtx?HM)BzNy;STzMKkFlkL4eg^fKTx=Iyj=B-QGGY>Le zn-&K&YQrGaa-M&|`N}UoK;PV!vz;s{^I)6%d7uw=yuD~Vb0PnNV35#JHRB(`C75Ah zaUd5IOy~Iv>ekQ45ek3qFxI_@1qZ+#Z~&bqmGj{*o5lU;-|Nk%Px}rI=t_NXs3JJ_ z54S#D2M+dk;AkP4^J6D-O*oF2BQk)%Dd>k$!yYkM@>*L{^M^4_>i(Oi9rl-j$(X^@ L)z4*}Q$iB}{<&M) literal 0 HcmV?d00001 diff --git a/resources/images/split/splitleft.png b/resources/images/split/splitleft.png new file mode 100644 index 0000000000000000000000000000000000000000..8d1cb0e199051fc8a141e4358dd9f4b83ce8edc5 GIT binary patch literal 812 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoEa{HEjtmSN`?>!lvI6;>1s;*b z3=DjSK$uZf!>a)(C|TkfQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QBXJq(MA#*AN1Jg=R z7srr_xVKXsvy=lxj?{eKdE}1y-u%a@PpP^u x**5HpK}tu>jC`lhJalHT?1rYe=*sHf>@I2d-_)ibodrzU44$rjF6*2UngBT^H=zIk literal 0 HcmV?d00001 diff --git a/resources/images/split/splitmove.png b/resources/images/split/splitmove.png new file mode 100644 index 0000000000000000000000000000000000000000..82bf5382bfb0030eea42e2b9e432e87db63d1252 GIT binary patch literal 1241 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoEa{HEjtmSN`?>!lvI6;>1s;*b z3=Dh+L6~vJ#O${~LCF%=h?3y^w370~qEv>0#LT=By}Z;C1rt33JtM=93Yk-Z28DUL zIEGZjy}e`DC*mp4`p}a3(2)mh9ug519Ngl3TgCk5Gce0{8$VEDInKbmfBU3gpMB5! z?0>l`r>o=I5%ty!c1g46O`pnhSTAO3keBA&eK}pTY`>jyTX8daeNGFE>ECf$Axk8w z-&Rqtc|~A{?YEX4Jd4~EzugdiWYi(mdL!AtqxjZadH>Ik&u{k(Tr5!ihO^MF_~-rQ zH~l}WzE%u?itPTYed_(^uJ@j;P(3?;e);ZM$qg~mV)}0X`uQc>8z7ROE&c%|%VCoI z|AD+x7_a^J{C{>U^B7IJHXffR@VwyH%lDI?i9zkzlL|D)1ZK`--TGg@m+WA@qH#p7 z+DRt+?&bUHM|BrKTp#foXwE~p(jMEtwTJSdrXH6BYHYd31o3#E@%@G}j_uFinzXxa zueaM4Zk`}qytAEs!Yl0ueNY$Qd>enys$qJKzZS%@IsUQ^8>|`uuldYXl%R?78#t5&!di(XCe*@6_G3b7pt!b$YW={mAmUdi%~V zm2;RM3KO~a>Cx|)UyNTOOQ2e7uK#-Ud(X^ewG*EERnM*exNG^dd(F^bnO*i<{Lg{o z_bxcky>^^iN(d4J`?lS-f68wCO-=4s&Fp8KzJH;XU4O;!Zua`iIW-Kve?>~F>-;}w z&U$X50&!tYc&$)ga`$^k9N(y(v7g5_vc?_iOkMj9Z@Y%0N6TT}dD*<<2y;X%Ou=he zpn{)gcg)}Otl*<8B)0o!+b{UP?5D-q>`R|>OBv4o*>77nSt)vSiv{MBj0XW?eY(c8>l{Xv1&7984Rl}J}rv%CES-tu{;yHnfhGl0bq NgQu&X%Q~loCIFysR_y=) literal 0 HcmV?d00001 diff --git a/resources/images/split/splitright.png b/resources/images/split/splitright.png new file mode 100644 index 0000000000000000000000000000000000000000..173537331602ebd35222e3c96ab9c596e2246bdc GIT binary patch literal 811 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoEa{HEjtmSN`?>!lvI6;>1s;*b z3=DjSK$uZf!>a)(C|TkfQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QBXJq(MA#*AN1Jepm z7srr_xVKXsvyuY^m}@`BD19&8Be1A*qtAoY@lLB8x=*%0UzTOK-CCxVphNqsJ6%Tw`a`Oqp{Qmm?&;D+;mIn#<@-DxW!?9uG!;o3L zjAmwYyf*)gZ20;1NZj4euih^gdp8lN=GY-ypqdL2JKTY4q`1F(Y*utgekhk|#*(3P zM;T~AZ)^3En*s|q7WA7)Gnvp$(;3}8Alr+%-veEA;Lagypeqfwf9L}`f=H>K@{IfH z_gB5I%dY_ihW592-;bFC{k0!lvI6;>1s;*b z3=DjSK$uZf!>a)(C|TkfQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QBXJq(MA#*AN1Jg85 z7srr_xVKXsv!nw=j?{dPTlC#`w*<>iO&-0^Z&_3>9E<|3hTet0t7f|`urQtx?HM)BzNy;STzMOjILoxf0h2^S1<8Bo}q)6o){x1EX zCjagJdofY>yg^nx-J8P39ubY;{BOBFZ8zA$o!T=GGF~H@^YA&}hggK0A24KluLs*v zr3&<2gWdCs#z1rPs=xRE?Y}K&J6TfZ!8Z5vDQ$KQe$YUA;C~^PtN=o>3>Zq6AYOimages/about.svg images/moderatormode_disabled.png images/moderatormode_enabled.png + images/split/splitdown.png + images/split/splitleft.png + images/split/splitright.png + images/split/splitup.png + images/split/splitmove.png qt.conf diff --git a/src/singletons/resourcemanager.cpp b/src/singletons/resourcemanager.cpp index 274b8ee86..b989261c7 100644 --- a/src/singletons/resourcemanager.cpp +++ b/src/singletons/resourcemanager.cpp @@ -1,6 +1,7 @@ #include "resourcemanager.hpp" #include "util/urlfetch.hpp" +#include #include namespace chatterino { @@ -288,6 +289,11 @@ ResourceManager::ResourceManager() , buttonBan(lli(":/images/button_ban.png", 0.25)) , buttonTimeout(lli(":/images/button_timeout.png", 0.25)) { + this->split.left = QIcon(":/images/split/splitleft.png"); + this->split.right = QIcon(":/images/split/splitright.png"); + this->split.up = QIcon(":/images/split/splitup.png"); + this->split.down = QIcon(":/images/split/splitdown.png"); + this->split.move = QIcon(":/images/split/splitmove.png"); qDebug() << "init ResourceManager"; } diff --git a/src/singletons/resourcemanager.hpp b/src/singletons/resourcemanager.hpp index 17bb7f18a..2da506583 100644 --- a/src/singletons/resourcemanager.hpp +++ b/src/singletons/resourcemanager.hpp @@ -20,6 +20,14 @@ public: void initialize(); + struct { + QIcon left; + QIcon right; + QIcon up; + QIcon down; + QIcon move; + } split; + messages::Image *badgeStaff; messages::Image *badgeAdmin; messages::Image *badgeGlobalModerator; diff --git a/src/widgets/basewidget.cpp b/src/widgets/basewidget.cpp index 74b548286..4dcc1a6d3 100644 --- a/src/widgets/basewidget.cpp +++ b/src/widgets/basewidget.cpp @@ -111,7 +111,7 @@ void BaseWidget::childEvent(QChildEvent *event) void BaseWidget::showEvent(QShowEvent *) { - this->scaleChangedEvent(this->getScale()); + this->setScale(this->getScale()); this->themeRefreshEvent(); } diff --git a/src/widgets/helper/splitoverlay.cpp b/src/widgets/helper/splitoverlay.cpp new file mode 100644 index 000000000..45758b3af --- /dev/null +++ b/src/widgets/helper/splitoverlay.cpp @@ -0,0 +1,152 @@ +#include "splitoverlay.hpp" + +#include +#include +#include +#include +#include + +#include "application.hpp" +#include "singletons/resourcemanager.hpp" +#include "widgets/split.hpp" + +namespace chatterino { +namespace widgets { + +SplitOverlay::SplitOverlay(Split *parent) + : BaseWidget(parent) + , split(parent) +{ + QGridLayout *layout = new QGridLayout(this); + layout->setMargin(1); + layout->setSpacing(1); + + layout->setRowStretch(1, 1); + layout->setRowStretch(3, 1); + layout->setColumnStretch(1, 1); + layout->setColumnStretch(3, 1); + + QPushButton *move = new QPushButton(getApp()->resources->split.move, QString()); + QPushButton *left = new QPushButton(getApp()->resources->split.left, QString()); + QPushButton *right = new QPushButton(getApp()->resources->split.right, QString()); + QPushButton *up = new QPushButton(getApp()->resources->split.up, QString()); + QPushButton *down = new QPushButton(getApp()->resources->split.down, QString()); + + move->setGraphicsEffect(new QGraphicsOpacityEffect(this)); + left->setGraphicsEffect(new QGraphicsOpacityEffect(this)); + right->setGraphicsEffect(new QGraphicsOpacityEffect(this)); + up->setGraphicsEffect(new QGraphicsOpacityEffect(this)); + down->setGraphicsEffect(new QGraphicsOpacityEffect(this)); + + move->setFlat(true); + left->setFlat(true); + right->setFlat(true); + up->setFlat(true); + down->setFlat(true); + + layout->addWidget(move, 2, 2); + layout->addWidget(left, 2, 0); + layout->addWidget(right, 2, 4); + layout->addWidget(up, 0, 2); + layout->addWidget(down, 4, 2); + + move->installEventFilter(new ButtonEventFilter(this, SplitMove)); + left->installEventFilter(new ButtonEventFilter(this, SplitLeft)); + right->installEventFilter(new ButtonEventFilter(this, SplitRight)); + up->installEventFilter(new ButtonEventFilter(this, SplitUp)); + down->installEventFilter(new ButtonEventFilter(this, SplitDown)); + + move->setFocusPolicy(Qt::NoFocus); + left->setFocusPolicy(Qt::NoFocus); + right->setFocusPolicy(Qt::NoFocus); + up->setFocusPolicy(Qt::NoFocus); + down->setFocusPolicy(Qt::NoFocus); + + move->setCursor(Qt::SizeAllCursor); + + this->managedConnect(this->scaleChanged, [=](float scale) { + int a = scale * 40; + QSize size(a, a); + + move->setIconSize(size); + left->setIconSize(size); + right->setIconSize(size); + up->setIconSize(size); + down->setIconSize(size); + }); +} + +void SplitOverlay::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + painter.fillRect(this->rect(), QColor(0, 0, 0, 90)); + + QRect rect; + switch (this->hoveredElement) { + case SplitLeft: { + rect = QRect(0, 0, this->width() / 2, this->height()); + } break; + case SplitRight: { + rect = QRect(this->width() / 2, 0, this->width() / 2, this->height()); + } break; + case SplitUp: { + rect = QRect(0, 0, this->width(), this->height() / 2); + } break; + case SplitDown: { + rect = QRect(0, this->height() / 2, this->width(), this->height() / 2); + } break; + } + if (!rect.isNull()) { + painter.setPen(QColor(0, 148, 255, 0x70)); + painter.setBrush(QColor(0, 148, 255, 0x30)); + painter.drawRect(rect); + } +} + +SplitOverlay::ButtonEventFilter::ButtonEventFilter(SplitOverlay *_parent, HoveredElement _element) + : QObject(_parent) + , parent(_parent) + , hoveredElement(_element) +{ +} + +bool SplitOverlay::ButtonEventFilter::eventFilter(QObject *watched, QEvent *event) +{ + switch (event->type()) { + case QEvent::Enter: { + QGraphicsOpacityEffect *effect = + dynamic_cast(((QWidget *)watched)->graphicsEffect()); + + if (effect != nullptr) { + effect->setOpacity(1); + } + + this->parent->hoveredElement = this->hoveredElement; + this->parent->update(); + } break; + case QEvent::Leave: { + QGraphicsOpacityEffect *effect = + dynamic_cast(((QWidget *)watched)->graphicsEffect()); + + if (effect != nullptr) { + effect->setOpacity(0.7); + } + + this->parent->hoveredElement = HoveredElement::None; + this->parent->update(); + } break; + case QEvent::MouseButtonPress: { + if (this->hoveredElement == HoveredElement::SplitMove) { + QMouseEvent *mouseEvent = static_cast(event); + if (mouseEvent->button() == Qt::LeftButton) { + this->parent->split->drag(); + } + return true; + } + } break; + } + return QObject::eventFilter(watched, event); +} + +} // namespace widgets +} // namespace chatterino diff --git a/src/widgets/helper/splitoverlay.hpp b/src/widgets/helper/splitoverlay.hpp new file mode 100644 index 000000000..31b7a4b42 --- /dev/null +++ b/src/widgets/helper/splitoverlay.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "pajlada/signals/signalholder.hpp" +#include "widgets/basewidget.hpp" + +namespace chatterino { +namespace widgets { + +class Split; + +class SplitOverlay : public BaseWidget, pajlada::Signals::SignalHolder +{ +public: + explicit SplitOverlay(Split *parent = nullptr); + +protected: + void paintEvent(QPaintEvent *event) override; + +private: + enum HoveredElement { None, SplitMove, SplitLeft, SplitRight, SplitUp, SplitDown }; + HoveredElement hoveredElement = None; + Split *split; + + class ButtonEventFilter : public QObject + { + HoveredElement hoveredElement; + SplitOverlay *parent; + + public: + ButtonEventFilter(SplitOverlay *parent, HoveredElement hoveredElement); + + protected: + bool eventFilter(QObject *watched, QEvent *event) override; + }; + + friend class ButtonEventFilter; +}; + +} // namespace widgets +} // namespace chatterino diff --git a/src/widgets/split.cpp b/src/widgets/split.cpp index d4408191a..c186188c5 100644 --- a/src/widgets/split.cpp +++ b/src/widgets/split.cpp @@ -13,6 +13,7 @@ #include "widgets/helper/debugpopup.hpp" #include "widgets/helper/searchpopup.hpp" #include "widgets/helper/shortcut.hpp" +#include "widgets/helper/splitoverlay.hpp" #include "widgets/qualitypopup.hpp" #include "widgets/selectchanneldialog.hpp" #include "widgets/splitcontainer.hpp" @@ -38,6 +39,9 @@ using namespace chatterino::messages; namespace chatterino { namespace widgets { +pajlada::Signals::Signal Split::altPressedStatusChanged; +bool Split::altPressesStatus = false; + Split::Split(SplitContainer *parent) : Split((QWidget *)parent) { @@ -52,6 +56,7 @@ Split::Split(QWidget *parent) , header(this) , view(this) , input(this) + , overlay(new SplitOverlay(this)) { auto app = getApp(); @@ -119,8 +124,17 @@ Split::Split(QWidget *parent) this->managedConnections); this->header.updateModerationModeIcon(); + this->overlay->hide(); this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + + this->managedConnect(altPressedStatusChanged, [this](bool status) { + if (status && this->isMouseOver) { + this->overlay->show(); + } else { + this->overlay->hide(); + } + }); } Split::~Split() @@ -287,15 +301,39 @@ void Split::keyReleaseEvent(QKeyEvent *event) this->handleModifiers(event, event->modifiers()); } +void Split::resizeEvent(QResizeEvent *event) +{ + BaseWidget::resizeEvent(event); + + this->overlay->setGeometry(this->rect()); +} + +void Split::enterEvent(QEvent *event) +{ + this->isMouseOver = true; + if (altPressesStatus) { + this->overlay->show(); + } +} + +void Split::leaveEvent(QEvent *event) +{ + this->isMouseOver = false; + this->overlay->hide(); +} + void Split::handleModifiers(QEvent *event, Qt::KeyboardModifiers modifiers) { if (modifiers == Qt::AltModifier) { - this->setCursor(Qt::SizeAllCursor); - event->accept(); - // } else if (modifiers == Qt::ControlModifier) { - // this->setCursor(Qt::SplitHCursor); - // event->accept(); + if (!altPressesStatus) { + altPressesStatus = true; + altPressedStatusChanged.invoke(true); + } } else { + if (altPressesStatus) { + altPressesStatus = false; + altPressedStatusChanged.invoke(false); + } this->setCursor(Qt::ArrowCursor); } } diff --git a/src/widgets/split.hpp b/src/widgets/split.hpp index dd6cbf56d..e184cefc9 100644 --- a/src/widgets/split.hpp +++ b/src/widgets/split.hpp @@ -21,6 +21,7 @@ namespace chatterino { namespace widgets { class SplitContainer; +class SplitOverlay; // Each ChatWidget consists of three sub-elements that handle their own part of the chat widget: // ChatWidgetHeader @@ -32,12 +33,15 @@ class SplitContainer; // - Responsible for rendering and handling user text input // // Each sub-element has a reference to the parent Chat Widget -class Split : public BaseWidget +class Split : public BaseWidget, pajlada::Signals::SignalHolder { friend class SplitInput; Q_OBJECT + static pajlada::Signals::Signal altPressedStatusChanged; + static bool altPressesStatus; + public: explicit Split(SplitContainer *parent); explicit Split(QWidget *parent); @@ -81,6 +85,9 @@ protected: void mousePressEvent(QMouseEvent *event) override; void keyPressEvent(QKeyEvent *event) override; void keyReleaseEvent(QKeyEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void enterEvent(QEvent *event) override; + void leaveEvent(QEvent *event) override; private: SplitContainer *container; @@ -90,11 +97,15 @@ private: SplitHeader header; ChannelView view; SplitInput input; + SplitOverlay *overlay; + double flexSizeX = 1; double flexSizeY = 1; bool moderationMode = false; + bool isMouseOver = false; + pajlada::Signals::Connection channelIDChangedConnection; pajlada::Signals::Connection usermodeChangedConnection; pajlada::Signals::Connection indirectChannelChangedConnection; diff --git a/src/widgets/window.cpp b/src/widgets/window.cpp index b2020ea23..ef667c50b 100644 --- a/src/widgets/window.cpp +++ b/src/widgets/window.cpp @@ -138,9 +138,9 @@ void Window::refreshWindowTitle(const QString &username) this->setWindowTitle(username + " - Chatterino for Twitch"); } -bool Window::event(QEvent *e) +bool Window::event(QEvent *event) { - switch (e->type()) { + switch (event->type()) { case QEvent::WindowActivate: break; @@ -156,7 +156,7 @@ bool Window::event(QEvent *e) } } break; }; - return BaseWindow::event(e); + return BaseWindow::event(event); } void Window::closeEvent(QCloseEvent *event)