diff --git a/chatterino.pro b/chatterino.pro index 2461429b3..8a5651d24 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -203,7 +203,8 @@ SOURCES += \ src/controllers/accounts/account.cpp \ src/widgets/helper/splitoverlay.cpp \ src/widgets/helper/dropoverlay.cpp \ - src/widgets/helper/splitnode.cpp + src/widgets/helper/splitnode.cpp \ + src/widgets/notificationpopup.cpp HEADERS += \ src/precompiled_header.hpp \ @@ -351,7 +352,8 @@ HEADERS += \ src/util/sharedptrelementless.hpp \ src/widgets/helper/splitoverlay.hpp \ src/widgets/helper/dropoverlay.hpp \ - src/widgets/helper/splitnode.hpp + src/widgets/helper/splitnode.hpp \ + src/widgets/notificationpopup.hpp RESOURCES += \ resources/resources.qrc diff --git a/src/controllers/highlights/highlightcontroller.cpp b/src/controllers/highlights/highlightcontroller.cpp index cab3cbbeb..8c6b789da 100644 --- a/src/controllers/highlights/highlightcontroller.cpp +++ b/src/controllers/highlights/highlightcontroller.cpp @@ -2,6 +2,7 @@ #include "application.hpp" #include "controllers/highlights/highlightmodel.hpp" +#include "widgets/notificationpopup.hpp" namespace chatterino { namespace controllers { @@ -34,6 +35,15 @@ HighlightModel *HighlightController::createModel(QObject *parent) return model; } +void HighlightController::addHighlight(const messages::MessagePtr &msg) +{ + // static widgets::NotificationPopup popup; + + // popup.updatePosition(); + // popup.addMessage(msg); + // popup.show(); +} + } // namespace highlights } // namespace controllers } // namespace chatterino diff --git a/src/controllers/highlights/highlightcontroller.hpp b/src/controllers/highlights/highlightcontroller.hpp index 98ad843d2..e6bed3343 100644 --- a/src/controllers/highlights/highlightcontroller.hpp +++ b/src/controllers/highlights/highlightcontroller.hpp @@ -1,6 +1,7 @@ #pragma once #include "controllers/highlights/highlightphrase.hpp" +#include "messages/message.hpp" #include "singletons/settingsmanager.hpp" #include "util/signalvector2.hpp" @@ -21,6 +22,8 @@ public: HighlightModel *createModel(QObject *parent); + void addHighlight(const messages::MessagePtr &msg); + private: bool initialized = false; diff --git a/src/providers/twitch/twitchserver.cpp b/src/providers/twitch/twitchserver.cpp index 6a6843f51..41d42cb7b 100644 --- a/src/providers/twitch/twitchserver.cpp +++ b/src/providers/twitch/twitchserver.cpp @@ -1,6 +1,7 @@ #include "twitchserver.hpp" #include "application.hpp" +#include "controllers/highlights/highlightcontroller.hpp" #include "providers/twitch/ircmessagehandler.hpp" #include "providers/twitch/twitchaccount.hpp" #include "providers/twitch/twitchhelpers.hpp" @@ -93,12 +94,13 @@ void TwitchServer::privateMessageReceived(IrcPrivateMessage *message) TwitchMessageBuilder builder(chan.get(), message, args); if (!builder.isIgnored()) { - messages::MessagePtr _message = builder.build(); - if (_message->flags & messages::Message::Highlighted) { - this->mentionsChannel->addMessage(_message); + messages::MessagePtr msg = builder.build(); + if (msg->flags & messages::Message::Highlighted) { + this->mentionsChannel->addMessage(msg); + getApp()->highlights->addHighlight(msg); } - chan->addMessage(_message); + chan->addMessage(msg); } } diff --git a/src/widgets/basewidget.hpp b/src/widgets/basewidget.hpp index 998befca9..6e6702a01 100644 --- a/src/widgets/basewidget.hpp +++ b/src/widgets/basewidget.hpp @@ -26,7 +26,7 @@ public: QSize getScaleIndependantSize() const; int getScaleIndependantWidth() const; int getScaleIndependantHeight() const; - void setScaleIndependantSize(int width, int yOffset); + void setScaleIndependantSize(int width, int height); void setScaleIndependantSize(QSize); void setScaleIndependantWidth(int value); void setScaleIndependantHeight(int value); diff --git a/src/widgets/basewindow.cpp b/src/widgets/basewindow.cpp index a1cd10421..50cbd73a9 100644 --- a/src/widgets/basewindow.cpp +++ b/src/widgets/basewindow.cpp @@ -32,10 +32,16 @@ namespace chatterino { namespace widgets { -BaseWindow::BaseWindow(QWidget *parent, bool _enableCustomFrame) +BaseWindow::BaseWindow(QWidget *parent, Flags flags) : BaseWidget(parent, Qt::Window) - , enableCustomFrame(_enableCustomFrame) + , enableCustomFrame(flags & EnableCustomFrame) + , frameless(flags & FrameLess) { + if (this->frameless) { + this->enableCustomFrame = false; + this->setWindowFlag(Qt::FramelessWindowHint); + } + this->init(); } @@ -53,55 +59,57 @@ void BaseWindow::init() layout->setSpacing(0); this->setLayout(layout); { - QHBoxLayout *buttonLayout = this->ui.titlebarBox = new QHBoxLayout(); - buttonLayout->setMargin(0); - layout->addLayout(buttonLayout); + if (!this->frameless) { + QHBoxLayout *buttonLayout = this->ui.titlebarBox = new QHBoxLayout(); + buttonLayout->setMargin(0); + layout->addLayout(buttonLayout); - // title - QLabel *title = new QLabel(" Chatterino"); - QObject::connect(this, &QWidget::windowTitleChanged, - [title](const QString &text) { title->setText(" " + text); }); + // title + QLabel *title = new QLabel(" Chatterino"); + QObject::connect(this, &QWidget::windowTitleChanged, + [title](const QString &text) { title->setText(" " + text); }); - QSizePolicy policy(QSizePolicy::Ignored, QSizePolicy::Preferred); - policy.setHorizontalStretch(1); - // title->setBaseSize(0, 0); - title->setScaledContents(true); - title->setSizePolicy(policy); - buttonLayout->addWidget(title); - this->ui.titleLabel = title; + QSizePolicy policy(QSizePolicy::Ignored, QSizePolicy::Preferred); + policy.setHorizontalStretch(1); + // title->setBaseSize(0, 0); + title->setScaledContents(true); + title->setSizePolicy(policy); + buttonLayout->addWidget(title); + this->ui.titleLabel = title; - // buttons - TitleBarButton *_minButton = new TitleBarButton; - _minButton->setButtonStyle(TitleBarButton::Minimize); - TitleBarButton *_maxButton = new TitleBarButton; - _maxButton->setButtonStyle(TitleBarButton::Maximize); - TitleBarButton *_exitButton = new TitleBarButton; - _exitButton->setButtonStyle(TitleBarButton::Close); + // buttons + TitleBarButton *_minButton = new TitleBarButton; + _minButton->setButtonStyle(TitleBarButton::Minimize); + TitleBarButton *_maxButton = new TitleBarButton; + _maxButton->setButtonStyle(TitleBarButton::Maximize); + TitleBarButton *_exitButton = new TitleBarButton; + _exitButton->setButtonStyle(TitleBarButton::Close); - QObject::connect(_minButton, &TitleBarButton::clicked, this, [this] { - this->setWindowState(Qt::WindowMinimized | this->windowState()); - }); - QObject::connect(_maxButton, &TitleBarButton::clicked, this, [this] { - this->setWindowState(this->windowState() == Qt::WindowMaximized - ? Qt::WindowActive - : Qt::WindowMaximized); - }); - QObject::connect(_exitButton, &TitleBarButton::clicked, this, - [this] { this->close(); }); + QObject::connect(_minButton, &TitleBarButton::clicked, this, [this] { + this->setWindowState(Qt::WindowMinimized | this->windowState()); + }); + QObject::connect(_maxButton, &TitleBarButton::clicked, this, [this] { + this->setWindowState(this->windowState() == Qt::WindowMaximized + ? Qt::WindowActive + : Qt::WindowMaximized); + }); + QObject::connect(_exitButton, &TitleBarButton::clicked, this, + [this] { this->close(); }); - this->ui.minButton = _minButton; - this->ui.maxButton = _maxButton; - this->ui.exitButton = _exitButton; + this->ui.minButton = _minButton; + this->ui.maxButton = _maxButton; + this->ui.exitButton = _exitButton; - this->ui.buttons.push_back(_minButton); - this->ui.buttons.push_back(_maxButton); - this->ui.buttons.push_back(_exitButton); + this->ui.buttons.push_back(_minButton); + this->ui.buttons.push_back(_maxButton); + this->ui.buttons.push_back(_exitButton); - // buttonLayout->addStretch(1); - buttonLayout->addWidget(_minButton); - buttonLayout->addWidget(_maxButton); - buttonLayout->addWidget(_exitButton); - buttonLayout->setSpacing(0); + // buttonLayout->addStretch(1); + buttonLayout->addWidget(_minButton); + buttonLayout->addWidget(_maxButton); + buttonLayout->addWidget(_exitButton); + buttonLayout->setSpacing(0); + } } this->ui.layoutBase = new BaseWidget(this); layout->addWidget(this->ui.layoutBase); @@ -165,10 +173,12 @@ void BaseWindow::themeRefreshEvent() palette.setColor(QPalette::Foreground, this->themeManager->window.text); this->setPalette(palette); - QPalette palette_title; - palette_title.setColor(QPalette::Foreground, - this->themeManager->isLightTheme() ? "#333" : "#ccc"); - this->ui.titleLabel->setPalette(palette_title); + if (this->ui.titleLabel) { + QPalette palette_title; + palette_title.setColor(QPalette::Foreground, + this->themeManager->isLightTheme() ? "#333" : "#ccc"); + this->ui.titleLabel->setPalette(palette_title); + } for (RippleEffectButton *button : this->ui.buttons) { button->setMouseEffectColor(this->themeManager->window.text); @@ -212,7 +222,7 @@ void BaseWindow::changeEvent(QEvent *) TooltipWidget::getInstance()->hide(); #ifdef USEWINSDK - if (this->hasCustomWindowFrame()) { + if (this->ui.maxButton) { this->ui.maxButton->setButtonStyle(this->windowState() & Qt::WindowMaximized ? TitleBarButton::Unmaximize : TitleBarButton::Maximize); @@ -449,13 +459,19 @@ void BaseWindow::calcButtonsSizes() return; } if ((this->width() / this->getScale()) < 300) { - this->ui.minButton->setScaleIndependantSize(30, 30); - this->ui.maxButton->setScaleIndependantSize(30, 30); - this->ui.exitButton->setScaleIndependantSize(30, 30); + if (this->ui.minButton) + this->ui.minButton->setScaleIndependantSize(30, 30); + if (this->ui.maxButton) + this->ui.maxButton->setScaleIndependantSize(30, 30); + if (this->ui.exitButton) + this->ui.exitButton->setScaleIndependantSize(30, 30); } else { - this->ui.minButton->setScaleIndependantSize(46, 30); - this->ui.maxButton->setScaleIndependantSize(46, 30); - this->ui.exitButton->setScaleIndependantSize(46, 30); + if (this->ui.minButton) + this->ui.minButton->setScaleIndependantSize(46, 30); + if (this->ui.maxButton) + this->ui.maxButton->setScaleIndependantSize(46, 30); + if (this->ui.exitButton) + this->ui.exitButton->setScaleIndependantSize(46, 30); } } } // namespace widgets diff --git a/src/widgets/basewindow.hpp b/src/widgets/basewindow.hpp index c1a65afbc..9483f0a4f 100644 --- a/src/widgets/basewindow.hpp +++ b/src/widgets/basewindow.hpp @@ -19,7 +19,9 @@ class BaseWindow : public BaseWidget Q_OBJECT public: - explicit BaseWindow(QWidget *parent = nullptr, bool enableCustomFrame = false); + enum Flags { None = 0, EnableCustomFrame = 1, FrameLess = 2 }; + + explicit BaseWindow(QWidget *parent = nullptr, Flags flags = None); QWidget *getLayoutContainer(); bool hasCustomWindowFrame(); @@ -51,16 +53,17 @@ private: void calcButtonsSizes(); bool enableCustomFrame; + bool frameless; bool stayInScreenRect = false; bool shown = false; struct { - QHBoxLayout *titlebarBox; - QWidget *titleLabel; + QHBoxLayout *titlebarBox = nullptr; + QWidget *titleLabel = nullptr; TitleBarButton *minButton = nullptr; TitleBarButton *maxButton = nullptr; TitleBarButton *exitButton = nullptr; - QWidget *layoutBase; + QWidget *layoutBase = nullptr; std::vector buttons; } ui; }; diff --git a/src/widgets/emotepopup.cpp b/src/widgets/emotepopup.cpp index 004cadce2..d3787d584 100644 --- a/src/widgets/emotepopup.cpp +++ b/src/widgets/emotepopup.cpp @@ -17,7 +17,7 @@ namespace chatterino { namespace widgets { EmotePopup::EmotePopup() - : BaseWindow(nullptr, true) + : BaseWindow(nullptr, BaseWindow::EnableCustomFrame) { this->viewEmotes = new ChannelView(); this->viewEmojis = new ChannelView(); diff --git a/src/widgets/notificationpopup.cpp b/src/widgets/notificationpopup.cpp new file mode 100644 index 000000000..aa21c5ec5 --- /dev/null +++ b/src/widgets/notificationpopup.cpp @@ -0,0 +1,50 @@ +#include "notificationpopup.hpp" + +#include "widgets/helper/channelview.hpp" + +#include +#include +#include + +namespace chatterino { +namespace widgets { + +NotificationPopup::NotificationPopup() + : BaseWindow((QWidget *)nullptr, BaseWindow::FrameLess) + , channel(std::make_shared("notifications", Channel::None)) + +{ + this->channelView = new ChannelView(this); + + auto *layout = new QVBoxLayout(this); + this->setLayout(layout); + + layout->addWidget(this->channelView); + + this->channelView->setChannel(this->channel); + this->setScaleIndependantSize(300, 150); +} + +void NotificationPopup::updatePosition() +{ + Location location = BottomRight; + + QDesktopWidget *desktop = QApplication::desktop(); + const QRect rect = desktop->availableGeometry(); + + switch (location) { + case BottomRight: { + this->move(rect.right() - this->width(), rect.bottom() - this->height()); + } break; + } +} + +void NotificationPopup::addMessage(messages::MessagePtr msg) +{ + this->channel->addMessage(msg); + + // QTimer::singleShot(5000, this, [this, msg] { this->channel->remove }); +} + +} // namespace widgets +} // namespace chatterino diff --git a/src/widgets/notificationpopup.hpp b/src/widgets/notificationpopup.hpp new file mode 100644 index 000000000..ab7409faf --- /dev/null +++ b/src/widgets/notificationpopup.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include "channel.hpp" +#include "messages/message.hpp" +#include "widgets/basewindow.hpp" + +namespace chatterino { +namespace widgets { + +class ChannelView; + +class NotificationPopup : public BaseWindow +{ +public: + enum Location { TopLeft, TopRight, BottomLeft, BottomRight }; + NotificationPopup(); + + void addMessage(messages::MessagePtr msg); + void updatePosition(); + +private: + ChannelView *channelView; + ChannelPtr channel; +}; + +} // namespace widgets +} // namespace chatterino diff --git a/src/widgets/selectchanneldialog.cpp b/src/widgets/selectchanneldialog.cpp index d444f4a82..6d1a810ad 100644 --- a/src/widgets/selectchanneldialog.cpp +++ b/src/widgets/selectchanneldialog.cpp @@ -17,7 +17,7 @@ namespace chatterino { namespace widgets { SelectChannelDialog::SelectChannelDialog() - : BaseWindow((QWidget *)nullptr, true) + : BaseWindow((QWidget *)nullptr, BaseWindow::EnableCustomFrame) , selectedChannel(Channel::getEmpty()) { this->setWindowTitle("Select a channel to join"); diff --git a/src/widgets/window.cpp b/src/widgets/window.cpp index a3fa14775..46168a72c 100644 --- a/src/widgets/window.cpp +++ b/src/widgets/window.cpp @@ -24,7 +24,7 @@ namespace chatterino { namespace widgets { Window::Window(WindowType _type) - : BaseWindow(nullptr, true) + : BaseWindow(nullptr, BaseWindow::EnableCustomFrame) , type(_type) , dpi(this->getScale()) , notebook(this)