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