2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-31 06:35:14 +00:00

Fixed scrolling by a child widget in ScrollArea by touch screen.

ScrollArea now always generates MouseMove when scrolled.
Fixed crash in BotKeyboard resizing with style change.
Fixed stickers box animations.
This commit is contained in:
John Preston
2016-06-15 20:13:46 +03:00
parent a058b6e3a6
commit 84f704448a
16 changed files with 94 additions and 74 deletions

View File

@@ -432,7 +432,6 @@ CountrySelectBox::CountrySelectBox() : ItemListBox(st::countriesScroll, st::boxW
, _topShadow(this) {
ItemListBox::init(&_inner, st::boxScrollSkip, st::boxTitleHeight + _filter.height());
connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(updateSel()));
connect(&_filter, SIGNAL(changed()), this, SLOT(onFilterUpdate()));
connect(&_filter, SIGNAL(submitted(bool)), this, SLOT(onSubmit()));
connect(&_filterCancel, SIGNAL(clicked()), this, SLOT(onFilterCancel()));

View File

@@ -77,6 +77,12 @@ signals:
void blurred();
protected:
void enterEventHook(QEvent *e) {
return QLineEdit::enterEvent(e);
}
void leaveEventHook(QEvent *e) {
return QLineEdit::leaveEvent(e);
}
virtual void correctValue(const QString &was, QString &now);
@@ -561,6 +567,12 @@ signals:
void blurred();
protected:
void enterEventHook(QEvent *e) {
return QLineEdit::enterEvent(e);
}
void leaveEventHook(QEvent *e) {
return QLineEdit::leaveEvent(e);
}
virtual void correctValue(const QString &was, int32 wasCursor, QString &now, int32 &nowCursor);
virtual void paintPlaceholder(Painter &p);

View File

@@ -142,6 +142,12 @@ signals:
void linksChanged();
protected:
void enterEventHook(QEvent *e) {
return QTextEdit::enterEvent(e);
}
void leaveEventHook(QEvent *e) {
return QTextEdit::leaveEvent(e);
}
bool viewportEvent(QEvent *e) override;
void touchEvent(QTouchEvent *e);

View File

@@ -239,6 +239,8 @@ void ScrollBar::mousePressEvent(QMouseEvent *e) {
_a_appearance.start();
}
}
area()->setMovingByScrollBar(true);
emit area()->scrollStarted();
}
@@ -262,6 +264,8 @@ void ScrollBar::mouseReleaseEvent(QMouseEvent *e) {
}
}
if (a) _a_appearance.start();
area()->setMovingByScrollBar(false);
emit area()->scrollFinished();
}
if (!_over) {
@@ -377,7 +381,12 @@ void ScrollArea::onScrolled() {
em = true;
}
}
if (em) emit scrolled();
if (em) {
emit scrolled();
if (!_movingByScrollBar) {
sendSynteticMouseEvent(this, QEvent::MouseMove, Qt::NoButton);
}
}
}
int ScrollArea::scrollWidth() const {
@@ -481,10 +490,8 @@ bool ScrollArea::eventFilter(QObject *obj, QEvent *e) {
QTouchEvent *ev = static_cast<QTouchEvent*>(e);
if (_touchEnabled && ev->device()->type() == QTouchDevice::TouchScreen) {
if (obj == widget()) {
if (ev->type() != QEvent::TouchBegin || ev->touchPoints().isEmpty() || !widget() || !widget()->childAt(widget()->mapFromGlobal(ev->touchPoints().cbegin()->screenPos().toPoint()))) {
touchEvent(ev);
return true;
}
touchEvent(ev);
return true;
}
}
}
@@ -495,10 +502,8 @@ bool ScrollArea::viewportEvent(QEvent *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() == QTouchDevice::TouchScreen) {
if (ev->type() != QEvent::TouchBegin || ev->touchPoints().isEmpty() || !widget() || !widget()->childAt(widget()->mapFromGlobal(ev->touchPoints().cbegin()->screenPos().toPoint()))) {
touchEvent(ev);
return true;
}
touchEvent(ev);
return true;
}
}
return QScrollArea::viewportEvent(e);
@@ -566,23 +571,20 @@ void ScrollArea::touchEvent(QTouchEvent *e) {
_touchWaitingAcceleration = false;
_touchPrevPosValid = false;
}
} else if (window() && widget()) { // one short tap -- like left mouse click, one long tap -- like right mouse click
#ifdef Q_OS_WIN
} else if (window()) { // one short tap -- like left mouse click, one long tap -- like right mouse click
Qt::MouseButton btn(_touchRightButton ? Qt::RightButton : Qt::LeftButton);
QPoint mapped(widget()->mapFromGlobal(_touchStart)), winMapped(window()->mapFromGlobal(_touchStart));
QMouseEvent pressEvent(QEvent::MouseButtonPress, mapped, winMapped, _touchStart, btn, Qt::MouseButtons(btn), Qt::KeyboardModifiers());
pressEvent.accept();
qt_sendSpontaneousEvent(widget(), &pressEvent);
QMouseEvent releaseEvent(QEvent::MouseButtonRelease, mapped, winMapped, _touchStart, btn, Qt::MouseButtons(btn), Qt::KeyboardModifiers());
qt_sendSpontaneousEvent(widget(), &releaseEvent);
sendSynteticMouseEvent(this, QEvent::MouseMove, Qt::NoButton, _touchStart);
sendSynteticMouseEvent(this, QEvent::MouseButtonPress, btn, _touchStart);
sendSynteticMouseEvent(this, QEvent::MouseButtonRelease, btn, _touchStart);
if (_touchRightButton) {
QContextMenuEvent contextEvent(QContextMenuEvent::Mouse, mapped, _touchStart);
qt_sendSpontaneousEvent(widget(), &contextEvent);
auto windowHandle = window()->windowHandle();
auto localPoint = windowHandle->mapFromGlobal(_touchStart);
QContextMenuEvent ev(QContextMenuEvent::Mouse, localPoint, _touchStart, QGuiApplication::keyboardModifiers());
ev.setTimestamp(getms());
QGuiApplication::sendEvent(windowHandle, &ev);
}
#endif
}
_touchTimer.stop();
_touchRightButton = false;
@@ -654,24 +656,20 @@ void ScrollArea::keyPressEvent(QKeyEvent *e) {
}
}
void ScrollArea::enterEvent(QEvent *e) {
void ScrollArea::enterEventHook(QEvent *e) {
if (_disabled) return;
if (_st.hiding) {
hor.hideTimeout(_st.hiding);
vert.hideTimeout(_st.hiding);
}
TWidget *p(tparent());
if (p) p->leaveToChildEvent(e);
return QScrollArea::enterEvent(e);
}
void ScrollArea::leaveEvent(QEvent *e) {
void ScrollArea::leaveEventHook(QEvent *e) {
if (_st.hiding) {
hor.hideTimeout(0);
vert.hideTimeout(0);
}
TWidget *p(tparent());
if (p) p->enterFromChildEvent(e);
return QScrollArea::leaveEvent(e);
}
@@ -794,6 +792,10 @@ bool ScrollArea::focusNextPrevChild(bool next) {
return false;
}
void ScrollArea::setMovingByScrollBar(bool movingByScrollBar) {
_movingByScrollBar = movingByScrollBar;
}
ScrollArea::~ScrollArea() {
if (!_ownsWidget) {
takeWidget();

View File

@@ -160,6 +160,7 @@ private:
class SplittedWidgetOther;
class ScrollArea : public QScrollArea {
Q_OBJECT
T_WIDGET
public:
@@ -174,9 +175,6 @@ public:
void moveEvent(QMoveEvent *e);
void keyPressEvent(QKeyEvent *e);
void enterEvent(QEvent *e);
void leaveEvent(QEvent *e);
int scrollWidth() const;
int scrollHeight() const;
int scrollLeftMax() const;
@@ -193,9 +191,15 @@ public:
void updateColors(const style::color &bar, const style::color &bg, const style::color &barOver, const style::color &bgOver);
bool focusNextPrevChild(bool next);
void setMovingByScrollBar(bool movingByScrollBar);
~ScrollArea();
protected:
void enterEventHook(QEvent *e);
void leaveEventHook(QEvent *e);
public slots:
void scrollToY(int toTop, int toBottom = -1);
@@ -220,12 +224,6 @@ signals:
protected:
void scrollContentsBy(int dx, int dy);
TWidget *tparent() {
return qobject_cast<TWidget*>(parentWidget());
}
const TWidget *tparent() const {
return qobject_cast<const TWidget*>(parentWidget());
}
private:
@@ -239,6 +237,7 @@ private:
bool _disabled;
bool _ownsWidget = false; // if true, the widget is deleted in destructor.
bool _movingByScrollBar = false;
style::flatScroll _st;
ScrollBar hor, vert;

View File

@@ -119,3 +119,11 @@ void ToggleableShadow::paintEvent(QPaintEvent *e) {
}
p.fillRect(e->rect(), _color);
}
void sendSynteticMouseEvent(QWidget *widget, QEvent::Type type, Qt::MouseButton button, const QPoint &globalPoint) {
auto windowHandle = widget->window()->windowHandle();
auto localPoint = windowHandle->mapFromGlobal(globalPoint);
QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, QGuiApplication::mouseButtons() | button, QGuiApplication::keyboardModifiers(), Qt::MouseEventSynthesizedByApplication);
ev.setTimestamp(getms());
QGuiApplication::sendEvent(windowHandle, &ev);
}

View File

@@ -159,12 +159,12 @@ protected: \
void enterEvent(QEvent *e) override { \
TWidget *p(tparent()); \
if (p) p->leaveToChildEvent(e); \
return QWidget::enterEvent(e); \
return enterEventHook(e); \
} \
void leaveEvent(QEvent *e) override { \
TWidget *p(tparent()); \
if (p) p->enterFromChildEvent(e); \
return QWidget::leaveEvent(e); \
return leaveEventHook(e); \
}
class TWidget : public QWidget {
@@ -199,6 +199,14 @@ public:
}
}
protected:
void enterEventHook(QEvent *e) {
return QWidget::enterEvent(e);
}
void leaveEventHook(QEvent *e) {
return QWidget::leaveEvent(e);
}
};
void myEnsureResized(QWidget *target);
@@ -330,3 +338,9 @@ private:
T *_widget;
};
void sendSynteticMouseEvent(QWidget *widget, QEvent::Type type, Qt::MouseButton button, const QPoint &globalPoint);
inline void sendSynteticMouseEvent(QWidget *widget, QEvent::Type type, Qt::MouseButton button) {
return sendSynteticMouseEvent(widget, type, button, QCursor::pos());
}