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;
203 * Rescales the inputer scale by the ratio of the height:width of it's parent.
205 struct RescaleConstraint
209 * @param[in] value0 Constant multiplication operand (K).
216 * @param[in] current The object's current property value
217 * @param[in] property0 The first property to multiplication operand
218 * @return The object's new property value
220 Vector3 operator()(const Vector3& current,
221 const PropertyInput& property0)
223 return current * Vector3( property0.GetVector3().y / property0.GetVector3().x, 1.0f, 1.0f );
229 * ClusterImageBorderSizeConstraint
231 struct ClusterImageBorderSizeConstraint
233 ClusterImageBorderSizeConstraint()
234 : mSizeOffset(Vector3(CLUSTER_IMAGE_BORDER_INDENT - 1, CLUSTER_IMAGE_BORDER_INDENT - 1, 0.0f) * 2.0f)
238 Vector3 operator()(const Vector3& current,
239 const PropertyInput& referenceSizeProperty)
241 const Vector3& referenceSize = referenceSizeProperty.GetVector3();
243 return referenceSize + mSizeOffset;
246 Vector3 mSizeOffset; ///< The amount to offset the size from referenceSize
250 * ShearEffectConstraint
252 * Constrains ShearEffect's tilt to be a function of scrollview's
253 * horizontal overshoot amount.
255 struct ShearEffectConstraint
258 * @param[in] stageSize The stage size (not subject to orientation)
259 * @param[in] maxOvershoot Maximum amount overshoot can affect shear.
260 * @param[in] componentMask Whether constraint should take the X shear
261 * or the Y shear component.
263 ShearEffectConstraint(Vector2 stageSize, float maxOvershoot, Vector2 componentMask)
264 : mStageSize(stageSize),
265 mMaxOvershoot(maxOvershoot),
266 mComponentMask(componentMask)
271 * @param[in] current The current shear effect Angle.
272 * @param[in] scrollOvershootProperty The overshoot property from ScrollView
273 * @param[in] propertyViewOrientation The orientation of the view e.g. Portrait, Landscape.
274 * @return angle to provide ShearShaderEffect
276 float operator()(const float& current,
277 const PropertyInput& scrollOvershootProperty,
278 const PropertyInput& propertyViewOrientation)
280 float f = scrollOvershootProperty.GetVector3().x;
282 float mag = fabsf(f);
283 float halfWidth = mStageSize.x * 0.5f;
285 // inverse exponential tail-off
286 float overshoot = 1.0f - halfWidth / (halfWidth + mag);
289 overshoot = -overshoot;
292 // Channel this shear value into either the X or Y axis depending on
293 // the component mask passed in.
296 propertyViewOrientation.GetQuaternion().ToAxisAngle( axis, angle );
297 Vector2 direction( cosf(angle), sinf(angle) );
298 float yield = direction.x * mComponentMask.x + direction.y * mComponentMask.y;
300 return overshoot * mMaxOvershoot * yield;
305 Vector2 mComponentMask;
309 * ShearEffectCenterConstraint
311 * Sets ShearEffect's center to be a function of the
312 * screen orientation (portrait or landscape).
314 struct ShearEffectCenterConstraint
317 * @param[in] stageSize The stage size (not subject to orientation)
318 * @param[in] center Shear Center position based on initial orientation.
320 ShearEffectCenterConstraint(Vector2 stageSize, Vector2 center)
321 : mStageSize(stageSize),
327 * @param[in] current The current center
328 * @param[in] propertyViewSize The current view size
329 * @return vector to provide ShearShaderEffect
331 Vector2 operator()(const Vector2& current,
332 const PropertyInput& propertyViewSize)
334 float f = propertyViewSize.GetVector3().width / mStageSize.width;
335 return Vector2( f * mCenter.x, mCenter.y );
343 * SphereEffectOffsetConstraint
345 * Sets SphereEffect's center to be a function of the
346 * screen orientation (portrait or landscape).
348 struct SphereEffectOffsetConstraint
351 * @param[in] stageSize The stage size (not subject to orientation)
352 * @param[in] center Shear Center position based on initial orientation.
354 SphereEffectOffsetConstraint(float offset)
360 * @param[in] current The current center
361 * @param[in] propertyViewSize The current view size
362 * @return vector to provide SphereShaderEffect
364 float operator()(const float& current)
366 return current + mOffset;
375 * Contains information about each cluster in mClusterInfo list.
382 * @param[in] cluster The cluster instance
383 * @param[in] index The cluster's index (starting from 0 for the first cluster)
384 * @param[in] position The cluster's original position
385 * @param[in] size The cluster's original size
387 ClusterInfo(Cluster cluster, int index, const Vector3& position, const Vector3& size)
399 * @param[in] rhs The ClusterInfo struct to be copied.
401 ClusterInfo( const ClusterInfo& rhs )
402 : mCluster(rhs.mCluster),
404 mPosition(rhs.mPosition),
411 * Assignment operator
413 ClusterInfo& operator=( const ClusterInfo& rhs )
417 mCluster = rhs.mCluster;
419 mPosition = rhs.mPosition;
426 Cluster mCluster; ///< Cluster instance
427 int mIndex; ///< Cluster index
428 Vector3 mPosition; ///< Cluster original position
429 Vector3 mSize; ///< Cluster original size
430 ActiveConstraint mEffectConstraint; ///< Cluster constraint
434 * Shrinks Actor based on parent's aspect ratio.
436 struct ShrinkConstraint
446 * @param[in] current The object's current scale value
447 * @param[in] parentScale The parent's scale
448 * @return The object's new scale value
450 Vector3 operator()(const Vector3& current,
451 const PropertyInput& parentScale)
453 return Vector3( parentScale.GetVector3().x / parentScale.GetVector3().y, 1.0f, 1.0f );
457 } // unnamed namespace
460 * Custom position and size of shadow image
462 namespace ShadowProperty
464 const Vector3 ANCHOR_POINT (0.54f, 0.6f, 0.5f);
465 const Vector3 RELATIVE_POSITION (0.0f, 0.0f, -0.1f);
466 const Vector3 SIZE_SCALE (1.4f, 1.4f, 1.0f);
469 // This example shows how to use Cluster UI control
471 class ClusterController : public ConnectionTracker
477 * @param application class, stored as reference
479 ClusterController(Application &app)
482 mExampleEffect(NO_EFFECT)
484 // Connect to the Application's Init signal
485 app.InitSignal().Connect(this, &ClusterController::Create);
490 // Nothing to do here; everything gets deleted automatically
494 * This method gets called once the main loop of application is up and running
496 void Create(Application& application)
498 Stage::GetCurrent().KeyEventSignal().Connect(this, &ClusterController::OnKeyEvent);
500 Vector2 stageSize = Stage::GetCurrent().GetSize();
502 // The Init signal is received once (only) during the Application lifetime
504 // Hide the indicator bar
505 application.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
507 // Creates a default view with a default tool bar.
508 // The view is added to the stage.
509 mContentLayer = DemoHelper::CreateView( application,
516 // Create a effect toggle button. (right of toolbar)
517 mLayoutButtonImages[ NO_EFFECT ] = Image::New( LAYOUT_NONE_IMAGE );
518 mLayoutButtonImages[ WOBBLE_EFFECT ] = Image::New( LAYOUT_WOBBLE_IMAGE );
519 mLayoutButtonImages[ CAROUSEL_EFFECT ] = Image::New( LAYOUT_CAROUSEL_IMAGE );
520 mLayoutButtonImages[ SPHERE_EFFECT ] = Image::New( LAYOUT_SPHERE_IMAGE );
522 mLayoutButton = Toolkit::PushButton::New();
523 mLayoutButton.ClickedSignal().Connect( this, &ClusterController::OnEffectTouched );
524 mToolBar.AddControl( mLayoutButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight, DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
526 // create and setup the scroll view...
527 mScrollView = ScrollView::New();
528 mScrollView.SetSize(stageSize);
530 // attach Wobble Effect to ScrollView
531 mScrollViewEffect = ScrollViewWobbleEffect::New();
532 mScrollView.ApplyEffect(mScrollViewEffect);
534 // anchor the scroll view from its center point to the middle of its parent
535 mScrollView.SetAnchorPoint(AnchorPoint::CENTER);
536 mScrollView.SetParentOrigin(ParentOrigin::CENTER);
538 // Scale ScrollView to fit within parent (mContentLayer)
539 Constraint constraint = Constraint::New<Vector3>( Actor::SCALE,
540 LocalSource( Actor::SIZE ),
541 ParentSource( Actor::SIZE ),
542 ScaleToFitConstraint() );
543 mScrollView.ApplyConstraint(constraint);
545 // Add the scroll view to the content layer
546 mContentLayer.Add(mScrollView);
548 // Create the image border shared by all the cluster image actors
549 mClusterBorderImage = Image::New(CLUSTER_BORDER_IMAGE_PATH);
551 AddCluster( PEOPLE, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle1) );
552 AddCluster( TODAY, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle2) );
553 AddCluster( PHONE, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle3) );
554 AddCluster( PICTURES, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle4) );
555 AddCluster( MUSIC, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle2) );
556 AddCluster( MAGAZINE, ClusterStyleStandard::New(ClusterStyleStandard::ClusterStyle3) );
558 SetEffect(WOBBLE_EFFECT);
562 * Helper to create the cluster actors
564 Cluster CreateClusterActor(ClusterType clusterType, ClusterStyle style)
566 // Create the cluster actor with the given cluster style
567 Cluster clusterActor = Cluster::New(style);
568 clusterActor.SetParentOrigin(ParentOrigin::CENTER);
569 clusterActor.SetAnchorPoint(AnchorPoint::CENTER);
571 Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
572 float minStageDimension = std::min(stageSize.x, stageSize.y);
573 clusterActor.SetSize(minStageDimension * CLUSTER_RELATIVE_SIZE, minStageDimension * CLUSTER_RELATIVE_SIZE, 0.0f);
575 DALI_ASSERT_ALWAYS(clusterType < CLUSTER_COUNT);
576 const char **paths = IMAGE_GROUPS[clusterType];
577 DALI_ASSERT_ALWAYS(paths);
579 // Add a background image to the cluster
580 Image bg = Image::New( CLUSTER_BACKGROUND_IMAGE_PATH );
581 ImageActor image = ImageActor::New(bg);
582 clusterActor.SetBackgroundImage(image);
584 // Add actors (pictures) as the children of the cluster
585 for (unsigned int i = 0; (i < style.GetMaximumNumberOfChildren()) && (*paths); i++, paths++)
587 clusterActor.AddChild(CreateClusterPictureActor(clusterType, *paths), i);
594 * Helper to create the picture actors in the cluster
596 Actor CreateClusterPictureActor(ClusterType clusterType, const std::string& imagePath)
598 // Create a picture for this cluster image
602 Actor actor = Actor::New();
603 actor.SetSize(CLUSTER_IMAGE_THUMBNAIL_WIDTH, CLUSTER_IMAGE_THUMBNAIL_HEIGHT);
604 actor.SetParentOrigin( ParentOrigin::CENTER );
605 actor.SetAnchorPoint( AnchorPoint::CENTER );
607 // Load the thumbnail
608 ImageAttributes attribs = ImageAttributes::New();
609 attribs.SetSize(CLUSTER_IMAGE_THUMBNAIL_WIDTH, CLUSTER_IMAGE_THUMBNAIL_HEIGHT);
610 attribs.SetScalingMode(Dali::ImageAttributes::ShrinkToFit);
611 attribs.SetPixelFormat( Pixel::RGB888 );
613 // Add a shadow image child actor
614 Image shadowImage = Image::New( CLUSTER_SHADOW_IMAGE_PATH, attribs );
615 ImageActor shadowActor = ImageActor::New(shadowImage);
617 // Shadow is not exactly located on the center of the image, so it is moved to a little
618 // upper-left side of the image relatively using customised AnchorPoint.
619 shadowActor.SetParentOrigin(ShadowProperty::ANCHOR_POINT);
620 shadowActor.SetAnchorPoint(AnchorPoint::CENTER);
621 shadowActor.SetPosition(Vector3(0.0f, 0.0f, -1.0f));
623 // Apply size constraint to the image shadow
624 shadowActor.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), RelativeToConstraint( ShadowProperty::SIZE_SCALE ) ) );
625 actor.Add(shadowActor);
627 // Add a picture image actor to actor.
628 Image image = Image::New( imagePath, attribs );
629 ImageActor imageActor = ImageActor::New(image);
630 imageActor.SetParentOrigin( ParentOrigin::CENTER );
631 imageActor.SetAnchorPoint( AnchorPoint::CENTER );
632 imageActor.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
633 actor.Add(imageActor);
635 // Add a border image child actor
636 ImageActor borderActor = ImageActor::New(mClusterBorderImage);
637 borderActor.SetParentOrigin( ParentOrigin::CENTER );
638 borderActor.SetAnchorPoint( AnchorPoint::CENTER );
639 borderActor.SetStyle( ImageActor::STYLE_NINE_PATCH );
640 borderActor.SetNinePatchBorder( CLUSTER_IMAGE_BORDER_ABSOLUTE );
641 borderActor.SetPosition(Vector3(0.0f, 0.0f, 1.0f));
643 // Apply size constraint to the image border
644 Constraint constraint = Constraint::New<Vector3>(Actor::SIZE,
645 ParentSource(Actor::SIZE),
646 ClusterImageBorderSizeConstraint());
647 borderActor.ApplyConstraint(constraint);
648 actor.Add(borderActor);
655 * Adds a Cluster to the ScrollView
657 * @param[in] clusterType The type of cluster (determines the image content)
658 * @param[in] style The style to be used for this cluster.
660 void AddCluster(ClusterType clusterType, ClusterStyle style)
662 Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
664 int column = mClusterCount>>1;
665 int row = mClusterCount&1;
667 float minStageDimension = std::min(stageSize.x, stageSize.y);
668 float clusterRightShift = 1.0f - CLUSTER_COLUMN_INDENT * 2.0f;
669 Vector3 clusterPosition = Vector3(CLUSTER_COLUMN_INDENT * stageSize.width + row * (clusterRightShift * stageSize.width - minStageDimension * CLUSTER_RELATIVE_SIZE),
670 CLUSTER_ROW_INDENT * stageSize.height + row * (clusterRightShift * stageSize.height - minStageDimension * CLUSTER_RELATIVE_SIZE), 0.0f);
672 Actor pageView = Actor::New();
673 mScrollView.Add(pageView);
674 pageView.SetParentOrigin(ParentOrigin::CENTER);
675 pageView.SetPosition(Vector3(stageSize.width * column, 0.0f, 0.0f));
676 pageView.SetSize(stageSize);
678 // Resize pageView (which contains a Cluster)
679 Constraint constraintScale = Constraint::New<Vector3>( Actor::SCALE,
680 ParentSource( Actor::SCALE ),
681 RescaleConstraint() );
682 constraintScale.SetRemoveAction(Constraint::Discard);
683 pageView.ApplyConstraint(constraintScale);
685 // Create cluster actors, add them to scroll view, and set the shear effect with the given center point.
686 Cluster cluster = CreateClusterActor(clusterType, style);
687 cluster.SetParentOrigin(ParentOrigin::TOP_LEFT);
688 cluster.SetAnchorPoint(AnchorPoint::TOP_LEFT);
689 cluster.SetPosition( clusterPosition );
691 pageView.Add(cluster);
692 Vector3 clusterSize = cluster.GetCurrentSize();
694 mClusterInfo.push_back(ClusterInfo( cluster, mClusterCount, clusterPosition, clusterSize ));
700 * Resets ScrollView and Clusters settings
701 * to reflect the new ExampleEffectType
703 * TODO: Add animation transition to fade out of existing effect,
704 * and into new effect.
706 * @param[in] type The desired effect to switch to.
708 void SetEffect(ExampleEffectType type)
710 Vector2 stageSize(Dali::Stage::GetCurrent().GetSize());
712 mExampleEffect = type;
714 std::stringstream ss(APPLICATION_TITLE);
715 ss << APPLICATION_TITLE << ": " << EXAMPLE_EFFECT_LABEL[mExampleEffect];
718 // Set up default ruler settings (fixed in horizontal, disabled in vertical)
720 rulerX = new FixedRuler(stageSize.x);
721 int columns = (mClusterCount + 1) >> 1;
722 rulerX->SetDomain(RulerDomain(0.0f, stageSize.x * columns, true));
723 mScrollView.SetRulerX(rulerX);
725 RulerPtr rulerY = new DefaultRuler();
727 mScrollView.SetRulerY(rulerY);
729 mScrollView.SetActorAutoSnap(false);
731 // Remove all shader-effects from mScrollView and it's children (the clusters)
732 mScrollView.SetPosition(Vector3::ZERO);
734 mLayoutButton.SetBackgroundImage( mLayoutButtonImages[ type ] );
736 for( std::vector<ClusterInfo>::iterator i = mClusterInfo.begin(); i != mClusterInfo.end(); ++i )
738 Cluster cluster = i->mCluster;
739 RemoveShaderEffectRecursively( cluster );
740 if( i->mEffectConstraint )
742 cluster.RemoveConstraint(i->mEffectConstraint);
743 i->mEffectConstraint.Reset();
747 // Apply new shader-effects.
748 // Move Y to origin incase we came from an effect where user could free pan in y axis.
749 const Vector3 currentScrollPosition(mScrollView.GetCurrentScrollPosition());
750 mScrollView.ScrollTo(Vector3(currentScrollPosition.x, 0.0f, 0.0f));
761 for( std::vector<ClusterInfo>::iterator i = mClusterInfo.begin(); i != mClusterInfo.end(); ++i )
763 Cluster cluster = i->mCluster;
764 Vector3 position = i->mPosition;
765 Vector3 size = i->mSize;
767 ShearEffect shaderEffect = ShearEffect::New();
768 Vector3 shearAnchor = SHEAR_EFFECT_ANCHOR_POINT;
770 Vector2 shearCenter( Vector2(position.x + size.width * shearAnchor.x, position.y + size.height * shearAnchor.y) );
771 Property::Index centerProperty = shaderEffect.GetPropertyIndex(shaderEffect.GetCenterPropertyName());
772 Constraint constraint = Constraint::New<Vector2>( centerProperty,
773 Source(mView, Actor::SIZE),
774 ShearEffectCenterConstraint(stageSize, shearCenter) );
775 shaderEffect.ApplyConstraint(constraint);
777 SetShaderEffectRecursively( cluster,shaderEffect );
779 // Apply Constraint to Shader Effect
780 Property::Index scrollOvershootProperty = /*targetGroup*/mScrollView.GetPropertyIndex(ScrollViewWobbleEffect::EFFECT_OVERSHOOT);
781 Property::Index angleXAxisProperty = shaderEffect.GetPropertyIndex(shaderEffect.GetAngleXAxisPropertyName());
782 Property::Index angleYAxisProperty = shaderEffect.GetPropertyIndex(shaderEffect.GetAngleYAxisPropertyName());
784 constraint = Constraint::New<float>( angleXAxisProperty,
785 Source(mScrollView, scrollOvershootProperty),
786 Source(mView, Actor::ROTATION),
787 ShearEffectConstraint(stageSize, SHEAR_EFFECT_MAX_OVERSHOOT, Vector2::XAXIS) );
788 shaderEffect.ApplyConstraint(constraint);
789 constraint = Constraint::New<float>( angleYAxisProperty,
790 Source(mScrollView, scrollOvershootProperty),
791 Source(mView, Actor::ROTATION),
792 ShearEffectConstraint(stageSize, SHEAR_EFFECT_MAX_OVERSHOOT, Vector2::YAXIS) );
793 shaderEffect.ApplyConstraint(constraint);
800 case CAROUSEL_EFFECT:
802 // Apply Carousel Shader Effect to scrollView
803 CarouselEffect shaderEffect = CarouselEffect::New();
804 shaderEffect.SetRadius( -CAROUSEL_EFFECT_RADIUS );
805 // dont apply shader effect to scrollview as it might override internal shaders for bounce effect etc
806 for( std::vector<ClusterInfo>::iterator i = mClusterInfo.begin(); i != mClusterInfo.end(); ++i )
808 Cluster cluster = i->mCluster;
809 SetShaderEffectRecursively( cluster, shaderEffect );
811 mScrollView.SetPosition( Vector3( 0.0f, 0.0f, CAROUSEL_EFFECT_RADIUS ) );
813 const Vector2 angleSweep( CAROUSEL_EFFECT_ANGLE_SWEEP / stageSize.width,
814 CAROUSEL_EFFECT_ANGLE_SWEEP / stageSize.width );
816 Property::Index anglePerUnit = shaderEffect.GetPropertyIndex( shaderEffect.GetAnglePerUnitPropertyName() );
817 shaderEffect.ApplyConstraint( Constraint::New<Vector2>( anglePerUnit,
818 Source(mView, Actor::ROTATION),
819 CarouselEffectOrientationConstraint( angleSweep ) ) );
826 // Change ruler to free panning...
828 rulerX = new DefaultRuler();
829 int columns = (mClusterCount + 1) >> 1;
830 rulerX->SetDomain(RulerDomain(0.0f, stageSize.x * columns, true));
831 mScrollView.SetRulerX(rulerX);
833 RulerPtr rulerY = new DefaultRuler();
834 rulerY->SetDomain(RulerDomain( -stageSize.y * SPHERE_EFFECT_VERTICAL_DOMAIN, stageSize.y * (1.0f + SPHERE_EFFECT_VERTICAL_DOMAIN), true));
835 mScrollView.SetRulerY(rulerY);
837 // Apply Carousel Shader Effect to scrollView (Spherical style)
838 CarouselEffect shaderEffect = CarouselEffect::New();
840 shaderEffect.SetRadius( SPHERE_EFFECT_RADIUS );
841 shaderEffect.SetAnglePerUnit( Vector2( SPHERE_EFFECT_ANGLE_SWEEP / stageSize.y, SPHERE_EFFECT_ANGLE_SWEEP / stageSize.y ) );
842 // dont apply shader effect to scrollview as it might override internal shaders for bounce effect etc
843 for( std::vector<ClusterInfo>::iterator i = mClusterInfo.begin(); i != mClusterInfo.end(); ++i )
845 Constraint constraint = Constraint::New<float>(Actor::POSITION_Z, SphereEffectOffsetConstraint(SPHERE_EFFECT_POSITION_Z));
846 constraint.SetRemoveAction(Constraint::Discard);
847 Cluster cluster = i->mCluster;
848 SetShaderEffectRecursively( cluster, shaderEffect );
849 i->mEffectConstraint = cluster.ApplyConstraint(constraint);
861 * Signal handler, called when quit button is pressed
863 bool OnEffectTouched( Toolkit::Button button )
865 // quit the application
866 SetEffect(static_cast<ExampleEffectType>( (mExampleEffect + 1) % TOTAL_EFFECTS) );
871 * Sets/Updates the title of the View
872 * @param[in] title The new title for the view.
874 void SetTitle(const std::string& title)
878 mTitleActor = TextView::New();
879 // Add title to the tool bar.
880 mToolBar.AddControl( mTitleActor, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarTitlePercentage, Alignment::HorizontalCenter );
883 Font font = Font::New();
884 mTitleActor.SetText( title );
885 mTitleActor.SetSize( font.MeasureText( title ) );
886 mTitleActor.SetStyleToCurrentText(DemoHelper::GetDefaultTextStyle());
890 * Main key event handler
892 void OnKeyEvent(const KeyEvent& event)
894 if(event.state == KeyEvent::Down)
896 if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
905 Application& mApplication; ///< Application instance
906 Toolkit::View mView; ///< The View instance.
907 Toolkit::ToolBar mToolBar; ///< The View's Toolbar.
908 TextView mTitleActor; ///< The Toolbar's Title.
910 Layer mContentLayer; ///< Content layer (scrolling cluster content)
912 ScrollView mScrollView; ///< The ScrollView container for all clusters
913 ScrollViewWobbleEffect mScrollViewEffect; ///< ScrollView Wobble effect
914 Image mClusterBorderImage; ///< The border frame that appears on each image
916 std::vector<ClusterInfo> mClusterInfo; ///< Keeps track of each cluster's information.
917 int mClusterCount; ///< Current number of clusters in use
918 ExampleEffectType mExampleEffect; ///< Current example effect.
920 Toolkit::PushButton mLayoutButton; ///< The layout button
921 Image mLayoutButtonImages[TOTAL_EFFECTS]; ///< Image when no layout
924 void RunTest(Application& app)
926 ClusterController test(app);
931 // Entry point for Linux & SLP applications
933 int main(int argc, char **argv)
935 Application app = Application::New(&argc, &argv);