Krita Source Code Documentation
Loading...
Searching...
No Matches
KisLongPressEventFilter Class Reference

#include <KisLongPressEventFilter.h>

+ Inheritance diagram for KisLongPressEventFilter:

Public Member Functions

bool eventFilter (QObject *watched, QEvent *event) override
 
 KisLongPressEventFilter (QObject *parent=nullptr)
 

Static Public Attributes

static constexpr char ENABLED_PROPERTY [] = "KRITA_LONG_PRESS"
 

Private Member Functions

void cancel ()
 
void handleMouseMove (const QMouseEvent *me)
 
void handleMousePress (QWidget *target, const QMouseEvent *me)
 
bool isWithinDistance (const QPoint &globalPos) const
 
void triggerLongPress ()
 

Static Private Member Functions

static bool isContextMenuTarget (QWidget *target)
 
static bool isLongPressableWidget (QWidget *target)
 

Private Attributes

long long m_distanceSquared = 0LL
 
QPoint m_pressGlobalPos
 
QPoint m_pressLocalPos
 
QPointer< QWidget > m_target
 
QTimer * m_timer
 

Static Private Attributes

static constexpr int MINIMUM_DELAY = 100
 
static constexpr int MINIMUM_DISTANCE = 0
 

Detailed Description

Definition at line 12 of file KisLongPressEventFilter.h.

Constructor & Destructor Documentation

◆ KisLongPressEventFilter()

KisLongPressEventFilter::KisLongPressEventFilter ( QObject * parent = nullptr)
explicit

Definition at line 20 of file KisLongPressEventFilter.cpp.

21 : QObject(parent)
22{
23 m_timer = new QTimer(this);
24 m_timer->setTimerType(Qt::CoarseTimer);
25 m_timer->setSingleShot(true);
27}
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))

References connect(), m_timer, and triggerLongPress().

Member Function Documentation

◆ cancel()

void KisLongPressEventFilter::cancel ( )
private

Definition at line 86 of file KisLongPressEventFilter.cpp.

87{
88 m_timer->stop();
89 m_target.clear();
90}

References m_target, and m_timer.

◆ eventFilter()

bool KisLongPressEventFilter::eventFilter ( QObject * watched,
QEvent * event )
override

Definition at line 29 of file KisLongPressEventFilter.cpp.

30{
31 switch (event->type()) {
32 case QEvent::MouseButtonPress:
33 case QEvent::MouseButtonDblClick:
34 handleMousePress(qobject_cast<QWidget *>(watched), static_cast<QMouseEvent *>(event));
35 break;
36 case QEvent::MouseMove:
37 handleMouseMove(static_cast<QMouseEvent *>(event));
38 break;
39 case QEvent::MouseButtonRelease:
40 cancel();
41 break;
42 default:
43 break;
44 }
45 return QObject::eventFilter(watched, event);
46}
void handleMousePress(QWidget *target, const QMouseEvent *me)
void handleMouseMove(const QMouseEvent *me)

References cancel(), handleMouseMove(), and handleMousePress().

◆ handleMouseMove()

void KisLongPressEventFilter::handleMouseMove ( const QMouseEvent * me)
private

Definition at line 74 of file KisLongPressEventFilter.cpp.

75{
76#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
77 QPoint globalPos = me->globalPos();
78#else
79 QPoint globalPos = me->globalPosition().toPoint();
80#endif
81 if (m_timer->isActive() && !isWithinDistance(globalPos)) {
82 cancel();
83 }
84}
bool isWithinDistance(const QPoint &globalPos) const

References cancel(), isWithinDistance(), and m_timer.

◆ handleMousePress()

void KisLongPressEventFilter::handleMousePress ( QWidget * target,
const QMouseEvent * me )
private

Definition at line 48 of file KisLongPressEventFilter.cpp.

49{
51 const QStyleHints *sh = qApp->styleHints();
52 long long distance = qMax(MINIMUM_DISTANCE, sh->startDragDistance());
54#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
55 m_pressLocalPos = me->pos();
56 m_pressGlobalPos = me->globalPos();
57#else
58 m_pressLocalPos = me->position().toPoint();
59 m_pressGlobalPos = me->globalPosition().toPoint();
60#endif
62#ifdef Q_OS_ANDROID
63 int longPressInterval =
64 QAndroidJniObject::callStaticMethod<jint>("org/krita/android/MainActivity", "getLongPressTimeout", "()I");
65#else
66 int longPressInterval = sh->mousePressAndHoldInterval();
67#endif
68 m_timer->start(qMax(MINIMUM_DELAY, longPressInterval));
69 } else {
70 cancel();
71 }
72}
KisMagneticGraph::vertex_descriptor target(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
qreal distance(const QPointF &p1, const QPointF &p2)
static constexpr int MINIMUM_DISTANCE
static constexpr int MINIMUM_DELAY
static bool isContextMenuTarget(QWidget *target)

References cancel(), distance(), isContextMenuTarget(), m_distanceSquared, m_pressGlobalPos, m_pressLocalPos, m_target, m_timer, MINIMUM_DELAY, MINIMUM_DISTANCE, and target().

◆ isContextMenuTarget()

bool KisLongPressEventFilter::isContextMenuTarget ( QWidget * target)
staticprivate

Definition at line 107 of file KisLongPressEventFilter.cpp.

108{
109 while (target && target->isVisible() && isLongPressableWidget(target)) {
110 switch (target->contextMenuPolicy()) {
111 case Qt::NoContextMenu:
112 target = target->parentWidget();
113 break;
114 case Qt::PreventContextMenu:
115 return false;
116 default:
117 return true;
118 }
119 }
120 return false;
121}
static bool isLongPressableWidget(QWidget *target)

References isLongPressableWidget(), and target().

◆ isLongPressableWidget()

bool KisLongPressEventFilter::isLongPressableWidget ( QWidget * target)
staticprivate

Definition at line 123 of file KisLongPressEventFilter.cpp.

124{
125 QVariant prop = target->property(ENABLED_PROPERTY);
126 if (prop.isValid()) {
127 return prop.toBool();
128 }
129
130 // Several widget types don't have desirable long-press behavior. If they're
131 // our own widgets, we should just fix that in the widget, but we can"t
132 // really sensibly do that to Qt's widgets. Luckily however, those widgets
133 // really shouldn't have context menus in the first place, so we can just
134 // disregard them as long-press targets and be done with it.
135
136 // Buttons get depressed when you click and hold on them and won't pop back
137 // up if a context menu is opened during that. They may also have a menu
138 // attached to them that the user operates like a context menu.
139 if (qobject_cast<QAbstractButton *>(target)) {
140 return false;
141 }
142
143 // Slightly non-obvious, but this thing has many child classes, like text
144 // areas or the canvas, none of which have sensible context menus.
145 if (qobject_cast<QAbstractScrollArea *>(target)) {
146 return false;
147 }
148
149 // Sliders (including scrollbars) may get dragged slowly.
150 if (qobject_cast<QAbstractSlider *>(target)) {
151 return false;
152 }
153
154 // Spinners may get held down to keep a number spinning.
155 if (qobject_cast<QAbstractSpinBox *>(target)) {
156 return false;
157 }
158
159 // Combo boxes get held down to pick an item.
160 if (qobject_cast<QComboBox *>(target)) {
161 return false;
162 }
163
164 // Text editing will have its own long-press handling.
165 if (qobject_cast<QLineEdit *>(target)) {
166 return false;
167 }
168
169 // Menus don't have context menus.
170 if (qobject_cast<QMenu *>(target)) {
171 return false;
172 }
173
174 // Menu bars don't have context menus either.
175 if (qobject_cast<QMenuBar *>(target)) {
176 return false;
177 }
178
179 return true;
180}
static constexpr char ENABLED_PROPERTY[]

References ENABLED_PROPERTY, and target().

◆ isWithinDistance()

bool KisLongPressEventFilter::isWithinDistance ( const QPoint & globalPos) const
private

Definition at line 92 of file KisLongPressEventFilter.cpp.

93{
94 long long x = globalPos.x() - m_pressGlobalPos.x();
95 long long y = globalPos.y() - m_pressGlobalPos.y();
96 return (x * x) + (y * y) <= m_distanceSquared;
97}

References m_distanceSquared, and m_pressGlobalPos.

◆ triggerLongPress()

void KisLongPressEventFilter::triggerLongPress ( )
private

Definition at line 99 of file KisLongPressEventFilter.cpp.

100{
101 QWidget *target = m_target.data();
103 qApp->postEvent(target, new QContextMenuEvent(QContextMenuEvent::Mouse, m_pressLocalPos, m_pressGlobalPos));
104 }
105}

References isContextMenuTarget(), m_pressGlobalPos, m_pressLocalPos, m_target, and target().

Member Data Documentation

◆ ENABLED_PROPERTY

constexpr char KisLongPressEventFilter::ENABLED_PROPERTY[] = "KRITA_LONG_PRESS"
staticconstexpr

Definition at line 16 of file KisLongPressEventFilter.h.

◆ m_distanceSquared

long long KisLongPressEventFilter::m_distanceSquared = 0LL
private

Definition at line 38 of file KisLongPressEventFilter.h.

◆ m_pressGlobalPos

QPoint KisLongPressEventFilter::m_pressGlobalPos
private

Definition at line 40 of file KisLongPressEventFilter.h.

◆ m_pressLocalPos

QPoint KisLongPressEventFilter::m_pressLocalPos
private

Definition at line 39 of file KisLongPressEventFilter.h.

◆ m_target

QPointer<QWidget> KisLongPressEventFilter::m_target
private

Definition at line 41 of file KisLongPressEventFilter.h.

◆ m_timer

QTimer* KisLongPressEventFilter::m_timer
private

Definition at line 37 of file KisLongPressEventFilter.h.

◆ MINIMUM_DELAY

constexpr int KisLongPressEventFilter::MINIMUM_DELAY = 100
staticconstexprprivate

Definition at line 23 of file KisLongPressEventFilter.h.

◆ MINIMUM_DISTANCE

constexpr int KisLongPressEventFilter::MINIMUM_DISTANCE = 0
staticconstexprprivate

Definition at line 24 of file KisLongPressEventFilter.h.


The documentation for this class was generated from the following files: