Fixes #53 last read message indicator

This commit is contained in:
fourtf
2018-01-23 22:48:33 +01:00
parent 418189d39c
commit 0f4ec70bf3
11 changed files with 69 additions and 7 deletions
+12 -1
View File
@@ -145,7 +145,8 @@ void MessageLayout::actuallyLayout(int width, MessageElement::Flags flags)
} }
// Painting // Painting
void MessageLayout::paint(QPainter &painter, int y, int messageIndex, Selection &selection) void MessageLayout::paint(QPainter &painter, int y, int messageIndex, Selection &selection,
bool isLastReadMessage, bool isWindowFocused)
{ {
QPixmap *pixmap = this->buffer.get(); QPixmap *pixmap = this->buffer.get();
singletons::ThemeManager &themeManager = singletons::ThemeManager::getInstance(); singletons::ThemeManager &themeManager = singletons::ThemeManager::getInstance();
@@ -180,6 +181,16 @@ void MessageLayout::paint(QPainter &painter, int y, int messageIndex, Selection
// draw gif emotes // draw gif emotes
this->container.paintAnimatedElements(painter, y); this->container.paintAnimatedElements(painter, y);
// draw last read message line
if (isLastReadMessage) {
QColor color = isWindowFocused ? themeManager.tabs.selected.backgrounds.regular.color()
: themeManager.tabs.selected.backgrounds.unfocused.color();
QBrush brush = QBrush(color, Qt::VerPattern);
painter.fillRect(0, y + this->container.getHeight() - 1, this->container.width, 1, brush);
}
this->bufferValid = true; this->bufferValid = true;
} }
+2 -1
View File
@@ -41,7 +41,8 @@ public:
bool layout(int width, float scale, MessageElement::Flags flags); bool layout(int width, float scale, MessageElement::Flags flags);
// Painting // Painting
void paint(QPainter &painter, int y, int messageIndex, Selection &selection); void paint(QPainter &painter, int y, int messageIndex, Selection &selection,
bool isLastReadMessage, bool isWindowFocused);
void invalidateBuffer(); void invalidateBuffer();
void deleteBuffer(); void deleteBuffer();
+21 -1
View File
@@ -96,6 +96,9 @@ ChannelView::ChannelView(BaseWidget *parent)
auto e = new QResizeEvent(this->size(), this->size()); auto e = new QResizeEvent(this->size(), this->size());
this->resizeEvent(e); this->resizeEvent(e);
delete e; delete e;
singletons::SettingManager::getInstance().showLastMessageIndicator.connect(
[this](auto, auto) { this->update(); }, this->managedConnections);
} }
ChannelView::~ChannelView() ChannelView::~ChannelView()
@@ -410,6 +413,17 @@ void ChannelView::pause(int msecTimeout)
this->pauseTimeout.start(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 *) void ChannelView::resizeEvent(QResizeEvent *)
{ {
this->scrollBar.resize(this->scrollBar.width(), height()); this->scrollBar.resize(this->scrollBar.width(), height());
@@ -477,11 +491,17 @@ void ChannelView::drawMessages(QPainter &painter)
(fmod(this->scrollBar.getCurrentValue(), 1))); (fmod(this->scrollBar.getCurrentValue(), 1)));
messages::MessageLayout *end = nullptr; messages::MessageLayout *end = nullptr;
bool windowFocused = this->window() == QApplication::activeWindow();
for (size_t i = start; i < messagesSnapshot.getLength(); ++i) { for (size_t i = start; i < messagesSnapshot.getLength(); ++i) {
messages::MessageLayout *layout = messagesSnapshot[i].get(); 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(); y += layout->getHeight();
+2
View File
@@ -39,6 +39,7 @@ public:
void setEnableScrollingToBottom(bool); void setEnableScrollingToBottom(bool);
bool getEnableScrollingToBottom() const; bool getEnableScrollingToBottom() const;
void pause(int msecTimeout); void pause(int msecTimeout);
void updateLastReadMessage();
void setChannel(SharedChannel channel); void setChannel(SharedChannel channel);
messages::LimitedQueueSnapshot<messages::MessageLayoutPtr> getMessagesSnapshot(); messages::LimitedQueueSnapshot<messages::MessageLayoutPtr> getMessagesSnapshot();
@@ -72,6 +73,7 @@ private:
bool messageWasAdded = false; bool messageWasAdded = false;
bool paused = false; bool paused = false;
QTimer pauseTimeout; QTimer pauseTimeout;
messages::MessageLayoutPtr lastReadMessage;
messages::LimitedQueueSnapshot<messages::MessageLayoutPtr> snapshot; messages::LimitedQueueSnapshot<messages::MessageLayoutPtr> snapshot;
+1 -1
View File
@@ -8,7 +8,7 @@
#define WINDOW_TOPMOST "Window always on top (requires restart)" #define WINDOW_TOPMOST "Window always on top (requires restart)"
#define INPUT_EMPTY "Hide input box when empty" #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 PAUSE_HOVERING "When hovering"
#define STREAMLINK_QUALITY "Choose", "Source", "High", "Medium", "Low", "Audio only" #define STREAMLINK_QUALITY "Choose", "Source", "High", "Medium", "Low", "Audio only"
+5
View File
@@ -252,6 +252,11 @@ void Split::updateGifEmotes()
this->view.queueUpdate(); this->view.queueUpdate();
} }
void Split::updateLastReadMessage()
{
this->view.updateLastReadMessage();
}
void Split::giveFocus(Qt::FocusReason reason) void Split::giveFocus(Qt::FocusReason reason)
{ {
this->input.textInput.setFocus(reason); this->input.textInput.setFocus(reason);
+1
View File
@@ -70,6 +70,7 @@ public:
bool hasFocus() const; bool hasFocus() const;
void layoutMessages(); void layoutMessages();
void updateGifEmotes(); void updateGifEmotes();
void updateLastReadMessage();
void drag(); void drag();
+1 -1
View File
@@ -143,7 +143,7 @@ void SplitContainer::addToLayout(Split *widget, std::pair<int, int> position)
this->refreshCurrentFocusCoordinates(); this->refreshCurrentFocusCoordinates();
} }
const std::vector<Split *> &SplitContainer::getChatWidgets() const const std::vector<Split *> &SplitContainer::getSplits() const
{ {
return this->splits; return this->splits;
} }
+1 -1
View File
@@ -33,7 +33,7 @@ public:
std::pair<int, int> removeFromLayout(Split *widget); std::pair<int, int> removeFromLayout(Split *widget);
void addToLayout(Split *widget, std::pair<int, int> position = std::pair<int, int>(-1, -1)); 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; NotebookTab *getTab() const;
void addChat(bool openChannelNameDialog = false, std::string chatUUID = std::string()); void addChat(bool openChannelNameDialog = false, std::string chatUUID = std::string());
+22 -1
View File
@@ -107,7 +107,7 @@ void Window::repaintVisibleChatWidgets(Channel *channel)
return; return;
} }
const std::vector<Split *> &widgets = page->getChatWidgets(); const std::vector<Split *> &widgets = page->getSplits();
for (auto it = widgets.begin(); it != widgets.end(); ++it) { for (auto it = widgets.begin(); it != widgets.end(); ++it) {
Split *widget = *it; Split *widget = *it;
@@ -140,6 +140,27 @@ void Window::closeEvent(QCloseEvent *)
this->closed(); 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() void Window::loadGeometry()
{ {
bool doSetGeometry = false; bool doSetGeometry = false;
+1
View File
@@ -57,6 +57,7 @@ public:
protected: protected:
virtual void closeEvent(QCloseEvent *event) override; virtual void closeEvent(QCloseEvent *event) override;
virtual bool event(QEvent *event) override;
private: private:
singletons::ThemeManager &themeManager; singletons::ThemeManager &themeManager;