This commit is contained in:
fourtf
2018-01-28 03:39:47 +01:00
76 changed files with 1645 additions and 561 deletions
+7 -6
View File
@@ -18,13 +18,15 @@
namespace chatterino {
namespace widgets {
AccountPopupWidget::AccountPopupWidget(SharedChannel _channel)
AccountPopupWidget::AccountPopupWidget(ChannelPtr _channel)
: BaseWindow()
, ui(new Ui::AccountPopup)
, channel(_channel)
{
this->ui->setupUi(this);
this->setStayInScreenRect(true);
this->layout()->setSizeConstraint(QLayout::SetFixedSize);
this->setWindowFlags(Qt::FramelessWindowHint);
@@ -49,7 +51,6 @@ AccountPopupWidget::AccountPopupWidget(SharedChannel _channel)
this->loggedInUser.userID = currentTwitchUser->getUserId();
this->loggedInUser.refreshUserType(this->channel, true);
});
singletons::SettingManager &settings = singletons::SettingManager::getInstance();
@@ -154,7 +155,7 @@ AccountPopupWidget::AccountPopupWidget(SharedChannel _channel)
this->hide(); //
});
this->dpiMultiplierChanged(this->getDpiMultiplier(), this->getDpiMultiplier());
this->scaleChangedEvent(this->getScale());
}
void AccountPopupWidget::setName(const QString &name)
@@ -171,7 +172,7 @@ void AccountPopupWidget::setName(const QString &name)
this->popupWidgetUser.refreshUserType(this->channel, false);
}
void AccountPopupWidget::User::refreshUserType(const SharedChannel &channel, bool loggedInUser)
void AccountPopupWidget::User::refreshUserType(const ChannelPtr &channel, bool loggedInUser)
{
if (channel->name == this->username) {
this->userType = UserType::Owner;
@@ -182,7 +183,7 @@ void AccountPopupWidget::User::refreshUserType(const SharedChannel &channel, boo
}
}
void AccountPopupWidget::setChannel(SharedChannel _channel)
void AccountPopupWidget::setChannel(ChannelPtr _channel)
{
this->channel = _channel;
}
@@ -246,7 +247,7 @@ void AccountPopupWidget::loadAvatar(const QUrl &avatarUrl)
}
}
void AccountPopupWidget::dpiMultiplierChanged(float /*oldDpi*/, float newDpi)
void AccountPopupWidget::scaleChangedEvent(float newDpi)
{
this->setStyleSheet(QString("* { font-size: <font-size>px; }")
.replace("<font-size>", QString::number((int)(12 * newDpi))));
+5 -5
View File
@@ -23,10 +23,10 @@ class AccountPopupWidget : public BaseWindow
{
Q_OBJECT
public:
AccountPopupWidget(SharedChannel _channel);
AccountPopupWidget(ChannelPtr _channel);
void setName(const QString &name);
void setChannel(SharedChannel _channel);
void setChannel(ChannelPtr _channel);
public slots:
void actuallyRefreshButtons();
@@ -35,7 +35,7 @@ signals:
void refreshButtons();
protected:
virtual void dpiMultiplierChanged(float oldDpi, float newDpi) override;
virtual void scaleChangedEvent(float newDpi) override;
private:
Ui::AccountPopup *ui;
@@ -52,7 +52,7 @@ private:
enum class UserType { User, Mod, Owner };
SharedChannel channel;
ChannelPtr channel;
QPixmap avatar;
@@ -63,7 +63,7 @@ private:
QString userID;
UserType userType = UserType::User;
void refreshUserType(const SharedChannel &channel, bool loggedInUser);
void refreshUserType(const ChannelPtr &channel, bool loggedInUser);
};
User loggedInUser;
+109 -13
View File
@@ -2,6 +2,7 @@
#include "singletons/settingsmanager.hpp"
#include "singletons/thememanager.hpp"
#include <QChildEvent>
#include <QDebug>
#include <QIcon>
#include <QLayout>
@@ -25,13 +26,7 @@ BaseWidget::BaseWidget(BaseWidget *parent, Qt::WindowFlags f)
this->init();
}
BaseWidget::BaseWidget(QWidget *parent, Qt::WindowFlags f)
: QWidget(parent, f)
, themeManager(singletons::ThemeManager::getInstance())
{
}
float BaseWidget::getDpiMultiplier()
float BaseWidget::getScale() const
{
// return 1.f;
BaseWidget *baseWidget = dynamic_cast<BaseWidget *>(this->window());
@@ -39,17 +34,56 @@ float BaseWidget::getDpiMultiplier()
if (baseWidget == nullptr) {
return 1.f;
} else {
return baseWidget->dpiMultiplier;
// int screenNr = QApplication::desktop()->screenNumber(this);
// QScreen *screen = QApplication::screens().at(screenNr);
// return screen->logicalDotsPerInch() / 96.f;
return baseWidget->scale;
}
}
QSize BaseWidget::getScaleIndependantSize() const
{
return this->scaleIndependantSize;
}
int BaseWidget::getScaleIndependantWidth() const
{
return this->scaleIndependantSize.width();
}
int BaseWidget::getScaleIndependantHeight() const
{
return this->scaleIndependantSize.height();
}
void BaseWidget::setScaleIndependantSize(int width, int height)
{
this->setScaleIndependantSize(QSize(width, height));
}
void BaseWidget::setScaleIndependantSize(QSize size)
{
this->scaleIndependantSize = size;
if (size.width() > 0) {
this->setFixedWidth((int)(size.width() * this->getScale()));
}
if (size.height() > 0) {
this->setFixedHeight((int)(size.height() * this->getScale()));
}
}
void BaseWidget::setScaleIndependantWidth(int value)
{
this->setScaleIndependantSize(QSize(value, this->scaleIndependantSize.height()));
}
void BaseWidget::setScaleIndependantHeight(int value)
{
this->setScaleIndependantSize(QSize(this->scaleIndependantSize.height(), value));
}
void BaseWidget::init()
{
auto connection = this->themeManager.updated.connect([this]() {
this->refreshTheme();
this->themeRefreshEvent();
this->update();
});
@@ -59,7 +93,69 @@ void BaseWidget::init()
});
}
void BaseWidget::refreshTheme()
void BaseWidget::childEvent(QChildEvent *event)
{
if (event->added()) {
BaseWidget *widget = dynamic_cast<BaseWidget *>(event->child());
if (widget) {
this->widgets.push_back(widget);
}
} else if (event->removed()) {
for (auto it = this->widgets.begin(); it != this->widgets.end(); it++) {
if (*it == event->child()) {
this->widgets.erase(it);
break;
}
}
}
}
void BaseWidget::setScale(float value)
{
// update scale value
this->scale = value;
this->scaleChangedEvent(value);
this->scaleChanged.invoke(value);
this->setScaleIndependantSize(this->getScaleIndependantSize());
// set scale for all children
BaseWidget::setScaleRecursive(value, this);
}
void BaseWidget::setScaleRecursive(float scale, QObject *object)
{
for (QObject *child : object->children()) {
BaseWidget *widget = dynamic_cast<BaseWidget *>(child);
if (widget != nullptr) {
widget->setScale(scale);
continue;
}
// QLayout *layout = nullptr;
// QWidget *widget = dynamic_cast<QWidget *>(child);
// if (widget != nullptr) {
// layout = widget->layout();
// }
// else {
QLayout *layout = dynamic_cast<QLayout *>(object);
if (layout != nullptr) {
setScaleRecursive(scale, layout);
}
// }
}
}
void BaseWidget::scaleChangedEvent(float newDpi)
{
}
void BaseWidget::themeRefreshEvent()
{
// Do any color scheme updates here
}
+24 -7
View File
@@ -1,6 +1,7 @@
#pragma once
#include <QWidget>
#include <pajlada/signals/signal.hpp>
namespace chatterino {
namespace singletons {
@@ -8,6 +9,7 @@ class ThemeManager;
}
namespace widgets {
class BaseWindow;
class BaseWidget : public QWidget
{
@@ -17,23 +19,38 @@ public:
explicit BaseWidget(singletons::ThemeManager &_themeManager, QWidget *parent,
Qt::WindowFlags f = Qt::WindowFlags());
explicit BaseWidget(BaseWidget *parent, Qt::WindowFlags f = Qt::WindowFlags());
explicit BaseWidget(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
singletons::ThemeManager &themeManager;
float getDpiMultiplier();
float getScale() const;
pajlada::Signals::Signal<float> scaleChanged;
QSize getScaleIndependantSize() const;
int getScaleIndependantWidth() const;
int getScaleIndependantHeight() const;
void setScaleIndependantSize(int width, int height);
void setScaleIndependantSize(QSize);
void setScaleIndependantWidth(int value);
void setScaleIndependantHeight(int value);
protected:
virtual void dpiMultiplierChanged(float /*oldDpi*/, float /*newDpi*/)
{
}
virtual void childEvent(QChildEvent *) override;
float dpiMultiplier = 1.f;
virtual void scaleChangedEvent(float newScale);
virtual void themeRefreshEvent();
void setScale(float value);
private:
void init();
float scale = 1.f;
QSize scaleIndependantSize;
virtual void refreshTheme();
std::vector<BaseWidget *> widgets;
static void setScaleRecursive(float scale, QObject *object);
friend class BaseWindow;
};
} // namespace widgets
+153 -61
View File
@@ -6,6 +6,7 @@
#include <QApplication>
#include <QDebug>
#include <QDesktopWidget>
#include <QIcon>
#ifdef USEWINSDK
@@ -22,7 +23,7 @@
#define WM_DPICHANGED 0x02E0
#endif
#include "widgets/helper/rippleeffectlabel.hpp"
#include "widgets/helper/titlebarbutton.hpp"
namespace chatterino {
namespace widgets {
@@ -43,7 +44,7 @@ BaseWindow::BaseWindow(BaseWidget *parent, bool _enableCustomFrame)
}
BaseWindow::BaseWindow(QWidget *parent, bool _enableCustomFrame)
: BaseWidget(parent, Qt::Window)
: BaseWidget(singletons::ThemeManager::getInstance(), parent, Qt::Window)
, enableCustomFrame(_enableCustomFrame)
{
this->init();
@@ -56,45 +57,57 @@ void BaseWindow::init()
#ifdef USEWINSDK
if (this->hasCustomWindowFrame()) {
// CUSTOM WINDOW FRAME
QVBoxLayout *layout = new QVBoxLayout;
QVBoxLayout *layout = new QVBoxLayout();
layout->setMargin(1);
layout->setSpacing(0);
this->setLayout(layout);
{
QHBoxLayout *buttons = this->titlebarBox = new QHBoxLayout;
buttons->setMargin(0);
layout->addLayout(buttons);
QHBoxLayout *buttonLayout = this->titlebarBox = new QHBoxLayout();
buttonLayout->setMargin(0);
layout->addLayout(buttonLayout);
// title
QLabel *titleLabel = new QLabel("Chatterino");
buttons->addWidget(titleLabel);
this->titleLabel = titleLabel;
QLabel *title = new QLabel(" Chatterino");
buttonLayout->addWidget(title);
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->setScaleIndependantSize(46, 30);
_minButton->setButtonStyle(TitleBarButton::Minimize);
TitleBarButton *_maxButton = new TitleBarButton;
_maxButton->setScaleIndependantSize(46, 30);
_maxButton->setButtonStyle(TitleBarButton::Maximize);
TitleBarButton *_exitButton = new TitleBarButton;
_exitButton->setScaleIndependantSize(46, 30);
_exitButton->setButtonStyle(TitleBarButton::Close);
this->minButton = min;
this->maxButton = max;
this->exitButton = exit;
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->widgets.push_back(min);
this->widgets.push_back(max);
this->widgets.push_back(exit);
this->minButton = _minButton;
this->maxButton = _maxButton;
this->exitButton = _exitButton;
buttons->addStretch(1);
buttons->addWidget(min);
buttons->addWidget(max);
buttons->addWidget(exit);
this->buttons.push_back(_minButton);
this->buttons.push_back(_maxButton);
this->buttons.push_back(_exitButton);
buttonLayout->addStretch(1);
buttonLayout->addWidget(_minButton);
buttonLayout->addWidget(_maxButton);
buttonLayout->addWidget(_exitButton);
buttonLayout->setSpacing(0);
}
this->layoutBase = new QWidget(this);
this->widgets.push_back(this->layoutBase);
this->layoutBase = new BaseWidget(this);
layout->addWidget(this->layoutBase);
}
@@ -102,10 +115,10 @@ void BaseWindow::init()
auto dpi = util::getWindowDpi(this->winId());
if (dpi) {
this->dpiMultiplier = dpi.value() / 96.f;
this->scale = dpi.value() / 96.f;
}
this->dpiMultiplierChanged(1, this->dpiMultiplier);
this->scaleChangedEvent(this->scale);
#endif
if (singletons::SettingManager::getInstance().windowTopMost.getValue()) {
@@ -113,6 +126,16 @@ void BaseWindow::init()
}
}
void BaseWindow::setStayInScreenRect(bool value)
{
this->stayInScreenRect = value;
}
bool BaseWindow::getStayInScreenRect() const
{
return this->stayInScreenRect;
}
QWidget *BaseWindow::getLayoutContainer()
{
if (this->hasCustomWindowFrame()) {
@@ -125,37 +148,96 @@ QWidget *BaseWindow::getLayoutContainer()
bool BaseWindow::hasCustomWindowFrame()
{
#ifdef Q_OS_WIN
// return this->enableCustomFrame;
return false;
return this->enableCustomFrame;
// return false;
#else
return false;
#endif
}
void BaseWindow::refreshTheme()
void BaseWindow::themeRefreshEvent()
{
QPalette palette;
palette.setColor(QPalette::Background, this->themeManager.windowBg);
palette.setColor(QPalette::Foreground, this->themeManager.windowText);
this->setPalette(palette);
for (RippleEffectButton *button : this->buttons) {
button->setMouseEffectColor(this->themeManager.windowText);
}
}
void BaseWindow::addTitleBarButton(const QString &text)
void BaseWindow::addTitleBarButton(const TitleBarButton::Style &style,
std::function<void()> onClicked)
{
RippleEffectLabel *label = new RippleEffectLabel;
label->getLabel().setText(text);
this->widgets.push_back(label);
this->titlebarBox->insertWidget(2, label);
TitleBarButton *button = new TitleBarButton;
button->setScaleIndependantSize(30, 30);
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();
TooltipWidget::getInstance()->hide();
#ifdef USEWINSDK
if (this->hasCustomWindowFrame()) {
this->maxButton->setButtonStyle(this->windowState() & Qt::WindowMaximized
? TitleBarButton::Unmaximize
: TitleBarButton::Maximize);
}
#endif
}
void BaseWindow::leaveEvent(QEvent *)
{
// TooltipWidget::getInstance()->hide();
TooltipWidget::getInstance()->hide();
}
void BaseWindow::moveTo(QWidget *parent, QPoint point)
{
point.rx() += 16;
point.ry() += 16;
this->move(point);
this->moveIntoDesktopRect(parent);
}
void BaseWindow::resizeEvent(QResizeEvent *)
{
this->moveIntoDesktopRect(this);
}
void BaseWindow::moveIntoDesktopRect(QWidget *parent)
{
if (!this->stayInScreenRect)
return;
// move the widget into the screen geometry if it's not already in there
QDesktopWidget *desktop = QApplication::desktop();
QRect s = desktop->screenGeometry(parent);
QPoint p = this->pos();
if (p.x() < s.left()) {
p.setX(s.left());
}
if (p.y() < s.top()) {
p.setY(s.top());
}
if (p.x() + this->width() > s.right()) {
p.setX(s.right() - this->width());
}
if (p.y() + this->height() > s.bottom()) {
p.setY(s.bottom() - this->height());
}
if (p != this->pos())
this->move(p);
}
#ifdef USEWINSDK
@@ -165,17 +247,16 @@ bool BaseWindow::nativeEvent(const QByteArray &eventType, void *message, long *r
switch (msg->message) {
case WM_DPICHANGED: {
qDebug() << "dpi changed";
int dpi = HIWORD(msg->wParam);
float oldDpiMultiplier = this->dpiMultiplier;
this->dpiMultiplier = dpi / 96.f;
float scale = this->dpiMultiplier / oldDpiMultiplier;
float oldScale = this->scale;
float _scale = dpi / 96.f;
float resizeScale = _scale / oldScale;
this->dpiMultiplierChanged(oldDpiMultiplier, this->dpiMultiplier);
this->resize(static_cast<int>(this->width() * resizeScale),
static_cast<int>(this->height() * resizeScale));
this->resize(static_cast<int>(this->width() * scale),
static_cast<int>(this->height() * scale));
this->setScale(_scale);
return true;
}
@@ -250,12 +331,16 @@ bool BaseWindow::nativeEvent(const QByteArray &eventType, void *message, long *r
bool client = false;
QPoint point(x - winrect.left, y - winrect.top);
for (QWidget *widget : this->widgets) {
for (QWidget *widget : this->buttons) {
if (widget->geometry().contains(point)) {
client = true;
}
}
if (this->layoutBase->geometry().contains(point)) {
client = true;
}
if (client) {
*result = HTCLIENT;
} else {
@@ -263,8 +348,6 @@ bool BaseWindow::nativeEvent(const QByteArray &eventType, void *message, long *r
}
}
qDebug() << *result;
return true;
} else {
return QWidget::nativeEvent(eventType, message, result);
@@ -272,9 +355,10 @@ bool BaseWindow::nativeEvent(const QByteArray &eventType, void *message, long *r
break;
} // end case WM_NCHITTEST
case WM_CLOSE: {
if (this->enableCustomFrame) {
return close();
}
// if (this->enableCustomFrame) {
// this->close();
// }
return QWidget::nativeEvent(eventType, message, result);
break;
}
default:
@@ -282,9 +366,10 @@ bool BaseWindow::nativeEvent(const QByteArray &eventType, void *message, long *r
}
}
void BaseWindow::showEvent(QShowEvent *)
void BaseWindow::showEvent(QShowEvent *event)
{
if (this->isVisible() && this->hasCustomWindowFrame()) {
if (!this->shown && this->isVisible() && this->hasCustomWindowFrame()) {
this->shown = true;
SetWindowLongPtr((HWND)this->winId(), GWL_STYLE,
WS_POPUP | WS_CAPTION | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX);
@@ -294,22 +379,29 @@ void BaseWindow::showEvent(QShowEvent *)
SetWindowPos((HWND)this->winId(), 0, 0, 0, 0, 0,
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
}
BaseWidget::showEvent(event);
}
void BaseWindow::paintEvent(QPaintEvent *event)
{
BaseWidget::paintEvent(event);
if (this->hasCustomWindowFrame()) {
BaseWidget::paintEvent(event);
QPainter painter(this);
bool windowFocused = this->window() == QApplication::activeWindow();
QLinearGradient gradient(0, 0, 10, 250);
gradient.setColorAt(1, this->themeManager.tabs.selected.backgrounds.unfocused.color());
if (windowFocused) {
painter.setPen(this->themeManager.tabs.selected.backgrounds.regular.color());
gradient.setColorAt(.4, this->themeManager.tabs.selected.backgrounds.regular.color());
} else {
painter.setPen(this->themeManager.tabs.selected.backgrounds.unfocused.color());
gradient.setColorAt(.4, this->themeManager.tabs.selected.backgrounds.unfocused.color());
}
painter.setPen(QPen(QBrush(gradient), 1));
painter.drawRect(0, 0, this->width() - 1, this->height() - 1);
}
}
+20 -6
View File
@@ -1,11 +1,16 @@
#pragma once
#include "basewidget.hpp"
#include "widgets/helper/titlebarbutton.hpp"
#include <functional>
class QHBoxLayout;
namespace chatterino {
namespace widgets {
class RippleEffectButton;
class TitleBarButton;
class BaseWindow : public BaseWidget
{
@@ -17,7 +22,12 @@ public:
QWidget *getLayoutContainer();
bool hasCustomWindowFrame();
void addTitleBarButton(const QString &text);
void addTitleBarButton(const TitleBarButton::Style &style, std::function<void()> onClicked);
void setStayInScreenRect(bool value);
bool getStayInScreenRect() const;
void moveTo(QWidget *widget, QPoint point);
protected:
#ifdef USEWINSDK
@@ -28,21 +38,25 @@ protected:
virtual void changeEvent(QEvent *) override;
virtual void leaveEvent(QEvent *) override;
virtual void resizeEvent(QResizeEvent *) override;
virtual void refreshTheme() override;
virtual void themeRefreshEvent() override;
private:
void init();
void moveIntoDesktopRect(QWidget *parent);
bool enableCustomFrame;
bool stayInScreenRect = false;
bool shown = false;
QHBoxLayout *titlebarBox;
QWidget *titleLabel;
QWidget *minButton;
QWidget *maxButton;
QWidget *exitButton;
TitleBarButton *minButton;
TitleBarButton *maxButton;
TitleBarButton *exitButton;
QWidget *layoutBase;
std::vector<QWidget *> widgets;
std::vector<RippleEffectButton *> buttons;
};
} // namespace widgets
} // namespace chatterino
+15 -5
View File
@@ -18,6 +18,11 @@ EmotePopup::EmotePopup(singletons::ThemeManager &themeManager)
this->viewEmotes = new ChannelView();
this->viewEmojis = new ChannelView();
this->viewEmotes->setOverrideFlags((MessageElement::Flags)(
MessageElement::Default | MessageElement::AlwaysShow | MessageElement::EmoteImages));
this->viewEmojis->setOverrideFlags((MessageElement::Flags)(
MessageElement::Default | MessageElement::AlwaysShow | MessageElement::EmoteImages));
this->viewEmotes->setEnableScrollingToBottom(false);
this->viewEmojis->setEnableScrollingToBottom(false);
@@ -30,9 +35,14 @@ EmotePopup::EmotePopup(singletons::ThemeManager &themeManager)
tabs->addTab(this->viewEmojis, "Emojis");
this->loadEmojis();
this->viewEmotes->linkClicked.connect(
[this](const Link &link) { this->linkClicked.invoke(link); });
this->viewEmojis->linkClicked.connect(
[this](const Link &link) { this->linkClicked.invoke(link); });
}
void EmotePopup::loadChannel(SharedChannel _channel)
void EmotePopup::loadChannel(ChannelPtr _channel)
{
TwitchChannel *channel = dynamic_cast<TwitchChannel *>(_channel.get());
@@ -40,7 +50,7 @@ void EmotePopup::loadChannel(SharedChannel _channel)
return;
}
SharedChannel emoteChannel(new Channel(""));
ChannelPtr emoteChannel(new Channel(""));
auto addEmotes = [&](util::EmoteMap &map, const QString &title, const QString &emoteDesc) {
// TITLE
@@ -57,7 +67,7 @@ void EmotePopup::loadChannel(SharedChannel _channel)
builder2.getMessage()->flags &= Message::DisableCompactEmotes;
map.each([&](const QString &key, const util::EmoteData &value) {
builder2.appendElement((new EmoteElement(value, MessageElement::Flags::AlwaysShow)) //
builder2.appendElement((new EmoteElement(value, MessageElement::Flags::AlwaysShow))
->setLink(Link(Link::InsertText, key)));
});
@@ -81,7 +91,7 @@ void EmotePopup::loadEmojis()
{
util::EmoteMap &emojis = singletons::EmoteManager::getInstance().getEmojis();
SharedChannel emojiChannel(new Channel(""));
ChannelPtr emojiChannel(new Channel(""));
// title
messages::MessageBuilder builder1;
@@ -96,7 +106,7 @@ void EmotePopup::loadEmojis()
builder.getMessage()->flags &= Message::DisableCompactEmotes;
emojis.each([this, &builder](const QString &key, const util::EmoteData &value) {
builder.appendElement((new EmoteElement(value, MessageElement::Flags::AlwaysShow)) //
builder.appendElement((new EmoteElement(value, MessageElement::Flags::AlwaysShow))
->setLink(Link(Link::Type::InsertText, key)));
});
emojiChannel->addMessage(builder.getMessage());
+5 -1
View File
@@ -4,6 +4,8 @@
#include "widgets/basewindow.hpp"
#include "widgets/helper/channelview.hpp"
#include <pajlada/signals/signal.hpp>
namespace chatterino {
namespace widgets {
@@ -12,9 +14,11 @@ class EmotePopup : public BaseWindow
public:
explicit EmotePopup(singletons::ThemeManager &);
void loadChannel(SharedChannel channel);
void loadChannel(ChannelPtr channel);
void loadEmojis();
pajlada::Signals::Signal<messages::Link> linkClicked;
private:
ChannelView *viewEmotes;
ChannelView *viewEmojis;
+109 -13
View File
@@ -13,6 +13,7 @@
#include "widgets/split.hpp"
#include "widgets/tooltipwidget.hpp"
#include <QClipboard>
#include <QDebug>
#include <QDesktopServices>
#include <QGraphicsBlurEffect>
@@ -24,8 +25,7 @@
#include <functional>
#include <memory>
#define LAYOUT_WIDTH \
(this->width() - (this->scrollBar.isVisible() ? 16 : 4) * this->getDpiMultiplier())
#define LAYOUT_WIDTH (this->width() - (this->scrollBar.isVisible() ? 16 : 4) * this->getScale())
using namespace chatterino::messages;
@@ -96,6 +96,9 @@ ChannelView::ChannelView(BaseWidget *parent)
auto e = new QResizeEvent(this->size(), this->size());
this->resizeEvent(e);
delete e;
singletons::SettingManager::getInstance().showLastMessageIndicator.connect(
[this](auto, auto) { this->update(); }, this->managedConnections);
}
ChannelView::~ChannelView()
@@ -111,6 +114,13 @@ ChannelView::~ChannelView()
this->messageReplacedConnection.disconnect();
}
void ChannelView::themeRefreshEvent()
{
BaseWidget::themeRefreshEvent();
this->layoutMessages();
}
void ChannelView::queueUpdate()
{
if (this->updateTimer.isActive()) {
@@ -164,7 +174,7 @@ void ChannelView::actuallyLayoutMessages()
for (size_t i = start; i < messagesSnapshot.getLength(); ++i) {
auto message = messagesSnapshot[i];
redrawRequired |= message->layout(layoutWidth, this->getDpiMultiplier(), flags);
redrawRequired |= message->layout(layoutWidth, this->getScale(), flags);
y += message->getHeight();
@@ -180,7 +190,7 @@ void ChannelView::actuallyLayoutMessages()
for (int i = (int)messagesSnapshot.getLength() - 1; i >= 0; i--) {
auto *message = messagesSnapshot[i].get();
message->layout(layoutWidth, this->getDpiMultiplier(), flags);
message->layout(layoutWidth, this->getScale(), flags);
h -= message->getHeight();
@@ -281,6 +291,16 @@ bool ChannelView::getEnableScrollingToBottom() const
return this->enableScrollingToBottom;
}
void ChannelView::setOverrideFlags(boost::optional<messages::MessageElement::Flags> value)
{
this->overrideFlags = value;
}
const boost::optional<messages::MessageElement::Flags> &ChannelView::getOverrideFlags() const
{
return this->overrideFlags;
}
messages::LimitedQueueSnapshot<MessageLayoutPtr> ChannelView::getMessagesSnapshot()
{
if (!this->paused) {
@@ -290,7 +310,7 @@ messages::LimitedQueueSnapshot<MessageLayoutPtr> ChannelView::getMessagesSnapsho
return this->snapshot;
}
void ChannelView::setChannel(SharedChannel newChannel)
void ChannelView::setChannel(ChannelPtr newChannel)
{
if (this->channel) {
this->detachChannel();
@@ -328,7 +348,6 @@ void ChannelView::setChannel(SharedChannel newChannel)
newChannel->messagesAddedAtStart.connect([this](std::vector<MessagePtr> &messages) {
std::vector<MessageLayoutPtr> messageRefs;
messageRefs.resize(messages.size());
qDebug() << messages.size();
for (size_t i = 0; i < messages.size(); i++) {
messageRefs.at(i) = MessageLayoutPtr(new MessageLayout(messages.at(i)));
}
@@ -410,6 +429,17 @@ void ChannelView::pause(int msecTimeout)
this->pauseTimeout.start(msecTimeout);
}
void ChannelView::updateLastReadMessage()
{
auto _snapshot = this->getMessagesSnapshot();
if (_snapshot.getLength() > 0) {
this->lastReadMessage = _snapshot[_snapshot.getLength() - 1];
}
this->update();
}
void ChannelView::resizeEvent(QResizeEvent *)
{
this->scrollBar.resize(this->scrollBar.width(), height());
@@ -434,6 +464,10 @@ void ChannelView::setSelection(const SelectionItem &start, const SelectionItem &
messages::MessageElement::Flags ChannelView::getFlags() const
{
if (this->overrideFlags) {
return this->overrideFlags.get();
}
MessageElement::Flags flags = singletons::SettingManager::getInstance().getWordFlags();
Split *split = dynamic_cast<Split *>(this->parentWidget());
@@ -442,6 +476,9 @@ messages::MessageElement::Flags ChannelView::getFlags() const
if (split->getModerationMode()) {
flags = (MessageElement::Flags)(flags | MessageElement::ModeratorTools);
}
if (this->channel == singletons::ChannelManager::getInstance().mentionsChannel) {
flags = (MessageElement::Flags)(flags | MessageElement::ChannelName);
}
}
return flags;
@@ -477,11 +514,17 @@ void ChannelView::drawMessages(QPainter &painter)
(fmod(this->scrollBar.getCurrentValue(), 1)));
messages::MessageLayout *end = nullptr;
bool windowFocused = this->window() == QApplication::activeWindow();
for (size_t i = start; i < messagesSnapshot.getLength(); ++i) {
messages::MessageLayout *layout = messagesSnapshot[i].get();
layout->paint(painter, y, i, this->selection);
bool isLastMessage = false;
if (singletons::SettingManager::getInstance().showLastMessageIndicator) {
isLastMessage = this->lastReadMessage.get() == layout;
}
layout->paint(painter, y, i, this->selection, isLastMessage, windowFocused);
y += layout->getHeight();
@@ -551,8 +594,7 @@ void ChannelView::wheelEvent(QWheelEvent *event)
if (i == 0) {
desired = 0;
} else {
snapshot[i - 1]->layout(LAYOUT_WIDTH, this->getDpiMultiplier(),
this->getFlags());
snapshot[i - 1]->layout(LAYOUT_WIDTH, this->getScale(), this->getFlags());
scrollFactor = 1;
currentScrollLeft = snapshot[i - 1]->getHeight();
}
@@ -574,8 +616,7 @@ void ChannelView::wheelEvent(QWheelEvent *event)
if (i == snapshotLength - 1) {
desired = snapshot.getLength();
} else {
snapshot[i + 1]->layout(LAYOUT_WIDTH, this->getDpiMultiplier(),
this->getFlags());
snapshot[i + 1]->layout(LAYOUT_WIDTH, this->getScale(), this->getFlags());
scrollFactor = 1;
currentScrollLeft = snapshot[i + 1]->getHeight();
@@ -782,12 +823,50 @@ void ChannelView::mouseReleaseEvent(QMouseEvent *event)
}
auto &link = hoverLayoutElement->getLink();
if (event->button() != Qt::LeftButton ||
!singletons::SettingManager::getInstance().linksDoubleClickOnly) {
this->handleLinkClick(event, link, layout.get());
}
this->linkClicked.invoke(link);
}
void ChannelView::mouseDoubleClickEvent(QMouseEvent *event)
{
if (singletons::SettingManager::getInstance().linksDoubleClickOnly) {
std::shared_ptr<messages::MessageLayout> layout;
QPoint relativePos;
int messageIndex;
if (!tryGetMessageAt(event->pos(), layout, relativePos, messageIndex)) {
return;
}
// message under cursor is collapsed
if (layout->getFlags() & MessageLayout::Collapsed) {
return;
}
const messages::MessageLayoutElement *hoverLayoutElement =
layout->getElementAt(relativePos);
if (hoverLayoutElement == nullptr) {
return;
}
auto &link = hoverLayoutElement->getLink();
this->handleLinkClick(event, link, layout.get());
}
}
void ChannelView::handleLinkClick(QMouseEvent *event, const messages::Link &link,
messages::MessageLayout *layout)
{
switch (link.getType()) {
case messages::Link::UserInfo: {
auto user = link.getValue();
this->userPopupWidget.setName(user);
this->userPopupWidget.move(event->screenPos().toPoint());
this->userPopupWidget.moveTo(this, event->screenPos().toPoint());
this->userPopupWidget.show();
this->userPopupWidget.setFocus();
@@ -795,7 +874,24 @@ void ChannelView::mouseReleaseEvent(QMouseEvent *event)
break;
}
case messages::Link::Url: {
QDesktopServices::openUrl(QUrl(link.getValue()));
if (event->button() == Qt::RightButton) {
static QMenu *menu = nullptr;
static QString url;
if (menu == nullptr) {
menu = new QMenu;
menu->addAction("Open in browser",
[] { QDesktopServices::openUrl(QUrl(url)); });
menu->addAction("Copy to clipboard",
[] { QApplication::clipboard()->setText(url); });
}
url = link.getValue();
menu->move(QCursor::pos());
menu->show();
} else {
QDesktopServices::openUrl(QUrl(link.getValue()));
}
break;
}
case messages::Link::UserAction: {
+14 -2
View File
@@ -38,9 +38,12 @@ public:
void clearSelection();
void setEnableScrollingToBottom(bool);
bool getEnableScrollingToBottom() const;
void setOverrideFlags(boost::optional<messages::MessageElement::Flags> value);
const boost::optional<messages::MessageElement::Flags> &getOverrideFlags() const;
void pause(int msecTimeout);
void updateLastReadMessage();
void setChannel(SharedChannel channel);
void setChannel(ChannelPtr channel);
messages::LimitedQueueSnapshot<messages::MessageLayoutPtr> getMessagesSnapshot();
void layoutMessages();
@@ -49,8 +52,11 @@ public:
boost::signals2::signal<void(QMouseEvent *)> mouseDown;
boost::signals2::signal<void()> selectionChanged;
pajlada::Signals::NoArgSignal highlightedMessageReceived;
pajlada::Signals::Signal<const messages::Link &> linkClicked;
protected:
virtual void themeRefreshEvent() override;
virtual void resizeEvent(QResizeEvent *) override;
virtual void paintEvent(QPaintEvent *) override;
@@ -62,6 +68,10 @@ protected:
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
void handleLinkClick(QMouseEvent *event, const messages::Link &link,
messages::MessageLayout *layout);
bool tryGetMessageAt(QPoint p, std::shared_ptr<messages::MessageLayout> &message,
QPoint &relativePos, int &index);
@@ -72,6 +82,8 @@ private:
bool messageWasAdded = false;
bool paused = false;
QTimer pauseTimeout;
boost::optional<messages::MessageElement::Flags> overrideFlags;
messages::MessageLayoutPtr lastReadMessage;
messages::LimitedQueueSnapshot<messages::MessageLayoutPtr> snapshot;
@@ -82,7 +94,7 @@ private:
void setSelection(const messages::SelectionItem &start, const messages::SelectionItem &end);
messages::MessageElement::Flags getFlags() const;
SharedChannel channel;
ChannelPtr channel;
Scrollbar scrollBar;
RippleEffectLabel *goToBottom;
+78
View File
@@ -0,0 +1,78 @@
#include "label.hpp"
#include "singletons/fontmanager.hpp"
#include <QPainter>
namespace chatterino {
namespace widgets {
Label::Label(BaseWidget *parent)
: BaseWidget(parent)
{
singletons::FontManager::getInstance().fontChanged.connect(
[this]() { this->scaleChangedEvent(this->getScale()); });
}
const QString &Label::getText() const
{
return this->text;
}
void Label::setText(const QString &value)
{
this->text = value;
this->scaleChangedEvent(this->getScale());
}
FontStyle Label::getFontStyle() const
{
return this->fontStyle;
}
void Label::setFontStyle(FontStyle style)
{
this->fontStyle = style;
this->scaleChangedEvent(this->getScale());
}
void Label::scaleChangedEvent(float scale)
{
QFontMetrics metrics =
singletons::FontManager::getInstance().getFontMetrics(this->fontStyle, scale);
this->preferedSize = QSize(metrics.width(this->text), metrics.height());
this->updateGeometry();
}
QSize Label::sizeHint() const
{
return this->preferedSize;
}
QSize Label::minimumSizeHint() const
{
return this->preferedSize;
}
void Label::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setFont(singletons::FontManager::getInstance().getFont(
this->fontStyle, this->getScale() / painter.device()->devicePixelRatioF()));
int width = singletons::FontManager::getInstance()
.getFontMetrics(this->fontStyle, this->getScale())
.width(this->text);
int flags = Qt::TextSingleLine;
if (this->width() < width) {
flags |= Qt::AlignLeft | Qt::AlignVCenter;
} else {
flags |= Qt::AlignCenter;
}
painter.drawText(this->rect(), flags, this->text);
}
} // namespace widgets
} // namespace chatterino
+33
View File
@@ -0,0 +1,33 @@
#pragma once
#include "singletons/fontmanager.hpp"
#include "widgets/basewidget.hpp"
namespace chatterino {
namespace widgets {
class Label : public BaseWidget
{
public:
Label(BaseWidget *parent);
const QString &getText() const;
void setText(const QString &text);
FontStyle getFontStyle() const;
void setFontStyle(FontStyle style);
protected:
virtual void scaleChangedEvent(float scale) override;
virtual void paintEvent(QPaintEvent *event) override;
virtual QSize sizeHint() const override;
virtual QSize minimumSizeHint() const override;
private:
QSize preferedSize;
QString text;
FontStyle fontStyle = FontStyle::Medium;
};
} // namespace widgets
} // namespace chatterino
+47
View File
@@ -1,12 +1,16 @@
#include "widgets/helper/notebookbutton.hpp"
#include "singletons/thememanager.hpp"
#include "widgets/helper/rippleeffectbutton.hpp"
#include "widgets/notebook.hpp"
#include "widgets/splitcontainer.hpp"
#include <QMouseEvent>
#include <QPainter>
#include <QPainterPath>
#include <QRadialGradient>
#define nuuls nullptr
namespace chatterino {
namespace widgets {
@@ -14,6 +18,8 @@ NotebookButton::NotebookButton(BaseWidget *parent)
: RippleEffectButton(parent)
{
setMouseEffectColor(QColor(0, 0, 0));
this->setAcceptDrops(true);
}
void NotebookButton::paintEvent(QPaintEvent *)
@@ -97,5 +103,46 @@ void NotebookButton::mouseReleaseEvent(QMouseEvent *event)
RippleEffectButton::mouseReleaseEvent(event);
}
void NotebookButton::dragEnterEvent(QDragEnterEvent *event)
{
if (!event->mimeData()->hasFormat("chatterino/split"))
return;
event->acceptProposedAction();
auto e = new QMouseEvent(QMouseEvent::MouseButtonPress,
QPointF(this->width() / 2, this->height() / 2), Qt::LeftButton,
Qt::LeftButton, 0);
RippleEffectButton::mousePressEvent(e);
delete e;
}
void NotebookButton::dragLeaveEvent(QDragLeaveEvent *)
{
this->mouseDown = true;
this->update();
auto e = new QMouseEvent(QMouseEvent::MouseButtonRelease,
QPointF(this->width() / 2, this->height() / 2), Qt::LeftButton,
Qt::LeftButton, 0);
RippleEffectButton::mouseReleaseEvent(e);
delete e;
}
void NotebookButton::dropEvent(QDropEvent *event)
{
if (SplitContainer::isDraggingSplit) {
event->acceptProposedAction();
Notebook *notebook = dynamic_cast<Notebook *>(this->parentWidget());
if (notebook != nuuls) {
SplitContainer *tab = notebook->addNewPage();
SplitContainer::draggingSplit->setParent(tab);
tab->addToLayout(SplitContainer::draggingSplit);
}
}
}
} // namespace widgets
} // namespace chatterino
+5 -2
View File
@@ -21,8 +21,11 @@ public:
NotebookButton(BaseWidget *parent);
protected:
void paintEvent(QPaintEvent *) override;
void mouseReleaseEvent(QMouseEvent *event) override;
virtual void paintEvent(QPaintEvent *) override;
virtual void mouseReleaseEvent(QMouseEvent *) override;
virtual void dragEnterEvent(QDragEnterEvent *) override;
virtual void dragLeaveEvent(QDragLeaveEvent *) override;
virtual void dropEvent(QDropEvent *) override;
signals:
void clicked();
+17 -15
View File
@@ -25,7 +25,6 @@ NotebookTab::NotebookTab(Notebook *_notebook, const std::string &_uuid)
, useDefaultBehaviour(fS("{}/useDefaultBehaviour", this->settingRoot), true)
, menu(this)
{
this->calcSize();
this->setAcceptDrops(true);
this->positionChangedAnimation.setEasingCurve(QEasingCurve(QEasingCurve::InCubic));
@@ -65,22 +64,25 @@ NotebookTab::NotebookTab(Notebook *_notebook, const std::string &_uuid)
this->menu.addAction(enableHighlightsOnNewMessageAction);
connect(enableHighlightsOnNewMessageAction, &QAction::toggled, [this](bool newValue) {
QObject::connect(enableHighlightsOnNewMessageAction, &QAction::toggled, [this](bool newValue) {
debug::Log("New value is {}", newValue); //
});
}
void NotebookTab::calcSize()
void NotebookTab::themeRefreshEvent()
{
float scale = getDpiMultiplier();
this->update();
}
void NotebookTab::updateSize()
{
float scale = getScale();
QString qTitle(qS(this->title));
if (singletons::SettingManager::getInstance().hideTabX) {
this->resize(static_cast<int>((fontMetrics().width(qTitle) + 16) * scale),
static_cast<int>(24 * scale));
this->resize((int)((fontMetrics().width(qTitle) + 16) * scale), (int)(24 * scale));
} else {
this->resize(static_cast<int>((fontMetrics().width(qTitle) + 8 + 24) * scale),
static_cast<int>(24 * scale));
this->resize((int)((fontMetrics().width(qTitle) + 8 + 24) * scale), (int)(24 * scale));
}
if (this->parent() != nullptr) {
@@ -97,7 +99,7 @@ void NotebookTab::setTitle(const QString &newTitle)
{
this->title = newTitle.toStdString();
this->calcSize();
this->updateSize();
}
bool NotebookTab::isSelected() const
@@ -134,7 +136,7 @@ QRect NotebookTab::getDesiredRect() const
void NotebookTab::hideTabXChanged(bool)
{
this->calcSize();
this->updateSize();
this->update();
}
@@ -197,7 +199,7 @@ void NotebookTab::paintEvent(QPaintEvent *)
painter.setPen(colors.text);
// set area for text
float scale = this->getDpiMultiplier();
float scale = this->getScale();
int rectW = (settingManager.hideTabX ? 0 : static_cast<int>(16) * scale);
QRect rect(0, 0, this->width() - rectW, this->height());
@@ -291,14 +293,14 @@ void NotebookTab::mouseMoveEvent(QMouseEvent *event)
}
}
if (this->mouseDown && !this->getDesiredRect().contains(event->pos())) {
QPoint relPoint = this->mapToParent(event->pos());
QPoint relPoint = this->mapToParent(event->pos());
if (this->mouseDown && !this->getDesiredRect().contains(relPoint)) {
int index;
SplitContainer *clickedPage = notebook->tabAt(relPoint, index);
SplitContainer *clickedPage = notebook->tabAt(relPoint, index, this->width());
if (clickedPage != nullptr && clickedPage != this->page) {
this->notebook->rearrangePage(clickedPage, index);
this->notebook->rearrangePage(this->page, index);
}
}
}
+11 -9
View File
@@ -25,7 +25,7 @@ class NotebookTab : public BaseWidget
public:
explicit NotebookTab(Notebook *_notebook, const std::string &_uuid);
void calcSize();
void updateSize();
SplitContainer *page;
@@ -42,16 +42,18 @@ public:
void hideTabXChanged(bool);
protected:
void paintEvent(QPaintEvent *) override;
virtual void themeRefreshEvent() override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void enterEvent(QEvent *) override;
void leaveEvent(QEvent *) override;
virtual void paintEvent(QPaintEvent *) override;
void dragEnterEvent(QDragEnterEvent *event) override;
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void enterEvent(QEvent *) override;
virtual void leaveEvent(QEvent *) override;
void mouseMoveEvent(QMouseEvent *event) override;
virtual void dragEnterEvent(QDragEnterEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
private:
std::vector<pajlada::Signals::ScopedConnection> managedConnections;
@@ -80,7 +82,7 @@ private:
QRect getXRect()
{
float scale = this->getDpiMultiplier();
float scale = this->getScale();
return QRect(this->width() - static_cast<int>(20 * scale), static_cast<int>(4 * scale),
static_cast<int>(16 * scale), static_cast<int>(16 * scale));
}
+3 -1
View File
@@ -44,7 +44,7 @@ void RippleEffectButton::paintEvent(QPaintEvent *)
if (this->pixmap != nullptr) {
QRect rect = this->rect();
int xD = 6 * this->getDpiMultiplier();
int xD = 6 * this->getScale();
rect.moveLeft(xD);
rect.setRight(rect.right() - xD - xD);
@@ -57,6 +57,8 @@ void RippleEffectButton::paintEvent(QPaintEvent *)
void RippleEffectButton::fancyPaint(QPainter &painter)
{
painter.setRenderHint(QPainter::HighQualityAntialiasing);
painter.setRenderHint(QPainter::Antialiasing);
QColor c;
if (this->mouseEffectColor) {
+2 -2
View File
@@ -58,7 +58,7 @@ void SearchPopup::initLayout()
}
}
void SearchPopup::setChannel(SharedChannel channel)
void SearchPopup::setChannel(ChannelPtr channel)
{
this->snapshot = channel->getMessageSnapshot();
this->performSearch();
@@ -70,7 +70,7 @@ void SearchPopup::performSearch()
{
QString text = searchInput->text();
SharedChannel channel(new Channel("search"));
ChannelPtr channel(new Channel("search"));
for (size_t i = 0; i < this->snapshot.getLength(); i++) {
messages::MessagePtr message = this->snapshot[i];
+4 -3
View File
@@ -10,7 +10,8 @@ namespace widgets {
SettingsDialogTab::SettingsDialogTab(SettingsDialog *_dialog, settingspages::SettingsPage *_page,
QString imageFileName)
: dialog(_dialog)
: BaseWidget(_dialog)
, dialog(_dialog)
, page(_page)
{
this->ui.labelText = page->getName();
@@ -47,8 +48,8 @@ void SettingsDialogTab::paintEvent(QPaintEvent *)
this->style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
int a = (this->height() - 20) / 2;
QPixmap pixmap = this->ui.icon.pixmap(QSize(20, 20));
int a = (this->height() - (20 * this->getScale())) / 2;
QPixmap pixmap = this->ui.icon.pixmap(QSize(this->height() - a * 2, this->height() - a * 2));
painter.drawPixmap(a, a, pixmap);
+3 -1
View File
@@ -4,6 +4,8 @@
#include <QPaintEvent>
#include <QWidget>
#include "widgets/basewidget.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
@@ -12,7 +14,7 @@ class SettingsPage;
class SettingsDialog;
class SettingsDialogTab : public QWidget
class SettingsDialogTab : public BaseWidget
{
Q_OBJECT
+12 -6
View File
@@ -4,6 +4,7 @@
#include "twitch/twitchchannel.hpp"
#include "util/layoutcreator.hpp"
#include "util/urlfetch.hpp"
#include "widgets/helper/label.hpp"
#include "widgets/split.hpp"
#include "widgets/splitcontainer.hpp"
#include "widgets/tooltipwidget.hpp"
@@ -47,7 +48,9 @@ SplitHeader::SplitHeader(Split *_split)
layout->addStretch(1);
// channel name label
// auto title = layout.emplace<Label>(this).assign(&this->titleLabel);
auto title = layout.emplace<SignalLabel>().assign(&this->titleLabel);
title->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
title->setMouseTracking(true);
QObject::connect(this->titleLabel, &SignalLabel::mouseDoubleClick, this,
&SplitHeader::mouseDoubleClickEvent);
@@ -66,7 +69,8 @@ SplitHeader::SplitHeader(Split *_split)
// ---- misc
this->layout()->setMargin(0);
this->refreshTheme();
this->themeRefreshEvent();
this->scaleChangedEvent(this->getScale());
this->updateChannelText();
@@ -93,7 +97,7 @@ void SplitHeader::addDropdownItems(RippleEffectButton *label)
this->dropdownMenu.addSeparator();
#ifdef USEWEBENGINE
this->dropdownMenu.addAction("Start watching", this, [this]{
SharedChannel _channel = this->split->getChannel();
ChannelPtr _channel = this->split->getChannel();
twitch::TwitchChannel *tc = dynamic_cast<twitch::TwitchChannel *>(_channel.get());
if (tc != nullptr) {
@@ -133,13 +137,15 @@ void SplitHeader::initializeChannelSignals()
}
}
void SplitHeader::resizeEvent(QResizeEvent *event)
void SplitHeader::scaleChangedEvent(float scale)
{
int w = 28 * getDpiMultiplier();
int w = 28 * scale;
this->setFixedHeight(w);
this->dropdownButton->setFixedWidth(w);
this->moderationButton->setFixedWidth(w);
// this->titleLabel->setFont(
// singletons::FontManager::getInstance().getFont(FontStyle::Medium, scale));
}
void SplitHeader::updateChannelText()
@@ -180,7 +186,7 @@ void SplitHeader::updateModerationModeIcon()
: resourceManager.moderationmode_disabled->getPixmap());
bool modButtonVisible = false;
SharedChannel channel = this->split->getChannel();
ChannelPtr channel = this->split->getChannel();
twitch::TwitchChannel *tc = dynamic_cast<twitch::TwitchChannel *>(channel.get());
@@ -242,7 +248,7 @@ void SplitHeader::rightButtonClicked()
{
}
void SplitHeader::refreshTheme()
void SplitHeader::themeRefreshEvent()
{
QPalette palette;
palette.setColor(QPalette::Foreground, this->themeManager.splits.header.text);
+5 -3
View File
@@ -1,6 +1,7 @@
#pragma once
#include "widgets/basewidget.hpp"
#include "widgets/helper/label.hpp"
#include "widgets/helper/rippleeffectlabel.hpp"
#include "widgets/helper/signallabel.hpp"
@@ -34,12 +35,14 @@ public:
void updateModerationModeIcon();
protected:
virtual void scaleChangedEvent(float) override;
virtual void themeRefreshEvent() override;
virtual void paintEvent(QPaintEvent *) override;
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void leaveEvent(QEvent *event) override;
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
virtual void resizeEvent(QResizeEvent *event) override;
private:
Split *const split;
@@ -50,6 +53,7 @@ private:
boost::signals2::connection onlineStatusChangedConnection;
RippleEffectButton *dropdownButton;
// Label *titleLabel;
SignalLabel *titleLabel;
RippleEffectButton *moderationButton;
@@ -57,8 +61,6 @@ private:
void rightButtonClicked();
virtual void refreshTheme() override;
void initializeChannelSignals();
QString tooltip;
+111 -75
View File
@@ -4,6 +4,7 @@
#include "singletons/ircmanager.hpp"
#include "singletons/settingsmanager.hpp"
#include "singletons/thememanager.hpp"
#include "util/layoutcreator.hpp"
#include "widgets/notebook.hpp"
#include "widgets/split.hpp"
#include "widgets/splitcontainer.hpp"
@@ -17,68 +18,124 @@ namespace widgets {
SplitInput::SplitInput(Split *_chatWidget)
: BaseWidget(_chatWidget)
, chatWidget(_chatWidget)
, emotesLabel(this)
{
this->setLayout(&this->hbox);
this->initLayout();
this->hbox.setMargin(4);
// auto completion
auto completer = new QCompleter(
singletons::CompletionManager::getInstance().createModel(this->chatWidget->channelName));
this->hbox.addLayout(&this->editContainer);
this->hbox.addLayout(&this->vbox);
this->ui.textEdit->setCompleter(completer);
// misc
this->installKeyPressedEvent();
this->themeRefreshEvent();
this->scaleChangedEvent(this->getScale());
}
void SplitInput::initLayout()
{
auto &fontManager = singletons::FontManager::getInstance();
util::LayoutCreator<SplitInput> layoutCreator(this);
auto layout = layoutCreator.setLayoutType<QHBoxLayout>().withoutMargin().assign(&this->ui.hbox);
// input
auto textEdit = layout.emplace<ResizingTextEdit>().assign(&this->ui.textEdit);
connect(textEdit.getElement(), &ResizingTextEdit::textChanged, this,
&SplitInput::editTextChanged);
// right box
auto box = layout.emplace<QVBoxLayout>().withoutMargin();
box->setSpacing(0);
{
auto textEditLength = box.emplace<QLabel>().assign(&this->ui.textEditLength);
textEditLength->setAlignment(Qt::AlignRight);
box->addStretch(1);
box.emplace<RippleEffectLabel>().assign(&this->ui.emoteButton);
}
this->ui.emoteButton->getLabel().setTextFormat(Qt::RichText);
// ---- misc
// set edit font
this->ui.textEdit->setFont(
fontManager.getFont(singletons::FontManager::Type::Medium, this->getScale()));
this->textInput.setFont(
fontManager.getFont(singletons::FontManager::Type::Medium, this->getDpiMultiplier()));
this->managedConnections.emplace_back(fontManager.fontChanged.connect([this, &fontManager]() {
this->textInput.setFont(
fontManager.getFont(singletons::FontManager::Type::Medium, this->getDpiMultiplier()));
this->ui.textEdit->setFont(
fontManager.getFont(singletons::FontManager::Type::Medium, this->getScale()));
}));
this->editContainer.addWidget(&this->textInput);
this->editContainer.setMargin(2);
this->emotesLabel.setMinimumHeight(24);
this->vbox.addWidget(&this->textLengthLabel);
this->vbox.addStretch(1);
this->vbox.addWidget(&this->emotesLabel);
this->textLengthLabel.setText("");
this->textLengthLabel.setAlignment(Qt::AlignRight);
this->emotesLabel.getLabel().setTextFormat(Qt::RichText);
this->emotesLabel.getLabel().setText("<img src=':/images/emote.svg' width='12' height='12' "
"/>");
connect(&this->emotesLabel, &RippleEffectLabel::clicked, [this] {
if (this->emotePopup == nullptr) {
this->emotePopup = new EmotePopup(this->themeManager);
// open emote popup
QObject::connect(this->ui.emoteButton, &RippleEffectLabel::clicked, [this] {
if (!this->emotePopup) {
this->emotePopup = std::make_unique<EmotePopup>(this->themeManager);
this->emotePopup->linkClicked.connect([this](const messages::Link &link) {
if (link.getType() == messages::Link::InsertText) {
this->insertText(link.getValue() + " ");
}
});
}
this->emotePopup->resize((int)(300 * this->emotePopup->getDpiMultiplier()),
(int)(500 * this->emotePopup->getDpiMultiplier()));
this->emotePopup->resize((int)(300 * this->emotePopup->getScale()),
(int)(500 * this->emotePopup->getScale()));
this->emotePopup->loadChannel(this->chatWidget->getChannel());
this->emotePopup->show();
});
connect(&textInput, &ResizingTextEdit::textChanged, this, &SplitInput::editTextChanged);
// clear channelview selection when selecting in the input
QObject::connect(this->ui.textEdit, &QTextEdit::copyAvailable, [this](bool available) {
if (available) {
this->chatWidget->view.clearSelection();
}
});
this->refreshTheme();
textLengthLabel.setHidden(!singletons::SettingManager::getInstance().showMessageLength);
// textEditLength visibility
singletons::SettingManager::getInstance().showMessageLength.connect(
[this](const bool &value, auto) { this->ui.textEditLength->setHidden(!value); },
this->managedConnections);
}
auto completer = new QCompleter(
singletons::CompletionManager::getInstance().createModel(this->chatWidget->channelName));
void SplitInput::scaleChangedEvent(float scale)
{
// update the icon size of the emote button
QString text = "<img src=':/images/emote.svg' width='xD' height='xD' />";
text.replace("xD", QString::number((int)12 * scale));
this->textInput.setCompleter(completer);
this->ui.emoteButton->getLabel().setText(text);
this->ui.emoteButton->setFixedHeight((int)18 * scale);
this->textInput.keyPressed.connect([this](QKeyEvent *event) {
// set maximum height
this->setMaximumHeight((int)(150 * this->getScale()));
this->themeRefreshEvent();
}
void SplitInput::themeRefreshEvent()
{
QPalette palette;
palette.setColor(QPalette::Foreground, this->themeManager.splits.input.text);
this->ui.textEditLength->setPalette(palette);
this->ui.textEdit->setStyleSheet(this->themeManager.splits.input.styleSheet);
this->ui.hbox->setMargin((this->themeManager.isLightTheme() ? 4 : 2) * this->getScale());
}
void SplitInput::installKeyPressedEvent()
{
this->ui.textEdit->keyPressed.connect([this](QKeyEvent *event) {
if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
auto c = this->chatWidget->getChannel();
if (c == nullptr) {
return;
}
QString message = textInput.toPlainText();
QString message = ui.textEdit->toPlainText();
QString sendMessage =
singletons::CommandManager::getInstance().execCommand(message, c, false);
@@ -89,9 +146,9 @@ SplitInput::SplitInput(Split *_chatWidget)
event->accept();
if (!(event->modifiers() == Qt::ControlModifier)) {
this->textInput.setText(QString());
this->ui.textEdit->setText(QString());
this->prevIndex = 0;
} else if (this->textInput.toPlainText() ==
} else if (this->ui.textEdit->toPlainText() ==
this->prevMsg.at(this->prevMsg.size() - 1)) {
this->prevMsg.removeLast();
}
@@ -110,7 +167,7 @@ SplitInput::SplitInput(Split *_chatWidget)
} else {
if (this->prevMsg.size() && this->prevIndex) {
this->prevIndex--;
this->textInput.setText(this->prevMsg.at(this->prevIndex));
this->ui.textEdit->setText(this->prevMsg.at(this->prevIndex));
}
}
} else if (event->key() == Qt::Key_Down) {
@@ -128,10 +185,10 @@ SplitInput::SplitInput(Split *_chatWidget)
if (this->prevIndex != (this->prevMsg.size() - 1) &&
this->prevIndex != this->prevMsg.size()) {
this->prevIndex++;
this->textInput.setText(this->prevMsg.at(this->prevIndex));
this->ui.textEdit->setText(this->prevMsg.at(this->prevIndex));
} else {
this->prevIndex = this->prevMsg.size();
this->textInput.setText(QString());
this->ui.textEdit->setText(QString());
}
}
} else if (event->key() == Qt::Key_Left) {
@@ -183,49 +240,32 @@ SplitInput::SplitInput(Split *_chatWidget)
}
}
});
singletons::SettingManager::getInstance().showMessageLength.connect(
[this](const bool &value, auto) { this->textLengthLabel.setHidden(!value); },
this->managedConnections);
QObject::connect(&this->textInput, &QTextEdit::copyAvailable, [this](bool available) {
if (available) {
this->chatWidget->view.clearSelection();
}
});
}
void SplitInput::clearSelection()
{
QTextCursor c = this->textInput.textCursor();
QTextCursor c = this->ui.textEdit->textCursor();
c.setPosition(c.position());
c.setPosition(c.position(), QTextCursor::KeepAnchor);
this->textInput.setTextCursor(c);
this->ui.textEdit->setTextCursor(c);
}
QString SplitInput::getInputText() const
{
return this->textInput.toPlainText();
return this->ui.textEdit->toPlainText();
}
void SplitInput::refreshTheme()
void SplitInput::insertText(const QString &text)
{
QPalette palette;
palette.setColor(QPalette::Foreground, this->themeManager.splits.input.text);
this->textLengthLabel.setPalette(palette);
this->textInput.setStyleSheet(this->themeManager.splits.input.styleSheet);
this->hbox.setMargin((this->themeManager.isLightTheme() ? 4 : 2) * this->getDpiMultiplier());
this->ui.textEdit->insertPlainText(text);
}
void SplitInput::editTextChanged()
{
QString text = this->textInput.toPlainText();
// set textLengthLabel value
QString text = this->ui.textEdit->toPlainText();
this->textChanged.invoke(text);
@@ -244,7 +284,7 @@ void SplitInput::editTextChanged()
labelText = QString::number(text.length());
}
this->textLengthLabel.setText(labelText);
this->ui.textEditLength->setText(labelText);
}
void SplitInput::paintEvent(QPaintEvent *)
@@ -255,7 +295,7 @@ void SplitInput::paintEvent(QPaintEvent *)
QPen pen(this->themeManager.splits.input.border);
if (this->themeManager.isLightTheme()) {
pen.setWidth((int)(6 * this->getDpiMultiplier()));
pen.setWidth((int)(6 * this->getScale()));
}
painter.setPen(pen);
painter.drawRect(0, 0, this->width() - 1, this->height() - 1);
@@ -264,14 +304,10 @@ void SplitInput::paintEvent(QPaintEvent *)
void SplitInput::resizeEvent(QResizeEvent *)
{
if (this->height() == this->maximumHeight()) {
this->textInput.setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
this->ui.textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
} else {
this->textInput.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
this->ui.textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}
this->setMaximumHeight((int)(150 * this->getDpiMultiplier()));
this->refreshTheme();
}
void SplitInput::mousePressEvent(QMouseEvent *)
+22 -8
View File
@@ -27,10 +27,13 @@ public:
void clearSelection();
QString getInputText() const;
void insertText(const QString &text);
pajlada::Signals::Signal<const QString &> textChanged;
protected:
virtual void scaleChangedEvent(float scale) override;
virtual void paintEvent(QPaintEvent *) override;
virtual void resizeEvent(QResizeEvent *) override;
@@ -38,18 +41,29 @@ protected:
private:
Split *const chatWidget;
EmotePopup *emotePopup = nullptr;
std::unique_ptr<EmotePopup> emotePopup;
struct {
ResizingTextEdit *textEdit;
QLabel *textEditLength;
RippleEffectLabel *emoteButton;
QHBoxLayout *hbox;
} ui;
std::vector<pajlada::Signals::ScopedConnection> managedConnections;
QHBoxLayout hbox;
QVBoxLayout vbox;
QHBoxLayout editContainer;
ResizingTextEdit textInput;
QLabel textLengthLabel;
RippleEffectLabel emotesLabel;
// QHBoxLayout hbox;
// QVBoxLayout vbox;
// QHBoxLayout editContainer;
// ResizingTextEdit textInput;
// QLabel textLengthLabel;
// RippleEffectLabel emotesLabel;
QStringList prevMsg;
int prevIndex = 0;
virtual void refreshTheme() override;
void initLayout();
void installKeyPressedEvent();
virtual void themeRefreshEvent() override;
private slots:
void editTextChanged();
+118
View File
@@ -0,0 +1,118 @@
#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::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
+24
View File
@@ -0,0 +1,24 @@
#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;
private:
Style style;
};
} // namespace widgets
} // namespace chatterino
+26 -32
View File
@@ -1,7 +1,7 @@
#include "widgets/notebook.hpp"
#include "debug/log.hpp"
#include "singletons/thememanager.hpp"
#include "widgets/accountswitchpopupwidget.hpp"
#include "singletons/windowmanager.hpp"
#include "widgets/helper/notebookbutton.hpp"
#include "widgets/helper/notebooktab.hpp"
#include "widgets/settingsdialog.hpp"
@@ -53,6 +53,8 @@ Notebook::Notebook(Window *parent, bool _showButtons, const std::string &setting
closeConfirmDialog.setIcon(QMessageBox::Icon::Question);
closeConfirmDialog.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
closeConfirmDialog.setDefaultButton(QMessageBox::Yes);
this->scaleChangedEvent(this->getScale());
}
SplitContainer *Notebook::addNewPage()
@@ -130,6 +132,9 @@ void Notebook::select(SplitContainer *page)
if (this->selectedPage != nullptr) {
this->selectedPage->setHidden(true);
this->selectedPage->getTab()->setSelected(false);
for (auto split : this->selectedPage->getSplits()) {
split->updateLastReadMessage();
}
}
this->selectedPage = page;
@@ -151,12 +156,15 @@ int Notebook::tabCount()
return this->pages.size();
}
SplitContainer *Notebook::tabAt(QPoint point, int &index)
SplitContainer *Notebook::tabAt(QPoint point, int &index, int maxWidth)
{
int i = 0;
for (auto *page : this->pages) {
if (page->getTab()->getDesiredRect().contains(point)) {
QRect rect = page->getTab()->getDesiredRect();
rect.setWidth(std::min(maxWidth, rect.width()));
if (rect.contains(point)) {
index = i;
return page;
}
@@ -206,7 +214,7 @@ void Notebook::performLayout(bool animated)
singletons::SettingManager &settings = singletons::SettingManager::getInstance();
int x = 0, y = 0;
float scale = this->getDpiMultiplier();
float scale = this->getScale();
bool customFrame = this->parentWindow->hasCustomWindowFrame();
if (!this->showButtons || settings.hidePreferencesButton || customFrame) {
@@ -250,51 +258,37 @@ void Notebook::performLayout(bool animated)
if (this->selectedPage != nullptr) {
this->selectedPage->move(0, y + tabHeight);
this->selectedPage->resize(width(), height() - y - tabHeight);
this->selectedPage->raise();
}
}
void Notebook::resizeEvent(QResizeEvent *)
{
float scale = this->getDpiMultiplier();
this->performLayout(false);
}
this->settingsButton.resize(static_cast<int>(24 * scale), static_cast<int>(24 * scale));
this->userButton.resize(static_cast<int>(24 * scale), static_cast<int>(24 * scale));
this->addButton.resize(static_cast<int>(24 * scale), static_cast<int>(24 * scale));
void Notebook::scaleChangedEvent(float)
{
float h = 24 * this->getScale();
this->settingsButton.setFixedSize(h, h);
this->userButton.setFixedSize(h, h);
this->addButton.setFixedSize(h, h);
for (auto &i : this->pages) {
i->getTab()->calcSize();
i->getTab()->updateSize();
}
this->performLayout(false);
}
void Notebook::settingsButtonClicked()
{
QTimer::singleShot(80, [this] { SettingsDialog::showDialog(); });
singletons::WindowManager::getInstance().showSettingsDialog();
}
void Notebook::usersButtonClicked()
{
static QWidget *lastFocusedWidget = nullptr;
static AccountSwitchPopupWidget *w = new AccountSwitchPopupWidget(this);
if (w->hasFocus()) {
w->hide();
if (lastFocusedWidget) {
lastFocusedWidget->setFocus();
}
return;
}
lastFocusedWidget = this->focusWidget();
w->refresh();
QPoint buttonPos = this->userButton.rect().bottomRight();
w->move(buttonPos.x(), buttonPos.y());
w->show();
w->setFocus();
singletons::WindowManager::getInstance().showAccountSelectPopup(
this->mapToGlobal(this->userButton.rect().bottomRight()));
}
void Notebook::addPageButtonClicked()
+2 -1
View File
@@ -41,13 +41,14 @@ public:
void performLayout(bool animate = true);
int tabCount();
SplitContainer *tabAt(QPoint point, int &index);
SplitContainer *tabAt(QPoint point, int &index, int maxWidth = 2000000000);
void rearrangePage(SplitContainer *page, int index);
void nextTab();
void previousTab();
protected:
void scaleChangedEvent(float scale);
void resizeEvent(QResizeEvent *);
void settingsButtonMouseReleased(QMouseEvent *event);
+4 -4
View File
@@ -18,7 +18,7 @@ Scrollbar::Scrollbar(ChannelView *parent)
, currentValueAnimation(this, "currentValue")
, smoothScrollingSetting(singletons::SettingManager::getInstance().enableSmoothScrolling)
{
resize((int)(16 * this->getDpiMultiplier()), 100);
resize((int)(16 * this->getScale()), 100);
this->currentValueAnimation.setDuration(150);
this->currentValueAnimation.setEasingCurve(QEasingCurve(QEasingCurve::OutCubic));
@@ -29,7 +29,7 @@ Scrollbar::Scrollbar(ChannelView *parent)
timer->setSingleShot(true);
connect(timer, &QTimer::timeout, [=]() {
resize((int)(16 * this->getDpiMultiplier()), 100);
resize((int)(16 * this->getScale()), 100);
timer->deleteLater();
});
@@ -194,7 +194,7 @@ void Scrollbar::printCurrentState(const QString &prefix) const
void Scrollbar::paintEvent(QPaintEvent *)
{
bool mouseOver = this->mouseOverIndex != -1;
int xOffset = mouseOver ? 0 : width() - (int)(4 * this->getDpiMultiplier());
int xOffset = mouseOver ? 0 : width() - (int)(4 * this->getScale());
QPainter painter(this);
// painter.fillRect(rect(), this->themeManager.ScrollbarBG);
@@ -248,7 +248,7 @@ void Scrollbar::paintEvent(QPaintEvent *)
void Scrollbar::resizeEvent(QResizeEvent *)
{
this->resize((int)(16 * this->getDpiMultiplier()), this->height());
this->resize((int)(16 * this->getScale()), this->height());
}
void Scrollbar::mouseMoveEvent(QMouseEvent *event)
+17 -3
View File
@@ -8,8 +8,12 @@
#include "widgets/settingspages/commandpage.hpp"
#include "widgets/settingspages/emotespage.hpp"
#include "widgets/settingspages/highlightingpage.hpp"
#include "widgets/settingspages/ignoremessagespage.hpp"
#include "widgets/settingspages/ignoreuserspage.hpp"
#include "widgets/settingspages/keyboardsettingspage.hpp"
#include "widgets/settingspages/logspage.hpp"
#include "widgets/settingspages/moderationpage.hpp"
#include "widgets/settingspages/specialchannelspage.hpp"
#include <QDialogButtonBox>
@@ -25,7 +29,7 @@ SettingsDialog::SettingsDialog()
this->addTabs();
this->dpiMultiplierChanged(this->getDpiMultiplier(), this->getDpiMultiplier());
this->scaleChangedEvent(this->getScale());
}
void SettingsDialog::initUi()
@@ -72,14 +76,24 @@ SettingsDialog *SettingsDialog::getHandle()
void SettingsDialog::addTabs()
{
this->ui.tabContainer->setSpacing(0);
this->addTab(new settingspages::AccountsPage);
this->addTab(new settingspages::AppearancePage);
this->addTab(new settingspages::BehaviourPage);
this->addTab(new settingspages::CommandPage);
this->addTab(new settingspages::EmotesPage);
this->addTab(new settingspages::HighlightingPage);
// this->addTab(new settingspages::LogsPage);
this->ui.tabContainer->addStretch(1);
this->addTab(new settingspages::IgnoreMessagesPage);
this->addTab(new settingspages::IgnoreUsersPage);
this->addTab(new settingspages::KeyboardSettingsPage);
this->addTab(new settingspages::LogsPage);
this->addTab(new settingspages::ModerationPage);
this->addTab(new settingspages::SpecialChannelsPage);
this->ui.tabContainer->addStretch(1);
this->addTab(new settingspages::AboutPage, Qt::AlignBottom);
}
@@ -135,7 +149,7 @@ void SettingsDialog::refresh()
singletons::SettingManager::getInstance().saveSnapshot();
}
void SettingsDialog::dpiMultiplierChanged(float oldDpi, float newDpi)
void SettingsDialog::scaleChangedEvent(float newDpi)
{
QFile file(":/qss/settings.qss");
file.open(QFile::ReadOnly);
+1 -1
View File
@@ -32,7 +32,7 @@ public:
static void showDialog(PreferredTab preferredTab = PreferredTab::NoPreference);
protected:
virtual void dpiMultiplierChanged(float oldDpi, float newDpi) override;
virtual void scaleChangedEvent(float newDpi) override;
private:
void refresh();
+5 -2
View File
@@ -44,8 +44,10 @@ AppearancePage::AppearancePage()
form->addRow("Font:", this->createFontChanger());
form->addRow("Tab bar:", this->createCheckBox(TAB_X, settings.hideTabX));
#ifndef USEWINSDK
form->addRow("", this->createCheckBox(TAB_PREF, settings.hidePreferencesButton));
form->addRow("", this->createCheckBox(TAB_USER, settings.hideUserButton));
#endif
form->addRow("Scrolling:", this->createCheckBox(SCROLL_SMOOTH, settings.enableSmoothScrolling));
form->addRow("", this->createCheckBox(SCROLL_NEWMSG, settings.enableSmoothScrollingNewMessages));
@@ -59,6 +61,7 @@ AppearancePage::AppearancePage()
{
tbox.emplace<QLabel>("timestamp format (a = am/pm):");
tbox.append(this->createComboBox({TIMESTAMP_FORMATS}, settings.timestampFormat));
tbox->addStretch(1);
}
messages.append(this->createCheckBox("Show badges", settings.showBadges));
messages.append(this->createCheckBox("Seperate messages", settings.seperateMessages));
@@ -77,7 +80,7 @@ QLayout *AppearancePage::createThemeColorChanger()
// SLIDER
QSlider *slider = new QSlider(Qt::Horizontal);
layout->addWidget(slider);
slider->setValue(std::min(std::max(themeHue.getValue(), 0.0), 1.0) * 1000);
slider->setValue(std::min(std::max(themeHue.getValue(), 0.0), 1.0) * 100);
// BUTTON
QPushButton *button = new QPushButton;
@@ -87,7 +90,7 @@ QLayout *AppearancePage::createThemeColorChanger()
// SIGNALS
QObject::connect(slider, &QSlider::valueChanged, this, [button, &themeHue](int value) mutable {
double newValue = value / 1000.0;
double newValue = value / 100.0;
themeHue.setValue(newValue);
+19 -5
View File
@@ -1,6 +1,7 @@
#include "behaviourpage.hpp"
#include <QFormLayout>
#include <QGroupBox>
#include <QLabel>
#include <QVBoxLayout>
@@ -8,7 +9,7 @@
#define WINDOW_TOPMOST "Window always on top (requires restart)"
#define INPUT_EMPTY "Hide input box when empty"
#define LAST_MSG "Show last read message indicator"
#define LAST_MSG "Show last read message indicator (marks the spot where you left the window)"
#define PAUSE_HOVERING "When hovering"
#define STREAMLINK_QUALITY "Choose", "Source", "High", "Medium", "Low", "Audio only"
@@ -22,7 +23,9 @@ BehaviourPage::BehaviourPage()
singletons::SettingManager &settings = singletons::SettingManager::getInstance();
util::LayoutCreator<BehaviourPage> layoutCreator(this);
auto form = layoutCreator.emplace<QFormLayout>().withoutMargin();
auto layout = layoutCreator.setLayoutType<QVBoxLayout>();
auto form = layout.emplace<QFormLayout>().withoutMargin();
{
form->addRow("Window:", this->createCheckBox(WINDOW_TOPMOST, settings.windowTopMost));
form->addRow("Messages:", this->createCheckBox(INPUT_EMPTY, settings.hideEmptyInput));
@@ -30,10 +33,21 @@ BehaviourPage::BehaviourPage()
form->addRow("Pause chat:", this->createCheckBox(PAUSE_HOVERING, settings.pauseChatHover));
form->addRow("Mouse scroll speed:", this->createMouseScrollSlider());
form->addRow("Streamlink path:", this->createLineEdit(settings.streamlinkPath));
form->addRow("Prefered quality:",
this->createComboBox({STREAMLINK_QUALITY}, settings.preferredQuality));
form->addRow("Links:", this->createCheckBox("Open links only on double click",
settings.linksDoubleClickOnly));
}
layout->addSpacing(16);
auto group = layout.emplace<QGroupBox>("Streamlink");
{
auto groupLayout = group.setLayoutType<QFormLayout>();
groupLayout->addRow("Streamlink path:", this->createLineEdit(settings.streamlinkPath));
groupLayout->addRow("Prefered quality:",
this->createComboBox({STREAMLINK_QUALITY}, settings.preferredQuality));
}
layout->addStretch(1);
}
QSlider *BehaviourPage::createMouseScrollSlider()
@@ -0,0 +1,37 @@
#include "ignoremessagespage.hpp"
#include "util/layoutcreator.hpp"
#include <QLabel>
#include <QTextEdit>
namespace chatterino {
namespace widgets {
namespace settingspages {
IgnoreMessagesPage::IgnoreMessagesPage()
: SettingsPage("Ignore Messages", "")
{
singletons::SettingManager &settings = singletons::SettingManager::getInstance();
util::LayoutCreator<IgnoreMessagesPage> layoutCreator(this);
auto layout = layoutCreator.setLayoutType<QVBoxLayout>();
layout.emplace<QLabel>("Ignored keywords:");
QTextEdit *textEdit = layout.emplace<QTextEdit>().getElement();
textEdit->setPlainText(settings.ignoredKeywords);
QObject::connect(textEdit, &QTextEdit::textChanged,
[this] { this->keywordsUpdated.start(200); });
QObject::connect(&this->keywordsUpdated, &QTimer::timeout, [textEdit, &settings] {
QString text = textEdit->toPlainText();
settings.ignoredKeywords = text;
});
// ---- misc
this->keywordsUpdated.setSingleShot(true);
}
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,19 @@
#pragma once
#include <QTimer>
#include "widgets/settingspages/settingspage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
class IgnoreMessagesPage : public SettingsPage
{
public:
IgnoreMessagesPage();
QTimer keywordsUpdated;
};
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,55 @@
#include "ignoreuserspage.hpp"
#include "singletons/settingsmanager.hpp"
#include "util/layoutcreator.hpp"
#include <QCheckBox>
#include <QGroupBox>
#include <QLabel>
#include <QListView>
#include <QPushButton>
#include <QVBoxLayout>
// clang-format off
#define INFO "/ignore <user> in chat ignores a user\n/unignore <user> in chat unignores a user\n\nChatterino uses the twitch api for ignored users so they are shared with the webchat.\nIf you use your own oauth key make sure that it has the correct permissions.\n"
// clang-format on
namespace chatterino {
namespace widgets {
namespace settingspages {
IgnoreUsersPage::IgnoreUsersPage()
: SettingsPage("Ignore Users", "")
{
singletons::SettingManager &settings = singletons::SettingManager::getInstance();
util::LayoutCreator<IgnoreUsersPage> layoutCreator(this);
auto layout = layoutCreator.setLayoutType<QVBoxLayout>();
auto label = layout.emplace<QLabel>(INFO);
label->setWordWrap(true);
label->setStyleSheet("color: #BBB");
auto group = layout.emplace<QGroupBox>("Ignored users").setLayoutType<QVBoxLayout>();
{
group.append(
this->createCheckBox("Enable twitch ignored users", settings.enableTwitchIgnoredUsers));
auto anyways = group.emplace<QHBoxLayout>().withoutMargin();
{
anyways.emplace<QLabel>("Show anyways if:");
anyways.emplace<QComboBox>();
anyways->addStretch(1);
}
auto addremove = group.emplace<QHBoxLayout>().withoutMargin();
{
auto add = addremove.emplace<QPushButton>("Ignore user");
auto remove = addremove.emplace<QPushButton>("Unignore User");
addremove->addStretch(1);
}
auto userList = group.emplace<QListView>();
}
}
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,15 @@
#pragma once
#include "widgets/settingspages/settingspage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
class IgnoreUsersPage : public SettingsPage
{
public:
IgnoreUsersPage();
};
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,12 @@
#include "keyboardsettingspage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
KeyboardSettingsPage::KeyboardSettingsPage()
: SettingsPage("Keybindings", "")
{
}
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,15 @@
#pragma once
#include "widgets/settingspages/settingspage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
class KeyboardSettingsPage : public SettingsPage
{
public:
KeyboardSettingsPage();
};
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
+1 -1
View File
@@ -4,7 +4,7 @@ namespace chatterino {
namespace widgets {
namespace settingspages {
LogsPage::LogsPage()
: SettingsPage("Logs", ":/images/VSO_Link_blue_16x.png")
: SettingsPage("Logs", "")
{
}
} // namespace settingspages
+20 -8
View File
@@ -1,5 +1,6 @@
#include "moderationpage.hpp"
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QListView>
@@ -18,22 +19,33 @@ ModerationPage::ModerationPage()
singletons::SettingManager &settings = singletons::SettingManager::getInstance();
util::LayoutCreator<ModerationPage> layoutCreator(this);
auto layout = layoutCreator.emplace<QVBoxLayout>().withoutMargin();
auto layout = layoutCreator.setLayoutType<QVBoxLayout>();
{
// clang-format off
auto label = layout.emplace<QLabel>("In channels that you moderate there is a button <insert image of button here> to enable moderation mode.\n\nOne action per line. {user} will be replaced with the username.\nExample `/timeout {user} 120`");
auto label = layout.emplace<QLabel>("Click the moderation mod button (<img width='18' height='18' src=':/images/moderatormode_disabled.png'>) in a channel that you moderate to enable moderator mode.<br>");
label->setWordWrap(true);
label->setStyleSheet("color: #bbb");
// clang-format on
auto text = layout.emplace<QTextEdit>().getElement();
auto modButtons =
layout.emplace<QGroupBox>("Custom moderator buttons").setLayoutType<QVBoxLayout>();
{
auto label2 =
modButtons.emplace<QLabel>("One action per line. {user} will be replaced with the "
"username.<br>Example `/timeout {user} 120`<br>");
label2->setWordWrap(true);
text->setPlainText(settings.moderationActions);
auto text = modButtons.emplace<QTextEdit>().getElement();
QObject::connect(text, &QTextEdit::textChanged, this,
[this] { this->itemsChangedTimer.start(200); });
text->setPlainText(settings.moderationActions);
QObject::connect(&this->itemsChangedTimer, &QTimer::timeout, this,
[text, &settings]() { settings.moderationActions = text->toPlainText(); });
QObject::connect(text, &QTextEdit::textChanged, this,
[this] { this->itemsChangedTimer.start(200); });
QObject::connect(&this->itemsChangedTimer, &QTimer::timeout, this, [text, &settings]() {
settings.moderationActions = text->toPlainText();
});
}
}
// ---- misc
@@ -0,0 +1,28 @@
#include "specialchannelspage.hpp"
#include "singletons/settingsmanager.hpp"
#include "util/layoutcreator.hpp"
#include <QGroupBox>
#include <QLabel>
#include <QVBoxLayout>
namespace chatterino {
namespace widgets {
namespace settingspages {
SpecialChannelsPage::SpecialChannelsPage()
: SettingsPage("Special channels", "")
{
util::LayoutCreator<SpecialChannelsPage> layoutCreator(this);
auto layout = layoutCreator.setLayoutType<QVBoxLayout>();
auto mentions = layout.emplace<QGroupBox>("Mentions channel").setLayoutType<QVBoxLayout>();
{
mentions.emplace<QLabel>("Join /mentions to view your mentions.");
}
layout->addStretch(1);
}
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,15 @@
#pragma once
#include "widgets/settingspages/settingspage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
class SpecialChannelsPage : public SettingsPage
{
public:
SpecialChannelsPage();
};
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
+15 -10
View File
@@ -87,7 +87,7 @@ Split::Split(SplitContainer *parent, const std::string &_uuid)
this->channelNameUpdated(this->channelName.getValue());
this->input.textInput.installEventFilter(parent);
this->input.ui.textEdit->installEventFilter(parent);
this->view.mouseDown.connect([this](QMouseEvent *) { this->giveFocus(Qt::MouseFocusReason); });
this->view.selectionChanged.connect([this]() {
@@ -132,17 +132,17 @@ const std::string &Split::getUUID() const
return this->uuid;
}
SharedChannel Split::getChannel() const
ChannelPtr Split::getChannel() const
{
return this->channel;
}
SharedChannel &Split::getChannelRef()
ChannelPtr &Split::getChannelRef()
{
return this->channel;
}
void Split::setChannel(SharedChannel _newChannel)
void Split::setChannel(ChannelPtr _newChannel)
{
this->view.setChannel(_newChannel);
@@ -248,18 +248,22 @@ void Split::layoutMessages()
void Split::updateGifEmotes()
{
qDebug() << "this shouldn't even exist";
this->view.queueUpdate();
}
void Split::updateLastReadMessage()
{
this->view.updateLastReadMessage();
}
void Split::giveFocus(Qt::FocusReason reason)
{
this->input.textInput.setFocus(reason);
this->input.ui.textEdit->setFocus(reason);
}
bool Split::hasFocus() const
{
return this->input.textInput.hasFocus();
return this->input.ui.textEdit->hasFocus();
}
void Split::paintEvent(QPaintEvent *)
@@ -350,7 +354,7 @@ void Split::doClearChat()
void Split::doOpenChannel()
{
SharedChannel _channel = this->channel;
ChannelPtr _channel = this->channel;
twitch::TwitchChannel *tc = dynamic_cast<twitch::TwitchChannel *>(_channel.get());
if (tc != nullptr) {
@@ -360,7 +364,7 @@ void Split::doOpenChannel()
void Split::doOpenPopupPlayer()
{
SharedChannel _channel = this->channel;
ChannelPtr _channel = this->channel;
twitch::TwitchChannel *tc = dynamic_cast<twitch::TwitchChannel *>(_channel.get());
if (tc != nullptr) {
@@ -460,6 +464,7 @@ void Split::doOpenViewerList()
viewerDock->move(0, this->header.height());
auto accountPopup = new AccountPopupWidget(this->channel);
accountPopup->setAttribute(Qt::WA_DeleteOnClose);
auto multiWidget = new QWidget(viewerDock);
auto dockVbox = new QVBoxLayout(viewerDock);
auto searchBar = new QLineEdit(viewerDock);
@@ -538,9 +543,9 @@ void Split::doOpenViewerList()
void Split::doOpenAccountPopupWidget(AccountPopupWidget *widget, QString user)
{
widget->setName(user);
widget->move(QCursor::pos());
widget->show();
widget->setFocus();
widget->moveTo(this, QCursor::pos());
}
void Split::doCopy()
+5 -4
View File
@@ -55,8 +55,8 @@ public:
}
const std::string &getUUID() const;
SharedChannel getChannel() const;
SharedChannel &getChannelRef();
ChannelPtr getChannel() const;
ChannelPtr &getChannelRef();
void setFlexSizeX(double x);
double getFlexSizeX();
void setFlexSizeY(double y);
@@ -70,6 +70,7 @@ public:
bool hasFocus() const;
void layoutMessages();
void updateGifEmotes();
void updateLastReadMessage();
void drag();
@@ -82,7 +83,7 @@ protected:
private:
SplitContainer &parentPage;
SharedChannel channel;
ChannelPtr channel;
QVBoxLayout vbox;
SplitHeader header;
@@ -96,7 +97,7 @@ private:
boost::signals2::connection channelIDChangedConnection;
boost::signals2::connection usermodeChangedConnection;
void setChannel(SharedChannel newChannel);
void setChannel(ChannelPtr newChannel);
void doOpenAccountPopupWidget(AccountPopupWidget *widget, QString user);
void channelNameUpdated(const std::string &newChannelName);
void handleModifiers(QEvent *event, Qt::KeyboardModifiers modifiers);
+1 -1
View File
@@ -143,7 +143,7 @@ void SplitContainer::addToLayout(Split *widget, std::pair<int, int> position)
this->refreshCurrentFocusCoordinates();
}
const std::vector<Split *> &SplitContainer::getChatWidgets() const
const std::vector<Split *> &SplitContainer::getSplits() const
{
return this->splits;
}
+1 -1
View File
@@ -33,7 +33,7 @@ public:
std::pair<int, int> removeFromLayout(Split *widget);
void addToLayout(Split *widget, std::pair<int, int> position = std::pair<int, int>(-1, -1));
const std::vector<Split *> &getChatWidgets() const;
const std::vector<Split *> &getSplits() const;
NotebookTab *getTab() const;
void addChat(bool openChannelNameDialog = false, std::string chatUUID = std::string());
+1 -1
View File
@@ -11,7 +11,7 @@
namespace chatterino {
namespace widgets {
StreamView::StreamView(SharedChannel channel, QUrl url)
StreamView::StreamView(ChannelPtr channel, QUrl url)
{
util::LayoutCreator<StreamView> layoutCreator(this);
+3 -41
View File
@@ -17,6 +17,7 @@ TooltipWidget::TooltipWidget(BaseWidget *parent)
this->setStyleSheet("color: #fff; background: #000");
this->setWindowOpacity(0.8);
this->updateFont();
this->setStayInScreenRect(true);
this->setAttribute(Qt::WA_ShowWithoutActivating);
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint |
@@ -39,7 +40,7 @@ TooltipWidget::~TooltipWidget()
this->fontChangedConnection.disconnect();
}
void TooltipWidget::dpiMultiplierChanged(float, float)
void TooltipWidget::scaleChangedEvent(float)
{
this->updateFont();
}
@@ -47,7 +48,7 @@ void TooltipWidget::dpiMultiplierChanged(float, float)
void TooltipWidget::updateFont()
{
this->setFont(singletons::FontManager::getInstance().getFont(
singletons::FontManager::Type::MediumSmall, this->getDpiMultiplier()));
singletons::FontManager::Type::MediumSmall, this->getScale()));
}
void TooltipWidget::setText(QString text)
@@ -55,45 +56,6 @@ void TooltipWidget::setText(QString text)
this->displayText->setText(text);
}
void TooltipWidget::moveTo(QWidget *parent, QPoint point)
{
point.rx() += 16;
point.ry() += 16;
this->move(point);
this->moveIntoDesktopRect(parent);
}
void TooltipWidget::resizeEvent(QResizeEvent *)
{
this->moveIntoDesktopRect(this);
}
void TooltipWidget::moveIntoDesktopRect(QWidget *parent)
{
QDesktopWidget *desktop = QApplication::desktop();
QRect s = desktop->screenGeometry(parent);
QPoint p = this->pos();
if (p.x() < s.left()) {
p.setX(s.left());
}
if (p.y() < s.top()) {
p.setY(s.top());
}
if (p.x() + this->width() > s.right()) {
p.setX(s.right() - this->width());
}
if (p.y() + this->height() > s.bottom()) {
p.setY(s.bottom() - this->height());
}
if (p != this->pos()) {
this->move(p);
}
}
void TooltipWidget::changeEvent(QEvent *)
{
// clear parents event
+1 -4
View File
@@ -16,7 +16,6 @@ public:
~TooltipWidget();
void setText(QString text);
void moveTo(QWidget *widget, QPoint point);
static TooltipWidget *getInstance()
{
@@ -28,16 +27,14 @@ public:
}
protected:
virtual void resizeEvent(QResizeEvent *) override;
virtual void changeEvent(QEvent *) override;
virtual void leaveEvent(QEvent *) override;
virtual void dpiMultiplierChanged(float, float) override;
virtual void scaleChangedEvent(float) override;
private:
QLabel *displayText;
pajlada::Signals::Connection fontChangedConnection;
void moveIntoDesktopRect(QWidget *parent);
void updateFont();
};
+32 -5
View File
@@ -4,6 +4,8 @@
#include "singletons/ircmanager.hpp"
#include "singletons/settingsmanager.hpp"
#include "singletons/thememanager.hpp"
#include "singletons/windowmanager.hpp"
#include "widgets/accountswitchpopupwidget.hpp"
#include "widgets/helper/shortcut.hpp"
#include "widgets/notebook.hpp"
#include "widgets/settingsdialog.hpp"
@@ -21,7 +23,7 @@ Window::Window(const QString &windowName, singletons::ThemeManager &_themeManage
: BaseWindow(_themeManager, nullptr, true)
, settingRoot(fS("/windows/{}", windowName))
, windowGeometry(this->settingRoot)
, dpi(this->getDpiMultiplier())
, dpi(this->getScale())
, themeManager(_themeManager)
, notebook(this, _isMainWindow, this->settingRoot)
{
@@ -35,8 +37,12 @@ Window::Window(const QString &windowName, singletons::ThemeManager &_themeManage
});
if (this->hasCustomWindowFrame()) {
this->addTitleBarButton("Preferences");
this->addTitleBarButton("User");
this->addTitleBarButton(TitleBarButton::Settings, [] {
singletons::WindowManager::getInstance().showSettingsDialog();
});
this->addTitleBarButton(TitleBarButton::User, [this] {
singletons::WindowManager::getInstance().showAccountSelectPopup(QCursor::pos());
});
}
QVBoxLayout *layout = new QVBoxLayout(this);
@@ -52,7 +58,7 @@ Window::Window(const QString &windowName, singletons::ThemeManager &_themeManage
// set margin
layout->setMargin(0);
this->refreshTheme();
this->themeRefreshEvent();
this->loadGeometry();
@@ -107,7 +113,7 @@ void Window::repaintVisibleChatWidgets(Channel *channel)
return;
}
const std::vector<Split *> &widgets = page->getChatWidgets();
const std::vector<Split *> &widgets = page->getSplits();
for (auto it = widgets.begin(); it != widgets.end(); ++it) {
Split *widget = *it;
@@ -140,6 +146,27 @@ void Window::closeEvent(QCloseEvent *)
this->closed();
}
bool Window::event(QEvent *e)
{
switch (e->type()) {
case QEvent::WindowActivate:
break;
case QEvent::WindowDeactivate: {
auto page = this->notebook.getSelectedPage();
if (page != nullptr) {
std::vector<Split *> splits = page->getSplits();
for (Split *split : splits) {
split->updateLastReadMessage();
}
}
} break;
};
return BaseWindow::event(e);
}
void Window::loadGeometry()
{
bool doSetGeometry = false;
+1
View File
@@ -57,6 +57,7 @@ public:
protected:
virtual void closeEvent(QCloseEvent *event) override;
virtual bool event(QEvent *event) override;
private:
singletons::ThemeManager &themeManager;