Merge "Alignment - Fix a pixel alignment issue with the center alignment." into new_text
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / buttons / radio-button-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
19 // CLASS HEADER
20 #include "radio-button-impl.h"
21
22 // EXTERNAL INCLUDES
23 #include <dali/public-api/object/type-registry.h>
24 #include <dali/public-api/images/resource-image.h>
25
26 namespace Dali
27 {
28
29 namespace Toolkit
30 {
31
32 namespace Internal
33 {
34
35 namespace
36 {
37
38 BaseHandle Create()
39 {
40   return Toolkit::RadioButton::New();
41 }
42
43 TypeRegistration typeRegistration( typeid( Toolkit::RadioButton ), typeid( Toolkit::Button ), Create);
44
45 const char* const UNSELECTED_BUTTON_IMAGE_DIR = DALI_IMAGE_DIR "radio-button-unselected.png";
46 const char* const SELECTED_BUTTON_IMAGE_DIR = DALI_IMAGE_DIR "radio-button-selected.png";
47
48 const Vector3 DISTANCE_BETWEEN_IMAGE_AND_LABEL(5.0f, 0.0f, 0.0f);
49 }
50
51 Dali::Toolkit::RadioButton RadioButton::New()
52 {
53   // Create the implementation, temporarily owned on stack
54   IntrusivePtr< RadioButton > internalRadioButton = new RadioButton();
55
56   // Pass ownership to CustomActor
57   Dali::Toolkit::RadioButton radioButton(*internalRadioButton);
58
59   // Second-phase init of the implementation
60   // This can only be done after the CustomActor connection has been made...
61   internalRadioButton->Initialize();
62
63   return radioButton;
64 }
65
66 RadioButton::RadioButton()
67 {
68   SetTogglableButton(true);
69 }
70
71 RadioButton::~RadioButton()
72 {
73 }
74
75 void RadioButton::SetButtonImage( Actor image )
76 {
77   Actor& buttonImage = GetButtonImage();
78
79   if( !IsSelected() )
80   {
81     if( buttonImage && buttonImage.GetParent() )
82     {
83       buttonImage.GetParent().Remove( buttonImage );
84       buttonImage.Reset();
85     }
86
87     Self().Add( image );
88
89     Actor& label = GetLabel();
90
91     if( label )
92     {
93       buttonImage.Remove( label );
94       image.Add( label );
95     }
96   }
97
98   buttonImage = image;
99
100   buttonImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
101   buttonImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
102 }
103
104 void RadioButton::SetSelectedImage( Actor image )
105 {
106   Actor& selectedImage = GetSelectedImage();
107
108   if( IsSelected() )
109   {
110     if( selectedImage && selectedImage.GetParent() )
111     {
112       selectedImage.GetParent().Remove( selectedImage );
113       selectedImage.Reset();
114     }
115
116     Self().Add( image );
117
118     Actor& label = GetLabel();
119
120     if( label )
121     {
122       selectedImage.Remove( label );
123       image.Add( label );
124     }
125   }
126
127   selectedImage = image;
128
129   selectedImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
130   selectedImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
131 }
132
133 void RadioButton::OnButtonInitialize()
134 {
135   Image buttonImage = Dali::ResourceImage::New( UNSELECTED_BUTTON_IMAGE_DIR );
136   Image selectedImage = Dali::ResourceImage::New( SELECTED_BUTTON_IMAGE_DIR );
137
138   SetButtonImage( ImageActor::New( buttonImage ) );
139   SetSelectedImage( ImageActor::New( selectedImage ) );
140
141   RelayoutRequest();
142 }
143
144 void RadioButton::OnButtonUp()
145 {
146   if( ButtonDown == GetState() )
147   {
148     // Don't allow selection on an already selected radio button
149     if( !IsSelected() )
150     {
151       SetSelected(!IsSelected());
152     }
153   }
154 }
155
156 void RadioButton::OnLabelSet()
157 {
158   Actor& label = GetLabel();
159
160   if( label )
161   {
162     label.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
163     label.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
164     label.TranslateBy( DISTANCE_BETWEEN_IMAGE_AND_LABEL );
165
166     if( IsSelected() )
167     {
168       GetSelectedImage().Add( label );
169     }
170     else
171     {
172       GetButtonImage().Add( label );
173     }
174   }
175 }
176
177 void RadioButton::OnSelected( bool selected )
178 {
179   Actor& buttonImage = GetButtonImage();
180   Actor& selectedImage = GetSelectedImage();
181   Actor& label = GetLabel();
182
183   if( selected )
184   {
185     Actor parent = Self().GetParent();
186     if( parent )
187     {
188       for( unsigned int i = 0; i < parent.GetChildCount(); ++i )
189       {
190         Dali::Toolkit::RadioButton rbChild = Dali::Toolkit::RadioButton::DownCast(parent.GetChildAt(i));
191
192         if( rbChild )
193         {
194           rbChild.SetSelected(false);
195         }
196       }
197     }
198
199     buttonImage.GetParent().Remove( buttonImage );
200     Self().Add( selectedImage );
201
202     if( label )
203     {
204       label.GetParent().Remove( label );
205       selectedImage.Add( label );
206     }
207   }
208   else
209   {
210     selectedImage.GetParent().Remove( selectedImage );
211     Self().Add( buttonImage );
212
213     if( label )
214     {
215       label.GetParent().Remove( label );
216       buttonImage.Add( label );
217     }
218   }
219 }
220
221 void RadioButton::OnRelayout( const Vector2& /*size*/, ActorSizeContainer& container )
222 {
223   Vector3 newSize;
224
225   if( IsSelected() )
226   {
227     newSize = GetSelectedImage().GetNaturalSize();
228   }
229   else
230   {
231     newSize = GetButtonImage().GetNaturalSize();
232   }
233
234   Actor& label = GetLabel();
235
236   if( label )
237   {
238     // Offset the label from the radio button image
239     newSize.width += DISTANCE_BETWEEN_IMAGE_AND_LABEL.width;
240
241     // Find the size of the control using size negotiation
242     Vector3 actorNaturalSize( label.GetNaturalSize() );
243     Control::Relayout( label, Vector2( actorNaturalSize.width, actorNaturalSize.height ), container );
244
245     Vector3 actorSize( label.GetSize() );
246     newSize.width += actorSize.width;
247     newSize.height = std::max( newSize.height, actorSize.height );
248   }
249
250   Self().SetSize( newSize );
251 }
252
253 } // namespace Internal
254
255 } // namespace Toolkit
256
257 } // namespace Dali