Merge remote-tracking branch 'origin/tizen' 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/scripting/scripting.h>
25
26 using namespace Dali;
27 using namespace Dali::Toolkit::Internal;
28
29 namespace
30 {
31
32 BaseHandle Create()
33 {
34   return Toolkit::RadioButton::New();
35 }
36
37 TypeRegistration typeRegistration( typeid( Toolkit::RadioButton ), typeid( Toolkit::Button ), Create);
38
39 const char* const UNSELECTED_BUTTON_IMAGE_DIR = DALI_IMAGE_DIR "radio-button-unselected.png";
40 const char* const SELECTED_BUTTON_IMAGE_DIR = DALI_IMAGE_DIR "radio-button-selected.png";
41
42 const Vector3 DISTANCE_BETWEEN_IMAGE_AND_LABEL(5.0f, 0.0f, 0.0f);
43 }
44
45 Dali::Toolkit::RadioButton RadioButton::New()
46 {
47   // Create the implementation, temporarily owned on stack
48   IntrusivePtr< RadioButton > internalRadioButton = new RadioButton();
49
50   // Pass ownership to CustomActor
51   Dali::Toolkit::RadioButton radioButton(*internalRadioButton);
52
53   // Second-phase init of the implementation
54   // This can only be done after the CustomActor connection has been made...
55   internalRadioButton->Initialize();
56
57   return radioButton;
58 }
59
60 RadioButton::RadioButton()
61   : mSelected(false)
62 {
63   mUnselectedImage = Dali::Image::New( UNSELECTED_BUTTON_IMAGE_DIR );
64   mSelectedImage = Dali::Image::New( SELECTED_BUTTON_IMAGE_DIR );
65
66   mRadioIcon = Dali::ImageActor::New( mUnselectedImage );
67 }
68
69 RadioButton::~RadioButton()
70 {
71 }
72
73 void RadioButton::SetLabel(const std::string& label)
74 {
75   // TODO
76
77   RelayoutRequest();
78 }
79
80 void RadioButton::SetLabel(Actor label)
81 {
82   if( mLabel != label )
83   {
84     if( mLabel )
85     {
86       mRadioIcon.Remove( mLabel );
87     }
88
89     if( label )
90     {
91       label.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
92       label.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
93       label.MoveBy( DISTANCE_BETWEEN_IMAGE_AND_LABEL );
94       mRadioIcon.Add( label );
95     }
96
97     mLabel = label;
98
99     RelayoutRequest();
100   }
101 }
102
103 Actor RadioButton::GetLabel() const
104 {
105   return mLabel;
106 }
107
108 void RadioButton::SetSelected(bool selected)
109 {
110   if( mSelected != selected )
111   {
112     if( selected )
113     {
114       Actor parent = Self().GetParent();
115       if( parent )
116       {
117         for( unsigned int i = 0; i < parent.GetChildCount(); ++i )
118         {
119           Dali::Toolkit::RadioButton rbChild = Dali::Toolkit::RadioButton::DownCast(parent.GetChildAt(i));
120
121           if( rbChild )
122           {
123             rbChild.SetSelected(false);
124           }
125         }
126       }
127
128       mSelected = true;
129       mRadioIcon.SetImage(mSelectedImage);
130     }
131     else
132     {
133       mSelected = false;
134       mRadioIcon.SetImage(mUnselectedImage);
135     }
136
137     // Raise state changed signal
138     Toolkit::RadioButton handle( GetOwner() );
139     mStateChangedSignal.Emit( handle, mSelected );
140
141     RelayoutRequest();
142   }
143 }
144
145 bool RadioButton::IsSelected()const
146 {
147   return mSelected;
148 }
149
150 void RadioButton::ToggleState()
151 {
152   SetSelected(!mSelected);
153 }
154
155 void RadioButton::OnRelayout( const Vector2& /*size*/, ActorSizeContainer& container )
156 {
157   Vector3 newSize( mRadioIcon.GetNaturalSize() );
158
159   if( mLabel )
160   {
161     // Offset the label from the radio button image
162     newSize.width += DISTANCE_BETWEEN_IMAGE_AND_LABEL.width;
163
164     // Find the size of the control using size negotiation
165     Vector3 actorNaturalSize( mLabel.GetNaturalSize() );
166     Control::Relayout( mLabel, Vector2( actorNaturalSize.width, actorNaturalSize.height ), container );
167
168     Vector3 actorSize( mLabel.GetSize() );
169     newSize.width += actorSize.width;
170     newSize.height = std::max( newSize.height, actorSize.height );
171   }
172
173   Self().SetSize( newSize );
174 }
175
176 void RadioButton::OnInitialize()
177 {
178   mRadioIcon.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
179   mRadioIcon.SetParentOrigin( ParentOrigin::CENTER_LEFT );
180   Self().Add( mRadioIcon );
181
182   RelayoutRequest();
183 }
184
185 void RadioButton::OnButtonUp()
186 {
187   // Don't allow selection on an already selected radio button
188   if( !mSelected )
189   {
190     ToggleState();
191   }
192 }
193
194 void RadioButton::SetProperty(BaseObject* object, Property::Index propertyIndex, const Property::Value& value)
195 {
196   Toolkit::RadioButton radioButton = Toolkit::RadioButton::DownCast( Dali::BaseHandle( object ) );
197
198   if( radioButton )
199   {
200     RadioButton& radioButtonImpl( GetImplementation( radioButton ) );
201
202     if ( propertyIndex == Toolkit::Button::PROPERTY_TOGGLED )
203     {
204       radioButtonImpl.SetSelected( value.Get< bool >( ) );
205     }
206     else if ( propertyIndex == Toolkit::Button::PROPERTY_LABEL_ACTOR )
207     {
208       radioButtonImpl.SetLabel( Scripting::NewActor( value.Get< Property::Map >( ) ) );
209     }
210   }
211 }
212
213 Property::Value RadioButton::GetProperty(BaseObject* object, Property::Index propertyIndex)
214 {
215   Property::Value value;
216
217   Toolkit::RadioButton radioButton = Toolkit::RadioButton::DownCast( Dali::BaseHandle(object) );
218
219   if( radioButton )
220   {
221     RadioButton& radioButtonImpl( GetImplementation( radioButton ) );
222
223     if ( propertyIndex == Toolkit::Button::PROPERTY_TOGGLED )
224     {
225       value = radioButtonImpl.mSelected;
226     }
227     else if ( propertyIndex == Toolkit::Button::PROPERTY_LABEL_ACTOR )
228     {
229       Property::Map map;
230       Scripting::CreatePropertyMap( radioButtonImpl.mLabel, map );
231       value = map;
232     }
233   }
234
235   return value;
236 }