mirror-chatterino2/widgets/scrollbar.cpp

223 lines
5.1 KiB
C++
Raw Normal View History

2017-01-18 21:30:23 +01:00
#include "widgets/scrollbar.h"
2017-01-03 21:19:33 +01:00
#include "colorscheme.h"
2017-01-26 04:26:40 +01:00
#include <QMouseEvent>
2017-01-18 04:52:47 +01:00
#include <QPainter>
2017-01-18 04:33:30 +01:00
#define MIN_THUMB_HEIGHT 10
2017-01-18 21:30:23 +01:00
namespace chatterino {
namespace widgets {
2017-01-11 18:52:09 +01:00
ScrollBar::ScrollBar(QWidget *widget)
: QWidget(widget)
, mutex()
2017-01-26 04:26:40 +01:00
, valueAnimation(this, "value")
2017-01-18 04:33:30 +01:00
, highlights(NULL)
2017-01-26 04:26:40 +01:00
, mouseOverIndex(-1)
, mouseDownIndex(-1)
, lastMousePosition()
, buttonHeight(16)
, trackHeight(100)
2017-01-18 04:33:30 +01:00
, thumbRect()
, maximum()
, minimum()
, largeChange()
, smallChange()
, value()
2017-01-26 04:26:40 +01:00
, valueChanged()
2017-01-03 21:19:33 +01:00
{
resize(16, 100);
2017-01-26 04:26:40 +01:00
valueAnimation.setDuration(300);
valueAnimation.setEasingCurve(QEasingCurve(QEasingCurve::OutCubic));
this->setMouseTracking(true);
2017-01-03 21:19:33 +01:00
}
ScrollBar::~ScrollBar()
{
2017-01-18 04:33:30 +01:00
auto highlight = this->highlights;
2017-01-03 21:19:33 +01:00
2017-01-11 18:52:09 +01:00
while (highlight != NULL) {
2017-01-03 21:19:33 +01:00
auto tmp = highlight->next;
delete highlight;
highlight = tmp;
}
}
2017-01-11 18:52:09 +01:00
void
ScrollBar::removeHighlightsWhere(std::function<bool(ScrollBarHighlight &)> func)
2017-01-03 21:19:33 +01:00
{
2017-01-18 04:33:30 +01:00
this->mutex.lock();
2017-01-03 21:19:33 +01:00
2017-01-11 18:52:09 +01:00
ScrollBarHighlight *last = NULL;
2017-01-18 04:33:30 +01:00
ScrollBarHighlight *current = this->highlights;
2017-01-03 21:19:33 +01:00
2017-01-11 18:52:09 +01:00
while (current != NULL) {
if (func(*current)) {
if (last == NULL) {
2017-01-18 04:33:30 +01:00
this->highlights = current->next;
2017-01-11 18:52:09 +01:00
} else {
2017-01-03 21:19:33 +01:00
last->next = current->next;
}
auto oldCurrent = current;
current = current->next;
last = current;
delete oldCurrent;
}
}
2017-01-18 04:33:30 +01:00
this->mutex.unlock();
2017-01-03 21:19:33 +01:00
}
2017-01-11 18:52:09 +01:00
void
ScrollBar::addHighlight(ScrollBarHighlight *highlight)
2017-01-03 21:19:33 +01:00
{
2017-01-18 04:33:30 +01:00
this->mutex.lock();
2017-01-03 21:19:33 +01:00
2017-01-18 04:33:30 +01:00
if (this->highlights == NULL) {
this->highlights = highlight;
2017-01-11 18:52:09 +01:00
} else {
2017-01-18 04:33:30 +01:00
highlight->next = this->highlights->next;
this->highlights->next = highlight;
2017-01-03 21:19:33 +01:00
}
2017-01-18 04:33:30 +01:00
this->mutex.unlock();
2017-01-03 21:19:33 +01:00
}
2017-01-11 18:52:09 +01:00
void
ScrollBar::paintEvent(QPaintEvent *)
2017-01-03 21:19:33 +01:00
{
QPainter painter(this);
2017-01-24 20:15:12 +01:00
painter.fillRect(rect(), ColorScheme::getInstance().ScrollbarBG);
2017-01-03 21:19:33 +01:00
2017-01-18 04:33:30 +01:00
painter.fillRect(QRect(0, 0, width(), this->buttonHeight),
QColor(255, 0, 0));
painter.fillRect(
QRect(0, height() - this->buttonHeight, width(), this->buttonHeight),
QColor(255, 0, 0));
2017-01-26 04:26:40 +01:00
painter.fillRect(this->thumbRect, QColor(0, 255, 255));
2017-01-18 04:33:30 +01:00
ScrollBarHighlight *highlight = this->highlights;
this->mutex.lock();
// do {
// painter.fillRect();
// } while ((highlight = highlight->next()) != NULL);
2017-01-03 21:19:33 +01:00
2017-01-18 04:33:30 +01:00
this->mutex.unlock();
}
2017-01-26 04:26:40 +01:00
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) {
2017-01-26 07:10:46 +01:00
this->update();
2017-01-26 04:26:40 +01:00
}
} 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) {
2017-01-26 05:26:21 +01:00
this->setValue(this->value - this->smallChange, true);
2017-01-26 04:26:40 +01:00
}
} else if (y < this->thumbRect.y()) {
2017-01-26 05:26:21 +01:00
if (this->mouseDownIndex == 1) {
this->setValue(this->value - this->smallChange, true);
2017-01-26 04:26:40 +01:00
}
} else if (this->thumbRect.contains(2, y)) {
// do nothing
} else if (y < height() - this->buttonHeight) {
2017-01-26 05:26:21 +01:00
if (this->mouseDownIndex == 3) {
this->setValue(this->value + this->smallChange, true);
2017-01-26 04:26:40 +01:00
}
} else {
2017-01-26 05:26:21 +01:00
if (this->mouseDownIndex == 4) {
this->setValue(this->value + this->smallChange, true);
2017-01-26 04:26:40 +01:00
}
}
this->mouseDownIndex = -1;
2017-01-26 07:10:46 +01:00
update();
2017-01-26 04:26:40 +01:00
}
void
ScrollBar::leaveEvent(QEvent *)
{
this->mouseOverIndex = -1;
2017-01-26 07:10:46 +01:00
update();
2017-01-26 04:26:40 +01:00
}
2017-01-18 04:33:30 +01:00
void
ScrollBar::updateScroll()
{
this->trackHeight = height() - this->buttonHeight - this->buttonHeight -
MIN_THUMB_HEIGHT - 1;
this->thumbRect =
QRect(0,
(int)(this->value / this->maximum * this->trackHeight) + 1 +
this->buttonHeight,
width(),
(int)(this->largeChange / this->maximum * this->trackHeight) +
MIN_THUMB_HEIGHT);
2017-01-26 07:10:46 +01:00
update();
2017-01-03 21:19:33 +01:00
}
2017-01-18 21:30:23 +01:00
}
}