Add scroll-down button

This commit is contained in:
Konstantinos Sideris 2017-10-27 22:20:33 +03:00
parent 8e15a5080d
commit 845228ac6a
8 changed files with 152 additions and 0 deletions

View file

@ -171,6 +171,7 @@ set(SRC_FILES
src/ui/Badge.cc src/ui/Badge.cc
src/ui/LoadingIndicator.cc src/ui/LoadingIndicator.cc
src/ui/FlatButton.cc src/ui/FlatButton.cc
src/ui/FloatingButton.cc
src/ui/Label.cc src/ui/Label.cc
src/ui/OverlayModal.cc src/ui/OverlayModal.cc
src/ui/ScrollBar.cc src/ui/ScrollBar.cc
@ -224,6 +225,7 @@ qt5_wrap_cpp(MOC_HEADERS
include/EmojiItemDelegate.h include/EmojiItemDelegate.h
include/EmojiPanel.h include/EmojiPanel.h
include/EmojiPickButton.h include/EmojiPickButton.h
include/ui/FloatingButton.h
include/ImageItem.h include/ImageItem.h
include/ImageOverlayDialog.h include/ImageOverlayDialog.h
include/JoinRoomDialog.h include/JoinRoomDialog.h

View file

@ -34,6 +34,8 @@
#include "RoomInfoListItem.h" #include "RoomInfoListItem.h"
#include "Text.h" #include "Text.h"
class FloatingButton;
namespace msgs = matrix::events::messages; namespace msgs = matrix::events::messages;
namespace events = matrix::events; namespace events = matrix::events;
@ -155,6 +157,8 @@ private:
int oldPosition_; int oldPosition_;
int oldHeight_; int oldHeight_;
FloatingButton *scrollDownBtn_;
TimelineDirection lastMessageDirection_; TimelineDirection lastMessageDirection_;
// The events currently rendered. Used for duplicate detection. // The events currently rendered. Used for duplicate detection.

View file

@ -0,0 +1,26 @@
#pragma once
#include "RaisedButton.h"
constexpr int DIAMETER = 40;
constexpr int ICON_SIZE = 18;
constexpr int OFFSET_X = 30;
constexpr int OFFSET_Y = 20;
class FloatingButton : public RaisedButton
{
Q_OBJECT
public:
FloatingButton(const QIcon &icon, QWidget *parent = nullptr);
QSize sizeHint() const override { return QSize(DIAMETER, DIAMETER); };
QRect buttonGeometry() const;
protected:
bool event(QEvent *event) override;
bool eventFilter(QObject *obj, QEvent *event) override;
void paintEvent(QPaintEvent *event) override;
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,013 B

View file

@ -22,6 +22,8 @@
<file>icons/ui/paper-clip-outline@2x.png</file> <file>icons/ui/paper-clip-outline@2x.png</file>
<file>icons/ui/angle-pointing-to-left.png</file> <file>icons/ui/angle-pointing-to-left.png</file>
<file>icons/ui/angle-pointing-to-left@2x.png</file> <file>icons/ui/angle-pointing-to-left@2x.png</file>
<file>icons/ui/angle-arrow-down.png</file>
<file>icons/ui/angle-arrow-down@2x.png</file>
<file>icons/emoji-categories/people.png</file> <file>icons/emoji-categories/people.png</file>
<file>icons/emoji-categories/people@2x.png</file> <file>icons/emoji-categories/people@2x.png</file>

View file

@ -27,6 +27,7 @@
#include "MessageEvent.h" #include "MessageEvent.h"
#include "MessageEventContent.h" #include "MessageEventContent.h"
#include "FloatingButton.h"
#include "ImageItem.h" #include "ImageItem.h"
#include "TimelineItem.h" #include "TimelineItem.h"
#include "TimelineView.h" #include "TimelineView.h"
@ -140,6 +141,16 @@ TimelineView::sliderMoved(int position)
if (!scroll_area_->verticalScrollBar()->isVisible()) if (!scroll_area_->verticalScrollBar()->isVisible())
return; return;
const int maxScroll = scroll_area_->verticalScrollBar()->maximum();
const int currentScroll = scroll_area_->verticalScrollBar()->value();
if (maxScroll - currentScroll > SCROLL_BAR_GAP) {
scrollDownBtn_->show();
scrollDownBtn_->raise();
} else {
scrollDownBtn_->hide();
}
// The scrollbar is high enough so we can start retrieving old events. // The scrollbar is high enough so we can start retrieving old events.
if (position < SCROLL_BAR_GAP) { if (position < SCROLL_BAR_GAP) {
if (isTimelineFinished) if (isTimelineFinished)
@ -376,6 +387,18 @@ TimelineView::init()
QSettings settings; QSettings settings;
local_user_ = settings.value("auth/user_id").toString(); local_user_ = settings.value("auth/user_id").toString();
QIcon icon;
icon.addFile(":/icons/icons/ui/angle-arrow-down.png");
scrollDownBtn_ = new FloatingButton(icon, this);
scrollDownBtn_->setBackgroundColor(QColor("#F5F5F5"));
scrollDownBtn_->setForegroundColor(QColor("black"));
scrollDownBtn_->hide();
connect(scrollDownBtn_, &QPushButton::clicked, this, [=]() {
const int max = scroll_area_->verticalScrollBar()->maximum();
scroll_area_->verticalScrollBar()->setValue(max);
});
top_layout_ = new QVBoxLayout(this); top_layout_ = new QVBoxLayout(this);
top_layout_->setSpacing(0); top_layout_->setSpacing(0);
top_layout_->setMargin(0); top_layout_->setMargin(0);

95
src/ui/FloatingButton.cc Normal file
View file

@ -0,0 +1,95 @@
#include <QPainterPath>
#include "FloatingButton.h"
FloatingButton::FloatingButton(const QIcon &icon, QWidget *parent)
: RaisedButton(parent)
{
setFixedSize(DIAMETER, DIAMETER);
setGeometry(buttonGeometry());
if (parentWidget())
parentWidget()->installEventFilter(this);
setFixedRippleRadius(50);
setIcon(icon);
raise();
}
QRect
FloatingButton::buttonGeometry() const
{
QWidget *parent = parentWidget();
if (!parent)
return QRect();
return QRect(parent->width() - (OFFSET_X + DIAMETER),
parent->height() - (OFFSET_Y + DIAMETER),
DIAMETER,
DIAMETER);
}
bool
FloatingButton::event(QEvent *event)
{
if (!parent())
return RaisedButton::event(event);
switch (event->type()) {
case QEvent::ParentChange: {
parent()->installEventFilter(this);
setGeometry(buttonGeometry());
break;
}
case QEvent::ParentAboutToChange: {
parent()->installEventFilter(this);
break;
}
default:
break;
}
return RaisedButton::event(event);
}
bool
FloatingButton::eventFilter(QObject *obj, QEvent *event)
{
const QEvent::Type type = event->type();
if (QEvent::Move == type || QEvent::Resize == type)
setGeometry(buttonGeometry());
return RaisedButton::eventFilter(obj, event);
}
void
FloatingButton::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QRect square = QRect(0, 0, DIAMETER, DIAMETER);
square.moveCenter(rect().center());
QPainter p(this);
p.setRenderHints(QPainter::Antialiasing);
QBrush brush;
brush.setStyle(Qt::SolidPattern);
brush.setColor(backgroundColor());
p.setBrush(brush);
p.setPen(Qt::NoPen);
p.drawEllipse(square);
QRect iconGeometry(0, 0, ICON_SIZE, ICON_SIZE);
iconGeometry.moveCenter(square.center());
QPixmap pixmap = icon().pixmap(QSize(ICON_SIZE, ICON_SIZE));
QPainter icon(&pixmap);
icon.setCompositionMode(QPainter::CompositionMode_SourceIn);
icon.fillRect(pixmap.rect(), foregroundColor());
p.drawPixmap(iconGeometry, pixmap);
}