2 * Copyright (c) 2020 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 "shared/view.h"
21 #include <dali-toolkit/dali-toolkit.h>
22 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
23 #include <dali/dali.h>
26 using namespace Dali::Toolkit;
39 const char* IMAGE_PATHS[] = {
40 DEMO_IMAGE_DIR "gallery-medium-1.jpg",
41 DEMO_IMAGE_DIR "gallery-medium-2.jpg",
42 DEMO_IMAGE_DIR "gallery-medium-3.jpg",
43 DEMO_IMAGE_DIR "gallery-medium-4.jpg",
44 DEMO_IMAGE_DIR "gallery-medium-5.jpg",
45 DEMO_IMAGE_DIR "gallery-medium-6.jpg",
46 DEMO_IMAGE_DIR "gallery-medium-7.jpg",
47 DEMO_IMAGE_DIR "gallery-medium-8.jpg",
48 DEMO_IMAGE_DIR "gallery-medium-9.jpg",
49 DEMO_IMAGE_DIR "gallery-medium-10.jpg",
50 DEMO_IMAGE_DIR "gallery-medium-11.jpg",
51 DEMO_IMAGE_DIR "gallery-medium-12.jpg",
52 DEMO_IMAGE_DIR "gallery-medium-13.jpg",
53 DEMO_IMAGE_DIR "gallery-medium-14.jpg",
54 DEMO_IMAGE_DIR "gallery-medium-15.jpg",
55 DEMO_IMAGE_DIR "gallery-medium-16.jpg",
56 DEMO_IMAGE_DIR "gallery-medium-17.jpg",
57 DEMO_IMAGE_DIR "gallery-medium-18.jpg",
58 DEMO_IMAGE_DIR "gallery-medium-19.jpg",
59 DEMO_IMAGE_DIR "gallery-medium-20.jpg",
60 DEMO_IMAGE_DIR "gallery-medium-21.jpg",
61 DEMO_IMAGE_DIR "gallery-medium-22.jpg",
62 DEMO_IMAGE_DIR "gallery-medium-23.jpg",
63 DEMO_IMAGE_DIR "gallery-medium-24.jpg",
64 DEMO_IMAGE_DIR "gallery-medium-25.jpg",
65 DEMO_IMAGE_DIR "gallery-medium-26.jpg",
66 DEMO_IMAGE_DIR "gallery-medium-27.jpg",
67 DEMO_IMAGE_DIR "gallery-medium-28.jpg",
68 DEMO_IMAGE_DIR "gallery-medium-29.jpg",
69 DEMO_IMAGE_DIR "gallery-medium-30.jpg",
70 DEMO_IMAGE_DIR "gallery-medium-31.jpg",
71 DEMO_IMAGE_DIR "gallery-medium-32.jpg",
72 DEMO_IMAGE_DIR "gallery-medium-33.jpg",
73 DEMO_IMAGE_DIR "gallery-medium-34.jpg",
74 DEMO_IMAGE_DIR "gallery-medium-35.jpg",
75 DEMO_IMAGE_DIR "gallery-medium-36.jpg",
76 DEMO_IMAGE_DIR "gallery-medium-37.jpg",
77 DEMO_IMAGE_DIR "gallery-medium-38.jpg",
78 DEMO_IMAGE_DIR "gallery-medium-39.jpg",
79 DEMO_IMAGE_DIR "gallery-medium-40.jpg",
80 DEMO_IMAGE_DIR "gallery-medium-41.jpg",
81 DEMO_IMAGE_DIR "gallery-medium-42.jpg",
82 DEMO_IMAGE_DIR "gallery-medium-43.jpg",
83 DEMO_IMAGE_DIR "gallery-medium-44.jpg",
84 DEMO_IMAGE_DIR "gallery-medium-45.jpg",
85 DEMO_IMAGE_DIR "gallery-medium-46.jpg",
86 DEMO_IMAGE_DIR "gallery-medium-47.jpg",
87 DEMO_IMAGE_DIR "gallery-medium-48.jpg",
88 DEMO_IMAGE_DIR "gallery-medium-49.jpg",
89 DEMO_IMAGE_DIR "gallery-medium-50.jpg",
90 DEMO_IMAGE_DIR "gallery-medium-51.jpg",
91 DEMO_IMAGE_DIR "gallery-medium-52.jpg",
92 DEMO_IMAGE_DIR "gallery-medium-53.jpg",
95 const unsigned int NUM_IMAGES = sizeof(IMAGE_PATHS) / sizeof(char*);
97 const char* BACKGROUND_IMAGE("");
98 const char* TOOLBAR_IMAGE(DEMO_IMAGE_DIR "top-bar.png");
99 const char* EDIT_IMAGE(DEMO_IMAGE_DIR "icon-edit.png");
100 const char* EDIT_IMAGE_SELECTED(DEMO_IMAGE_DIR "icon-edit-selected.png");
101 const char* SPIRAL_LAYOUT_IMAGE(DEMO_IMAGE_DIR "icon-item-view-layout-spiral.png");
102 const char* SPIRAL_LAYOUT_IMAGE_SELECTED(DEMO_IMAGE_DIR "icon-item-view-layout-spiral-selected.png");
103 const char* GRID_LAYOUT_IMAGE(DEMO_IMAGE_DIR "icon-item-view-layout-grid.png");
104 const char* GRID_LAYOUT_IMAGE_SELECTED(DEMO_IMAGE_DIR "icon-item-view-layout-grid-selected.png");
105 const char* DEPTH_LAYOUT_IMAGE(DEMO_IMAGE_DIR "icon-item-view-layout-depth.png");
106 const char* DEPTH_LAYOUT_IMAGE_SELECTED(DEMO_IMAGE_DIR "icon-item-view-layout-depth-selected.png");
107 const char* DELETE_IMAGE(DEMO_IMAGE_DIR "icon-delete.png");
108 const char* DELETE_IMAGE_SELECTED(DEMO_IMAGE_DIR "icon-delete-selected.png");
109 const char* REPLACE_IMAGE(DEMO_IMAGE_DIR "icon-replace.png");
110 const char* REPLACE_IMAGE_SELECTED(DEMO_IMAGE_DIR "icon-replace-selected.png");
111 const char* INSERT_IMAGE(DEMO_IMAGE_DIR "icon-insert.png");
112 const char* INSERT_IMAGE_SELECTED(DEMO_IMAGE_DIR "icon-insert-selected.png");
113 const char* SELECTED_IMAGE(DEMO_IMAGE_DIR "item-select-check.png");
114 const char* APPLICATION_TITLE("ItemView");
116 const char* SPIRAL_LABEL("Spiral");
117 const char* GRID_LABEL("Grid");
118 const char* DEPTH_LABEL("Depth");
120 const float ITEM_BORDER_SIZE = 2.0f;
122 const float DEPTH_LAYOUT_ITEM_SIZE_FACTOR_PORTRAIT = 1.0f;
123 const float DEPTH_LAYOUT_ITEM_SIZE_FACTOR_LANDSCAPE = 0.8f;
124 const float DEPTH_LAYOUT_COLUMNS = 3.0f;
126 const float MIN_SWIPE_DISTANCE = 15.0f;
127 const float MIN_SWIPE_SPEED = 5.0f;
129 const float SELECTION_BORDER_WIDTH = 3.0f;
130 const float BUTTON_BORDER = -10.0f;
131 const float MENU_OPTION_HEIGHT(140.0f);
132 const float LABEL_TEXT_SIZE_Y = 20.0f;
134 const Vector3 INITIAL_OFFSCREEN_POSITION(1000.0f, 0, -1000.0f);
136 const float SCROLL_TO_ITEM_ANIMATION_TIME = 5.f;
138 static Vector3 DepthLayoutItemSizeFunctionPortrait(float layoutWidth)
140 float width = (layoutWidth / (DEPTH_LAYOUT_COLUMNS + 1.0f)) * DEPTH_LAYOUT_ITEM_SIZE_FACTOR_PORTRAIT;
143 return Vector3(width, width, width);
146 static Vector3 DepthLayoutItemSizeFunctionLandscape(float layoutWidth)
148 float width = (layoutWidth / (DEPTH_LAYOUT_COLUMNS + 1.0f)) * DEPTH_LAYOUT_ITEM_SIZE_FACTOR_LANDSCAPE;
151 return Vector3(width, width, width);
154 } // unnamed namespace
157 * This example shows how to use ItemView UI control.
158 * There are three layouts created for ItemView, i.e., Spiral, Depth and Grid.
159 * There is one button in the upper-left corner for quitting the application and
160 * another button in the upper-right corner for switching between different layouts.
162 class ItemViewExample : public ConnectionTracker, public ItemFactory
179 * @param application class, stored as reference
181 ItemViewExample(Application& application)
182 : mApplication(application),
185 mCurrentLayout(SPIRAL_LAYOUT),
186 mDurationSeconds(0.25f)
188 // Connect to the Application's Init signal
189 mApplication.InitSignal().Connect(this, &ItemViewExample::OnInit);
193 * This method gets called once the main loop of application is up and running
195 void OnInit(Application& app)
197 Window window = app.GetWindow();
198 window.KeyEventSignal().Connect(this, &ItemViewExample::OnKeyEvent);
199 window.GetRootLayer().SetProperty(Layer::Property::BEHAVIOR, Layer::LAYER_3D);
201 Vector2 windowSize = window.GetSize();
203 // Creates a default view with a default tool bar.
204 // The view is added to the window.
206 Layer contents = DemoHelper::CreateView(mApplication,
213 // Create an edit mode button. (left of toolbar)
214 Toolkit::PushButton editButton = Toolkit::PushButton::New();
215 editButton.SetProperty(Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL, EDIT_IMAGE);
216 editButton.SetProperty(Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL, EDIT_IMAGE_SELECTED);
217 editButton.ClickedSignal().Connect(this, &ItemViewExample::OnModeButtonClicked);
218 editButton.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
219 mToolBar.AddControl(editButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HORIZONTAL_LEFT, DemoHelper::DEFAULT_MODE_SWITCH_PADDING);
221 // Create a layout toggle button. (right of toolbar)
222 mLayoutButton = Toolkit::PushButton::New();
223 mLayoutButton.SetProperty(Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL, SPIRAL_LAYOUT_IMAGE);
224 mLayoutButton.SetProperty(Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL, SPIRAL_LAYOUT_IMAGE_SELECTED);
225 mLayoutButton.ClickedSignal().Connect(this, &ItemViewExample::OnLayoutButtonClicked);
226 mLayoutButton.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
227 mToolBar.AddControl(mLayoutButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HORIZONTAL_RIGHT, DemoHelper::DEFAULT_MODE_SWITCH_PADDING);
229 // Create a delete button (bottom right of screen)
230 mDeleteButton = Toolkit::PushButton::New();
231 mDeleteButton.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_RIGHT);
232 mDeleteButton.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_RIGHT);
233 mDeleteButton.SetProperty(Actor::Property::POSITION, Vector2(BUTTON_BORDER, BUTTON_BORDER));
234 mDeleteButton.SetProperty(Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D);
235 mDeleteButton.SetProperty(Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL, DELETE_IMAGE);
236 mDeleteButton.SetProperty(Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL, DELETE_IMAGE_SELECTED);
237 mDeleteButton.SetProperty(Toolkit::Control::Property::BACKGROUND, TOOLBAR_IMAGE);
238 mDeleteButton.SetProperty(Actor::Property::SIZE, Vector2(windowSize.width * 0.15f, windowSize.width * 0.15f));
239 mDeleteButton.ClickedSignal().Connect(this, &ItemViewExample::OnDeleteButtonClicked);
240 mDeleteButton.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
241 mDeleteButton.SetProperty(Actor::Property::VISIBLE, false);
242 window.Add(mDeleteButton);
244 // Create an insert button (bottom right of screen)
245 mInsertButton = Toolkit::PushButton::New();
246 mInsertButton.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_RIGHT);
247 mInsertButton.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_RIGHT);
248 mInsertButton.SetProperty(Actor::Property::POSITION, Vector2(BUTTON_BORDER, BUTTON_BORDER));
249 mInsertButton.SetProperty(Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D);
250 mInsertButton.SetProperty(Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL, INSERT_IMAGE);
251 mInsertButton.SetProperty(Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL, INSERT_IMAGE_SELECTED);
252 mInsertButton.SetProperty(Toolkit::Control::Property::BACKGROUND, TOOLBAR_IMAGE);
253 mInsertButton.SetProperty(Actor::Property::SIZE, Vector2(windowSize.width * 0.15f, windowSize.width * 0.15f));
254 mInsertButton.ClickedSignal().Connect(this, &ItemViewExample::OnInsertButtonClicked);
255 mInsertButton.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
256 mInsertButton.SetProperty(Actor::Property::VISIBLE, false);
257 window.Add(mInsertButton);
259 // Create an replace button (bottom right of screen)
260 mReplaceButton = Toolkit::PushButton::New();
261 mReplaceButton.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_RIGHT);
262 mReplaceButton.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_RIGHT);
263 mReplaceButton.SetProperty(Actor::Property::POSITION, Vector2(BUTTON_BORDER, BUTTON_BORDER));
264 mReplaceButton.SetProperty(Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D);
265 mReplaceButton.SetProperty(Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL, REPLACE_IMAGE);
266 mReplaceButton.SetProperty(Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL, REPLACE_IMAGE_SELECTED);
267 mReplaceButton.SetProperty(Toolkit::Control::Property::BACKGROUND, TOOLBAR_IMAGE);
268 mReplaceButton.SetProperty(Actor::Property::SIZE, Vector2(windowSize.width * 0.15f, windowSize.width * 0.15f));
269 mReplaceButton.ClickedSignal().Connect(this, &ItemViewExample::OnReplaceButtonClicked);
270 mReplaceButton.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
271 mReplaceButton.SetProperty(Actor::Property::VISIBLE, false);
272 window.Add(mReplaceButton);
274 // Create the item view actor
275 mItemView = ItemView::New(*this);
276 mItemView.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
277 mItemView.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
279 // Display item view on the window
280 window.Add(mItemView);
281 window.GetRootLayer().SetProperty(Layer::Property::BEHAVIOR, Layer::LAYER_3D);
283 // Create the layouts
284 mSpiralLayout = DefaultItemLayout::New(DefaultItemLayout::SPIRAL);
285 mDepthLayout = DefaultItemLayout::New(DefaultItemLayout::DEPTH);
286 mGridLayout = DefaultItemLayout::New(DefaultItemLayout::GRID);
288 // Add the layouts to item view
289 mItemView.AddLayout(*mSpiralLayout);
290 mItemView.AddLayout(*mDepthLayout);
291 mItemView.AddLayout(*mGridLayout);
293 mItemView.SetMinimumSwipeDistance(MIN_SWIPE_DISTANCE);
294 mItemView.SetMinimumSwipeSpeed(MIN_SWIPE_SPEED);
296 // Activate the spiral layout
297 SetLayout(mCurrentLayout);
298 mItemView.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
299 KeyboardFocusManager::Get().PreFocusChangeSignal().Connect(this, &ItemViewExample::OnKeyboardPreFocusChange);
301 // Set the title and icon to the current layout
305 mLongPressDetector = LongPressGestureDetector::New();
306 mLongPressDetector.Attach(mItemView);
307 mLongPressDetector.DetectedSignal().Connect(this, &ItemViewExample::OnLongPress);
310 Actor OnKeyboardPreFocusChange(Actor current, Actor proposed, Control::KeyboardFocus::Direction direction)
312 if(!current && !proposed)
321 * Animate to a different layout
325 Animation animation = Animation::New(mDurationSeconds);
326 animation.FinishedSignal().Connect(this, &ItemViewExample::AnimationFinished);
327 animation.AnimateTo(Property(mItemView, Actor::Property::COLOR_ALPHA), 0.0f);
331 void AnimationFinished(Animation&)
333 SetLayout(mCurrentLayout);
335 Animation animation = Animation::New(mDurationSeconds);
336 animation.AnimateTo(Property(mItemView, Actor::Property::COLOR_ALPHA), 1.0f);
341 * Switch to a different item view layout
343 void SetLayout(int layoutId)
345 Window window = mApplication.GetWindow();
346 switch(mCurrentLayout)
351 window.GetRootLayer().SetProperty(Layer::Property::BEHAVIOR, Layer::LAYER_3D);
356 window.GetRootLayer().SetProperty(Layer::Property::BEHAVIOR, Layer::LAYER_UI);
361 // Set the new orientation to the layout
362 mItemView.GetLayout(layoutId)->SetOrientation(static_cast<ControlOrientation::Type>(mOrientation / 90));
364 Vector2 windowSize = window.GetSize();
366 if(layoutId == DEPTH_LAYOUT)
368 // Set up the depth layout according to the new orientation
369 if(Toolkit::IsVertical(mDepthLayout->GetOrientation()))
371 mDepthLayout->SetItemSize(DepthLayoutItemSizeFunctionPortrait(windowSize.width));
375 mDepthLayout->SetItemSize(DepthLayoutItemSizeFunctionLandscape(windowSize.height));
379 // Enable anchoring for depth layout only
380 mItemView.SetAnchoring(layoutId == DEPTH_LAYOUT);
382 // Activate the layout
383 mItemView.ActivateLayout(layoutId, Vector3(windowSize.x, windowSize.y, windowSize.x), 0.0f);
386 bool OnLayoutButtonClicked(Toolkit::Button button)
388 // Switch to the next layout
389 mCurrentLayout = (mCurrentLayout + 1) % mItemView.GetLayoutCount();
399 bool OnModeButtonClicked(Toolkit::Button button)
406 void SwitchToNextMode()
413 mMode = MODE_REMOVE_MANY;
414 EnterRemoveManyMode();
418 case MODE_REMOVE_MANY:
420 ExitRemoveManyMode();
429 mMode = MODE_INSERT_MANY;
430 EnterInsertManyMode();
434 case MODE_INSERT_MANY:
436 ExitInsertManyMode();
437 mMode = MODE_REPLACE;
445 mMode = MODE_REPLACE_MANY;
446 EnterReplaceManyMode();
450 case MODE_REPLACE_MANY:
452 ExitReplaceManyMode();
468 void EnterRemoveMode()
470 SetTitle("Edit: Remove");
472 mTapDetector = TapGestureDetector::New();
474 for(unsigned int i = 0u; i < mItemView.GetChildCount(); ++i)
476 mTapDetector.Attach(mItemView.GetChildAt(i));
479 mTapDetector.DetectedSignal().Connect(this, &ItemViewExample::RemoveOnTap);
482 void ExitRemoveMode()
484 mTapDetector.Reset();
487 void RemoveOnTap(Actor actor, const TapGesture& tap)
489 mItemView.RemoveItem(mItemView.GetItemId(actor), 0.5f);
492 void EnterRemoveManyMode()
494 SetTitle("Edit: Remove Many");
496 mDeleteButton.SetProperty(Actor::Property::VISIBLE, true);
498 mTapDetector = TapGestureDetector::New();
500 for(unsigned int i = 0u; i < mItemView.GetChildCount(); ++i)
502 Actor child = mItemView.GetChildAt(i);
503 Actor box = child.FindChildByName("CheckBox");
507 mTapDetector.Attach(child);
508 box.SetProperty(Actor::Property::VISIBLE, true);
512 mTapDetector.DetectedSignal().Connect(this, &ItemViewExample::SelectOnTap);
515 void ExitRemoveManyMode()
517 for(unsigned int i = 0u; i < mItemView.GetChildCount(); ++i)
519 Actor child = mItemView.GetChildAt(i);
520 Actor box = child.FindChildByName("CheckBox");
524 box.SetProperty(Actor::Property::VISIBLE, false);
526 Actor tick = box.FindChildByName("Tick");
529 tick.SetProperty(Actor::Property::VISIBLE, false);
534 mTapDetector.Reset();
536 mDeleteButton.SetProperty(Actor::Property::VISIBLE, false);
539 void SelectOnTap(Actor actor, const TapGesture& tap)
541 Actor tick = actor.FindChildByName("Tick");
544 tick.SetProperty(Actor::Property::VISIBLE, !tick.GetCurrentProperty<bool>(Actor::Property::VISIBLE));
548 void OnLongPress(Actor actor, const LongPressGesture& gesture)
550 switch(gesture.GetState())
552 case GestureState::STARTED:
554 const Size& size = mApplication.GetWindow().GetSize();
556 ItemRange range(0u, 0u);
557 mItemView.GetItemsRange(range);
559 const unsigned int item = (gesture.GetScreenPoint().y < 0.5f * size.height) ? range.begin : range.end;
560 mItemView.ScrollToItem(item, SCROLL_TO_ITEM_ANIMATION_TIME);
564 case GestureState::FINISHED:
566 Property::Map attributes;
567 mItemView.DoAction("stopScrolling", attributes);
577 bool OnDeleteButtonClicked(Toolkit::Button button)
579 ItemIdContainer removeList;
581 for(unsigned int i = 0u; i < mItemView.GetChildCount(); ++i)
583 Actor child = mItemView.GetChildAt(i);
584 Actor tick = child.FindChildByName("Tick");
586 if(tick && tick.GetCurrentProperty<bool>(Actor::Property::VISIBLE))
588 removeList.push_back(mItemView.GetItemId(child));
592 if(!removeList.empty())
594 mItemView.RemoveItems(removeList, 0.5f);
600 void EnterInsertMode()
602 SetTitle("Edit: Insert");
604 mTapDetector = TapGestureDetector::New();
606 for(unsigned int i = 0u; i < mItemView.GetChildCount(); ++i)
608 mTapDetector.Attach(mItemView.GetChildAt(i));
611 mTapDetector.DetectedSignal().Connect(this, &ItemViewExample::InsertOnTap);
614 void ExitInsertMode()
616 mTapDetector.Reset();
619 void InsertOnTap(Actor actor, const TapGesture& tap)
621 ItemId id = mItemView.GetItemId(actor);
623 Actor newActor = NewItem(rand());
625 mItemView.InsertItem(Item(id, newActor), 0.5f);
628 void EnterInsertManyMode()
630 SetTitle("Edit: Insert Many");
632 mInsertButton.SetProperty(Actor::Property::VISIBLE, true);
634 mTapDetector = TapGestureDetector::New();
636 for(unsigned int i = 0u; i < mItemView.GetChildCount(); ++i)
638 Actor child = mItemView.GetChildAt(i);
639 Actor box = child.FindChildByName("CheckBox");
643 mTapDetector.Attach(child);
644 box.SetProperty(Actor::Property::VISIBLE, true);
648 mTapDetector.DetectedSignal().Connect(this, &ItemViewExample::SelectOnTap);
651 void ExitInsertManyMode()
653 for(unsigned int i = 0u; i < mItemView.GetChildCount(); ++i)
655 Actor child = mItemView.GetChildAt(i);
656 Actor box = child.FindChildByName("CheckBox");
660 box.SetProperty(Actor::Property::VISIBLE, false);
662 Actor tick = box.FindChildByName("Tick");
665 tick.SetProperty(Actor::Property::VISIBLE, false);
670 mTapDetector.Reset();
672 mInsertButton.SetProperty(Actor::Property::VISIBLE, false);
675 bool OnInsertButtonClicked(Toolkit::Button button)
677 ItemContainer insertList;
679 for(unsigned int i = 0u; i < mItemView.GetChildCount(); ++i)
681 Actor child = mItemView.GetChildAt(i);
682 Actor tick = child.FindChildByName("Tick");
684 if(tick && tick.GetCurrentProperty<bool>(Actor::Property::VISIBLE))
686 insertList.push_back(Item(mItemView.GetItemId(child), NewItem(rand())));
690 if(!insertList.empty())
692 mItemView.InsertItems(insertList, 0.5f);
698 void EnterReplaceMode()
700 SetTitle("Edit: Replace");
702 mTapDetector = TapGestureDetector::New();
704 for(unsigned int i = 0u; i < mItemView.GetChildCount(); ++i)
706 mTapDetector.Attach(mItemView.GetChildAt(i));
709 mTapDetector.DetectedSignal().Connect(this, &ItemViewExample::ReplaceOnTap);
712 void ReplaceOnTap(Actor actor, const TapGesture& tap)
714 mItemView.ReplaceItem(Item(mItemView.GetItemId(actor), NewItem(rand())), 0.5f);
717 void ExitReplaceMode()
719 mTapDetector.Reset();
722 void EnterReplaceManyMode()
724 SetTitle("Edit: Replace Many");
726 mReplaceButton.SetProperty(Actor::Property::VISIBLE, true);
728 mTapDetector = TapGestureDetector::New();
730 for(unsigned int i = 0u; i < mItemView.GetChildCount(); ++i)
732 Actor child = mItemView.GetChildAt(i);
733 Actor box = child.FindChildByName("CheckBox");
737 mTapDetector.Attach(child);
738 box.SetProperty(Actor::Property::VISIBLE, true);
742 mTapDetector.DetectedSignal().Connect(this, &ItemViewExample::SelectOnTap);
745 void ExitReplaceManyMode()
747 for(unsigned int i = 0u; i < mItemView.GetChildCount(); ++i)
749 Actor child = mItemView.GetChildAt(i);
750 Actor box = child.FindChildByName("CheckBox");
754 box.SetProperty(Actor::Property::VISIBLE, false);
756 Actor tick = box.FindChildByName("Tick");
759 tick.SetProperty(Actor::Property::VISIBLE, false);
764 mTapDetector.Reset();
766 mReplaceButton.SetProperty(Actor::Property::VISIBLE, false);
769 bool OnReplaceButtonClicked(Toolkit::Button button)
771 ItemContainer replaceList;
773 for(unsigned int i = 0u; i < mItemView.GetChildCount(); ++i)
775 Actor child = mItemView.GetChildAt(i);
776 Actor tick = child.FindChildByName("Tick");
778 if(tick && tick.GetCurrentProperty<bool>(Actor::Property::VISIBLE))
780 replaceList.push_back(Item(mItemView.GetItemId(child), NewItem(rand())));
784 if(!replaceList.empty())
786 mItemView.ReplaceItems(replaceList, 0.5f);
792 void SetLayoutTitle()
794 if(MODE_NORMAL == mMode)
796 std::stringstream ss(APPLICATION_TITLE);
797 switch(mCurrentLayout)
800 ss << APPLICATION_TITLE << ": " << SPIRAL_LABEL;
803 ss << APPLICATION_TITLE << ": " << GRID_LABEL;
806 ss << APPLICATION_TITLE << ": " << DEPTH_LABEL;
815 void SetLayoutImage()
819 switch(mCurrentLayout)
823 mLayoutButton.SetProperty(Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL, SPIRAL_LAYOUT_IMAGE);
824 mLayoutButton.SetProperty(Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL, SPIRAL_LAYOUT_IMAGE_SELECTED);
830 mLayoutButton.SetProperty(Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL, GRID_LAYOUT_IMAGE);
831 mLayoutButton.SetProperty(Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL, GRID_LAYOUT_IMAGE_SELECTED);
837 mLayoutButton.SetProperty(Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL, DEPTH_LAYOUT_IMAGE);
838 mLayoutButton.SetProperty(Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL, DEPTH_LAYOUT_IMAGE_SELECTED);
848 public: // From ItemFactory
850 * Query the number of items available from the factory.
851 * The maximum available item has an ID of GetNumberOfItems() - 1.
853 virtual unsigned int GetNumberOfItems()
855 return NUM_IMAGES * 10;
859 * Create an Actor to represent a visible item.
861 * @return the created actor.
863 virtual Actor NewItem(unsigned int itemId)
865 // Create an image view for this item
866 Property::Map propertyMap;
867 propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE);
868 propertyMap.Insert(ImageVisual::Property::URL, IMAGE_PATHS[itemId % NUM_IMAGES]);
869 propertyMap.Insert(DevelVisual::Property::VISUAL_FITTING_MODE, DevelVisual::FILL);
870 ImageView actor = ImageView::New();
871 actor.SetProperty(Toolkit::ImageView::Property::IMAGE, propertyMap);
872 actor.SetProperty(Actor::Property::POSITION_Z, 0.0f);
873 actor.SetProperty(Actor::Property::POSITION, INITIAL_OFFSCREEN_POSITION);
875 // Add a border image child actor
876 ImageView borderActor = ImageView::New();
877 borderActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
878 borderActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
879 borderActor.SetResizePolicy(ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS);
880 borderActor.SetProperty(Actor::Property::SIZE_MODE_FACTOR, Vector3(2.0f * ITEM_BORDER_SIZE, 2.0f * ITEM_BORDER_SIZE, 0.0f));
881 borderActor.SetProperty(Actor::Property::COLOR_MODE, USE_PARENT_COLOR);
883 Property::Map borderProperty;
884 borderProperty.Insert(Toolkit::Visual::Property::TYPE, Visual::BORDER);
885 borderProperty.Insert(BorderVisual::Property::COLOR, Color::WHITE);
886 borderProperty.Insert(BorderVisual::Property::SIZE, ITEM_BORDER_SIZE);
887 borderProperty.Insert(BorderVisual::Property::ANTI_ALIASING, true);
888 borderActor.SetProperty(ImageView::Property::IMAGE, borderProperty);
890 actor.Add(borderActor);
892 actor.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
894 Vector3 spiralItemSize;
895 Vector2 windowSize = mApplication.GetWindow().GetSize();
896 static_cast<ItemLayout&>(*mSpiralLayout).GetItemSize(0u, Vector3(windowSize), spiralItemSize);
898 // Add a checkbox child actor; invisible until edit-mode is enabled
899 ImageView checkbox = ImageView::New();
900 checkbox.SetProperty(Dali::Actor::Property::NAME, "CheckBox");
901 checkbox.SetProperty(Actor::Property::COLOR_MODE, USE_PARENT_COLOR);
902 checkbox.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_RIGHT);
903 checkbox.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_RIGHT);
904 checkbox.SetProperty(Actor::Property::SIZE, Vector2(spiralItemSize.width * 0.2f, spiralItemSize.width * 0.2f));
905 checkbox.SetProperty(Actor::Property::POSITION, Vector2(-SELECTION_BORDER_WIDTH, SELECTION_BORDER_WIDTH));
906 checkbox.SetProperty(Actor::Property::POSITION_Z, 0.1f);
908 Property::Map solidColorProperty;
909 solidColorProperty.Insert(Toolkit::Visual::Property::TYPE, Visual::COLOR);
910 solidColorProperty.Insert(ColorVisual::Property::MIX_COLOR, Vector4(0.f, 0.f, 0.f, 0.6f));
911 checkbox.SetProperty(ImageView::Property::IMAGE, solidColorProperty);
913 if(MODE_REMOVE_MANY != mMode &&
914 MODE_INSERT_MANY != mMode &&
915 MODE_REPLACE_MANY != mMode)
917 checkbox.SetProperty(Actor::Property::VISIBLE, false);
919 borderActor.Add(checkbox);
921 ImageView tick = ImageView::New(SELECTED_IMAGE);
922 tick.SetProperty(Dali::Actor::Property::NAME, "Tick");
923 tick.SetProperty(Actor::Property::COLOR_MODE, USE_PARENT_COLOR);
924 tick.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_RIGHT);
925 tick.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_RIGHT);
926 tick.SetProperty(Actor::Property::SIZE, Vector2(spiralItemSize.width * 0.2f, spiralItemSize.width * 0.2f));
927 tick.SetProperty(Actor::Property::POSITION_Z, 0.2f);
928 tick.SetProperty(Actor::Property::VISIBLE, false);
931 // Connect new items for various editing modes
934 mTapDetector.Attach(actor);
942 * Sets/Updates the title of the View
943 * @param[in] title The new title for the view.
945 void SetTitle(const std::string& title)
949 mTitleActor = DemoHelper::CreateToolBarLabel("");
950 // Add title to the tool bar.
951 mToolBar.AddControl(mTitleActor, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarTitlePercentage, Alignment::HORIZONTAL_CENTER);
954 mTitleActor.SetProperty(TextLabel::Property::TEXT, title);
958 * Main key event handler
960 void OnKeyEvent(const KeyEvent& event)
962 if(event.GetState() == KeyEvent::DOWN)
964 if(IsKey(event, DALI_KEY_ESCAPE) || IsKey(event, DALI_KEY_BACK))
972 Application& mApplication;
975 Toolkit::Control mView;
976 unsigned int mOrientation;
978 Toolkit::ToolBar mToolBar;
979 TextLabel mTitleActor; ///< The Toolbar's Title.
982 unsigned int mCurrentLayout;
983 float mDurationSeconds;
985 ItemLayoutPtr mSpiralLayout;
986 ItemLayoutPtr mDepthLayout;
987 ItemLayoutPtr mGridLayout;
989 TapGestureDetector mTapDetector;
990 Toolkit::PushButton mLayoutButton;
991 Toolkit::PushButton mDeleteButton;
992 Toolkit::PushButton mInsertButton;
993 Toolkit::PushButton mReplaceButton;
995 LongPressGestureDetector mLongPressDetector;
998 int DALI_EXPORT_API main(int argc, char** argv)
1000 Application app = Application::New(&argc, &argv, DEMO_THEME_PATH);
1001 ItemViewExample test(app);