Merge "Size negotiation patch 4: Remove SetRelayoutEnabled" into tizen
[platform/core/uifw/dali-demo.git] / examples / buttons / buttons-example.cpp
1 /*
2  * Copyright (c) 2014 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 #include "shared/view.h"
19 #include <dali/dali.h>
20 #include <dali-toolkit/dali-toolkit.h>
21
22 using namespace Dali;
23
24 // Define this so that it is interchangeable
25 // "DP" stands for Device independent Pixels
26 #define DP(x) x
27
28
29 namespace
30 {
31
32 const char* const BACKGROUND_IMAGE = DALI_IMAGE_DIR "background-gradient.jpg";
33 const char* const TOOLBAR_IMAGE = DALI_IMAGE_DIR "top-bar.png";
34
35 const char* const TOOLBAR_TITLE = "Buttons";
36
37 const char* const SMALL_IMAGE_1 = DALI_IMAGE_DIR "gallery-small-14.jpg";
38 const char* const BIG_IMAGE_1 = DALI_IMAGE_DIR "gallery-large-4.jpg";
39
40 const char* const SMALL_IMAGE_2 = DALI_IMAGE_DIR "gallery-small-20.jpg";
41 const char* const BIG_IMAGE_2 = DALI_IMAGE_DIR "gallery-large-11.jpg";
42
43 const char* const SMALL_IMAGE_3 = DALI_IMAGE_DIR "gallery-small-25.jpg";
44 const char* const BIG_IMAGE_3 = DALI_IMAGE_DIR "gallery-large-13.jpg";
45
46 const char* const ENABLED_IMAGE = DALI_IMAGE_DIR "item-select-check.png";
47
48 const char* const PUSHBUTTON_PRESS_IMAGE = DALI_IMAGE_DIR "button-down.9.png";
49 const char* const PUSHBUTTON_DISABLED_IMAGE = DALI_IMAGE_DIR "button-disabled.9.png";
50 const char* const PUSHBUTTON_BUTTON_IMAGE = DALI_IMAGE_DIR "button-up.9.png";
51
52 const char* const CHECKBOX_UNSELECTED_IMAGE = DALI_IMAGE_DIR "checkbox-unselected.png";
53 const char* const CHECKBOX_SELECTED_IMAGE = DALI_IMAGE_DIR "checkbox-selected.png";
54
55 const Vector4 BACKGROUND_COLOUR( 1.0f, 1.0f, 1.0f, 0.15f );
56
57 // Layout sizes
58 const int RADIO_LABEL_THUMBNAIL_SIZE = 60;
59 const int RADIO_IMAGE_SPACING = 8;
60 const int BUTTON_HEIGHT = 48;
61
62 const int MARGIN_SIZE = 10;
63 const int TOP_MARGIN = 85;
64 const int GROUP2_HEIGHT = 238;
65 const int GROUP1_HEIGHT = 120;
66 const int GROUP3_HEIGHT = 190;
67 const int GROUP4_HEIGHT = BUTTON_HEIGHT + MARGIN_SIZE * 2;
68
69 }  // namespace
70
71 /** This example shows how to create and use different buttons.
72  *
73  * 1. First group of radio buttons with image actor labels selects an image to load
74  * 2. A push button loads the selected thumbnail image into the larger image pane
75  * 3. Second group of radio buttons with a table view label containing a text view and image view, and a normal text view.
76  *    Selecting one of these will enable/disable the image loading push button
77  * 4. A group of check boxes
78  */
79 class ButtonsController: public ConnectionTracker
80 {
81  public:
82
83   ButtonsController( Application& application )
84     : mApplication( application )
85   {
86     // Connect to the Application's Init signal
87     mApplication.InitSignal().Connect( this, &ButtonsController::Create );
88   }
89
90   ~ButtonsController()
91   {
92     // Nothing to do here
93   }
94
95   void Create( Application& application )
96   {
97     // The Init signal is received once (only) during the Application lifetime
98
99     DemoHelper::RequestThemeChange();
100
101     // Respond to key events
102     Stage::GetCurrent().KeyEventSignal().Connect(this, &ButtonsController::OnKeyEvent);
103
104     // Creates a default view with a default tool bar.
105     // The view is added to the stage.
106     mContentLayer = DemoHelper::CreateView( application,
107                                             mView,
108                                             mToolBar,
109                                             BACKGROUND_IMAGE,
110                                             TOOLBAR_IMAGE,
111                                             TOOLBAR_TITLE );
112
113     Toolkit::TableView contentTable = Toolkit::TableView::New( 4, 1 );
114     contentTable.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
115     contentTable.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
116     contentTable.SetAnchorPoint( AnchorPoint::TOP_LEFT );
117     contentTable.SetParentOrigin( ParentOrigin::TOP_LEFT );
118     contentTable.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE * 0.5f ) );
119 //    contentTable.TouchedSignal().Connect( this, &ButtonsController::OnTouchEvent );
120
121     for( unsigned int i = 0; i < contentTable.GetRows(); ++i )
122     {
123       contentTable.SetFitHeight( i );
124     }
125
126     contentTable.SetPosition( 0.0f, TOP_MARGIN );
127
128     mContentLayer.Add( contentTable );
129
130     // Image selector radio group
131     Toolkit::TableView radioGroup2Background = Toolkit::TableView::New( 2, 2 );
132     radioGroup2Background.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
133     radioGroup2Background.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
134     radioGroup2Background.SetBackgroundColor( BACKGROUND_COLOUR );
135     radioGroup2Background.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE ) );
136     radioGroup2Background.SetFitHeight( 0 );
137     radioGroup2Background.SetFitHeight( 1 );
138     radioGroup2Background.SetFitWidth( 0 );
139
140     contentTable.Add( radioGroup2Background );
141
142     Toolkit::TableView radioButtonsGroup2 = Toolkit::TableView::New( 3, 1 );
143     radioButtonsGroup2.SetCellPadding( Size( 0.0f, MARGIN_SIZE * 0.5f ) );
144     radioButtonsGroup2.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
145     for( unsigned int i = 0; i < radioButtonsGroup2.GetRows(); ++i )
146     {
147       radioButtonsGroup2.SetFitHeight( i );
148     }
149     radioButtonsGroup2.SetFitWidth( 0 );
150
151     radioGroup2Background.AddChild( radioButtonsGroup2, Toolkit::TableView::CellPosition( 0, 0 ) );
152
153     int radioY = 0;
154
155     // Radio 1
156     {
157       ImageActor imageActor = ImageActor::New( ResourceImage::New( SMALL_IMAGE_1 ) );
158       imageActor.SetSize( DP(RADIO_LABEL_THUMBNAIL_SIZE), DP(RADIO_LABEL_THUMBNAIL_SIZE) );
159       mRadioButtonImage1 = Dali::Toolkit::RadioButton::New( imageActor );
160       mRadioButtonImage1.SetParentOrigin( ParentOrigin::TOP_LEFT );
161       mRadioButtonImage1.SetAnchorPoint( AnchorPoint::TOP_LEFT );
162       mRadioButtonImage1.SetPosition( 0, DP(radioY) );
163       mRadioButtonImage1.SetSelected( true );
164
165       radioButtonsGroup2.Add( mRadioButtonImage1 );
166     }
167
168     // Radio 2
169     {
170       radioY += RADIO_LABEL_THUMBNAIL_SIZE + RADIO_IMAGE_SPACING;
171
172       ImageActor imageActor = ImageActor::New( ResourceImage::New( SMALL_IMAGE_2 ) );
173       imageActor.SetSize( DP(RADIO_LABEL_THUMBNAIL_SIZE), DP(RADIO_LABEL_THUMBNAIL_SIZE) );
174
175       mRadioButtonImage2 = Dali::Toolkit::RadioButton::New( imageActor );
176       mRadioButtonImage2.SetParentOrigin( ParentOrigin::TOP_LEFT );
177       mRadioButtonImage2.SetAnchorPoint( AnchorPoint::TOP_LEFT );
178       mRadioButtonImage2.SetPosition( 0, DP(radioY) );
179
180       radioButtonsGroup2.Add( mRadioButtonImage2 );
181     }
182
183     // Radio 3
184     {
185       radioY += RADIO_LABEL_THUMBNAIL_SIZE + RADIO_IMAGE_SPACING;
186
187       ImageActor imageActor = ImageActor::New( ResourceImage::New( SMALL_IMAGE_3 ) );
188       imageActor.SetSize( DP(RADIO_LABEL_THUMBNAIL_SIZE), DP(RADIO_LABEL_THUMBNAIL_SIZE) );
189
190       mRadioButtonImage3 = Dali::Toolkit::RadioButton::New( imageActor );
191       mRadioButtonImage3.SetParentOrigin( ParentOrigin::TOP_LEFT );
192       mRadioButtonImage3.SetAnchorPoint( AnchorPoint::TOP_LEFT );
193       mRadioButtonImage3.SetPosition( 0, DP(radioY) );
194
195       radioButtonsGroup2.Add( mRadioButtonImage3 );
196     }
197
198     // Create select button
199     mUpdateButton = Toolkit::PushButton::New();
200     mUpdateButton.SetLabel( "Select" );
201     mUpdateButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
202
203     mUpdateButton.SetSelectedImage( Dali::ResourceImage::New( PUSHBUTTON_PRESS_IMAGE ) );
204     mUpdateButton.SetDisabledImage( Dali::ResourceImage::New( PUSHBUTTON_DISABLED_IMAGE ) );
205     mUpdateButton.SetButtonImage( Dali::ResourceImage::New( PUSHBUTTON_BUTTON_IMAGE ) );
206
207     mUpdateButton.ClickedSignal().Connect( this, &ButtonsController::OnButtonClicked );
208
209     radioGroup2Background.AddChild( mUpdateButton, Toolkit::TableView::CellPosition( 1, 0 ) );
210
211     // ImageActor to display selected image
212     mBigImage1 = ResourceImage::New( BIG_IMAGE_1 );
213     mBigImage2 = ResourceImage::New( BIG_IMAGE_2 );
214     mBigImage3 = ResourceImage::New( BIG_IMAGE_3 );
215
216     mImage = ImageActor::New( mBigImage1 );
217     mImage.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
218     mImage.SetSizeScalePolicy( SizeScalePolicy::FIT_WITH_ASPECT_RATIO );
219     radioGroup2Background.AddChild( mImage, Toolkit::TableView::CellPosition( 0, 1, 2, 1 ) );
220
221     // The enable/disable radio group
222     Toolkit::TableView radioGroup1Background = Toolkit::TableView::New( 1, 1 );
223     radioGroup1Background.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
224     radioGroup1Background.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
225     radioGroup1Background.SetBackgroundColor( BACKGROUND_COLOUR );
226     radioGroup1Background.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE ) );
227     radioGroup1Background.SetFitHeight( 0 );
228
229     contentTable.Add( radioGroup1Background );
230
231     // Radio group
232     Toolkit::TableView radioButtonsGroup1 = Toolkit::TableView::New( 2, 1 );
233     radioButtonsGroup1.SetCellPadding( Size( 0.0f, MARGIN_SIZE * 0.5f ) );
234     radioButtonsGroup1.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
235     for( unsigned int i = 0; i < radioButtonsGroup1.GetRows(); ++i )
236     {
237       radioButtonsGroup1.SetFitHeight( i );
238     }
239     radioButtonsGroup1.SetFitWidth( 0 );
240
241     radioGroup1Background.Add( radioButtonsGroup1 );
242
243     // First radio button
244     {
245       Toolkit::TableView tableView = Toolkit::TableView::New( 1, 2 );
246       tableView.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
247       tableView.SetFitHeight( 0 );
248       tableView.SetFitWidth( 0 );
249       tableView.SetFitWidth( 1 );
250
251       Toolkit::TextLabel textLabel = Toolkit::TextLabel::New( "Select enabled" );
252       textLabel.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::WIDTH );
253       textLabel.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
254       textLabel.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
255       tableView.AddChild( textLabel, Toolkit::TableView::CellPosition( 0, 0 ) );
256
257       ImageActor imageActor = ImageActor::New( ResourceImage::New( ENABLED_IMAGE ) );
258       imageActor.SetSize( DP(RADIO_LABEL_THUMBNAIL_SIZE), DP(RADIO_LABEL_THUMBNAIL_SIZE) );
259       imageActor.SetPadding( Padding( DP(20.0f), 0.0f, 0.0f, 0.0f ) );
260       tableView.AddChild( imageActor, Toolkit::TableView::CellPosition( 0, 1 ) );
261
262       Toolkit::RadioButton radioButton = Dali::Toolkit::RadioButton::New( tableView );
263       radioButton.SetName( "radio-select-enable" );
264       radioButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
265       radioButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
266       radioButton.SetPosition( 0, 0 );
267       radioButton.SetSelected( true );
268
269       radioButton.StateChangedSignal().Connect( this, &ButtonsController::EnableSelectButton );
270
271       radioButtonsGroup1.Add( radioButton );
272     }
273
274     // Second radio button
275     {
276       Toolkit::RadioButton radioButton = Dali::Toolkit::RadioButton::New( "Select disabled" );
277       radioButton.SetName( "radio-select-disable" );
278       radioButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
279       radioButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
280       radioButton.SetPosition( 0, DP(50) );
281
282       radioButton.StateChangedSignal().Connect( this, &ButtonsController::EnableSelectButton );
283
284       radioButtonsGroup1.Add( radioButton );
285     }
286
287     // CheckBoxes
288     Toolkit::TableView checkBoxBackground = Toolkit::TableView::New( 3, 1 );
289     checkBoxBackground.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
290     checkBoxBackground.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
291     checkBoxBackground.SetBackgroundColor( BACKGROUND_COLOUR );
292     checkBoxBackground.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE ) );
293
294     for( unsigned int i = 0; i < checkBoxBackground.GetRows(); ++i )
295     {
296       checkBoxBackground.SetFitHeight( i );
297     }
298
299     contentTable.Add( checkBoxBackground );
300
301     Dali::Image unselected = Dali::ResourceImage::New( CHECKBOX_UNSELECTED_IMAGE );
302     Dali::Image selected = Dali::ResourceImage::New( CHECKBOX_SELECTED_IMAGE );
303
304     {
305       Toolkit::CheckBoxButton checkBox = Toolkit::CheckBoxButton::New();
306       checkBox.SetName( "checkbox1" );
307       checkBox.SetBackgroundImage( unselected );
308       checkBox.SetSelectedImage( selected );
309       checkBox.SetLabel( "CheckBox1 is unselected" );
310       checkBox.StateChangedSignal().Connect( this, &ButtonsController::OnCheckBoxesSelected );
311
312       checkBoxBackground.Add( checkBox );
313     }
314
315     {
316       Toolkit::CheckBoxButton checkBox = Toolkit::CheckBoxButton::New();
317       checkBox.SetName( "checkbox2" );
318       checkBox.SetBackgroundImage( unselected );
319       checkBox.SetSelectedImage( selected );
320       checkBox.SetLabel( "CheckBox2 is selected" );
321       checkBox.SetSelected( true );
322       checkBox.StateChangedSignal().Connect( this, &ButtonsController::OnCheckBoxesSelected );
323
324       checkBoxBackground.Add( checkBox );
325     }
326
327     {
328       Toolkit::CheckBoxButton checkBox = Toolkit::CheckBoxButton::New();
329       checkBox.SetName( "checkbox3" );
330       checkBox.SetBackgroundImage( unselected );
331       checkBox.SetSelectedImage( selected );
332       checkBox.SetLabel( "CheckBox3 is unselected" );
333       checkBox.StateChangedSignal().Connect( this, &ButtonsController::OnCheckBoxesSelected );
334
335       checkBoxBackground.Add( checkBox );
336     }
337
338     // Create togglabe button
339     Toolkit::TableView toggleBackground = Toolkit::TableView::New( 3, 1 );
340     toggleBackground.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
341     toggleBackground.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
342     toggleBackground.SetBackgroundColor( BACKGROUND_COLOUR );
343     toggleBackground.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE ) );
344
345     for( unsigned int i = 0; i < toggleBackground.GetRows(); ++i )
346     {
347       toggleBackground.SetFitHeight( i );
348     }
349
350     contentTable.Add( toggleBackground );
351
352     Toolkit::PushButton toggleButton = Toolkit::PushButton::New();
353     toggleButton.SetTogglableButton( true );
354     toggleButton.SetLabel( "Unselected" );
355     toggleButton.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
356     toggleButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
357
358     toggleButton.SetSelectedImage( Dali::ResourceImage::New( PUSHBUTTON_PRESS_IMAGE ) );
359     toggleButton.SetDisabledImage( Dali::ResourceImage::New( PUSHBUTTON_DISABLED_IMAGE ) );
360     toggleButton.SetButtonImage( Dali::ResourceImage::New( PUSHBUTTON_BUTTON_IMAGE ) );
361
362     toggleButton.StateChangedSignal().Connect( this, &ButtonsController::OnButtonSelected );
363
364     toggleBackground.Add( toggleButton );
365   }
366
367   void OnKeyEvent( const KeyEvent& event )
368   {
369     if( event.state == KeyEvent::Down )
370     {
371       if( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
372       {
373         // Exit application when click back or escape.
374         mApplication.Quit();
375       }
376     }
377   }
378
379   bool OnButtonSelected( Toolkit::Button button )
380   {
381     Toolkit::PushButton pushButton = Toolkit::PushButton::DownCast( button );
382     if( pushButton )
383     {
384       if( button.IsSelected() )
385       {
386         pushButton.SetLabel( "Selected" );
387       }
388       else
389       {
390         pushButton.SetLabel( "Unselected" );
391       }
392     }
393
394     return true;
395   }
396
397   bool EnableSelectButton( Toolkit::Button button )
398   {
399     if( button.GetName() == "radio-select-enable" && button.IsSelected() == true )
400     {
401       mUpdateButton.SetDisabled( false );
402     }
403     else if( button.GetName() == "radio-select-disable" && button.IsSelected() == true )
404     {
405       mUpdateButton.SetDisabled( true );
406     }
407
408     return true;
409   }
410
411   bool OnButtonClicked(Toolkit::Button button)
412   {
413     if( mRadioButtonImage1.IsSelected() )
414     {
415       mImage.SetImage( mBigImage1 );
416     }
417     else if( mRadioButtonImage2.IsSelected() )
418     {
419       mImage.SetImage( mBigImage2 );
420     }
421     else if( mRadioButtonImage3.IsSelected() )
422     {
423       mImage.SetImage( mBigImage3 );
424     }
425     return true;
426   }
427
428   bool OnCheckBoxesSelected( Toolkit::Button button )
429   {
430     if( button.GetName() == "checkbox1" )
431     {
432       if( button.IsSelected() )
433       {
434         button.SetLabel("CheckBox1 is selected");
435       }
436       else
437       {
438         button.SetLabel("CheckBox1 is unselected");
439       }
440     }
441
442     if( button.GetName() == "checkbox2" )
443     {
444       if( button.IsSelected() )
445       {
446         button.SetLabel("CheckBox2 is selected");
447       }
448       else
449       {
450         button.SetLabel("CheckBox2 is unselected");
451       }
452     }
453
454     if( button.GetName() == "checkbox3" )
455     {
456       if( button.IsSelected() )
457       {
458         button.SetLabel("CheckBox3 is selected");
459       }
460       else
461       {
462         button.SetLabel("CheckBox3 is unselected");
463       }
464     }
465
466     return true;
467   }
468
469   bool OnTouchEvent( Actor actor, const TouchEvent& event )
470   {
471     if( 1u == event.GetPointCount() )
472     {
473       const TouchPoint::State state = event.GetPoint(0u).state;
474
475       // Clamp to integer values; this is to reduce flicking due to pixel misalignment
476       const float localPoint = static_cast<float>( static_cast<int>( event.GetPoint( 0 ).local.y ) );
477
478       if( TouchPoint::Down == state )
479       {
480         mLastPoint = localPoint;
481         mAnimation = Animation::New( 0.25f );
482       }
483       else if( TouchPoint::Motion == state )
484       {
485         if( mAnimation )
486         {
487           mAnimation.AnimateBy( Property(actor, Actor::Property::POSITION), Vector3( 0.f, localPoint - mLastPoint, 0.f ), AlphaFunctions::Linear );
488           mAnimation.Play();
489           mLastPoint = localPoint;
490         }
491       }
492     }
493
494     return true;
495   }
496
497  private:
498
499   Application&      mApplication;
500   Toolkit::View     mView;                              ///< The View instance.
501   Toolkit::ToolBar  mToolBar;                           ///< The View's Toolbar.
502   Layer             mContentLayer;                      ///< Content layer
503
504   Toolkit::RadioButton mRadioButtonImage1;
505   Toolkit::RadioButton mRadioButtonImage2;
506   Toolkit::RadioButton mRadioButtonImage3;
507
508   Toolkit::PushButton mUpdateButton;
509
510   Animation      mAnimation;
511   float          mLastPoint;
512
513   Image mBigImage1;
514   Image mBigImage2;
515   Image mBigImage3;
516   ImageActor mImage;
517 };
518
519 void RunTest( Application& application )
520 {
521   ButtonsController test( application );
522
523   application.MainLoop();
524 }
525
526 // Entry point for Linux & Tizen applications
527 //
528 int main( int argc, char **argv )
529 {
530   Application application = Application::New( &argc, &argv );
531
532   RunTest( application );
533
534   return 0;
535 }