Button Refactoring phase 1
[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
25 using namespace Dali;
26 using namespace Dali::Toolkit::Internal;
27
28 namespace
29 {
30
31 BaseHandle Create()
32 {
33   return Toolkit::RadioButton::New();
34 }
35
36 TypeRegistration typeRegistration( typeid( Toolkit::RadioButton ), typeid( Toolkit::Button ), Create);
37
38 const char* const UNSELECTED_BUTTON_IMAGE_DIR = DALI_IMAGE_DIR "radio-button-unselected.png";
39 const char* const SELECTED_BUTTON_IMAGE_DIR = DALI_IMAGE_DIR "radio-button-selected.png";
40
41 const Vector3 DISTANCE_BETWEEN_IMAGE_AND_LABEL(5.0f, 0.0f, 0.0f);
42 }
43
44 Dali::Toolkit::RadioButton RadioButton::New()
45 {
46   // Create the implementation, temporarily owned on stack
47   IntrusivePtr< RadioButton > internalRadioButton = new RadioButton();
48
49   // Pass ownership to CustomActor
50   Dali::Toolkit::RadioButton radioButton(*internalRadioButton);
51
52   // Second-phase init of the implementation
53   // This can only be done after the CustomActor connection has been made...
54   internalRadioButton->Initialize();
55
56   return radioButton;
57 }
58
59 RadioButton::RadioButton()
60 {
61   mUnselectedImage = Dali::Image::New( UNSELECTED_BUTTON_IMAGE_DIR );
62   mSelectedImage = Dali::Image::New( SELECTED_BUTTON_IMAGE_DIR );
63
64   mRadioIcon = Dali::ImageActor::New( mUnselectedImage );
65
66 //  SetTogglableButton(true);
67   mTogglableButton = true;    // TODO: Use SetTogglableButton() after refactoring painter
68 }
69
70 RadioButton::~RadioButton()
71 {
72 }
73
74 void RadioButton::SetLabel( Actor label )
75 {
76   if( mLabel != label )
77   {
78     if( mLabel )
79     {
80       mRadioIcon.Remove( mLabel );
81     }
82
83     if( label )
84     {
85       label.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
86       label.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
87       label.MoveBy( DISTANCE_BETWEEN_IMAGE_AND_LABEL );
88       mRadioIcon.Add( label );
89     }
90
91     mLabel = label;
92
93     RelayoutRequest();
94   }
95 }
96
97 void RadioButton::SetSelected( bool selected )
98 {
99   if( IsSelected() != selected )
100   {
101     if( selected )
102     {
103       Actor parent = Self().GetParent();
104       if( parent )
105       {
106         for( unsigned int i = 0; i < parent.GetChildCount(); ++i )
107         {
108           Dali::Toolkit::RadioButton rbChild = Dali::Toolkit::RadioButton::DownCast(parent.GetChildAt(i));
109
110           if( rbChild )
111           {
112             rbChild.SetSelected(false);
113           }
114         }
115       }
116
117       mSelected = true;
118       mRadioIcon.SetImage(mSelectedImage);
119     }
120     else
121     {
122       mSelected = false;
123       mRadioIcon.SetImage(mUnselectedImage);
124     }
125
126     // Raise state changed signal
127     Toolkit::RadioButton handle( GetOwner() );
128     StateChangedSignal().Emit( handle );
129
130     RelayoutRequest();
131   }
132 }
133
134 void RadioButton::OnRelayout( const Vector2& /*size*/, ActorSizeContainer& container )
135 {
136   Vector3 newSize( mRadioIcon.GetNaturalSize() );
137
138   Actor& label = GetLabel();
139
140   if( label )
141   {
142     // Offset the label from the radio button image
143     newSize.width += DISTANCE_BETWEEN_IMAGE_AND_LABEL.width;
144
145     // Find the size of the control using size negotiation
146     Vector3 actorNaturalSize( label.GetNaturalSize() );
147     Control::Relayout( label, Vector2( actorNaturalSize.width, actorNaturalSize.height ), container );
148
149     Vector3 actorSize( label.GetSize() );
150     newSize.width += actorSize.width;
151     newSize.height = std::max( newSize.height, actorSize.height );
152   }
153
154   Self().SetSize( newSize );
155 }
156
157 void RadioButton::OnInitialize()
158 {
159   mRadioIcon.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
160   mRadioIcon.SetParentOrigin( ParentOrigin::CENTER_LEFT );
161   Self().Add( mRadioIcon );
162
163   RelayoutRequest();
164 }
165
166 void RadioButton::OnButtonUp()
167 {
168   if( ButtonDown == GetState() )
169   {
170     // Don't allow selection on an already selected radio button
171     if( !IsSelected() )
172     {
173       SetSelected(!IsSelected());
174     }
175   }
176 }