added scrollbar and smooth scrolling

This commit is contained in:
fourtf
2017-01-26 04:26:40 +01:00
parent 3d6b9f7645
commit 700c756f5a
12 changed files with 333 additions and 10 deletions
+3
View File
@@ -59,6 +59,9 @@ ChatWidget::setChannelName(const QString &name)
} else {
this->channel = Channels::addChannel(channel);
}
this->view.layoutMessages();
this->view.repaint();
}
void
+29 -4
View File
@@ -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);
}
}
}
+7
View File
@@ -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;
+103
View File
@@ -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
View File
@@ -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();
};
}