Remove SharedChannel (just use std::shared_ptr<Channel>)

More code-refactoring BBaper
This commit is contained in:
Rasmus Karlsson 2017-06-11 11:36:42 +02:00
parent 9cd70877a5
commit 1d6f558452
12 changed files with 230 additions and 257 deletions

View file

@ -20,8 +20,6 @@ class Message;
class ChannelManager; class ChannelManager;
typedef std::shared_ptr<Channel> SharedChannel;
class Channel class Channel
{ {
public: public:

View file

@ -14,26 +14,26 @@ ChannelManager::ChannelManager()
{ {
} }
SharedChannel ChannelManager::getWhispers() std::shared_ptr<Channel> ChannelManager::getWhispers()
{ {
return _whispers; return _whispers;
} }
SharedChannel ChannelManager::getMentions() std::shared_ptr<Channel> ChannelManager::getMentions()
{ {
return _mentions; return _mentions;
} }
SharedChannel ChannelManager::getEmpty() std::shared_ptr<Channel> ChannelManager::getEmpty()
{ {
return _empty; return _empty;
} }
const std::vector<SharedChannel> ChannelManager::getItems() const std::vector<std::shared_ptr<Channel>> ChannelManager::getItems()
{ {
QMutexLocker locker(&_channelsMutex); QMutexLocker locker(&_channelsMutex);
std::vector<SharedChannel> items; std::vector<std::shared_ptr<Channel>> items;
for (auto &item : _channels.values()) { for (auto &item : _channels.values()) {
items.push_back(std::get<0>(item)); items.push_back(std::get<0>(item));
@ -42,7 +42,7 @@ const std::vector<SharedChannel> ChannelManager::getItems()
return items; return items;
} }
SharedChannel ChannelManager::addChannel(const QString &channel) std::shared_ptr<Channel> ChannelManager::addChannel(const QString &channel)
{ {
QMutexLocker locker(&_channelsMutex); QMutexLocker locker(&_channelsMutex);
@ -55,7 +55,7 @@ SharedChannel ChannelManager::addChannel(const QString &channel)
auto it = _channels.find(channelName); auto it = _channels.find(channelName);
if (it == _channels.end()) { if (it == _channels.end()) {
auto channel = SharedChannel(new Channel(channelName)); auto channel = std::shared_ptr<Channel>(new Channel(channelName));
_channels.insert(channelName, std::make_tuple(channel, 1)); _channels.insert(channelName, std::make_tuple(channel, 1));
IrcManager::getInstance().joinChannel(channelName); IrcManager::getInstance().joinChannel(channelName);

View file

@ -12,14 +12,14 @@ public:
return instance; return instance;
} }
SharedChannel getWhispers(); std::shared_ptr<Channel> getWhispers();
SharedChannel getMentions(); std::shared_ptr<Channel> getMentions();
SharedChannel getEmpty(); std::shared_ptr<Channel> getEmpty();
const std::vector<SharedChannel> getItems(); const std::vector<std::shared_ptr<Channel>> getItems();
SharedChannel addChannel(const QString &channel); std::shared_ptr<Channel> addChannel(const QString &channel);
SharedChannel getChannel(const QString &channel); std::shared_ptr<Channel> getChannel(const QString &channel);
void removeChannel(const QString &channel); void removeChannel(const QString &channel);
private: private:
@ -27,12 +27,12 @@ private:
ChannelManager(); ChannelManager();
QMap<QString, std::tuple<SharedChannel, int>> _channels; QMap<QString, std::tuple<std::shared_ptr<Channel>, int>> _channels;
QMutex _channelsMutex; QMutex _channelsMutex;
SharedChannel _whispers; std::shared_ptr<Channel> _whispers;
SharedChannel _mentions; std::shared_ptr<Channel> _mentions;
SharedChannel _empty; std::shared_ptr<Channel> _empty;
}; };
} // namespace chatterino } // namespace chatterino

View file

@ -7,7 +7,7 @@
namespace chatterino { namespace chatterino {
namespace widgets { namespace widgets {
AccountPopupWidget::AccountPopupWidget(SharedChannel &channel) AccountPopupWidget::AccountPopupWidget(std::shared_ptr<Channel> &channel)
: QWidget(nullptr) : QWidget(nullptr)
, _ui(new Ui::AccountPopup) , _ui(new Ui::AccountPopup)
, _channel(channel) , _channel(channel)

View file

@ -18,153 +18,152 @@ using namespace chatterino::messages;
namespace chatterino { namespace chatterino {
namespace widgets { namespace widgets {
namespace {
template <typename T>
inline void ezShortcut(ChatWidget *w, const char *key, T t)
{
auto s = new QShortcut(QKeySequence(key), w);
s->setContext(Qt::WidgetWithChildrenShortcut);
QObject::connect(s, &QShortcut::activated, w, t);
}
} // namespace
ChatWidget::ChatWidget(QWidget *parent) ChatWidget::ChatWidget(QWidget *parent)
: QWidget(parent) : QWidget(parent)
, _messages() , channel(ChannelManager::getInstance().getEmpty())
, _channel(ChannelManager::getInstance().getEmpty()) , vbox(this)
, _channelName(QString()) , header(this)
, _vbox(this) , view(this)
, _header(this) , input(this)
, _view(this)
, _input(this)
{ {
this->_vbox.setSpacing(0); this->vbox.setSpacing(0);
this->_vbox.setMargin(1); this->vbox.setMargin(1);
this->_vbox.addWidget(&_header); this->vbox.addWidget(&this->header);
this->_vbox.addWidget(&_view, 1); this->vbox.addWidget(&this->view, 1);
this->_vbox.addWidget(&_input); this->vbox.addWidget(&this->input);
// Initialize widget-wide hotkeys // Initialize chat widget-wide hotkeys
// CTRL+T: Create new split (Add page) // CTRL+T: Create new split (Add page)
{ ezShortcut(this, "CTRL+T", &ChatWidget::doAddSplit);
auto s = new QShortcut(QKeySequence("CTRL+T"), this);
s->setContext(Qt::WidgetWithChildrenShortcut);
connect(s, &QShortcut::activated, this, &ChatWidget::doAddSplit);
}
// CTRL+W: Close Split // CTRL+W: Close Split
{ ezShortcut(this, "CTRL+W", &ChatWidget::doCloseSplit);
auto s = new QShortcut(QKeySequence("CTRL+W"), this);
s->setContext(Qt::WidgetWithChildrenShortcut);
connect(s, &QShortcut::activated, this, &ChatWidget::doCloseSplit);
}
// CTRL+R: Change Channel // CTRL+R: Change Channel
{ ezShortcut(this, "CTRL+R", &ChatWidget::doChangeChannel);
auto s = new QShortcut(QKeySequence("CTRL+R"), this);
s->setContext(Qt::WidgetWithChildrenShortcut);
connect(s, &QShortcut::activated, this, &ChatWidget::doChangeChannel);
}
} }
ChatWidget::~ChatWidget() ChatWidget::~ChatWidget()
{ {
detachChannel(); this->detachChannel();
} }
std::shared_ptr<Channel> ChatWidget::getChannel() const std::shared_ptr<Channel> ChatWidget::getChannel() const
{ {
return _channel; return this->channel;
} }
std::shared_ptr<Channel> &ChatWidget::getChannelRef() std::shared_ptr<Channel> &ChatWidget::getChannelRef()
{ {
return _channel; return this->channel;
} }
const QString &ChatWidget::getChannelName() const const QString &ChatWidget::getChannelName() const
{ {
return _channelName; return this->channelName;
} }
void ChatWidget::setChannelName(const QString &name) void ChatWidget::setChannelName(const QString &_newChannelName)
{ {
QString channelName = name.trimmed(); QString newChannelName = _newChannelName.trimmed();
// return if channel name is the same // return if channel name is the same
if (QString::compare(channelName, _channelName, Qt::CaseInsensitive) == 0) { if (QString::compare(newChannelName, this->channelName, Qt::CaseInsensitive) == 0) {
_channelName = channelName; this->channelName = newChannelName;
_header.updateChannelText(); this->header.updateChannelText();
return; return;
} }
// remove current channel // remove current channel
if (!_channelName.isEmpty()) { if (!this->channelName.isEmpty()) {
ChannelManager::getInstance().removeChannel(_channelName); ChannelManager::getInstance().removeChannel(this->channelName);
detachChannel(); this->detachChannel();
} }
// update members // update members
_channelName = channelName; this->channelName = newChannelName;
// update messages // update messages
_messages.clear(); this->messages.clear();
printf("Set channel name xD %s\n", qPrintable(name)); printf("Set channel name xD %s\n", qPrintable(_newChannelName));
if (channelName.isEmpty()) { if (newChannelName.isEmpty()) {
_channel = nullptr; this->channel = nullptr;
} else { } else {
_channel = ChannelManager::getInstance().addChannel(channelName); this->setChannel(ChannelManager::getInstance().addChannel(newChannelName));
printf("Created channel FeelsGoodMan %p\n", _channel.get());
attachChannel(_channel);
} }
// update header // update header
_header.updateChannelText(); this->header.updateChannelText();
// update view // update view
_view.layoutMessages(); this->view.layoutMessages();
_view.update(); this->view.update();
} }
void ChatWidget::attachChannel(SharedChannel channel) void ChatWidget::setChannel(std::shared_ptr<Channel> _newChannel)
{ {
this->channel = _newChannel;
// on new message // on new message
_messageAppendedConnection = channel->messageAppended.connect([this](SharedMessage &message) { this->messageAppendedConnection =
this->channel->messageAppended.connect([this](SharedMessage &message) {
SharedMessageRef deleted; SharedMessageRef deleted;
auto messageRef = new MessageRef(message); auto messageRef = new MessageRef(message);
if (_messages.appendItem(SharedMessageRef(messageRef), deleted)) { if (this->messages.appendItem(SharedMessageRef(messageRef), deleted)) {
qreal value = std::max(0.0, _view.getScrollbar()->getDesiredValue() - 1); qreal value = std::max(0.0, this->view.getScrollBar().getDesiredValue() - 1);
_view.getScrollbar()->setDesiredValue(value, false); this->view.getScrollBar().setDesiredValue(value, false);
} }
}); });
// on message removed // on message removed
_messageRemovedConnection = _channel->messageRemovedFromStart.connect([](SharedMessage &) { this->messageRemovedConnection =
this->channel->messageRemovedFromStart.connect([](SharedMessage &) {
// //
}); });
auto snapshot = _channel.get()->getMessageSnapshot(); auto snapshot = this->channel->getMessageSnapshot();
for (int i = 0; i < snapshot.getSize(); i++) { for (int i = 0; i < snapshot.getSize(); i++) {
SharedMessageRef deleted; SharedMessageRef deleted;
auto messageRef = new MessageRef(snapshot[i]); auto messageRef = new MessageRef(snapshot[i]);
_messages.appendItem(SharedMessageRef(messageRef), deleted); this->messages.appendItem(SharedMessageRef(messageRef), deleted);
} }
} }
void ChatWidget::detachChannel() void ChatWidget::detachChannel()
{ {
// on message added // on message added
_messageAppendedConnection.disconnect(); this->messageAppendedConnection.disconnect();
// on message removed // on message removed
_messageRemovedConnection.disconnect(); this->messageRemovedConnection.disconnect();
} }
LimitedQueueSnapshot<SharedMessageRef> ChatWidget::getMessagesSnapshot() LimitedQueueSnapshot<SharedMessageRef> ChatWidget::getMessagesSnapshot()
{ {
return _messages.getSnapshot(); return this->messages.getSnapshot();
} }
void ChatWidget::showChangeChannelPopup() void ChatWidget::showChangeChannelPopup()
@ -172,7 +171,7 @@ void ChatWidget::showChangeChannelPopup()
// create new input dialog and execute it // create new input dialog and execute it
TextInputDialog dialog(this); TextInputDialog dialog(this);
dialog.setText(_channelName); dialog.setText(this->channelName);
if (dialog.exec() == QDialog::Accepted) { if (dialog.exec() == QDialog::Accepted) {
setChannelName(dialog.getText()); setChannelName(dialog.getText());
@ -181,14 +180,14 @@ void ChatWidget::showChangeChannelPopup()
void ChatWidget::layoutMessages() void ChatWidget::layoutMessages()
{ {
if (_view.layoutMessages()) { if (this->view.layoutMessages()) {
_view.update(); this->view.update();
} }
} }
void ChatWidget::updateGifEmotes() void ChatWidget::updateGifEmotes()
{ {
_view.updateGifEmotes(); this->view.updateGifEmotes();
} }
void ChatWidget::paintEvent(QPaintEvent *) void ChatWidget::paintEvent(QPaintEvent *)
@ -227,7 +226,7 @@ void ChatWidget::doAddSplit()
void ChatWidget::doCloseSplit() void ChatWidget::doCloseSplit()
{ {
qDebug() << "Close split for" << this->getChannelName(); qDebug() << "[UNIMPLEMENTED] Close split for" << this->getChannelName();
} }
void ChatWidget::doChangeChannel() void ChatWidget::doChangeChannel()
@ -245,17 +244,17 @@ void ChatWidget::doPopup()
void ChatWidget::doClearChat() void ChatWidget::doClearChat()
{ {
qDebug() << "[UNIMPLEMENTED]: Clear chat"; qDebug() << "[UNIMPLEMENTED] Clear chat";
} }
void ChatWidget::doOpenChannel() void ChatWidget::doOpenChannel()
{ {
qDebug() << "[UNIMPLEMENTED]: Open twitch.tv/" << this->getChannelName(); qDebug() << "[UNIMPLEMENTED] Open twitch.tv/" << this->getChannelName();
} }
void ChatWidget::doOpenPopupPlayer() void ChatWidget::doOpenPopupPlayer()
{ {
qDebug() << "[UNIMPLEMENTED]: Open twitch.tv/" << this->getChannelName() << "/popout"; qDebug() << "[UNIMPLEMENTED] Open twitch.tv/" << this->getChannelName() << "/popout";
} }
} // namespace widgets } // namespace widgets

View file

@ -37,8 +37,8 @@ public:
ChatWidget(QWidget *parent = nullptr); ChatWidget(QWidget *parent = nullptr);
~ChatWidget(); ~ChatWidget();
SharedChannel getChannel() const; std::shared_ptr<Channel> getChannel() const;
SharedChannel &getChannelRef(); std::shared_ptr<Channel> &getChannelRef();
const QString &getChannelName() const; const QString &getChannelName() const;
void setChannelName(const QString &name); void setChannelName(const QString &name);
@ -51,22 +51,21 @@ protected:
void paintEvent(QPaintEvent *) override; void paintEvent(QPaintEvent *) override;
private: private:
void attachChannel(std::shared_ptr<Channel> _channel); void setChannel(std::shared_ptr<Channel> newChannel);
void detachChannel(); void detachChannel();
messages::LimitedQueue<messages::SharedMessageRef> _messages; messages::LimitedQueue<messages::SharedMessageRef> messages;
SharedChannel _channel; std::shared_ptr<Channel> channel;
QString _channelName; QString channelName;
QFont _font; QVBoxLayout vbox;
QVBoxLayout _vbox; ChatWidgetHeader header;
ChatWidgetHeader _header; ChatWidgetView view;
ChatWidgetView _view; ChatWidgetInput input;
ChatWidgetInput _input;
boost::signals2::connection _messageAppendedConnection; boost::signals2::connection messageAppendedConnection;
boost::signals2::connection _messageRemovedConnection; boost::signals2::connection messageRemovedConnection;
public: public:
void load(const boost::property_tree::ptree &tree); void load(const boost::property_tree::ptree &tree);

View file

@ -11,44 +11,38 @@
namespace chatterino { namespace chatterino {
namespace widgets { namespace widgets {
ChatWidgetInput::ChatWidgetInput(ChatWidget *widget) ChatWidgetInput::ChatWidgetInput(ChatWidget *_chatWidget)
: _chatWidget(widget) : QWidget(_chatWidget)
, _hbox() , chatWidget(_chatWidget)
, _vbox()
, _editContainer()
, _edit()
, _textLengthLabel()
, _emotesLabel(0)
{ {
setLayout(&_hbox); this->setMaximumHeight(150);
setMaximumHeight(150);
_hbox.setMargin(4);
_hbox.addLayout(&_editContainer); this->setLayout(&this->hbox);
_hbox.addLayout(&_vbox);
_editContainer.addWidget(&_edit); this->hbox.setMargin(4);
_editContainer.setMargin(4);
_vbox.addWidget(&_textLengthLabel); this->hbox.addLayout(&this->editContainer);
_vbox.addStretch(1); this->hbox.addLayout(&this->vbox);
_vbox.addWidget(&_emotesLabel);
_textLengthLabel.setText("100"); this->editContainer.addWidget(&this->textInput);
_textLengthLabel.setAlignment(Qt::AlignRight); this->editContainer.setMargin(4);
_emotesLabel.getLabel().setTextFormat(Qt::RichText);
_emotesLabel.getLabel().setText( this->vbox.addWidget(&this->textLengthLabel);
this->vbox.addStretch(1);
this->vbox.addWidget(&this->emotesLabel);
this->textLengthLabel.setText("100");
this->textLengthLabel.setAlignment(Qt::AlignRight);
this->emotesLabel.getLabel().setTextFormat(Qt::RichText);
this->emotesLabel.getLabel().setText(
"<img src=':/images/Emoji_Color_1F60A_19.png' width='12' height='12' " "<img src=':/images/Emoji_Color_1F60A_19.png' width='12' height='12' "
"/>"); "/>");
QObject::connect(&_edit, &ResizingTextEdit::textChanged, this, connect(&textInput, &ResizingTextEdit::textChanged, this, &ChatWidgetInput::editTextChanged);
&ChatWidgetInput::editTextChanged);
// QObject::connect(&edit, &ResizingTextEdit::keyPressEvent, this, this->refreshTheme();
// &ChatWidgetInput::editKeyPressed); this->setMessageLengthVisisble(SettingsManager::getInstance().showMessageLength.get());
refreshTheme();
setMessageLengthVisisble(SettingsManager::getInstance().showMessageLength.get());
QStringList list; QStringList list;
list.append("asd"); list.append("asd");
@ -56,20 +50,20 @@ ChatWidgetInput::ChatWidgetInput(ChatWidget *widget)
list.append("asdg"); list.append("asdg");
list.append("asdh"); list.append("asdh");
QCompleter *completer = new QCompleter(list, &_edit); QCompleter *completer = new QCompleter(list, &this->textInput);
completer->setWidget(&_edit); completer->setWidget(&textInput);
_edit.keyPressed.connect([this /*, completer*/](QKeyEvent *event) { this->textInput.keyPressed.connect([this /*, completer*/](QKeyEvent *event) {
if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) { if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
auto c = _chatWidget->getChannel(); auto c = this->chatWidget->getChannel();
if (c == nullptr) { if (c == nullptr) {
return; return;
} }
c->sendMessage(_edit.toPlainText()); c->sendMessage(textInput.toPlainText());
event->accept(); event->accept();
_edit.setText(QString()); textInput.setText(QString());
} }
// else { // else {
// completer->setCompletionPrefix("asdf"); // completer->setCompletionPrefix("asdf");
@ -101,9 +95,9 @@ void ChatWidgetInput::refreshTheme()
palette.setColor(QPalette::Foreground, ColorScheme::getInstance().Text); palette.setColor(QPalette::Foreground, ColorScheme::getInstance().Text);
_textLengthLabel.setPalette(palette); this->textLengthLabel.setPalette(palette);
_edit.setStyleSheet(ColorScheme::getInstance().InputStyleSheet); this->textInput.setStyleSheet(ColorScheme::getInstance().InputStyleSheet);
} }
void ChatWidgetInput::editTextChanged() void ChatWidgetInput::editTextChanged()
@ -124,17 +118,17 @@ void ChatWidgetInput::paintEvent(QPaintEvent *)
{ {
QPainter painter(this); QPainter painter(this);
painter.fillRect(rect(), ColorScheme::getInstance().ChatInputBackground); painter.fillRect(this->rect(), ColorScheme::getInstance().ChatInputBackground);
painter.setPen(ColorScheme::getInstance().ChatInputBorder); painter.setPen(ColorScheme::getInstance().ChatInputBorder);
painter.drawRect(0, 0, width() - 1, height() - 1); painter.drawRect(0, 0, this->width() - 1, this->height() - 1);
} }
void ChatWidgetInput::resizeEvent(QResizeEvent *) void ChatWidgetInput::resizeEvent(QResizeEvent *)
{ {
if (height() == maximumHeight()) { if (this->height() == this->maximumHeight()) {
_edit.setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); this->textInput.setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
} else { } else {
_edit.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); this->textInput.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
} }
} }

View file

@ -21,29 +21,28 @@ class ChatWidgetInput : public QWidget
Q_OBJECT Q_OBJECT
public: public:
ChatWidgetInput(ChatWidget *parent); ChatWidgetInput(ChatWidget *_chatWidget);
~ChatWidgetInput(); ~ChatWidgetInput();
protected: protected:
void paintEvent(QPaintEvent *); virtual void paintEvent(QPaintEvent *) override;
virtual void resizeEvent(QResizeEvent *) override;
void resizeEvent(QResizeEvent *);
private: private:
ChatWidget *_chatWidget; ChatWidget *chatWidget;
QHBoxLayout _hbox; QHBoxLayout hbox;
QVBoxLayout _vbox; QVBoxLayout vbox;
QHBoxLayout _editContainer; QHBoxLayout editContainer;
ResizingTextEdit _edit; ResizingTextEdit textInput;
QLabel _textLengthLabel; QLabel textLengthLabel;
ChatWidgetHeaderButton _emotesLabel; ChatWidgetHeaderButton emotesLabel;
private slots: private slots:
void refreshTheme(); void refreshTheme();
void setMessageLengthVisisble(bool value) void setMessageLengthVisisble(bool value)
{ {
_textLengthLabel.setHidden(!value); textLengthLabel.setHidden(!value);
} }
void editTextChanged(); void editTextChanged();
// void editKeyPressed(QKeyEvent *event); // void editKeyPressed(QKeyEvent *event);

View file

@ -19,23 +19,19 @@
namespace chatterino { namespace chatterino {
namespace widgets { namespace widgets {
ChatWidgetView::ChatWidgetView(ChatWidget *parent) ChatWidgetView::ChatWidgetView(ChatWidget *_chatWidget)
: QWidget(parent) : QWidget(_chatWidget)
, _chatWidget(parent) , chatWidget(_chatWidget)
, _scrollbar(this) , scrollBar(this)
, _userPopupWidget(_chatWidget->getChannelRef()) , userPopupWidget(_chatWidget->getChannelRef())
, _onlyUpdateEmotes(false)
, _mouseDown(false)
, _lastPressPosition()
{ {
setAttribute(Qt::WA_OpaquePaintEvent); this->setAttribute(Qt::WA_OpaquePaintEvent);
_scrollbar.setSmallChange(5); this->setMouseTracking(true);
setMouseTracking(true);
QObject::connect(&SettingsManager::getInstance(), &SettingsManager::wordTypeMaskChanged, this, QObject::connect(&SettingsManager::getInstance(), &SettingsManager::wordTypeMaskChanged, this,
&ChatWidgetView::wordTypeMaskChanged); &ChatWidgetView::wordTypeMaskChanged);
_scrollbar.getCurrentValueChanged().connect([this] { this->scrollBar.getCurrentValueChanged().connect([this] {
// Whenever the scrollbar value has been changed, re-render the ChatWidgetView // Whenever the scrollbar value has been changed, re-render the ChatWidgetView
this->update(); this->update();
}); });
@ -49,28 +45,28 @@ ChatWidgetView::~ChatWidgetView()
bool ChatWidgetView::layoutMessages() bool ChatWidgetView::layoutMessages()
{ {
auto messages = _chatWidget->getMessagesSnapshot(); auto messages = this->chatWidget->getMessagesSnapshot();
if (messages.getSize() == 0) { if (messages.getSize() == 0) {
_scrollbar.setVisible(false); this->scrollBar.setVisible(false);
return false; return false;
} }
bool showScrollbar = false, redraw = false; bool showScrollbar = false;
bool redraw = false;
// Bool indicating whether or not we were showing all messages // Bool indicating whether or not we were showing all messages
// True if one of the following statements are true: // True if one of the following statements are true:
// The scrollbar was not visible // The scrollbar was not visible
// The scrollbar was visible and at the bottom // The scrollbar was visible and at the bottom
this->showingLatestMessages = this->_scrollbar.isAtBottom() || !this->_scrollbar.isVisible(); this->showingLatestMessages = this->scrollBar.isAtBottom() || !this->scrollBar.isVisible();
int start = _scrollbar.getCurrentValue(); int start = this->scrollBar.getCurrentValue();
int layoutWidth = _scrollbar.isVisible() ? width() - _scrollbar.width() : width(); int layoutWidth = this->scrollBar.isVisible() ? width() - this->scrollBar.width() : width();
// layout the visible messages in the view // layout the visible messages in the view
if (messages.getSize() > start) { if (messages.getSize() > start) {
int y = -(messages[start]->getHeight() * (fmod(_scrollbar.getCurrentValue(), 1))); int y = -(messages[start]->getHeight() * (fmod(this->scrollBar.getCurrentValue(), 1)));
for (int i = start; i < messages.getSize(); ++i) { for (int i = start; i < messages.getSize(); ++i) {
auto message = messages[i]; auto message = messages[i];
@ -96,21 +92,22 @@ bool ChatWidgetView::layoutMessages()
h -= message->getHeight(); h -= message->getHeight();
if (h < 0) { if (h < 0) {
_scrollbar.setLargeChange((messages.getSize() - i) + (qreal)h / message->getHeight()); this->scrollBar.setLargeChange((messages.getSize() - i) +
_scrollbar.setDesiredValue(_scrollbar.getDesiredValue()); (qreal)h / message->getHeight());
this->scrollBar.setDesiredValue(this->scrollBar.getDesiredValue());
showScrollbar = true; showScrollbar = true;
break; break;
} }
} }
_scrollbar.setVisible(showScrollbar); this->scrollBar.setVisible(showScrollbar);
if (!showScrollbar) { if (!showScrollbar) {
_scrollbar.setDesiredValue(0); this->scrollBar.setDesiredValue(0);
} }
_scrollbar.setMaximum(messages.getSize()); this->scrollBar.setMaximum(messages.getSize());
if (this->showingLatestMessages && showScrollbar) { if (this->showingLatestMessages && showScrollbar) {
// If we were showing the latest messages and the scrollbar now wants to be rendered, scroll // If we were showing the latest messages and the scrollbar now wants to be rendered, scroll
@ -118,7 +115,7 @@ bool ChatWidgetView::layoutMessages()
// TODO: Do we want to check if the user is currently moving the scrollbar? // TODO: Do we want to check if the user is currently moving the scrollbar?
// Perhaps also if the user scrolled with the scrollwheel in this ChatWidget in the last 0.2 // Perhaps also if the user scrolled with the scrollwheel in this ChatWidget in the last 0.2
// seconds or something // seconds or something
this->_scrollbar.scrollToBottom(); this->scrollBar.scrollToBottom();
} }
return redraw; return redraw;
@ -126,26 +123,26 @@ bool ChatWidgetView::layoutMessages()
void ChatWidgetView::updateGifEmotes() void ChatWidgetView::updateGifEmotes()
{ {
_onlyUpdateEmotes = true; this->onlyUpdateEmotes = true;
this->update(); this->update();
} }
ScrollBar *ChatWidgetView::getScrollbar() ScrollBar &ChatWidgetView::getScrollBar()
{ {
return &_scrollbar; return this->scrollBar;
} }
void ChatWidgetView::resizeEvent(QResizeEvent *) void ChatWidgetView::resizeEvent(QResizeEvent *)
{ {
_scrollbar.resize(_scrollbar.width(), height()); this->scrollBar.resize(this->scrollBar.width(), height());
_scrollbar.move(width() - _scrollbar.width(), 0); this->scrollBar.move(width() - this->scrollBar.width(), 0);
layoutMessages(); layoutMessages();
this->update(); this->update();
} }
void ChatWidgetView::paintEvent(QPaintEvent *event) void ChatWidgetView::paintEvent(QPaintEvent * /*event*/)
{ {
QPainter _painter(this); QPainter _painter(this);
@ -154,10 +151,10 @@ void ChatWidgetView::paintEvent(QPaintEvent *event)
ColorScheme &scheme = ColorScheme::getInstance(); ColorScheme &scheme = ColorScheme::getInstance();
// only update gif emotes // only update gif emotes
if (_onlyUpdateEmotes) { if (this->onlyUpdateEmotes) {
_onlyUpdateEmotes = false; this->onlyUpdateEmotes = false;
for (GifEmoteData &item : _gifEmotes) { for (const GifEmoteData &item : this->gifEmotes) {
_painter.fillRect(item.rect, scheme.ChatBackground); _painter.fillRect(item.rect, scheme.ChatBackground);
_painter.drawPixmap(item.rect, *item.image->getPixmap()); _painter.drawPixmap(item.rect, *item.image->getPixmap());
@ -167,7 +164,7 @@ void ChatWidgetView::paintEvent(QPaintEvent *event)
} }
// update all messages // update all messages
_gifEmotes.clear(); this->gifEmotes.clear();
_painter.fillRect(rect(), scheme.ChatBackground); _painter.fillRect(rect(), scheme.ChatBackground);
@ -204,15 +201,15 @@ void ChatWidgetView::paintEvent(QPaintEvent *event)
painter.fillRect(QRect(0, 9, 500, 2), QColor(0, 0, 0));*/ painter.fillRect(QRect(0, 9, 500, 2), QColor(0, 0, 0));*/
auto messages = _chatWidget->getMessagesSnapshot(); auto messages = this->chatWidget->getMessagesSnapshot();
int start = _scrollbar.getCurrentValue(); int start = this->scrollBar.getCurrentValue();
if (start >= messages.getSize()) { if (start >= messages.getSize()) {
return; return;
} }
int y = -(messages[start].get()->getHeight() * (fmod(_scrollbar.getCurrentValue(), 1))); int y = -(messages[start].get()->getHeight() * (fmod(this->scrollBar.getCurrentValue(), 1)));
for (int i = start; i < messages.getSize(); ++i) { for (int i = start; i < messages.getSize(); ++i) {
messages::MessageRef *messageRef = messages[i].get(); messages::MessageRef *messageRef = messages[i].get();
@ -276,7 +273,7 @@ void ChatWidgetView::paintEvent(QPaintEvent *event)
data.rect = rect; data.rect = rect;
_gifEmotes.push_back(data); this->gifEmotes.push_back(data);
} }
} }
} }
@ -292,7 +289,7 @@ void ChatWidgetView::paintEvent(QPaintEvent *event)
} }
} }
for (GifEmoteData &item : _gifEmotes) { for (GifEmoteData &item : this->gifEmotes) {
_painter.fillRect(item.rect, scheme.ChatBackground); _painter.fillRect(item.rect, scheme.ChatBackground);
_painter.drawPixmap(item.rect, *item.image->getPixmap()); _painter.drawPixmap(item.rect, *item.image->getPixmap());
@ -301,11 +298,11 @@ void ChatWidgetView::paintEvent(QPaintEvent *event)
void ChatWidgetView::wheelEvent(QWheelEvent *event) void ChatWidgetView::wheelEvent(QWheelEvent *event)
{ {
if (_scrollbar.isVisible()) { if (this->scrollBar.isVisible()) {
auto mouseMultiplier = SettingsManager::getInstance().mouseScrollMultiplier.get(); auto mouseMultiplier = SettingsManager::getInstance().mouseScrollMultiplier.get();
_scrollbar.setDesiredValue( this->scrollBar.setDesiredValue(
_scrollbar.getDesiredValue() - event->delta() / 10.0 * mouseMultiplier, true); this->scrollBar.getDesiredValue() - event->delta() / 10.0 * mouseMultiplier, true);
} }
} }
@ -337,21 +334,21 @@ void ChatWidgetView::mouseMoveEvent(QMouseEvent *event)
void ChatWidgetView::mousePressEvent(QMouseEvent *event) void ChatWidgetView::mousePressEvent(QMouseEvent *event)
{ {
_mouseDown = true; this->isMouseDown = true;
_lastPressPosition = event->screenPos(); this->lastPressPosition = event->screenPos();
} }
void ChatWidgetView::mouseReleaseEvent(QMouseEvent *event) void ChatWidgetView::mouseReleaseEvent(QMouseEvent *event)
{ {
if (!_mouseDown) { if (!this->isMouseDown) {
// We didn't grab the mouse press, so we shouldn't be handling the mouse // We didn't grab the mouse press, so we shouldn't be handling the mouse
// release // release
return; return;
} }
_mouseDown = false; this->isMouseDown = false;
float distance = util::distanceBetweenPoints(_lastPressPosition, event->screenPos()); float distance = util::distanceBetweenPoints(this->lastPressPosition, event->screenPos());
qDebug() << "Distance: " << distance; qDebug() << "Distance: " << distance;
@ -370,7 +367,7 @@ void ChatWidgetView::mouseReleaseEvent(QMouseEvent *event)
if (!tryGetMessageAt(event->pos(), message, relativePos)) { if (!tryGetMessageAt(event->pos(), message, relativePos)) {
// No message at clicked position // No message at clicked position
_userPopupWidget.hide(); this->userPopupWidget.hide();
return; return;
} }
@ -385,10 +382,10 @@ void ChatWidgetView::mouseReleaseEvent(QMouseEvent *event)
switch (link.getType()) { switch (link.getType()) {
case messages::Link::UserInfo: case messages::Link::UserInfo:
auto user = message->getMessage()->getUserName(); auto user = message->getMessage()->getUserName();
_userPopupWidget.setName(user); this->userPopupWidget.setName(user);
_userPopupWidget.move(event->screenPos().toPoint()); this->userPopupWidget.move(event->screenPos().toPoint());
_userPopupWidget.show(); this->userPopupWidget.show();
_userPopupWidget.setFocus(); this->userPopupWidget.setFocus();
qDebug() << "Clicked " << user << "s message"; qDebug() << "Clicked " << user << "s message";
break; break;
@ -398,15 +395,15 @@ void ChatWidgetView::mouseReleaseEvent(QMouseEvent *event)
bool ChatWidgetView::tryGetMessageAt(QPoint p, std::shared_ptr<messages::MessageRef> &_message, bool ChatWidgetView::tryGetMessageAt(QPoint p, std::shared_ptr<messages::MessageRef> &_message,
QPoint &relativePos) QPoint &relativePos)
{ {
auto messages = _chatWidget->getMessagesSnapshot(); auto messages = this->chatWidget->getMessagesSnapshot();
int start = _scrollbar.getCurrentValue(); int start = this->scrollBar.getCurrentValue();
if (start >= messages.getSize()) { if (start >= messages.getSize()) {
return false; return false;
} }
int y = -(messages[start]->getHeight() * (fmod(_scrollbar.getCurrentValue(), 1))); int y = -(messages[start]->getHeight() * (fmod(this->scrollBar.getCurrentValue(), 1)));
for (int i = start; i < messages.getSize(); ++i) { for (int i = start; i < messages.getSize(); ++i) {
auto message = messages[i]; auto message = messages[i];

View file

@ -14,24 +14,25 @@
namespace chatterino { namespace chatterino {
namespace widgets { namespace widgets {
class ChatWidget; class ChatWidget;
class ChatWidgetView : public QWidget class ChatWidgetView : public QWidget
{ {
public: public:
explicit ChatWidgetView(ChatWidget *parent); explicit ChatWidgetView(ChatWidget *_chatWidget);
~ChatWidgetView(); ~ChatWidgetView();
bool layoutMessages(); bool layoutMessages();
void updateGifEmotes(); void updateGifEmotes();
ScrollBar *getScrollbar(); ScrollBar &getScrollBar();
protected: protected:
void resizeEvent(QResizeEvent *) override; virtual void resizeEvent(QResizeEvent *) override;
void paintEvent(QPaintEvent *) override; virtual void paintEvent(QPaintEvent *) override;
void wheelEvent(QWheelEvent *event) override; virtual void wheelEvent(QWheelEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override;
@ -46,22 +47,22 @@ private:
QRect rect; QRect rect;
}; };
std::vector<GifEmoteData> _gifEmotes; std::vector<GifEmoteData> gifEmotes;
ChatWidget *_chatWidget; ChatWidget *chatWidget;
ScrollBar _scrollbar; ScrollBar scrollBar;
// This variable can be used to decide whether or not we should render the "Show latest // This variable can be used to decide whether or not we should render the "Show latest
// messages" button // messages" button
bool showingLatestMessages = true; bool showingLatestMessages = true;
AccountPopupWidget _userPopupWidget; AccountPopupWidget userPopupWidget;
bool _onlyUpdateEmotes; bool onlyUpdateEmotes = false;
// Mouse event variables // Mouse event variables
bool _mouseDown; bool isMouseDown = false;
QPointF _lastPressPosition; QPointF lastPressPosition;
private slots: private slots:
void wordTypeMaskChanged() void wordTypeMaskChanged()

View file

@ -12,22 +12,8 @@ namespace widgets {
ScrollBar::ScrollBar(QWidget *widget) ScrollBar::ScrollBar(QWidget *widget)
: QWidget(widget) : QWidget(widget)
, _mutex()
, _currentValueAnimation(this, "currentValue") , _currentValueAnimation(this, "currentValue")
, _highlights(nullptr) , _highlights(nullptr)
, _mouseOverIndex(-1)
, _mouseDownIndex(-1)
, _lastMousePosition()
, _buttonHeight(16)
, _trackHeight(100)
, _thumbRect()
, _maximum()
, _minimum()
, _largeChange()
, _smallChange()
, _desiredValue()
, _currentValue()
, _currentValueChanged()
{ {
resize(16, 100); resize(16, 100);

View file

@ -58,21 +58,21 @@ private:
void mouseReleaseEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event);
void leaveEvent(QEvent *); void leaveEvent(QEvent *);
int _mouseOverIndex; int _mouseOverIndex = -1;
int _mouseDownIndex; int _mouseDownIndex = -1;
QPoint _lastMousePosition; QPoint _lastMousePosition;
int _buttonHeight; int _buttonHeight = 16;
int _trackHeight; int _trackHeight = 100;
QRect _thumbRect; QRect _thumbRect;
qreal _maximum; qreal _maximum = 0;
qreal _minimum; qreal _minimum = 0;
qreal _largeChange; qreal _largeChange = 0;
qreal _smallChange; qreal _smallChange = 5;
qreal _desiredValue; qreal _desiredValue = 0;
qreal _currentValue; qreal _currentValue = 0;
boost::signals2::signal<void()> _currentValueChanged; boost::signals2::signal<void()> _currentValueChanged;