a95ee7cafcb26a8429833f76a808ac203be02f57
[platform/core/uifw/dali-toolkit.git] / optional / dali-toolkit / internal / controls / selectors / rotating-selector-impl.cpp
1 /*
2  * Copyright (c) 2014 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 // CLASS HEADER
19 #include <dali-toolkit/internal/controls/selectors/rotating-selector-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>
23 #include <dali/public-api/animation/constraints.h>
24 #include <dali/public-api/events/touch-event.h>
25 #include <dali/public-api/object/type-registry.h>
26
27 // INTERNAL INCLUDES
28 #include <dali-toolkit/public-api/controls/selectors/rotating-selector.h>
29
30 namespace
31 {
32 const float TOUCH_OPACITY_THRESHOLD = 0.1f;
33 } // namespace
34
35 namespace Dali
36 {
37
38 namespace Toolkit
39 {
40
41 namespace Internal
42 {
43 namespace
44 {
45 //Type registration
46 BaseHandle Create()
47 {
48   // empty handle, as RotatingSelector takes children during construction
49   return Toolkit::RotatingSelector();
50 }
51 TypeRegistration mType( typeid(Toolkit::RotatingSelector), typeid(Toolkit::Control), Create );
52
53 const Quaternion ROTATION_ANGLE(0.0f, Vector3(1.0f, 0.0f, 0.0f));
54 }
55
56 Dali::Toolkit::RotatingSelector RotatingSelector::New(Actor& unSelectedActor, Actor& selectedActor)
57 {
58   // Create the implementation, temporarily owned on stack
59   IntrusivePtr< RotatingSelector > customCheckActor = new RotatingSelector;
60
61   // Pass ownership to CustomActor
62   Dali::Toolkit::RotatingSelector handle( *customCheckActor );
63
64   // Second-phase init of the implementation
65   // This can only be done after the CustomActor connection has been made...
66   customCheckActor->Initialize();
67
68   customCheckActor->SetSelectedActor(selectedActor);
69   customCheckActor->SetUnSelectedActor(unSelectedActor);
70
71   return handle;
72 }
73
74 void RotatingSelector::OnInitialize()
75 {
76   mContainer = Actor::New();
77   mContainer.SetName("Selector Container");
78   mUnSelectedActor = Actor::New();
79   mSelectedActor = Actor::New();
80
81   mRotateAnimation = Animation::New(0.5f);
82   mRotateAnimation.FinishedSignal().Connect(this, &RotatingSelector::AnimationCompleted);
83
84   mUnSelectedActor.SetParentOrigin(ParentOrigin::CENTER);
85   mUnSelectedActor.SetAnchorPoint(AnchorPoint::CENTER);
86
87   mSelectedActor.SetParentOrigin(ParentOrigin::CENTER);
88   mSelectedActor.SetAnchorPoint(AnchorPoint::CENTER);
89
90   mContainer.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
91
92   Constraint constraint = Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() );
93   mSelectedActor.ApplyConstraint(constraint);
94   mUnSelectedActor.ApplyConstraint(constraint);
95   mContainer.ApplyConstraint(constraint);
96
97   mContainer.Add(mUnSelectedActor);
98   mSelectedActor.SetRotation(Radian(Math::PI), Vector3::XAXIS );
99
100   mUnSelectedActor.SetName("RotatingSelector : UnSelectedActor");
101   mSelectedActor.SetName("RotatingSelector : SelectedActor");
102
103   Self().Add(mContainer);
104   Self().SetLeaveRequired(true);
105
106   mRotateAnimation.RotateBy(mContainer, Radian(Math::PI), Vector3(1.0f, 0.0f, 0.0f));
107 }
108
109 RotatingSelector::RotatingSelector()
110 : Control( REQUIRES_TOUCH_EVENTS ),
111   mSelected(false),
112   mSelectable(true),
113   mPressed(false),
114   mIsAnimating(false)
115 {
116 }
117
118 RotatingSelector::~RotatingSelector()
119 {
120   mRotateAnimation.Reset();
121 }
122
123 void RotatingSelector::SetSelected( bool toggle )
124 {
125   if(toggle != mSelected)
126   {
127     if( mSelectable )
128     {
129       ToggleAndAnimateSelection();
130     }
131   }
132 }
133
134 void RotatingSelector::SetSelectedActor( Actor& selectedActor )
135 {
136   unsigned int numChildren = mSelectedActor.GetChildCount();
137   for( unsigned int i=0; i<numChildren; ++i )
138   {
139     Actor actor = mSelectedActor.GetChildAt(i);
140     mSelectedActor.Remove(actor);
141   }
142
143   mSelectedActor.Add(selectedActor);
144 }
145
146 Actor RotatingSelector::GetSelectedActor()
147 {
148   return mSelectedActor.GetChildAt(0);
149 }
150
151 void RotatingSelector::SetUnSelectedActor( Actor& unSelectedActor )
152 {
153   unsigned int numChildren = mUnSelectedActor.GetChildCount();
154
155   for(unsigned int i=0; i<numChildren; ++i)
156   {
157     mUnSelectedActor.Remove(mUnSelectedActor.GetChildAt(0));
158   }
159
160   mUnSelectedActor.Add(unSelectedActor);
161 }
162
163 Actor RotatingSelector::GetUnSelectedActor()
164 {
165   return mUnSelectedActor.GetChildAt(0);
166 }
167
168 void RotatingSelector::SetSelectable( bool selectable )
169 {
170   mSelectable = selectable;
171 }
172
173 Toolkit::RotatingSelector::SelectedSignalV2& RotatingSelector::SelectedSignal()
174 {
175   return mCheckedSignalV2;
176 }
177
178 bool RotatingSelector::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
179 {
180   Dali::BaseHandle handle( object );
181
182   bool connected( true );
183   Toolkit::RotatingSelector selector = Toolkit::RotatingSelector::DownCast(handle);
184
185   if( Toolkit::RotatingSelector::SIGNAL_CHECKED == signalName )
186   {
187     selector.SelectedSignal().Connect( tracker, functor );
188   }
189   else
190   {
191     // signalName does not match any signal
192     connected = false;
193   }
194
195   return connected;
196 }
197
198 bool RotatingSelector::OnTouchEvent(const TouchEvent& event)
199 {
200   if( 1 == event.GetPointCount() )
201   {
202     switch( event.GetPoint(0).state )
203     {
204       case TouchPoint::Down:
205         if(Self().GetCurrentOpacity() > TOUCH_OPACITY_THRESHOLD)
206         {
207           mPressed = true;
208         }
209         break;
210       case TouchPoint::Leave:
211         mPressed = false;
212         break;
213       case TouchPoint::Up:
214       {
215         if(mSelectable && mPressed)
216         {
217           ToggleAndAnimateSelection();
218         }
219         mPressed = false;
220         break;
221       }
222       default:
223         break;
224     }
225   }
226
227  return false; // dont consume
228 }
229
230 void RotatingSelector::ToggleAndAnimateSelection()
231 {
232   if(!mIsAnimating)
233   {
234     mSelected = !mSelected;
235     if(mSelected)
236     {
237       //The checked image (i.e mSelectedActor should be in front)
238       mSelectedActor.SetPosition(0.0f, 0.0f, -1.0f);
239       mContainer.Add(mSelectedActor);
240     }
241     else
242     {
243       //The un checked image (i.e mUnSelectedActor should be in front)
244       mUnSelectedActor.SetPosition(0.0f, 0.0f, 1.0f);
245       mContainer.Add(mUnSelectedActor);
246     }
247
248     mIsAnimating = true;
249     mRotateAnimation.Play();
250   }
251 }
252
253 void RotatingSelector::AnimationCompleted( Animation& animation )
254 {
255   if(mSelected)
256   {
257     //The checked image (i.e mSelectedActor should be in front)
258     mSelectedActor.SetPosition(0.0f, 0.0f, 0.0f);
259     mContainer.Remove(mUnSelectedActor);
260
261   }
262   else
263   {
264     //The un checked image (i.e mUnSelectedActor should be in front)
265     mContainer.Remove(mSelectedActor);
266     mUnSelectedActor.SetPosition(0.0f, 0.0f, 0.0f);
267   }
268
269   mIsAnimating = false;
270
271   //Emit signal.
272   Dali::Toolkit::RotatingSelector handle( GetOwner() );
273   mCheckedSignalV2.Emit( handle, mSelected );
274 }
275
276 } // namespace Internal
277
278 } // namespace Toolkit
279
280 } // namespace Dali