Krita Source Code Documentation
Loading...
Searching...
No Matches
KisPopupWidgetAction.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2 * SPDX-FileCopyrightText: 2012 Arjen Hiemstra <ahiemstra@heimr.nl>
3 * SPDX-FileCopyrightText: 2021 Emmet O 'Neill <emmetoneill.pdx@gmail.com>
4 * SPDX-FileCopyrightText: 2021 Eoin O 'Neill <eoinoneill1991@gmail.com>
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
10
11#include <QCursor>
12#include <QMenu>
13#include <QTouchEvent>
14
15#include <klocalizedstring.h>
16
18#include <kis_canvas2.h>
19#include "kis_tool_proxy.h"
20#include "kis_popup_palette.h"
21#include "kis_input_manager.h"
22
23struct SinglePressEventEater : public QObject
24{
25 bool eventFilter(QObject *, QEvent *event) override {
26 if (hungry && event->type() == QEvent::MouseButtonPress) {
27 hungry = false;
28 return true;
29 }
30
31 return false;
32 }
33
34private:
35 bool hungry = true;
36};
37
38
39//=================================================================
40
42 : KisAbstractInputAction("Show Popup Widget")
43{
44 setName(i18n("Show Popup Widget"));
45 setDescription(i18n("Show the current tool's popup widget."));
46}
47
51
52void KisPopupWidgetAction::end(QEvent *event)
53{
54 if (QMenu *popupMenu = inputManager()->toolProxy()->popupActionsMenu()) { // Handle popup menus...
55 QEvent::Type requestingEventType = event ? event->type() : QEvent::None;
56
57 // Touch events don't update the cursor position.
58 QPointF touchPos;
59 if (requestingEventType == QEvent::TouchBegin) {
60 const QTouchEvent *touchEvent = static_cast<const QTouchEvent *>(event);
61#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
62 const QList<QEventPoint> &touchPoints = touchEvent->points();
63#else
64 const QList<QTouchEvent::TouchPoint> &touchPoints = touchEvent->touchPoints();
65#endif
66 if (touchPoints.isEmpty()) {
67 // Getting zero touch points can happen on Android when pressing
68 // on the screen with an entire palm. Punt to using the cursor
69 // position after all.
70 requestingEventType = QEvent::None;
71 } else {
72#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
73 touchPos = touchPoints.constFirst().globalPosition();
74#else
75 touchPos = touchPoints.constFirst().screenPos();
76#endif
77 }
78 }
79
84 QTimer::singleShot(0, this, [popupMenu, requestingEventType, touchPos](){
85 if (popupMenu) {
86 QPoint popupPos;
87 QScopedPointer<SinglePressEventEater> eventEater;
88
89 if (requestingEventType == QEvent::TabletPress) {
90 eventEater.reset(new SinglePressEventEater());
91 popupMenu->installEventFilter(eventEater.data());
92 popupPos = QCursor::pos() + QPoint(10,10);
93 } else if (requestingEventType == QEvent::TouchBegin) {
94 popupPos = touchPos.toPoint();
95 } else {
96 popupPos = QCursor::pos();
97 }
98
99 popupMenu->exec(popupPos);
100 popupMenu->clear();
101 }
102 });
103 } else if (KisPopupWidgetInterface *popupWidget = inputManager()->toolProxy()->popupWidget()) { // Handle other popup widgets...
104 if (!popupWidget->onScreen()) {
105 QPoint pos = eventPos(event);
106 if (pos.isNull()) {
107 pos = inputManager()->canvas()->canvasWidget()->mapFromGlobal(QCursor::pos());
108 }
109 inputManager()->registerPopupWidget(popupWidget);
110 popupWidget->popup(pos);
111 } else {
112 popupWidget->dismiss();
113 }
114 }
115}
Abstract base class for input actions.
static KisInputManager * inputManager
QPoint eventPos(const QEvent *event)
void setName(const QString &name)
void setDescription(const QString &description)
KisAbstractCanvasWidget * canvasWidget
KisCanvas2 * canvas() const
QPointer< KisToolProxy > toolProxy() const
void registerPopupWidget(KisPopupWidgetInterface *popupWidget)
void end(QEvent *) override
The PopupWidgetInterface abstract class defines the basic interface that will be used by all popup wi...
bool eventFilter(QObject *, QEvent *event) override