/* This file is part of Telegram Desktop, an unofficial desktop messaging app, see https://telegram.org Telegram Desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014 John Preston, https://tdesktop.com */ #pragma once #include #include "style.h" enum TouchScrollState { TouchScrollManual, // Scrolling manually with the finger on the screen TouchScrollAuto, // Scrolling automatically TouchScrollAcceleration // Scrolling automatically but a finger is on the screen }; class ScrollArea; class ScrollShadow : public QWidget { Q_OBJECT public: ScrollShadow(ScrollArea *parent, const style::flatScroll *st); void paintEvent(QPaintEvent *e); public slots: void changeVisibility(bool shown); private: const style::flatScroll *_st; }; class ScrollBar : public QWidget, public Animated { Q_OBJECT public: ScrollBar(ScrollArea *parent, bool vertical, const style::flatScroll *st); void recountSize(); void paintEvent(QPaintEvent *e); void enterEvent(QEvent *e); void leaveEvent(QEvent *e); void mouseMoveEvent(QMouseEvent *e); void mousePressEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e); void resizeEvent(QResizeEvent *e); bool animStep(float64 ms); void hideTimeout(int64 dt); public slots: void updateBar(); void onHideTimer(); signals: void topShadowVisibility(bool); void bottomShadowVisibility(bool); private: ScrollArea *_area; const style::flatScroll *_st; bool _vertical; bool _over, _overbar, _moving; bool _topSh, _bottomSh; QPoint _dragStart; QScrollBar *_connected; int32 _startFrom, _scrollMax; int64 _hideIn; QTimer _hideTimer; anim::cvalue a_bg, a_bar; QRect _bar; }; class ScrollArea : public QScrollArea { Q_OBJECT public: ScrollArea(QWidget *parent, const style::flatScroll &st = st::scrollDef, bool handleTouch = true); bool viewportEvent(QEvent *e); void touchEvent(QTouchEvent *e); bool eventFilter(QObject *obj, QEvent *e); void resizeEvent(QResizeEvent *e); void moveEvent(QMoveEvent *e); void enterEvent(QEvent *e); void leaveEvent(QEvent *e); int scrollWidth() const; int scrollHeight() const; int scrollLeftMax() const; int scrollTopMax() const; int scrollLeft() const; int scrollTop() const; void setWidget(QWidget *widget); void rangeChanged(int oldMax, int newMax, bool vertical); public slots: void scrollToY(int toTop, int toBottom = -1); void onScrolled(); void onTouchTimer(); void onTouchScrollTimer(); signals: void scrolled(); void scrollStarted(); void scrollFinished(); void geometryChanged(); private: bool touchScroll(const QPoint &delta); void touchScrollUpdated(const QPoint &screenPos); void touchResetSpeed(); void touchUpdateSpeed(); void touchDeaccelerate(int32 elapsed); style::flatScroll _st; ScrollBar hor, vert; ScrollShadow topSh, bottomSh; int32 _horValue, _vertValue; bool _touchEnabled; QTimer _touchTimer; bool _touchScroll, _touchPress, _touchRightButton; QPoint _touchStart, _touchPrevPos, _touchPos; TouchScrollState _touchScrollState; bool _touchPrevPosValid, _touchWaitingAcceleration; QPoint _touchSpeed; uint64 _touchSpeedTime, _touchAccelerationTime, _touchTime; QTimer _touchScrollTimer; bool _widgetAcceptsTouch; };