MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
pagedcontainer.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 _uipagedcontainer_cpp
41 #define _uipagedcontainer_cpp
42 
43 #include "UI/pagedcontainer.h"
44 #include "UI/pageprovider.h"
45 #include "UI/screen.h"
46 
47 namespace Mezzanine
48 {
49  namespace UI
50  {
51  const String PagedContainer::TypeName = "PagedContainer";
52  const String PagedContainer::EventChildFocusGained = "ChildFocusGained";
53 
55  Widget(Parent),
56  LastFocusedChild(NULL),
57  XProvider(NULL),
58  YProvider(NULL)
59  { }
60 
61  PagedContainer::PagedContainer(const String& RendName, Screen* Parent) :
62  Widget(RendName,Parent),
63  LastFocusedChild(NULL),
64  XProvider(NULL),
65  YProvider(NULL)
66  { }
67 
68  PagedContainer::PagedContainer(const String& RendName, const UnifiedRect& RendRect, Screen* Parent) :
69  Widget(RendName,RendRect,Parent),
70  LastFocusedChild(NULL),
71  XProvider(NULL),
72  YProvider(NULL)
73  { }
74 
76  {
77  if( this->XProvider != NULL )
78  this->XProvider->_SetContainer(NULL);
79  if( this->YProvider != NULL )
80  this->YProvider->_SetContainer(NULL);
81  }
82 
84  {
85  this->Widget::ProtoSerializeImpl(SelfRoot);
86  this->ProtoSerializePageData(SelfRoot);
87  }
88 
90  {
91  this->Widget::ProtoDeSerializeImpl(SelfRoot);
92  this->ProtoDeSerializePageData(SelfRoot);
93  }
94 
95  ///////////////////////////////////////////////////////////////////////////////
96  // Utility
97 
99  {
100  if( this->WorkAreaSize != Area ) {
101  this->WorkAreaSize = Area;
102  }
103  }
104 
106  {
107  return this->WorkAreaSize;
108  }
109 
111  {
112  if( this->ParentQuad != NULL ) {
114  }else{
115  return Vector2(0.0,0.0);
116  }
117  }
118 
119  void PagedContainer::UpdateDimensions(const Rect& OldSelfRect, const Rect& NewSelfRect)
120  {
121  /*if( this->XProvider != NULL ) {
122  this->XProvider->ConfigureProviderMetaData(this->ActDims.Size,this->GetActualWorkAreaSize());
123  }//*/
124  /*if( this->YProvider != NULL && this->YProvider != this->XProvider ) {
125  this->YProvider->ConfigureProviderMetaData(this->ActDims.Size,this->GetActualWorkAreaSize());
126  }//*/
127 
128  // Update the personal data first
129  this->ActDims = NewSelfRect;
130 
131  // Perform the container specific update logic
132  this->UpdateContainerDimensionsImpl(OldSelfRect,NewSelfRect);
133 
134  /*// Update the children, if any
135  if( this->VisibleChildren.empty() == false )
136  this->LayoutStrat->Layout(OldSelfRect,NewSelfRect,this->VisibleChildren);//*/
137 
138  // We done got icky
139  this->_MarkAllLayersDirty();
140  }
141 
143  {
144  return this->LastFocusedChild;
145  }
146 
148  {
149  if( this->XProvider != NULL && this->YProvider != NULL ) {
151  }else if( this->XProvider != NULL ) {
153  }else if( this->YProvider != NULL ) {
155  }else{
157  }
158  }
159 
161  {
162  if( this->XProvider == Prov && this->YProvider == Prov ) {
164  }else if( this->XProvider == Prov ) {
166  }else if( this->YProvider == Prov ) {
168  }else{
170  }
171  }
172 
174  { return this->XProvider; }
175 
177  { return this->YProvider; }
178 
180  {
181  if( this->XProvider == Prov ) {
182  this->XProvider->_SetContainer(NULL);
183  this->XProvider = NULL;
184  }
185  if( this->YProvider == Prov ) {
186  this->YProvider->_SetContainer(NULL);
187  this->YProvider = NULL;
188  }
189  }
190 
191  ///////////////////////////////////////////////////////////////////////////////
192  // Child Management
193 
195  {
196  this->QuadRenderable::AddChild(Child);
197  Child->Subscribe(Widget::EventFocusGained,this);
198  }
199 
201  {
202  if( this->LastFocusedChild == Child ) {
203  this->LastFocusedChild = NULL;
204  }
206  this->QuadRenderable::RemoveChild(Child);
207  }
208 
210  {
211  this->LastFocusedChild = NULL;
212  for( ChildIterator It = this->ChildWidgets.begin() ; It != this->ChildWidgets.end() ; ++It )
213  {
214  (*It)->_NotifyParenthood(NULL);
215  (*It)->Unsubscribe(Widget::EventFocusGained,this);
216  }
217  this->ChildWidgets.clear();
218  this->_MarkDirty();
219  }
220 
221  ///////////////////////////////////////////////////////////////////////////////
222  // Serialization
223 
225  {
226  if( this->XProvider != NULL || this->YProvider != NULL ) {
227  XML::Node PageDataNode = SelfRoot.AppendChild( PagedContainer::GetSerializableName() + "PageData" );
228  if( PageDataNode.AppendAttribute("Version").SetValue("1") )
229  {
230  if( this->XProvider != NULL ) {
231  XML::Node XProviderNode = PageDataNode.AppendChild("XProvider");
232  if( XProviderNode.AppendAttribute("Name").SetValue( this->XProvider->GetName() ) &&
233  XProviderNode.AppendAttribute("Config").SetValue( this->GetProviderConfig( this->XProvider ) ) )
234  {
235  return;
236  }else{
237  SerializeError("Create XML Attribute Values",PagedContainer::GetSerializableName() + "PageData",true);
238  }
239  }
240 
241  if( this->YProvider != NULL ) {
242  XML::Node YProviderNode = PageDataNode.AppendChild("YProvider");
243  if( YProviderNode.AppendAttribute("Name").SetValue( this->YProvider->GetName() ) &&
244  YProviderNode.AppendAttribute("Config").SetValue( this->GetProviderConfig( this->YProvider ) ) )
245  {
246  return;
247  }else{
248  SerializeError("Create XML Attribute Values",PagedContainer::GetSerializableName() + "PageData",true);
249  }
250  }
251 
252  return;
253  }else{
254  SerializeError("Create XML Attribute Values",PagedContainer::GetSerializableName() + "PageData",true);
255  }
256  }
257  }
258 
260  {
261  this->Widget::ProtoSerializeProperties(SelfRoot);
262 
263  XML::Node PropertiesNode = SelfRoot.AppendChild( PagedContainer::GetSerializableName() + "Properties" );
264 
265  if( PropertiesNode.AppendAttribute("Version").SetValue("1") )
266  {
267  XML::Node WorkAreaSizeNode = PropertiesNode.AppendChild("WorkAreaSize");
268  this->WorkAreaSize.ProtoSerialize(WorkAreaSizeNode);
269 
270  return;
271  }else{
272  SerializeError("Create XML Attribute Values",PagedContainer::GetSerializableName() + "Properties",true);
273  }
274  }
275 
277  {
278  XML::Attribute CurrAttrib;
279  XML::Node PageDataNode = SelfRoot.GetChild( PagedContainer::GetSerializableName() + "PageData" );
280 
281  if( !PageDataNode.Empty() ) {
282  if(PageDataNode.GetAttribute("Version").AsInt() == 1) {
283  XML::Node XProviderNode = PageDataNode.GetChild("XProvider");
284  if( !XProviderNode.Empty() ) {
285  String ProviderName;
286  ProviderMode ProviderConfig;
287 
288  CurrAttrib = XProviderNode.GetAttribute("Name");
289  if( !CurrAttrib.Empty() )
290  ProviderName = CurrAttrib.AsString();
291 
292  CurrAttrib = XProviderNode.GetAttribute("Config");
293  if( !CurrAttrib.Empty() )
294  ProviderConfig = static_cast<ProviderMode>( CurrAttrib.AsWhole() );
295 
296  if( !ProviderName.empty() ) {
297  /// @todo This is a blind cast and can cause some issues if the configuration is edited externally such that the named
298  /// widget isn't a provider. Some check may being added may be warrented.
299  PageProvider* Casted = static_cast<PageProvider*>( this->ParentScreen->GetWidget(ProviderName) );
300  if( Casted ) {
301  switch( ProviderConfig )
302  {
303  case PagedContainer::PM_Single_X: this->SetXProvider(Casted); break;
304  case PagedContainer::PM_Single_Y: this->SetYProvider(Casted); break;
305  case PagedContainer::PM_Single_XY: this->SetProviders(Casted,Casted); break;
306  default: /* Do Nothing */ break;
307  }
308  }
309  }
310  }
311 
312  XML::Node YProviderNode = PageDataNode.GetChild("YProvider");
313  if( !YProviderNode.Empty() ) {
314  String ProviderName;
315  ProviderMode ProviderConfig;
316 
317  CurrAttrib = YProviderNode.GetAttribute("Name");
318  if( !CurrAttrib.Empty() )
319  ProviderName = CurrAttrib.AsString();
320 
321  CurrAttrib = YProviderNode.GetAttribute("Config");
322  if( !CurrAttrib.Empty() )
323  ProviderConfig = static_cast<ProviderMode>( CurrAttrib.AsWhole() );
324 
325  if( !ProviderName.empty() ) {
326  /// @todo This is a blind cast and can cause some issues if the configuration is edited externally such that the named
327  /// widget isn't a provider. Some check may being added may be warrented.
328  PageProvider* Casted = static_cast<PageProvider*>( this->ParentScreen->GetWidget(ProviderName) );
329  if( Casted ) {
330  switch( ProviderConfig )
331  {
332  case PagedContainer::PM_Single_X: this->SetXProvider(Casted); break;
333  case PagedContainer::PM_Single_Y: this->SetYProvider(Casted); break;
334  case PagedContainer::PM_Single_XY: this->SetProviders(Casted,Casted); break;
335  default: /* Do Nothing */ break;
336  }
337  }
338  }
339  }
340  }else{
341  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + (PagedContainer::GetSerializableName() + "PageData") + ": Not Version 1.");
342  }
343  }else{
344  MEZZ_EXCEPTION(Exception::II_IDENTITY_NOT_FOUND_EXCEPTION,PagedContainer::GetSerializableName() + "PageData" + " was not found in the provided XML node, which was expected.");
345  }
346  }
347 
349  {
350  this->Widget::ProtoDeSerializeProperties(SelfRoot);
351 
352  //XML::Attribute CurrAttrib;
353  XML::Node PropertiesNode = SelfRoot.GetChild( PagedContainer::GetSerializableName() + "Properties" );
354 
355  if( !PropertiesNode.Empty() ) {
356  if(PropertiesNode.GetAttribute("Version").AsInt() == 1) {
357  XML::Node WorkAreaSizeNode = PropertiesNode.GetChild("WorkAreaSize");
358  if( !WorkAreaSizeNode.Empty() ) {
359  this->WorkAreaSize.ProtoDeSerialize(WorkAreaSizeNode);
360  }
361  }else{
362  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + (PagedContainer::GetSerializableName() + "Properties") + ": Not Version 1.");
363  }
364  }else{
365  MEZZ_EXCEPTION(Exception::II_IDENTITY_NOT_FOUND_EXCEPTION,PagedContainer::GetSerializableName() + "Properties" + " was not found in the provided XML node, which was expected.");
366  }
367  }
368 
370  {
372  }
373 
374  ///////////////////////////////////////////////////////////////////////////////
375  // Internal Event Methods
376 
378  {
380  this->FireEvent(Args);
381  }
382 
383  ///////////////////////////////////////////////////////////////////////////////
384  // Internal Methods
385 
387  {
388  if( Args.EventName == Widget::EventFocusGained ) {
389  const WidgetEventArguments& WidArgs = static_cast<const WidgetEventArguments&>(Args);
390  Widget* EventWidget = this->GetChild(WidArgs.WidgetName);
391  if( EventWidget != NULL ) {
392  this->LastFocusedChild = EventWidget;
393  this->_OnChildFocusGained( this->LastFocusedChild->GetName() );
394  }
395  }
396  }
397 
399  {
400  // Update the children based on page positions and the container size so we can grab the proper vertices.
401  if(this->VertexCache) {
402  if( this->Dirty || this->AllLayersDirty ) {
403  this->VertexCache->Clear();
405  for( VisibleChildIterator ChildIt = this->VisibleChildren.begin() ; ChildIt != this->VisibleChildren.end() ; ++ChildIt )
406  {
407  if( (*ChildIt)->IsVisible() ) {
408  (*ChildIt)->_AppendRenderDataCascading(*VertexCache);
409  }
410  }
411  }
412  RenderData.Append(*VertexCache);
413  }else{
414  this->_AppendRenderData(RenderData);
415  for( VisibleChildIterator It = this->VisibleChildren.begin() ; It != this->VisibleChildren.end() ; ++It )
416  {
417  if( (*It)->IsVisible() ) {
418  (*It)->_AppendRenderDataCascading(RenderData);
419  }
420  }
421  }
422  }
423  }//UI
424 }//Mezzanine
425 
426 #endif