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