From 9aa9b90267e438b81df4b74b6debe424bbe1bea0 Mon Sep 17 00:00:00 2001 From: fourtf Date: Fri, 25 May 2018 13:53:55 +0200 Subject: [PATCH] fixed /r and tab text alignment --- chatterino.pro | 3 +- src/channel.cpp | 5 ++ src/channel.hpp | 2 + src/providers/twitch/ircmessagehandler.cpp | 2 + src/providers/twitch/twitchchannel.hpp | 2 + src/providers/twitch/twitchserver.cpp | 14 +++++ src/providers/twitch/twitchserver.hpp | 10 ++++ src/util/mutexvalue.h | 40 ++++++++++++++ src/widgets/helper/notebooktab.cpp | 17 ++++-- src/widgets/helper/splitinput.cpp | 63 ++++++++++++---------- src/widgets/helper/splitinput.hpp | 2 +- src/widgets/window.cpp | 19 ++++--- src/widgets/window.hpp | 2 + 13 files changed, 140 insertions(+), 41 deletions(-) create mode 100644 src/util/mutexvalue.h diff --git a/chatterino.pro b/chatterino.pro index f99c77bf..a611e711 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -358,7 +358,8 @@ HEADERS += \ src/widgets/helper/splitoverlay.hpp \ src/widgets/helper/dropoverlay.hpp \ src/widgets/helper/splitnode.hpp \ - src/widgets/notificationpopup.hpp + src/widgets/notificationpopup.hpp \ + src/util/mutexvalue.h RESOURCES += \ resources/resources.qrc diff --git a/src/channel.cpp b/src/channel.cpp index 2e340665..5c264c83 100644 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -45,6 +45,11 @@ Channel::Type Channel::getType() const return this->type; } +bool Channel::isTwitchChannel() const +{ + return this->type >= Twitch && this->type < TwitchEnd; +} + bool Channel::isEmpty() const { return this->name.isEmpty(); diff --git a/src/channel.hpp b/src/channel.hpp index 91d2ad4f..7b6f1715 100644 --- a/src/channel.hpp +++ b/src/channel.hpp @@ -29,6 +29,7 @@ public: TwitchWhispers, TwitchWatching, TwitchMentions, + TwitchEnd, }; explicit Channel(const QString &_name, Type type); @@ -43,6 +44,7 @@ public: pajlada::Signals::NoArgSignal destroyed; Type getType() const; + bool isTwitchChannel() const; virtual bool isEmpty() const; messages::LimitedQueueSnapshot getMessageSnapshot(); diff --git a/src/providers/twitch/ircmessagehandler.cpp b/src/providers/twitch/ircmessagehandler.cpp index a8b22649..6fbb95b4 100644 --- a/src/providers/twitch/ircmessagehandler.cpp +++ b/src/providers/twitch/ircmessagehandler.cpp @@ -166,6 +166,8 @@ void IrcMessageHandler::handleWhisperMessage(Communi::IrcMessage *message) app->twitch.server->mentionsChannel->addMessage(_message); } + app->twitch.server->lastUserThatWhisperedMe.set(builder.userName); + c->addMessage(_message); if (app->settings->inlineWhispers) { diff --git a/src/providers/twitch/twitchchannel.hpp b/src/providers/twitch/twitchchannel.hpp index a594bdf7..8a8e5727 100644 --- a/src/providers/twitch/twitchchannel.hpp +++ b/src/providers/twitch/twitchchannel.hpp @@ -7,6 +7,7 @@ #include "singletons/emotemanager.hpp" #include "singletons/ircmanager.hpp" #include "util/concurrentmap.hpp" +#include "util/mutexvalue.h" #include @@ -78,6 +79,7 @@ public: pajlada::Signals::NoArgSignal roomModesChanged; QString roomID; + RoomModes getRoomModes(); void setRoomModes(const RoomModes &roomModes); diff --git a/src/providers/twitch/twitchserver.cpp b/src/providers/twitch/twitchserver.cpp index ab184535..9b10df7b 100644 --- a/src/providers/twitch/twitchserver.cpp +++ b/src/providers/twitch/twitchserver.cpp @@ -197,6 +197,20 @@ std::shared_ptr TwitchServer::getChannelOrEmptyByID(const QString &chan return Channel::getEmpty(); } +// QString TwitchServer::getLastWhisperedPerson() const +//{ +// std::lock_guard guard(this->lastWhisperedPersonMutex); + +// return this->lastWhisperedPerson; +//} + +// void TwitchServer::setLastWhisperedPerson(const QString &person) +//{ +// std::lock_guard guard(this->lastWhisperedPersonMutex); + +// this->lastWhisperedPerson = person; +//} + QString TwitchServer::cleanChannelName(const QString &dirtyChannelName) { return dirtyChannelName.toLower(); diff --git a/src/providers/twitch/twitchserver.hpp b/src/providers/twitch/twitchserver.hpp index 99852197..d143856e 100644 --- a/src/providers/twitch/twitchserver.hpp +++ b/src/providers/twitch/twitchserver.hpp @@ -3,6 +3,7 @@ #include "providers/irc/abstractircserver.hpp" #include "providers/twitch/twitchaccount.hpp" #include "providers/twitch/twitchchannel.hpp" +#include "util/mutexvalue.h" #include @@ -22,6 +23,11 @@ public: std::shared_ptr getChannelOrEmptyByID(const QString &channelID); + util::MutexValue lastUserThatWhisperedMe; + + // QString getLastWhisperedPerson() const; + // void setLastWhisperedPerson(const QString &person); + const ChannelPtr whispersChannel; const ChannelPtr mentionsChannel; IndirectChannel watchingChannel; @@ -38,6 +44,10 @@ protected: std::shared_ptr getCustomChannel(const QString &channelname) override; QString cleanChannelName(const QString &dirtyChannelName) override; + +private: + // mutable std::mutex lastWhisperedPersonMutex; + // QString lastWhisperedPerson; }; } // namespace twitch diff --git a/src/util/mutexvalue.h b/src/util/mutexvalue.h new file mode 100644 index 00000000..9b0f37a4 --- /dev/null +++ b/src/util/mutexvalue.h @@ -0,0 +1,40 @@ +#pragma once + +#include + +namespace chatterino { +namespace util { + +template +class MutexValue +{ + mutable std::mutex mutex; + T value; + +public: + MutexValue() + { + } + + MutexValue(T &&val) + : value(val) + { + } + + T get() const + { + std::lock_guard guard(this->mutex); + + return this->value; + } + + void set(const T &val) + { + std::lock_guard guard(this->mutex); + + this->value = val; + } +}; + +} // namespace util +} // namespace chatterino diff --git a/src/widgets/helper/notebooktab.cpp b/src/widgets/helper/notebooktab.cpp index 179cc47c..d992d4f7 100644 --- a/src/widgets/helper/notebooktab.cpp +++ b/src/widgets/helper/notebooktab.cpp @@ -86,7 +86,8 @@ void NotebookTab::updateSize() float scale = getScale(); int width; - QFontMetrics metrics = getApp()->fonts->getFontMetrics(FontStyle::UiTabs, this->getScale() * this->devicePixelRatioF()); + QFontMetrics metrics = getApp()->fonts->getFontMetrics( + FontStyle::UiTabs, this->getScale() * this->devicePixelRatioF()); if (this->hasXButton()) { width = (int)((metrics.width(this->title) + 32) * scale); @@ -189,8 +190,10 @@ void NotebookTab::paintEvent(QPaintEvent *) float scale = this->getScale(); painter.setFont(getApp()->fonts->getFont(FontStyle::UiTabs, scale * this->devicePixelRatioF())); + QFontMetrics metrics = + app->fonts->getFontMetrics(FontStyle::UiTabs, scale * this->devicePixelRatioF()); - int height = (int)(scale * NOTEBOOK_TAB_HEIGHT); + int height = int(scale * NOTEBOOK_TAB_HEIGHT); // int fullHeight = (int)(scale * 48); // select the right tab colors @@ -241,20 +244,24 @@ void NotebookTab::paintEvent(QPaintEvent *) painter.setPen(colors.text); // set area for text - int rectW = (!app->settings->showTabCloseButton ? 0 : static_cast(16) * scale); + int rectW = (!app->settings->showTabCloseButton ? 0 : int(16 * scale)); QRect rect(0, 0, this->width() - rectW, height); // draw text if (true) { // legacy // painter.drawText(rect, this->getTitle(), QTextOption(Qt::AlignCenter)); - int offset = (int)(scale * 8); + int offset = int(scale * 8); QRect textRect(offset, this->selected ? 1 : 2, this->width() - offset - offset, height); if (this->shouldDrawXButton()) { textRect.setRight(textRect.right() - this->height() / 2); } - QTextOption option(Qt::AlignHCenter | Qt::AlignVCenter); + int width = metrics.width(this->getTitle()); + Qt::Alignment alignment = width > textRect.width() ? Qt::AlignLeft | Qt::AlignVCenter + : Qt::AlignHCenter | Qt::AlignVCenter; + + QTextOption option(alignment); option.setWrapMode(QTextOption::NoWrap); painter.drawText(textRect, this->getTitle(), option); } else { diff --git a/src/widgets/helper/splitinput.cpp b/src/widgets/helper/splitinput.cpp index f08ddfc0..b0644473 100644 --- a/src/widgets/helper/splitinput.cpp +++ b/src/widgets/helper/splitinput.cpp @@ -2,6 +2,8 @@ #include "application.hpp" #include "controllers/commands/commandcontroller.hpp" +#include "providers/twitch/twitchchannel.hpp" +#include "providers/twitch/twitchserver.hpp" #include "singletons/ircmanager.hpp" #include "singletons/settingsmanager.hpp" #include "singletons/thememanager.hpp" @@ -19,15 +21,15 @@ namespace widgets { SplitInput::SplitInput(Split *_chatWidget) : BaseWidget(_chatWidget) - , chatWidget(_chatWidget) + , split(_chatWidget) { this->initLayout(); - auto completer = new QCompleter(&this->chatWidget->getChannel().get()->completionModel); + auto completer = new QCompleter(&this->split->getChannel().get()->completionModel); this->ui.textEdit->setCompleter(completer); - this->chatWidget->channelChanged.connect([this] { - auto completer = new QCompleter(&this->chatWidget->getChannel()->completionModel); + this->split->channelChanged.connect([this] { + auto completer = new QCompleter(&this->split->getChannel()->completionModel); this->ui.textEdit->setCompleter(completer); }); @@ -83,16 +85,16 @@ void SplitInput::initLayout() }); } - this->emotePopup->resize((int)(300 * this->emotePopup->getScale()), - (int)(500 * this->emotePopup->getScale())); - this->emotePopup->loadChannel(this->chatWidget->getChannel()); + this->emotePopup->resize(int(300 * this->emotePopup->getScale()), + int(500 * this->emotePopup->getScale())); + this->emotePopup->loadChannel(this->split->getChannel()); this->emotePopup->show(); }); // 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->split->view.clearSelection(); } }); @@ -106,13 +108,13 @@ void SplitInput::scaleChangedEvent(float scale) { // update the icon size of the emote button QString text = ""; - text.replace("xD", QString::number((int)12 * scale)); + text.replace("xD", QString::number(int(12 * scale))); this->ui.emoteButton->getLabel().setText(text); - this->ui.emoteButton->setFixedHeight((int)18 * scale); + this->ui.emoteButton->setFixedHeight(int(18 * scale)); // set maximum height - this->setMaximumHeight((int)(150 * this->getScale())); + this->setMaximumHeight(int(150 * this->getScale())); } void SplitInput::themeRefreshEvent() @@ -125,7 +127,7 @@ void SplitInput::themeRefreshEvent() this->ui.textEdit->setStyleSheet(this->themeManager->splits.input.styleSheet); - this->ui.hbox->setMargin((this->themeManager->isLightTheme() ? 4 : 2) * this->getScale()); + this->ui.hbox->setMargin(int((this->themeManager->isLightTheme() ? 4 : 2) * this->getScale())); } void SplitInput::installKeyPressedEvent() @@ -134,7 +136,7 @@ void SplitInput::installKeyPressedEvent() this->ui.textEdit->keyPressed.connect([this, app](QKeyEvent *event) { if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) { - auto c = this->chatWidget->getChannel(); + auto c = this->split->getChannel(); if (c == nullptr) { return; } @@ -241,8 +243,7 @@ void SplitInput::installKeyPressedEvent() } } else if (event->key() == Qt::Key_Tab) { if (event->modifiers() == Qt::ControlModifier) { - SplitContainer *page = - static_cast(this->chatWidget->parentWidget()); + SplitContainer *page = static_cast(this->split->parentWidget()); Notebook *notebook = static_cast(page->parentWidget()); @@ -250,16 +251,15 @@ void SplitInput::installKeyPressedEvent() } } else if (event->key() == Qt::Key_Backtab) { if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) { - SplitContainer *page = - static_cast(this->chatWidget->parentWidget()); + SplitContainer *page = static_cast(this->split->parentWidget()); Notebook *notebook = static_cast(page->parentWidget()); notebook->selectPreviousTab(); } } else if (event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier) { - if (this->chatWidget->view.hasSelection()) { - this->chatWidget->doCopy(); + if (this->split->view.hasSelection()) { + this->split->doCopy(); event->accept(); } } @@ -293,13 +293,22 @@ void SplitInput::editTextChanged() // set textLengthLabel value QString text = this->ui.textEdit->toPlainText(); - this->textChanged.invoke(text); + if (text.startsWith("/r ") && this->split->getChannel()->isTwitchChannel()) // + { + QString lastUser = app->twitch.server->lastUserThatWhisperedMe.get(); + if (!lastUser.isEmpty()) { + this->ui.textEdit->setPlainText("/w " + lastUser + text.mid(2)); + this->ui.textEdit->moveCursor(QTextCursor::EndOfBlock); + } + } else { + this->textChanged.invoke(text); - text = text.trimmed(); - static QRegularExpression spaceRegex("\\s\\s+"); - text = text.replace(spaceRegex, " "); + text = text.trimmed(); + static QRegularExpression spaceRegex("\\s\\s+"); + text = text.replace(spaceRegex, " "); - text = app->commands->execCommand(text, this->chatWidget->getChannel(), true); + text = app->commands->execCommand(text, this->split->getChannel(), true); + } QString labelText; @@ -317,7 +326,7 @@ void SplitInput::paintEvent(QPaintEvent *) QPainter painter(this); if (this->themeManager->isLightTheme()) { - int s = (int)(3 * this->getScale()); + int s = int(3 * this->getScale()); QRect rect = this->rect().marginsRemoved(QMargins(s, s, s, s)); painter.fillRect(rect, this->themeManager->splits.input.background); @@ -325,7 +334,7 @@ void SplitInput::paintEvent(QPaintEvent *) painter.setPen(QColor("#ccc")); painter.drawRect(rect); } else { - int s = (int)(1 * this->getScale()); + int s = int(1 * this->getScale()); QRect rect = this->rect().marginsRemoved(QMargins(s, s, s, s)); painter.fillRect(rect, this->themeManager->splits.input.background); @@ -346,7 +355,7 @@ void SplitInput::resizeEvent(QResizeEvent *) void SplitInput::mousePressEvent(QMouseEvent *) { - this->chatWidget->giveFocus(Qt::MouseFocusReason); + this->split->giveFocus(Qt::MouseFocusReason); } } // namespace widgets diff --git a/src/widgets/helper/splitinput.hpp b/src/widgets/helper/splitinput.hpp index a4c9e45c..b73a6421 100644 --- a/src/widgets/helper/splitinput.hpp +++ b/src/widgets/helper/splitinput.hpp @@ -40,7 +40,7 @@ protected: virtual void mousePressEvent(QMouseEvent *event) override; private: - Split *const chatWidget; + Split *const split; std::unique_ptr emotePopup; struct { diff --git a/src/widgets/window.cpp b/src/widgets/window.cpp index 46168a72..60396d5d 100644 --- a/src/widgets/window.cpp +++ b/src/widgets/window.cpp @@ -43,18 +43,21 @@ Window::Window(WindowType _type) this->addTitleBarButton(TitleBarButton::Settings, [app] { app->windows->showSettingsDialog(); // }); - auto user = this->addTitleBarLabel([app] { - app->windows->showAccountSelectPopup(QCursor::pos()); // + + this->userLabel = this->addTitleBarLabel([this, app] { + app->windows->showAccountSelectPopup( + this->userLabel->mapToGlobal(this->userLabel->rect().bottomLeft())); // }); - app->accounts->Twitch.currentUserChanged.connect( - [=] { user->getLabel().setText(app->accounts->Twitch.getCurrent()->getUserName()); }); + app->accounts->Twitch.currentUserChanged.connect([=] { + this->userLabel->getLabel().setText(app->accounts->Twitch.getCurrent()->getUserName()); + }); } if (_type == Window::Main) { - this->resize((int)(600 * this->getScale()), (int)(500 * this->getScale())); + this->resize(int(600 * this->getScale()), int(500 * this->getScale())); } else { - this->resize((int)(300 * this->getScale()), (int)(500 * this->getScale())); + this->resize(int(300 * this->getScale()), int(500 * this->getScale())); } QVBoxLayout *layout = new QVBoxLayout(this); @@ -162,11 +165,13 @@ bool Window::event(QEvent *event) } } } break; + + default:; }; return BaseWindow::event(event); } -void Window::closeEvent(QCloseEvent *event) +void Window::closeEvent(QCloseEvent *) { if (this->type == Window::Main) { auto app = getApp(); diff --git a/src/widgets/window.hpp b/src/widgets/window.hpp index fe3d68b3..702bd946 100644 --- a/src/widgets/window.hpp +++ b/src/widgets/window.hpp @@ -42,6 +42,8 @@ protected: bool event(QEvent *event) override; private: + RippleEffectLabel *userLabel; + WindowType type; float dpi;