Updated demos to use DALi clang-format
[platform/core/uifw/dali-demo.git] / examples / styling / styling-application.cpp
1 /*
2  * Copyright (c) 2020 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  * @file style-example.cpp
19  * @brief Example of styling Toolkit controls.
20  */
21
22 // Class include
23 #include "styling-application.h"
24
25 // External includes
26 #include <dali-toolkit/dali-toolkit.h>
27 #include <dali-toolkit/devel-api/controls/popup/popup.h>
28 #include <dali-toolkit/devel-api/controls/table-view/table-view.h>
29 #include <dali/devel-api/actors/actor-devel.h>
30 #include <cstdio>
31 #include <sstream>
32 #include "image-channel-control.h"
33
34 // Internal includes
35
36 using namespace Dali;
37 using namespace Dali::Toolkit;
38
39 namespace Demo
40 {
41 const char* StylingApplication::DEMO_THEME_ONE_PATH(DEMO_STYLE_DIR "style-example-theme-one.json");
42 const char* StylingApplication::DEMO_THEME_TWO_PATH(DEMO_STYLE_DIR "style-example-theme-two.json");
43 const char* StylingApplication::DEMO_THEME_THREE_PATH(DEMO_STYLE_DIR "style-example-theme-three.json");
44
45 namespace
46 {
47 #define DP(x) x
48
49 const char* DEFAULT_CONTROL_AREA_IMAGE_PATH(DEMO_IMAGE_DIR "popup_button_background.9.png");
50
51 const char* POPUP_CONTROL_OK_NAME("PopupControlOk");
52 const char* POPUP_CONTROL_CANCEL_NAME("PopupControlCancel");
53 const char* BORDER_IMAGE(DEMO_IMAGE_DIR "border-4px.9.png");
54 const char* RESIZE_HANDLE_IMAGE(DEMO_IMAGE_DIR "resize-handle.png");
55
56 const int NUMBER_OF_THEMES(3); // The default theme is considered.
57
58 const Vector4 BACKGROUND_COLOUR(1.0f, 1.0f, 1.0f, 0.15f);
59 const int     BORDER_WIDTH(4);
60
61 const char* const SMALL_IMAGE_1 = DEMO_IMAGE_DIR "gallery-small-14.jpg";
62 const char* const BIG_IMAGE_1   = DEMO_IMAGE_DIR "gallery-large-4.jpg";
63
64 const char* const SMALL_IMAGE_2 = DEMO_IMAGE_DIR "gallery-small-39.jpg";
65 const char* const BIG_IMAGE_2   = DEMO_IMAGE_DIR "gallery-large-7.jpg";
66
67 const char* const SMALL_IMAGE_3 = DEMO_IMAGE_DIR "gallery-small-20.jpg";
68 const char* const BIG_IMAGE_3   = DEMO_IMAGE_DIR "gallery-large-11.jpg";
69
70 // Layout
71 const int MARGIN_SIZE = 10;
72
73 const int RADIO_LABEL_THUMBNAIL_SIZE       = 60;
74 const int RADIO_LABEL_THUMBNAIL_SIZE_SMALL = 40;
75 const int RADIO_IMAGE_SPACING              = 8;
76 const int BUTTON_HEIGHT                    = 48;
77
78 Property::Index GetChannelProperty(int index)
79 {
80   Property::Index channelIndex = Property::INVALID_INDEX;
81   switch(index)
82   {
83     case 0:
84     {
85       channelIndex = ImageChannelControl::Property::RED_CHANNEL;
86       break;
87     }
88     case 1:
89     {
90       channelIndex = ImageChannelControl::Property::GREEN_CHANNEL;
91       break;
92     }
93     case 2:
94     {
95       channelIndex = ImageChannelControl::Property::BLUE_CHANNEL;
96       break;
97     }
98   }
99   return channelIndex;
100 }
101
102 } // anonymous namespace
103
104 StylingApplication::StylingApplication(Application& application)
105 : mApplication(application),
106   mCurrentTheme(0)
107 {
108   application.InitSignal().Connect(this, &StylingApplication::Create);
109 }
110
111 StylingApplication::~StylingApplication()
112 {
113 }
114
115 void StylingApplication::Create(Application& application)
116 {
117   Window window = application.GetWindow();
118   window.KeyEventSignal().Connect(this, &StylingApplication::OnKeyEvent);
119   window.SetBackgroundColor(Vector4(0.1f, 0.1f, 0.1f, 1.0f));
120
121   mContentPane = CreateContentPane();
122   window.Add(mContentPane);
123   mContentPane.SetProperty(Actor::Property::SIZE, Vector2(window.GetSize()));
124
125   // Content panes:
126   TableView contentLayout = TableView::New(5, 1);
127   contentLayout.SetProperty(Dali::Actor::Property::NAME, "ContentLayout");
128   contentLayout.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
129   contentLayout.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
130   contentLayout.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
131   contentLayout.SetCellPadding(Size(MARGIN_SIZE, MARGIN_SIZE));
132
133   // Assign all rows the size negotiation property of fitting to children
134   for(unsigned int i = 0; i < contentLayout.GetRows(); ++i)
135   {
136     if(i != 1)
137     {
138       contentLayout.SetFitHeight(i); // Row 1 should fill
139     }
140   }
141
142   mContentPane.Add(contentLayout);
143
144   mTitle = TextLabel::New("Styling Example");
145   mTitle.SetProperty(Dali::Actor::Property::NAME, "Title");
146   mTitle.SetStyleName("Title");
147   mTitle.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
148   mTitle.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
149   mTitle.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
150   mTitle.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT);
151   mTitle.SetProperty(TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER");
152   contentLayout.Add(mTitle);
153
154   // Buttons:
155
156   TableView imageSelectLayout = TableView::New(1, 2);
157   imageSelectLayout.SetProperty(Dali::Actor::Property::NAME, "ImageSelectLayout");
158
159   imageSelectLayout.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
160   imageSelectLayout.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT);
161   imageSelectLayout.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
162   imageSelectLayout.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
163   imageSelectLayout.SetCellPadding(Size(MARGIN_SIZE, MARGIN_SIZE));
164
165   // Fit radio button column to child width, leave image to fill remainder
166   imageSelectLayout.SetFitWidth(0);
167
168   contentLayout.Add(imageSelectLayout);
169
170   TableView radioButtonsLayout = TableView::New(3, 2);
171   radioButtonsLayout.SetProperty(Dali::Actor::Property::NAME, "RadioButtonsLayout");
172   radioButtonsLayout.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT);
173   // Leave each row to fill to parent height
174   // Set each column to fit to child width
175   radioButtonsLayout.SetFitWidth(0);
176   radioButtonsLayout.SetFitWidth(1);
177   radioButtonsLayout.SetCellPadding(Vector2(6.0f, 0.0f));
178
179   imageSelectLayout.AddChild(radioButtonsLayout, TableView::CellPosition(0, 0));
180   imageSelectLayout.SetCellAlignment(TableView::CellPosition(0, 0), HorizontalAlignment::LEFT, VerticalAlignment::CENTER);
181
182   const char* images[] = {SMALL_IMAGE_1, SMALL_IMAGE_2, SMALL_IMAGE_3};
183
184   for(int i = 0; i < 3; ++i)
185   {
186     std::ostringstream thumbnailName;
187     thumbnailName << "thumbnail" << i + 1;
188     ImageView image = ImageView::New(images[i]);
189     image.SetProperty(Dali::Actor::Property::NAME, thumbnailName.str());
190     image.SetProperty(Actor::Property::SIZE, Vector2(DP(RADIO_LABEL_THUMBNAIL_SIZE), DP(RADIO_LABEL_THUMBNAIL_SIZE)));
191
192     std::ostringstream label;
193     label << (i + 1);
194     std::ostringstream radioButtonStyleName;
195     radioButtonStyleName << "imageSelectButton" << i + 1;
196     mRadioButtons[i] = RadioButton::New(label.str());
197     mRadioButtons[i].SetProperty(Dali::Actor::Property::NAME, radioButtonStyleName.str());
198     mRadioButtons[i].SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
199     mRadioButtons[i].SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
200     mRadioButtons[i].SetProperty(Button::Property::SELECTED, false);
201     mRadioButtons[i].StateChangedSignal().Connect(this, &StylingApplication::OnButtonStateChange);
202
203     radioButtonsLayout.AddChild(mRadioButtons[i], TableView::CellPosition(i, 0));
204     radioButtonsLayout.AddChild(image, TableView::CellPosition(i, 1));
205     radioButtonsLayout.SetCellAlignment(TableView::CellPosition(i, 0), HorizontalAlignment::CENTER, VerticalAlignment::CENTER);
206     radioButtonsLayout.SetCellAlignment(TableView::CellPosition(i, 1), HorizontalAlignment::CENTER, VerticalAlignment::CENTER);
207   }
208
209   mRadioButtons[0].SetProperty(Button::Property::SELECTED, true);
210
211   mImagePlacement = Actor::New();
212   mImagePlacement.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
213   mImagePlacement.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
214   mImagePlacement.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
215   imageSelectLayout.AddChild(mImagePlacement, TableView::CellPosition(0, 1));
216   imageSelectLayout.SetCellAlignment(TableView::CellPosition(0, 1), HorizontalAlignment::RIGHT, VerticalAlignment::CENTER);
217
218   mIcc1 = ImageChannelControl::New(BIG_IMAGE_1);
219   mIcc1.SetProperty(Dali::Actor::Property::NAME, "ICC1");
220   mIcc1.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
221   mIcc1.SetProperty(Actor::Property::SIZE_SCALE_POLICY, SizeScalePolicy::FIT_WITH_ASPECT_RATIO);
222   mIcc1.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
223   mIcc1.SetVisibility(true);
224
225   mImagePlacement.Add(mIcc1);
226
227   mIcc2 = ImageChannelControl::New(BIG_IMAGE_2);
228   mIcc2.SetProperty(Dali::Actor::Property::NAME, "ICC2");
229   mIcc2.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
230   mIcc2.SetProperty(Actor::Property::SIZE_SCALE_POLICY, SizeScalePolicy::FIT_WITH_ASPECT_RATIO);
231   mIcc2.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
232   mIcc2.SetVisibility(false);
233
234   mImagePlacement.Add(mIcc2);
235
236   mIcc3 = ImageChannelControl::New(BIG_IMAGE_3);
237   mIcc3.SetProperty(Dali::Actor::Property::NAME, "ICC3");
238   mIcc3.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
239   mIcc3.SetProperty(Actor::Property::SIZE_SCALE_POLICY, SizeScalePolicy::FIT_WITH_ASPECT_RATIO);
240   mIcc3.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
241   mIcc3.SetVisibility(false);
242
243   mImagePlacement.Add(mIcc3);
244
245   mImageChannelControl = mIcc1;
246
247   TableView channelSliderLayout = TableView::New(3, 3);
248   channelSliderLayout.SetProperty(Dali::Actor::Property::NAME, "ChannelSliderLayout");
249
250   // Contains a column of check buttons and a column of sliders for R/G/B
251   channelSliderLayout.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
252   channelSliderLayout.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT);
253   channelSliderLayout.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
254   channelSliderLayout.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
255   channelSliderLayout.SetCellPadding(Size(MARGIN_SIZE, MARGIN_SIZE));
256
257   // Set each row to fit to child height
258   channelSliderLayout.SetFitHeight(0);
259   channelSliderLayout.SetFitHeight(1);
260   channelSliderLayout.SetFitHeight(2);
261
262   // Set each column to fit to child width
263   channelSliderLayout.SetFitWidth(0);
264   channelSliderLayout.SetFitWidth(1);
265
266   contentLayout.Add(channelSliderLayout);
267   const char* checkboxLabels[3] = {"R", "G", "B"};
268
269   for(int i = 0; i < 3; ++i)
270   {
271     std::ostringstream checkBoxStyleName;
272     checkBoxStyleName << "channelActiveCheckBox" << i + 1;
273     mCheckButtons[i] = CheckBoxButton::New();
274     mCheckButtons[i].SetProperty(Dali::Actor::Property::NAME, checkBoxStyleName.str());
275     mCheckButtons[i].SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
276     mCheckButtons[i].SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
277     mCheckButtons[i].SetProperty(Button::Property::SELECTED, true);
278
279     mCheckButtons[i].StateChangedSignal().Connect(this, &StylingApplication::OnCheckButtonChange);
280     mCheckButtons[i].RegisterProperty("channel", i, Property::READ_WRITE);
281
282     channelSliderLayout.AddChild(mCheckButtons[i], TableView::CellPosition(i, 0));
283     channelSliderLayout.SetCellAlignment(TableView::CellPosition(i, 0), HorizontalAlignment::CENTER, VerticalAlignment::CENTER);
284
285     TextLabel          label = TextLabel::New(checkboxLabels[i]);
286     std::ostringstream labelStyleName;
287     labelStyleName << "ColorLabel" << i + 1;
288     label.SetProperty(Dali::Actor::Property::NAME, labelStyleName.str());
289     label.SetStyleName(labelStyleName.str());
290     label.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
291     label.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
292     label.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::WIDTH);
293     label.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT);
294
295     channelSliderLayout.AddChild(label, TableView::CellPosition(i, 1));
296     channelSliderLayout.SetCellAlignment(TableView::CellPosition(i, 1), HorizontalAlignment::CENTER, VerticalAlignment::CENTER);
297
298     mChannelSliders[i] = Slider::New();
299     std::ostringstream sliderStyleName;
300     sliderStyleName << "ColorSlider" << i + 1;
301     mChannelSliders[i].SetProperty(Dali::Actor::Property::NAME, sliderStyleName.str());
302     mChannelSliders[i].SetStyleName(sliderStyleName.str());
303     mChannelSliders[i].SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
304     mChannelSliders[i].SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
305     mChannelSliders[i].SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
306     mChannelSliders[i].SetResizePolicy(ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT);
307     mChannelSliders[i].SetProperty(Slider::Property::LOWER_BOUND, 0.0f);
308     mChannelSliders[i].SetProperty(Slider::Property::UPPER_BOUND, 100.0f);
309     mChannelSliders[i].SetProperty(Slider::Property::VALUE_PRECISION, 0);
310     mChannelSliders[i].SetProperty(Slider::Property::VALUE, 100.0f);
311     mChannelSliders[i].SetProperty(Slider::Property::SHOW_POPUP, true);
312     mChannelSliders[i].SetProperty(Slider::Property::SHOW_VALUE, true);
313
314     mChannelSliders[i].RegisterProperty("channel", i, Property::READ_WRITE);
315
316     channelSliderLayout.AddChild(mChannelSliders[i], TableView::CellPosition(i, 2));
317     channelSliderLayout.SetCellAlignment(TableView::CellPosition(i, 2), HorizontalAlignment::RIGHT, VerticalAlignment::CENTER);
318
319     mChannelSliders[i].ValueChangedSignal().Connect(this, &StylingApplication::OnSliderChanged);
320   }
321
322   mResetButton = PushButton::New();
323   mResetButton.SetProperty(Toolkit::Button::Property::LABEL, "Reset");
324   mResetButton.SetProperty(Dali::Actor::Property::NAME, "ResetButton");
325   mResetButton.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
326   mResetButton.ClickedSignal().Connect(this, &StylingApplication::OnResetClicked);
327
328   contentLayout.Add(mResetButton);
329   contentLayout.SetCellAlignment(TableView::CellPosition(3, 0), HorizontalAlignment::CENTER, VerticalAlignment::CENTER);
330
331   TableView themeButtonLayout = TableView::New(1, 4);
332   themeButtonLayout.SetProperty(Dali::Actor::Property::NAME, "ThemeButtonsLayout");
333   themeButtonLayout.SetCellPadding(Vector2(6.0f, 0.0f));
334
335   themeButtonLayout.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
336   themeButtonLayout.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
337   themeButtonLayout.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
338   themeButtonLayout.SetResizePolicy(ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT);
339   themeButtonLayout.SetCellPadding(Size(MARGIN_SIZE, MARGIN_SIZE));
340   themeButtonLayout.SetFitHeight(0);
341
342   TextLabel label = TextLabel::New("Theme: ");
343   label.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
344   label.SetStyleName("ThemeLabel");
345   label.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
346   label.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
347   themeButtonLayout.AddChild(label, TableView::CellPosition(0, 0));
348   themeButtonLayout.SetCellAlignment(TableView::CellPosition(0, 0), HorizontalAlignment::LEFT, VerticalAlignment::CENTER);
349
350   for(int i = 0; i < 3; ++i)
351   {
352     mThemeButtons[i] = PushButton::New();
353     mThemeButtons[i].SetProperty(Dali::Actor::Property::NAME, "ThemeButton");
354     mThemeButtons[i].SetStyleName("ThemeButton");
355     mThemeButtons[i].SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
356     mThemeButtons[i].SetProperty(Actor::Property::ANCHOR_POINT, ParentOrigin::CENTER);
357     mThemeButtons[i].SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
358     mThemeButtons[i].SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT);
359     mThemeButtons[i].RegisterProperty("theme", i, Property::READ_WRITE);
360     mThemeButtons[i].ClickedSignal().Connect(this, &StylingApplication::OnThemeButtonClicked);
361     themeButtonLayout.AddChild(mThemeButtons[i], TableView::CellPosition(0, 1 + i));
362   }
363   mThemeButtons[0].SetProperty(Toolkit::Button::Property::LABEL, "Lite"); // Lightweight changes on top of Dali
364   mThemeButtons[1].SetProperty(Toolkit::Button::Property::LABEL, "App1"); // Different application style
365   mThemeButtons[2].SetProperty(Toolkit::Button::Property::LABEL, "App2");
366
367   contentLayout.Add(themeButtonLayout);
368 }
369
370 Actor StylingApplication::CreateContentPane()
371 {
372   Toolkit::ImageView contentPane = Toolkit::ImageView::New(BORDER_IMAGE);
373   contentPane.SetProperty(Dali::Actor::Property::NAME, "ContentPane");
374   contentPane.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
375   contentPane.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
376   contentPane.SetProperty(Actor::Property::PADDING, Padding(BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH));
377   return contentPane;
378 }
379
380 Actor StylingApplication::CreateResizableContentPane()
381 {
382   Toolkit::ImageView contentPane = Toolkit::ImageView::New(BORDER_IMAGE);
383   contentPane.SetProperty(Dali::Actor::Property::NAME, "ContentPane");
384   contentPane.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
385   contentPane.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
386   contentPane.SetProperty(Actor::Property::PADDING, Padding(BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH));
387
388   Toolkit::ImageView grabHandle = Toolkit::ImageView::New(RESIZE_HANDLE_IMAGE);
389   grabHandle.SetProperty(Dali::Actor::Property::NAME, "GrabHandle");
390   grabHandle.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
391   grabHandle.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_RIGHT);
392   grabHandle.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_RIGHT);
393   grabHandle.SetProperty(Actor::Property::POSITION, Vector2(-BORDER_WIDTH, -BORDER_WIDTH));
394   grabHandle.SetProperty(Actor::Property::OPACITY, 0.6f);
395
396   Layer grabCornerLayer = Layer::New();
397   grabCornerLayer.SetProperty(Dali::Actor::Property::NAME, "GrabCornerLayer");
398   grabCornerLayer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_RIGHT);
399   grabCornerLayer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_RIGHT);
400   grabCornerLayer.Add(grabHandle);
401   contentPane.Add(grabCornerLayer);
402
403   mPanGestureDetector = PanGestureDetector::New();
404   mPanGestureDetector.Attach(grabHandle);
405   mPanGestureDetector.DetectedSignal().Connect(this, &StylingApplication::OnPan);
406
407   return contentPane;
408 }
409
410 Popup StylingApplication::CreateResetPopup()
411 {
412   Window window = mApplication.GetWindow();
413
414   Popup popup = Popup::New();
415   popup.SetProperty(Dali::Actor::Property::NAME, "ResetPopup");
416   popup.SetStyleName("ResetPopup");
417   popup.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
418   popup.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
419   popup.SetProperty(Actor::Property::SIZE, Vector2(window.GetSize().GetWidth() * 0.75f, 0.0f));
420   popup.SetProperty(Popup::Property::TAIL_VISIBILITY, false);
421   popup.OutsideTouchedSignal().Connect(this, &StylingApplication::HidePopup);
422   popup.HiddenSignal().Connect(this, &StylingApplication::PopupHidden);
423
424   popup.SetTitle(CreateTitle("Reset channels"));
425
426   TextLabel text = TextLabel::New("This will reset the channel data to full value. Are you sure?");
427   text.SetProperty(Dali::Actor::Property::NAME, "PopupContentText");
428   text.SetStyleName("PopupBody");
429   text.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
430   text.SetResizePolicy(ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT);
431   text.SetProperty(TextLabel::Property::MULTI_LINE, true);
432   text.SetProperty(Actor::Property::PADDING, Padding(10.0f, 10.0f, 20.0f, 0.0f));
433   popup.SetContent(text);
434
435   ImageView footer = ImageView::New(DEFAULT_CONTROL_AREA_IMAGE_PATH);
436   footer.SetProperty(Dali::Actor::Property::NAME, "PopupFooter");
437   footer.SetStyleName("PopupFooter");
438   footer.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
439   footer.SetResizePolicy(ResizePolicy::FIXED, Dimension::HEIGHT);
440   footer.SetProperty(Actor::Property::SIZE, Vector2(0.0f, 80.0f));
441   footer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
442   footer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
443
444   TableView footerLayout = TableView::New(1, 2);
445   footerLayout.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
446   footerLayout.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
447   footerLayout.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
448
449   PushButton okayButton = PushButton::New();
450   okayButton.SetProperty(Dali::Actor::Property::NAME, POPUP_CONTROL_OK_NAME);
451   okayButton.SetStyleName(POPUP_CONTROL_OK_NAME);
452   okayButton.SetProperty(Toolkit::Button::Property::LABEL, "Ok!");
453   okayButton.ClickedSignal().Connect(this, &StylingApplication::OnReset);
454   okayButton.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
455   okayButton.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
456   okayButton.SetResizePolicy(ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS);
457   okayButton.SetProperty(Actor::Property::SIZE_MODE_FACTOR, Vector3(-20.0f, -20.0f, 0.0f));
458
459   PushButton cancelButton = PushButton::New();
460   cancelButton.SetProperty(Dali::Actor::Property::NAME, POPUP_CONTROL_CANCEL_NAME);
461   cancelButton.SetStyleName(POPUP_CONTROL_CANCEL_NAME);
462   cancelButton.SetProperty(Toolkit::Button::Property::LABEL, "Cancel");
463   cancelButton.ClickedSignal().Connect(this, &StylingApplication::OnResetCancelled);
464   cancelButton.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
465   cancelButton.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
466   cancelButton.SetResizePolicy(ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS);
467   cancelButton.SetProperty(Actor::Property::SIZE_MODE_FACTOR, Vector3(-20.0f, -20.0f, 0.0f));
468
469   footerLayout.SetCellAlignment(TableView::CellPosition(0, 0), HorizontalAlignment::CENTER, VerticalAlignment::CENTER);
470   footerLayout.SetCellAlignment(TableView::CellPosition(0, 1), HorizontalAlignment::CENTER, VerticalAlignment::CENTER);
471   footerLayout.AddChild(okayButton, TableView::CellPosition(0, 0));
472   footerLayout.AddChild(cancelButton, TableView::CellPosition(0, 1));
473   footerLayout.SetCellPadding(Size(10.f, 10.f));
474   footer.Add(footerLayout);
475
476   popup.SetFooter(footer);
477   return popup;
478 }
479
480 TextLabel StylingApplication::CreateTitle(std::string title)
481 {
482   TextLabel titleActor = TextLabel::New(title);
483   titleActor.SetProperty(Dali::Actor::Property::NAME, "titleActor");
484   titleActor.SetStyleName("PopupTitle");
485   titleActor.SetProperty(TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER");
486   titleActor.SetProperty(TextLabel::Property::MULTI_LINE, false);
487
488   return titleActor;
489 }
490
491 bool StylingApplication::OnButtonStateChange(Button button)
492 {
493   // On button press, called twice, once to tell new button it's selected,
494   // once to tell old button it isn't selected?
495
496   // Todo: save / restore slider states per image
497
498   if(button.GetProperty<bool>(Button::Property::SELECTED))
499   {
500     ImageChannelControl prevIcc = mImageChannelControl;
501
502     if(mRadioButtons[0].GetProperty<bool>(Button::Property::SELECTED))
503     {
504       mImageChannelControl = mIcc1;
505     }
506     else if(mRadioButtons[1].GetProperty<bool>(Button::Property::SELECTED))
507     {
508       mImageChannelControl = mIcc2;
509     }
510     else if(mRadioButtons[2].GetProperty<bool>(Button::Property::SELECTED))
511     {
512       mImageChannelControl = mIcc3;
513     }
514
515     if(prevIcc)
516     {
517       prevIcc.SetVisibility(false);
518     }
519
520     if(mImageChannelControl)
521     {
522       mImageChannelControl.SetVisibility(true);
523     }
524   }
525
526   return true;
527 }
528
529 bool StylingApplication::OnCheckButtonChange(Button button)
530 {
531   Property::Index index = button.GetPropertyIndex("channel");
532   if(index != Property::INVALID_INDEX)
533   {
534     int   channel = button["channel"];
535     float value   = mChannelSliders[channel][Slider::Property::VALUE];
536     if(!button[Button::Property::SELECTED])
537     {
538       // "Turn off" the channel's contribution
539       value = 0.0f;
540     }
541     Property::Index channelIndex = GetChannelProperty(channel);
542     mImageChannelControl.SetProperty(channelIndex, value / 100.0f);
543   }
544   return true;
545 }
546
547 bool StylingApplication::OnThemeButtonClicked(Button button)
548 {
549   int         theme     = button.GetProperty<int>(button.GetPropertyIndex("theme"));
550   const char* themePath = NULL;
551
552   switch(theme)
553   {
554     case 0:
555     {
556       themePath = DEMO_THEME_ONE_PATH;
557       break;
558     }
559     case 1:
560     {
561       themePath = DEMO_THEME_TWO_PATH;
562       break;
563     }
564     case 2:
565     {
566       themePath = DEMO_THEME_THREE_PATH;
567       break;
568     }
569   }
570
571   StyleManager::Get().ApplyTheme(themePath);
572
573   return true;
574 }
575
576 bool StylingApplication::OnResetClicked(Button button)
577 {
578   if(!mResetPopup)
579   {
580     mResetPopup = CreateResetPopup();
581   }
582
583   mApplication.GetWindow().Add(mResetPopup);
584
585   mResetPopup.SetDisplayState(Popup::SHOWN);
586   return true;
587 }
588
589 bool StylingApplication::OnReset(Button button)
590 {
591   // todo: Reset the sliders for this image
592   for(int i = 0; i < 3; ++i)
593   {
594     mChannelSliders[i].SetProperty(Slider::Property::VALUE, 100.0f);
595   }
596   HidePopup();
597   return true;
598 }
599
600 bool StylingApplication::OnResetCancelled(Button button)
601 {
602   HidePopup();
603   return true;
604 }
605
606 bool StylingApplication::OnSliderChanged(Slider slider, float value)
607 {
608   // todo - change color channel's saturation
609   Property::Index index = slider.GetPropertyIndex("channel");
610   if(index != Property::INVALID_INDEX)
611   {
612     int channel = slider["channel"];
613     if(mCheckButtons[channel]["selected"])
614     {
615       Property::Index channelIndex = GetChannelProperty(channel);
616       mImageChannelControl.SetProperty(channelIndex, value / 100.0f);
617     }
618   }
619   return true;
620 }
621
622 void StylingApplication::HidePopup()
623 {
624   if(mResetPopup)
625   {
626     mResetPopup.SetDisplayState(Popup::HIDDEN);
627   }
628 }
629
630 void StylingApplication::PopupHidden()
631 {
632   if(mResetPopup)
633   {
634     // Clear down resources
635     mResetPopup.Unparent();
636     mResetPopup.Reset();
637   }
638 }
639
640 void StylingApplication::OnPan(Actor actor, const PanGesture& gesture)
641 {
642   Vector3 size = mContentPane.GetTargetSize();
643   mContentPane.SetProperty(Actor::Property::SIZE, Vector2(size.GetVectorXY() + gesture.GetDisplacement() * 2.0f));
644 }
645
646 void StylingApplication::OnKeyEvent(const KeyEvent& keyEvent)
647 {
648   static int keyPressed = 0;
649
650   if(keyEvent.GetState() == KeyEvent::DOWN)
651   {
652     if(keyPressed == 0) // Is this the first down event?
653     {
654       printf("Key pressed: %s %d\n", keyEvent.GetKeyName().c_str(), keyEvent.GetKeyCode());
655
656       if(IsKey(keyEvent, DALI_KEY_ESCAPE) || IsKey(keyEvent, DALI_KEY_BACK))
657       {
658         mApplication.Quit();
659       }
660       else if(keyEvent.GetKeyName().compare("Return") == 0)
661       {
662         mCurrentTheme++;
663         mCurrentTheme %= NUMBER_OF_THEMES;
664
665         StyleManager styleManager = StyleManager::Get();
666         switch(mCurrentTheme)
667         {
668           case 0:
669           {
670             styleManager.ApplyTheme(DEMO_THEME_ONE_PATH);
671             printf("Changing to theme One\n");
672             break;
673           }
674           case 1:
675           {
676             styleManager.ApplyTheme(DEMO_THEME_TWO_PATH);
677             printf("Changing to theme Two\n");
678             break;
679           }
680           case 2:
681           {
682             styleManager.ApplyDefaultTheme();
683             printf("Changing to Toolkit theme\n");
684             break;
685           }
686         }
687       }
688     }
689     keyPressed = 1;
690   }
691   else if(keyEvent.GetState() == KeyEvent::UP)
692   {
693     keyPressed = 0;
694   }
695 }
696
697 } // namespace Demo