added scrollbar and smooth scrolling
This commit is contained in:
@@ -59,6 +59,9 @@ ChatWidget::setChannelName(const QString &name)
|
||||
} else {
|
||||
this->channel = Channels::addChannel(channel);
|
||||
}
|
||||
|
||||
this->view.layoutMessages();
|
||||
this->view.repaint();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include <math.h>
|
||||
#include <QPainter>
|
||||
#include <QScroller>
|
||||
#include <functional>
|
||||
|
||||
namespace chatterino {
|
||||
@@ -19,12 +18,12 @@ ChatWidgetView::ChatWidgetView(ChatWidget *parent)
|
||||
, chatWidget(parent)
|
||||
, scrollbar(this)
|
||||
{
|
||||
auto scroll = QScroller::scroller(this);
|
||||
|
||||
scroll->scrollTo(QPointF(0, 100));
|
||||
this->scrollbar.setSmallChange(2);
|
||||
|
||||
QObject::connect(&Settings::getInstance(), &Settings::wordTypeMaskChanged,
|
||||
this, &ChatWidgetView::wordTypeMaskChanged);
|
||||
|
||||
this->scrollbar.getValueChanged().connect([this] { repaint(); });
|
||||
}
|
||||
|
||||
ChatWidgetView::~ChatWidgetView()
|
||||
@@ -50,9 +49,25 @@ ChatWidgetView::layoutMessages()
|
||||
redraw |= message.get()->layout(this->width(), true);
|
||||
}
|
||||
|
||||
updateScrollbar();
|
||||
|
||||
return redraw;
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetView::updateScrollbar()
|
||||
{
|
||||
auto c = this->chatWidget->getChannel();
|
||||
|
||||
if (c == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// this->scrollbar.setValue(0);
|
||||
this->scrollbar.setLargeChange(10);
|
||||
this->scrollbar.setMaximum(c->getMessages().size());
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetView::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
@@ -163,5 +178,15 @@ ChatWidgetView::paintEvent(QPaintEvent *)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetView::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
this->scrollbar.setValue(
|
||||
this->scrollbar.getValue() -
|
||||
event->delta() / 10.0 *
|
||||
Settings::getInstance().mouseScrollMultiplier.get(),
|
||||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "widgets/scrollbar.h"
|
||||
|
||||
#include <QPaintEvent>
|
||||
#include <QScroller>
|
||||
#include <QWheelEvent>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
@@ -22,10 +24,15 @@ public:
|
||||
|
||||
bool layoutMessages();
|
||||
|
||||
void updateScrollbar();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *);
|
||||
|
||||
void paintEvent(QPaintEvent *);
|
||||
void wheelEvent(QWheelEvent *event);
|
||||
|
||||
void scroll(int dx, int dy);
|
||||
|
||||
private:
|
||||
ChatWidget *chatWidget;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "widgets/scrollbar.h"
|
||||
#include "colorscheme.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
|
||||
#define MIN_THUMB_HEIGHT 10
|
||||
@@ -11,15 +12,27 @@ namespace widgets {
|
||||
ScrollBar::ScrollBar(QWidget *widget)
|
||||
: QWidget(widget)
|
||||
, mutex()
|
||||
, valueAnimation(this, "value")
|
||||
, highlights(NULL)
|
||||
, mouseOverIndex(-1)
|
||||
, mouseDownIndex(-1)
|
||||
, lastMousePosition()
|
||||
, buttonHeight(16)
|
||||
, trackHeight(100)
|
||||
, thumbRect()
|
||||
, maximum()
|
||||
, minimum()
|
||||
, largeChange()
|
||||
, smallChange()
|
||||
, value()
|
||||
, valueChanged()
|
||||
{
|
||||
resize(16, 100);
|
||||
|
||||
valueAnimation.setDuration(300);
|
||||
valueAnimation.setEasingCurve(QEasingCurve(QEasingCurve::OutCubic));
|
||||
|
||||
this->setMouseTracking(true);
|
||||
}
|
||||
|
||||
ScrollBar::~ScrollBar()
|
||||
@@ -88,6 +101,8 @@ ScrollBar::paintEvent(QPaintEvent *)
|
||||
QRect(0, height() - this->buttonHeight, width(), this->buttonHeight),
|
||||
QColor(255, 0, 0));
|
||||
|
||||
painter.fillRect(this->thumbRect, QColor(0, 255, 255));
|
||||
|
||||
ScrollBarHighlight *highlight = this->highlights;
|
||||
|
||||
this->mutex.lock();
|
||||
@@ -99,6 +114,94 @@ ScrollBar::paintEvent(QPaintEvent *)
|
||||
this->mutex.unlock();
|
||||
}
|
||||
|
||||
void
|
||||
ScrollBar::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (this->mouseDownIndex == -1) {
|
||||
int y = event->pos().y();
|
||||
|
||||
auto oldIndex = this->mouseOverIndex;
|
||||
|
||||
if (y < this->buttonHeight) {
|
||||
this->mouseOverIndex = 0;
|
||||
} else if (y < this->thumbRect.y()) {
|
||||
this->mouseOverIndex = 1;
|
||||
} else if (this->thumbRect.contains(2, y)) {
|
||||
this->mouseOverIndex = 2;
|
||||
} else if (y < height() - this->buttonHeight) {
|
||||
this->mouseOverIndex = 3;
|
||||
} else {
|
||||
this->mouseOverIndex = 4;
|
||||
}
|
||||
|
||||
if (oldIndex != this->mouseOverIndex) {
|
||||
this->repaint();
|
||||
}
|
||||
} else if (this->mouseDownIndex == 2) {
|
||||
int delta = event->pos().y() - lastMousePosition.y();
|
||||
|
||||
this->setValue(this->value +
|
||||
(qreal)delta / this->trackHeight * maximum);
|
||||
}
|
||||
|
||||
this->lastMousePosition = event->pos();
|
||||
}
|
||||
|
||||
void
|
||||
ScrollBar::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
int y = event->pos().y();
|
||||
|
||||
if (y < this->buttonHeight) {
|
||||
this->mouseDownIndex = 0;
|
||||
} else if (y < this->thumbRect.y()) {
|
||||
this->mouseDownIndex = 1;
|
||||
} else if (this->thumbRect.contains(2, y)) {
|
||||
this->mouseDownIndex = 2;
|
||||
} else if (y < height() - this->buttonHeight) {
|
||||
this->mouseDownIndex = 3;
|
||||
} else {
|
||||
this->mouseDownIndex = 4;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScrollBar::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
int y = event->pos().y();
|
||||
|
||||
if (y < this->buttonHeight) {
|
||||
if (this->mouseDownIndex == 0) {
|
||||
this->setValue(this->value - this->smallChange);
|
||||
}
|
||||
} else if (y < this->thumbRect.y()) {
|
||||
if (this->mouseDownIndex == 0) {
|
||||
this->setValue(this->value - this->smallChange);
|
||||
}
|
||||
} else if (this->thumbRect.contains(2, y)) {
|
||||
// do nothing
|
||||
} else if (y < height() - this->buttonHeight) {
|
||||
if (this->mouseDownIndex == 0) {
|
||||
this->setValue(this->value + this->smallChange);
|
||||
}
|
||||
} else {
|
||||
if (this->mouseDownIndex == 0) {
|
||||
this->setValue(this->value + this->smallChange);
|
||||
}
|
||||
}
|
||||
|
||||
this->mouseDownIndex = -1;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void
|
||||
ScrollBar::leaveEvent(QEvent *)
|
||||
{
|
||||
this->mouseOverIndex = -1;
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void
|
||||
ScrollBar::updateScroll()
|
||||
{
|
||||
|
||||
+41
-3
@@ -4,7 +4,9 @@
|
||||
#include "widgets/scrollbarhighlight.h"
|
||||
|
||||
#include <QMutex>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QWidget>
|
||||
#include <boost/signals2.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace chatterino {
|
||||
@@ -21,6 +23,8 @@ public:
|
||||
void removeHighlightsWhere(std::function<bool(ScrollBarHighlight &)> func);
|
||||
void addHighlight(ScrollBarHighlight *highlight);
|
||||
|
||||
Q_PROPERTY(qreal value READ getValue WRITE setValue)
|
||||
|
||||
void
|
||||
setMaximum(qreal value)
|
||||
{
|
||||
@@ -54,11 +58,26 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
setValue(qreal value)
|
||||
setValue(qreal value, bool animated = false)
|
||||
{
|
||||
this->value = value;
|
||||
value = std::max(this->minimum,
|
||||
std::min(this->maximum - this->largeChange, value));
|
||||
|
||||
this->updateScroll();
|
||||
if (this->value != value) {
|
||||
if (animated) {
|
||||
this->valueAnimation.stop();
|
||||
this->valueAnimation.setStartValue(this->value);
|
||||
this->valueAnimation.setEndValue(value);
|
||||
this->valueAnimation.start();
|
||||
} else {
|
||||
this->value = value;
|
||||
}
|
||||
|
||||
this->updateScroll();
|
||||
this->valueChanged();
|
||||
|
||||
this->repaint();
|
||||
}
|
||||
}
|
||||
|
||||
qreal
|
||||
@@ -91,10 +110,27 @@ public:
|
||||
return this->value;
|
||||
}
|
||||
|
||||
boost::signals2::signal<void()> &
|
||||
getValueChanged()
|
||||
{
|
||||
return valueChanged;
|
||||
}
|
||||
|
||||
private:
|
||||
QMutex mutex;
|
||||
ScrollBarHighlight *highlights;
|
||||
|
||||
QPropertyAnimation valueAnimation;
|
||||
|
||||
void paintEvent(QPaintEvent *);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
void leaveEvent(QEvent *);
|
||||
|
||||
int mouseOverIndex;
|
||||
int mouseDownIndex;
|
||||
QPoint lastMousePosition;
|
||||
|
||||
int buttonHeight;
|
||||
int trackHeight;
|
||||
@@ -107,6 +143,8 @@ private:
|
||||
qreal smallChange;
|
||||
qreal value;
|
||||
|
||||
boost::signals2::signal<void()> valueChanged;
|
||||
|
||||
void updateScroll();
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user