1 #include <dali-toolkit/dali-toolkit.h>
2 #include <dali-toolkit/devel-api/controls/table-view/table-view.h>
6 using namespace Dali::Toolkit;
10 const char* DEMO_THEME_TWO_PATH(DEMO_STYLE_DIR "style-example-theme-two.json");
12 const std::string images[5] =
14 DEMO_IMAGE_DIR "application-icon-97.png",
15 DEMO_IMAGE_DIR "application-icon-84.png",
16 DEMO_IMAGE_DIR "application-icon-76.png",
17 DEMO_IMAGE_DIR "application-icon-69.png",
18 DEMO_IMAGE_DIR "application-icon-72.png",
21 const char* BORDER_IMAGE(DEMO_IMAGE_DIR "border-4px.9.png");
22 const char* RESIZE_HANDLE_IMAGE(DEMO_IMAGE_DIR "resize-handle.png");
23 const char* CIRCLE_POINT(DEMO_IMAGE_DIR "circle_point.png");
24 const char* CIRCLE_STROKE(DEMO_IMAGE_DIR "circle_stroke_point.png");
26 const int BORDER_WIDTH(4);
30 struct CameraPosConstraint
32 CameraPosConstraint() = default;
34 void operator()(Vector3& current, const PropertyInputContainer& inputs)
36 auto& newPos = inputs[0]->GetVector3();
42 struct BoundaryConstraint
44 BoundaryConstraint(std::string name, Vector2 size, bool centered)
50 void operator()(Vector3& current, const PropertyInputContainer& inputs)
52 Vector3 curPos = inputs[0]->GetVector3();
53 Vector3 curSize = inputs[1]->GetVector3();
57 // AnchorPoint is center of actor
58 current.x = std::clamp(curPos.x, 0.0f, boundarySize.x);
59 current.y = std::clamp(curPos.y, 0.0f, boundarySize.y);
63 // Anchor point is top left of actor.
64 current.x = std::clamp(curPos.x, 0.0f, boundarySize.x - curSize.x);
65 current.y = std::clamp(curPos.y, 0.0f, boundarySize.y - curSize.y);
74 struct ViewportPositionConstraint
76 ViewportPositionConstraint(Vector2 windowOrigin)
77 : origin(windowOrigin)
80 void operator()(Vector2& current, const PropertyInputContainer& inputs)
82 Vector3 framePos = inputs[0]->GetVector3();
83 current.x = framePos.x + origin.x;
84 current.y = framePos.y + origin.y;
89 struct ViewportSizeConstraint
91 ViewportSizeConstraint() = default;
93 void operator()(Vector2& current, const PropertyInputContainer& inputs)
95 Vector3 frameSize = inputs[0]->GetVector3();
96 current.x = frameSize.x;
97 current.y = frameSize.y;
101 class CameraTestExample : public ConnectionTracker
104 CameraTestExample(Application app)
107 mApp.InitSignal().Connect(this, &CameraTestExample::OnCreate);
110 void OnCreate(Application& app)
112 // Use default camera.
113 Window window = app.GetWindow();
114 Vector2 windowSize(1280, 800);
115 if(window.GetSize().GetWidth() < 1280)
117 window.SetSize(Uint16Pair(windowSize.x, windowSize.y)); // 1280 divides into 427, 427, 426
121 windowSize.x = window.GetSize().GetWidth();
122 windowSize.y = window.GetSize().GetHeight();
125 window.KeyEventSignal().Connect(this, &CameraTestExample::OnKeyEvent);
127 // Divide the screen up into 3 regions:
128 // left: the scene + camera outline
130 // right: actor / camera controls
132 // Viewport frame position is constrained to the mid third, but is actually drawn into full screen overlay.
133 // Camera frame position is constrained to the left third, but is actually drawn into full screen overlay.
135 Vector2 sceneSize = Vector2(ceilf(windowSize.x / 3.0f), 720);
136 Vector2 panelSize = Vector2(ceilf(windowSize.x / 3.0f), windowSize.y);
138 viewLayer = CreateScene(window, Vector2::ZERO, sceneSize);
140 sceneRenderTask = CreateSceneRenderTask(window, viewLayer, sceneSize);
142 Layer overlayLayer = Layer::New(); // Will be drawn last by separate render tasks
143 window.Add(overlayLayer);
144 overlayLayer.SetProperty(Actor::Property::POSITION, Vector3::ZERO);
145 overlayLayer.SetProperty(Actor::Property::SIZE, windowSize);
146 overlayLayer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
147 overlayLayer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
149 overlayRenderTask = CreateOverlayRenderTask(window, windowSize, overlayLayer);
151 // Create camera frame
152 initialCameraSize = Vector3(windowSize.x / 3.0f, windowSize.y, 1);
153 initialCameraPosition = Vector3(windowSize.x / 6.0f, windowSize.y * 0.5f, 0);
155 cameraFrame = CreateFrame(Vector2(initialCameraSize), sceneSize, "Camera");
156 cameraFrame.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
157 cameraFrame.SetProperty(Actor::Property::POSITION, initialCameraPosition);
159 cameraGrabHandle = CreateCornerHandle(cameraFrame);
160 cameraGrabCenter = CreateCenterHandle(cameraFrame);
162 // Create viewport frame
163 initialViewportSize = sceneSize * 0.75f; // Maintain aspect ratio
164 initialViewportPosition = Vector3(100, 100, 0);
166 viewportFrame = CreateFrame(Vector2(initialViewportPosition), Vector2(initialViewportSize), "Viewport");
167 viewportFrame.SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(1.0f / 3.0f, 0.0f, 0.5f)); // TL of 2nd third of screen
168 viewportFrame.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
170 viewportGrabHandle = CreateCornerHandle(viewportFrame);
171 viewportGrabCenter = CreateCenterHandle(viewportFrame);
173 Vector2 viewportOrigin(windowSize.x / 3.0f, 0.0f); // Viewport origin in window coords (to match frame)
174 ConstrainSceneViewportCamera(sceneRenderTask, viewportOrigin);
176 Constraint constraint = Constraint::New<Vector3>(cameraFrame, Actor::Property::POSITION, BoundaryConstraint("cameraFrame", panelSize, true));
177 constraint.AddSource(LocalSource(Actor::Property::POSITION));
178 constraint.AddSource(LocalSource(Actor::Property::SIZE));
181 constraint = Constraint::New<Vector3>(viewportFrame, Actor::Property::POSITION, BoundaryConstraint("viewportFrame", panelSize, false));
182 constraint.AddSource(LocalSource(Actor::Property::POSITION));
183 constraint.AddSource(LocalSource(Actor::Property::SIZE));
186 overlayLayer.Add(viewportFrame);
187 overlayLayer.Add(cameraFrame);
189 CreateActorControls(overlayLayer, panelSize);
191 mPanGestureDetector = PanGestureDetector::New();
192 mPanGestureDetector.Attach(viewportGrabHandle);
193 mPanGestureDetector.Attach(viewportGrabCenter);
194 mPanGestureDetector.Attach(cameraGrabHandle);
195 mPanGestureDetector.Attach(cameraGrabCenter);
196 mPanGestureDetector.DetectedSignal().Connect(this, &CameraTestExample::OnPan);
198 mTapGestureDetector = TapGestureDetector::New(2);
199 mTapGestureDetector.Attach(viewportGrabHandle);
200 mTapGestureDetector.Attach(viewportGrabCenter);
201 mTapGestureDetector.Attach(cameraGrabHandle);
202 mTapGestureDetector.Attach(cameraGrabCenter);
203 mTapGestureDetector.DetectedSignal().Connect(this, &CameraTestExample::OnDoubleTap);
206 Layer CreateScene(Window window, Vector2 position, Vector2 size)
208 const Vector3 offsets[] =
210 Dali::ParentOrigin::TOP_LEFT,
211 Dali::ParentOrigin::TOP_RIGHT,
212 Dali::ParentOrigin::BOTTOM_LEFT,
213 Dali::ParentOrigin::BOTTOM_RIGHT,
214 Dali::ParentOrigin::CENTER,
217 Layer viewLayer = Layer::New();
218 window.Add(viewLayer);
220 viewLayer.SetProperty(Actor::Property::POSITION, Vector3(position));
221 viewLayer.SetProperty(Actor::Property::SIZE, size);
222 viewLayer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER_LEFT);
223 viewLayer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER_LEFT);
225 auto bg = Control::New();
226 bg.SetBackgroundColor(Vector4(0.1, 0.0, 0.1, 0.5));
227 bg.SetProperty(Actor::Property::SIZE, size);
228 bg.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
229 bg.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
232 auto label = TextLabel::New("Scene");
233 label[TextLabel::Property::POINT_SIZE] = 12;
234 label[TextLabel::Property::HORIZONTAL_ALIGNMENT] = HorizontalAlignment::CENTER;
235 label[TextLabel::Property::TEXT_COLOR] = Color::WHITE;
236 label[Actor::Property::PARENT_ORIGIN] = ParentOrigin::TOP_CENTER;
237 label[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_CENTER;
238 viewLayer.Add(label);
241 for(auto& image : images)
243 auto imageView = ImageView::New(image);
244 imageViews.push_back(imageView);
245 viewLayer.Add(imageView);
247 printf("ActorId: %d\n", imageView.GetProperty<int>(Actor::Property::ID));
249 imageView.SetProperty(Actor::Property::PARENT_ORIGIN, offsets[i]);
250 imageView.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
251 imageView.SetProperty(Actor::Property::POSITION, Vector3((0.5f - offsets[i].x) * 50.0f, (0.5f - offsets[i].y) * 50.0f, 0.0f));
252 imageView.SetProperty(Actor::Property::SIZE, Vector2(97.0f, 97.0f));
258 void CreateActorControls(Layer parent, Vector2 sceneSize)
260 // Create a container that sits on the rightmost third of the window
261 Actor layoutContainer = Actor::New();
262 layoutContainer[Actor::Property::SIZE] = Vector3(sceneSize.x, sceneSize.y, sceneSize.x);
263 layoutContainer[Actor::Property::PARENT_ORIGIN] = ParentOrigin::TOP_RIGHT;
264 layoutContainer[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_RIGHT;
266 auto bg = Control::New();
267 bg.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
268 bg[Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
269 bg.SetBackgroundColor(Vector4(0.05f, 0.05f, 0.1f, 1.0f));
270 layoutContainer.Add(bg);
272 parent.Add(layoutContainer);
274 // Add a table for actor rotations
275 TableView actorProps = TableView::New(7, 2);
276 actorProps.SetProperty(Actor::Property::NAME, "ActorSliderLayout");
277 actorProps.SetProperty(Actor::Property::SIZE, Vector3(sceneSize.x, sceneSize.y, sceneSize.x));
278 actorProps.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
279 actorProps.SetFitWidth(0);
280 actorProps.SetResizePolicy(ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT);
283 for(auto& image : images)
285 actorProps.SetFitHeight(i);
287 auto icon = ImageView::New(image);
288 icon.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
289 // I would like 50% of natural size...
290 icon.SetProperty(Actor::Property::SIZE, Vector3(50, 50, 50));
291 actorProps.AddChild(icon, TableView::CellPosition(i, 0));
292 actorProps.SetCellAlignment(TableView::CellPosition(i, 0), HorizontalAlignment::CENTER, VerticalAlignment::CENTER);
293 auto slider = Slider::New();
294 std::ostringstream sliderStyleName;
295 sliderStyleName << "RotationSlider" << i + 1;
296 slider.SetProperty(Actor::Property::NAME, sliderStyleName.str());
297 slider.SetStyleName("ThinSlider");
298 slider.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
299 slider.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
300 slider.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
301 slider.SetResizePolicy(ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT);
302 slider.SetProperty(Slider::Property::LOWER_BOUND, -180.0f);
303 slider.SetProperty(Slider::Property::UPPER_BOUND, 180.0f);
304 slider.SetProperty(Slider::Property::VALUE_PRECISION, 0);
305 slider.SetProperty(Slider::Property::VALUE, 0.0f);
306 slider.SetProperty(Slider::Property::SHOW_POPUP, true);
307 slider.RegisterProperty("actorId", i, Property::READ_ONLY); // imageViews[i].GetId()
309 actorProps.AddChild(slider, TableView::CellPosition(i, 1));
310 actorProps.SetCellAlignment(TableView::CellPosition(i, 1), HorizontalAlignment::RIGHT, VerticalAlignment::CENTER);
311 slider.ValueChangedSignal().Connect(this, &CameraTestExample::OnRotationSliderChanged);
315 auto fovLabel = TextLabel::New("FOV");
316 fovLabel.SetProperty(TextLabel::Property::POINT_SIZE, 12);
317 fovLabel.SetProperty(TextLabel::Property::TEXT_COLOR, Color::WHITE);
318 fovLabel[TextLabel::Property::HORIZONTAL_ALIGNMENT] = HorizontalAlignment::CENTER;
319 fovLabel[Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
320 fovLabel[Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER;
321 actorProps.AddChild(fovLabel, TableView::CellPosition(i, 0));
323 auto slider = Slider::New();
324 slider.SetProperty(Actor::Property::NAME, "FOVSlider");
325 slider.SetStyleName("ThinSlider");
326 slider.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
327 slider.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
328 slider.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
329 slider.SetResizePolicy(ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT);
330 slider.SetProperty(Slider::Property::LOWER_BOUND, 1.0f);
331 slider.SetProperty(Slider::Property::UPPER_BOUND, 160.0f);
332 slider.SetProperty(Slider::Property::VALUE_PRECISION, 0);
333 slider.SetProperty(Slider::Property::VALUE, Degree(Radian(cameraActor.GetFieldOfView())).degree);
334 slider.SetProperty(Slider::Property::SHOW_POPUP, true);
335 slider.ValueChangedSignal().Connect(this, &CameraTestExample::OnFOVChanged);
336 actorProps.AddChild(slider, TableView::CellPosition(i, 1));
338 layoutContainer.Add(actorProps);
340 cameraDetail = TextLabel::New();
341 cameraDetail[TextLabel::Property::POINT_SIZE] = 10;
342 cameraDetail[TextLabel::Property::HORIZONTAL_ALIGNMENT] = HorizontalAlignment::CENTER;
343 cameraDetail[TextLabel::Property::MULTI_LINE] = true;
344 cameraDetail[TextLabel::Property::TEXT_COLOR] = Color::WHITE;
345 cameraDetail[Actor::Property::PARENT_ORIGIN] = ParentOrigin::BOTTOM_CENTER;
346 cameraDetail[Actor::Property::ANCHOR_POINT] = AnchorPoint::BOTTOM_CENTER;
348 cameraDetail[Actor::Property::POSITION] = Vector3(0.0f, -15.0f, 0.0f);
349 cameraDetail.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
350 cameraDetail.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT);
351 layoutContainer.Add(cameraDetail);
353 SetCameraDetailString();
356 RenderTask CreateSceneRenderTask(Window window, Layer source, Vector2 sceneSize)
358 // Create a render task with moveable viewport and camera
359 RenderTask renderTask = window.GetRenderTaskList().CreateTask();
361 cameraActor = CameraActor::New();
362 cameraActor.SetType(Camera::FREE_LOOK);
363 cameraActor.SetPerspectiveProjection(sceneSize);
364 window.Add(cameraActor);
366 renderTask.SetCameraActor(cameraActor);
367 renderTask.SetInputEnabled(false);
368 renderTask.SetClearColor(Vector4(0.05f, 0.05f, 0.05f, 1.0f));
369 renderTask.SetClearEnabled(true);
370 renderTask.SetSourceActor(source);
375 void ConstrainSceneViewportCamera(RenderTask sceneRenderTask, Vector2 viewportOrigin)
377 Constraint constraint = Constraint::New<Vector3>(cameraActor, Actor::Property::POSITION, CameraPosConstraint());
378 constraint.AddSource(Source(cameraFrame, Actor::Property::POSITION));
381 constraint = Constraint::New<Vector2>(cameraActor, Actor::Property::SIZE, EqualToConstraint());
382 constraint.AddSource(Source(cameraFrame, Actor::Property::SIZE));
385 constraint = Constraint::New<Vector2>(sceneRenderTask, RenderTask::Property::VIEWPORT_POSITION, ViewportPositionConstraint(viewportOrigin));
386 constraint.AddSource(Source(viewportFrame, Actor::Property::POSITION));
389 constraint = Constraint::New<Vector2>(sceneRenderTask, RenderTask::Property::VIEWPORT_SIZE, ViewportSizeConstraint());
390 constraint.AddSource(Source(viewportFrame, Actor::Property::SIZE));
394 RenderTask CreateOverlayRenderTask(Window window, Vector2 windowSize, Layer source)
396 // Create a separate camera / render task to visualize the input frames above the 2nd rendered layer above.
397 CameraActor overlayCameraActor = CameraActor::New();
398 overlayCameraActor.SetType(Camera::FREE_LOOK);
399 overlayCameraActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
400 overlayCameraActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
401 overlayCameraActor.SetProperty(Actor::Property::POSITION, Vector2::ZERO);
402 overlayCameraActor.SetProperty(Actor::Property::SIZE, windowSize);
403 overlayCameraActor.SetPerspectiveProjection(windowSize);
404 window.Add(overlayCameraActor);
406 RenderTask overlayRenderTask = window.GetRenderTaskList().CreateTask();
408 overlayRenderTask.SetCameraActor(overlayCameraActor);
409 overlayRenderTask.SetInputEnabled(true);
410 overlayRenderTask.SetClearEnabled(false);
411 overlayRenderTask.SetSourceActor(source);
412 overlayRenderTask.SetExclusive(true);
414 overlayRenderTask.SetViewportPosition(Vector2(0, 0));
415 overlayRenderTask.SetViewportSize(windowSize);
417 overlayRenderTask.SetCullMode(false);
419 return overlayRenderTask;
422 Actor CreateFrame(Vector2 position, Vector2 size, std::string label)
424 Actor frame = Toolkit::ImageView::New(BORDER_IMAGE);
425 frame.SetProperty(Dali::Actor::Property::NAME, "ContentFrame");
426 frame.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
427 frame.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
428 frame.SetProperty(Actor::Property::SIZE, size);
429 frame.SetProperty(Actor::Property::POSITION, position);
431 auto frameLabel = TextLabel::New(label);
432 frameLabel[TextLabel::Property::POINT_SIZE] = 12;
433 frameLabel[TextLabel::Property::HORIZONTAL_ALIGNMENT] = HorizontalAlignment::CENTER;
434 frameLabel[TextLabel::Property::TEXT_COLOR] = Color::YELLOW;
435 frameLabel[Actor::Property::PARENT_ORIGIN] = ParentOrigin::BOTTOM_CENTER;
436 frameLabel[Actor::Property::ANCHOR_POINT] = AnchorPoint::BOTTOM_CENTER;
437 frameLabel[Actor::Property::POSITION] = Vector3(0.0f, 15.0f, 0.0f);
438 frame.Add(frameLabel);
443 Actor CreateCornerHandle(Actor parent)
445 Actor cornerHandle = Toolkit::ImageView::New(RESIZE_HANDLE_IMAGE);
446 cornerHandle.SetProperty(Dali::Actor::Property::NAME, "GrabHandle");
447 cornerHandle.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
448 cornerHandle.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_RIGHT);
449 cornerHandle.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_RIGHT);
450 cornerHandle.SetProperty(Actor::Property::POSITION, Vector2(-BORDER_WIDTH, -BORDER_WIDTH));
451 cornerHandle.SetProperty(Actor::Property::OPACITY, 0.6f);
452 parent.Add(cornerHandle);
456 Actor CreateCenterHandle(Actor parent)
458 Actor grabCenter = Toolkit::ImageView::New(CIRCLE_STROKE);
459 grabCenter.SetProperty(Dali::Actor::Property::NAME, "GrabCenter");
460 grabCenter.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
461 grabCenter.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
462 grabCenter.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
463 Toolkit::ImageView grabCenter2 = Toolkit::ImageView::New(CIRCLE_POINT);
464 grabCenter2.SetProperty(Dali::Actor::Property::NAME, "GrabCenter2");
465 grabCenter2.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
466 grabCenter2.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
467 grabCenter2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
468 grabCenter.Add(grabCenter2);
469 grabCenter.SetProperty(Actor::Property::OPACITY, 0.6f);
470 parent.Add(grabCenter);
474 void SetCameraDetailString()
476 std::ostringstream oss;
478 auto pos = cameraActor.GetCurrentProperty<Vector3>(Actor::Property::POSITION);
479 auto size = cameraFrame.GetTargetSize();
481 oss << "Camera Detail: Pos: (" << pos.x << ", " << pos.y << ")" << std::endl;
482 oss << " Frame size: (" << size.x << ", " << size.y << ")" << std::endl;
484 // Really, just need a box that represents the screen plane at z=0 from MVP.
486 cameraDetail.SetProperty(TextLabel::Property::TEXT, oss.str());
489 void OnPan(Actor actor, const PanGesture& gesture)
491 if(actor == viewportGrabHandle)
493 auto size = viewportFrame.GetTargetSize();
494 auto newSize = Vector2(size.GetVectorXY() + gesture.GetDisplacement() * 2.0f);
495 viewportFrame.SetProperty(Actor::Property::SIZE, newSize);
497 else if(actor == viewportGrabCenter)
500 if(gesture.GetState() == GestureState::FINISHED)
502 pos = viewportFrame.GetCurrentProperty<Vector3>(Actor::Property::POSITION);
506 pos = viewportFrame.GetProperty<Vector3>(Actor::Property::POSITION);
508 pos = Vector2(pos.GetVectorXY() + gesture.GetDisplacement());
509 viewportFrame.SetProperty(Actor::Property::POSITION, pos);
511 else if(actor == cameraGrabHandle)
513 auto size = cameraFrame.GetTargetSize();
514 auto newSize = Vector2(size.GetVectorXY() + gesture.GetDisplacement() * 2.0f);
515 cameraFrame.SetProperty(Actor::Property::SIZE, newSize);
516 cameraActor.SetPerspectiveProjection(newSize);
518 else if(actor == cameraGrabCenter)
521 if(gesture.GetState() == GestureState::FINISHED)
523 pos = cameraFrame.GetCurrentProperty<Vector3>(Actor::Property::POSITION);
527 pos = cameraFrame.GetProperty<Vector3>(Actor::Property::POSITION);
529 pos = Vector2(pos.GetVectorXY() + gesture.GetDisplacement());
530 cameraFrame.SetProperty(Actor::Property::POSITION, pos);
533 SetCameraDetailString();
536 void OnDoubleTap(Actor actor, const TapGesture& gesture)
538 if(actor == viewportGrabHandle)
540 viewportFrame.SetProperty(Actor::Property::SIZE, initialViewportSize);
542 else if(actor == viewportGrabCenter)
544 viewportFrame.SetProperty(Actor::Property::POSITION, initialViewportPosition);
546 else if(actor == cameraGrabHandle)
548 cameraFrame.SetProperty(Actor::Property::SIZE, initialCameraSize);
549 cameraActor.SetProperty(Actor::Property::SIZE, initialCameraSize);
550 cameraActor.SetPerspectiveProjection(Vector2(initialCameraSize));
552 else if(actor == cameraGrabCenter)
554 cameraFrame.SetProperty(Actor::Property::POSITION, initialCameraPosition);
558 bool OnFOVChanged(Slider slider, float value)
560 cameraActor.SetProperty(CameraActor::Property::FIELD_OF_VIEW, (float)Radian(Degree(value)));
564 bool OnRotationSliderChanged(Slider slider, float value)
566 auto actorIdIndex = slider.GetPropertyIndex("actorId");
567 if(actorIdIndex != Property::INVALID_INDEX)
569 int actorIndex = slider["actorId"];
570 float value = slider["value"];
571 imageViews[actorIndex].SetProperty(Actor::Property::ORIENTATION, AngleAxis(Degree(value), Vector3::ZAXIS));
577 * Main key event handler
579 void OnKeyEvent(const KeyEvent& event)
581 if(event.GetState() == KeyEvent::DOWN)
583 if(IsKey(event, DALI_KEY_ESCAPE) || IsKey(event, DALI_KEY_BACK))
590 RenderTask sceneRenderTask;
591 RenderTask overlayRenderTask;
593 PanGestureDetector mPanGestureDetector;
594 TapGestureDetector mTapGestureDetector;
597 std::vector<ImageView> imageViews;
599 Layer viewLayer; // The "scene"
601 Vector3 initialCameraPosition;
602 Vector3 initialCameraSize;
603 Vector3 initialViewportPosition;
604 Vector3 initialViewportSize;
607 Actor viewportGrabCenter;
608 Actor viewportGrabHandle;
611 Actor cameraGrabCenter;
612 Actor cameraGrabHandle;
614 CameraActor cameraActor;
615 TextLabel cameraDetail;
618 int DALI_EXPORT_API main(int argc, char** argv)
620 Application application = Application::New(&argc, &argv, DEMO_THEME_TWO_PATH);
621 CameraTestExample test(application);
622 application.MainLoop();