2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <dali-toolkit/dali-toolkit.h>
19 #include <dali-toolkit/devel-api/controls/table-view/table-view.h>
22 using namespace Dali::Toolkit;
27 const char* BUTTON_IMAGE_URL[] =
29 DEMO_IMAGE_DIR "sphere-button.png",
30 DEMO_IMAGE_DIR "cone-button.png",
31 DEMO_IMAGE_DIR "conical-frustum-button.png",
32 DEMO_IMAGE_DIR "cylinder-button.png",
33 DEMO_IMAGE_DIR "cube-button.png",
34 DEMO_IMAGE_DIR "bevelled-cube-button.png",
35 DEMO_IMAGE_DIR "octahedron-button.png"};
37 //Prefix of all shape titles.
38 const std::string SHAPE_TITLE_PREFIX = "Current Shape: ";
40 //Shape property defaults
41 const int DEFAULT_SLICES = 32;
42 const int DEFAULT_STACKS = 32;
43 const float DEFAULT_SCALE_HEIGHT = 16.0f;
44 const float DEFAULT_SCALE_BOTTOM_RADIUS = 8.0f;
45 const float DEFAULT_SCALE_TOP_RADIUS = 4.0f;
46 const float DEFAULT_SCALE_RADIUS = 8.0f;
47 const float DEFAULT_BEVEL_PERCENTAGE = 0.3f;
48 const float DEFAULT_BEVEL_SMOOTHNESS = 0.0f;
50 //Shape property limits
51 const int SLICES_LOWER_BOUND = 3;
52 const int SLICES_UPPER_BOUND = 16;
53 const int STACKS_LOWER_BOUND = 2;
54 const int STACKS_UPPER_BOUND = 16;
56 //Used to the control rate of rotation when panning an object.
57 const float X_ROTATION_DISPLACEMENT_FACTOR = 60.0f;
58 const float Y_ROTATION_DISPLACEMENT_FACTOR = 60.0f;
60 const int NUM_MODELS = 7; //Total number of possible base shapes.
61 const int MAX_PROPERTIES = 3; //Maximum number of properties a shape may require. (For displaying sliders.)
65 class PrimitiveShapesController : public ConnectionTracker
68 PrimitiveShapesController(Application& application)
69 : mApplication(application),
70 mColor(Vector4(0.3f, 0.7f, 1.0f, 1.0f)),
71 mRotation(Vector2::ZERO)
73 // Connect to the Application's Init signal
74 mApplication.InitSignal().Connect(this, &PrimitiveShapesController::Create);
77 ~PrimitiveShapesController()
81 // The Init signal is received once (only) during the Application lifetime
82 void Create(Application& application)
84 // Get a handle to the window
85 Window window = application.GetWindow();
86 window.SetBackgroundColor(Color::WHITE);
88 //Set up layer to place UI on.
89 Layer layer = Layer::New();
90 layer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
91 layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
92 layer.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
93 layer.SetProperty(Layer::Property::BEHAVIOR, Layer::LAYER_UI); //We use a 2D layer as this is closer to UI work than full 3D scene creation.
94 layer.SetProperty(Layer::Property::DEPTH_TEST, true); //Enable depth testing, as otherwise the 2D layer would not do so.
97 //Set up model selection buttons.
100 //Set up model parameter sliders.
106 //Allow for exiting of the application via key presses.
107 window.KeyEventSignal().Connect(this, &PrimitiveShapesController::OnKeyEvent);
110 //Place buttons on the top of the screen, which allow for selection of the shape to be displayed.
111 //A title above indicates the currently selected shape.
112 //The buttons are laid out like so:
114 // ^ +--------------------------------+
115 // | | Current Shape: ~~~~~ |
117 // | | +----+ +----+ +----+ +----+ |
118 // | | | | | | | | | | |
119 // 30% | | +----+ +----+ +----+ +----+ |
121 // | | +----+ +----+ +----+ |
123 // v | +----+ +----+ +----+ |
142 // +--------------------------------+
144 void SetupButtons(Layer layer)
146 float containerPadding = 10.0f;
147 float elementPadding = 5.0f;
149 //Used to layout the title and the buttons below it.
150 Control topAlignment = Control::New();
151 topAlignment.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
152 topAlignment.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
153 topAlignment.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
154 topAlignment.SetResizePolicy(ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT);
155 layer.Add(topAlignment);
157 //Add a title to indicate the currently selected shape.
158 mShapeTitle = TextLabel::New("DEFAULT");
159 mShapeTitle.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
160 mShapeTitle.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
161 mShapeTitle.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
162 mShapeTitle.SetProperty(Actor::Property::PADDING, Padding(elementPadding, elementPadding, elementPadding, elementPadding));
163 topAlignment.Add(mShapeTitle);
165 //Create a variable-length container that can wrap buttons around as more are added.
166 FlexContainer buttonContainer = FlexContainer::New();
167 buttonContainer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER);
168 buttonContainer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
169 buttonContainer.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
170 buttonContainer.SetResizePolicy(ResizePolicy::FIXED, Dimension::HEIGHT);
171 buttonContainer.SetProperty(Actor::Property::PADDING, Padding(containerPadding, containerPadding, containerPadding, containerPadding));
172 buttonContainer.SetProperty(FlexContainer::Property::FLEX_DIRECTION, FlexContainer::ROW);
173 buttonContainer.SetProperty(FlexContainer::Property::FLEX_WRAP, FlexContainer::WRAP);
174 topAlignment.Add(buttonContainer);
176 //Create buttons and place them in the container.
177 for(int modelNumber = 0; modelNumber < NUM_MODELS; modelNumber++)
179 PushButton button = Toolkit::PushButton::New();
180 button.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
181 button.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
182 button.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
183 button.SetProperty(Actor::Property::PADDING, Padding(elementPadding, elementPadding, elementPadding, elementPadding));
184 button.SetProperty(Button::Property::UNSELECTED_BACKGROUND_VISUAL, BUTTON_IMAGE_URL[modelNumber]);
185 button.SetProperty(Button::Property::SELECTED_BACKGROUND_VISUAL, BUTTON_IMAGE_URL[modelNumber]);
186 button.RegisterProperty("modelNumber", Property::Value(modelNumber));
187 button.ClickedSignal().Connect(this, &PrimitiveShapesController::OnChangeShapeClicked);
189 buttonContainer.Add(button);
193 //Add sliders to the bottom of the screen, which allow for control of shape properties such as radius.
194 //Each slider is placed next to a label that states the property it affects.
195 //The sliders are laid out like so:
197 // +--------------------------------+
217 // ^ | Label +----------O-----------+ |
220 // | | Label +--O-------------------+ |
223 // | | Label +----------------------O |
225 // v +--------------------------------+
227 void SetupSliders(Layer layer)
229 //Create table to hold sliders and their corresponding labels.
230 mSliderTable = Toolkit::TableView::New(MAX_PROPERTIES, 2);
231 mSliderTable.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER);
232 mSliderTable.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER);
233 mSliderTable.SetResizePolicy(ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS);
234 mSliderTable.SetProperty(Actor::Property::SIZE_MODE_FACTOR, Vector3(0.9, 0.3, 0.0)); //90% of width, 30% of height.
235 mSliderTable.SetFitWidth(0); //Label column should fit to natural size of label.
236 mSliderTable.SetRelativeWidth(1, 1.0f); //Slider column should fill remaining space.
237 mSliderTable.SetCellPadding(Vector2(10.0f, 0.0f)); //Leave a gap between the slider and its label.
238 layer.Add(mSliderTable);
240 //Set up sliders, and place labels next to them.
241 for(int i = 0; i < MAX_PROPERTIES; i++)
244 Slider slider = Slider::New();
245 slider.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
246 slider.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
247 slider.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
248 slider.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT);
249 slider.ValueChangedSignal().Connect(this, &PrimitiveShapesController::OnSliderValueChanged);
250 mSliders.push_back(slider);
252 //Setup slider cell properties
253 mSliderTable.AddChild(slider, TableView::CellPosition(i, 1));
254 mSliderTable.SetCellAlignment(TableView::CellPosition(i, 1), HorizontalAlignment::CENTER, VerticalAlignment::CENTER);
256 //Create slider label
257 TextLabel sliderLabel = TextLabel::New();
258 sliderLabel.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
259 sliderLabel.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
260 sliderLabel.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
261 mSliderLabels.push_back(sliderLabel);
263 //Setup slider-label cell properties
264 mSliderTable.AddChild(sliderLabel, TableView::CellPosition(i, 0));
265 mSliderTable.SetCellAlignment(TableView::CellPosition(i, 0), HorizontalAlignment::LEFT, VerticalAlignment::CENTER);
269 //Adds a control to the centre of the window to display the 3D shapes.
270 //The model is placed in the center of the screen, like so:
272 // +--------------------------------+
300 // +--------------------------------+
302 void SetupModel(Layer layer)
304 //Create a container to house the visual-holding actor, to provide a constant hitbox.
305 Actor container = Actor::New();
306 container.SetResizePolicy(ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS);
307 container.SetProperty(Actor::Property::SIZE_MODE_FACTOR, Vector3(0.9, 0.3, 0.0)); //90% of width, 30% of height.
308 container.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
309 container.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
310 layer.Add(container);
312 //Create control to display the 3D primitive.
313 mModel = Control::New();
314 mModel.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
315 mModel.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
316 mModel.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
317 container.Add(mModel);
319 //Load default shape.
322 //Make model spin to demonstrate 3D.
323 mRotationAnimation = Animation::New(15.0f);
324 mRotationAnimation.AnimateBy(Property(mModel, Actor::Property::ORIENTATION),
325 Quaternion(Degree(0.0f), Degree(360.0f), Degree(0.0f)));
326 mRotationAnimation.SetLooping(true);
327 mRotationAnimation.Play();
329 //Attach gesture detector to pan models when rotated.
330 mPanGestureDetector = PanGestureDetector::New();
331 mPanGestureDetector.Attach(container);
332 mPanGestureDetector.DetectedSignal().Connect(this, &PrimitiveShapesController::OnPan);
335 //Clears all sliders and resets the primitive visual property map.
336 void InitialiseSlidersAndModel()
339 for(unsigned i = 0; i < mSliders.size(); i++)
341 mSliders.at(i).SetProperty(Slider::Property::MARKS, Property::Value(0)); //Remove marks
342 mSliders.at(i).SetProperty(Actor::Property::VISIBLE, false);
343 mSliderLabels.at(i).SetProperty(TextLabel::Property::TEXT, Property::Value("Default"));
344 mSliderLabels.at(i).SetProperty(Actor::Property::VISIBLE, false);
347 //Visual map for model
349 mVisualMap[Toolkit::Visual::Property::TYPE] = Visual::PRIMITIVE;
350 mVisualMap[PrimitiveVisual::Property::MIX_COLOR] = mColor;
351 mVisualMap[Visual::Property::TRANSFORM] =
352 Property::Map().Add(Visual::Transform::Property::ORIGIN, Align::CENTER).Add(Visual::Transform::Property::ANCHOR_POINT, Align::CENTER);
355 //Sets the 3D model to a sphere and modifies the sliders appropriately.
358 InitialiseSlidersAndModel();
360 //Set up specific visual properties.
361 mVisualMap[PrimitiveVisual::Property::SHAPE] = PrimitiveVisual::Shape::SPHERE;
362 mVisualMap[PrimitiveVisual::Property::SLICES] = DEFAULT_SLICES;
363 mVisualMap[PrimitiveVisual::Property::STACKS] = DEFAULT_STACKS;
366 SetupSlider(0, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND, DEFAULT_STACKS, PrimitiveVisual::Property::SLICES, "slices");
367 SetupMarks(0, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND);
368 mSliders.at(0).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(0));
370 SetupSlider(1, STACKS_LOWER_BOUND, STACKS_UPPER_BOUND, DEFAULT_STACKS, PrimitiveVisual::Property::STACKS, "stacks");
371 SetupMarks(1, STACKS_LOWER_BOUND, STACKS_UPPER_BOUND);
372 mSliders.at(1).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(0));
374 //Set model in control.
375 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
378 mShapeTitle.SetProperty(TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Sphere");
381 //Sets the 3D model to a cone and modifies the sliders appropriately.
384 InitialiseSlidersAndModel();
386 //Set up specific visual properties.
387 mVisualMap[PrimitiveVisual::Property::SHAPE] = PrimitiveVisual::Shape::CONE;
388 mVisualMap[PrimitiveVisual::Property::SCALE_HEIGHT] = DEFAULT_SCALE_HEIGHT;
389 mVisualMap[PrimitiveVisual::Property::SCALE_BOTTOM_RADIUS] = DEFAULT_SCALE_BOTTOM_RADIUS;
390 mVisualMap[PrimitiveVisual::Property::SLICES] = DEFAULT_SLICES;
393 SetupSlider(0, 1.0f, 32.0f, DEFAULT_SCALE_HEIGHT, PrimitiveVisual::Property::SCALE_HEIGHT, "scaleHeight");
394 mSliders.at(0).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(1));
396 SetupSlider(1, 1.0f, 32.0f, DEFAULT_SCALE_BOTTOM_RADIUS, PrimitiveVisual::Property::SCALE_BOTTOM_RADIUS, "scaleBottomRadius");
397 mSliders.at(1).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(1));
399 SetupSlider(2, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND, DEFAULT_STACKS, PrimitiveVisual::Property::SLICES, "slices");
400 SetupMarks(2, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND);
401 mSliders.at(2).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(0));
403 //Set model in control.
404 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
407 mShapeTitle.SetProperty(TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Cone");
410 //Sets the 3D model to a conical frustum and modifies the sliders appropriately.
411 void LoadConicalFrustum()
413 InitialiseSlidersAndModel();
415 //Set up specific visual properties.
416 mVisualMap[PrimitiveVisual::Property::SHAPE] = PrimitiveVisual::Shape::CONICAL_FRUSTUM;
417 mVisualMap[PrimitiveVisual::Property::SCALE_TOP_RADIUS] = DEFAULT_SCALE_TOP_RADIUS;
418 mVisualMap[PrimitiveVisual::Property::SCALE_BOTTOM_RADIUS] = DEFAULT_SCALE_BOTTOM_RADIUS;
419 mVisualMap[PrimitiveVisual::Property::SCALE_HEIGHT] = DEFAULT_SCALE_HEIGHT;
420 mVisualMap[PrimitiveVisual::Property::SLICES] = DEFAULT_SLICES;
422 //Set up used sliders.
423 SetupSlider(0, 1.0f, 32.0f, DEFAULT_SCALE_HEIGHT, PrimitiveVisual::Property::SCALE_HEIGHT, "scaleHeight");
424 mSliders.at(0).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(1));
426 SetupSlider(1, 0.0f, 32.0f, DEFAULT_SCALE_BOTTOM_RADIUS, PrimitiveVisual::Property::SCALE_BOTTOM_RADIUS, "scaleBottomRadius");
427 mSliders.at(1).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(1));
429 SetupSlider(2, 0.0f, 32.0f, DEFAULT_SCALE_TOP_RADIUS, PrimitiveVisual::Property::SCALE_TOP_RADIUS, "scaleTopRadius");
430 mSliders.at(2).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(1));
432 //Set model in control.
433 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
436 mShapeTitle.SetProperty(TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Conical Frustum");
439 //Sets the 3D model to a cylinder and modifies the sliders appropriately.
442 InitialiseSlidersAndModel();
444 //Set up specific visual properties.
445 mVisualMap[PrimitiveVisual::Property::SHAPE] = PrimitiveVisual::Shape::CYLINDER;
446 mVisualMap[PrimitiveVisual::Property::SCALE_HEIGHT] = DEFAULT_SCALE_HEIGHT;
447 mVisualMap[PrimitiveVisual::Property::SCALE_RADIUS] = DEFAULT_SCALE_RADIUS;
448 mVisualMap[PrimitiveVisual::Property::SLICES] = DEFAULT_SLICES;
450 //Set up used sliders.
451 SetupSlider(0, 1.0f, 32.0f, DEFAULT_SCALE_HEIGHT, PrimitiveVisual::Property::SCALE_HEIGHT, "scaleHeight");
452 mSliders.at(0).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(1));
454 SetupSlider(1, 1.0f, 32.0f, DEFAULT_SCALE_RADIUS, PrimitiveVisual::Property::SCALE_RADIUS, "scaleRadius");
455 mSliders.at(1).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(1));
457 SetupSlider(2, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND, DEFAULT_STACKS, PrimitiveVisual::Property::SLICES, "slices");
458 SetupMarks(2, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND);
459 mSliders.at(2).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(0));
461 //Set model in control.
462 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
465 mShapeTitle.SetProperty(TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Cylinder");
468 //Sets the 3D model to a cube and modifies the sliders appropriately.
471 InitialiseSlidersAndModel();
473 //Set up specific visual properties.
474 mVisualMap[PrimitiveVisual::Property::SHAPE] = PrimitiveVisual::Shape::CUBE;
476 //Set model in control.
477 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
480 mShapeTitle.SetProperty(TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Cube");
483 //Sets the 3D model to a bevelled cube and modifies the sliders appropriately.
484 void LoadBevelledCube()
486 InitialiseSlidersAndModel();
488 //Set up specific visual properties.
489 mVisualMap[PrimitiveVisual::Property::SHAPE] = PrimitiveVisual::Shape::BEVELLED_CUBE;
490 mVisualMap[PrimitiveVisual::Property::BEVEL_PERCENTAGE] = DEFAULT_BEVEL_PERCENTAGE;
491 mVisualMap[PrimitiveVisual::Property::BEVEL_SMOOTHNESS] = DEFAULT_BEVEL_SMOOTHNESS;
493 //Set up used sliders.
494 SetupSlider(0, 0.0f, 1.0f, DEFAULT_BEVEL_PERCENTAGE, PrimitiveVisual::Property::BEVEL_PERCENTAGE, "bevelPercentage");
495 mSliders.at(0).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(2));
497 SetupSlider(1, 0.0f, 1.0f, DEFAULT_BEVEL_SMOOTHNESS, PrimitiveVisual::Property::BEVEL_SMOOTHNESS, "bevelSmoothness");
498 mSliders.at(1).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(2));
500 //Set model in control.
501 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
504 mShapeTitle.SetProperty(TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Bevelled Cube");
507 //Sets the 3D model to an octahedron and modifies the sliders appropriately.
508 void LoadOctahedron()
510 InitialiseSlidersAndModel();
512 //Set up specific visual properties.
513 mVisualMap[PrimitiveVisual::Property::SHAPE] = PrimitiveVisual::Shape::OCTAHEDRON;
515 //Set model in control.
516 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
519 mShapeTitle.SetProperty(TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Octahedron");
522 //Sets up the slider at the given index for the supplied property, and labels it appropriately.
523 // visualProperty is the property that will be set by this slider.
524 void SetupSlider(int sliderIndex, float lowerBound, float upperBound, float startPoint, Property::Index visualProperty, std::string visualPropertyLabel)
526 //Set up the slider itself.
527 mSliders.at(sliderIndex).RegisterProperty("visualProperty", Property::Value(visualProperty), Property::READ_WRITE);
528 mSliders.at(sliderIndex).SetProperty(Slider::Property::LOWER_BOUND, Property::Value(lowerBound));
529 mSliders.at(sliderIndex).SetProperty(Slider::Property::UPPER_BOUND, Property::Value(upperBound));
530 mSliders.at(sliderIndex).SetProperty(Slider::Property::VALUE, Property::Value(startPoint));
531 mSliders.at(sliderIndex).SetProperty(Actor::Property::VISIBLE, true);
533 //Label the slider with the property.
534 //We reset the TextLabel to force a relayout of the table.
535 mSliderTable.RemoveChildAt(TableView::CellPosition(sliderIndex, 0));
537 TextLabel sliderLabel = TextLabel::New(visualPropertyLabel);
538 sliderLabel.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
539 sliderLabel.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
540 sliderLabel.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
542 mSliderTable.AddChild(sliderLabel, TableView::CellPosition(sliderIndex, 0));
543 mSliderTable.SetCellAlignment(TableView::CellPosition(sliderIndex, 0), HorizontalAlignment::LEFT, VerticalAlignment::CENTER);
545 mSliderLabels.at(sliderIndex).SetProperty(Actor::Property::VISIBLE, true);
546 mSliderLabels.at(sliderIndex) = sliderLabel;
549 //Setup snapping to integer values between the two given values.
550 void SetupMarks(int sliderIndex, int lower, int upper)
552 Property::Array marks;
554 for(int mark = lower; mark <= upper; mark++)
556 marks.PushBack(Property::Value(mark));
559 mSliders.at(sliderIndex).SetProperty(Slider::Property::MARKS, Property::Value(marks));
560 mSliders.at(sliderIndex).SetProperty(Slider::Property::SNAP_TO_MARKS, Property::Value(true));
563 //When a shape button is tapped, switch to the corresponding shape.
564 bool OnChangeShapeClicked(Button button)
566 //Get the model number from the button.
568 button.GetProperty(button.GetPropertyIndex("modelNumber")).Get(modelNumber);
570 //Switch to the shape that corresponds to the model number.
585 LoadConicalFrustum();
613 //When the slider is adjusted, change the corresponding shape property accordingly.
614 bool OnSliderValueChanged(Slider slider, float value)
616 //Update property map to reflect the change to the specific visual property.
618 slider.GetProperty(slider.GetPropertyIndex("visualProperty")).Get(visualProperty);
619 mVisualMap[visualProperty] = value;
621 //Reload the model to display the change.
622 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
627 //Panning around the shape rotates it.
628 void OnPan(Actor actor, const PanGesture& gesture)
630 switch(gesture.GetState())
632 case GestureState::STARTED:
634 //Pause animation, as the gesture will be used to manually rotate the model
635 mRotationAnimation.Pause();
639 case GestureState::CONTINUING:
641 //Rotate based off the gesture.
642 const Vector2& displacement = gesture.GetDisplacement();
643 mRotation.x -= displacement.y / X_ROTATION_DISPLACEMENT_FACTOR; // Y displacement rotates around X axis
644 mRotation.y += displacement.x / Y_ROTATION_DISPLACEMENT_FACTOR; // X displacement rotates around Y axis
645 Quaternion rotation = Quaternion(Radian(mRotation.x), Vector3::XAXIS) *
646 Quaternion(Radian(mRotation.y), Vector3::YAXIS);
648 mModel.SetProperty(Actor::Property::ORIENTATION, rotation);
652 case GestureState::FINISHED:
654 //Return to automatic animation
655 mRotationAnimation.Play();
659 case GestureState::CANCELLED:
661 //Return to automatic animation
662 mRotationAnimation.Play();
673 //If escape or the back button is pressed, quit the application (and return to the launcher)
674 void OnKeyEvent(const KeyEvent& event)
676 if(event.GetState() == KeyEvent::DOWN)
678 if(IsKey(event, DALI_KEY_ESCAPE) || IsKey(event, DALI_KEY_BACK))
686 Application& mApplication;
688 std::vector<Slider> mSliders; ///< Holds the sliders on screen that each shape accesses.
689 std::vector<TextLabel> mSliderLabels; ///< Holds the labels to each slider.
690 TableView mSliderTable; ///< A table to layout the sliders next to their labels.
692 Property::Map mVisualMap; ///< Property map to create a primitive visual.
693 Control mModel; ///< Control to house the primitive visual.
694 TextLabel mShapeTitle; ///< Indicates what the currently selected shape is.
696 PanGestureDetector mPanGestureDetector; ///< Detects pan gestures for rotation of the model.
697 Animation mRotationAnimation; ///< Automatically rotates the model, unless it is being panned.
699 Vector4 mColor; ///< Color to set all shapes.
700 Vector2 mRotation; ///< Keeps track of model rotation.
703 int DALI_EXPORT_API main(int argc, char** argv)
705 Application application = Application::New(&argc, &argv);
706 PrimitiveShapesController test(application);
707 application.MainLoop();