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