Allow custom touch event processing in scroll area.
This commit is contained in:
parent
8908c9b5c0
commit
6fe9e08386
2 changed files with 47 additions and 27 deletions
|
|
@ -475,32 +475,27 @@ void ScrollArea::touchResetSpeed() {
|
||||||
_touchPrevPosValid = false;
|
_touchPrevPosValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScrollArea::eventFilter(QObject *obj, QEvent *e) {
|
bool ScrollArea::eventHook(QEvent *e) {
|
||||||
bool res = QScrollArea::eventFilter(obj, e);
|
const auto was = (e->type() == QEvent::LayoutRequest)
|
||||||
if (e->type() == QEvent::TouchBegin || e->type() == QEvent::TouchUpdate || e->type() == QEvent::TouchEnd || e->type() == QEvent::TouchCancel) {
|
? verticalScrollBar()->minimum()
|
||||||
QTouchEvent *ev = static_cast<QTouchEvent*>(e);
|
: 0;
|
||||||
if (_touchEnabled && ev->device()->type() == base::TouchDevice::TouchScreen) {
|
const auto result = RpWidgetBase<QScrollArea>::eventHook(e);
|
||||||
if (obj == widget()) {
|
if (was) {
|
||||||
touchEvent(ev);
|
// Because LayoutRequest resets custom-set minimum allowed value.
|
||||||
return true;
|
verticalScrollBar()->setMinimum(was);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return res;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScrollArea::eventFilter(QObject *obj, QEvent *e) {
|
||||||
|
const auto result = QScrollArea::eventFilter(obj, e);
|
||||||
|
return (obj == widget() && filterOutTouchEvent(e)) || result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScrollArea::viewportEvent(QEvent *e) {
|
bool ScrollArea::viewportEvent(QEvent *e) {
|
||||||
const auto type = e->type();
|
if (filterOutTouchEvent(e)) {
|
||||||
if (type == QEvent::TouchBegin
|
return true;
|
||||||
|| type == QEvent::TouchUpdate
|
} else if (e->type() == QEvent::Wheel) {
|
||||||
|| type == QEvent::TouchEnd
|
|
||||||
|| type == QEvent::TouchCancel) {
|
|
||||||
QTouchEvent *ev = static_cast<QTouchEvent*>(e);
|
|
||||||
if (_touchEnabled && ev->device()->type() == base::TouchDevice::TouchScreen) {
|
|
||||||
touchEvent(ev);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (type == QEvent::Wheel) {
|
|
||||||
if (_customWheelProcess
|
if (_customWheelProcess
|
||||||
&& _customWheelProcess(static_cast<QWheelEvent*>(e))) {
|
&& _customWheelProcess(static_cast<QWheelEvent*>(e))) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -509,6 +504,24 @@ bool ScrollArea::viewportEvent(QEvent *e) {
|
||||||
return QScrollArea::viewportEvent(e);
|
return QScrollArea::viewportEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScrollArea::filterOutTouchEvent(QEvent *e) {
|
||||||
|
const auto type = e->type();
|
||||||
|
if (type == QEvent::TouchBegin
|
||||||
|
|| type == QEvent::TouchUpdate
|
||||||
|
|| type == QEvent::TouchEnd
|
||||||
|
|| type == QEvent::TouchCancel) {
|
||||||
|
const auto ev = static_cast<QTouchEvent*>(e);
|
||||||
|
if (_customTouchProcess && _customTouchProcess(ev)) {
|
||||||
|
return true;
|
||||||
|
} else if (_touchEnabled
|
||||||
|
&& ev->device()->type() == base::TouchDevice::TouchScreen) {
|
||||||
|
touchEvent(ev);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void ScrollArea::touchEvent(QTouchEvent *e) {
|
void ScrollArea::touchEvent(QTouchEvent *e) {
|
||||||
if (!e->touchPoints().isEmpty()) {
|
if (!e->touchPoints().isEmpty()) {
|
||||||
_touchPrevPos = _touchPos;
|
_touchPrevPos = _touchPos;
|
||||||
|
|
@ -624,9 +637,12 @@ void ScrollArea::scrollContentsBy(int dx, int dy) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScrollArea::touchScroll(const QPoint &delta) {
|
bool ScrollArea::touchScroll(const QPoint &delta) {
|
||||||
int32 scTop = scrollTop(), scMax = scrollTopMax(), scNew = std::clamp(scTop - delta.y(), 0, scMax);
|
const auto scTop = scrollTop();
|
||||||
if (scNew == scTop) return false;
|
const auto scMax = scrollTopMax();
|
||||||
|
const auto scNew = std::clamp(scTop - delta.y(), 0, scMax);
|
||||||
|
if (scNew == scTop) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
scrollToY(scNew);
|
scrollToY(scNew);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -175,12 +175,16 @@ public:
|
||||||
void setCustomWheelProcess(Fn<bool(not_null<QWheelEvent*>)> process) {
|
void setCustomWheelProcess(Fn<bool(not_null<QWheelEvent*>)> process) {
|
||||||
_customWheelProcess = std::move(process);
|
_customWheelProcess = std::move(process);
|
||||||
}
|
}
|
||||||
|
void setCustomTouchProcess(Fn<bool(not_null<QTouchEvent*>)> process) {
|
||||||
|
_customTouchProcess = std::move(process);
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<> scrolls() const;
|
[[nodiscard]] rpl::producer<> scrolls() const;
|
||||||
[[nodiscard]] rpl::producer<> innerResizes() const;
|
[[nodiscard]] rpl::producer<> innerResizes() const;
|
||||||
[[nodiscard]] rpl::producer<> geometryChanged() const;
|
[[nodiscard]] rpl::producer<> geometryChanged() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool eventHook(QEvent *e) override;
|
||||||
bool eventFilter(QObject *obj, QEvent *e) override;
|
bool eventFilter(QObject *obj, QEvent *e) override;
|
||||||
|
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
@ -197,8 +201,7 @@ private:
|
||||||
void doSetOwnedWidget(object_ptr<QWidget> widget);
|
void doSetOwnedWidget(object_ptr<QWidget> widget);
|
||||||
object_ptr<QWidget> doTakeWidget();
|
object_ptr<QWidget> doTakeWidget();
|
||||||
|
|
||||||
void setWidget(QWidget *widget);
|
bool filterOutTouchEvent(QEvent *e);
|
||||||
|
|
||||||
void touchScrollTimer();
|
void touchScrollTimer();
|
||||||
bool touchScroll(const QPoint &delta);
|
bool touchScroll(const QPoint &delta);
|
||||||
void touchScrollUpdated(const QPoint &screenPos);
|
void touchScrollUpdated(const QPoint &screenPos);
|
||||||
|
|
@ -232,6 +235,7 @@ private:
|
||||||
base::Timer _touchScrollTimer;
|
base::Timer _touchScrollTimer;
|
||||||
|
|
||||||
Fn<bool(not_null<QWheelEvent*>)> _customWheelProcess;
|
Fn<bool(not_null<QWheelEvent*>)> _customWheelProcess;
|
||||||
|
Fn<bool(not_null<QTouchEvent*>)> _customTouchProcess;
|
||||||
bool _widgetAcceptsTouch = false;
|
bool _widgetAcceptsTouch = false;
|
||||||
|
|
||||||
object_ptr<QWidget> _widget = { nullptr };
|
object_ptr<QWidget> _widget = { nullptr };
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue