source: trunk/examples/script/context2d/environment.cpp@ 857

Last change on this file since 857 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 17.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "environment.h"
42#include "qcontext2dcanvas.h"
43#include "context2d.h"
44#include <QScriptValueIterator>
45#include <QDateTime>
46
47struct FakeDomEvent
48{
49 enum KeyCodes {
50 DOM_VK_UNDEFINED = 0x0,
51 DOM_VK_RIGHT_ALT = 0x12,
52 DOM_VK_LEFT_ALT = 0x12,
53 DOM_VK_LEFT_CONTROL = 0x11,
54 DOM_VK_RIGHT_CONTROL = 0x11,
55 DOM_VK_LEFT_SHIFT = 0x10,
56 DOM_VK_RIGHT_SHIFT = 0x10,
57 DOM_VK_META = 0x9D,
58 DOM_VK_BACK_SPACE = 0x08,
59 DOM_VK_CAPS_LOCK = 0x14,
60 DOM_VK_DELETE = 0x7F,
61 DOM_VK_END = 0x23,
62 DOM_VK_ENTER = 0x0D,
63 DOM_VK_ESCAPE = 0x1B,
64 DOM_VK_HOME = 0x24,
65 DOM_VK_NUM_LOCK = 0x90,
66 DOM_VK_PAUSE = 0x13,
67 DOM_VK_PRINTSCREEN = 0x9A,
68 DOM_VK_SCROLL_LOCK = 0x91,
69 DOM_VK_SPACE = 0x20,
70 DOM_VK_TAB = 0x09,
71 DOM_VK_LEFT = 0x25,
72 DOM_VK_RIGHT = 0x27,
73 DOM_VK_UP = 0x26,
74 DOM_VK_DOWN = 0x28,
75 DOM_VK_PAGE_DOWN = 0x22,
76 DOM_VK_PAGE_UP = 0x21,
77 DOM_VK_F1 = 0x70,
78 DOM_VK_F2 = 0x71,
79 DOM_VK_F3 = 0x72,
80 DOM_VK_F4 = 0x73,
81 DOM_VK_F5 = 0x74,
82 DOM_VK_F6 = 0x75,
83 DOM_VK_F7 = 0x76,
84 DOM_VK_F8 = 0x77,
85 DOM_VK_F9 = 0x78,
86 DOM_VK_F10 = 0x79,
87 DOM_VK_F11 = 0x7A,
88 DOM_VK_F12 = 0x7B,
89 DOM_VK_F13 = 0xF000,
90 DOM_VK_F14 = 0xF001,
91 DOM_VK_F15 = 0xF002,
92 DOM_VK_F16 = 0xF003,
93 DOM_VK_F17 = 0xF004,
94 DOM_VK_F18 = 0xF005,
95 DOM_VK_F19 = 0xF006,
96 DOM_VK_F20 = 0xF007,
97 DOM_VK_F21 = 0xF008,
98 DOM_VK_F22 = 0xF009,
99 DOM_VK_F23 = 0xF00A,
100 DOM_VK_F24 = 0xF00B
101 };
102
103 static int qtToDomKey(int keyCode);
104};
105
106int FakeDomEvent::qtToDomKey(int keyCode)
107{
108 switch (keyCode) {
109 case Qt::Key_Backspace:
110 return DOM_VK_BACK_SPACE;
111 case Qt::Key_Enter:
112 return DOM_VK_ENTER;
113 case Qt::Key_Return:
114 return DOM_VK_ENTER;
115 case Qt::Key_NumLock:
116 return DOM_VK_NUM_LOCK;
117 case Qt::Key_Alt:
118 return DOM_VK_RIGHT_ALT;
119 case Qt::Key_Control:
120 return DOM_VK_LEFT_CONTROL;
121 case Qt::Key_Shift:
122 return DOM_VK_LEFT_SHIFT;
123 case Qt::Key_Meta:
124 return DOM_VK_META;
125 case Qt::Key_CapsLock:
126 return DOM_VK_CAPS_LOCK;
127 case Qt::Key_Delete:
128 return DOM_VK_DELETE;
129 case Qt::Key_End:
130 return DOM_VK_END;
131 case Qt::Key_Escape:
132 return DOM_VK_ESCAPE;
133 case Qt::Key_Home:
134 return DOM_VK_HOME;
135 case Qt::Key_Pause:
136 return DOM_VK_PAUSE;
137 case Qt::Key_Print:
138 return DOM_VK_PRINTSCREEN;
139 case Qt::Key_ScrollLock:
140 return DOM_VK_SCROLL_LOCK;
141 case Qt::Key_Left:
142 return DOM_VK_LEFT;
143 case Qt::Key_Right:
144 return DOM_VK_RIGHT;
145 case Qt::Key_Up:
146 return DOM_VK_UP;
147 case Qt::Key_Down:
148 return DOM_VK_DOWN;
149 case Qt::Key_PageDown:
150 return DOM_VK_PAGE_DOWN;
151 case Qt::Key_PageUp:
152 return DOM_VK_PAGE_UP;
153 case Qt::Key_F1:
154 return DOM_VK_F1;
155 case Qt::Key_F2:
156 return DOM_VK_F2;
157 case Qt::Key_F3:
158 return DOM_VK_F3;
159 case Qt::Key_F4:
160 return DOM_VK_F4;
161 case Qt::Key_F5:
162 return DOM_VK_F5;
163 case Qt::Key_F6:
164 return DOM_VK_F6;
165 case Qt::Key_F7:
166 return DOM_VK_F7;
167 case Qt::Key_F8:
168 return DOM_VK_F8;
169 case Qt::Key_F9:
170 return DOM_VK_F9;
171 case Qt::Key_F10:
172 return DOM_VK_F10;
173 case Qt::Key_F11:
174 return DOM_VK_F11;
175 case Qt::Key_F12:
176 return DOM_VK_F12;
177 case Qt::Key_F13:
178 return DOM_VK_F13;
179 case Qt::Key_F14:
180 return DOM_VK_F14;
181 case Qt::Key_F15:
182 return DOM_VK_F15;
183 case Qt::Key_F16:
184 return DOM_VK_F16;
185 case Qt::Key_F17:
186 return DOM_VK_F17;
187 case Qt::Key_F18:
188 return DOM_VK_F18;
189 case Qt::Key_F19:
190 return DOM_VK_F19;
191 case Qt::Key_F20:
192 return DOM_VK_F20;
193 case Qt::Key_F21:
194 return DOM_VK_F21;
195 case Qt::Key_F22:
196 return DOM_VK_F22;
197 case Qt::Key_F23:
198 return DOM_VK_F23;
199 case Qt::Key_F24:
200 return DOM_VK_F24;
201 }
202 return keyCode;
203}
204
205//! [0]
206Environment::Environment(QObject *parent)
207 : QObject(parent)
208{
209 m_engine = new QScriptEngine(this);
210
211 m_document = m_engine->newQObject(
212 new Document(this), QScriptEngine::QtOwnership,
213 QScriptEngine::ExcludeSuperClassContents);
214
215 CanvasGradientPrototype::setup(m_engine);
216
217 m_originalGlobalObject = m_engine->globalObject();
218 reset();
219}
220//! [0]
221
222Environment::~Environment()
223{
224}
225
226QScriptEngine *Environment::engine() const
227{
228 return m_engine;
229}
230
231QScriptValue Environment::document() const
232{
233 return m_document;
234}
235
236int Environment::setTimeout(const QScriptValue &expression, int delay)
237{
238 if (expression.isString() || expression.isFunction()) {
239 int timerId = startTimer(delay);
240 m_timeoutHash.insert(timerId, expression);
241 return timerId;
242 }
243 return -1;
244}
245
246void Environment::clearTimeout(int timerId)
247{
248 killTimer(timerId);
249 m_timeoutHash.remove(timerId);
250}
251
252//! [1]
253int Environment::setInterval(const QScriptValue &expression, int delay)
254{
255 if (expression.isString() || expression.isFunction()) {
256 int timerId = startTimer(delay);
257 m_intervalHash.insert(timerId, expression);
258 return timerId;
259 }
260 return -1;
261}
262
263void Environment::clearInterval(int timerId)
264{
265 killTimer(timerId);
266 m_intervalHash.remove(timerId);
267}
268
269void Environment::timerEvent(QTimerEvent *event)
270{
271 int id = event->timerId();
272 QScriptValue expression = m_intervalHash.value(id);
273 if (!expression.isValid()) {
274 expression = m_timeoutHash.value(id);
275 if (expression.isValid())
276 killTimer(id);
277 }
278 if (expression.isString()) {
279 evaluate(expression.toString());
280 } else if (expression.isFunction()) {
281 expression.call();
282 }
283 maybeEmitScriptError();
284}
285//! [1]
286
287//! [5]
288void Environment::addCanvas(QContext2DCanvas *canvas)
289{
290 m_canvases.append(canvas);
291}
292
293QContext2DCanvas *Environment::canvasByName(const QString &name) const
294{
295 for (int i = 0; i < m_canvases.size(); ++i) {
296 QContext2DCanvas *canvas = m_canvases.at(i);
297 if (canvas->objectName() == name)
298 return canvas;
299 }
300 return 0;
301}
302//! [5]
303
304QList<QContext2DCanvas*> Environment::canvases() const
305{
306 return m_canvases;
307}
308
309void Environment::reset()
310{
311 if (m_engine->isEvaluating())
312 m_engine->abortEvaluation();
313
314 {
315 QHash<int, QScriptValue>::const_iterator it;
316 for (it = m_intervalHash.constBegin(); it != m_intervalHash.constEnd(); ++it)
317 killTimer(it.key());
318 m_intervalHash.clear();
319 for (it = m_timeoutHash.constBegin(); it != m_timeoutHash.constEnd(); ++it)
320 killTimer(it.key());
321 m_timeoutHash.clear();
322 }
323
324 for (int i = 0; i < m_canvases.size(); ++i)
325 m_canvases.at(i)->reset();
326
327 QScriptValue self = m_engine->newQObject(
328 this, QScriptEngine::QtOwnership,
329 QScriptEngine::ExcludeSuperClassContents);
330
331 {
332 QScriptValueIterator it(m_originalGlobalObject);
333 while (it.hasNext()) {
334 it.next();
335 self.setProperty(it.scriptName(), it.value(), it.flags());
336 }
337 }
338
339 self.setProperty("self", self);
340 self.setProperty("window", self);
341
342 QScriptValue navigator = m_engine->newObject();
343 navigator.setProperty("appCodeName", "context2d");
344 navigator.setProperty("appMinorVersion", 1);
345 navigator.setProperty("appVersion", 1);
346 navigator.setProperty("browserLanguage", "en_US");
347 navigator.setProperty("cookieEnabled", false);
348 navigator.setProperty("cpuClass", "i686");
349 navigator.setProperty("onLine", false);
350 navigator.setProperty("platform", "bogus OS");
351 navigator.setProperty("systemLanguage", "en_US");
352 navigator.setProperty("userAgent", "Context2D/1.1");
353 navigator.setProperty("userLanguage", "en_US");
354 self.setProperty("navigator", navigator);
355
356 m_engine->setGlobalObject(self);
357
358 m_engine->collectGarbage();
359}
360
361QScriptValue Environment::evaluate(const QString &code, const QString &fileName)
362{
363 return m_engine->evaluate(code, fileName);
364}
365
366//! [2]
367QScriptValue Environment::toWrapper(QObject *object)
368{
369 return m_engine->newQObject(object, QScriptEngine::QtOwnership,
370 QScriptEngine::PreferExistingWrapperObject
371 | QScriptEngine::ExcludeSuperClassContents);
372}
373//! [2]
374
375//! [3]
376void Environment::handleEvent(QContext2DCanvas *canvas, QMouseEvent *e)
377{
378 QString type;
379 switch (e->type()) {
380 case QEvent::MouseButtonPress:
381 type = "mousedown"; break;
382 case QEvent::MouseButtonRelease:
383 type = "mouseup"; break;
384 case QEvent::MouseMove:
385 type = "mousemove"; break;
386 default: break;
387 }
388 if (type.isEmpty())
389 return;
390
391 QScriptValue handlerObject;