2 * Copyright (c) 2017 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.
19 #include <dali/dali.h>
20 #include <dali-toolkit/dali-toolkit.h>
21 #include <dali/devel-api/actors/actor-devel.h>
22 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
23 #include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
26 #include "clipping-item-factory.h"
27 #include "item-view-orientation-constraint.h"
30 using namespace Dali::Toolkit;
34 const char * const APPLICATION_TITLE( "Clipping Controls" );
35 const Vector3 APPLICATION_TITLE_PARENT_ORIGIN( 0.5f, 0.03f, 0.5f ); // Set the parent origin to a small percentage below the top (so the demo will scale for different resolutions).
37 const Vector3 ITEM_VIEW_LAYOUT_SIZE_SCALE( 0.75f, 0.5f, 0.75f );
38 const float ITEM_VIEW_BORDER_SIZE = 2.0f;
39 const float ITEM_VIEW_MAXIMUM_ROTATION_IN_DEGREES = 20.0f;
40 const float ITEM_VIEW_LAYOUT_POSITION_CHANGE_MULTIPLIER = 3.0f;
41 const float ITEM_VIEW_ROTATION_ANIMATION_TIME = 0.2f;
43 const char * const BUTTON_LABEL( "Toggle Clipping Mode" );
44 } // unnamed namespace
47 * @brief Demonstrates the control clipping of a UI Control.
49 * When an Actor is set to clip its children, the renderers have to be added manually in order to specify what its children
50 * need to clip to. UI Controls automate the creation of the renderers/visuals when they are set to clip their children.
52 * This example displays an item-view whose clipping mode is toggled without the need for adding any renderers to it.
54 * Additionally, a constraint is used to modify the item-view's orientation.
56 class ClippingExample : public ConnectionTracker
62 * @param[in] application A reference to the Application class.
64 ClippingExample( Application& application )
65 : mApplication( application )
67 // Connect to the Application's Init signal
68 mApplication.InitSignal().Connect( this, &ClippingExample::Create );
74 * @brief Called to initialise the application content.
75 * @param[in] application A reference to the Application class.
77 void Create( Application& application )
79 // Hide the indicator bar
80 application.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
82 // Connect to the stage's key signal to allow Back and Escape to exit.
83 Stage stage = Dali::Stage::GetCurrent();
84 stage.KeyEventSignal().Connect( this, &ClippingExample::OnKeyEvent );
86 // Create a TextLabel for the application title.
87 Toolkit::TextLabel label = Toolkit::TextLabel::New( APPLICATION_TITLE );
88 label.SetAnchorPoint( AnchorPoint::TOP_CENTER );
89 label.SetParentOrigin( APPLICATION_TITLE_PARENT_ORIGIN );
90 label.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
91 label.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
92 label.SetProperty( Toolkit::TextLabel::Property::TEXT_COLOR, Color::WHITE );
95 // Create an item-view which clips its children.
96 mItemView = ItemView::New( mClippingItemFactory );
97 mItemView.SetParentOrigin( ParentOrigin::CENTER );
98 mItemView.SetAnchorPoint( AnchorPoint::CENTER );
99 mItemView.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); // Enable clipping. No need to create any renderers.
100 stage.Add( mItemView );
102 // Create a Spiral Layout and add it to the Item View.
103 mItemView.AddLayout( * DefaultItemLayout::New( DefaultItemLayout::SPIRAL ) );
104 stage.GetRootLayer().SetBehavior( Layer::LAYER_3D ); // The item-view spiral layout requires Layer 3D behaviour.
106 // Calculate the size we would like our item-view layout to be, and then activate the layout.
107 const Vector2 stageSize = stage.GetSize();
108 const Vector3 itemViewLayoutSize( ITEM_VIEW_LAYOUT_SIZE_SCALE.x * stageSize.x, ITEM_VIEW_LAYOUT_SIZE_SCALE.y * stageSize.y, ITEM_VIEW_LAYOUT_SIZE_SCALE.z * stageSize.x );
109 mItemView.ActivateLayout( 0, itemViewLayoutSize, 0.0f );
111 // Connect to the scroll started and completed signals to apply orientation constraints & animations.
112 mItemView.ScrollStartedSignal().Connect( this, &ClippingExample::ScrollStarted );
113 mItemView.ScrollCompletedSignal().Connect( this, &ClippingExample::ScrollCompleted );
115 // Create a constraint for the item-view which we apply when we start scrolling and remove when we stop.
116 mItemViewOrientationConstraint = Constraint::New< Quaternion >( mItemView, Actor::Property::ORIENTATION, ItemViewOrientationConstraint( ITEM_VIEW_MAXIMUM_ROTATION_IN_DEGREES, ITEM_VIEW_LAYOUT_POSITION_CHANGE_MULTIPLIER ) );
117 mItemViewOrientationConstraint.AddSource( LocalSource( ItemView::Property::LAYOUT_POSITION ) );
119 // Create a border around item-view (as item-view is clipping its children, we should NOT add this as a child of item-view).
120 Control border = Control::New();
121 border.SetParentOrigin( ParentOrigin::CENTER );
122 border.SetAnchorPoint( AnchorPoint::CENTER );
123 border.SetProperty( Control::Property::BACKGROUND,
124 Property::Map().Add( Visual::Property::TYPE, Visual::BORDER )
125 .Add( BorderVisual::Property::COLOR, Color::WHITE )
126 .Add( BorderVisual::Property::SIZE, 2.0f )
127 .Add( BorderVisual::Property::ANTI_ALIASING, true ) );
128 border.SetSize( Vector3( itemViewLayoutSize.x + ITEM_VIEW_BORDER_SIZE * 2.0f, itemViewLayoutSize.y + ITEM_VIEW_BORDER_SIZE * 2.0f, itemViewLayoutSize.z + ITEM_VIEW_BORDER_SIZE * 2.0f ) );
131 // Constrain the border's orientation to the orientation of item-view.
132 Constraint constraint = Constraint::New< Quaternion >( border, Actor::Property::ORIENTATION, EqualToConstraint() );
133 constraint.AddSource( Source( mItemView, Actor::Property::ORIENTATION ) );
136 // Create a button to toggle the clipping mode
137 PushButton button = Toolkit::PushButton::New();
138 button.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
139 button.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
140 button.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
141 button.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
142 button.SetProperty( Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D );
143 button.SetProperty( Button::Property::LABEL, BUTTON_LABEL );
144 button.ClickedSignal().Connect( this, &ClippingExample::OnButtonClicked );
149 * @brief Called when the item-view starts to scroll.
151 * Here we want to apply the item-view constraint.
153 void ScrollStarted( const Vector2& /* currentScrollPosition */ )
155 mItemViewOrientationConstraint.Apply();
159 * @brief Called when the item-view scrolling completes.
161 * Here we remove the item-view orientation constraint and perform an animation to return the item-view back to base-rotation.
163 void ScrollCompleted( const Vector2& /* currentScrollPosition */ )
165 Animation animation = Animation::New( ITEM_VIEW_ROTATION_ANIMATION_TIME );
166 animation.AnimateTo( Property( mItemView, Actor::Property::ORIENTATION ), Quaternion( Degree( 0.0f ), Vector3::XAXIS ), AlphaFunction::EASE_IN_SINE );
169 mItemViewOrientationConstraint.Remove();
173 * @brief Called when any key event is received
175 * Will use this to quit the application if Back or the Escape key is received
176 * @param[in] event The key event information
178 void OnKeyEvent( const KeyEvent& event )
180 if( event.state == KeyEvent::Down )
182 if( IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK ) )
190 * @brief Called when the button is clicked.
192 * Will use this to toggle between the clipping modes.
193 * @param[in] button The button that has been clicked.
195 bool OnButtonClicked( Toolkit::Button button )
199 ClippingMode::Type currentMode = static_cast< ClippingMode::Type >( mItemView.GetProperty( Actor::Property::CLIPPING_MODE ).Get< int >() );
200 mItemView.SetProperty( Actor::Property::CLIPPING_MODE, ( currentMode == ClippingMode::CLIP_CHILDREN ) ? ClippingMode::DISABLED : ClippingMode::CLIP_CHILDREN );
207 Application& mApplication; ///< Reference to the application class.
208 ItemView mItemView; ///< The item view which whose children we would like to clip.
209 ClippingItemFactory mClippingItemFactory; ///< The ItemFactory used to create our items.
210 Constraint mItemViewOrientationConstraint; ///< The constraint used to control the orientation of item-view.
213 int DALI_EXPORT_API main( int argc, char **argv )
215 Application app = Application::New(&argc, &argv, DEMO_THEME_PATH);
216 ClippingExample test(app);