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.
19 #include <actors/actor-wrapper.h>
20 #include "control-wrapper.h"
23 #include <dali/public-api/object/type-registry.h>
26 #include <controls/item-view-api.h>
27 #include <controls/scroll-view-api.h>
29 #include <dali-wrapper.h>
37 v8::Persistent<v8::ObjectTemplate> ControlWrapper::mControlTemplate;
38 v8::Persistent<v8::ObjectTemplate> ControlWrapper::mItemViewTemplate;
39 v8::Persistent<v8::ObjectTemplate> ControlWrapper::mScrollViewTemplate;
41 Vector< void* > ControlWrapper::mControlGarbageContainer;
48 * pointer to a persistent template handle
50 struct ControlTemplate
52 v8::Persistent<v8::ObjectTemplate>* controlTemplate;
56 * array of templates for each type of control
58 const ControlTemplate ControlTemplateLookup[]=
60 { &ControlWrapper::mControlTemplate }, // CONTROL
61 { &ControlWrapper::mItemViewTemplate }, // ITEMVIEW
62 { &ControlWrapper::mScrollViewTemplate } // SCROLLVIEW
66 * Bitmask of API's that an control can support
68 enum ControlApiBitMask
71 ITEMVIEW_API = 1 << 1,
72 SCROLLVIEW_API = 1 << 2
76 * structure used for the ControlApiLookup.
78 struct ControlApiStruct
80 const char* controlName;
81 ControlWrapper::ControlType controlType;
82 Toolkit::Control (*constructor)( const v8::FunctionCallbackInfo< v8::Value >& args);
87 * Lookup table to match a control type with a constructor and supported API's.
88 * ControlWrapper::ControlType is used to index this table
90 const ControlApiStruct ControlApiLookup[]=
92 {"Control", ControlWrapper::CONTROL, NULL, CONTROL_API },
93 {"ItemView", ControlWrapper::ITEMVIEW, ItemViewApi::New, CONTROL_API | ITEMVIEW_API },
94 {"ScrollView", ControlWrapper::SCROLLVIEW, ScrollViewApi::New, CONTROL_API | SCROLLVIEW_API }
97 const unsigned int ControlApiLookupCount = sizeof(ControlApiLookup)/sizeof(ControlApiLookup[0]);
101 * Creates a control given a type name
102 * Uses the type registry to create an control of the correct type
104 Toolkit::Control CreateControl( const v8::FunctionCallbackInfo< v8::Value >& args,
105 const std::string& typeName )
107 Toolkit::Control control;
109 ControlWrapper::ControlType controlType = ControlWrapper::GetControlType( typeName );
111 // if we don't currently have specific binding for the given control type,
112 // try to use type registry to create it
113 if( controlType == ControlWrapper::UNKNOWN_CONTROL )
115 Dali::TypeInfo typeInfo = Dali::TypeRegistry::Get().GetTypeInfo( typeName );
118 Dali::BaseHandle handle = typeInfo.CreateInstance();
121 control = Toolkit::Control::DownCast( handle );
124 DALI_SCRIPT_EXCEPTION( args.GetIsolate(), "Unknown control type" );
125 return Toolkit::Control();
132 // run the constructor for this type of control so it can pull out custom parameters
133 control = (ControlApiLookup[controlType].constructor)( args );
140 * given a control type return what api's it supports
142 int GetControlSupportedApis( ControlWrapper::ControlType type )
144 return ControlApiLookup[type].supportApis;
148 * Used for the ControlFunctionTable to map function names to functions
149 * with for a specific API
151 struct ControlFunctions
153 const char* name; ///< function name
154 void (*function)( const v8::FunctionCallbackInfo< v8::Value >& args);
155 ControlApiBitMask api;
159 * Contains a list of all functions that can be called in
162 const ControlFunctions ControlFunctionTable[]=
165 /**************************************
167 **************************************/
168 { "GetLayoutCount", ItemViewApi::GetLayoutCount, ITEMVIEW_API },
169 { "AddLayout", ItemViewApi::AddLayout, ITEMVIEW_API },
170 { "RemoveLayout", ItemViewApi::RemoveLayout, ITEMVIEW_API },
171 { "ActivateLayout", ItemViewApi::ActivateLayout, ITEMVIEW_API },
172 { "GetItemSize", ItemViewApi::GetItemSize, ITEMVIEW_API },
173 { "SetItemSize", ItemViewApi::SetItemSize, ITEMVIEW_API },
174 { "ScrollToItem", ItemViewApi::ScrollToItem, ITEMVIEW_API },
175 { "GetItem", ItemViewApi::GetItem, ITEMVIEW_API },
176 { "GetItemId", ItemViewApi::GetItemId, ITEMVIEW_API },
177 { "GetItemsRange", ItemViewApi::GetItemsRange, ITEMVIEW_API },
179 /**************************************
181 **************************************/
182 { "SetScrollMode", ScrollViewApi::SetScrollMode, SCROLLVIEW_API },
183 { "GetCurrentPage", ScrollViewApi::GetCurrentPage, SCROLLVIEW_API },
184 { "ScrollToPosition", ScrollViewApi::ScrollToPosition, SCROLLVIEW_API },
185 { "ScrollToPage", ScrollViewApi::ScrollToPage, SCROLLVIEW_API },
186 { "ScrollToActor", ScrollViewApi::ScrollToActor, SCROLLVIEW_API },
187 { "ScrollToSnapInterval", ScrollViewApi::ScrollToSnapInterval, SCROLLVIEW_API },
188 { "SetScrollFlickAlphaFunction", ScrollViewApi::SetScrollFlickAlphaFunction, SCROLLVIEW_API },
189 { "SetScrollSnapAlphaFunction", ScrollViewApi::SetScrollSnapAlphaFunction, SCROLLVIEW_API },
190 { "SetSnapOvershootAlphaFunction", ScrollViewApi::SetSnapOvershootAlphaFunction, SCROLLVIEW_API },
194 const unsigned int ControlFunctionTableCount = sizeof(ControlFunctionTable)/sizeof(ControlFunctionTable[0]);
198 ControlWrapper::ControlWrapper( Toolkit::Control control,
199 GarbageCollectorInterface& gc )
200 : ActorWrapper( control, gc ),
206 ControlWrapper::~ControlWrapper()
208 mControlGarbageContainer.Release();
211 v8::Handle<v8::Object> ControlWrapper::WrapControl(v8::Isolate* isolate, Toolkit::Control control )
213 v8::EscapableHandleScope handleScope( isolate );
215 // Check whether the control is a Control
216 ControlWrapper::ControlType controlType = GetControlType( control.GetTypeName() );
218 if( controlType == ControlWrapper::UNKNOWN_CONTROL && Toolkit::Control::DownCast(control) )
220 controlType = ControlWrapper::CONTROL;
223 v8::Local<v8::Object> object = WrapControl( isolate, control, controlType );
225 return handleScope.Escape( object );
228 Toolkit::Control ControlWrapper::GetControl()
233 v8::Handle<v8::Object> ControlWrapper::WrapControl( v8::Isolate* isolate, Toolkit::Control control, ControlType controlType )
235 v8::EscapableHandleScope handleScope( isolate );
236 v8::Local<v8::ObjectTemplate> objectTemplate;
238 objectTemplate = GetControlTemplate( isolate, controlType );
240 // create an instance of the template
241 v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
243 // create the control object
244 ControlWrapper* pointer = new ControlWrapper( control, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
246 // assign the JavaScript object to the wrapper.
247 // This also stores Dali object, in an internal field inside the JavaScript object.
248 pointer->SetJavascriptObject( isolate, localObject );
250 return handleScope.Escape( localObject );
253 v8::Local<v8::ObjectTemplate> ControlWrapper::GetControlTemplate( v8::Isolate* isolate, ControlWrapper::ControlType type )
255 v8::EscapableHandleScope handleScope( isolate );
256 v8::Local<v8::ObjectTemplate> objectTemplate;
258 if( ControlTemplateLookup[type].controlTemplate->IsEmpty() )
260 objectTemplate = MakeDaliControlTemplate( isolate, type );
261 ControlTemplateLookup[type].controlTemplate->Reset( isolate, objectTemplate );
265 // get the object template
266 objectTemplate = v8::Local<v8::ObjectTemplate>::New( isolate, *ControlTemplateLookup[type].controlTemplate );
269 return handleScope.Escape( objectTemplate );
272 v8::Handle<v8::ObjectTemplate> ControlWrapper::MakeDaliControlTemplate( v8::Isolate* isolate, ControlType controlType )
274 v8::EscapableHandleScope handleScope( isolate );
276 // all the controls support actor APIs
277 v8::Local<v8::ObjectTemplate> objTemplate = ActorWrapper::MakeDaliActorTemplate( isolate, ActorWrapper::ACTOR );
279 // find out what API's this control supports
280 int supportApis = GetControlSupportedApis( controlType );
282 // add our function properties
283 for( unsigned int i = 0; i < ControlFunctionTableCount; ++i )
285 const ControlFunctions property = ControlFunctionTable[i];
287 // check to see if the control supports a certain type of API
288 // e.g. ItemView will support CONTROL_API and ITEMVIEW_API
289 if( supportApis & property.api )
291 std::string funcName = V8Utils::GetJavaScriptFunctionName( property.name);
293 objTemplate->Set( v8::String::NewFromUtf8( isolate, funcName.c_str() ),
294 v8::FunctionTemplate::New( isolate, property.function ) );
298 return handleScope.Escape( objTemplate );
301 void ControlWrapper::NewControl( const v8::FunctionCallbackInfo< v8::Value >& args)
303 v8::Isolate* isolate = args.GetIsolate();
304 v8::HandleScope handleScope( isolate );
306 if( !args.IsConstructCall() )
308 DALI_SCRIPT_EXCEPTION( isolate, "constructor called without 'new" );
313 std::string controlName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
315 Toolkit::Control control;
316 if( found && controlName != ControlApiLookup[0].controlName )
318 control = CreateControl( args, controlName ); // create the control with the given type
322 control = Toolkit::Control::New(); // no given type, so create the base type of control
327 v8::Local<v8::Object> localObject = WrapControl( isolate, control );
328 args.GetReturnValue().Set( localObject );
332 DALI_SCRIPT_EXCEPTION( isolate, "unsupported control type" );
337 * Given a control type name, e.g. ItemView returns the type, e.g. ControlWrapper::ITEMVIEW
339 ControlWrapper::ControlType ControlWrapper::GetControlType( const std::string& name )
341 for( unsigned int i = 0 ; i < ControlApiLookupCount ; i++ )
343 if( ControlApiLookup[i].controlName == name )
345 return ControlApiLookup[i].controlType;
348 return ControlWrapper::UNKNOWN_CONTROL;
351 void ControlWrapper::RegisterGarbage(void* garbage)
353 mControlGarbageContainer.PushBack(garbage);
356 } // namespace V8Plugin