Overte C++ Documentation
QmlWindowClass.h
1 //
2 // Created by Bradley Austin Davis on 2015-12-15
3 // Copyright 2015 High Fidelity, Inc.
4 // Copyright 2023 Overte e.V.
5 //
6 // Distributed under the Apache License, Version 2.0.
7 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
8 // SPDX-License-Identifier: Apache-2.0
9 //
10 
11 #ifndef hifi_ui_QmlWindowClass_h
12 #define hifi_ui_QmlWindowClass_h
13 
14 #include <QtCore/QObject>
15 #include <QtCore/QPointer>
16 #include <QtQuick/QQuickItem>
17 
18 #include <GLMHelpers.h>
19 #include <ScriptValue.h>
20 
21 class ScriptContext;
22 class ScriptEngine;
23 
24 /*@jsdoc
25  * A <code>OverlayWindow</code> displays a QML window inside Interface.
26  *
27  * <p>The QML can optionally include a <code>WebView</code> control that embeds an HTML-based windows. (The <code>WebView</code>
28  * control is defined by a "WebView.qml" file included in the Interface install.) Alternatively, an {@link OverlayWebWindow}
29  * can be used for HTML-based windows.</p>
30  *
31  * <p>Create using <code>new OverlayWindow(...)</code>.</p>
32  *
33  * @class OverlayWindow
34  * @param {string|OverlayWindow.Properties} [titleOrProperties="WebWindow"] - The window's title or initial property values.
35  * @param {string} [source] - The source of the QML to display. Not used unless the first parameter is the window title.
36  * @param {number} [width=0] - The width of the window interior, in pixels. Not used unless the first parameter is the window
37  * title.
38  * @param {number} [height=0] - The height of the window interior, in pixels. Not used unless the first parameter is the
39  * window title.
40  *
41  * @hifi-interface
42  * @hifi-client-entity
43  * @hifi-avatar
44  *
45  * @property {Vec2} position - The position of the window, in pixels.
46  * @property {Vec2} size - The size of the window interior, in pixels.
47  * @property {boolean} visible - <code>true</code> if the window is visible, <code>false</code> if it isn't.
48  */
49 
50 // FIXME refactor this class to be a QQuickItem derived type and eliminate the needless wrapping
51 class QmlWindowClass : public QObject {
52  Q_OBJECT
53  Q_PROPERTY(glm::vec2 position READ getPosition WRITE setPosition NOTIFY positionChanged)
54  Q_PROPERTY(glm::vec2 size READ getSize WRITE setSize NOTIFY sizeChanged)
55  Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
56 
57 private:
58  static ScriptValue internal_constructor(ScriptContext* context, ScriptEngine* engine, bool restricted);
59 public:
60  static ScriptValue constructor(ScriptContext* context, ScriptEngine* engine) {
61  return internal_constructor(context, engine, false);
62  }
63 
64  static ScriptValue restricted_constructor(ScriptContext* context, ScriptEngine* engine ){
65  return internal_constructor(context, engine, true);
66  }
67 
68  QmlWindowClass(bool restricted);
69  ~QmlWindowClass();
70 
71  /*@jsdoc
72  * @function OverlayWindow.initQml
73  * @param {OverlayWindow.Properties} properties - Properties.
74  * @deprecated This method is deprecated and will be removed.
75  */
76  // FIXME: This shouldn't be in the API. It is an internal function used in object construction.
77  Q_INVOKABLE virtual void initQml(QVariantMap properties);
78 
79  QQuickItem* asQuickItem() const;
80 
81 
82 
83 public slots:
84 
85  /*@jsdoc
86  * Gets whether the window is shown or hidden.
87  * @function OverlayWindow.isVisible
88  * @returns {boolean} code>true</code> if the window is shown, <code>false</code> if it is hidden.
89  */
90  bool isVisible();
91 
92  /*@jsdoc
93  * Shows or hides the window.
94  * @function OverlayWindow.setVisible
95  * @param {boolean} visible - code>true</code> to show the window, <code>false</code> to hide it.
96  */
97  void setVisible(bool visible);
98 
99 
100  /*@jsdoc
101  * Gets the position of the window.
102  * @function OverlayWindow.getPosition
103  * @returns {Vec2} The position of the window, in pixels.
104  */
105  glm::vec2 getPosition();
106 
107  /*@jsdoc
108  * Sets the position of the window, from a {@link Vec2}.
109  * @function OverlayWindow.setPosition
110  * @param {Vec2} position - The position of the window, in pixels.
111  */
112  void setPosition(const glm::vec2& position);
113 
114  /*@jsdoc
115  * Sets the position of the window, from a pair of numbers.
116  * @function OverlayWindow.setPosition
117  * @param {number} x - The x position of the window, in pixels.
118  * @param {number} y - The y position of the window, in pixels.
119  */
120  void setPosition(int x, int y);
121 
122 
123  /*@jsdoc
124  * Gets the size of the window interior.
125  * @function OverlayWindow.getSize
126  * @returns {Vec2} The size of the window interior, in pixels.
127  */
128  glm::vec2 getSize();
129 
130  /*@jsdoc
131  * Sets the size of the window interior, from a {@link Vec2}.
132  * @function OverlayWindow.setSize
133  * @param {Vec2} size - The size of the window interior, in pixels.
134  */
135  void setSize(const glm::vec2& size);
136 
137  /*@jsdoc
138  * Sets the size of the window interior, from a pair of numbers.
139  * @function OverlayWindow.setSize
140  * @param {number} width - The width of the window interior, in pixels.
141  * @param {number} height - The height of the window interior, in pixels.
142  */
143  void setSize(int width, int height);
144 
145  /*@jsdoc
146  * Sets the window title.
147  * @function OverlayWindow.setTitle
148  * @param {string} title - The window title.
149  */
150  void setTitle(const QString& title);
151 
152  /*@jsdoc
153  * Raises the window to the top.
154  * @function OverlayWindow.raise
155  */
156  Q_INVOKABLE void raise();
157 
158  /*@jsdoc
159  * Closes the window.
160  * <p>Note: The window also closes when the script ends.</p>
161  * @function OverlayWindow.close
162  */
163  Q_INVOKABLE void close();
164 
165  /*@jsdoc
166  * @function OverlayWindow.getEventBridge
167  * @returns {object} Object.
168  * @deprecated This method is deprecated and will be removed.
169  */
170  // Shouldn't be in the API: It returns the OverlayWindow object, not the even bridge.
171  Q_INVOKABLE QObject* getEventBridge() { return this; };
172 
173 
174  /*@jsdoc
175  * Sends a message to the QML. To receive the message, the QML must implement a function:
176  * <pre class="prettyprint"><code>function fromScript(message) {
177  * ...
178  * }</code></pre>
179  * @function OverlayWindow.sendToQml
180  * @param {string | object} message - The message to send to the QML.
181  * @example <caption>Send and receive messages with a QML window.</caption>
182  * // JavaScript file.
183  *
184  * var overlayWindow = new OverlayWindow({
185  * title: "Overlay Window",
186  * source: Script.resolvePath("OverlayWindow.qml"),
187  * width: 400,
188  * height: 300
189  * });
190  *
191  * overlayWindow.fromQml.connect(function (message) {
192  * print("Message received: " + message);
193  * });
194  *
195  * Script.setTimeout(function () {
196  * overlayWindow.sendToQml("Hello world!");
197  * }, 2000);
198  *
199  * @example
200  * // QML file, "OverlayWindow.qml".
201  *
202  * import QtQuick 2.5
203  * import QtQuick.Controls 1.4
204  *
205  * Rectangle {
206  * width: parent.width
207  * height: parent.height
208  *
209  * function fromScript(message) {
210  * text.text = message;
211  * sendToScript("Hello back!");
212  * }
213  *
214  * Label{
215  * id: text
216  * anchors.centerIn : parent
217  * text : "..."
218  * }
219  * }
220  */
221  // Scripts can use this to send a message to the QML object
222  void sendToQml(const QVariant& message);
223 
224  /*@jsdoc
225  * Calls a <code>clearWindow()</code> function if present in the QML.
226  * @function OverlayWindow.clearDebugWindow
227  */
228  void clearDebugWindow();
229 
230  /*@jsdoc
231  * Sends a message to an embedded HTML web page. To receive the message, the HTML page's script must connect to the
232  * <code>EventBridge</code> that is automatically provided for the script:
233  * <pre class="prettyprint"><code>EventBridge.scriptEventReceived.connect(function(message) {
234  * ...
235  * });</code></pre>
236  * @function OverlayWindow.emitScriptEvent
237  * @param {string|object} message - The message to send to the embedded HTML page.
238  */
239  // QmlWindow content may include WebView requiring EventBridge.
240  void emitScriptEvent(const QVariant& scriptMessage);
241 
242  /*@jsdoc
243  * @function OverlayWindow.emitWebEvent
244  * @param {object|string} message - The message.
245  * @deprecated This function is deprecated and will be removed.
246  */
247  void emitWebEvent(const QVariant& webMessage);
248 
249 signals:
250 
251  /*@jsdoc
252  * Triggered when the window is hidden or shown.
253  * @function OverlayWindow.visibleChanged
254  * @returns {Signal}
255  */
256  void visibleChanged();
257 
258  /*@jsdoc
259  * Triggered when the window changes position.
260  * @function OverlayWindow.positionChanged
261  * @returns {Signal}
262  */
263  void positionChanged();
264 
265  /*@jsdoc
266  * Triggered when the window changes size.
267  * @function OverlayWindow.sizeChanged
268  * @returns {Signal}
269  */
270  void sizeChanged();
271 
272  /*@jsdoc
273  * Triggered when the window changes position.
274  * @function OverlayWindow.moved
275  * @param {Vec2} position - The position of the window, in pixels.
276  * @returns {Signal}
277  */
278  void moved(glm::vec2 position);
279 
280  /*@jsdoc
281  * Triggered when the window changes size.
282  * @function OverlayWindow.resized
283  * @param {Size} size - The size of the window interior, in pixels.
284  * @returns {Signal}
285  */
286  void resized(QSizeF size);
287 
288  /*@jsdoc
289  * Triggered when the window is closed.
290  * @function OverlayWindow.closed
291  * @returns {Signal}
292  */
293  void closed();
294 
295  /*@jsdoc
296  * Triggered when a message from the QML page is received. The QML page can send a message (string or object) by calling:
297  * <pre class="prettyprint"><code>sendToScript(message);</code></pre>
298  * @function OverlayWindow.fromQml
299  * @param {object} message - The message received.
300  * @returns {Signal}
301  */
302  // Scripts can connect to this signal to receive messages from the QML object
303  void fromQml(const QVariant& message);
304 
305 
306  /*@jsdoc
307  * @function OverlayWindow.scriptEventReceived
308  * @param {object} message - The message.
309  * @returns {Signal}
310  * @deprecated This signal is deprecated and will be removed.
311  */
312  // QmlWindow content may include WebView requiring EventBridge.
313  void scriptEventReceived(const QVariant& message);
314 
315  /*@jsdoc
316  * Triggered when a message from an embedded HTML page is received. The HTML page can send a message by calling:
317  * <pre class="prettyprint"><code>EventBridge.emitWebEvent(message);</code></pre>
318  * @function OverlayWindow.webEventReceived
319  * @param {string|object} message - The message received.
320  * @returns {Signal}
321  */
322  void webEventReceived(const QVariant& message);
323 
324 protected slots:
325 
326  /*@jsdoc
327  * @function OverlayWindow.hasMoved
328  * @param {Vec2} position - Position.
329  * @deprecated This method is deprecated and will be removed.
330  */
331  // Shouldn't be in the API: it is just connected to in order to emit a signal.
332  void hasMoved(QVector2D);
333 
334  /*@jsdoc
335  * @function OverlayWindow.hasClosed
336  * @deprecated This method is deprecated and will be removed.
337  */
338  // Shouldn't be in the API: it is just connected to in order to emit a signal.
339  void hasClosed();
340 
341  /*@jsdoc
342  * @function OverlayWindow.qmlToScript
343  * @param {object} message - Message.
344  * @deprecated This method is deprecated and will be removed.
345  */
346  // Shouldn't be in the API: it is just connected to in order to emit a signal.
347  void qmlToScript(const QVariant& message);
348 
349 protected:
350  static QVariantMap parseArguments(ScriptContext* context);
351  static ScriptValue internalConstructor(ScriptContext* context, ScriptEngine* engine,
352  std::function<QmlWindowClass*(QVariantMap)> function);
353 
354  virtual QString qmlSource() const { return "QmlWindow.qml"; }
355 
356  QPointer<QObject> _qmlWindow;
357  QString _source;
358  const bool _restricted;
359 
360 private:
361  // QmlWindow content may include WebView requiring EventBridge.
362  void setKeyboardRaised(QObject* object, bool raised, bool numeric = false);
363 
364 };
365 
366 #endif
[ScriptInterface] Provides an engine-independent interface for QScriptContext
Definition: ScriptContext.h:55
Provides an engine-independent interface for a scripting engine.
Definition: ScriptEngine.h:93
[ScriptInterface] Provides an engine-independent interface for QScriptValue
Definition: ScriptValue.h:40