QmlMaterial 0.1.0
Loading...
Searching...
No Matches
popup_presenter.hpp
1#pragma once
2
3#include <QObject>
4#include <QPointer>
5#include <QVariant>
6#include <qqmlregistration.h>
7#include <vector>
8
9#include "qml_material/export.hpp"
10#include "qml_material/util/pool.hpp"
11
12class QQuickItem;
13
14namespace qml_material
15{
16
17class PopupPresenter;
18class PresentationAttached;
19
20class QML_MATERIAL_API PopupPresentation : public QObject {
21 Q_OBJECT
22 QML_NAMED_ELEMENT(PopupPresentation)
23 QML_UNCREATABLE("PopupPresentation objects are returned by PopupPresenter.present()")
24
25 Q_PROPERTY(Status status READ status NOTIFY statusChanged FINAL)
26 Q_PROPERTY(bool active READ active NOTIFY activeChanged FINAL)
27 Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged FINAL)
28 Q_PROPERTY(QVariant result READ result NOTIFY resultChanged FINAL)
29
30public:
31 enum Status
32 {
33 Loading,
34 WaitingForReady,
35 Opening,
36 Open,
37 Closing,
38 Closed,
39 Error,
40 Cancelled,
41 };
42 Q_ENUM(Status)
43
44 ~PopupPresentation() override;
45
46 auto status() const -> Status;
47 auto active() const -> bool;
48 auto errorString() const -> QString;
49 auto result() const -> QVariant;
50
51 Q_INVOKABLE void close();
52 Q_INVOKABLE void cancel();
53
54 Q_SIGNAL void statusChanged();
55 Q_SIGNAL void activeChanged();
56 Q_SIGNAL void errorStringChanged();
57 Q_SIGNAL void resultChanged();
58 Q_SIGNAL void opened();
59 Q_SIGNAL void completed(const QVariant& result);
60 Q_SIGNAL void closed();
61 Q_SIGNAL void failed(const QString& error);
62 Q_SIGNAL void cancelled();
63
64private Q_SLOTS:
65 void onPopupOpened();
66 void onPopupClosed();
67
68private:
69 friend class PopupPresenter;
70 friend class PresentationAttached;
71
72 enum class Finish
73 {
74 None,
75 Closed,
76 Error,
77 Cancelled,
78 };
79
80 explicit PopupPresentation(PopupPresenter* presenter);
81
82 void setStatus(Status value);
83 void setErrorString(QString value);
84 void setResult(QVariant value);
85
86 QPointer<PopupPresenter> m_presenter;
87 QPointer<PoolRequest> m_request;
88 QPointer<QObject> m_popup;
89 QPointer<PresentationAttached> m_attached;
90 Status m_status { Loading };
91 Finish m_finish { Finish::None };
92 QString m_errorString;
93 QVariant m_result;
94 bool m_terminal { false };
95 bool m_completed { false };
96};
97
98class QML_MATERIAL_API PresentationAttached final : public QObject {
99 Q_OBJECT
100
101 Q_PROPERTY(bool ready READ ready WRITE setReady NOTIFY readyChanged FINAL)
102
103public:
104 explicit PresentationAttached(QObject* parent = nullptr);
105
106 auto ready() const -> bool;
107 void setReady(bool value);
108
109 Q_INVOKABLE void fail(const QString& error);
110 Q_INVOKABLE void complete(const QVariant& result = {});
111
112 Q_SIGNAL void readyChanged();
113 Q_SIGNAL void failureReported(const QString& error);
114 Q_SIGNAL void completionRequested(const QVariant& result);
115
116private:
117 friend class PopupPresenter;
118
119 void bind(PopupPresentation* presentation);
120 void unbind(PopupPresentation* presentation);
121
122 QPointer<PopupPresentation> m_presentation;
123 QString m_errorString;
124 bool m_ready { true };
125 bool m_failed { false };
126};
127
128class QML_MATERIAL_API Presentation : public QObject {
129 Q_OBJECT
130 QML_NAMED_ELEMENT(Presentation)
131 QML_UNCREATABLE("Presentation is only available as an attached property")
132 QML_ATTACHED(PresentationAttached)
133
134public:
135 explicit Presentation(QObject* parent = nullptr);
136
137 static PresentationAttached* qmlAttachedProperties(QObject* object);
138};
139
140class QML_MATERIAL_API PopupPresenter : public QObject {
141 Q_OBJECT
142 QML_ELEMENT
143
144 Q_PROPERTY(QQuickItem* host READ host WRITE setHost NOTIFY hostChanged FINAL)
145 Q_PROPERTY(Pool::IncubationMode incubationMode READ incubationMode WRITE setIncubationMode
146 NOTIFY incubationModeChanged FINAL)
147
148public:
149 explicit PopupPresenter(QObject* parent = nullptr);
150 ~PopupPresenter() override;
151
152 auto host() const -> QQuickItem*;
153 void setHost(QQuickItem* value);
154
155 auto incubationMode() const -> Pool::IncubationMode;
156 void setIncubationMode(Pool::IncubationMode value);
157
158 Q_INVOKABLE PopupPresentation* present(const QVariant& source,
159 const QVariantMap& initialProperties = {});
160 Q_INVOKABLE void closeAll();
161
162 Q_SIGNAL void hostChanged();
163 Q_SIGNAL void incubationModeChanged();
164
165private:
166 friend class PopupPresentation;
167
168 void requestClose(PopupPresentation* presentation, PopupPresentation::Finish finish);
169 void handleRequest(PopupPresentation* presentation);
170 void attachPopup(PopupPresentation* presentation, QObject* popup);
171 void openPopup(PopupPresentation* presentation);
172 void failPresentation(PopupPresentation* presentation, QString error);
173 void finishPresentation(PopupPresentation* presentation, PopupPresentation::Finish finish);
174 void completePresentation(PopupPresentation* presentation, QVariant result);
175 void popupOpened(PopupPresentation* presentation);
176 void popupClosed(PopupPresentation* presentation);
177 void popupDestroyed(PopupPresentation* presentation);
178 void presentationDestroyed(PopupPresentation* presentation);
179 void retire(PopupPresentation* presentation);
180 void ensurePoolContext();
181
182 QPointer<QQuickItem> m_host;
183 Pool* m_pool;
184 Pool::IncubationMode m_incubationMode { Pool::AsynchronousIfNested };
185 std::vector<QPointer<PopupPresentation>> m_presentations;
186 bool m_destroying { false };
187};
188
189} // namespace qml_material