mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-25 12:38:48 +03:00
Add scroll-down button
This commit is contained in:
parent
8e15a5080d
commit
845228ac6a
8 changed files with 152 additions and 0 deletions
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
26
include/ui/FloatingButton.h
Normal file
26
include/ui/FloatingButton.h
Normal 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;
|
||||||
|
};
|
BIN
resources/icons/ui/angle-arrow-down.png
Normal file
BIN
resources/icons/ui/angle-arrow-down.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 698 B |
BIN
resources/icons/ui/angle-arrow-down@2x.png
Normal file
BIN
resources/icons/ui/angle-arrow-down@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1,013 B |
|
@ -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>
|
||||||
|
|
|
@ -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
95
src/ui/FloatingButton.cc
Normal 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);
|
||||||
|
}
|
Loading…
Reference in a new issue