06e794ac396c314e878ffe9616e19dd72e0fa60f
[platform/core/uifw/dali-demo.git] / examples / primitive-shapes / primitive-shapes-example.cpp
1 #include <dali-toolkit/dali-toolkit.h>
2 #include <dali/public-api/object/property-map.h>
3 #include <dali-toolkit/public-api/controls/slider/slider.h>
4
5 using namespace Dali;
6 using namespace Dali::Toolkit;
7
8 namespace
9 {
10   //Button image urls
11   const char* BUTTON_IMAGE_URL[] =
12   {
13     DEMO_IMAGE_DIR "sphere-button.png",
14     DEMO_IMAGE_DIR "cone-button.png",
15     DEMO_IMAGE_DIR "conical-frustrum-button.png",
16     DEMO_IMAGE_DIR "cylinder-button.png",
17     DEMO_IMAGE_DIR "cube-button.png",
18     DEMO_IMAGE_DIR "bevelled-cube-button.png",
19     DEMO_IMAGE_DIR "octahedron-button.png"
20   };
21
22   //Prefix of all shape titles.
23   const std::string SHAPE_TITLE_PREFIX = "Current Shape: ";
24
25   //Shape property defaults
26   const int DEFAULT_SLICES = 32;
27   const int DEFAULT_STACKS = 32;
28   const float DEFAULT_SCALE_HEIGHT = 16.0f;
29   const float DEFAULT_SCALE_BOTTOM_RADIUS = 8.0f;
30   const float DEFAULT_SCALE_TOP_RADIUS = 4.0f;
31   const float DEFAULT_SCALE_RADIUS = 8.0f;
32   const float DEFAULT_BEVEL_PERCENTAGE = 0.3f;
33   const float DEFAULT_BEVEL_SMOOTHNESS = 0.0f;
34
35   //Shape property limits
36   const int SLICES_LOWER_BOUND = 3;
37   const int SLICES_UPPER_BOUND = 16;
38   const int STACKS_LOWER_BOUND = 2;
39   const int STACKS_UPPER_BOUND = 16;
40
41   //Used to the control rate of rotation when panning an object.
42   const float X_ROTATION_DISPLACEMENT_FACTOR = 60.0f;
43   const float Y_ROTATION_DISPLACEMENT_FACTOR = 60.0f;
44
45   const int NUM_MODELS = 7; //Total number of possible base shapes.
46   const int MAX_PROPERTIES = 3; //Maximum number of properties a shape may require. (For displaying sliders.)
47
48 } //End namespace
49
50 class PrimitiveShapesController : public ConnectionTracker
51 {
52 public:
53
54   PrimitiveShapesController( Application& application )
55   : mApplication( application ),
56     mColor( Vector4( 0.3f, 0.7f, 1.0f, 1.0f ) ),
57     mRotation( Vector2::ZERO )
58   {
59     // Connect to the Application's Init signal
60     mApplication.InitSignal().Connect( this, &PrimitiveShapesController::Create );
61   }
62
63   ~PrimitiveShapesController()
64   {
65   }
66
67   // The Init signal is received once (only) during the Application lifetime
68   void Create( Application& application )
69   {
70     // Get a handle to the stage
71     Stage stage = Stage::GetCurrent();
72     stage.SetBackgroundColor( Color::WHITE );
73
74     // Hide the indicator bar
75     application.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
76
77     //Set up layer to place UI on.
78     Layer layer = Layer::New();
79     layer.SetParentOrigin( ParentOrigin::CENTER );
80     layer.SetAnchorPoint( AnchorPoint::CENTER );
81     layer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
82     layer.SetBehavior( Layer::LAYER_2D ); //We use a 2D layer as this is closer to UI work than full 3D scene creation.
83     layer.SetDepthTestDisabled( false ); //Enable depth testing, as otherwise the 2D layer would not do so.
84     stage.Add( layer );
85
86     //Set up model selection buttons.
87     SetupButtons( layer );
88
89     //Set up model parameter sliders.
90     SetupSliders( layer );
91
92     //Set up 3D model.
93     SetupModel( layer );
94
95     //Allow for exiting of the application via key presses.
96     stage.KeyEventSignal().Connect( this, &PrimitiveShapesController::OnKeyEvent );
97   }
98
99   //Place buttons on the top of the screen, which allow for selection of the shape to be displayed.
100   //A title above indicates the currently selected shape.
101   //The buttons are laid out like so:
102   //
103   //      ^    +--------------------------------+
104   //      |    | Current Shape: ~~~~~           |
105   //      |    |                                |
106   //      |    | +----+ +----+ +----+ +----+    |
107   //      |    | |    | |    | |    | |    |    |
108   //  30% |    | +----+ +----+ +----+ +----+    |
109   //      |    |                                |
110   //      |    | +----+ +----+ +----+           |
111   //      |    | |    | |    | |    |           |
112   //      v    | +----+ +----+ +----+           |
113   //           |                                |
114   //           |                                |
115   //           |                                |
116   //           |                                |
117   //           |                                |
118   //           |                                |
119   //           |                                |
120   //           |                                |
121   //           |                                |
122   //           |                                |
123   //           |                                |
124   //           |                                |
125   //           |                                |
126   //           |                                |
127   //           |                                |
128   //           |                                |
129   //           |                                |
130   //           |                                |
131   //           +--------------------------------+
132   //
133   void SetupButtons( Layer layer )
134   {
135     float containerPadding = 10.0f;
136     float elementPadding = 5.0f;
137
138     //Used to layout the title and the buttons below it.
139     Control topAlignment = Control::New();
140     topAlignment.SetParentOrigin( ParentOrigin::TOP_CENTER );
141     topAlignment.SetAnchorPoint( AnchorPoint::TOP_CENTER );
142     topAlignment.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
143     topAlignment.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT );
144     layer.Add( topAlignment );
145
146     //Add a title to indicate the currently selected shape.
147     mShapeTitle = TextLabel::New( "DEFAULT" );
148     mShapeTitle.SetParentOrigin( ParentOrigin::CENTER );
149     mShapeTitle.SetAnchorPoint( AnchorPoint::CENTER );
150     mShapeTitle.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
151     mShapeTitle.SetPadding( Padding( elementPadding, elementPadding, elementPadding, elementPadding ) );
152     topAlignment.Add( mShapeTitle );
153
154     //Create a variable-length container that can wrap buttons around as more are added.
155     FlexContainer buttonContainer = FlexContainer::New();
156     buttonContainer.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
157     buttonContainer.SetAnchorPoint( AnchorPoint::TOP_CENTER );
158     buttonContainer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
159     buttonContainer.SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
160     buttonContainer.SetPadding( Padding( containerPadding, containerPadding, containerPadding, containerPadding ) );
161     buttonContainer.SetProperty( FlexContainer::Property::FLEX_DIRECTION, FlexContainer::ROW );
162     buttonContainer.SetProperty( FlexContainer::Property::FLEX_WRAP, FlexContainer::WRAP );
163     topAlignment.Add( buttonContainer );
164
165     //Create buttons and place them in the container.
166     for( int modelNumber = 0; modelNumber < NUM_MODELS; modelNumber++ )
167     {
168       PushButton button = Toolkit::PushButton::New();
169       button.SetParentOrigin( ParentOrigin::CENTER );
170       button.SetAnchorPoint( AnchorPoint::CENTER );
171       button.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
172       button.SetPadding( Padding( elementPadding, elementPadding, elementPadding, elementPadding ) );
173       button.SetProperty( Button::Property::UNSELECTED_STATE_IMAGE, Property::Value( BUTTON_IMAGE_URL[modelNumber] ) );
174       button.SetProperty( Button::Property::SELECTED_STATE_IMAGE, Property::Value( BUTTON_IMAGE_URL[modelNumber] ) );
175       button.RegisterProperty( "modelNumber", Property::Value( modelNumber ) );
176       button.ClickedSignal().Connect( this, &PrimitiveShapesController::OnChangeShapeClicked );
177
178       buttonContainer.Add( button );
179     }
180   }
181
182   //Add sliders to the bottom of the screen, which allow for control of shape properties such as radius.
183   //Each slider is placed next to a label that states the property it affects.
184   //The sliders are laid out like so:
185   //
186   //           +--------------------------------+
187   //           |                                |
188   //           |                                |
189   //           |                                |
190   //           |                                |
191   //           |                                |
192   //           |                                |
193   //           |                                |
194   //           |                                |
195   //           |                                |
196   //           |                                |
197   //           |                                |
198   //           |                                |
199   //           |                                |
200   //           |                                |
201   //           |                                |
202   //           |                                |
203   //           |                                |
204   //           |                                |
205   //           |                                |
206   //      ^    | Label +----------O-----------+ |
207   //      |    |                                |
208   //      |    |                                |
209   //      |    | Label +--O-------------------+ |
210   //  30% |    |                                |
211   //      |    |                                |
212   //      |    | Label +----------------------O |
213   //      |    |                                |
214   //      v    +--------------------------------+
215   //
216   void SetupSliders( Layer layer )
217   {
218     //Create table to hold sliders and their corresponding labels.
219     mSliderTable = Toolkit::TableView::New( MAX_PROPERTIES, 2 );
220     mSliderTable.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
221     mSliderTable.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
222     mSliderTable.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
223     mSliderTable.SetSizeModeFactor( Vector3( 0.9, 0.3, 0.0 ) );  //90% of width, 30% of height.
224     mSliderTable.SetFitWidth( 0 );  //Label column should fit to natural size of label.
225     mSliderTable.SetRelativeWidth( 1, 1.0f );  //Slider column should fill remaining space.
226     mSliderTable.SetCellPadding( Vector2( 10.0f, 0.0f ) ); //Leave a gap between the slider and its label.
227     layer.Add( mSliderTable );
228
229     //Set up sliders, and place labels next to them.
230     for( int i = 0; i < MAX_PROPERTIES; i++ )
231     {
232       //Create slider
233       Slider slider = Slider::New();
234       slider.SetParentOrigin( ParentOrigin::CENTER );
235       slider.SetAnchorPoint( AnchorPoint::CENTER );
236       slider.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
237       slider.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
238       slider.ValueChangedSignal().Connect( this, &PrimitiveShapesController::OnSliderValueChanged );
239       mSliders.push_back( slider );
240
241       //Setup slider cell properties
242       mSliderTable.AddChild( slider, TableView::CellPosition( i, 1 ) );
243       mSliderTable.SetCellAlignment( TableView::CellPosition( i, 1 ), HorizontalAlignment::CENTER, VerticalAlignment::CENTER );
244
245       //Create slider label
246       TextLabel sliderLabel = TextLabel::New();
247       sliderLabel.SetParentOrigin( ParentOrigin::CENTER );
248       sliderLabel.SetAnchorPoint( AnchorPoint::CENTER );
249       sliderLabel.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
250       mSliderLabels.push_back( sliderLabel );
251
252       //Setup slider-label cell properties
253       mSliderTable.AddChild( sliderLabel, TableView::CellPosition( i, 0 ) );
254       mSliderTable.SetCellAlignment( TableView::CellPosition( i, 0 ), HorizontalAlignment::LEFT, VerticalAlignment::CENTER );
255     }
256   }
257
258   //Adds a control to the centre of the stage to display the 3D shapes.
259   //The model is placed in the center of the screen, like so:
260   //
261   //           +--------------------------------+
262   //           |                                |
263   //           |                                |
264   //           |                                |
265   //           |                                |
266   //           |                                |
267   //           |                                |
268   //           |                                |
269   //           |                                |
270   //           |                                |
271   //       ^   |           ----------           |
272   //       |   |          /          \          |
273   //       |   |         /            \         |
274   //       |   |        |              |        |
275   //   30% |   |        |              |        |
276   //       |   |        |              |        |
277   //       |   |         \            /         |
278   //       |   |          \          /          |
279   //       v   |           ----------           |
280   //           |                                |
281   //           |                                |
282   //           |                                |
283   //           |                                |
284   //           |                                |
285   //           |                                |
286   //           |                                |
287   //           |                                |
288   //           |                                |
289   //           +--------------------------------+
290   //
291   void SetupModel( Layer layer )
292   {
293     //Create a container to house the visual-holding actor, to provide a constant hitbox.
294     Actor container = Actor::New();
295     container.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
296     container.SetSizeModeFactor( Vector3( 0.9, 0.3, 0.0 ) );  //90% of width, 30% of height.
297     container.SetParentOrigin( ParentOrigin::CENTER );
298     container.SetAnchorPoint( AnchorPoint::CENTER );
299     layer.Add( container );
300
301     //Create control to display the 3D primitive.
302     mModel = Control::New();
303     mModel.SetParentOrigin( ParentOrigin::CENTER );
304     mModel.SetAnchorPoint( AnchorPoint::CENTER);
305     mModel.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
306     container.Add( mModel );
307
308     //Load default shape.
309     LoadCube();
310
311     //Make model spin to demonstrate 3D.
312     mRotationAnimation = Animation::New(15.0f);
313     mRotationAnimation.AnimateBy( Property( mModel, Actor::Property::ORIENTATION ),
314                                  Quaternion( Degree( 0.0f ), Degree( 360.0f ), Degree( 0.0f ) ) );
315     mRotationAnimation.SetLooping(true);
316     mRotationAnimation.Play();
317
318     //Attach gesture detector to pan models when rotated.
319     mPanGestureDetector = PanGestureDetector::New();
320     mPanGestureDetector.Attach( container );
321     mPanGestureDetector.DetectedSignal().Connect( this, &PrimitiveShapesController::OnPan );
322   }
323
324   //Clears all sliders and resets the primitive visual property map.
325   void InitialiseSlidersAndModel()
326   {
327     //Sliders
328     for( unsigned i = 0; i < mSliders.size(); i++ )
329     {
330       mSliders.at( i ).SetProperty( Slider::Property::MARKS, Property::Value( 0 ) ); //Remove marks
331       mSliders.at( i ).SetVisible( false );
332       mSliderLabels.at( i ).SetProperty( TextLabel::Property::TEXT, Property::Value( "Default" ) );
333       mSliderLabels.at( i ).SetVisible( false );
334     }
335
336     //Visual map for model
337     mVisualMap.Clear();
338     mVisualMap[ Visual::Property::TYPE           ] = Visual::PRIMITIVE;
339     mVisualMap[ PrimitiveVisual::Property::MIX_COLOR ] = mColor;
340   }
341
342   //Sets the 3D model to a sphere and modifies the sliders appropriately.
343   void LoadSphere()
344   {
345     InitialiseSlidersAndModel();
346
347     //Set up specific visual properties.
348     mVisualMap[ PrimitiveVisual::Property::SHAPE  ] = PrimitiveVisual::Shape::SPHERE;
349     mVisualMap[ PrimitiveVisual::Property::SLICES ] = DEFAULT_SLICES;
350     mVisualMap[ PrimitiveVisual::Property::STACKS ] = DEFAULT_STACKS;
351
352     //Set up sliders.
353     SetupSlider( 0, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND, DEFAULT_STACKS, PrimitiveVisual::Property::SLICES, "slices" );
354     SetupMarks( 0, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND );
355     mSliders.at( 0 ).SetProperty( Slider::Property::VALUE_PRECISION, Property::Value( 0 ) );
356
357     SetupSlider( 1, STACKS_LOWER_BOUND, STACKS_UPPER_BOUND, DEFAULT_STACKS, PrimitiveVisual::Property::STACKS, "stacks" );
358     SetupMarks( 1, STACKS_LOWER_BOUND, STACKS_UPPER_BOUND );
359     mSliders.at( 1 ).SetProperty( Slider::Property::VALUE_PRECISION, Property::Value( 0 ) );
360
361     //Set model in control.
362     mModel.SetProperty( Control::Property::BACKGROUND, Property::Value( mVisualMap ) );
363
364     //Update title.
365     mShapeTitle.SetProperty( TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Sphere" );
366   }
367
368   //Sets the 3D model to a cone and modifies the sliders appropriately.
369   void LoadCone()
370   {
371     InitialiseSlidersAndModel();
372
373     //Set up specific visual properties.
374     mVisualMap[ PrimitiveVisual::Property::SHAPE               ] = PrimitiveVisual::Shape::CONE;
375     mVisualMap[ PrimitiveVisual::Property::SCALE_HEIGHT        ] = DEFAULT_SCALE_HEIGHT;
376     mVisualMap[ PrimitiveVisual::Property::SCALE_BOTTOM_RADIUS ] = DEFAULT_SCALE_BOTTOM_RADIUS;
377     mVisualMap[ PrimitiveVisual::Property::SLICES              ] = DEFAULT_SLICES;
378
379     //Set up sliders.
380     SetupSlider( 0, 1.0f, 32.0f, DEFAULT_SCALE_HEIGHT, PrimitiveVisual::Property::SCALE_HEIGHT, "scaleHeight" );
381     mSliders.at( 0 ).SetProperty( Slider::Property::VALUE_PRECISION, Property::Value( 1 ) );
382
383     SetupSlider( 1, 1.0f, 32.0f, DEFAULT_SCALE_BOTTOM_RADIUS, PrimitiveVisual::Property::SCALE_BOTTOM_RADIUS, "scaleBottomRadius" );
384     mSliders.at( 1 ).SetProperty( Slider::Property::VALUE_PRECISION, Property::Value( 1 ) );
385
386     SetupSlider( 2, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND, DEFAULT_STACKS, PrimitiveVisual::Property::SLICES, "slices" );
387     SetupMarks( 2, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND );
388     mSliders.at( 2 ).SetProperty( Slider::Property::VALUE_PRECISION, Property::Value( 0 ) );
389
390     //Set model in control.
391     mModel.SetProperty( Control::Property::BACKGROUND, Property::Value( mVisualMap ) );
392
393     //Update title.
394     mShapeTitle.SetProperty( TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Cone" );
395   }
396
397   //Sets the 3D model to a conical frustrum and modifies the sliders appropriately.
398   void LoadConicalFrustrum()
399   {
400     InitialiseSlidersAndModel();
401
402     //Set up specific visual properties.
403     mVisualMap[ PrimitiveVisual::Property::SHAPE               ] = PrimitiveVisual::Shape::CONICAL_FRUSTRUM;
404     mVisualMap[ PrimitiveVisual::Property::SCALE_TOP_RADIUS    ] = DEFAULT_SCALE_TOP_RADIUS;
405     mVisualMap[ PrimitiveVisual::Property::SCALE_BOTTOM_RADIUS ] = DEFAULT_SCALE_BOTTOM_RADIUS;
406     mVisualMap[ PrimitiveVisual::Property::SCALE_HEIGHT        ] = DEFAULT_SCALE_HEIGHT;
407     mVisualMap[ PrimitiveVisual::Property::SLICES              ] = DEFAULT_SLICES;
408
409     //Set up used sliders.
410     SetupSlider( 0, 1.0f, 32.0f, DEFAULT_SCALE_HEIGHT, PrimitiveVisual::Property::SCALE_HEIGHT, "scaleHeight" );
411     mSliders.at( 0 ).SetProperty( Slider::Property::VALUE_PRECISION, Property::Value( 1 ) );
412
413     SetupSlider( 1, 0.0f, 32.0f, DEFAULT_SCALE_BOTTOM_RADIUS, PrimitiveVisual::Property::SCALE_BOTTOM_RADIUS, "scaleBottomRadius" );
414     mSliders.at( 1 ).SetProperty( Slider::Property::VALUE_PRECISION, Property::Value( 1 ) );
415
416     SetupSlider( 2, 0.0f, 32.0f, DEFAULT_SCALE_TOP_RADIUS, PrimitiveVisual::Property::SCALE_TOP_RADIUS, "scaleTopRadius" );
417     mSliders.at( 2 ).SetProperty( Slider::Property::VALUE_PRECISION, Property::Value( 1 ) );
418
419     //Set model in control.
420     mModel.SetProperty( Control::Property::BACKGROUND, Property::Value( mVisualMap ) );
421
422     //Update title.
423     mShapeTitle.SetProperty( TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Conical Frustrum" );
424   }
425
426   //Sets the 3D model to a cylinder and modifies the sliders appropriately.
427   void LoadCylinder()
428   {
429     InitialiseSlidersAndModel();
430
431     //Set up specific visual properties.
432     mVisualMap[ PrimitiveVisual::Property::SHAPE        ] = PrimitiveVisual::Shape::CYLINDER;
433     mVisualMap[ PrimitiveVisual::Property::SCALE_HEIGHT ] = DEFAULT_SCALE_HEIGHT;
434     mVisualMap[ PrimitiveVisual::Property::SCALE_RADIUS ] = DEFAULT_SCALE_RADIUS;
435     mVisualMap[ PrimitiveVisual::Property::SLICES       ] = DEFAULT_SLICES;
436
437     //Set up used sliders.
438     SetupSlider( 0, 1.0f, 32.0f, DEFAULT_SCALE_HEIGHT, PrimitiveVisual::Property::SCALE_HEIGHT, "scaleHeight" );
439     mSliders.at( 0 ).SetProperty( Slider::Property::VALUE_PRECISION, Property::Value( 1 ) );
440
441     SetupSlider( 1, 1.0f, 32.0f, DEFAULT_SCALE_RADIUS, PrimitiveVisual::Property::SCALE_RADIUS, "scaleRadius" );
442     mSliders.at( 1 ).SetProperty( Slider::Property::VALUE_PRECISION, Property::Value( 1 ) );
443
444     SetupSlider( 2, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND, DEFAULT_STACKS, PrimitiveVisual::Property::SLICES, "slices" );
445     SetupMarks( 2 , SLICES_LOWER_BOUND, SLICES_UPPER_BOUND );
446     mSliders.at( 2 ).SetProperty( Slider::Property::VALUE_PRECISION, Property::Value( 0 ) );
447
448     //Set model in control.
449     mModel.SetProperty( Control::Property::BACKGROUND, Property::Value( mVisualMap ) );
450
451     //Update title.
452     mShapeTitle.SetProperty( TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Cylinder" );
453   }
454
455   //Sets the 3D model to a cube and modifies the sliders appropriately.
456   void LoadCube()
457   {
458     InitialiseSlidersAndModel();
459
460     //Set up specific visual properties.
461     mVisualMap[ PrimitiveVisual::Property::SHAPE ] = PrimitiveVisual::Shape::CUBE;
462
463     //Set model in control.
464     mModel.SetProperty( Control::Property::BACKGROUND, Property::Value( mVisualMap ) );
465
466     //Update title.
467     mShapeTitle.SetProperty( TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Cube" );
468   }
469
470   //Sets the 3D model to a bevelled cube and modifies the sliders appropriately.
471   void LoadBevelledCube()
472   {
473     InitialiseSlidersAndModel();
474
475     //Set up specific visual properties.
476     mVisualMap[ PrimitiveVisual::Property::SHAPE            ] = PrimitiveVisual::Shape::BEVELLED_CUBE;
477     mVisualMap[ PrimitiveVisual::Property::BEVEL_PERCENTAGE ] = DEFAULT_BEVEL_PERCENTAGE;
478     mVisualMap[ PrimitiveVisual::Property::BEVEL_SMOOTHNESS ] = DEFAULT_BEVEL_SMOOTHNESS;
479
480     //Set up used sliders.
481     SetupSlider( 0, 0.0f, 1.0f, DEFAULT_BEVEL_PERCENTAGE, PrimitiveVisual::Property::BEVEL_PERCENTAGE, "bevelPercentage" );
482     mSliders.at( 0 ).SetProperty( Slider::Property::VALUE_PRECISION, Property::Value( 2 ) );
483
484     SetupSlider( 1, 0.0f, 1.0f, DEFAULT_BEVEL_SMOOTHNESS, PrimitiveVisual::Property::BEVEL_SMOOTHNESS, "bevelSmoothness" );
485     mSliders.at( 1 ).SetProperty( Slider::Property::VALUE_PRECISION, Property::Value( 2 ) );
486
487     //Set model in control.
488     mModel.SetProperty( Control::Property::BACKGROUND, Property::Value( mVisualMap ) );
489
490     //Update title.
491     mShapeTitle.SetProperty( TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Bevelled Cube" );
492   }
493
494   //Sets the 3D model to an octahedron and modifies the sliders appropriately.
495   void LoadOctahedron()
496   {
497     InitialiseSlidersAndModel();
498
499     //Set up specific visual properties.
500     mVisualMap[ PrimitiveVisual::Property::SHAPE ] = PrimitiveVisual::Shape::OCTAHEDRON;
501
502     //Set model in control.
503     mModel.SetProperty( Control::Property::BACKGROUND, Property::Value( mVisualMap ) );
504
505     //Update title.
506     mShapeTitle.SetProperty( TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Octahedron" );
507   }
508
509   //Sets up the slider at the given index for the supplied property, and labels it appropriately.
510   // visualProperty is the property that will be set by this slider.
511   void SetupSlider( int sliderIndex, float lowerBound, float upperBound, float startPoint,
512                     Property::Index visualProperty, std::string visualPropertyLabel )
513   {
514     //Set up the slider itself.
515     mSliders.at( sliderIndex ).RegisterProperty( "visualProperty", Property::Value( visualProperty ), Property::READ_WRITE );
516     mSliders.at( sliderIndex ).SetProperty( Slider::Property::LOWER_BOUND, Property::Value( lowerBound ) );
517     mSliders.at( sliderIndex ).SetProperty( Slider::Property::UPPER_BOUND, Property::Value( upperBound ) );
518     mSliders.at( sliderIndex ).SetProperty( Slider::Property::VALUE, Property::Value( startPoint ) );
519     mSliders.at( sliderIndex ).SetVisible( true );
520
521     //Label the slider with the property.
522     //We reset the TextLabel to force a relayout of the table.
523     mSliderTable.RemoveChildAt( TableView::CellPosition(sliderIndex, 0) );
524
525     TextLabel sliderLabel = TextLabel::New( visualPropertyLabel );
526     sliderLabel.SetParentOrigin( ParentOrigin::CENTER );
527     sliderLabel.SetAnchorPoint( AnchorPoint::CENTER );
528     sliderLabel.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
529
530     mSliderTable.AddChild( sliderLabel, TableView::CellPosition( sliderIndex, 0 ) );
531     mSliderTable.SetCellAlignment( TableView::CellPosition( sliderIndex, 0 ), HorizontalAlignment::LEFT, VerticalAlignment::CENTER );
532
533     mSliderLabels.at( sliderIndex ).SetVisible( true );
534     mSliderLabels.at( sliderIndex) = sliderLabel;
535   }
536
537   //Setup snapping to integer values between the two given values.
538   void SetupMarks( int sliderIndex, int lower, int upper )
539   {
540     Property::Array marks;
541
542     for( int mark = lower; mark <= upper; mark++ )
543     {
544       marks.PushBack( Property::Value( mark ) );
545     }
546
547     mSliders.at( sliderIndex ).SetProperty( Slider::Property::MARKS, Property::Value( marks ) );
548     mSliders.at( sliderIndex ).SetProperty( Slider::Property::SNAP_TO_MARKS, Property::Value( true ) );
549   }
550
551   //When a shape button is tapped, switch to the corresponding shape.
552   bool OnChangeShapeClicked( Button button )
553   {
554     //Get the model number from the button.
555     int modelNumber;
556     button.GetProperty( button.GetPropertyIndex( "modelNumber" ) ).Get( modelNumber );
557
558     //Switch to the shape that corresponds to the model number.
559     switch( modelNumber )
560     {
561       case 0:
562       {
563         LoadSphere();
564         break;
565       }
566       case 1:
567       {
568         LoadCone();
569         break;
570       }
571       case 2:
572       {
573         LoadConicalFrustrum();
574         break;
575       }
576       case 3:
577       {
578         LoadCylinder();
579         break;
580       }
581       case 4:
582       {
583         LoadCube();
584         break;
585       }
586       case 5:
587       {
588         LoadBevelledCube();
589         break;
590       }
591       case 6:
592       {
593         LoadOctahedron();
594         break;
595       }
596     }
597
598     return true;
599   }
600
601   //When the slider is adjusted, change the corresponding shape property accordingly.
602   bool OnSliderValueChanged( Slider slider, float value )
603   {
604     //Update property map to reflect the change to the specific visual property.
605     int visualProperty;
606     slider.GetProperty( slider.GetPropertyIndex( "visualProperty" ) ).Get( visualProperty );
607     mVisualMap[ visualProperty ] = value;
608
609     //Reload the model to display the change.
610     mModel.SetProperty( Control::Property::BACKGROUND, Property::Value( mVisualMap ) );
611
612     return true;
613   }
614
615   //Panning around the shape rotates it.
616   void OnPan( Actor actor, const PanGesture& gesture )
617   {
618     switch( gesture.state )
619     {
620       case Gesture::Started:
621       {
622         //Pause animation, as the gesture will be used to manually rotate the model
623         mRotationAnimation.Pause();
624
625         break;
626       }
627       case Gesture::Continuing:
628       {
629         //Rotate based off the gesture.
630         mRotation.x -= gesture.displacement.y / X_ROTATION_DISPLACEMENT_FACTOR; // Y displacement rotates around X axis
631         mRotation.y += gesture.displacement.x / Y_ROTATION_DISPLACEMENT_FACTOR; // X displacement rotates around Y axis
632         Quaternion rotation = Quaternion( Radian( mRotation.x ), Vector3::XAXIS) *
633                               Quaternion( Radian( mRotation.y ), Vector3::YAXIS);
634
635         mModel.SetOrientation( rotation );
636
637         break;
638       }
639       case Gesture::Finished:
640       {
641         //Return to automatic animation
642         mRotationAnimation.Play();
643
644         break;
645       }
646       case Gesture::Cancelled:
647       {
648         //Return to automatic animation
649         mRotationAnimation.Play();
650
651         break;
652       }
653       default:
654       {
655         break;
656       }
657     }
658   }
659
660   //If escape or the back button is pressed, quit the application (and return to the launcher)
661   void OnKeyEvent( const KeyEvent& event )
662   {
663     if( event.state == KeyEvent::Down )
664     {
665       if( IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK ) )
666       {
667         mApplication.Quit();
668       }
669     }
670   }
671
672 private:
673   Application& mApplication;
674
675   std::vector<Slider>       mSliders;               ///< Holds the sliders on screen that each shape accesses.
676   std::vector<TextLabel>    mSliderLabels;          ///< Holds the labels to each slider.
677   TableView                 mSliderTable;           ///< A table to layout the sliders next to their labels.
678
679   Property::Map             mVisualMap;             ///< Property map to create a primitive visual.
680   Control                   mModel;                 ///< Control to house the primitive visual.
681   TextLabel                 mShapeTitle;            ///< Indicates what the currently selected shape is.
682
683   PanGestureDetector        mPanGestureDetector;    ///< Detects pan gestures for rotation of the model.
684   Animation                 mRotationAnimation;     ///< Automatically rotates the model, unless it is being panned.
685
686   Vector4                   mColor;                 ///< Color to set all shapes.
687   Vector2                   mRotation;              ///< Keeps track of model rotation.
688 };
689
690 void RunTest( Application& application )
691 {
692   PrimitiveShapesController test( application );
693
694   application.MainLoop();
695 }
696
697 // Entry point for Linux & Tizen applications
698 //
699 int main( int argc, char **argv )
700 {
701   Application application = Application::New( &argc, &argv );
702
703   RunTest( application );
704
705   return 0;
706 }