JavaScript binding for ItemView
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / controls / item-view-api.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 "item-view-api.h"
20
21 // EXTERNAL INCLUDES
22 #include <fstream>
23 #include <dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h>
24 #include <dali-toolkit/public-api/controls/scrollable/item-view/item-factory.h>
25 #include <dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h>
26
27 // INTERNAL INCLUDES
28 #include <v8-utils.h>
29 #include <actors/actor-wrapper.h>
30 #include <controls/control-wrapper.h>
31 #include <controls/item-factory-wrapper.h>
32
33 namespace Dali
34 {
35
36 namespace V8Plugin
37 {
38
39 namespace  // unanmed namespace
40 {
41
42 Toolkit::ItemView GetItemView( v8::Isolate* isolate, const v8::FunctionCallbackInfo<v8::Value>& args )
43 {
44   HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, args.This() );
45   return Toolkit::ItemView::DownCast( handleWrapper->mHandle );
46 }
47
48 } //unanmed namespace
49
50 /***************************************
51  * ITEMVIEW API FUNCTIONS
52  ***************************************/
53
54 /**
55  * Constructor
56  *
57  * @for ItemView
58  * @constructor
59  * @method ItemView
60  * @return {Object} itemView
61  */
62 Toolkit::Control ItemViewApi::New( const v8::FunctionCallbackInfo< v8::Value >& args )
63 {
64   v8::Isolate* isolate = args.GetIsolate();
65   v8::HandleScope handleScope( isolate );
66
67   bool found( false );
68   Toolkit::ItemFactory& factory = ItemFactoryWrapper::GetItemFactoryFromParams( 1, found, isolate, args );
69   if( !found )
70   {
71     DALI_SCRIPT_EXCEPTION( isolate, "invalid ItemFactory parameter" );
72     return Toolkit::Control();
73   }
74   else
75   {
76     Toolkit::ItemView itemView = Toolkit::ItemView::New(factory);
77     ItemFactoryWrapper::SetItemView(factory, itemView);
78     return itemView;
79   }
80 }
81
82 /**
83  * Query the number of layouts.
84  *
85  * @for ItemView
86  * @method getLayoutCount
87  * @return {Integer} The number of layouts.
88  */
89 void ItemViewApi::GetLayoutCount( const v8::FunctionCallbackInfo< v8::Value >& args)
90 {
91   v8::Isolate* isolate = args.GetIsolate();
92   v8::HandleScope handleScope( isolate );
93
94   Toolkit::ItemView itemView = GetItemView( isolate, args );
95
96   args.GetReturnValue().Set( v8::Integer::New( isolate, itemView.GetLayoutCount() ) );
97 }
98
99 /**
100  * Add a layout
101  *
102  * @for ItemView
103  * @method addLayout
104  * @param {Integer} layout The layout to be added
105  * @example
106  *      // layout is one of the following
107  *      dali.ITEM_LAYOUT_LIST
108  *      dali.ITEM_LAYOUT_GRID
109  *
110  *      itemView.addLayout( dali.ITEM_LAYOUT_LIST );
111  */
112 void ItemViewApi::AddLayout( const v8::FunctionCallbackInfo<v8::Value>& args )
113 {
114   v8::Isolate* isolate = args.GetIsolate();
115   v8::HandleScope handleScope( isolate );
116
117   Toolkit::ItemView itemView = GetItemView( isolate, args );
118
119   bool found( false );
120   int layout = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
121   if( !found )
122   {
123     DALI_SCRIPT_EXCEPTION( isolate, "invalid layout parameter" );
124     return;
125   }
126
127   Toolkit::ItemLayoutPtr layoutPtr = Toolkit::DefaultItemLayout::New( static_cast<Toolkit::DefaultItemLayout::Type>(layout) );
128   itemView.AddLayout( *layoutPtr );
129 }
130
131 /**
132  * Remove a layout.
133  *
134  * @for ItemView
135  * @method removeLayout
136  * @param {Integer} layoutIndex The index of the ItemView layouts which must be less than getLayoutCount().
137  */
138 void ItemViewApi::RemoveLayout( const v8::FunctionCallbackInfo<v8::Value>& args )
139 {
140   v8::Isolate* isolate = args.GetIsolate();
141   v8::HandleScope handleScope( isolate );
142
143   Toolkit::ItemView itemView = GetItemView( isolate, args );
144
145   bool found( false );
146   int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
147   if( !found )
148   {
149     DALI_SCRIPT_EXCEPTION( isolate, "invalid index parameter" );
150     return;
151   }
152
153   itemView.RemoveLayout( layoutIndex );
154 }
155
156 /**
157  * Activate one of the layouts. This will resize the ItemView and relayout actors within the ItemView.
158  *
159  * @for ItemView
160  * @method activateLayout
161  * @param {Integer} layoutIndex The index of the ItemView layout which must be less than getLayoutCount().
162  * @param {Object} targetSize An array of 3 numbers for the target ItemView and layout size.
163  * @param {Float} [durationSeconds] The time taken to relayout in seconds (0 by default for immediate).
164  */
165 void ItemViewApi::ActivateLayout( const v8::FunctionCallbackInfo<v8::Value>& args )
166 {
167   v8::Isolate* isolate = args.GetIsolate();
168   v8::HandleScope handleScope( isolate );
169
170   Toolkit::ItemView itemView = GetItemView( isolate, args );
171
172   bool found( false );
173   int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
174   if( !found )
175   {
176     DALI_SCRIPT_EXCEPTION( isolate, "invalid layout index parameter" );
177     return;
178   }
179
180   found = false;
181   Vector3 targetSize = V8Utils::GetVector3Parameter( PARAMETER_1, found, isolate, args );
182   if( !found )
183   {
184     DALI_SCRIPT_EXCEPTION( isolate, "Vector3 targetSize size parameter missing" );
185     return;
186   }
187
188   found = false;
189   float durationSeconds = V8Utils::GetFloatParameter( PARAMETER_2, found, isolate, args, 0.0f ); // 0 by default for immediate activation
190
191   itemView.ActivateLayout( layoutIndex, targetSize, durationSeconds );
192 }
193
194 /**
195  * Retrieve the target size of an item in the given layout.
196  * This will return the default size for the layout unless overridden by calling setLayoutItemSize().
197  *
198  * @for ItemView
199  * @method getItemSize
200  * @param {Integer} layoutIndex The index of the ItemView layout which must be less than getLayoutCount().
201  * @param {Integer} itemId The ID of an item in the layout.
202  * @param {Object} targetLayoutSize An array of 3 numbers for the target ItemView and layout size.
203  * @return {Object} The target size of the item {x, y, z}.
204  */
205 void ItemViewApi::GetItemSize( const v8::FunctionCallbackInfo<v8::Value>& args )
206 {
207   v8::Isolate* isolate = args.GetIsolate();
208   v8::HandleScope handleScope( isolate );
209
210   Toolkit::ItemView itemView = GetItemView( isolate, args );
211
212   bool found( false );
213   int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
214   if( !found )
215   {
216     DALI_SCRIPT_EXCEPTION( isolate, "invalid layout index parameter" );
217     return;
218   }
219
220   found = false;
221   int itemId = V8Utils::GetIntegerParameter( PARAMETER_1, found, isolate, args, 0 /* default */);
222   if( !found )
223   {
224     DALI_SCRIPT_EXCEPTION( isolate, "invalid item ID parameter" );
225     return;
226   }
227
228   found = false;
229   Vector3 targetLayoutSize = V8Utils::GetVector3Parameter( PARAMETER_2, found, isolate, args );
230   if( found )
231   {
232     Toolkit::ItemLayoutPtr layoutPtr = itemView.GetLayout(layoutIndex);
233     Vector3 itemSize;
234     layoutPtr->GetItemSize( itemId, targetLayoutSize, itemSize );
235
236     v8::Local<v8::Object> itemSizeObject = v8::Object::New( isolate );
237
238     itemSizeObject->Set( v8::String::NewFromUtf8( isolate, "x" ), v8::Integer::New( isolate, itemSize.width ) );
239     itemSizeObject->Set( v8::String::NewFromUtf8( isolate, "y" ), v8::Integer::New( isolate, itemSize.height ) );
240     itemSizeObject->Set( v8::String::NewFromUtf8( isolate, "z" ), v8::Integer::New( isolate, itemSize.depth ) );
241
242     args.GetReturnValue().Set( itemSizeObject );
243   }
244   else
245   {
246     DALI_SCRIPT_EXCEPTION( isolate, "invalid Vector3 target size parameter" );
247   }
248 }
249
250 /**
251  * Set the size of the item for the given layout which overrides the default item size for the layout.
252  *
253  * @for ItemView
254  * @method setItemSize
255  * @param {Integer} layoutIndex The index of the ItemView layout which must be less than getLayoutCount().
256  * @param {Object} itemSize An array of 3 numbers for the size of the item.
257  * @example
258  *      itemView.setLayoutItemSize( 0, [100.0, 50.0, 0.0] );
259  */
260 void ItemViewApi::SetItemSize( const v8::FunctionCallbackInfo<v8::Value>& args )
261 {
262   v8::Isolate* isolate = args.GetIsolate();
263   v8::HandleScope handleScope( isolate );
264
265   Toolkit::ItemView itemView = GetItemView( isolate, args );
266
267   bool found( false );
268   int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
269   if( !found )
270   {
271     DALI_SCRIPT_EXCEPTION( isolate, "invalid layout index parameter" );
272     return;
273   }
274
275   found = false;
276   Vector3 itemSize = V8Utils::GetVector3Parameter( PARAMETER_1, found, isolate, args );
277   if( found )
278   {
279     Toolkit::ItemLayoutPtr layoutPtr = itemView.GetLayout(layoutIndex);
280     layoutPtr->SetItemSize( itemSize );
281   }
282   else
283   {
284     DALI_SCRIPT_EXCEPTION( isolate, "invalid item size parameter" );
285   }
286 }
287
288 /**
289  * Scroll the current layout to a particular item.
290  * If calling this with zero second of duration immediately after calling activateLayout(),
291  * it will not work unless the duration of relayout animation for activateLayout is also
292  * set to zero.
293  *
294  * @for ItemView
295  * @method scrollToItem
296  * @param {Integer} itemId The ID of an item in the layout.
297  * @param {Float} [durationSeconds] How long the scrolling takes in seconds (0 by default for instant scrolling to the particular item).
298  */
299 void ItemViewApi::ScrollToItem( const v8::FunctionCallbackInfo<v8::Value>& args )
300 {
301   v8::Isolate* isolate = args.GetIsolate();
302   v8::HandleScope handleScope( isolate );
303
304   Toolkit::ItemView itemView = GetItemView( isolate, args );
305
306   bool found( false );
307   int itemId = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
308   if( !found )
309   {
310     DALI_SCRIPT_EXCEPTION( isolate, "invalid item Id parameter" );
311     return;
312   }
313
314   found = false;
315   float durationSeconds = V8Utils::GetFloatParameter( PARAMETER_1, found, isolate, args, 0.0f ); // 0 by default for instant scrolling
316
317   itemView.ScrollToItem( itemId, durationSeconds );
318 }
319
320 /**
321  * Given the Item ID, this returns the accompanying actor.
322  *
323  * @for ItemView
324  * @method getItem
325  * @param {Integer} itemId The Item ID of the actor required.
326  * @return {Object} The Actor corresponding to the Item ID.
327  */
328 void ItemViewApi::GetItem( const v8::FunctionCallbackInfo<v8::Value>& args )
329 {
330   v8::Isolate* isolate = args.GetIsolate();
331   v8::HandleScope handleScope( isolate );
332
333   Toolkit::ItemView itemView = GetItemView( isolate, args );
334
335   bool found( false );
336   int itemId = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
337   if( found )
338   {
339     found = false;
340     Actor actor = itemView.GetItem( itemId );
341     if( actor )
342     {
343       found = true;
344       // wrap the actor
345       v8::Handle < v8::Object > wrappedActor = ActorWrapper::WrapActor( isolate, actor );
346       args.GetReturnValue().Set( wrappedActor );
347     }
348   }
349
350   if( !found )
351   {
352     DALI_SCRIPT_EXCEPTION( isolate, "invalid item ID" );
353     return;
354   }
355 }
356
357 /**
358  * Returns the Item ID of the specified actor. The actor must be an item of ItemView.
359  *
360  * @for ItemView
361  * @method getItemId
362  * @param {Object} actor The actor whose Item ID is required.
363  * @return {Integer} The Item ID of the item.
364  */
365 void ItemViewApi::GetItemId( const v8::FunctionCallbackInfo<v8::Value>& args )
366 {
367   v8::Isolate* isolate = args.GetIsolate();
368   v8::HandleScope handleScope( isolate );
369
370   Toolkit::ItemView itemView = GetItemView( isolate, args );
371
372   bool found( false );
373   Actor actor = V8Utils::GetActorParameter( 0, found, isolate, args );
374   if( found )
375   {
376     args.GetReturnValue().Set( itemView.GetItemId(actor) );
377   }
378   else
379   {
380     DALI_SCRIPT_EXCEPTION( isolate, "invalid item actor parameter" );
381     return;
382   }
383 }
384
385 /**
386  * Get the range of items that are currently in ItemView.
387  *
388  * @for ItemView
389  * @method getItemsRange
390  * @return {Object} The range of items in the item ID {begin, end}.
391  */
392 void ItemViewApi::GetItemsRange( const v8::FunctionCallbackInfo<v8::Value>& args )
393 {
394   v8::Isolate* isolate = args.GetIsolate();
395   v8::HandleScope handleScope( isolate );
396
397   Toolkit::ItemView itemView = GetItemView( isolate, args );
398
399   Toolkit::ItemRange range(0, 0);
400   itemView.GetItemsRange(range);
401
402   v8::Local<v8::Object> itemRangeObject = v8::Object::New( isolate );
403
404   itemRangeObject->Set( v8::String::NewFromUtf8( isolate, "begin" ), v8::Integer::New( isolate, range.begin ) );
405   itemRangeObject->Set( v8::String::NewFromUtf8( isolate, "end" ), v8::Integer::New( isolate, range.end ) );
406
407   args.GetReturnValue().Set( itemRangeObject );
408 }
409
410 } // namespace V8Plugin
411
412 } // namespace Dali