2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "actor-wrapper.h"
21 #include <dali/devel-api/scripting/scripting.h>
24 #include "emscripten-utils.h"
25 #include "signal-holder.h"
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
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}
50 const unsigned int ConditionTypeTableSize = sizeof( ConditionTypeTable ) / sizeof( ConditionTypeTable[0] );
61 emscripten::val JavascriptValue( const Dali::Property::Value& v );
64 * Struct to hold notification callback
66 struct EmscriptenNotifiy
68 EmscriptenNotifiy(const emscripten::val& callback )
69 : mCallback(callback) {};
70 emscripten::val mCallback;
74 emscripten::val ret = mCallback();
79 * Emscripten touched signal callback.
81 * Provides more contextual state information to the browser with the OnTouched signal.
84 struct EmscriptenTouchedSignal : public BaseSignalSlot
86 EmscriptenTouchedSignal(const emscripten::val& callback, unsigned int id)
87 : mCallback(callback), mId(id) {};
88 emscripten::val mCallback;
91 bool OnTouched(Dali::Actor actor, const Dali::TouchData& touch)
93 Dali::Property::Map map;
94 Dali::Property::Array points;
96 const int pointCount = static_cast<int>( touch.GetPointCount() );
98 map["pointCount"] = pointCount;
99 map["time"] = static_cast<int>( touch.GetTime() );
101 for( int i = 0; i < pointCount; ++i )
103 Dali::Property::Map pointMap;
104 Dali::Actor hitActor = touch.GetHitActor( i );
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 );
111 switch( touch.GetState( i ) )
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; }
121 points.PushBack(pointMap);
124 map["points"] = points;
126 Dali::Property::Value value(map);
127 emscripten::val ret = mCallback( actor, JavascriptValue(value) );
131 bool OnHovered(Dali::Actor actor, const Dali::HoverEvent& event)
133 Dali::Property::Map map;
134 Dali::Property::Array points;
136 map["pointCount"] = static_cast<int>(event.GetPointCount());
137 map["time"] = static_cast<int>(event.time);
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;
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; }
159 points.PushBack(pointMap);
162 map["points"] = points;
164 Dali::Property::Value value(map);
165 emscripten::val ret = mCallback( actor, JavascriptValue(value) );
172 * Struct to wrap a generic Emscripten callback.
175 struct EmscriptenSignal
177 EmscriptenSignal(const emscripten::val& callback, unsigned int id)
178 : mCallback(callback), mId(id) {};
179 emscripten::val mCallback;
183 Dali::Actor a = Dali::Stage::GetCurrent().GetRootLayer().FindChildById(mId);
186 emscripten::val ret = mCallback( a );
190 emscripten::val ret = mCallback();
196 bool ConnectSignal( Dali::Actor actor,
197 SignalHolder& signalHolder,
198 const std::string& signalName,
199 const emscripten::val& javascriptFunction )
202 if(0 == signalName.compare("touched"))
204 EmscriptenTouchedSignal* slot = new EmscriptenTouchedSignal(javascriptFunction, actor.GetId());
205 actor.TouchSignal().Connect(slot, &EmscriptenTouchedSignal::OnTouched);
206 signalHolder.add(slot);
209 else if(0 == signalName.compare("hovered"))
211 EmscriptenTouchedSignal* slot = new EmscriptenTouchedSignal(javascriptFunction, actor.GetId());
212 actor.HoveredSignal().Connect(slot, &EmscriptenTouchedSignal::OnHovered);
213 signalHolder.add(slot);
218 actor.ConnectSignal( &signalHolder, signalName, EmscriptenSignal(javascriptFunction, actor.GetId()));
225 unsigned int AddressOf(Dali::Actor self)
227 return (unsigned int)&self.GetBaseObject();
230 std::vector<float> ScreenToLocal(Dali::Actor self, float screenX, float screenY)
232 std::vector<float> ret;
235 bool ok = self.ScreenToLocal(localX, localY, screenX, screenY);
238 ret.push_back(localX);
239 ret.push_back(localY);
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)
256 unsigned int i = FindEnumIndex( propertyConditionType.c_str(), ConditionTypeTable, ConditionTypeTableSize );
258 if( i < ConditionTypeTableSize )
260 ConditionType type = static_cast<ConditionType>(ConditionTypeTable[i].value);
261 Dali::PropertyNotification notification;
264 case ConditionType::False:
266 notification = self.AddPropertyNotification( index, Dali::LessThanCondition(arg0) );
268 case ConditionType::LessThan:
270 notification = self.AddPropertyNotification( index, Dali::LessThanCondition(arg0) );
272 case ConditionType::GreaterThan:
274 notification = self.AddPropertyNotification( index, Dali::GreaterThanCondition(arg0) );
276 case ConditionType::Inside:
278 notification = self.AddPropertyNotification( index, Dali::InsideCondition(arg0, arg1) );
280 case ConditionType::Outside:
282 notification = self.AddPropertyNotification( index, Dali::OutsideCondition(arg0, arg1) );
284 case ConditionType::Step:
286 notification = self.AddPropertyNotification( index, Dali::StepCondition(arg0, arg1) );
288 case ConditionType::VariableStep:
290 notification = self.AddPropertyNotification( index, Dali::StepCondition(arg0, arg1) );
296 notification.NotifySignal().Connect( &signalHolder, FunctorDelegate::New(EmscriptenNotifiy(javascriptFunction)) );
300 EM_ASM( throw "Cannot set notification" );
306 }; // namespace Emscripten
307 }; // namespace Internal