KeyEvent class pimpling
[platform/core/uifw/dali-demo.git] / examples / clipping / clipping-example.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // EXTERNAL INCLUDES
19 #include <dali/dali.h>
20 #include <dali-toolkit/dali-toolkit.h>
21 #include <dali/devel-api/actors/actor-devel.h>
22
23 // INTERNAL INCLUDES
24 #include "clipping-item-factory.h"
25 #include "item-view-orientation-constraint.h"
26
27 using namespace Dali;
28 using namespace Dali::Toolkit;
29
30 namespace
31 {
32 const char * const APPLICATION_TITLE( "Clipping Controls" );
33 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).
34
35 const Vector3 ITEM_VIEW_LAYOUT_SIZE_SCALE( 0.75f, 0.5f, 0.75f );
36 const float ITEM_VIEW_BORDER_SIZE = 2.0f;
37 const float ITEM_VIEW_MAXIMUM_ROTATION_IN_DEGREES = 20.0f;
38 const float ITEM_VIEW_LAYOUT_POSITION_CHANGE_MULTIPLIER = 3.0f;
39 const float ITEM_VIEW_ROTATION_ANIMATION_TIME = 0.2f;
40
41 const char * const BUTTON_LABEL( "Toggle Clipping Mode" );
42 } // unnamed namespace
43
44 /**
45  * @brief Demonstrates the control clipping of a UI Control.
46  *
47  * When an Actor is set to clip its children, the renderers have to be added manually in order to specify what its children
48  * need to clip to. UI Controls automate the creation of the renderers/visuals when they are set to clip their children.
49  *
50  * This example displays an item-view whose clipping mode is toggled without the need for adding any renderers to it.
51  *
52  * Additionally, a constraint is used to modify the item-view's orientation.
53  */
54 class ClippingExample : public ConnectionTracker
55 {
56 public:
57
58   /**
59    * @brief Constructor.
60    * @param[in] application A reference to the Application class.
61    */
62   ClippingExample( Application& application )
63   : mApplication( application )
64   {
65     // Connect to the Application's Init signal
66     mApplication.InitSignal().Connect( this, &ClippingExample::Create );
67   }
68
69 private:
70
71   /**
72    * @brief Called to initialise the application content.
73    * @param[in] application A reference to the Application class.
74    */
75   void Create( Application& application )
76   {
77     // Connect to the window's key signal to allow Back and Escape to exit.
78     Window window = application.GetWindow();
79     window.KeyEventSignal().Connect( this, &ClippingExample::OnKeyEvent );
80
81     // Create a TextLabel for the application title.
82     Toolkit::TextLabel label = Toolkit::TextLabel::New( APPLICATION_TITLE );
83     label.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER );
84     label.SetProperty( Actor::Property::PARENT_ORIGIN, APPLICATION_TITLE_PARENT_ORIGIN );
85     label.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
86     label.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
87     label.SetProperty( Toolkit::TextLabel::Property::TEXT_COLOR, Color::WHITE );
88     window.Add( label );
89
90     // Create an item-view which clips its children.
91     mItemView = ItemView::New( mClippingItemFactory );
92     mItemView.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
93     mItemView.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
94     mItemView.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); // Enable clipping. No need to create any renderers.
95     window.Add( mItemView );
96
97     // Create a Spiral Layout and add it to the Item View.
98     mItemView.AddLayout( * DefaultItemLayout::New( DefaultItemLayout::SPIRAL ) );
99     window.GetRootLayer().SetProperty( Layer::Property::BEHAVIOR, Layer::LAYER_3D ); // The item-view spiral layout requires Layer 3D behaviour.
100
101     // Calculate the size we would like our item-view layout to be, and then activate the layout.
102     const Vector2 windowSize = window.GetSize();
103     const Vector3 itemViewLayoutSize( ITEM_VIEW_LAYOUT_SIZE_SCALE.x * windowSize.x, ITEM_VIEW_LAYOUT_SIZE_SCALE.y * windowSize.y, ITEM_VIEW_LAYOUT_SIZE_SCALE.z * windowSize.x );
104     mItemView.ActivateLayout( 0, itemViewLayoutSize, 0.0f );
105
106     // Connect to the scroll started and completed signals to apply orientation constraints & animations.
107     mItemView.ScrollStartedSignal().Connect( this, &ClippingExample::ScrollStarted );
108     mItemView.ScrollCompletedSignal().Connect( this, &ClippingExample::ScrollCompleted );
109
110     // Create a constraint for the item-view which we apply when we start scrolling and remove when we stop.
111     mItemViewOrientationConstraint = Constraint::New< Quaternion >( mItemView, Actor::Property::ORIENTATION, ItemViewOrientationConstraint( ITEM_VIEW_MAXIMUM_ROTATION_IN_DEGREES, ITEM_VIEW_LAYOUT_POSITION_CHANGE_MULTIPLIER ) );
112     mItemViewOrientationConstraint.AddSource( LocalSource( ItemView::Property::LAYOUT_POSITION ) );
113
114     // Create a border around item-view (as item-view is clipping its children, we should NOT add this as a child of item-view).
115     Control border = Control::New();
116     border.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
117     border.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
118     border.SetProperty( Control::Property::BACKGROUND,
119                         Property::Map().Add( Toolkit::Visual::Property::TYPE, Visual::BORDER )
120                                        .Add( BorderVisual::Property::COLOR, Color::WHITE )
121                                        .Add( BorderVisual::Property::SIZE, 2.0f )
122                                        .Add( BorderVisual::Property::ANTI_ALIASING, true ) );
123     border.SetProperty( Actor::Property::SIZE, 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 ) );
124     window.Add( border );
125
126     // Constrain the border's orientation to the orientation of item-view.
127     Constraint constraint = Constraint::New< Quaternion >( border, Actor::Property::ORIENTATION, EqualToConstraint() );
128     constraint.AddSource( Source( mItemView, Actor::Property::ORIENTATION ) );
129     constraint.Apply();
130
131     // Create a button to toggle the clipping mode
132     PushButton button = Toolkit::PushButton::New();
133     button.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER );
134     button.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER );
135     button.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
136     button.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
137     button.SetProperty( Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D );
138     button.SetProperty( Button::Property::LABEL, BUTTON_LABEL );
139     button.ClickedSignal().Connect( this, &ClippingExample::OnButtonClicked );
140     window.Add( button );
141   }
142
143   /**
144    * @brief Called when the item-view starts to scroll.
145    *
146    * Here we want to apply the item-view constraint.
147    */
148   void ScrollStarted( const Vector2& /* currentScrollPosition */ )
149   {
150     mItemViewOrientationConstraint.Apply();
151   }
152
153   /**
154    * @brief Called when the item-view scrolling completes.
155    *
156    * Here we remove the item-view orientation constraint and perform an animation to return the item-view back to base-rotation.
157    */
158   void ScrollCompleted( const Vector2& /* currentScrollPosition */ )
159   {
160     Animation animation = Animation::New( ITEM_VIEW_ROTATION_ANIMATION_TIME );
161     animation.AnimateTo( Property( mItemView, Actor::Property::ORIENTATION ), Quaternion( Degree( 0.0f ), Vector3::XAXIS ), AlphaFunction::EASE_IN_SINE );
162     animation.Play();
163
164     mItemViewOrientationConstraint.Remove();
165   }
166
167   /**
168    * @brief Called when any key event is received
169    *
170    * Will use this to quit the application if Back or the Escape key is received
171    * @param[in] event The key event information
172    */
173   void OnKeyEvent( const KeyEvent& event )
174   {
175     if( event.GetState() == KeyEvent::Down )
176     {
177       if( IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK ) )
178       {
179         mApplication.Quit();
180       }
181     }
182   }
183
184   /**
185    * @brief Called when the button is clicked.
186    *
187    * Will use this to toggle between the clipping modes.
188    * @param[in] button The button that has been clicked.
189    */
190   bool OnButtonClicked( Toolkit::Button button )
191   {
192     if( mItemView )
193     {
194       ClippingMode::Type currentMode = static_cast< ClippingMode::Type >( mItemView.GetProperty( Actor::Property::CLIPPING_MODE ).Get< int >() );
195       mItemView.SetProperty( Actor::Property::CLIPPING_MODE, ( currentMode == ClippingMode::CLIP_CHILDREN ) ? ClippingMode::DISABLED : ClippingMode::CLIP_CHILDREN );
196     }
197     return true;
198   }
199
200   // Data
201
202   Application& mApplication; ///< Reference to the application class.
203   ItemView mItemView; ///< The item view which whose children we would like to clip.
204   ClippingItemFactory mClippingItemFactory; ///< The ItemFactory used to create our items.
205   Constraint mItemViewOrientationConstraint; ///< The constraint used to control the orientation of item-view.
206 };
207
208 int DALI_EXPORT_API main( int argc, char **argv )
209 {
210   Application app = Application::New(&argc, &argv, DEMO_THEME_PATH);
211   ClippingExample test(app);
212   app.MainLoop();
213   return 0;
214 }