Revert "[Tizen] Fix build errors in adaptor-uv by ecore wayland"
[platform/core/uifw/dali-adaptor.git] / adaptors / emscripten / wrappers / actor-wrapper.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 #include "actor-wrapper.h"
19
20 // EXTERNAL INCLUDES
21 #include <dali/devel-api/scripting/scripting.h>
22
23 // INTERNAL INCLUDES
24 #include "emscripten-utils.h"
25 #include "signal-holder.h"
26
27 namespace
28 {
29   enum ConditionType
30   {
31     False,                ///< Result Always False
32     LessThan,             ///< Magnitude of type is less than float value (arg0).
33     GreaterThan,          ///< Magnitude of type is greater than float value (arg0).
34     Inside,               ///< Magnitude of type is within float values (arg0 & arg1).
35     Outside,              ///< Magnitude of type is outside float values (arg0 & arg1).
36     Step,                 ///< Value of type has crossed a step amount
37     VariableStep          ///< Similar to step, except user can define a list of steps from reference value
38   };
39
40   Dali::Scripting::StringEnum ConditionTypeTable[] =
41   { { "False",           ConditionType::False},
42     { "LessThan",        ConditionType::LessThan},
43     { "GreaterThan",     ConditionType::GreaterThan},
44     { "Inside",          ConditionType::Inside},
45     { "Outside",         ConditionType::Outside},
46     { "Step",            ConditionType::Step},
47     { "VariableStep",    ConditionType::VariableStep}
48   };
49
50 const unsigned int ConditionTypeTableSize = sizeof( ConditionTypeTable ) / sizeof( ConditionTypeTable[0] );
51
52 };
53
54 namespace Dali
55 {
56 namespace Internal
57 {
58 namespace Emscripten
59 {
60
61 emscripten::val JavascriptValue( const Dali::Property::Value& v );
62
63 /**
64  * Struct to hold notification callback
65  */
66 struct EmscriptenNotifiy
67 {
68   EmscriptenNotifiy(const emscripten::val& callback )
69     : mCallback(callback) {};
70   emscripten::val mCallback;
71
72   void operator()(void)
73   {
74     emscripten::val ret = mCallback();
75   }
76 };
77
78 /**
79  * Emscripten touched signal callback.
80  *
81  * Provides more contextual state information to the browser with the OnTouched signal.
82  *
83  */
84 struct EmscriptenTouchedSignal : public BaseSignalSlot
85 {
86   EmscriptenTouchedSignal(const emscripten::val& callback, unsigned int id)
87     : mCallback(callback), mId(id)  {};
88   emscripten::val mCallback;
89   unsigned int mId;
90
91   bool OnTouched(Dali::Actor actor, const Dali::TouchData& touch)
92   {
93     Dali::Property::Map map;
94     Dali::Property::Array points;
95
96     const int pointCount = static_cast<int>( touch.GetPointCount() );
97
98     map["pointCount"] = pointCount;
99     map["time"] = static_cast<int>( touch.GetTime() );
100
101     for( int i = 0; i < pointCount; ++i )
102     {
103       Dali::Property::Map pointMap;
104       Dali::Actor hitActor = touch.GetHitActor( i );
105
106       pointMap["deviceId"] = touch.GetDeviceId( i );
107       pointMap["hitActorId"] = static_cast<int>( hitActor ? hitActor.GetId() : -1 );
108       pointMap["local"] = touch.GetLocalPosition( i );
109       pointMap["screen"]= touch.GetScreenPosition( i );
110
111       switch( touch.GetState( i ) )
112       {
113         case PointState::DOWN:        { pointMap["state"] = "DOWN";         break; }
114         case PointState::UP:          { pointMap["state"] = "UP";           break; }
115         case PointState::MOTION:      { pointMap["state"] = "MOTION";       break; }
116         case PointState::LEAVE:       { pointMap["state"] = "LEAVE";        break; }
117         case PointState::STATIONARY:  { pointMap["state"] = "STATIONARY";   break; }
118         case PointState::INTERRUPTED: { pointMap["state"] = "INTERRUPTED";  break; }
119       };
120
121       points.PushBack(pointMap);
122     }
123
124     map["points"] = points;
125
126     Dali::Property::Value value(map);
127     emscripten::val ret = mCallback( actor, JavascriptValue(value) );
128     return true;
129   }
130
131   bool OnHovered(Dali::Actor actor, const Dali::HoverEvent& event)
132   {
133     Dali::Property::Map map;
134     Dali::Property::Array points;
135
136     map["pointCount"] = static_cast<int>(event.GetPointCount());
137     map["time"] = static_cast<int>(event.time);
138
139     for(TouchPointContainer::const_iterator iter = event.points.begin();
140         iter != event.points.end(); ++iter) {
141       const Dali::TouchPoint& pt = *iter;
142       Dali::Property::Map pointMap;
143       pointMap["deviceId"] = pt.deviceId;
144       pointMap["hitActorId"] = static_cast<int>(pt.hitActor.GetId());
145       pointMap["local"] = pt.local;
146       pointMap["screen"]= pt.screen;
147
148       switch(pt.state)
149       {
150         case TouchPoint::Down:        { pointMap["state"] = "Down"; break; }
151         case TouchPoint::Up:          { pointMap["state"] = "Up"; break; }
152         case TouchPoint::Motion:      { pointMap["state"] = "Motion"; break; }
153         case TouchPoint::Leave:       { pointMap["state"] = "Leave"; break; }
154         case TouchPoint::Stationary:  { pointMap["state"] = "Stationary"; break; }
155         case TouchPoint::Interrupted: { pointMap["state"] = "Interrupted"; break; }
156         case TouchPoint::Last:        { pointMap["state"] = "Last"; break; }
157       };
158
159       points.PushBack(pointMap);
160     }
161
162     map["points"] = points;
163
164     Dali::Property::Value value(map);
165     emscripten::val ret = mCallback( actor, JavascriptValue(value) );
166     return true;
167   }
168
169 };
170
171 /**
172  * Struct to wrap a generic Emscripten callback.
173  *
174  */
175 struct EmscriptenSignal
176 {
177   EmscriptenSignal(const emscripten::val& callback, unsigned int id)
178     : mCallback(callback), mId(id) {};
179   emscripten::val mCallback;
180   unsigned int mId;
181   bool operator()()
182   {
183     Dali::Actor a = Dali::Stage::GetCurrent().GetRootLayer().FindChildById(mId);
184     if(a)
185     {
186       emscripten::val ret = mCallback( a );
187     }
188     else
189     {
190       emscripten::val ret = mCallback();
191     }
192     return true;
193   }
194 };
195
196 bool ConnectSignal( Dali::Actor actor,
197                     SignalHolder& signalHolder,
198                     const std::string& signalName,
199                     const emscripten::val& javascriptFunction )
200 {
201   bool ret = false;
202   if(0 == signalName.compare("touched"))
203   {
204     EmscriptenTouchedSignal* slot = new EmscriptenTouchedSignal(javascriptFunction, actor.GetId());
205     actor.TouchSignal().Connect(slot, &EmscriptenTouchedSignal::OnTouched);
206     signalHolder.add(slot);
207     ret = true;
208   }
209   else if(0 == signalName.compare("hovered"))
210   {
211     EmscriptenTouchedSignal* slot = new EmscriptenTouchedSignal(javascriptFunction, actor.GetId());
212     actor.HoveredSignal().Connect(slot, &EmscriptenTouchedSignal::OnHovered);
213     signalHolder.add(slot);
214     ret = true;
215   }
216   else
217   {
218     actor.ConnectSignal( &signalHolder, signalName, EmscriptenSignal(javascriptFunction, actor.GetId()));
219     ret = true;
220   }
221
222   return ret;
223 }
224
225 unsigned int AddressOf(Dali::Actor self)
226 {
227   return (unsigned int)&self.GetBaseObject();
228 }
229
230 std::vector<float> ScreenToLocal(Dali::Actor self, float screenX, float screenY)
231 {
232   std::vector<float> ret;
233   float localX = 0.f;
234   float localY = 0.f;
235   bool ok = self.ScreenToLocal(localX, localY, screenX, screenY);
236   if( ok )
237   {
238     ret.push_back(localX);
239     ret.push_back(localY);
240     ret.push_back(1.0);
241   }
242   else
243   {
244     ret.push_back(0.0);
245     ret.push_back(0.0);
246     ret.push_back(0.0);
247   }
248   return ret;
249 }
250
251 void SetPropertyNotification( Dali::Actor self,
252                               SignalHolder& signalHolder,
253                               Dali::Property::Index index, const std::string& propertyConditionType, float arg0, float arg1,
254                               const emscripten::val& javascriptFunction)
255 {
256   unsigned int i = FindEnumIndex( propertyConditionType.c_str(), ConditionTypeTable, ConditionTypeTableSize );
257
258   if( i < ConditionTypeTableSize )
259   {
260     ConditionType type = static_cast<ConditionType>(ConditionTypeTable[i].value);
261     Dali::PropertyNotification notification;
262     switch(type)
263     {
264       case ConditionType::False:
265       {
266         notification = self.AddPropertyNotification( index, Dali::LessThanCondition(arg0) );
267       }
268       case ConditionType::LessThan:
269       {
270         notification = self.AddPropertyNotification( index, Dali::LessThanCondition(arg0) );
271       }
272       case ConditionType::GreaterThan:
273       {
274         notification = self.AddPropertyNotification( index, Dali::GreaterThanCondition(arg0) );
275       }
276       case ConditionType::Inside:
277       {
278         notification = self.AddPropertyNotification( index, Dali::InsideCondition(arg0, arg1) );
279       }
280       case ConditionType::Outside:
281       {
282         notification = self.AddPropertyNotification( index, Dali::OutsideCondition(arg0, arg1) );
283       }
284       case ConditionType::Step:
285       {
286         notification = self.AddPropertyNotification( index, Dali::StepCondition(arg0, arg1) );
287       }
288       case ConditionType::VariableStep:
289       {
290         notification = self.AddPropertyNotification( index, Dali::StepCondition(arg0, arg1) );
291       }
292     };
293
294     if(notification)
295     {
296       notification.NotifySignal().Connect( &signalHolder, FunctorDelegate::New(EmscriptenNotifiy(javascriptFunction)) );
297     }
298     else
299     {
300       EM_ASM( throw "Cannot set notification" );
301     }
302   }
303 }
304
305
306 }; // namespace Emscripten
307 }; // namespace Internal
308 }; // namespace Dali