f41f5ac6fc20e8fc07aba652e167418620108532
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / events / event-object-generator.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "event-object-generator.h"
20
21 // INTERNAL INCLUDES
22 #include <v8-utils.h>
23 #include <actors/actor-wrapper.h>
24 #include <object/property-value-wrapper.h>
25
26 namespace Dali
27 {
28
29 namespace V8Plugin
30 {
31
32 namespace
33 {
34
35 struct PointState
36 {
37   TouchPoint::State state;
38   const char* name;
39 };
40
41 const PointState PointStateLookup[]=
42 {
43     { TouchPoint::Down,         "down"        },       /**< Screen touched */
44     { TouchPoint::Up,           "up"          },       /**< Touch stopped */
45     { TouchPoint::Motion,       "motion"      },       /**< Touch stopped */
46     { TouchPoint::Leave,        "leave"       },       /**< Touch stopped */
47     { TouchPoint::Stationary,   "stationary"  },       /**< Touch stopped */
48     { TouchPoint::Interrupted,  "interrupt"   },       /**< Touch stopped */
49     { TouchPoint::Started,      "started"     },       /**< Touch or hover started */
50     { TouchPoint::Finished,     "finished"    },       /**< Touch or hover finished */
51 };
52
53 const unsigned int PointStateLookupCount = sizeof(PointStateLookup)/sizeof(PointStateLookup[0]);
54
55 struct GestureState
56 {
57   Gesture::State state;
58   const char* name;
59 };
60
61 const GestureState GestureStateLookup[]=
62 {
63     { Gesture::Clear,      "clear"        },       /**< No state associated */
64     { Gesture::Started,    "started"      },       /**< Gesture started */
65     { Gesture::Continuing, "continuing"   },       /**< Gesture continuing */
66     { Gesture::Finished,   "finished"     },       /**< Gesture finished */
67     { Gesture::Cancelled,  "cancelled"    },       /**< Gesture cancelled */
68     { Gesture::Possible,   "possible"     },       /**< Gesture is possible */
69 };
70
71 const unsigned int GestureStateLookupCount = sizeof(GestureStateLookup)/sizeof(GestureStateLookup[0]);
72
73 const char* GetTouchPointStateName( TouchPoint::State state )
74 {
75   // could use the enum as index, but dali-core may change, so for now just do a lookup
76   for( unsigned int i = 0; i < PointStateLookupCount; i++ )
77   {
78     if( PointStateLookup[i].state == state )
79     {
80       return PointStateLookup[i].name;
81     }
82   }
83   return "error point state not found";
84 }
85
86 const char* GetGestureStateName( Gesture::State state )
87 {
88   // could use the enum as index, but dali-core may change, so for now just do a lookup
89   for( unsigned int i = 0; i < GestureStateLookupCount; i++ )
90   {
91     if( GestureStateLookup[i].state == state )
92     {
93       return GestureStateLookup[i].name;
94     }
95   }
96   return "error gesture state not found";
97 }
98
99 // create a point object, x,y
100 v8::Local<v8::Object> CreateTouchPoint( v8::Isolate* isolate, const TouchPoint& touchPoint )
101 {
102   /*
103    * touch point object
104    *
105    *   { "deviceId",  int }  Each touch point has a unique device ID
106    *   { "state",   string } touch state ="Down,Up,Motion,Leave,Stationary, Interrupted }
107    *   { "hitActor", actor } actor that was hit ( wrapped dali object)
108    *   { "local",  {x,y} } co-ordinates of top left of hit actor
109    *   { "screen", {x,y} } co-ordinates of top left of hit actor
110    */
111   v8::EscapableHandleScope handleScope( isolate );
112
113   v8::Local<v8::Object> pointObject = v8::Object::New( isolate );
114
115   // set device id
116   pointObject->Set( v8::String::NewFromUtf8( isolate, "deviceId"), v8::Integer::New( isolate, touchPoint.deviceId ));
117
118   // set state
119   pointObject->Set( v8::String::NewFromUtf8( isolate, "state"), v8::String::NewFromUtf8( isolate, GetTouchPointStateName(touchPoint.state)));
120
121   // set the hit actor
122   pointObject->Set( v8::String::NewFromUtf8( isolate, "hitActor"), ActorWrapper::WrapActor(isolate, touchPoint.hitActor ));
123
124   // Think about changing these Vector 2 from wrapped objects to JavaScript objects...
125
126   // Set the local co-ordinates
127   v8::Local<v8::Object> localPointObject = v8::Object::New( isolate );
128   localPointObject->Set( v8::String::NewFromUtf8( isolate, "x"),v8::Integer::New( isolate, touchPoint.local.x) );
129   localPointObject->Set( v8::String::NewFromUtf8( isolate, "y"),v8::Integer::New( isolate, touchPoint.local.y) );
130   pointObject->Set( v8::String::NewFromUtf8( isolate, "local"),  localPointObject);
131
132
133   // set the screen co-ordinates
134   v8::Local<v8::Object> screenPointObject = v8::Object::New( isolate );
135   screenPointObject->Set( v8::String::NewFromUtf8( isolate, "x"),v8::Integer::New( isolate, touchPoint.screen.x) );
136   screenPointObject->Set( v8::String::NewFromUtf8( isolate, "y"),v8::Integer::New( isolate, touchPoint.screen.y) );
137   pointObject->Set( v8::String::NewFromUtf8( isolate, "screen"), screenPointObject );
138
139
140   return handleScope.Escape( pointObject );
141 }
142
143 } // un-named namespace
144
145
146 v8::Handle<v8::Object> EventObjectGenerator::CreateTouchEvent( v8::Isolate* isolate, const TouchEvent& touchEvent)
147 {
148   // we are creating a touch event object that looks like this
149   //
150   //  event.pointCount = points touched
151   //  event.time       = The time (in ms) that the touch event occurred.
152   //  event.point[]    = array of TouchPoints
153   //
154   // A TouchPoint =
155   //   { "deviceId",  int }  Each touch point has a unique device ID
156   //   { "state",   string } touch state ="Down,Up,Motion,Leave,Stationary, Interrupted }
157   //   { "sourceActor", actor }  the actor that is emitting the callback (the actor that is hit maybe a child of it)
158   //   { "hitActor", actor } actor that was hit
159   //   { "local",  {x,y} } co-ordinates of top left of hit actor
160   //   { "screen", {x,y} } co-ordinates of top left of hit actor
161   //
162
163   v8::EscapableHandleScope handleScope( isolate );
164
165   v8::Local<v8::Object> touchObject = v8::Object::New( isolate );
166
167   // Set the pointCount
168   touchObject->Set( v8::String::NewFromUtf8( isolate, "pointCount" ), v8::Integer::New( isolate, touchEvent.GetPointCount() ) );
169
170   // Set the time
171   touchObject->Set( v8::String::NewFromUtf8( isolate, "time" ), v8::Number::New( isolate, touchEvent.time ) );
172
173   // Set the emitting actor
174   // touchObject->Set( v8::String::NewFromUtf8( isolate, "sourceActor" ), ActorWrapper::WrapActor(isolate, emittingActor));
175
176   // Create the array of touch points
177   v8::Local < v8::Array > pointArrayObject = v8::Array::New( isolate, touchEvent.GetPointCount() );
178   for( unsigned int i = 0 ; i < touchEvent.GetPointCount() ; ++i )
179   {
180     v8::Local < v8::Object > pointObject = CreateTouchPoint( isolate, touchEvent.points[i] );
181     pointArrayObject->Set( v8::Number::New( isolate, i ), pointObject  );
182   }
183
184   // set the array
185   touchObject->Set( v8::String::NewFromUtf8( isolate, "points" ), pointArrayObject );
186
187   return handleScope.Escape( touchObject );
188 }
189
190 v8::Handle<v8::Object> EventObjectGenerator::CreateHoverEvent( v8::Isolate* isolate, const HoverEvent& hoverEvent)
191 {
192   // we are creating a hover event object that looks like this
193   //
194   //  event.pointCount = points hovered
195   //  event.time       = The time (in ms) that the hover event occurred.
196   //  event.point[]    = array of TouchPoints
197   //
198   // A TouchPoint =
199   //   { "deviceId",  int }  Each touch point has a unique device ID
200   //   { "state",   string } touch state ="Down,Up,Motion,Leave,Stationary, Interrupted }
201   //   { "sourceActor", actor }  the actor that is emitting the callback (the actor that is hit maybe a child of it)
202   //   { "hitActor", actor } actor that was hit
203   //   { "local",  {x,y} } co-ordinates of top left of hit actor
204   //   { "screen", {x,y} } co-ordinates of top left of hit actor
205   //
206
207   v8::EscapableHandleScope handleScope( isolate );
208
209   v8::Local<v8::Object> hoverObject = v8::Object::New( isolate );
210
211   // Set the pointCount
212   hoverObject->Set( v8::String::NewFromUtf8( isolate, "pointCount" ), v8::Integer::New( isolate, hoverEvent.GetPointCount() ) );
213
214   // Set the time
215   hoverObject->Set( v8::String::NewFromUtf8( isolate, "time" ), v8::Number::New( isolate, hoverEvent.time ) );
216
217   // Set the emitting actor
218   // hoverObject->Set( v8::String::NewFromUtf8( isolate, "sourceActor" ), ActorWrapper::WrapActor(isolate, emittingActor));
219
220   // Create the array of touch points
221   v8::Local < v8::Array > pointArrayObject = v8::Array::New( isolate, hoverEvent.GetPointCount() );
222   for( unsigned int i = 0 ; i < hoverEvent.GetPointCount() ; ++i )
223   {
224     v8::Local < v8::Object > pointObject = CreateTouchPoint( isolate, hoverEvent.points[i] );
225     pointArrayObject->Set( v8::Number::New( isolate, i ), pointObject  );
226   }
227
228   // set the array
229   hoverObject->Set( v8::String::NewFromUtf8( isolate, "points" ), pointArrayObject );
230
231   return handleScope.Escape( hoverObject );
232 }
233
234 v8::Handle<v8::Object> EventObjectGenerator::CreateMouseWheelEvent( v8::Isolate* isolate, const MouseWheelEvent& wheelEvent)
235 {
236   //  we are creating a mouse wheel event object that looks like this
237   //
238   //  event.direction = "vertical" or "horizontal" direction the wheel is being rolled
239   //  event.shiftPressed       = boolean, shift key is held
240   //  event.ctrlPressed        = boolean, ctrl key is held
241   //  event.altPressed     = boolean, alt key is held
242   //  event.keyModifiers = bitmask of keys pressed
243   //  event.point {x,y}    = The co-ordinates of the mouse cursor relative to the top-left of the screen when the wheel is being rolled.
244   //  event.rolled          = offset of mouse wheel rolling, positive = rolling down, negative = rolling up
245   //  event.timestamp    = The time (in ms) that the touch event occurred
246
247   v8::EscapableHandleScope handleScope( isolate );
248
249   v8::Local<v8::Object> wheelObject = v8::Object::New( isolate );
250
251   // Set the direction
252   std::string direction = wheelEvent.direction ? "vertical" : "horizontal";
253   wheelObject->Set( v8::String::NewFromUtf8( isolate, "direction" ), v8::String::NewFromUtf8( isolate, direction.c_str() ) );
254
255   // set shift / ctrl/ alt keys
256   wheelObject->Set( v8::String::NewFromUtf8( isolate, "shiftPressed" ), v8::Boolean::New( isolate, wheelEvent.IsShiftModifier()) );
257   wheelObject->Set( v8::String::NewFromUtf8( isolate, "ctrlPressed" ),  v8::Boolean::New( isolate, wheelEvent.IsCtrlModifier()) );
258   wheelObject->Set( v8::String::NewFromUtf8( isolate, "altPressed" ),   v8::Boolean::New( isolate, wheelEvent.IsAltModifier()) );
259
260   // set keyModifiers
261   wheelObject->Set( v8::String::NewFromUtf8( isolate, "keyModifiers" ),  v8::Integer::New( isolate, wheelEvent.modifiers) );
262
263   // set Point
264   v8::Local<v8::Object> wheelPointObject = v8::Object::New( isolate );
265   wheelPointObject->Set( v8::String::NewFromUtf8( isolate, "x"),v8::Integer::New( isolate, wheelEvent.point.x ) );
266   wheelPointObject->Set( v8::String::NewFromUtf8( isolate, "y"),v8::Integer::New( isolate, wheelEvent.point.y ) );
267   wheelObject->Set( v8::String::NewFromUtf8( isolate, "point"), wheelPointObject );
268
269   // set rolledAmout
270   wheelObject->Set( v8::String::NewFromUtf8( isolate, "rolled" ),  v8::Integer::New( isolate, wheelEvent.z) );
271
272   // set timestamp
273   wheelObject->Set( v8::String::NewFromUtf8( isolate, "timestamp" ),  v8::Integer::New( isolate, wheelEvent.timeStamp) );
274
275   return handleScope.Escape( wheelObject );
276
277 }
278
279 v8::Handle<v8::Object> EventObjectGenerator::CreateKeyEvent( v8::Isolate* isolate, const KeyEvent& keyEvent)
280 {
281   // keyCode
282   // keyModifier
283   // event.keyCode       = key code
284   // event.key           = key presssed
285   // event.keyDescription = key description, e.g. BackSpace
286   // event.state = "down" or "up" key state
287   // event.shiftPressed  = boolean, shift key is held
288   // event.ctrlPressed   = boolean, ctrl key is held
289   // event.altPressed    = boolean, alt key is held
290   // event.keyModifiers  = key modifiers
291   // event.timestamp     = Time stamp
292
293   v8::EscapableHandleScope handleScope( isolate );
294
295   v8::Local<v8::Object> keyObject = v8::Object::New( isolate );
296
297   // Set the direction
298   std::string state ("up");
299   if ( keyEvent.state == KeyEvent::Down)
300   {
301     state = "down";
302   }
303
304   keyObject->Set( v8::String::NewFromUtf8( isolate, "state" ), v8::String::NewFromUtf8( isolate, state.c_str() ) );
305
306   // set keyCode
307    keyObject->Set( v8::String::NewFromUtf8( isolate, "keyCode" ),  v8::Integer::New( isolate, keyEvent.keyCode) );
308
309   // set keyModifiers
310   keyObject->Set( v8::String::NewFromUtf8( isolate, "keyModifier" ),  v8::Integer::New( isolate, keyEvent.keyModifier) );
311
312   // set Key pressed name
313   keyObject->Set( v8::String::NewFromUtf8( isolate, "keyDescription" ),  v8::String::NewFromUtf8( isolate, keyEvent.keyPressedName.c_str() )  );
314
315   // set Key pressed
316   keyObject->Set( v8::String::NewFromUtf8( isolate, "key" ),  v8::String::NewFromUtf8( isolate, keyEvent.keyPressed.c_str() )  );
317
318   // set time stamp
319   keyObject->Set( v8::String::NewFromUtf8( isolate, "timestamp" ),  v8::Integer::New( isolate, keyEvent.time) );
320
321   // set shift / ctrl/ alt keys
322   keyObject->Set( v8::String::NewFromUtf8( isolate, "shiftPressed" ), v8::Boolean::New( isolate, keyEvent.IsShiftModifier()) );
323   keyObject->Set( v8::String::NewFromUtf8( isolate, "ctrlPressed" ),  v8::Boolean::New( isolate, keyEvent.IsCtrlModifier()) );
324   keyObject->Set( v8::String::NewFromUtf8( isolate, "altPressed" ),   v8::Boolean::New( isolate, keyEvent.IsAltModifier()) );
325
326   return handleScope.Escape( keyObject );
327
328 }
329
330 v8::Handle<v8::Object> EventObjectGenerator::CreatePanGesture( v8::Isolate* isolate, const PanGesture& panGesture)
331 {
332   // gesture.numberOfTouches     = total number of fingers touching the screen
333   // gesture.state               = pan state {Clear, Started, Continuing, Finished, Cancelled, Possible}
334   // gesture.time                = Time stamp
335   // gesture.velocity            = pan velocity in actor coordinates
336   // gesture.displacement        = pan displacement in actor coordinates
337   // gesture.position            = pan position in actor coordinates
338   // gesture.screenVelocity      = pan velocity in screen coordinates
339   // gesture.screenDisplacement  = pan displacement in screen coordinates
340   // gesture.screenPosition      = pan position in screen coordinates
341
342   v8::EscapableHandleScope handleScope( isolate );
343
344   v8::Local<v8::Object> panObject = v8::Object::New( isolate );
345
346   // Set the numberOfTouches
347   panObject->Set( v8::String::NewFromUtf8( isolate, "numberOfTouches" ), v8::Integer::New( isolate, panGesture.numberOfTouches ) );
348
349   // Set the state
350   panObject->Set( v8::String::NewFromUtf8( isolate, "state"), v8::String::NewFromUtf8( isolate, GetGestureStateName(panGesture.state)));
351
352   // Set the time
353   panObject->Set( v8::String::NewFromUtf8( isolate, "time" ), v8::Number::New( isolate, panGesture.time ) );
354
355   // Set the local velocity
356   v8::Local<v8::Object> velocityObject = v8::Object::New( isolate );
357   velocityObject->Set( v8::String::NewFromUtf8( isolate, "x"),v8::Number::New( isolate, panGesture.velocity.x) );
358   velocityObject->Set( v8::String::NewFromUtf8( isolate, "y"),v8::Number::New( isolate, panGesture.velocity.y) );
359   panObject->Set( v8::String::NewFromUtf8( isolate, "velocity"),  velocityObject);
360
361   // Set the local displacement
362   v8::Local<v8::Object> displacementObject = v8::Object::New( isolate );
363   displacementObject->Set( v8::String::NewFromUtf8( isolate, "x"),v8::Number::New( isolate, panGesture.displacement.x) );
364   displacementObject->Set( v8::String::NewFromUtf8( isolate, "y"),v8::Number::New( isolate, panGesture.displacement.y) );
365   panObject->Set( v8::String::NewFromUtf8( isolate, "displacement"),  displacementObject);
366
367   // Set the local position
368   v8::Local<v8::Object> positionObject = v8::Object::New( isolate );
369   positionObject->Set( v8::String::NewFromUtf8( isolate, "x"),v8::Number::New( isolate, panGesture.position.x) );
370   positionObject->Set( v8::String::NewFromUtf8( isolate, "y"),v8::Number::New( isolate, panGesture.position.y) );
371   panObject->Set( v8::String::NewFromUtf8( isolate, "position"),  positionObject);
372
373   // Set the screen velocity
374   v8::Local<v8::Object> screenVelocityObject = v8::Object::New( isolate );
375   screenVelocityObject->Set( v8::String::NewFromUtf8( isolate, "x"),v8::Number::New( isolate, panGesture.screenVelocity.x) );
376   screenVelocityObject->Set( v8::String::NewFromUtf8( isolate, "y"),v8::Number::New( isolate, panGesture.screenVelocity.y) );
377   panObject->Set( v8::String::NewFromUtf8( isolate, "screenVelocity"),  screenVelocityObject);
378
379   // Set the screen displacement
380   v8::Local<v8::Object> screenDisplacementObject = v8::Object::New( isolate );
381   screenDisplacementObject->Set( v8::String::NewFromUtf8( isolate, "x"),v8::Number::New( isolate, panGesture.screenDisplacement.x) );
382   screenDisplacementObject->Set( v8::String::NewFromUtf8( isolate, "y"),v8::Number::New( isolate, panGesture.screenDisplacement.y) );
383   panObject->Set( v8::String::NewFromUtf8( isolate, "screenDisplacement"),  screenDisplacementObject);
384
385   // Set the screen position
386   v8::Local<v8::Object> screenPositionObject = v8::Object::New( isolate );
387   screenPositionObject->Set( v8::String::NewFromUtf8( isolate, "x"),v8::Number::New( isolate, panGesture.screenPosition.x) );
388   screenPositionObject->Set( v8::String::NewFromUtf8( isolate, "y"),v8::Number::New( isolate, panGesture.screenPosition.y) );
389   panObject->Set( v8::String::NewFromUtf8( isolate, "screenPosition"),  screenPositionObject);
390
391   return handleScope.Escape( panObject );
392
393 }
394
395
396
397 } // V8Plugin
398
399 } // namespace Dali