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