fixed /r and tab text alignment

This commit is contained in:
fourtf 2018-05-25 13:53:55 +02:00
parent b68b7ecb10
commit 9aa9b90267
13 changed files with 140 additions and 41 deletions

View file

@ -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

View file

@ -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();

View file

@ -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<messages::MessagePtr> getMessageSnapshot();

View file

@ -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) {

View file

@ -7,6 +7,7 @@
#include "singletons/emotemanager.hpp"
#include "singletons/ircmanager.hpp"
#include "util/concurrentmap.hpp"
#include "util/mutexvalue.h"
#include <pajlada/signals/signalholder.hpp>
@ -78,6 +79,7 @@ public:
pajlada::Signals::NoArgSignal roomModesChanged;
QString roomID;
RoomModes getRoomModes();
void setRoomModes(const RoomModes &roomModes);

View file

@ -197,6 +197,20 @@ std::shared_ptr<Channel> TwitchServer::getChannelOrEmptyByID(const QString &chan
return Channel::getEmpty();
}
// QString TwitchServer::getLastWhisperedPerson() const
//{
// std::lock_guard<std::mutex> guard(this->lastWhisperedPersonMutex);
// return this->lastWhisperedPerson;
//}
// void TwitchServer::setLastWhisperedPerson(const QString &person)
//{
// std::lock_guard<std::mutex> guard(this->lastWhisperedPersonMutex);
// this->lastWhisperedPerson = person;
//}
QString TwitchServer::cleanChannelName(const QString &dirtyChannelName)
{
return dirtyChannelName.toLower();

View file

@ -3,6 +3,7 @@
#include "providers/irc/abstractircserver.hpp"
#include "providers/twitch/twitchaccount.hpp"
#include "providers/twitch/twitchchannel.hpp"
#include "util/mutexvalue.h"
#include <memory>
@ -22,6 +23,11 @@ public:
std::shared_ptr<Channel> getChannelOrEmptyByID(const QString &channelID);
util::MutexValue<QString> 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<Channel> getCustomChannel(const QString &channelname) override;
QString cleanChannelName(const QString &dirtyChannelName) override;
private:
// mutable std::mutex lastWhisperedPersonMutex;
// QString lastWhisperedPerson;
};
} // namespace twitch

40
src/util/mutexvalue.h Normal file
View file

@ -0,0 +1,40 @@
#pragma once
#include <mutex>
namespace chatterino {
namespace util {
template <typename T>
class MutexValue
{
mutable std::mutex mutex;
T value;
public:
MutexValue()
{
}
MutexValue(T &&val)
: value(val)
{
}
T get() const
{
std::lock_guard<std::mutex> guard(this->mutex);
return this->value;
}
void set(const T &val)
{
std::lock_guard<std::mutex> guard(this->mutex);
this->value = val;
}
};
} // namespace util
} // namespace chatterino

View file

@ -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<int>(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 {

View file

@ -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 = "<img src=':/images/emote.svg' width='xD' height='xD' />";
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<SplitContainer *>(this->chatWidget->parentWidget());
SplitContainer *page = static_cast<SplitContainer *>(this->split->parentWidget());
Notebook *notebook = static_cast<Notebook *>(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<SplitContainer *>(this->chatWidget->parentWidget());
SplitContainer *page = static_cast<SplitContainer *>(this->split->parentWidget());
Notebook *notebook = static_cast<Notebook *>(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

View file

@ -40,7 +40,7 @@ protected:
virtual void mousePressEvent(QMouseEvent *event) override;
private:
Split *const chatWidget;
Split *const split;
std::unique_ptr<EmotePopup> emotePopup;
struct {

View file

@ -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();

View file

@ -42,6 +42,8 @@ protected:
bool event(QEvent *event) override;
private:
RippleEffectLabel *userLabel;
WindowType type;
float dpi;