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

View file

@ -145,7 +145,8 @@ void MessageLayout::actuallyLayout(int width, MessageElement::Flags flags)
}
// 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();
singletons::ThemeManager &themeManager = singletons::ThemeManager::getInstance();
@ -180,6 +181,16 @@ void MessageLayout::paint(QPainter &painter, int y, int messageIndex, Selection
// draw gif emotes
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;
}

View file

@ -41,7 +41,8 @@ public:
bool layout(int width, float scale, MessageElement::Flags flags);
// 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 deleteBuffer();

View file

@ -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()
@ -410,6 +413,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());
@ -477,11 +491,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();

View file

@ -39,6 +39,7 @@ public:
void setEnableScrollingToBottom(bool);
bool getEnableScrollingToBottom() const;
void pause(int msecTimeout);
void updateLastReadMessage();
void setChannel(SharedChannel channel);
messages::LimitedQueueSnapshot<messages::MessageLayoutPtr> getMessagesSnapshot();
@ -72,6 +73,7 @@ private:
bool messageWasAdded = false;
bool paused = false;
QTimer pauseTimeout;
messages::MessageLayoutPtr lastReadMessage;
messages::LimitedQueueSnapshot<messages::MessageLayoutPtr> snapshot;

View file

@ -8,7 +8,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"

View file

@ -252,6 +252,11 @@ void Split::updateGifEmotes()
this->view.queueUpdate();
}
void Split::updateLastReadMessage()
{
this->view.updateLastReadMessage();
}
void Split::giveFocus(Qt::FocusReason reason)
{
this->input.textInput.setFocus(reason);

View file

@ -70,6 +70,7 @@ public:
bool hasFocus() const;
void layoutMessages();
void updateGifEmotes();
void updateLastReadMessage();
void drag();

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;
}

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

View file

@ -107,7 +107,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 +140,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;

View file

@ -57,6 +57,7 @@ public:
protected:
virtual void closeEvent(QCloseEvent *event) override;
virtual bool event(QEvent *event) override;
private:
singletons::ThemeManager &themeManager;