MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
button.cpp
1 // © Copyright 2010 - 2014 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 _uibutton_cpp
41 #define _uibutton_cpp
42 
43 #include "UI/uimanager.h"
44 #include "UI/button.h"
45 #include "UI/screen.h"
46 
47 namespace Mezzanine
48 {
49  namespace UI
50  {
51  const String Button::TypeName = "Button";
52 
53  const String Button::EventActivated = "Activated";
54  const String Button::EventStandby = "Standby";
55  const String Button::EventDeactivated = "Deactivated";
56 
57  ///////////////////////////////////////////////////////////////////////////////
58  // Button Methods
59 
61  Widget(Parent),
62  Activation(AS_Deactivated)
63  { }
64 
65  Button::Button(const String& RendName, Screen* Parent) :
66  Widget(RendName,Parent),
67  Activation(AS_Deactivated)
68  { this->ConstructButton(); }
69 
70  Button::Button(const String& RendName, const UnifiedRect& RendRect, Screen* Parent) :
71  Widget(RendName,RendRect,Parent),
72  Activation(AS_Deactivated)
73  { this->ConstructButton(); }
74 
75  Button::Button(const XML::Node& XMLNode, Screen* Parent) :
76  Widget(Parent),
77  Activation(AS_Deactivated)
78  { this->ProtoDeSerialize(XMLNode); }
79 
81  { }
82 
84  {
85  // Check to see if this is an activation code
86  if( this->ActivationCodes.count( Input::MetaCodeKey(Code) ) )
87  {
88  // Are we changing our activation state from a mouse code?
89  if( Code.IsMouseButton() ) {
90  if( this->IsHovered() && Input::BUTTON_PRESSING == Code.GetMetaValue() )
91  {
92  Boolean Result = this->Activate();
93  if(Result)
94  this->MouseActivated = true;
95  return true;
96  }
97  else if( Input::BUTTON_LIFTING == Code.GetMetaValue() )
98  {
99  this->Deactivate();
100  this->MouseActivated = false;
101  return true;
102  }
103  }else{
104  if( Input::BUTTON_PRESSING == Code.GetMetaValue() )
105  {
106  this->Activate();
107  return true;
108  }
109  else if( Input::BUTTON_LIFTING == Code.GetMetaValue() )
110  {
111  this->Deactivate();
112  return true;
113  }
114  }
115  }
116  return false;
117  }
118 
120  {
121  // Add our button events
125  // Handle auto activation registration
126  UIManager* Manager = this->ParentScreen->GetManager();
127  if( Manager->ButtonAutoRegisterEnabled() )
128  {
130  for( Whole X = 0 ; X < Codes->size() ; X++ )
131  this->BindActivationKeyOrButton(Codes->at(X));
132  }
133  }
134 
136  {
137  return (Input::KEY_FIRST < Code && Input::KEY_LAST > Code) ||
138  (Input::MOUSEBUTTON_FIRST <= Code && Input::MOUSEBUTTON_LAST >= Code) ||
139  (Input::CONTROLLERBUTTON_FIRST <= Code && Input::CONTROLLERBUTTON_LAST >= Code);
140  }
141 
143  {
144  if( this->Activation == AS_Activated )
145  return false;
146  if( this->LockoutTimer.GetInitialTime() != 0 && !(this->LockoutTimer.IsStopped()) )
147  return false;
148 
149  this->Activation = AS_Activated;
150  this->_OnActivate();
151  return true;
152  }
153 
155  {
156  if( this->Activation == AS_Deactivated )
157  return false;
158  if( this->LockoutTimer.GetInitialTime() != 0 )
159  {
160  this->LockoutTimer.Reset();
161  this->LockoutTimer.Start();
162  }
163 
164  this->Activation = AS_Deactivated;
165  this->_OnDeactivate();
166  return true;
167  }
168 
169  Boolean Button::Standby()
170  {
171  if(this->Activation == AS_Activation_Standby)
172  return false;
173 
175  this->_OnStandby();
176  return true;
177  }
178 
179  ///////////////////////////////////////////////////////////////////////////////
180  // Utility Methods
181 
182  void Button::SetLockoutTime(const UInt32& Milliseconds)
183  { this->LockoutTimer.SetInitialTimeInMilliseconds(Milliseconds); }
184 
186  { return this->LockoutTimer; }
187 
188  Boolean Button::IsActivated() const
189  { return ( this->Activation == AS_Activated ); }
190 
191  Boolean Button::IsOnStandby() const
192  { return ( this->Activation == AS_Activation_Standby ); }
193 
194  Boolean Button::IsDeactivated() const
195  { return ( this->Activation == AS_Deactivated ); }
196 
198  { return Button::TypeName; }
199 
200  ///////////////////////////////////////////////////////////////////////////////
201  // Binding Methods
202 
204  {
205  if( this->VertifyActivationCode( Code.GetCode() ) ) {
206  this->ActivationCodes.insert(Input::MetaCodeKey(Code));
207  }else{
208  MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"Attempting to bind an unsupported InputCode to a button.");
209  }
210  }
211 
213  {
214  this->ActivationCodes.erase(Input::MetaCodeKey(Code));
215  }
216 
218  {
219  for( ActivationCodeIterator ActIt = this->ActivationCodes.begin() ; ActIt != this->ActivationCodes.end() ; )
220  {
221  if( (*ActIt).GetKeyData().IsKeyboardButton() ) {
222  this->ActivationCodes.erase(ActIt++);
223  }else{
224  ++ActIt;
225  }
226  }
227  }
228 
230  {
231  for( ActivationCodeIterator ActIt = this->ActivationCodes.begin() ; ActIt != this->ActivationCodes.end() ; )
232  {
233  if( (*ActIt).GetKeyData().IsMouseButton() ) {
234  this->ActivationCodes.erase(ActIt++);
235  }else{
236  ++ActIt;
237  }
238  }
239  }
240 
242  {
243  for( ActivationCodeIterator ActIt = this->ActivationCodes.begin() ; ActIt != this->ActivationCodes.end() ; )
244  {
245  if( (*ActIt).GetKeyData().IsControllerButton() ) {
246  this->ActivationCodes.erase(ActIt++);
247  }else{
248  ++ActIt;
249  }
250  }
251  }
252 
254  {
255  this->ActivationCodes.clear();
256  }
257 
258  ///////////////////////////////////////////////////////////////////////////////
259  // Fetch Methods
260 
262  {
263  return this->ActivationCodes;
264  }
265 
266  ///////////////////////////////////////////////////////////////////////////////
267  // Serialization
268 
270  {
271  this->Widget::ProtoSerializeProperties(SelfRoot);
272 
273  XML::Node PropertiesNode = SelfRoot.AppendChild( Button::GetSerializableName() + "Properties" );
274 
275  if( PropertiesNode.AppendAttribute("Version").SetValue("1") )
276  {
277  // Only if we have a valid timer
278  if( this->LockoutTimer.GetInitialTime() != 0 ) {
279  if( PropertiesNode.AppendAttribute("LockoutTime").SetValue( this->LockoutTimer.GetInitialTime() ) == false ) {
280  SerializeError("Create XML Attribute Values",Button::GetSerializableName() + "Properties",true);
281  }
282  }
283 
284  XML::Node CodesNode = PropertiesNode.AppendChild( "ActivationCodes" );
285  for( ActivationCodeIterator CodeIt = this->ActivationCodes.begin() ; CodeIt != this->ActivationCodes.end() ; ++CodeIt )
286  {
287  (*CodeIt).GetKeyData().ProtoSerialize(CodesNode);
288  }
289 
290  return;
291  }else{
292  SerializeError("Create XML Attribute Values",Button::GetSerializableName() + "Properties",true);
293  }
294  }
295 
297  {
298  this->Widget::ProtoDeSerializeProperties(SelfRoot);
299 
300  XML::Attribute CurrAttrib;
301  XML::Node PropertiesNode = SelfRoot.GetChild( Button::GetSerializableName() + "Properties" );
302 
303  if( !PropertiesNode.Empty() ) {
304  if(PropertiesNode.GetAttribute("Version").AsInt() == 1) {
305  CurrAttrib = PropertiesNode.GetAttribute("LockoutTime");
306  if( !CurrAttrib.Empty() )
307  this->SetLockoutTime( CurrAttrib.AsUint() );
308 
309  XML::Node CodesNode = PropertiesNode.GetChild( "ActivationCodes" );
310  if( !CodesNode.Empty() ) {
311  for( XML::NodeIterator CodeNodeIt = CodesNode.begin() ; CodeNodeIt != CodesNode.end() ; ++CodeNodeIt )
312  {
313  Input::MetaCode ActivationCode;
314  ActivationCode.ProtoDeSerialize( (*CodeNodeIt) );
315  this->BindActivationKeyOrButton(ActivationCode);
316  }
317  }
318  }else{
319  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + (Button::GetSerializableName() + "Properties") + ": Not Version 1.");
320  }
321  }else{
322  MEZZ_EXCEPTION(Exception::II_IDENTITY_NOT_FOUND_EXCEPTION,Button::GetSerializableName() + "Properties" + " was not found in the provided XML node, which was expected.");
323  }
324  }
325 
327  {
328  return Button::TypeName;
329  }
330 
331  ///////////////////////////////////////////////////////////////////////////////
332  // Internal Event Methods
333 
335  {
337 
338  if( this->MouseActivated && this->Activation == AS_Activation_Standby ) {
339  this->Activate();
340  }
341  }
342 
344  {
346 
347  if( this->MouseActivated && this->Activation == AS_Activated ) {
348  this->Standby();
349  }
350  }
351 
353  {
355  this->FireEvent(Args);
356  }
357 
359  {
361  this->FireEvent(Args);
362  }
363 
365  {
367  this->FireEvent(Args);
368  }
369 
370  ///////////////////////////////////////////////////////////////////////////////
371  // ButtonFactory Methods
372 
374  { return Button::TypeName; }
375 
376  Button* ButtonFactory::CreateButton(const String& RendName, Screen* Parent)
377  { return new Button(RendName,Parent); }
378 
379  Button* ButtonFactory::CreateButton(const String& RendName, const UnifiedRect& RendRect, Screen* Parent)
380  { return new Button(RendName,RendRect,Parent); }
381 
383  { return new Button(XMLNode,Parent); }
384 
386  { return new Button(Parent); }
387 
388  Widget* ButtonFactory::CreateWidget(const String& RendName, const NameValuePairMap& Params, Screen* Parent)
389  { return this->CreateButton(RendName,Parent); }
390 
391  Widget* ButtonFactory::CreateWidget(const String& RendName, const UnifiedRect& RendRect, const NameValuePairMap& Params, Screen* Parent)
392  { return this->CreateButton(RendName,RendRect,Parent); }
393 
395  { return this->CreateButton(XMLNode,Parent); }
396 
398  { delete static_cast<Button*>( ToBeDestroyed ); }
399  }//UI
400 }//Mezzanine
401 
402 #endif