2 * Copyright (c) 2021 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))
72 // Connect to the Application's Init signal
73 mApplication.InitSignal().Connect(this, &PrimitiveShapesController::Create);
76 ~PrimitiveShapesController()
80 // The Init signal is received once (only) during the Application lifetime
81 void Create(Application& application)
83 // Get a handle to the window
84 Window window = application.GetWindow();
85 window.SetBackgroundColor(Color::WHITE);
87 //Set up layer to place UI on.
88 Layer layer = Layer::New();
89 layer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
90 layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
91 layer.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
92 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.
93 layer.SetProperty(Layer::Property::DEPTH_TEST, true); //Enable depth testing, as otherwise the 2D layer would not do so.
96 //Set up model selection buttons.
99 //Set up model parameter sliders.
105 //Allow for exiting of the application via key presses.
106 window.KeyEventSignal().Connect(this, &PrimitiveShapesController::OnKeyEvent);
109 //Place buttons on the top of the screen, which allow for selection of the shape to be displayed.
110 //A title above indicates the currently selected shape.
111 //The buttons are laid out like so:
113 // ^ +--------------------------------+
114 // | | Current Shape: ~~~~~ |
116 // | | +----+ +----+ +----+ +----+ |
117 // | | | | | | | | | | |
118 // 30% | | +----+ +----+ +----+ +----+ |
120 // | | +----+ +----+ +----+ |
122 // v | +----+ +----+ +----+ |
141 // +--------------------------------+
143 void SetupButtons(Layer layer)
145 float containerPadding = 10.0f;
146 float elementPadding = 5.0f;
148 //Used to layout the title and the buttons below it.
149 Control topAlignment = Control::New();
150 topAlignment.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
151 topAlignment.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
152 topAlignment.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
153 topAlignment.SetResizePolicy(ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT);
154 layer.Add(topAlignment);
156 //Add a title to indicate the currently selected shape.
157 mShapeTitle = TextLabel::New("DEFAULT");
158 mShapeTitle.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
159 mShapeTitle.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
160 mShapeTitle.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
161 mShapeTitle.SetProperty(Actor::Property::PADDING, Padding(elementPadding, elementPadding, elementPadding, elementPadding));
162 topAlignment.Add(mShapeTitle);
164 //Create a variable-length container that can wrap buttons around as more are added.
165 FlexContainer buttonContainer = FlexContainer::New();
166 buttonContainer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER);
167 buttonContainer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
168 buttonContainer.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
169 buttonContainer.SetResizePolicy(ResizePolicy::FIXED, Dimension::HEIGHT);
170 buttonContainer.SetProperty(Actor::Property::PADDING, Padding(containerPadding, containerPadding, containerPadding, containerPadding));
171 buttonContainer.SetProperty(FlexContainer::Property::FLEX_DIRECTION, FlexContainer::ROW);
172 buttonContainer.SetProperty(FlexContainer::Property::FLEX_WRAP, FlexContainer::WRAP);
173 topAlignment.Add(buttonContainer);
175 //Create buttons and place them in the container.
176 for(int modelNumber = 0; modelNumber < NUM_MODELS; modelNumber++)
178 PushButton button = Toolkit::PushButton::New();
179 button.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
180 button.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
181 button.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
182 button.SetProperty(Actor::Property::PADDING, Padding(elementPadding, elementPadding, elementPadding, elementPadding));
183 button.SetProperty(Button::Property::UNSELECTED_BACKGROUND_VISUAL, BUTTON_IMAGE_URL[modelNumber]);
184 button.SetProperty(Button::Property::SELECTED_BACKGROUND_VISUAL, BUTTON_IMAGE_URL[modelNumber]);
185 button.RegisterProperty("modelNumber", Property::Value(modelNumber));
186 button.ClickedSignal().Connect(this, &PrimitiveShapesController::OnChangeShapeClicked);
188 buttonContainer.Add(button);
192 //Add sliders to the bottom of the screen, which allow for control of shape properties such as radius.
193 //Each slider is placed next to a label that states the property it affects.
194 //The sliders are laid out like so:
196 // +--------------------------------+
216 // ^ | Label +----------O-----------+ |
219 // | | Label +--O-------------------+ |
222 // | | Label +----------------------O |
224 // v +--------------------------------+
226 void SetupSliders(Layer layer)
228 //Create table to hold sliders and their corresponding labels.
229 mSliderTable = Toolkit::TableView::New(MAX_PROPERTIES, 2);
230 mSliderTable.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER);
231 mSliderTable.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER);
232 mSliderTable.SetResizePolicy(ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS);
233 mSliderTable.SetProperty(Actor::Property::SIZE_MODE_FACTOR, Vector3(0.9, 0.3, 0.0)); //90% of width, 30% of height.
234 mSliderTable.SetFitWidth(0); //Label column should fit to natural size of label.
235 mSliderTable.SetRelativeWidth(1, 1.0f); //Slider column should fill remaining space.
236 mSliderTable.SetCellPadding(Vector2(10.0f, 0.0f)); //Leave a gap between the slider and its label.
237 layer.Add(mSliderTable);
239 //Set up sliders, and place labels next to them.
240 for(int i = 0; i < MAX_PROPERTIES; i++)
243 Slider slider = Slider::New();
244 slider.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
245 slider.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
246 slider.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
247 slider.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT);
248 slider.ValueChangedSignal().Connect(this, &PrimitiveShapesController::OnSliderValueChanged);
249 mSliders.push_back(slider);
251 //Setup slider cell properties
252 mSliderTable.AddChild(slider, TableView::CellPosition(i, 1));
253 mSliderTable.SetCellAlignment(TableView::CellPosition(i, 1), HorizontalAlignment::CENTER, VerticalAlignment::CENTER);
255 //Create slider label
256 TextLabel sliderLabel = TextLabel::New();
257 sliderLabel.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
258 sliderLabel.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
259 sliderLabel.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
260 mSliderLabels.push_back(sliderLabel);
262 //Setup slider-label cell properties
263 mSliderTable.AddChild(sliderLabel, TableView::CellPosition(i, 0));
264 mSliderTable.SetCellAlignment(TableView::CellPosition(i, 0), HorizontalAlignment::LEFT, VerticalAlignment::CENTER);
268 //Adds a control to the centre of the window to display the 3D shapes.
269 //The model is placed in the center of the screen, like so:
271 // +--------------------------------+
299 // +--------------------------------+
301 void SetupModel(Layer layer)
303 //Create a container to house the visual-holding actor, to provide a constant hitbox.
304 Actor container = Actor::New();
305 container.SetResizePolicy(ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS);
306 container.SetProperty(Actor::Property::SIZE_MODE_FACTOR, Vector3(0.9, 0.3, 0.0)); //90% of width, 30% of height.
307 container.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
308 container.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
309 layer.Add(container);
311 //Create control to display the 3D primitive.
312 mModel = Control::New();
313 mModel.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
314 mModel.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
315 mModel.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
316 container.Add(mModel);
318 //Load default shape.
321 //Make model spin to demonstrate 3D.
322 mRotationAnimation = Animation::New(15.0f);
323 mRotationAnimation.AnimateBy(Property(mModel, Actor::Property::ORIENTATION),
324 Quaternion(Degree(0.0f), Degree(360.0f), Degree(0.0f)));
325 mRotationAnimation.SetLooping(true);
326 mRotationAnimation.Play();
328 //Attach gesture detector to pan models when rotated.
329 mPanGestureDetector = PanGestureDetector::New();
330 mPanGestureDetector.Attach(container);
331 mPanGestureDetector.DetectedSignal().Connect(this, &PrimitiveShapesController::OnPan);
334 //Clears all sliders and resets the primitive visual property map.
335 void InitialiseSlidersAndModel()
338 for(unsigned i = 0; i < mSliders.size(); i++)
340 mSliders.at(i).SetProperty(Slider::Property::MARKS, Property::Value(0)); //Remove marks
341 mSliders.at(i).SetProperty(Actor::Property::VISIBLE, false);
342 mSliderLabels.at(i).SetProperty(TextLabel::Property::TEXT, Property::Value("Default"));
343 mSliderLabels.at(i).SetProperty(Actor::Property::VISIBLE, false);
346 //Visual map for model
348 mVisualMap[Toolkit::Visual::Property::TYPE] = Visual::PRIMITIVE;
349 mVisualMap[PrimitiveVisual::Property::MIX_COLOR] = mColor;
350 mVisualMap[Visual::Property::TRANSFORM] =
351 Property::Map().Add(Visual::Transform::Property::ORIGIN, Align::CENTER).Add(Visual::Transform::Property::ANCHOR_POINT, Align::CENTER);
354 //Sets the 3D model to a sphere and modifies the sliders appropriately.
357 InitialiseSlidersAndModel();
359 //Set up specific visual properties.
360 mVisualMap[PrimitiveVisual::Property::SHAPE] = PrimitiveVisual::Shape::SPHERE;
361 mVisualMap[PrimitiveVisual::Property::SLICES] = DEFAULT_SLICES;
362 mVisualMap[PrimitiveVisual::Property::STACKS] = DEFAULT_STACKS;
365 SetupSlider(0, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND, DEFAULT_STACKS, PrimitiveVisual::Property::SLICES, "slices");
366 SetupMarks(0, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND);
367 mSliders.at(0).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(0));
369 SetupSlider(1, STACKS_LOWER_BOUND, STACKS_UPPER_BOUND, DEFAULT_STACKS, PrimitiveVisual::Property::STACKS, "stacks");
370 SetupMarks(1, STACKS_LOWER_BOUND, STACKS_UPPER_BOUND);
371 mSliders.at(1).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(0));
373 //Set model in control.
374 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
377 mShapeTitle.SetProperty(TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Sphere");
380 //Sets the 3D model to a cone and modifies the sliders appropriately.
383 InitialiseSlidersAndModel();
385 //Set up specific visual properties.
386 mVisualMap[PrimitiveVisual::Property::SHAPE] = PrimitiveVisual::Shape::CONE;
387 mVisualMap[PrimitiveVisual::Property::SCALE_HEIGHT] = DEFAULT_SCALE_HEIGHT;
388 mVisualMap[PrimitiveVisual::Property::SCALE_BOTTOM_RADIUS] = DEFAULT_SCALE_BOTTOM_RADIUS;
389 mVisualMap[PrimitiveVisual::Property::SLICES] = DEFAULT_SLICES;
392 SetupSlider(0, 1.0f, 32.0f, DEFAULT_SCALE_HEIGHT, PrimitiveVisual::Property::SCALE_HEIGHT, "scaleHeight");
393 mSliders.at(0).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(1));
395 SetupSlider(1, 1.0f, 32.0f, DEFAULT_SCALE_BOTTOM_RADIUS, PrimitiveVisual::Property::SCALE_BOTTOM_RADIUS, "scaleBottomRadius");
396 mSliders.at(1).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(1));
398 SetupSlider(2, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND, DEFAULT_STACKS, PrimitiveVisual::Property::SLICES, "slices");
399 SetupMarks(2, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND);
400 mSliders.at(2).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(0));
402 //Set model in control.
403 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
406 mShapeTitle.SetProperty(TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Cone");
409 //Sets the 3D model to a conical frustum and modifies the sliders appropriately.
410 void LoadConicalFrustum()
412 InitialiseSlidersAndModel();
414 //Set up specific visual properties.
415 mVisualMap[PrimitiveVisual::Property::SHAPE] = PrimitiveVisual::Shape::CONICAL_FRUSTUM;
416 mVisualMap[PrimitiveVisual::Property::SCALE_TOP_RADIUS] = DEFAULT_SCALE_TOP_RADIUS;
417 mVisualMap[PrimitiveVisual::Property::SCALE_BOTTOM_RADIUS] = DEFAULT_SCALE_BOTTOM_RADIUS;
418 mVisualMap[PrimitiveVisual::Property::SCALE_HEIGHT] = DEFAULT_SCALE_HEIGHT;
419 mVisualMap[PrimitiveVisual::Property::SLICES] = DEFAULT_SLICES;
421 //Set up used sliders.
422 SetupSlider(0, 1.0f, 32.0f, DEFAULT_SCALE_HEIGHT, PrimitiveVisual::Property::SCALE_HEIGHT, "scaleHeight");
423 mSliders.at(0).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(1));
425 SetupSlider(1, 0.0f, 32.0f, DEFAULT_SCALE_BOTTOM_RADIUS, PrimitiveVisual::Property::SCALE_BOTTOM_RADIUS, "scaleBottomRadius");
426 mSliders.at(1).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(1));
428 SetupSlider(2, 0.0f, 32.0f, DEFAULT_SCALE_TOP_RADIUS, PrimitiveVisual::Property::SCALE_TOP_RADIUS, "scaleTopRadius");
429 mSliders.at(2).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(1));
431 //Set model in control.
432 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
435 mShapeTitle.SetProperty(TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Conical Frustum");
438 //Sets the 3D model to a cylinder and modifies the sliders appropriately.
441 InitialiseSlidersAndModel();
443 //Set up specific visual properties.
444 mVisualMap[PrimitiveVisual::Property::SHAPE] = PrimitiveVisual::Shape::CYLINDER;
445 mVisualMap[PrimitiveVisual::Property::SCALE_HEIGHT] = DEFAULT_SCALE_HEIGHT;
446 mVisualMap[PrimitiveVisual::Property::SCALE_RADIUS] = DEFAULT_SCALE_RADIUS;
447 mVisualMap[PrimitiveVisual::Property::SLICES] = DEFAULT_SLICES;
449 //Set up used sliders.
450 SetupSlider(0, 1.0f, 32.0f, DEFAULT_SCALE_HEIGHT, PrimitiveVisual::Property::SCALE_HEIGHT, "scaleHeight");
451 mSliders.at(0).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(1));
453 SetupSlider(1, 1.0f, 32.0f, DEFAULT_SCALE_RADIUS, PrimitiveVisual::Property::SCALE_RADIUS, "scaleRadius");
454 mSliders.at(1).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(1));
456 SetupSlider(2, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND, DEFAULT_STACKS, PrimitiveVisual::Property::SLICES, "slices");
457 SetupMarks(2, SLICES_LOWER_BOUND, SLICES_UPPER_BOUND);
458 mSliders.at(2).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(0));
460 //Set model in control.
461 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
464 mShapeTitle.SetProperty(TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Cylinder");
467 //Sets the 3D model to a cube and modifies the sliders appropriately.
470 InitialiseSlidersAndModel();
472 //Set up specific visual properties.
473 mVisualMap[PrimitiveVisual::Property::SHAPE] = PrimitiveVisual::Shape::CUBE;
475 //Set model in control.
476 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
479 mShapeTitle.SetProperty(TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Cube");
482 //Sets the 3D model to a bevelled cube and modifies the sliders appropriately.
483 void LoadBevelledCube()
485 InitialiseSlidersAndModel();
487 //Set up specific visual properties.
488 mVisualMap[PrimitiveVisual::Property::SHAPE] = PrimitiveVisual::Shape::BEVELLED_CUBE;
489 mVisualMap[PrimitiveVisual::Property::BEVEL_PERCENTAGE] = DEFAULT_BEVEL_PERCENTAGE;
490 mVisualMap[PrimitiveVisual::Property::BEVEL_SMOOTHNESS] = DEFAULT_BEVEL_SMOOTHNESS;
492 //Set up used sliders.
493 SetupSlider(0, 0.0f, 1.0f, DEFAULT_BEVEL_PERCENTAGE, PrimitiveVisual::Property::BEVEL_PERCENTAGE, "bevelPercentage");
494 mSliders.at(0).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(2));
496 SetupSlider(1, 0.0f, 1.0f, DEFAULT_BEVEL_SMOOTHNESS, PrimitiveVisual::Property::BEVEL_SMOOTHNESS, "bevelSmoothness");
497 mSliders.at(1).SetProperty(Slider::Property::VALUE_PRECISION, Property::Value(2));
499 //Set model in control.
500 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
503 mShapeTitle.SetProperty(TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Bevelled Cube");
506 //Sets the 3D model to an octahedron and modifies the sliders appropriately.
507 void LoadOctahedron()
509 InitialiseSlidersAndModel();
511 //Set up specific visual properties.
512 mVisualMap[PrimitiveVisual::Property::SHAPE] = PrimitiveVisual::Shape::OCTAHEDRON;
514 //Set model in control.
515 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
518 mShapeTitle.SetProperty(TextLabel::Property::TEXT, SHAPE_TITLE_PREFIX + "Octahedron");
521 //Sets up the slider at the given index for the supplied property, and labels it appropriately.
522 // visualProperty is the property that will be set by this slider.
523 void SetupSlider(int sliderIndex, float lowerBound, float upperBound, float startPoint, Property::Index visualProperty, std::string visualPropertyLabel)
525 //Set up the slider itself.
526 mSliders.at(sliderIndex).RegisterProperty("visualProperty", Property::Value(visualProperty), Property::READ_WRITE);
527 mSliders.at(sliderIndex).SetProperty(Slider::Property::LOWER_BOUND, Property::Value(lowerBound));
528 mSliders.at(sliderIndex).SetProperty(Slider::Property::UPPER_BOUND, Property::Value(upperBound));
529 mSliders.at(sliderIndex).SetProperty(Slider::Property::VALUE, Property::Value(startPoint));
530 mSliders.at(sliderIndex).SetProperty(Actor::Property::VISIBLE, true);
532 //Label the slider with the property.
533 //We reset the TextLabel to force a relayout of the table.
534 mSliderTable.RemoveChildAt(TableView::CellPosition(sliderIndex, 0));
536 TextLabel sliderLabel = TextLabel::New(visualPropertyLabel);
537 sliderLabel.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
538 sliderLabel.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
539 sliderLabel.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
541 mSliderTable.AddChild(sliderLabel, TableView::CellPosition(sliderIndex, 0));
542 mSliderTable.SetCellAlignment(TableView::CellPosition(sliderIndex, 0), HorizontalAlignment::LEFT, VerticalAlignment::CENTER);
544 mSliderLabels.at(sliderIndex).SetProperty(Actor::Property::VISIBLE, true);
545 mSliderLabels.at(sliderIndex) = sliderLabel;
548 //Setup snapping to integer values between the two given values.
549 void SetupMarks(int sliderIndex, int lower, int upper)
551 Property::Array marks;
553 for(int mark = lower; mark <= upper; mark++)
555 marks.PushBack(Property::Value(mark));
558 mSliders.at(sliderIndex).SetProperty(Slider::Property::MARKS, Property::Value(marks));
559 mSliders.at(sliderIndex).SetProperty(Slider::Property::SNAP_TO_MARKS, Property::Value(true));
562 //When a shape button is tapped, switch to the corresponding shape.
563 bool OnChangeShapeClicked(Button button)
565 //Get the model number from the button.
567 button.GetProperty(button.GetPropertyIndex("modelNumber")).Get(modelNumber);
569 //Switch to the shape that corresponds to the model number.
584 LoadConicalFrustum();
612 //When the slider is adjusted, change the corresponding shape property accordingly.
613 bool OnSliderValueChanged(Slider slider, float value)
615 //Update property map to reflect the change to the specific visual property.
617 slider.GetProperty(slider.GetPropertyIndex("visualProperty")).Get(visualProperty);
618 mVisualMap[visualProperty] = value;
620 //Reload the model to display the change.
621 mModel.SetProperty(Control::Property::BACKGROUND, Property::Value(mVisualMap));
626 //Panning around the shape rotates it.
627 void OnPan(Actor actor, const PanGesture& gesture)
629 switch(gesture.GetState())
631 case GestureState::STARTED:
633 //Pause animation, as the gesture will be used to manually rotate the model
634 mRotationAnimation.Pause();
638 case GestureState::CONTINUING:
640 //Rotate based off the gesture.
641 Vector2 displacement = gesture.GetDisplacement();
643 -displacement.y / X_ROTATION_DISPLACEMENT_FACTOR, // Y displacement rotates around X axis
644 displacement.x / Y_ROTATION_DISPLACEMENT_FACTOR // X displacement rotates around Y axis
647 Quaternion q = Quaternion(Radian(rotation.x), Radian(rotation.y), Radian(0.f));
648 Quaternion q0 = mModel.GetProperty(Actor::Property::ORIENTATION).Get<Quaternion>();
650 mModel.SetProperty(Actor::Property::ORIENTATION, q * q0);
654 case GestureState::FINISHED:
656 //Return to automatic animation
657 mRotationAnimation.Play();
661 case GestureState::CANCELLED:
663 //Return to automatic animation
664 mRotationAnimation.Play();
675 //If escape or the back button is pressed, quit the application (and return to the launcher)
676 void OnKeyEvent(const KeyEvent& event)
678 if(event.GetState() == KeyEvent::DOWN)
680 if(IsKey(event, DALI_KEY_ESCAPE) || IsKey(event, DALI_KEY_BACK))
688 Application& mApplication;
690 std::vector<Slider> mSliders; ///< Holds the sliders on screen that each shape accesses.
691 std::vector<TextLabel> mSliderLabels; ///< Holds the labels to each slider.
692 TableView mSliderTable; ///< A table to layout the sliders next to their labels.
694 Property::Map mVisualMap; ///< Property map to create a primitive visual.
695 Control mModel; ///< Control to house the primitive visual.
696 TextLabel mShapeTitle; ///< Indicates what the currently selected shape is.
698 PanGestureDetector mPanGestureDetector; ///< Detects pan gestures for rotation of the model.
699 Animation mRotationAnimation; ///< Automatically rotates the model, unless it is being panned.
701 Vector4 mColor; ///< Color to set all shapes.
704 int DALI_EXPORT_API main(int argc, char** argv)
706 Application application = Application::New(&argc, &argv, DEMO_THEME_PATH);
707 PrimitiveShapesController test(application);
708 application.MainLoop();