MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
radiobutton.cpp
1 // © Copyright 2010 - 2012 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _uiradiobutton_cpp
41 #define _uiradiobutton_cpp
42 
43 #include "UI/radiobutton.h"
44 #include "UI/screen.h"
45 
46 #include "stringtool.h"
47 #include "serialization.h"
48 #include "exception.h"
49 
50 #include <algorithm>
51 
52 namespace Mezzanine
53 {
54  namespace UI
55  {
56  ///////////////////////////////////////////////////////////////////////////////
57  // RadioButtonGroup Methods
58 
60  CurrentSelection(NULL)
61  { }
62 
64  { }
65 
66  ///////////////////////////////////////////////////////////////////////////////
67  // Utility Methods
68 
70  {
71  RadioButtonIterator RadioIt = std::find(this->GroupButtons.begin(),this->GroupButtons.end(),ToAdd);
72  if( RadioIt == this->GroupButtons.end() ) {
73  this->GroupButtons.push_back( ToAdd );
74  }
75  }
76 
78  {
79  return this->GroupButtons.size();
80  }
81 
83  {
84  RadioButtonIterator RadioIt = std::find(this->GroupButtons.begin(),this->GroupButtons.end(),ToRemove);
85  if( RadioIt != this->GroupButtons.end() ) {
86  this->GroupButtons.erase( RadioIt );
87  }
88  }
89 
91  {
92  this->DeselectOtherButtons(ToSelect);
93  this->CurrentSelection = ToSelect;
94  if( this->CurrentSelection != NULL ) {
95  this->CurrentSelection->ManualSelect(true);
96  }
97  }
98 
100  {
101  for( RadioButtonIterator RadioIt = this->GroupButtons.begin() ; RadioIt != this->GroupButtons.end() ; ++RadioIt )
102  {
103  if( (*RadioIt) != Exclude ) {
104  (*RadioIt)->ManualSelect(false);
105  }
106  }
107  }
108 
110  { return this->GroupButtons.begin(); }
111 
113  { return this->GroupButtons.end(); }
114 
116  { return this->GroupButtons.begin(); }
117 
119  { return this->GroupButtons.end(); }
120 
121  ///////////////////////////////////////////////////////////////////////////////
122  // Internal Methods
123 
125  {
126  this->DeselectOtherButtons(Selected);
127  this->CurrentSelection = Selected;
128  }
129 
130  ///////////////////////////////////////////////////////////////////////////////
131  // RadioButton Static Members
132 
133  const String RadioButton::TypeName = "RadioButton";
134 
135  ///////////////////////////////////////////////////////////////////////////////
136  // RadioButton Methods
137 
139  CheckBox(Parent)
140  { }
141 
142  RadioButton::RadioButton(const String& RendName, Screen* Parent) :
143  CheckBox(RendName,Parent)
144  { }
145 
146  RadioButton::RadioButton(const String& RendName, const UnifiedRect& RendRect, Screen* Parent) :
147  CheckBox(RendName,RendRect,Parent)
148  { }
149 
150  RadioButton::RadioButton(const XML::Node& XMLNode, Screen* Parent) :
151  CheckBox(Parent)
152  { this->ProtoDeSerialize(XMLNode); }
153 
155  { this->RemoveFromButtonGroup(); }
156 
158  {
159  this->Widget::ProtoSerializeImpl(SelfRoot);
160  this->ProtoSerializeGroupButtons(SelfRoot);
161  }
162 
164  {
165  this->Widget::ProtoDeSerializeImpl(SelfRoot);
166  this->ProtoDeSerializeGroupButtons(SelfRoot);
167  }
168 
169  ///////////////////////////////////////////////////////////////////////////////
170  // Utility Methods
171 
172  ///////////////////////////////////////////////////////////////////////////////
173  // RadioButton Properties
174 
175  ///////////////////////////////////////////////////////////////////////////////
176  // RadioButton Configuration
177 
179  {
180  RadioButtonGroup* OtherGroup = ToAdd->_GetButtonGroup();
181  if( this->ButtonGroup != NULL ) {
182  if( OtherGroup == NULL ) {
183  this->ButtonGroup->AddButtonToGroup(ToAdd);
184  }else{
185  MEZZ_EXCEPTION(Exception::INVALID_STATE_EXCEPTION,"Attempting to add RadioButton to another group when it already has one.");
186  }
187  }else{
188  if( OtherGroup != NULL ) {
189  OtherGroup->AddButtonToGroup(this);
190  }else{
191  OtherGroup = new RadioButtonGroup();
192  OtherGroup->AddButtonToGroup(this);
193  OtherGroup->AddButtonToGroup(ToAdd);
194  }
195  }
196  }
197 
199  {
200  if( this->ButtonGroup != NULL ) {
201  this->ButtonGroup->RemoveButtonFromGroup(this);
202 
203  if( this->ButtonGroup->GetNumButtons() == 0 ) {
204  delete this->ButtonGroup;
205  }
206 
207  this->ButtonGroup = NULL;
208  }
209  }
210 
211  ///////////////////////////////////////////////////////////////////////////////
212  // Serialization
213 
215  {
216  XML::Node ButtonsNode = SelfRoot.AppendChild( "GroupButtons" );
217 
218  if( ButtonsNode.AppendAttribute("Version").SetValue("1") ) {
221  for( RadioButtonGroup::ConstRadioButtonIterator ButIt = ButBeg ; ButIt != ButEnd ; ++ButIt )
222  {
223  XML::Node ButtonNode = ButtonsNode.AppendChild( "GroupButton" );
224 
225  if( ButtonNode.AppendAttribute("Version").SetValue("1") &&
226  ButtonNode.AppendAttribute("GroupButtonName").SetValue( (*ButIt)->GetName() ) )
227  {
228  continue;
229  }else{
230  SerializeError("Create XML Version Attribute","GroupButton",true);
231  }
232  }
233  }else{
234  SerializeError("Create XML Version Attribute","GroupButtons",true);
235  }
236  }
237 
239  {
240  this->CheckBox::ProtoSerializeProperties(SelfRoot);
241  }
242 
244  {
245  this->RemoveFromButtonGroup();
246 
247  XML::Attribute CurrAttrib;
248  XML::Node ButtonsNode = SelfRoot.GetChild( "GroupButtons" );
249 
250  if( !ButtonsNode.Empty() ) {
251  if( ButtonsNode.GetAttribute("Version").AsInt() == 1 ) {
252  for( XML::NodeIterator ButtonNodeIt = ButtonsNode.begin() ; ButtonNodeIt != ButtonsNode.end() ; ++ButtonNodeIt )
253  {
254  if( (*ButtonNodeIt).GetAttribute("Version").AsInt() == 1 ) {
255  String GroupButtonName;
256 
257  CurrAttrib = (*ButtonNodeIt).GetAttribute("GroupButtonName");
258  if( !CurrAttrib.Empty() )
259  GroupButtonName = CurrAttrib.AsString();
260 
261  if( !GroupButtonName.empty() ) {
262  Widget* NamedButton = this->ParentScreen->GetWidget(GroupButtonName);
263  if( NamedButton != NULL && NamedButton->GetTypeName() == RadioButton::TypeName ) {
264  this->AddToButtonGroup( static_cast<RadioButton*>( NamedButton ) );
265  }else{
266  StringStream ExceptionStream;
267  ExceptionStream << "Named Widget \"" << GroupButtonName << "\" not found or not a RadioButton when deserializing Widget named \"" << this->GetName() << "\".";
268  MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,ExceptionStream.str());
269  }
270  }
271  }else{
272  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + String("GroupButtons") + ": Not Version 1.");
273  }
274  }
275  }else{
276  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + String("GroupButtons") + ": Not Version 1.");
277  }
278  }
279  }
280 
282  {
283  this->CheckBox::ProtoDeSerializeProperties(SelfRoot);
284 
285  XML::Attribute CurrAttrib;
286  XML::Node PropertiesNode = SelfRoot.GetChild( RadioButton::GetSerializableName() + "Properties" );
287 
288  if( !PropertiesNode.Empty() ) {
289  if(PropertiesNode.GetAttribute("Version").AsInt() == 1) {
290  CurrAttrib = PropertiesNode.GetAttribute("LockoutTime");
291  if( !CurrAttrib.Empty() )
292  this->SelectLock = StringTools::ConvertToBool( CurrAttrib.AsString() );
293  }else{
294  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + (RadioButton::GetSerializableName() + "Properties") + ": Not Version 1.");
295  }
296  }else{
297  MEZZ_EXCEPTION(Exception::II_IDENTITY_NOT_FOUND_EXCEPTION,RadioButton::GetSerializableName() + "Properties" + " was not found in the provided XML node, which was expected.");
298  }
299  }
300 
302  {
303  return RadioButton::TypeName;
304  }
305 
306  ///////////////////////////////////////////////////////////////////////////////
307  // Internal Event Methods
308 
310  {
311  if( this->ButtonGroup != NULL ) {
312  this->ButtonGroup->_NotifyButtonSelected(this);
313  }
314  this->CheckBox::_OnSelected();
315  }
316 
318  {
319  // For now do nothing extra
320  this->CheckBox::_OnDeselected();
321  }
322 
323  ///////////////////////////////////////////////////////////////////////////////
324  // Internal Methods
325 
327  {
328  return this->ButtonGroup;
329  }
330 
331  ///////////////////////////////////////////////////////////////////////////////
332  // RadioButtonFactory Methods
333 
335  { return RadioButton::TypeName; }
336 
338  { return new RadioButton(RendName,Parent); }
339 
340  RadioButton* RadioButtonFactory::CreateRadioButton(const String& RendName, const UnifiedRect& RendRect, Screen* Parent)
341  { return new RadioButton(RendName,RendRect,Parent); }
342 
344  { return new RadioButton(XMLNode,Parent); }
345 
347  { return new RadioButton(Parent); }
348 
349  Widget* RadioButtonFactory::CreateWidget(const String& RendName, const NameValuePairMap& Params, Screen* Parent)
350  { return this->CreateRadioButton(RendName,Parent); }
351 
352  Widget* RadioButtonFactory::CreateWidget(const String& RendName, const UnifiedRect& RendRect, const NameValuePairMap& Params, Screen* Parent)
353  { return this->CreateRadioButton(RendName,RendRect,Parent); }
354 
356  { return this->CreateRadioButton(XMLNode,Parent); }
357 
359  { delete static_cast<RadioButton*>( ToBeDestroyed ); }
360  }//UI
361 }//Mezzanine
362 
363 #endif