1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QEVENT_P_H
5#define QEVENT_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists for the convenience
12// of other Qt classes. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtGui/private/qtguiglobal_p.h>
19#include <QtCore/qurl.h>
20#include <QtGui/qevent.h>
21#include <QtGui/qwindow.h>
22
23QT_BEGIN_NAMESPACE
24
25class QPointingDevice;
26
27/*!
28 \internal
29 \since 6.9
30
31 This class provides a way to store copies of QEvents. QEvents can otherwise
32 only be copied by \l{QEvent::clone()}{cloning}, which allocates the copy on
33 the heap. By befriending concrete QEvent subclasses, QEventStorage gains
34 access to their protected copy constructors.
35
36 It is similar to std::optional, but with a more targeted API.
37
38 Note that by storing an event in QEventStorage, it may be sliced.
39*/
40template <typename Event>
41class QEventStorage
42{
43 Q_DISABLE_COPY_MOVE(QEventStorage)
44 static_assert(std::is_base_of_v<QEvent, Event>);
45 union {
46 char m_eventNotSet; // could be std::monostate, but don't want to pay for <variant> include
47 Event m_event;
48 };
49 bool m_engaged = false;
50
51 void engage(const Event &e)
52 {
53 Q_ASSERT(!m_engaged);
54 new (&m_event) Event(e);
55 m_engaged = true;
56 }
57
58 void disengage()
59 {
60 Q_ASSERT(m_engaged);
61 m_event.~Event();
62 m_engaged = false;
63 }
64
65public:
66 QEventStorage() noexcept : m_eventNotSet{} {}
67 explicit QEventStorage(const Event &e)
68 {
69 engage(e);
70 }
71
72 ~QEventStorage()
73 {
74 if (m_engaged)
75 disengage();
76 }
77
78 explicit operator bool() const noexcept { return m_engaged; }
79 bool operator!() const noexcept { return !m_engaged; }
80
81 Event &store(const Event &e)
82 {
83 if (m_engaged)
84 disengage();
85 engage(e);
86 return m_event;
87 }
88
89 Event &storeUnlessAlias(const Event &e)
90 {
91 if (m_engaged && &e == &m_event)
92 return m_event;
93 return store(e);
94 }
95
96 const Event &operator*() const
97 {
98 Q_PRE(m_engaged);
99 return m_event;
100 }
101
102 Event &operator*()
103 {
104 Q_PRE(m_engaged);
105 return m_event;
106 }
107
108 const Event *operator->() const
109 {
110 Q_PRE(m_engaged);
111 return &m_event;
112 }
113
114 Event *operator->()
115 {
116 Q_PRE(m_engaged);
117 return &m_event;
118 }
119};
120
121class Q_GUI_EXPORT QMutableTouchEvent : public QTouchEvent
122{
123public:
124 QMutableTouchEvent(QEvent::Type eventType = QEvent::TouchBegin,
125 const QPointingDevice *device = nullptr,
126 Qt::KeyboardModifiers modifiers = Qt::NoModifier,
127 const QList<QEventPoint> &touchPoints = QList<QEventPoint>()) :
128 QTouchEvent(eventType, device, modifiers, touchPoints) { }
129 ~QMutableTouchEvent() override;
130
131 void setTarget(QObject *target) { m_target = target; }
132 void addPoint(const QEventPoint &point);
133
134 static void setTarget(QTouchEvent *e, QObject *target) { e->m_target = target; }
135 static void addPoint(QTouchEvent *e, const QEventPoint &point);
136};
137
138class Q_GUI_EXPORT QMutableSinglePointEvent : public QSinglePointEvent
139{
140public:
141 QMutableSinglePointEvent(const QSinglePointEvent &other) : QSinglePointEvent(other) {}
142 QMutableSinglePointEvent(Type type = QEvent::None, const QPointingDevice *device = nullptr, const QEventPoint &point = QEventPoint(),
143 Qt::MouseButton button = Qt::NoButton, Qt::MouseButtons buttons = Qt::NoButton,
144 Qt::KeyboardModifiers modifiers = Qt::NoModifier,
145 Qt::MouseEventSource source = Qt::MouseEventSynthesizedByQt) :
146 QSinglePointEvent(type, device, point, button, buttons, modifiers, source) { }
147 ~QMutableSinglePointEvent() override;
148
149 void setSource(Qt::MouseEventSource s) { m_source = s; }
150
151 bool isDoubleClick() { return m_doubleClick; }
152
153 void setDoubleClick(bool d = true) { m_doubleClick = d; }
154
155 static bool isDoubleClick(const QSinglePointEvent *ev)
156 {
157 return ev->m_doubleClick;
158 }
159
160 static void setDoubleClick(QSinglePointEvent *ev, bool d)
161 {
162 ev->m_doubleClick = d;
163 }
164};
165
166QT_END_NAMESPACE
167
168#endif // QEVENT_P_H
169

source code of qtbase/src/gui/kernel/qevent_p.h