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>
28 #include <dali-wrapper.h>
36 v8::Persistent<v8::ObjectTemplate> ControlWrapper::mControlTemplate;
37 v8::Persistent<v8::ObjectTemplate> ControlWrapper::mItemViewTemplate;
39 Vector< void* > ControlWrapper::mControlGarbageContainer;
46 * pointer to a persistent template handle
48 struct ControlTemplate
50 v8::Persistent<v8::ObjectTemplate>* controlTemplate;
54 * array of templates for each type of control
56 const ControlTemplate ControlTemplateLookup[]=
58 { &ControlWrapper::mControlTemplate }, // CONTROL
59 { &ControlWrapper::mItemViewTemplate } // ITEMVIEW
63 * Bitmask of API's that an control can support
65 enum ControlApiBitMask
72 * structure used for the ControlApiLookup.
74 struct ControlApiStruct
76 const char* controlName;
77 ControlWrapper::ControlType controlType;
78 Toolkit::Control (*constructor)( const v8::FunctionCallbackInfo< v8::Value >& args);
83 * Lookup table to match a control type with a constructor and supported API's.
84 * ControlWrapper::ControlType is used to index this table
86 const ControlApiStruct ControlApiLookup[]=
88 {"Control", ControlWrapper::CONTROL, NULL, CONTROL_API },
89 {"ItemView", ControlWrapper::ITEMVIEW, ItemViewApi::New, CONTROL_API | ITEMVIEW_API },
92 const unsigned int ControlApiLookupCount = sizeof(ControlApiLookup)/sizeof(ControlApiLookup[0]);
96 * Creates a control given a type name
97 * Uses the type registry to create an control of the correct type
99 Toolkit::Control CreateControl( const v8::FunctionCallbackInfo< v8::Value >& args,
100 const std::string& typeName )
102 Toolkit::Control control;
104 ControlWrapper::ControlType controlType = ControlWrapper::GetControlType( typeName );
106 // if we don't currently have specific binding for the given control type,
107 // try to use type registry to create it
108 if( controlType == ControlWrapper::UNKNOWN_CONTROL )
110 Dali::TypeInfo typeInfo = Dali::TypeRegistry::Get().GetTypeInfo( typeName );
113 Dali::BaseHandle handle = typeInfo.CreateInstance();
116 control = Toolkit::Control::DownCast( handle );
119 DALI_SCRIPT_EXCEPTION( args.GetIsolate(), "Unknown control type" );
120 return Toolkit::Control();
127 // run the constructor for this type of control so it can pull out custom parameters
128 control = (ControlApiLookup[controlType].constructor)( args );
135 * given a control type return what api's it supports
137 int GetControlSupportedApis( ControlWrapper::ControlType type )
139 return ControlApiLookup[type].supportApis;
143 * Used for the ControlFunctionTable to map function names to functions
144 * with for a specific API
146 struct ControlFunctions
148 const char* name; ///< function name
149 void (*function)( const v8::FunctionCallbackInfo< v8::Value >& args);
150 ControlApiBitMask api;
154 * Contains a list of all functions that can be called in
157 const ControlFunctions ControlFunctionTable[]=
160 /**************************************
162 **************************************/
163 { "GetLayoutCount", ItemViewApi::GetLayoutCount, ITEMVIEW_API },
164 { "AddLayout", ItemViewApi::AddLayout, ITEMVIEW_API },
165 { "RemoveLayout", ItemViewApi::RemoveLayout, ITEMVIEW_API },
166 { "ActivateLayout", ItemViewApi::ActivateLayout, ITEMVIEW_API },
167 { "GetItemSize", ItemViewApi::GetItemSize, ITEMVIEW_API },
168 { "SetItemSize", ItemViewApi::SetItemSize, ITEMVIEW_API },
169 { "ScrollToItem", ItemViewApi::ScrollToItem, ITEMVIEW_API },
170 { "GetItem", ItemViewApi::GetItem, ITEMVIEW_API },
171 { "GetItemId", ItemViewApi::GetItemId, ITEMVIEW_API },
172 { "GetItemsRange", ItemViewApi::GetItemsRange, ITEMVIEW_API },
176 const unsigned int ControlFunctionTableCount = sizeof(ControlFunctionTable)/sizeof(ControlFunctionTable[0]);
180 ControlWrapper::ControlWrapper( Toolkit::Control control,
181 GarbageCollectorInterface& gc )
182 : ActorWrapper( control, gc ),
188 ControlWrapper::~ControlWrapper()
190 mControlGarbageContainer.Release();
193 v8::Handle<v8::Object> ControlWrapper::WrapControl(v8::Isolate* isolate, Toolkit::Control control )
195 v8::EscapableHandleScope handleScope( isolate );
197 // Check whether the control is a Control
198 ControlWrapper::ControlType controlType = GetControlType( control.GetTypeName() );
200 if( controlType == ControlWrapper::UNKNOWN_CONTROL && Toolkit::Control::DownCast(control) )
202 controlType = ControlWrapper::CONTROL;
205 v8::Local<v8::Object> object = WrapControl( isolate, control, controlType );
207 return handleScope.Escape( object );
210 Toolkit::Control ControlWrapper::GetControl()
215 v8::Handle<v8::Object> ControlWrapper::WrapControl( v8::Isolate* isolate, Toolkit::Control control, ControlType controlType )
217 v8::EscapableHandleScope handleScope( isolate );
218 v8::Local<v8::ObjectTemplate> objectTemplate;
220 objectTemplate = GetControlTemplate( isolate, controlType );
222 // create an instance of the template
223 v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
225 // create the control object
226 ControlWrapper* pointer = new ControlWrapper( control, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
228 // assign the JavaScript object to the wrapper.
229 // This also stores Dali object, in an internal field inside the JavaScript object.
230 pointer->SetJavascriptObject( isolate, localObject );
232 return handleScope.Escape( localObject );
235 v8::Local<v8::ObjectTemplate> ControlWrapper::GetControlTemplate( v8::Isolate* isolate, ControlWrapper::ControlType type )
237 v8::EscapableHandleScope handleScope( isolate );
238 v8::Local<v8::ObjectTemplate> objectTemplate;
240 if( ControlTemplateLookup[type].controlTemplate->IsEmpty() )
242 objectTemplate = MakeDaliControlTemplate( isolate, type );
243 ControlTemplateLookup[type].controlTemplate->Reset( isolate, objectTemplate );
247 // get the object template
248 objectTemplate = v8::Local<v8::ObjectTemplate>::New( isolate, *ControlTemplateLookup[type].controlTemplate );
251 return handleScope.Escape( objectTemplate );
254 v8::Handle<v8::ObjectTemplate> ControlWrapper::MakeDaliControlTemplate( v8::Isolate* isolate, ControlType controlType )
256 v8::EscapableHandleScope handleScope( isolate );
258 // all the controls support actor APIs
259 v8::Local<v8::ObjectTemplate> objTemplate = ActorWrapper::MakeDaliActorTemplate( isolate, ActorWrapper::ACTOR );
261 // find out what API's this control supports
262 int supportApis = GetControlSupportedApis( controlType );
264 // add our function properties
265 for( unsigned int i = 0; i < ControlFunctionTableCount; ++i )
267 const ControlFunctions property = ControlFunctionTable[i];
269 // check to see if the control supports a certain type of API
270 // e.g. ItemView will support CONTROL_API and ITEMVIEW_API
271 if( supportApis & property.api )
273 std::string funcName = V8Utils::GetJavaScriptFunctionName( property.name);
275 objTemplate->Set( v8::String::NewFromUtf8( isolate, funcName.c_str() ),
276 v8::FunctionTemplate::New( isolate, property.function ) );
280 return handleScope.Escape( objTemplate );
283 void ControlWrapper::NewControl( const v8::FunctionCallbackInfo< v8::Value >& args)
285 v8::Isolate* isolate = args.GetIsolate();
286 v8::HandleScope handleScope( isolate );
288 if( !args.IsConstructCall() )
290 DALI_SCRIPT_EXCEPTION( isolate, "constructor called without 'new" );
295 std::string controlName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
297 Toolkit::Control control;
298 if( found && controlName != ControlApiLookup[0].controlName )
300 control = CreateControl( args, controlName ); // create the control with the given type
304 control = Toolkit::Control::New(); // no given type, so create the base type of control
309 v8::Local<v8::Object> localObject = WrapControl( isolate, control );
310 args.GetReturnValue().Set( localObject );
314 DALI_SCRIPT_EXCEPTION( isolate, "unsupported control type" );
319 * Given a control type name, e.g. ItemView returns the type, e.g. ControlWrapper::ITEMVIEW
321 ControlWrapper::ControlType ControlWrapper::GetControlType( const std::string& name )
323 for( unsigned int i = 0 ; i < ControlApiLookupCount ; i++ )
325 if( ControlApiLookup[i].controlName == name )
327 return ControlApiLookup[i].controlType;
330 return ControlWrapper::UNKNOWN_CONTROL;
333 void ControlWrapper::RegisterGarbage(void* garbage)
335 mControlGarbageContainer.PushBack(garbage);
338 } // namespace V8Plugin