2 * Copyright (c) 2014 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.
21 #include "shared/view.h"
22 #include <dali/dali.h>
23 #include <dali-toolkit/dali-toolkit.h>
24 #include <dali-toolkit/devel-api/shader-effects/motion-blur-effect.h>
25 #include <dali-toolkit/devel-api/controls/popup/popup.h>
26 #include <dali-toolkit/devel-api/shader-effects/carousel-effect.h>
29 #include "cluster-style.h"
33 using namespace Dali::Demo;
34 using namespace Dali::Toolkit;
35 using namespace DemoHelper;
37 namespace // unnamed namespace
40 const char * const BACKGROUND_IMAGE( DALI_IMAGE_DIR "background-default.png" );
41 const char * const TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" );
42 const char * const APPLICATION_TITLE( "Clusters" );
43 const char * const LAYOUT_NONE_IMAGE( DALI_IMAGE_DIR "icon-cluster-none.png" );
44 const char * const LAYOUT_MOTION_BLUR_IMAGE( DALI_IMAGE_DIR "icon-cluster-wobble.png" );
45 const char * const LAYOUT_CAROUSEL_IMAGE( DALI_IMAGE_DIR "icon-cluster-carousel.png" );
46 const char * const LAYOUT_SPHERE_IMAGE( DALI_IMAGE_DIR "icon-cluster-sphere.png" );
60 const char* PEOPLE_IMAGE_PATHS[] = { DALI_IMAGE_DIR "people-medium-1.jpg",
61 DALI_IMAGE_DIR "people-medium-2.jpg",
62 DALI_IMAGE_DIR "people-medium-3.jpg",
63 DALI_IMAGE_DIR "people-medium-4.jpg",
64 DALI_IMAGE_DIR "people-medium-5.jpg",
65 DALI_IMAGE_DIR "people-medium-6.jpg",
66 DALI_IMAGE_DIR "people-medium-7.jpg",
67 DALI_IMAGE_DIR "people-medium-8.jpg",
70 const char* TODAY_IMAGE_PATHS[] = { DALI_IMAGE_DIR "gallery-medium-1.jpg",
71 DALI_IMAGE_DIR "gallery-medium-2.jpg",
72 DALI_IMAGE_DIR "gallery-medium-3.jpg",
73 DALI_IMAGE_DIR "gallery-medium-4.jpg",
74 DALI_IMAGE_DIR "gallery-medium-5.jpg",
75 DALI_IMAGE_DIR "gallery-medium-6.jpg",
78 const char* PHONE_IMAGE_PATHS[] = { DALI_IMAGE_DIR "gallery-medium-7.jpg",
79 DALI_IMAGE_DIR "gallery-medium-8.jpg",
80 DALI_IMAGE_DIR "gallery-medium-9.jpg",
81 DALI_IMAGE_DIR "gallery-medium-10.jpg",
82 DALI_IMAGE_DIR "gallery-medium-11.jpg",
83 DALI_IMAGE_DIR "gallery-medium-12.jpg",
86 const char* PICTURES_IMAGE_PATHS[] = { DALI_IMAGE_DIR "gallery-medium-13.jpg",
87 DALI_IMAGE_DIR "gallery-medium-14.jpg",
88 DALI_IMAGE_DIR "gallery-medium-15.jpg",
89 DALI_IMAGE_DIR "gallery-medium-16.jpg",
90 DALI_IMAGE_DIR "gallery-medium-17.jpg",
91 DALI_IMAGE_DIR "gallery-medium-18.jpg",
94 const char* MUSIC_IMAGE_PATHS[] = { DALI_IMAGE_DIR "gallery-medium-19.jpg",
95 DALI_IMAGE_DIR "gallery-medium-20.jpg",
96 DALI_IMAGE_DIR "gallery-medium-21.jpg",
97 DALI_IMAGE_DIR "gallery-medium-22.jpg",
98 DALI_IMAGE_DIR "gallery-medium-23.jpg",
99 DALI_IMAGE_DIR "gallery-medium-24.jpg",
102 const char* MAGAZINE_IMAGE_PATHS[] = { DALI_IMAGE_DIR "gallery-medium-25.jpg",
103 DALI_IMAGE_DIR "gallery-medium-26.jpg",
104 DALI_IMAGE_DIR "gallery-medium-27.jpg",
105 DALI_IMAGE_DIR "gallery-medium-28.jpg",
106 DALI_IMAGE_DIR "gallery-medium-29.jpg",
107 DALI_IMAGE_DIR "gallery-medium-30.jpg",
110 const char **IMAGE_GROUPS[] = {PEOPLE_IMAGE_PATHS,
113 PICTURES_IMAGE_PATHS,
115 MAGAZINE_IMAGE_PATHS,
118 const float CLUSTER_IMAGE_THUMBNAIL_WIDTH = 256.0f;
119 const float CLUSTER_IMAGE_THUMBNAIL_HEIGHT = 256.0f;
121 const char* CLUSTER_SHADOW_IMAGE_PATH = DALI_IMAGE_DIR "cluster-image-shadow.png";
122 const char* CLUSTER_BORDER_IMAGE_PATH = DALI_IMAGE_DIR "cluster-image-frame.png";
123 const char* CLUSTER_BACKGROUND_IMAGE_PATH = DALI_IMAGE_DIR "cluster-background.png";
125 const float CLUSTER_IMAGE_BORDER_INDENT = 14.0f; ///< Indent of border in pixels.
126 const float CLUSTER_IMAGE_BORDER_WIDTH = 128; ///< Width of border in pixels.
127 const float CLUSTER_IMAGE_BORDER_HEIGHT = 128; ///< Height of border in pixels.
129 const Vector4 CLUSTER_IMAGE_BORDER_ABSOLUTE( 16.0f, 16.0f, 16.0f, 16.0f ); // Border dimensions in absolute pixel coordinates.
131 // These values depend on the border image
132 const float CLUSTER_RELATIVE_SIZE = 0.65f; ///< Cluster size relative to screen width
134 const float CLUSTER_GROUP_DELAY_TOP = 0.25f; ///< Delay for top Clusters in seconds.
135 const float CLUSTER_GROUP_DELAY_BOTTOM = 0.0f; ///< Delay for bottom Clusters in seconds.
137 const float CLUSTER_COLUMN_INDENT = 0.1f; ///< Left Indentation in screen coordinates.
138 const float CLUSTER_ROW_INDENT = 0.13f; ///< Top Indentation in screen coordinates.
140 const float UI_MARGIN = 10.0f; ///< Screen Margin for placement of UI buttons
142 const float CAROUSEL_EFFECT_RADIUS = 500.0f; ///< In Carousel Effect mode: Radius of carousel (Z peak depth)
143 const float CAROUSEL_EFFECT_ANGLE_SWEEP = 90.0f; ///< In Carousel Effect mode: Angle sweep from left to right of screen
144 const float SPHERE_EFFECT_RADIUS = 1000.0f; ///< In Sphere Effect mode: Radius of sphere carousel (Z peak depth)
145 const float SPHERE_EFFECT_POSITION_Z = -700.0f; ///< In Sphere Effect mode: Z position alter (as carousel is coming out to screen we move back)
146 const float SPHERE_EFFECT_ANGLE_SWEEP = 90.0f; ///< In Sphere Effect mode: Angle sweep from edge to opposite side of circle.
147 const float SPHERE_EFFECT_VERTICAL_DOMAIN = 0.15f; ///< In Sphere Effect mode: How much the user can pan in the vertical axis. (in stageHeights)
150 * List of effect types that user can select through.
152 enum ExampleEffectType
162 * List of effect type names that appear on the Effect button.
164 const char* EXAMPLE_EFFECT_LABEL[] = { "None",
171 * CarouselEffectOrientationConstraint
172 * Based on the View orientation i.e. portrait (0 degrees), landscape (90 degrees) etc.
173 * carousel shader effect should bend differently (as a function of this orientation),
174 * as shader effect is applied to the screen coordinates.
176 struct CarouselEffectOrientationConstraint
180 * @param[in] angleSweep The amount of degrees to rotate by per pixel.
182 CarouselEffectOrientationConstraint( const Vector2 angleSweep )
183 : mAngleSweep( angleSweep )
188 * @param[in] current The object's current property value
189 * @return The object's new property value
191 void operator()( Vector2& current, const PropertyInputContainer& inputs )
195 inputs[0]->GetQuaternion().ToAxisAngle( axis, angle );
197 current.x = cosf(angle);
198 current.y = sinf(angle);
200 current *= mAngleSweep;
208 * SphereEffectOffsetConstraint
210 * Sets SphereEffect's center to be a function of the
211 * screen orientation (portrait or landscape).
213 struct SphereEffectOffsetConstraint
216 * @param[in] stageSize The stage size (not subject to orientation)
217 * @param[in] center Shear Center position based on initial orientation.
219 SphereEffectOffsetConstraint(float offset)
225 * @param[in] current The current center
226 * @param[in] propertyViewSize The current view size
227 * @return vector to provide SphereShaderEffect
229 void operator()( float& current, const PropertyInputContainer& /* inputs */ )
240 * Contains information about each cluster in mClusterInfo list.
247 * @param[in] cluster The cluster instance
248 * @param[in] index The cluster's index (starting from 0 for the first cluster)
249 * @param[in] position The cluster's original position
250 * @param[in] size The cluster's original size
252 ClusterInfo(Cluster cluster, int index, const Vector3& position, const Vector3& size)
264 * @param[in] rhs The ClusterInfo struct to be copied.
266 ClusterInfo( const ClusterInfo& rhs )
267 : mCluster(rhs.mCluster),
269 mPosition(rhs.mPosition),
276 * Assignment operator
278 ClusterInfo& operator=( const ClusterInfo& rhs )
282 mCluster = rhs.mCluster;
284 mPosition = rhs.mPosition;
291 Cluster mCluster; ///< Cluster instance
292 int mIndex; ///< Cluster index
293 Vector3 mPosition; ///< Cluster original position
294 Vector3 mSize; ///< Cluster original size
295 Constraint mEffectConstraint; ///< Cluster constraint
299 * Shrinks Actor based on parent's aspect ratio.
301 struct ShrinkConstraint
311 * @param[in] current The object's current scale value
312 * @param[in] parentScale The parent's scale
313 * @return The object's new scale value
315 Vector3 operator()(const Vector3& current,
316 const PropertyInput& parentScale)
318 return Vector3( parentScale.GetVector3().x / parentScale.GetVector3().y, 1.0f, 1.0f );
322 } // unnamed namespace
325 * Custom position and size of shadow image
327 namespace ShadowProperty
329 const Vector3 ANCHOR_POINT (0.54f, 0.6f, 0.5f);
330 const Vector3 RELATIVE_POSITION (0.0f, 0.0f, -0.1f);
331 const Vector3 SIZE_SCALE (1.4f, 1.4f, 1.0f);
334 // This example shows how to use Cluster UI control
336 class ClusterController : public ConnectionTracker
342 * @param application class, stored as reference
344 ClusterController(Application &app)
347 mExampleEffect(NO_EFFECT)
349 // Connect to the Application's Init signal
350 app.InitSignal().Connect(this, &ClusterController::Create);
355 // Nothing to do here; everything gets deleted automatically
359 * This method gets called once the main loop of application is up and running
361 void Create(Application& application)
363 Stage::GetCurrent().KeyEventSignal().Connect(this, &ClusterController::OnKeyEvent);
365 // The Init signal is received once (only) during the Application lifetime
367 // Hide the indicator bar
368 application.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
370 // Creates a default view with a default tool bar.
371 // The view is added to the stage.
372 mContentLayer = DemoHelper::CreateView( application,
379 // Create a effect toggle button. (right of toolbar)
380 mLayoutButtonImages[ NO_EFFECT ] = ResourceImage::New( LAYOUT_NONE_IMAGE );
381 mLayoutButtonImages[ MOTION_BLUR_EFFECT ] = ResourceImage::New( LAYOUT_MOTION_BLUR_IMAGE );
382 mLayoutButtonImages[ CAROUSEL_EFFECT ] = ResourceImage::New( LAYOUT_CAROUSEL_IMAGE );
383 mLayoutButtonImages[ SPHERE_EFFECT ] = ResourceImage::New( LAYOUT_SPHERE_IMAGE );
385 mLayoutButton = Toolkit::PushButton::New();
386 mLayoutButton.ClickedSignal().Connect( this, &ClusterController::OnEffectTouched );
387 mToolBar.AddControl( mLayoutButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight, DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
389 // create and setup the scroll view...
390 mScrollView = ScrollView::New();
391 mScrollView.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
393 // anchor the scroll view from its center point to the middle of its parent
394 mScrollView.SetAnchorPoint(AnchorPoint::CENTER);
395 mScrollView.SetParentOrigin(ParentOrigin::CENTER);
397 // Scale ScrollView to fit parent (mContentLayer)
398 mScrollView.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
400 // Add the scroll view to the content layer
401 mContentLayer.Add(mScrollView);
403 // Create the image border shared by all the cluster image actors
404 mClusterBorderImage = ResourceImage::New(CLUSTER_BORDER_IMAGE_PATH);
406 AddCluster( PEOPLE, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle1) );
407 AddCluster( TODAY, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle2) );
408 AddCluster( PHONE, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle3) );
409 AddCluster( PICTURES, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle4) );
410 AddCluster( MUSIC, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle2) );
411 AddCluster( MAGAZINE, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle3) );
413 SetEffect(MOTION_BLUR_EFFECT);
417 * Helper to create the cluster actors
419 Cluster CreateClusterActor(ClusterType clusterType, ClusterStyle style, Vector3& clusterSize)
421 // Create the cluster actor with the given cluster style
422 Cluster clusterActor = Cluster::New(style);
423 clusterActor.SetParentOrigin(ParentOrigin::CENTER);
424 clusterActor.SetAnchorPoint(AnchorPoint::CENTER);
426 Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
427 float minStageDimension = std::min(stageSize.x, stageSize.y);
429 clusterSize.x = minStageDimension * CLUSTER_RELATIVE_SIZE;
430 clusterSize.y = minStageDimension * CLUSTER_RELATIVE_SIZE;
432 clusterActor.SetSize( clusterSize );
434 DALI_ASSERT_ALWAYS(clusterType < CLUSTER_COUNT);
435 const char **paths = IMAGE_GROUPS[clusterType];
436 DALI_ASSERT_ALWAYS(paths);
438 // Add a background image to the cluster, limiting the loaded size by
439 // fitting it inside a quarter of the stage area with the conservative BOX
441 Image bg = ResourceImage::New( CLUSTER_BACKGROUND_IMAGE_PATH, Dali::ImageDimensions( stageSize.x * 0.5f, stageSize.y * 0.5f ), Dali::FittingMode::SHRINK_TO_FIT, Dali::SamplingMode::BOX );
442 ImageActor image = ImageActor::New(bg);
443 clusterActor.SetBackgroundImage(image);
445 // Add actors (pictures) as the children of the cluster
446 for (unsigned int i = 0; (i < style.GetMaximumNumberOfChildren()) && (*paths); i++, paths++)
448 clusterActor.AddChild(CreateClusterPictureActor(clusterType, *paths), i);
455 * Helper to create the picture actors in the cluster
457 Actor CreateClusterPictureActor(ClusterType clusterType, const std::string& imagePath)
459 // Create a picture for this cluster image
463 Actor actor = Actor::New();
464 actor.SetSize(CLUSTER_IMAGE_THUMBNAIL_WIDTH, CLUSTER_IMAGE_THUMBNAIL_HEIGHT);
465 actor.SetParentOrigin( ParentOrigin::CENTER );
466 actor.SetAnchorPoint( AnchorPoint::CENTER );
468 // Load the thumbnail at quarter of screen width or standard size if that is smaller:
469 Size stageQuarter = Stage::GetCurrent().GetSize() * 0.25f;
470 const ImageDimensions requestedDims = ImageDimensions( std::min( stageQuarter.x, CLUSTER_IMAGE_THUMBNAIL_WIDTH ), std::min( stageQuarter.y, CLUSTER_IMAGE_THUMBNAIL_HEIGHT ) );
472 // Add a shadow image child actor
473 Image shadowImage = ResourceImage::New( CLUSTER_SHADOW_IMAGE_PATH, requestedDims, Dali::FittingMode::SHRINK_TO_FIT, Dali::SamplingMode::BOX );
474 ImageActor shadowActor = ImageActor::New(shadowImage);
476 // Shadow is not exactly located on the center of the image, so it is moved to a little
477 // upper-left side of the image relatively using customised AnchorPoint.
478 shadowActor.SetParentOrigin(ShadowProperty::ANCHOR_POINT);
479 shadowActor.SetAnchorPoint(AnchorPoint::CENTER);
480 shadowActor.SetPosition(Vector3(0.0f, 0.0f, -1.0f));
482 // Apply size-relative mode to auto-size the image shadow
483 shadowActor.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
484 shadowActor.SetSizeModeFactor( ShadowProperty::SIZE_SCALE );
485 actor.Add( shadowActor );
487 // Add a picture image actor to actor (with equal size to the parent).
488 Image image = ResourceImage::New( imagePath, requestedDims, Dali::FittingMode::SHRINK_TO_FIT, Dali::SamplingMode::BOX );
489 ImageActor imageActor = ImageActor::New( image );
490 imageActor.SetParentOrigin( ParentOrigin::CENTER );
491 imageActor.SetAnchorPoint( AnchorPoint::CENTER );
492 imageActor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
493 actor.Add( imageActor );
495 // Add a border image child actor (with a fixed size offset from parent).
496 ImageActor borderActor = ImageActor::New( mClusterBorderImage );
497 borderActor.SetParentOrigin( ParentOrigin::CENTER );
498 borderActor.SetAnchorPoint( AnchorPoint::CENTER );
499 borderActor.SetStyle( ImageActor::STYLE_NINE_PATCH );
500 borderActor.SetNinePatchBorder( CLUSTER_IMAGE_BORDER_ABSOLUTE );
501 borderActor.SetPosition( Vector3( 0.0f, 0.0f, 1.0f ) );
502 borderActor.SetResizePolicy( ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS );
503 borderActor.SetSizeModeFactor( Vector3( CLUSTER_IMAGE_BORDER_INDENT - 1.0f, CLUSTER_IMAGE_BORDER_INDENT - 1.0f, 0.0f ) * 2.0f );
504 actor.Add( borderActor );
511 * Adds a Cluster to the ScrollView
513 * @param[in] clusterType The type of cluster (determines the image content)
514 * @param[in] style The style to be used for this cluster.
516 void AddCluster(ClusterType clusterType, ClusterStyle style)
518 Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
520 int column = mClusterCount>>1;
521 int row = mClusterCount&1;
523 float minStageDimension = std::min(stageSize.x, stageSize.y);
524 float clusterRightShift = 1.0f - CLUSTER_COLUMN_INDENT * 2.0f;
525 Vector3 clusterPosition = Vector3(CLUSTER_COLUMN_INDENT * stageSize.width + row * (clusterRightShift * stageSize.width - minStageDimension * CLUSTER_RELATIVE_SIZE),
526 CLUSTER_ROW_INDENT * stageSize.height + row * (clusterRightShift * stageSize.height - minStageDimension * CLUSTER_RELATIVE_SIZE), 0.0f);
528 Actor pageView = Actor::New();
529 mScrollView.Add(pageView);
530 pageView.SetParentOrigin(ParentOrigin::CENTER);
531 pageView.SetPosition(Vector3(stageSize.width * column, 0.0f, 0.0f));
532 pageView.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
534 // Create cluster actors and add them to scroll view
536 Cluster cluster = CreateClusterActor( clusterType, style, clusterSize );
537 cluster.SetParentOrigin(ParentOrigin::TOP_LEFT);
538 cluster.SetAnchorPoint(AnchorPoint::TOP_LEFT);
539 cluster.SetPosition( clusterPosition );
541 pageView.Add(cluster);
543 mClusterInfo.push_back( ClusterInfo( cluster, mClusterCount, clusterPosition, clusterSize ) );
549 * Sets motion blur effect to a cluster and all its children
551 * @param[in] actor Cluster control to which the effect will be applied
553 void SetMotionBlurEffect( Actor actor )
555 // only do something if the actor and effect are valid
558 // first remove from this actor
559 RenderableActor renderable = RenderableActor::DownCast( actor );
562 MotionBlurEffect shaderEffect = MotionBlurEffect::New();
563 shaderEffect.SetSpeedScalingFactor(0.1f);
565 Dali::Property::Index uModelProperty = shaderEffect.GetPropertyIndex( "uModelLastFrame" );
566 Constraint constraint = Constraint::New<Matrix>( shaderEffect, uModelProperty, EqualToConstraint() );
567 constraint.AddSource( Source( actor , Actor::Property::WORLD_MATRIX ) );
569 renderable.SetShaderEffect( shaderEffect );
571 // then all children recursively
572 const unsigned int count = actor.GetChildCount();
573 for( unsigned int index = 0; index < count; ++index )
575 Actor child( actor.GetChildAt( index ) );
576 SetMotionBlurEffect( child );
582 * Resets ScrollView and Clusters settings
583 * to reflect the new ExampleEffectType
585 * TODO: Add animation transition to fade out of existing effect,
586 * and into new effect.
588 * @param[in] type The desired effect to switch to.
590 void SetEffect(ExampleEffectType type)
592 Vector2 stageSize(Dali::Stage::GetCurrent().GetSize());
594 mExampleEffect = type;
596 std::stringstream ss(APPLICATION_TITLE);
597 ss << APPLICATION_TITLE << ": " << EXAMPLE_EFFECT_LABEL[mExampleEffect];
600 // Set up default ruler settings (fixed in horizontal, disabled in vertical)
602 rulerX = new FixedRuler(stageSize.x);
603 int columns = (mClusterCount + 1) >> 1;
604 rulerX->SetDomain(RulerDomain(0.0f, stageSize.x * columns, true));
605 mScrollView.SetRulerX(rulerX);
607 RulerPtr rulerY = new DefaultRuler();
609 mScrollView.SetRulerY(rulerY);
611 mScrollView.SetActorAutoSnap(false);
613 // Remove all shader-effects from mScrollView and it's children (the clusters)
614 mScrollView.SetPosition(Vector3::ZERO);
616 mLayoutButton.SetBackgroundImage( mLayoutButtonImages[ type ] );
618 for( std::vector<ClusterInfo>::iterator i = mClusterInfo.begin(); i != mClusterInfo.end(); ++i )
620 Cluster cluster = i->mCluster;
621 RemoveShaderEffectRecursively( cluster );
622 if( i->mEffectConstraint )
624 i->mEffectConstraint.Remove();
625 i->mEffectConstraint.Reset();
629 // Apply new shader-effects.
630 // Move Y to origin incase we came from an effect where user could free pan in y axis.
631 const Vector2 currentScrollPosition(mScrollView.GetCurrentScrollPosition());
632 mScrollView.ScrollTo(Vector2(currentScrollPosition.x, 0.0f));
641 case MOTION_BLUR_EFFECT:
643 for( std::vector<ClusterInfo>::iterator i = mClusterInfo.begin(); i != mClusterInfo.end(); ++i )
645 SetMotionBlurEffect( i->mCluster );
650 case CAROUSEL_EFFECT:
652 // Apply Carousel Shader Effect to scrollView
653 CarouselEffect shaderEffect = CarouselEffect::New();
654 shaderEffect.SetRadius( -CAROUSEL_EFFECT_RADIUS );
655 // dont apply shader effect to scrollview as it might override internal shaders for bounce effect etc
656 for( std::vector<ClusterInfo>::iterator i = mClusterInfo.begin(); i != mClusterInfo.end(); ++i )
658 Cluster cluster = i->mCluster;
659 SetShaderEffectRecursively( cluster, shaderEffect );
661 mScrollView.SetPosition( Vector3( 0.0f, 0.0f, CAROUSEL_EFFECT_RADIUS ) );
663 const Vector2 angleSweep( CAROUSEL_EFFECT_ANGLE_SWEEP / stageSize.width,
664 CAROUSEL_EFFECT_ANGLE_SWEEP / stageSize.width );
666 Property::Index anglePerUnit = shaderEffect.GetPropertyIndex( shaderEffect.GetAnglePerUnitPropertyName() );
667 Constraint constraint = Constraint::New<Vector2>( shaderEffect, anglePerUnit, CarouselEffectOrientationConstraint( angleSweep ) );
668 constraint.AddSource( Source(mView, Actor::Property::ORIENTATION) );
676 // Change ruler to free panning...
678 rulerX = new DefaultRuler();
679 int columns = (mClusterCount + 1) >> 1;
680 rulerX->SetDomain(RulerDomain(0.0f, stageSize.x * columns, true));
681 mScrollView.SetRulerX(rulerX);
683 RulerPtr rulerY = new DefaultRuler();
684 rulerY->SetDomain(RulerDomain( -stageSize.y * SPHERE_EFFECT_VERTICAL_DOMAIN, stageSize.y * (1.0f + SPHERE_EFFECT_VERTICAL_DOMAIN), true));
685 mScrollView.SetRulerY(rulerY);
687 // Apply Carousel Shader Effect to scrollView (Spherical style)
688 CarouselEffect shaderEffect = CarouselEffect::New();
690 shaderEffect.SetRadius( SPHERE_EFFECT_RADIUS );
691 shaderEffect.SetAnglePerUnit( Vector2( SPHERE_EFFECT_ANGLE_SWEEP / stageSize.y, SPHERE_EFFECT_ANGLE_SWEEP / stageSize.y ) );
692 // dont apply shader effect to scrollview as it might override internal shaders for bounce effect etc
693 for( std::vector<ClusterInfo>::iterator i = mClusterInfo.begin(); i != mClusterInfo.end(); ++i )
695 Cluster cluster = i->mCluster;
696 i->mEffectConstraint = Constraint::New<float>( cluster, Actor::Property::POSITION_Z, SphereEffectOffsetConstraint( SPHERE_EFFECT_POSITION_Z ) );
697 i->mEffectConstraint.SetRemoveAction(Constraint::Discard);
698 SetShaderEffectRecursively( cluster, shaderEffect );
699 i->mEffectConstraint.Apply();
711 * Signal handler, called when quit button is pressed
713 bool OnEffectTouched( Toolkit::Button button )
715 // quit the application
716 SetEffect(static_cast<ExampleEffectType>( (mExampleEffect + 1) % TOTAL_EFFECTS) );
721 * Sets/Updates the title of the View
722 * @param[in] title The new title for the view.
724 void SetTitle(const std::string& title)
728 mTitleActor = DemoHelper::CreateToolBarLabel( "" );
730 // Add title to the tool bar.
731 mToolBar.AddControl( mTitleActor, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarTitlePercentage, Alignment::HorizontalCenter );
734 mTitleActor.SetProperty( TextLabel::Property::TEXT, title );
738 * Main key event handler
740 void OnKeyEvent(const KeyEvent& event)
742 if(event.state == KeyEvent::Down)
744 if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
753 Application& mApplication; ///< Application instance
754 Toolkit::Control mView; ///< The View instance.
755 Toolkit::ToolBar mToolBar; ///< The View's Toolbar.
756 TextLabel mTitleActor; ///< The Toolbar's Title.
758 Layer mContentLayer; ///< Content layer (scrolling cluster content)
760 ScrollView mScrollView; ///< The ScrollView container for all clusters
761 Image mClusterBorderImage; ///< The border frame that appears on each image
763 std::vector<ClusterInfo> mClusterInfo; ///< Keeps track of each cluster's information.
764 int mClusterCount; ///< Current number of clusters in use
765 ExampleEffectType mExampleEffect; ///< Current example effect.
767 Toolkit::PushButton mLayoutButton; ///< The layout button
768 Image mLayoutButtonImages[TOTAL_EFFECTS]; ///< Image when no layout
771 void RunTest(Application& app)
773 ClusterController test(app);
778 // Entry point for Linux & Tizen applications
780 int main(int argc, char **argv)
782 Application app = Application::New(&argc, &argv, DALI_DEMO_THEME_PATH);