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