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>
26 using namespace Dali::Toolkit;
27 using namespace DemoHelper;
29 namespace // unnamed namespace
32 const char * const BACKGROUND_IMAGE( DALI_IMAGE_DIR "background-default.png" );
33 const char * const TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" );
34 const char * const APPLICATION_TITLE( "Clusters" );
35 const char * const LAYOUT_NONE_IMAGE( DALI_IMAGE_DIR "icon-cluster-none.png" );
36 const char * const LAYOUT_WOBBLE_IMAGE( DALI_IMAGE_DIR "icon-cluster-wobble.png" );
37 const char * const LAYOUT_CAROUSEL_IMAGE( DALI_IMAGE_DIR "icon-cluster-carousel.png" );
38 const char * const LAYOUT_SPHERE_IMAGE( DALI_IMAGE_DIR "icon-cluster-sphere.png" );
52 const char* PEOPLE_IMAGE_PATHS[] = { DALI_IMAGE_DIR "people-medium-1.jpg",
53 DALI_IMAGE_DIR "people-medium-2.jpg",
54 DALI_IMAGE_DIR "people-medium-3.jpg",
55 DALI_IMAGE_DIR "people-medium-4.jpg",
56 DALI_IMAGE_DIR "people-medium-5.jpg",
57 DALI_IMAGE_DIR "people-medium-6.jpg",
58 DALI_IMAGE_DIR "people-medium-7.jpg",
59 DALI_IMAGE_DIR "people-medium-8.jpg",
62 const char* TODAY_IMAGE_PATHS[] = { DALI_IMAGE_DIR "gallery-medium-1.jpg",
63 DALI_IMAGE_DIR "gallery-medium-2.jpg",
64 DALI_IMAGE_DIR "gallery-medium-3.jpg",
65 DALI_IMAGE_DIR "gallery-medium-4.jpg",
66 DALI_IMAGE_DIR "gallery-medium-5.jpg",
67 DALI_IMAGE_DIR "gallery-medium-6.jpg",
70 const char* PHONE_IMAGE_PATHS[] = { DALI_IMAGE_DIR "gallery-medium-7.jpg",
71 DALI_IMAGE_DIR "gallery-medium-8.jpg",
72 DALI_IMAGE_DIR "gallery-medium-9.jpg",
73 DALI_IMAGE_DIR "gallery-medium-10.jpg",
74 DALI_IMAGE_DIR "gallery-medium-11.jpg",
75 DALI_IMAGE_DIR "gallery-medium-12.jpg",
78 const char* PICTURES_IMAGE_PATHS[] = { DALI_IMAGE_DIR "gallery-medium-13.jpg",
79 DALI_IMAGE_DIR "gallery-medium-14.jpg",
80 DALI_IMAGE_DIR "gallery-medium-15.jpg",
81 DALI_IMAGE_DIR "gallery-medium-16.jpg",
82 DALI_IMAGE_DIR "gallery-medium-17.jpg",
83 DALI_IMAGE_DIR "gallery-medium-18.jpg",
86 const char* MUSIC_IMAGE_PATHS[] = { DALI_IMAGE_DIR "gallery-medium-19.jpg",
87 DALI_IMAGE_DIR "gallery-medium-20.jpg",
88 DALI_IMAGE_DIR "gallery-medium-21.jpg",
89 DALI_IMAGE_DIR "gallery-medium-22.jpg",
90 DALI_IMAGE_DIR "gallery-medium-23.jpg",
91 DALI_IMAGE_DIR "gallery-medium-24.jpg",
94 const char* MAGAZINE_IMAGE_PATHS[] = { DALI_IMAGE_DIR "gallery-medium-25.jpg",
95 DALI_IMAGE_DIR "gallery-medium-26.jpg",
96 DALI_IMAGE_DIR "gallery-medium-27.jpg",
97 DALI_IMAGE_DIR "gallery-medium-28.jpg",
98 DALI_IMAGE_DIR "gallery-medium-29.jpg",
99 DALI_IMAGE_DIR "gallery-medium-30.jpg",
102 const char **IMAGE_GROUPS[] = {PEOPLE_IMAGE_PATHS,
105 PICTURES_IMAGE_PATHS,
107 MAGAZINE_IMAGE_PATHS,
110 const float CLUSTER_IMAGE_THUMBNAIL_WIDTH = 256.0f;
111 const float CLUSTER_IMAGE_THUMBNAIL_HEIGHT = 256.0f;
113 const char* CLUSTER_SHADOW_IMAGE_PATH = DALI_IMAGE_DIR "cluster-image-shadow.png";
114 const char* CLUSTER_BORDER_IMAGE_PATH = DALI_IMAGE_DIR "cluster-image-frame.png";
115 const char* CLUSTER_BACKGROUND_IMAGE_PATH = DALI_IMAGE_DIR "cluster-background.png";
117 const float CLUSTER_IMAGE_BORDER_INDENT = 14.0f; ///< Indent of border in pixels.
118 const float CLUSTER_IMAGE_BORDER_WIDTH = 128; ///< Width of border in pixels.
119 const float CLUSTER_IMAGE_BORDER_HEIGHT = 128; ///< Height of border in pixels.
121 const Vector4 CLUSTER_IMAGE_BORDER_ABSOLUTE( 16.0f, 16.0f, 16.0f, 16.0f ); // Border dimensions in absolute pixel coordinates.
123 // These values depend on the border image
124 const float CLUSTER_RELATIVE_SIZE = 0.65f; ///< Cluster size relative to screen width
126 const float CLUSTER_GROUP_DELAY_TOP = 0.25f; ///< Delay for top Clusters in seconds.
127 const float CLUSTER_GROUP_DELAY_BOTTOM = 0.0f; ///< Delay for bottom Clusters in seconds.
129 const float CLUSTER_COLUMN_INDENT = 0.1f; ///< Left Indentation in screen coordinates.
130 const float CLUSTER_ROW_INDENT = 0.13f; ///< Top Indentation in screen coordinates.
132 const Vector3 SHEAR_EFFECT_ANCHOR_POINT(0.5f, 1.0f, 0.5f); ///< Anchor Point used for the shear effect (extends outside of Cluster)
133 const float SHEAR_EFFECT_MAX_OVERSHOOT = 30.0f; ///< Max Overshoot for shear effect (in degrees).
135 const float UI_MARGIN = 10.0f; ///< Screen Margin for placement of UI buttons
137 const float CAROUSEL_EFFECT_RADIUS = 500.0f; ///< In Carousel Effect mode: Radius of carousel (Z peak depth)
138 const float CAROUSEL_EFFECT_ANGLE_SWEEP = 90.0f; ///< In Carousel Effect mode: Angle sweep from left to right of screen
139 const float SPHERE_EFFECT_RADIUS = 1000.0f; ///< In Sphere Effect mode: Radius of sphere carousel (Z peak depth)
140 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)
141 const float SPHERE_EFFECT_ANGLE_SWEEP = 90.0f; ///< In Sphere Effect mode: Angle sweep from edge to opposite side of circle.
142 const float SPHERE_EFFECT_VERTICAL_DOMAIN = 0.15f; ///< In Sphere Effect mode: How much the user can pan in the vertical axis. (in stageHeights)
145 * List of effect types that user can select through.
147 enum ExampleEffectType
157 * List of effect type names that appear on the Effect button.
159 const char* EXAMPLE_EFFECT_LABEL[] = { "NONE",
166 * CarouselEffectOrientationConstraint
167 * Based on the View orientation i.e. portrait (0 degrees), landscape (90 degrees) etc.
168 * carousel shader effect should bend differently (as a function of this orientation),
169 * as shader effect is applied to the screen coordinates.
171 struct CarouselEffectOrientationConstraint
175 * @param[in] angleSweep The amount of degrees to rotate by per pixel.
177 CarouselEffectOrientationConstraint( const Vector2 angleSweep )
178 : mAngleSweep( angleSweep )
183 * @param[in] current The object's current property value
184 * @return The object's new property value
186 Vector2 operator()(const Vector2& current,
187 const PropertyInput& propertyOrientation)
191 propertyOrientation.GetQuaternion().ToAxisAngle( axis, angle );
192 Vector2 direction( cosf(angle), sinf(angle) );
194 return mAngleSweep * direction;
202 * ShearEffectConstraint
204 * Constrains ShearEffect's tilt to be a function of scrollview's
205 * horizontal overshoot amount.
207 struct ShearEffectConstraint
210 * @param[in] stageSize The stage size (not subject to orientation)
211 * @param[in] maxOvershoot Maximum amount overshoot can affect shear.
212 * @param[in] componentMask Whether constraint should take the X shear
213 * or the Y shear component.
215 ShearEffectConstraint(Vector2 stageSize, float maxOvershoot, Vector2 componentMask)
216 : mStageSize(stageSize),
217 mMaxOvershoot(maxOvershoot),
218 mComponentMask(componentMask)
223 * @param[in] current The current shear effect Angle.
224 * @param[in] scrollOvershootProperty The overshoot property from ScrollView
225 * @param[in] propertyViewOrientation The orientation of the view e.g. Portrait, Landscape.
226 * @return angle to provide ShearShaderEffect
228 float operator()(const float& current,
229 const PropertyInput& scrollOvershootProperty,
230 const PropertyInput& propertyViewOrientation)
232 float f = scrollOvershootProperty.GetVector3().x;
234 float mag = fabsf(f);
235 float halfWidth = mStageSize.x * 0.5f;
237 // inverse exponential tail-off
238 float overshoot = 1.0f - halfWidth / (halfWidth + mag);
241 overshoot = -overshoot;
244 // Channel this shear value into either the X or Y axis depending on
245 // the component mask passed in.
248 propertyViewOrientation.GetQuaternion().ToAxisAngle( axis, angle );
249 Vector2 direction( cosf(angle), sinf(angle) );
250 float yield = direction.x * mComponentMask.x + direction.y * mComponentMask.y;
252 return overshoot * mMaxOvershoot * yield;
257 Vector2 mComponentMask;
261 * ShearEffectCenterConstraint
263 * Sets ShearEffect's center to be a function of the
264 * screen orientation (portrait or landscape).
266 struct ShearEffectCenterConstraint
269 * @param[in] stageSize The stage size (not subject to orientation)
270 * @param[in] center Shear Center position based on initial orientation.
272 ShearEffectCenterConstraint(Vector2 stageSize, Vector2 center)
273 : mStageSize(stageSize),
279 * @param[in] current The current center
280 * @param[in] propertyViewSize The current view size
281 * @return vector to provide ShearShaderEffect
283 Vector2 operator()(const Vector2& current,
284 const PropertyInput& propertyViewSize)
286 float f = propertyViewSize.GetVector3().width / mStageSize.width;
287 return Vector2( f * mCenter.x, mCenter.y );
295 * SphereEffectOffsetConstraint
297 * Sets SphereEffect's center to be a function of the
298 * screen orientation (portrait or landscape).
300 struct SphereEffectOffsetConstraint
303 * @param[in] stageSize The stage size (not subject to orientation)
304 * @param[in] center Shear Center position based on initial orientation.
306 SphereEffectOffsetConstraint(float offset)
312 * @param[in] current The current center
313 * @param[in] propertyViewSize The current view size
314 * @return vector to provide SphereShaderEffect
316 float operator()(const float& current)
318 return current + mOffset;
327 * Contains information about each cluster in mClusterInfo list.
334 * @param[in] cluster The cluster instance
335 * @param[in] index The cluster's index (starting from 0 for the first cluster)
336 * @param[in] position The cluster's original position
337 * @param[in] size The cluster's original size
339 ClusterInfo(Cluster cluster, int index, const Vector3& position, const Vector3& size)
351 * @param[in] rhs The ClusterInfo struct to be copied.
353 ClusterInfo( const ClusterInfo& rhs )
354 : mCluster(rhs.mCluster),
356 mPosition(rhs.mPosition),
363 * Assignment operator
365 ClusterInfo& operator=( const ClusterInfo& rhs )
369 mCluster = rhs.mCluster;
371 mPosition = rhs.mPosition;
378 Cluster mCluster; ///< Cluster instance
379 int mIndex; ///< Cluster index
380 Vector3 mPosition; ///< Cluster original position
381 Vector3 mSize; ///< Cluster original size
382 ActiveConstraint mEffectConstraint; ///< Cluster constraint
386 * Shrinks Actor based on parent's aspect ratio.
388 struct ShrinkConstraint
398 * @param[in] current The object's current scale value
399 * @param[in] parentScale The parent's scale
400 * @return The object's new scale value
402 Vector3 operator()(const Vector3& current,
403 const PropertyInput& parentScale)
405 return Vector3( parentScale.GetVector3().x / parentScale.GetVector3().y, 1.0f, 1.0f );
409 } // unnamed namespace
412 * Custom position and size of shadow image
414 namespace ShadowProperty
416 const Vector3 ANCHOR_POINT (0.54f, 0.6f, 0.5f);
417 const Vector3 RELATIVE_POSITION (0.0f, 0.0f, -0.1f);
418 const Vector3 SIZE_SCALE (1.4f, 1.4f, 1.0f);
421 // This example shows how to use Cluster UI control
423 class ClusterController : public ConnectionTracker
429 * @param application class, stored as reference
431 ClusterController(Application &app)
434 mExampleEffect(NO_EFFECT)
436 // Connect to the Application's Init signal
437 app.InitSignal().Connect(this, &ClusterController::Create);
442 // Nothing to do here; everything gets deleted automatically
446 * This method gets called once the main loop of application is up and running
448 void Create(Application& application)
450 Stage::GetCurrent().KeyEventSignal().Connect(this, &ClusterController::OnKeyEvent);
452 Vector2 stageSize = Stage::GetCurrent().GetSize();
454 // The Init signal is received once (only) during the Application lifetime
456 // Hide the indicator bar
457 application.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
459 // Creates a default view with a default tool bar.
460 // The view is added to the stage.
461 mContentLayer = DemoHelper::CreateView( application,
468 // Create a effect toggle button. (right of toolbar)
469 mLayoutButtonImages[ NO_EFFECT ] = ResourceImage::New( LAYOUT_NONE_IMAGE );
470 mLayoutButtonImages[ WOBBLE_EFFECT ] = ResourceImage::New( LAYOUT_WOBBLE_IMAGE );
471 mLayoutButtonImages[ CAROUSEL_EFFECT ] = ResourceImage::New( LAYOUT_CAROUSEL_IMAGE );
472 mLayoutButtonImages[ SPHERE_EFFECT ] = ResourceImage::New( LAYOUT_SPHERE_IMAGE );
474 mLayoutButton = Toolkit::PushButton::New();
475 mLayoutButton.ClickedSignal().Connect( this, &ClusterController::OnEffectTouched );
476 mToolBar.AddControl( mLayoutButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight, DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
478 // create and setup the scroll view...
479 mScrollView = ScrollView::New();
480 mScrollView.SetSize(stageSize);
482 // attach Wobble Effect to ScrollView
483 mScrollViewEffect = ScrollViewWobbleEffect::New();
484 mScrollView.ApplyEffect(mScrollViewEffect);
486 // anchor the scroll view from its center point to the middle of its parent
487 mScrollView.SetAnchorPoint(AnchorPoint::CENTER);
488 mScrollView.SetParentOrigin(ParentOrigin::CENTER);
490 // Scale ScrollView to fit parent (mContentLayer)
491 mScrollView.SetSizeMode( SIZE_EQUAL_TO_PARENT );
493 // Add the scroll view to the content layer
494 mContentLayer.Add(mScrollView);
496 // Create the image border shared by all the cluster image actors
497 mClusterBorderImage = ResourceImage::New(CLUSTER_BORDER_IMAGE_PATH);
499 AddCluster( PEOPLE, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle1) );
500 AddCluster( TODAY, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle2) );
501 AddCluster( PHONE, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle3) );
502 AddCluster( PICTURES, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle4) );
503 AddCluster( MUSIC, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle2) );
504 AddCluster( MAGAZINE, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle3) );
506 SetEffect(WOBBLE_EFFECT);
510 * Helper to create the cluster actors
512 Cluster CreateClusterActor(ClusterType clusterType, ClusterStyle style)
514 // Create the cluster actor with the given cluster style
515 Cluster clusterActor = Cluster::New(style);
516 clusterActor.SetParentOrigin(ParentOrigin::CENTER);
517 clusterActor.SetAnchorPoint(AnchorPoint::CENTER);
519 Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
520 float minStageDimension = std::min(stageSize.x, stageSize.y);
521 clusterActor.SetSize(minStageDimension * CLUSTER_RELATIVE_SIZE, minStageDimension * CLUSTER_RELATIVE_SIZE, 0.0f);
523 DALI_ASSERT_ALWAYS(clusterType < CLUSTER_COUNT);
524 const char **paths = IMAGE_GROUPS[clusterType];
525 DALI_ASSERT_ALWAYS(paths);
527 // Add a background image to the cluster
528 Image bg = ResourceImage::New( CLUSTER_BACKGROUND_IMAGE_PATH );
529 ImageActor image = ImageActor::New(bg);
530 clusterActor.SetBackgroundImage(image);
532 // Add actors (pictures) as the children of the cluster
533 for (unsigned int i = 0; (i < style.GetMaximumNumberOfChildren()) && (*paths); i++, paths++)
535 clusterActor.AddChild(CreateClusterPictureActor(clusterType, *paths), i);
542 * Helper to create the picture actors in the cluster
544 Actor CreateClusterPictureActor(ClusterType clusterType, const std::string& imagePath)
546 // Create a picture for this cluster image
550 Actor actor = Actor::New();
551 actor.SetSize(CLUSTER_IMAGE_THUMBNAIL_WIDTH, CLUSTER_IMAGE_THUMBNAIL_HEIGHT);
552 actor.SetParentOrigin( ParentOrigin::CENTER );
553 actor.SetAnchorPoint( AnchorPoint::CENTER );
555 // Load the thumbnail
556 ImageAttributes attribs = ImageAttributes::New();
557 attribs.SetSize(CLUSTER_IMAGE_THUMBNAIL_WIDTH, CLUSTER_IMAGE_THUMBNAIL_HEIGHT);
558 attribs.SetScalingMode(Dali::ImageAttributes::ShrinkToFit);
560 // Add a shadow image child actor
561 Image shadowImage = ResourceImage::New( CLUSTER_SHADOW_IMAGE_PATH, attribs );
562 ImageActor shadowActor = ImageActor::New(shadowImage);
564 // Shadow is not exactly located on the center of the image, so it is moved to a little
565 // upper-left side of the image relatively using customised AnchorPoint.
566 shadowActor.SetParentOrigin(ShadowProperty::ANCHOR_POINT);
567 shadowActor.SetAnchorPoint(AnchorPoint::CENTER);
568 shadowActor.SetPosition(Vector3(0.0f, 0.0f, -1.0f));
570 // Apply size-relative mode to auto-size the image shadow
571 shadowActor.SetSizeMode( SIZE_RELATIVE_TO_PARENT );
572 shadowActor.SetSizeModeFactor( ShadowProperty::SIZE_SCALE );
573 actor.Add( shadowActor );
575 // Add a picture image actor to actor (with equal size to the parent).
576 Image image = ResourceImage::New( imagePath, attribs );
577 ImageActor imageActor = ImageActor::New( image );
578 imageActor.SetParentOrigin( ParentOrigin::CENTER );
579 imageActor.SetAnchorPoint( AnchorPoint::CENTER );
580 imageActor.SetSizeMode( SIZE_EQUAL_TO_PARENT );
581 actor.Add( imageActor );
583 // Add a border image child actor (with a fixed size offset from parent).
584 ImageActor borderActor = ImageActor::New( mClusterBorderImage );
585 borderActor.SetParentOrigin( ParentOrigin::CENTER );
586 borderActor.SetAnchorPoint( AnchorPoint::CENTER );
587 borderActor.SetStyle( ImageActor::STYLE_NINE_PATCH );
588 borderActor.SetNinePatchBorder( CLUSTER_IMAGE_BORDER_ABSOLUTE );
589 borderActor.SetPosition( Vector3( 0.0f, 0.0f, 1.0f ) );
590 borderActor.SetSizeMode( SIZE_FIXED_OFFSET_FROM_PARENT );
591 borderActor.SetSizeModeFactor( Vector3( CLUSTER_IMAGE_BORDER_INDENT - 1.0f, CLUSTER_IMAGE_BORDER_INDENT - 1.0f, 0.0f ) * 2.0f );
592 actor.Add( borderActor );
599 * Adds a Cluster to the ScrollView
601 * @param[in] clusterType The type of cluster (determines the image content)
602 * @param[in] style The style to be used for this cluster.
604 void AddCluster(ClusterType clusterType, ClusterStyle style)
606 Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
608 int column = mClusterCount>>1;
609 int row = mClusterCount&1;
611 float minStageDimension = std::min(stageSize.x, stageSize.y);
612 float clusterRightShift = 1.0f - CLUSTER_COLUMN_INDENT * 2.0f;
613 Vector3 clusterPosition = Vector3(CLUSTER_COLUMN_INDENT * stageSize.width + row * (clusterRightShift * stageSize.width - minStageDimension * CLUSTER_RELATIVE_SIZE),
614 CLUSTER_ROW_INDENT * stageSize.height + row * (clusterRightShift * stageSize.height - minStageDimension * CLUSTER_RELATIVE_SIZE), 0.0f);
616 Actor pageView = Actor::New();
617 mScrollView.Add(pageView);
618 pageView.SetParentOrigin(ParentOrigin::CENTER);
619 pageView.SetPosition(Vector3(stageSize.width * column, 0.0f, 0.0f));
620 pageView.SetSizeMode( SIZE_EQUAL_TO_PARENT );
622 // Create cluster actors, add them to scroll view, and set the shear effect with the given center point.
623 Cluster cluster = CreateClusterActor(clusterType, style);
624 cluster.SetParentOrigin(ParentOrigin::TOP_LEFT);
625 cluster.SetAnchorPoint(AnchorPoint::TOP_LEFT);
626 cluster.SetPosition( clusterPosition );
628 pageView.Add(cluster);
629 Vector3 clusterSize = cluster.GetCurrentSize();
631 mClusterInfo.push_back(ClusterInfo( cluster, mClusterCount, clusterPosition, clusterSize ));
637 * Resets ScrollView and Clusters settings
638 * to reflect the new ExampleEffectType
640 * TODO: Add animation transition to fade out of existing effect,
641 * and into new effect.
643 * @param[in] type The desired effect to switch to.
645 void SetEffect(ExampleEffectType type)
647 Vector2 stageSize(Dali::Stage::GetCurrent().GetSize());
649 mExampleEffect = type;
651 std::stringstream ss(APPLICATION_TITLE);
652 ss << APPLICATION_TITLE << ": " << EXAMPLE_EFFECT_LABEL[mExampleEffect];
655 // Set up default ruler settings (fixed in horizontal, disabled in vertical)
657 rulerX = new FixedRuler(stageSize.x);
658 int columns = (mClusterCount + 1) >> 1;
659 rulerX->SetDomain(RulerDomain(0.0f, stageSize.x * columns, true));
660 mScrollView.SetRulerX(rulerX);
662 RulerPtr rulerY = new DefaultRuler();
664 mScrollView.SetRulerY(rulerY);
666 mScrollView.SetActorAutoSnap(false);
668 // Remove all shader-effects from mScrollView and it's children (the clusters)
669 mScrollView.SetPosition(Vector3::ZERO);
671 mLayoutButton.SetBackgroundImage( mLayoutButtonImages[ type ] );
673 for( std::vector<ClusterInfo>::iterator i = mClusterInfo.begin(); i != mClusterInfo.end(); ++i )
675 Cluster cluster = i->mCluster;
676 RemoveShaderEffectRecursively( cluster );
677 if( i->mEffectConstraint )
679 cluster.RemoveConstraint(i->mEffectConstraint);
680 i->mEffectConstraint.Reset();
684 // Apply new shader-effects.
685 // Move Y to origin incase we came from an effect where user could free pan in y axis.
686 const Vector3 currentScrollPosition(mScrollView.GetCurrentScrollPosition());
687 mScrollView.ScrollTo(Vector3(currentScrollPosition.x, 0.0f, 0.0f));
698 for( std::vector<ClusterInfo>::iterator i = mClusterInfo.begin(); i != mClusterInfo.end(); ++i )
700 Cluster cluster = i->mCluster;
701 Vector3 position = i->mPosition;
702 Vector3 size = i->mSize;
704 ShearEffect shaderEffect = ShearEffect::New();
705 Vector3 shearAnchor = SHEAR_EFFECT_ANCHOR_POINT;
707 Vector2 shearCenter( Vector2(position.x + size.width * shearAnchor.x, position.y + size.height * shearAnchor.y) );
708 Property::Index centerProperty = shaderEffect.GetPropertyIndex(shaderEffect.GetCenterPropertyName());
709 Constraint constraint = Constraint::New<Vector2>( centerProperty,
710 Source(mView, Actor::SIZE),
711 ShearEffectCenterConstraint(stageSize, shearCenter) );
712 shaderEffect.ApplyConstraint(constraint);
714 SetShaderEffectRecursively( cluster,shaderEffect );
716 // Apply Constraint to Shader Effect
717 Property::Index scrollOvershootProperty = /*targetGroup*/mScrollView.GetPropertyIndex(ScrollViewWobbleEffect::EFFECT_OVERSHOOT);
718 Property::Index angleXAxisProperty = shaderEffect.GetPropertyIndex(shaderEffect.GetAngleXAxisPropertyName());
719 Property::Index angleYAxisProperty = shaderEffect.GetPropertyIndex(shaderEffect.GetAngleYAxisPropertyName());
721 constraint = Constraint::New<float>( angleXAxisProperty,
722 Source(mScrollView, scrollOvershootProperty),
723 Source(mView, Actor::ROTATION),
724 ShearEffectConstraint(stageSize, SHEAR_EFFECT_MAX_OVERSHOOT, Vector2::XAXIS) );
725 shaderEffect.ApplyConstraint(constraint);
726 constraint = Constraint::New<float>( angleYAxisProperty,
727 Source(mScrollView, scrollOvershootProperty),
728 Source(mView, Actor::ROTATION),
729 ShearEffectConstraint(stageSize, SHEAR_EFFECT_MAX_OVERSHOOT, Vector2::YAXIS) );
730 shaderEffect.ApplyConstraint(constraint);
737 case CAROUSEL_EFFECT:
739 // Apply Carousel Shader Effect to scrollView
740 CarouselEffect shaderEffect = CarouselEffect::New();
741 shaderEffect.SetRadius( -CAROUSEL_EFFECT_RADIUS );
742 // dont apply shader effect to scrollview as it might override internal shaders for bounce effect etc
743 for( std::vector<ClusterInfo>::iterator i = mClusterInfo.begin(); i != mClusterInfo.end(); ++i )
745 Cluster cluster = i->mCluster;
746 SetShaderEffectRecursively( cluster, shaderEffect );
748 mScrollView.SetPosition( Vector3( 0.0f, 0.0f, CAROUSEL_EFFECT_RADIUS ) );
750 const Vector2 angleSweep( CAROUSEL_EFFECT_ANGLE_SWEEP / stageSize.width,
751 CAROUSEL_EFFECT_ANGLE_SWEEP / stageSize.width );
753 Property::Index anglePerUnit = shaderEffect.GetPropertyIndex( shaderEffect.GetAnglePerUnitPropertyName() );
754 shaderEffect.ApplyConstraint( Constraint::New<Vector2>( anglePerUnit,
755 Source(mView, Actor::ROTATION),
756 CarouselEffectOrientationConstraint( angleSweep ) ) );
763 // Change ruler to free panning...
765 rulerX = new DefaultRuler();
766 int columns = (mClusterCount + 1) >> 1;
767 rulerX->SetDomain(RulerDomain(0.0f, stageSize.x * columns, true));
768 mScrollView.SetRulerX(rulerX);
770 RulerPtr rulerY = new DefaultRuler();
771 rulerY->SetDomain(RulerDomain( -stageSize.y * SPHERE_EFFECT_VERTICAL_DOMAIN, stageSize.y * (1.0f + SPHERE_EFFECT_VERTICAL_DOMAIN), true));
772 mScrollView.SetRulerY(rulerY);
774 // Apply Carousel Shader Effect to scrollView (Spherical style)
775 CarouselEffect shaderEffect = CarouselEffect::New();
777 shaderEffect.SetRadius( SPHERE_EFFECT_RADIUS );
778 shaderEffect.SetAnglePerUnit( Vector2( SPHERE_EFFECT_ANGLE_SWEEP / stageSize.y, SPHERE_EFFECT_ANGLE_SWEEP / stageSize.y ) );
779 // dont apply shader effect to scrollview as it might override internal shaders for bounce effect etc
780 for( std::vector<ClusterInfo>::iterator i = mClusterInfo.begin(); i != mClusterInfo.end(); ++i )
782 Constraint constraint = Constraint::New<float>(Actor::POSITION_Z, SphereEffectOffsetConstraint(SPHERE_EFFECT_POSITION_Z));
783 constraint.SetRemoveAction(Constraint::Discard);
784 Cluster cluster = i->mCluster;
785 SetShaderEffectRecursively( cluster, shaderEffect );
786 i->mEffectConstraint = cluster.ApplyConstraint(constraint);
798 * Signal handler, called when quit button is pressed
800 bool OnEffectTouched( Toolkit::Button button )
802 // quit the application
803 SetEffect(static_cast<ExampleEffectType>( (mExampleEffect + 1) % TOTAL_EFFECTS) );
808 * Sets/Updates the title of the View
809 * @param[in] title The new title for the view.
811 void SetTitle(const std::string& title)
815 mTitleActor = TextView::New();
816 // Add title to the tool bar.
817 mToolBar.AddControl( mTitleActor, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarTitlePercentage, Alignment::HorizontalCenter );
820 Font font = Font::New();
821 mTitleActor.SetText( title );
822 mTitleActor.SetSize( font.MeasureText( title ) );
823 mTitleActor.SetStyleToCurrentText(DemoHelper::GetDefaultTextStyle());
827 * Main key event handler
829 void OnKeyEvent(const KeyEvent& event)
831 if(event.state == KeyEvent::Down)
833 if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
842 Application& mApplication; ///< Application instance
843 Toolkit::View mView; ///< The View instance.
844 Toolkit::ToolBar mToolBar; ///< The View's Toolbar.
845 TextView mTitleActor; ///< The Toolbar's Title.
847 Layer mContentLayer; ///< Content layer (scrolling cluster content)
849 ScrollView mScrollView; ///< The ScrollView container for all clusters
850 ScrollViewWobbleEffect mScrollViewEffect; ///< ScrollView Wobble effect
851 Image mClusterBorderImage; ///< The border frame that appears on each image
853 std::vector<ClusterInfo> mClusterInfo; ///< Keeps track of each cluster's information.
854 int mClusterCount; ///< Current number of clusters in use
855 ExampleEffectType mExampleEffect; ///< Current example effect.
857 Toolkit::PushButton mLayoutButton; ///< The layout button
858 Image mLayoutButtonImages[TOTAL_EFFECTS]; ///< Image when no layout
861 void RunTest(Application& app)
863 ClusterController test(app);
868 // Entry point for Linux & SLP applications
870 int main(int argc, char **argv)
872 Application app = Application::New(&argc, &argv);