MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
quadrenderable.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 _uiquadrenderable_cpp
41 #define _uiquadrenderable_cpp
42 
43 #include "UI/quadrenderable.h"
44 
45 #include "UI/multilinetextlayer.h"
46 #include "UI/singlelinetextlayer.h"
47 #include "UI/layoutstrategy.h"
48 #include "UI/widget.h"
49 #include "UI/screen.h"
50 
51 #include "UI/imagelayer.h"
52 #include "UI/multilinetextlayer.h"
53 #include "UI/singlelinetextlayer.h"
54 
55 #include "stringtool.h"
56 #include "serialization.h"
57 
58 #include <algorithm>
59 
60 namespace Mezzanine
61 {
62  namespace UI
63  {
64  ///////////////////////////////////////////////////////////////////////////////
65  // RenderLayerGroup Methods
66 
68  GroupName(Name),
69  ParentQuad(Creator)
70  { }
71 
73  { }
74 
75  ///////////////////////////////////////////////////////////////////////////////
76  // Utility
77 
79  {
80  return this->GroupName;
81  }
82 
84  {
85  for( RenderLayerIterator It = this->RenderLayers.begin() ; It != this->RenderLayers.end() ; ++It )
86  { (*It).second->NotifyActive(); }
87  }
88 
90  {
91  for( RenderLayerIterator It = this->RenderLayers.begin() ; It != this->RenderLayers.end() ; ++It )
92  { (*It).second->NotifyInactive(); }
93  }
94 
95  ///////////////////////////////////////////////////////////////////////////////
96  // RenderLayer Management
97 
99  {
100  for( RenderLayerIterator It = this->RenderLayers.begin() ; It != this->RenderLayers.end() ; ++It )
101  {
102  if( (*It).first > ZOrder ) {
103  this->RenderLayers.insert(It,RenderLayerPair(ZOrder,RL));
104  if( this->ParentQuad->GetActiveGroup() == this ) {
105  this->ParentQuad->_MarkDirty();
106  }
107  return;
108  }
109  }
110  this->RenderLayers.push_back(RenderLayerPair(ZOrder,RL));
111  if( this->ParentQuad->GetActiveGroup() == this ) {
112  this->ParentQuad->_MarkDirty();
113  }
114  return;
115  }
116 
118  {
119  return this->RenderLayers.size();
120  }
121 
123  {
124  this->RenderLayers.swap( OtherGroup->RenderLayers );
125  if( this->ParentQuad->GetActiveGroup() == this ) {
126  this->ParentQuad->_MarkDirty();
127  }
128  }
129 
131  {
132  for( RenderLayerIterator It = this->RenderLayers.begin() ; It != this->RenderLayers.end() ; ++It )
133  {
134  if( (*It).second == RL ) {
135  this->RenderLayers.erase(It);
136  if( this->ParentQuad->GetActiveGroup() == this ) {
137  this->ParentQuad->_MarkDirty();
138  }
139  return;
140  }
141  }
142  }
143 
145  {
146  // We don't own them, QuadRenderables do, so just clear
147  this->RenderLayers.clear();
148  }
149 
151  { return this->RenderLayers.begin(); }
152 
154  { return this->RenderLayers.end(); }
155 
157  { return this->RenderLayers.begin(); }
158 
160  { return this->RenderLayers.end(); }
161 
162  ///////////////////////////////////////////////////////////////////////////////
163  // Serialization
164 
166  { return "RenderLayerGroup"; }
167 
168  ///////////////////////////////////////////////////////////////////////////////
169  // QuadRenderable Methods
170 
172  Renderable(Parent),
173  ParentQuad(NULL),
174  ActiveGroup(NULL),
175  LayoutStrat(NULL),
176  VertexCache(NULL),
177  ZOrder(0),
178  Priority(UI::RP_Medium),
179  MousePassthrough(false),
180  ManualTransformUpdates(false),
181  AllLayersDirty(false)
182  {
183  this->ActDims.SetIdentity();
184  }
185 
186  QuadRenderable::QuadRenderable(const String& RendName, Screen* Parent) :
187  Renderable(RendName,Parent),
188  ParentQuad(NULL),
189  ActiveGroup(NULL),
190  LayoutStrat(NULL),
191  VertexCache(NULL),
192  ZOrder(0),
193  Priority(UI::RP_Medium),
194  MousePassthrough(false),
195  ManualTransformUpdates(false),
196  AllLayersDirty(false)
197  {
198  this->ActDims.SetIdentity();
199  }
200 
201  QuadRenderable::QuadRenderable(const String& RendName, const UnifiedRect& RendRect, Screen* Parent) :
202  Renderable(RendName,Parent),
203  ParentQuad(NULL),
204  ActiveGroup(NULL),
205  LayoutStrat(NULL),
206  VertexCache(NULL),
207  ZOrder(0),
208  Priority(UI::RP_Medium),
209  MousePassthrough(false),
210  ManualTransformUpdates(false),
211  AllLayersDirty(false)
212  {
213  this->ActDims.SetIdentity();
214 
215  this->PositioningPolicy.UPosition = RendRect.Position;
216  this->SizingPolicy.USize = RendRect.Size;
217  }
218 
220  {
221  for( ChildIterator ChildIt = this->ChildWidgets.begin() ; ChildIt != this->ChildWidgets.end() ; ++ChildIt )
222  { this->ParentScreen->DestroyWidget( (*ChildIt) ); }
223  this->ChildWidgets.clear();
225  this->DestroyAllRenderLayers();
226  this->SetLocalVertexCaching(false);
227  }
228 
230  {
231  this->ProtoSerializeProperties(SelfRoot);
232  this->ProtoSerializeRenderLayers(SelfRoot);
233  this->ProtoSerializeRenderLayerGroups(SelfRoot);
234  }
235 
237  {
238  // Get the render layers first in this case as our properties partially depend on them (ActiveGroup)
239  this->ProtoDeSerializeRenderLayers(SelfRoot);
240  this->ProtoDeSerializeRenderLayerGroups(SelfRoot);
241  this->ProtoDeSerializeProperties(SelfRoot);
242  }
243 
244  void QuadRenderable::AppendLayerVertices(std::vector<VertexData>& Vertices)
245  {
246  if( this->ActiveGroup == NULL )
247  return;
249  {
250  (*It).second->_AppendVertices(Vertices);
251  }
252  }
253 
255  {
256  if( this->Dirty || this->AllLayersDirty )
257  {
258  for( RenderLayerIterator It = this->RenderLayers.begin() ; It != this->RenderLayers.end() ; ++It )
259  {
260  (*It)->_Redraw(AllLayersDirty);
261  }
262  this->Dirty = this->AllLayersDirty = false;
263  }
264  }
265 
267  {
268  if( NewSize > this->RenderLayers.size() )
269  {
270  Whole Pow2 = 1;
271  while( Pow2 < NewSize )
272  Pow2 <<= 1;
273 
274  this->RenderLayers.resize(Pow2,NULL);
275  }
276  }
277 
278  ///////////////////////////////////////////////////////////////////////////////
279  // Utility Methods
280 
282  { return this->ZOrder; }
283 
284  Boolean QuadRenderable::CheckOverlap(const QuadRenderable* Quad) const
285  { return this->GetRect().CheckOverlap(Quad->GetRect()); }
286 
287  Boolean QuadRenderable::IsInside(const Vector2& Point) const
288  { return this->GetRect().IsInside(Point); }
289 
291  { return (this->ParentScreen == this->ParentQuad); }
292 
294  {
295  Real Ret = 0;
296  for( ConstRenderLayerIterator LayerIt = this->RenderLayers.begin() ; LayerIt != this->RenderLayers.end() ; ++LayerIt )
297  {
298  RenderLayer::RenderLayerType LayerType = (*LayerIt)->GetLayerType();
299  if( LayerType == RenderLayer::RLT_MultiLineText || LayerType == RenderLayer::RLT_SingleLineText ) {
300  Real LayerHeight = static_cast<TextLayer*>( *LayerIt )->GetTotalHeight();
301  if( LayerHeight > Ret )
302  Ret = LayerHeight;
303  }
304  }
305  return Ret;
306  }
307 
309  {
310  if( this->ParentQuad ) {
311  Rect ParentRect = this->ParentQuad->GetRect();
312  this->ParentQuad->UpdateDimensions(ParentRect,ParentRect);
313  }
314  }
315 
317  {
318  Rect TempRect = this->GetRect();
319  this->UpdateDimensions(TempRect,TempRect);
320  }
321 
322  void QuadRenderable::UpdateDimensions(const Rect& OldSelfRect, const Rect& NewSelfRect)
323  {
324  // Update the personal data first
325  this->ActDims = NewSelfRect;
326 
327  // Update the children, if we have a layout strat and the chidlren exist
328  if( this->LayoutStrat != NULL && this->ChildWidgets.empty() == false )
329  this->LayoutStrat->Layout(OldSelfRect,NewSelfRect,this->ChildWidgets);
330 
331  // We done got icky
332  this->_MarkAllLayersDirty();
333  }
334 
336  { this->MousePassthrough = Enable; }
337 
339  { return this->MousePassthrough; }
340 
342  { this->ManualTransformUpdates = Enable; }
343 
345  { return this->ManualTransformUpdates; }
346 
348  { this->Priority = RP; }
349 
351  {
352  this->SetRenderPriority(RP);
353  for( ChildIterator ChildIt = this->ChildWidgets.begin() ; ChildIt != this->ChildWidgets.end() ; ++ChildIt )
354  (*ChildIt)->SetRenderPriorityCascading(RP);
355  }
356 
358  { return this->Priority; }
359 
360  ///////////////////////////////////////////////////////////////////////////////
361  // Transform Policy Methods
362 
364  {
365  if( this->PositioningPolicy != Policy ) {
366  this->PositioningPolicy = Policy;
367  }
368  }
369 
371  {
372  return this->PositioningPolicy;
373  }
374 
376  {
377  if( this->SizingPolicy != Policy ) {
378  this->SizingPolicy = Policy;
379  }
380  }
381 
383  {
384  return this->SizingPolicy;
385  }
386 
388  {
389  if( this->PositioningPolicy.PositionRules != Rules ) {
390  this->PositioningPolicy.PositionRules = Rules;
391  }
392  }
393 
395  {
396  return this->PositioningPolicy.PositionRules;
397  }
398 
400  {
401  if( this->SizingPolicy.HorizontalRules != Rules ) {
402  this->SizingPolicy.HorizontalRules = Rules;
403  }
404  }
405 
407  {
408  return this->SizingPolicy.HorizontalRules;
409  }
410 
412  {
413  if( this->SizingPolicy.VerticalRules != Rules ) {
414  this->SizingPolicy.VerticalRules = Rules;
415  }
416  }
417 
419  {
420  return this->SizingPolicy.VerticalRules;
421  }
422 
424  {
425  if( this->SizingPolicy.MinSize != Min ) {
426  this->SizingPolicy.MinSize = Min;
427  }
428  }
429 
431  {
432  return this->SizingPolicy.MinSize;
433  }
434 
436  {
437  if( this->SizingPolicy.MaxSize != Max ) {
438  this->SizingPolicy.MaxSize = Max;
439  }
440  }
441 
443  {
444  return this->SizingPolicy.MaxSize;
445  }
446 
447  ///////////////////////////////////////////////////////////////////////////////
448  // RenderLayer Management
449 
451  {
452  ImageLayer* NewLayer = new ImageLayer(this);
453  NewLayer->_UpdateIndex(this->RenderLayers.size());
454  this->RenderLayers.push_back(NewLayer);
455  this->_MarkDirty();
456  return NewLayer;
457  }
458 
459  ImageLayer* QuadRenderable::CreateImageLayer(const UInt16 ZOrder, const String& GroupName)
460  {
461  ImageLayer* NewLayer = this->CreateImageLayer();
462  this->AddLayerToGroup(NewLayer,ZOrder,GroupName);
463  return NewLayer;
464  }
465 
467  {
468  ImageLayer* NewLayer = this->CreateImageLayer();
469  this->AddLayerToGroups(NewLayer,Entrys);
470  return NewLayer;
471  }
472 
474  {
475  SingleLineTextLayer* NewLayer = new SingleLineTextLayer(this);
476  NewLayer->_UpdateIndex(this->RenderLayers.size());
477  this->RenderLayers.push_back(NewLayer);
478  this->_MarkDirty();
479  return NewLayer;
480  }
481 
483  {
485  this->AddLayerToGroup(NewLayer,ZOrder,GroupName);
486  return NewLayer;
487  }
488 
490  {
492  this->AddLayerToGroups(NewLayer,Entrys);
493  return NewLayer;
494  }
495 
497  {
498  SingleLineTextLayer* NewLayer = new SingleLineTextLayer(FontName,this);
499  NewLayer->_UpdateIndex(this->RenderLayers.size());
500  this->RenderLayers.push_back(NewLayer);
501  this->_MarkDirty();
502  return NewLayer;
503  }
504 
505  SingleLineTextLayer* QuadRenderable::CreateSingleLineTextLayer(const String& FontName, const UInt16 ZOrder, const String& GroupName)
506  {
507  SingleLineTextLayer* NewLayer = this->CreateSingleLineTextLayer(FontName);
508  this->AddLayerToGroup(NewLayer,ZOrder,GroupName);
509  return NewLayer;
510  }
511 
513  {
514  SingleLineTextLayer* NewLayer = this->CreateSingleLineTextLayer(FontName);
515  this->AddLayerToGroups(NewLayer,Entrys);
516  return NewLayer;
517  }
518 
520  {
521  SingleLineTextLayer* NewLayer = new SingleLineTextLayer(LineHeight,this);
522  NewLayer->_UpdateIndex(this->RenderLayers.size());
523  this->RenderLayers.push_back(NewLayer);
524  this->_MarkDirty();
525  return NewLayer;
526  }
527 
528  SingleLineTextLayer* QuadRenderable::CreateSingleLineTextLayer(const Real& LineHeight, const UInt16 ZOrder, const String& GroupName)
529  {
530  SingleLineTextLayer* NewLayer = this->CreateSingleLineTextLayer(LineHeight);
531  this->AddLayerToGroup(NewLayer,ZOrder,GroupName);
532  return NewLayer;
533  }
534 
536  {
537  SingleLineTextLayer* NewLayer = this->CreateSingleLineTextLayer(LineHeight);
538  this->AddLayerToGroups(NewLayer,Entrys);
539  return NewLayer;
540  }
541 
543  {
544  MultiLineTextLayer* NewLayer = new MultiLineTextLayer(this);
545  NewLayer->_UpdateIndex(this->RenderLayers.size());
546  this->RenderLayers.push_back(NewLayer);
547  this->_MarkDirty();
548  return NewLayer;
549  }
550 
552  {
553  MultiLineTextLayer* NewLayer = this->CreateMultiLineTextLayer();
554  this->AddLayerToGroup(NewLayer,ZOrder,GroupName);
555  return NewLayer;
556  }
557 
559  {
560  MultiLineTextLayer* NewLayer = this->CreateMultiLineTextLayer();
561  this->AddLayerToGroups(NewLayer,Entrys);
562  return NewLayer;
563  }
564 
566  {
567  MultiLineTextLayer* NewLayer = new MultiLineTextLayer(FontName,this);
568  NewLayer->_UpdateIndex(this->RenderLayers.size());
569  this->RenderLayers.push_back(NewLayer);
570  this->_MarkDirty();
571  return NewLayer;
572  }
573 
574  MultiLineTextLayer* QuadRenderable::CreateMultiLineTextLayer(const String& FontName, const UInt16 ZOrder, const String& GroupName)
575  {
576  MultiLineTextLayer* NewLayer = this->CreateMultiLineTextLayer(FontName);
577  this->AddLayerToGroup(NewLayer,ZOrder,GroupName);
578  return NewLayer;
579  }
580 
582  {
583  MultiLineTextLayer* NewLayer = this->CreateMultiLineTextLayer(FontName);
584  this->AddLayerToGroups(NewLayer,Entrys);
585  return NewLayer;
586  }
587 
589  {
590  MultiLineTextLayer* NewLayer = new MultiLineTextLayer(LineHeight,this);
591  NewLayer->_UpdateIndex(this->RenderLayers.size());
592  this->RenderLayers.push_back(NewLayer);
593  this->_MarkDirty();
594  return NewLayer;
595  }
596 
597  MultiLineTextLayer* QuadRenderable::CreateMultiLineTextLayer(const Real& LineHeight, const UInt16 ZOrder, const String& GroupName)
598  {
599  MultiLineTextLayer* NewLayer = this->CreateMultiLineTextLayer(LineHeight);
600  this->AddLayerToGroup(NewLayer,ZOrder,GroupName);
601  return NewLayer;
602  }
603 
605  {
606  MultiLineTextLayer* NewLayer = this->CreateMultiLineTextLayer(LineHeight);
607  this->AddLayerToGroups(NewLayer,Entrys);
608  return NewLayer;
609  }
610 
612  { return this->RenderLayers.at(Index); }
613 
615  { return this->RenderLayers.size(); }
616 
618  { return ( this->ActiveGroup != NULL ? this->ActiveGroup->GetNumRenderLayers() : 0 ); }
619 
621  {
622  for( RenderLayerGroupIterator It = this->RenderLayerGroups.begin() ; It != this->RenderLayerGroups.end() ; ++It )
623  {
624  (*It).second->RemoveLayer(ToBeDestroyed);
625  }
626  for( Whole Index = 0 ; Index < this->RenderLayers.size() ; ++Index )
627  {
628  if( ToBeDestroyed == this->RenderLayers[Index] ) {
629  if( Index != this->RenderLayers.size() - 1 ) {
630  // swap...
631  std::swap(this->RenderLayers[Index],this->RenderLayers[this->RenderLayers.size()-1]);
632  this->RenderLayers[Index]->_UpdateIndex(Index);
633  }
634  // ...and pop
635  this->RenderLayers.pop_back();
636  break;
637  }
638  }
639  delete ToBeDestroyed;
640  }
641 
643  {
644  for( RenderLayerGroupIterator It = this->RenderLayerGroups.begin() ; It != this->RenderLayerGroups.end() ; ++It )
645  {
646  (*It).second->RemoveAllLayers();
647  }
648  for( RenderLayerIterator It = this->RenderLayers.begin() ; It != this->RenderLayers.end() ; ++It )
649  {
650  delete (*It);
651  }
652  this->RenderLayers.clear();
653  }
654 
656  { return this->RenderLayers.begin(); }
657 
659  { return this->RenderLayers.end(); }
660 
662  { return this->RenderLayers.begin(); }
663 
665  { return this->RenderLayers.end(); }
666 
667  ///////////////////////////////////////////////////////////////////////////////
668  // RenderLayerGroup Management
669 
671  {
672  RenderLayerGroupIterator It = this->RenderLayerGroups.find(Name);
673  if( It != this->RenderLayerGroups.end() ) {
674  this->SetActiveGroup( (*It).second );
675  }else{
676  MEZZ_EXCEPTION(Exception::II_IDENTITY_NOT_FOUND_EXCEPTION,"RenderLayerGroup named \"" + Name + "\" does not exist in QuadRenderable: \"" + GetName() + "\"." );
677  }
678  }
679 
681  {
682  if( this->ActiveGroup != Group ) {
683  // Out with the old
684  if( this->ActiveGroup != NULL )
685  this->ActiveGroup->NotifyInactive();
686  // In with the new
687  this->ActiveGroup = Group;
688  if( this->ActiveGroup != NULL )
689  this->ActiveGroup->NotifyActive();
690  this->_MarkDirty();
691  }
692  }
693 
695  {
696  return this->ActiveGroup;
697  }
698 
700  {
701  ConstRenderLayerGroupIterator It = this->RenderLayerGroups.find(Name);
702  return ( It != this->RenderLayerGroups.end() );
703  }
704 
706  {
707  return this->RenderLayerGroups.size();
708  }
709 
710  void QuadRenderable::AddLayerToGroup(RenderLayer* Layer, const UInt16 ZOrder, const String& GroupName)
711  {
712  this->CreateOrRetrieveRenderLayerGroup(GroupName)->AddLayer(Layer,ZOrder);
713  }
714 
716  {
717  for( GroupOrderEntryVector::const_iterator It = Entrys.begin() ; It != Entrys.end() ; ++It )
718  {
719  this->CreateOrRetrieveRenderLayerGroup( (*It).second )->AddLayer( Layer, (*It).first );
720  }
721  }
722 
724  {
725  RenderLayerGroupIterator It = this->RenderLayerGroups.find(GroupName);
726  if( It != this->RenderLayerGroups.end() ) {
727  (*It).second->RemoveLayer(Layer);
728  }
729  }
730 
732  {
733  for( RenderLayerGroupIterator It = this->RenderLayerGroups.begin() ; It != this->RenderLayerGroups.end() ; ++It )
734  {
735  (*It).second->RemoveLayer(Layer);
736  }
737  }
738 
740  {
741  RenderLayerGroupIterator It = this->RenderLayerGroups.find(Name);
742  if( It == this->RenderLayerGroups.end() ) {
743  Boolean Empty = ( this->RenderLayerGroups.empty() && this->ActiveGroup == NULL );
744  RenderLayerGroup* NewGroup = new RenderLayerGroup(Name,this);
745  this->RenderLayerGroups.insert( std::pair<String,RenderLayerGroup*>(Name,NewGroup) );
746  if( Empty ) {
747  this->SetActiveGroup( NewGroup );
748  }
749  return NewGroup;
750  }else{
751  MEZZ_EXCEPTION(Exception::II_DUPLICATE_IDENTITY_EXCEPTION,"RenderLayerGroup named \"" + Name + "\" already exists in QuadRenderable: \"" + this->GetName() + "\"." );
752  }
753  return NULL;
754  }
755 
757  {
758  RenderLayerGroupIterator It = this->RenderLayerGroups.find(Name);
759  if( It != this->RenderLayerGroups.end() ) return (*It).second;
760  else return this->CreateRenderLayerGroup(Name);
761  }
762 
764  {
765  ConstRenderLayerGroupIterator It = this->RenderLayerGroups.find(Name);
766  if( It != this->RenderLayerGroups.end() ) return (*It).second;
767  else return NULL;
768  }
769 
771  {
772  RenderLayerGroupIterator It = this->RenderLayerGroups.find(Name);
773  if( It != this->RenderLayerGroups.end() ) {
774  delete (*It).second;
775  this->RenderLayerGroups.erase(It);
776  }
777  }
778 
780  {
781  this->DestroyRenderLayerGroup(ToBeDestroyed->GetName());
782  }
783 
785  {
786  for( RenderLayerGroupIterator It = this->RenderLayerGroups.begin() ; It != this->RenderLayerGroups.end() ; ++It )
787  {
788  delete (*It).second;
789  }
790  this->RenderLayerGroups.clear();
791  }
792 
794  { return this->RenderLayerGroups.begin(); }
795 
797  { return this->RenderLayerGroups.end(); }
798 
800  { return this->RenderLayerGroups.begin(); }
801 
803  { return this->RenderLayerGroups.end(); }
804 
805  ///////////////////////////////////////////////////////////////////////////////
806  // Child Management
807 
809  {
810  if( this->GetRenderableType() == Renderable::RT_Screen ) {
811  // If this is the screen adding a direct child, enable vertex caching
812  Child->SetLocalVertexCaching(true);
813  }
814 
815  UInt16 Zorder = Child->GetZOrder();
816  for( ChildIterator It = this->ChildWidgets.begin() ; It != this->ChildWidgets.end() ; ++It )
817  {
818  if( (*It)->GetZOrder() > Zorder ) {
819  this->ChildWidgets.insert(It,Child);
820  Child->_NotifyParenthood(this);
821  Child->_MarkAllChildrenDirty();
822  //this->_MarkDirty();
823  return;
824  }
825  }
826  this->ChildWidgets.push_back(Child);
827  Child->_NotifyParenthood(this);
828  Child->_MarkAllChildrenDirty();
829  //this->_MarkDirty();
830  }
831 
832  void QuadRenderable::AddChild(Widget* Child, const UInt16 ZOrder)
833  {
834  Child->_SetZOrder(ZOrder);
835  this->AddChild(Child);
836  }
837 
839  {
840  for( ConstChildIterator ChildIt = this->ChildWidgets.begin() ; ChildIt != this->ChildWidgets.end() ; ++ChildIt )
841  {
842  if( Zorder == (*ChildIt)->GetZOrder() )
843  return (*ChildIt);
844  }
845  return NULL;
846  }
847 
848  Widget* QuadRenderable::GetChild(const String& RendName) const
849  {
850  for( ConstChildIterator ChildIt = this->ChildWidgets.begin() ; ChildIt != this->ChildWidgets.end() ; ++ChildIt )
851  {
852  if( RendName == (*ChildIt)->GetName() )
853  return (*ChildIt);
854  }
855  return NULL;
856  }
857 
859  {
860  return this->ChildWidgets.size();
861  }
862 
864  {
865  for( ChildIterator It = this->ChildWidgets.begin() ; It != this->ChildWidgets.end() ; ++It )
866  {
867  if( Child == (*It) ) {
868  Child->ParentQuad = NULL;
869  this->ChildWidgets.erase(It);
870  return;
871  }
872  }
873  _MarkDirty();
874  }
875 
877  {
878  for( ChildIterator It = this->ChildWidgets.begin() ; It != this->ChildWidgets.end() ; ++It )
879  {
880  (*It)->ParentQuad = NULL;
881  }
882  this->ChildWidgets.clear();
883  this->_MarkDirty();
884  }
885 
887  { return this->ChildWidgets.begin(); }
888 
890  { return this->ChildWidgets.end(); }
891 
893  { return this->ChildWidgets.begin(); }
894 
896  { return this->ChildWidgets.end(); }
897 
899  { return this->ChildWidgets.rbegin(); }
900 
902  { return this->ChildWidgets.rend(); }
903 
905  { return this->ChildWidgets.rbegin(); }
906 
908  { return this->ChildWidgets.rend(); }
909 
910  ///////////////////////////////////////////////////////////////////////////////
911  // Transform Methods
912 
914  {
915  if( this->PositioningPolicy.UPosition != Position ) {
916  this->PositioningPolicy.UPosition = Position;
917  }
918  }
919 
921  {
922  if( this->SizingPolicy.USize != Size ) {
923  this->SizingPolicy.USize = Size;
924  }
925  }
926 
928  { return this->PositioningPolicy.UPosition; }
929 
931  { return this->SizingPolicy.USize; }
932 
934  { return UnifiedRect(this->PositioningPolicy.UPosition,this->SizingPolicy.USize); }
935 
937  { return this->ActDims.Position; }
938 
940  { return this->ActDims.Size; }
941 
943  { return this->ActDims; }
944 
945  ///////////////////////////////////////////////////////////////////////////////
946  // Fetch Methods
947 
949  { return this->ParentQuad; }
950 
952  {
953  if( this->ParentQuad ) {
954  ConstChildIterator ParentEnd = this->ParentQuad->ChildrenEnd();
955  ConstChildIterator ParentBegin = this->ParentQuad->ChildrenBegin();
956  for( ConstChildIterator ChildIt = ParentBegin ; ChildIt != ParentEnd ; ++ChildIt )
957  {
958  if( this == (*ChildIt) ) {
959  if( ParentEnd != (++ChildIt) ) return (*ChildIt);
960  else return ( Wrap ? (*ParentBegin) : this );
961  }
962  }
963  }
964  return NULL;
965  }
966 
968  {
969  if( this->ParentQuad ) {
970  ConstChildIterator ParentEnd = this->ParentQuad->ChildrenEnd();
971  ConstChildIterator ParentBegin = this->ParentQuad->ChildrenBegin();
972  for( ConstChildIterator ChildIt = ParentBegin ; ChildIt != ParentEnd ; ++ChildIt )
973  {
974  if( this == (*ChildIt) ) {
975  if( ParentBegin != (--ChildIt) ) return (*ChildIt);
976  else return ( Wrap ? (*ParentEnd) : this );
977  }
978  }
979  }
980  return NULL;
981  }
982 
984  {
985  if(this->IsChildOfScreen()) return this;
986  else return (this->ParentQuad ? this->ParentQuad->GetTopMostQuad() : this );
987  }
988 
989  ///////////////////////////////////////////////////////////////////////////////
990  // VertexCaching Methods
991 
993  {
994  if(Enable && !VertexCache) {
995  this->VertexCache = new ScreenRenderData();
996  }else if(!Enable && VertexCache) {
997  this->VertexCache->Clear();
998  delete this->VertexCache;
999  this->VertexCache = NULL;
1000  }
1001  }
1002 
1004  {
1005  return this->VertexCache != NULL;
1006  }
1007 
1008  ///////////////////////////////////////////////////////////////////////////////
1009  // Serialization
1010 
1012  {
1013  XML::Node SelfRoot = ParentNode.AppendChild(this->GetDerivedSerializableName());
1014 
1015  this->ProtoSerializeImpl(SelfRoot);
1016 
1017  // Child quads always get serialized last
1018  this->ProtoSerializeChildQuads(SelfRoot);
1019  }
1020 
1022  {
1023  this->Renderable::ProtoSerializeProperties(SelfRoot);
1024  XML::Node PropertiesNode = SelfRoot.AppendChild( QuadRenderable::GetSerializableName() + "Properties" );
1025 
1026  if( PropertiesNode.AppendAttribute("Version").SetValue("1") &&
1027  PropertiesNode.AppendAttribute("MousePassthrough").SetValue( this->MousePassthrough ? "true" : "false" ) &&
1028  PropertiesNode.AppendAttribute("ManualTransformUpdates").SetValue( this->ManualTransformUpdates ? "true" : "false" ) &&
1029  PropertiesNode.AppendAttribute("ZOrder").SetValue(this->ZOrder) &&
1030  PropertiesNode.AppendAttribute("VertexCache").SetValue( this->IsVertexCachingEnabled() ? "true" : "false" ) )
1031  {
1032  XML::Node ActDimsNode = PropertiesNode.AppendChild("Dimensions");
1033  this->ActDims.ProtoSerialize( ActDimsNode );
1034  XML::Node PositioningPolicyNode = PropertiesNode.AppendChild("PositioningPolicy");
1035  this->PositioningPolicy.ProtoSerialize( PositioningPolicyNode );
1036  XML::Node SizingPolicyNode = PropertiesNode.AppendChild("SizingPolicy");
1037  this->SizingPolicy.ProtoSerialize( SizingPolicyNode );
1038 
1039  return;
1040  }else{
1041  SerializeError("Create XML Attribute Values",QuadRenderable::GetSerializableName() + "Properties",true);
1042  }
1043  }
1044 
1046  {
1047  XML::Node LayersNode = SelfRoot.AppendChild( "RenderLayers" );
1048  if( LayersNode.AppendAttribute("Version").SetValue("1") == false ) {
1049  SerializeError("Create XML Version Attribute","RenderLayers",true);
1050  }
1051 
1052  for( ConstRenderLayerIterator LayerIt = this->RenderLayers.begin() ; LayerIt != this->RenderLayers.end() ; ++LayerIt )
1053  {
1054  (*LayerIt)->ProtoSerialize(SelfRoot);
1055  }
1056  }
1057 
1059  {
1060  XML::Node GroupsNode = SelfRoot.AppendChild( "RenderLayerGroups" );
1061  if( GroupsNode.AppendAttribute("Version").SetValue("1") == false ) {
1062  SerializeError("Create XML Version Attribute","RenderLayerGroups",true);
1063  }
1064 
1065  for( ConstRenderLayerGroupIterator GroupIt = this->RenderLayerGroups.begin() ; GroupIt != this->RenderLayerGroups.end() ; ++GroupIt )
1066  {
1067  XML::Node CurrGroupNode = GroupsNode.AppendChild( "RenderLayerGroup" );
1068  if( CurrGroupNode.AppendAttribute( "Name" ).SetValue( (*GroupIt).first ) ) {
1069  for( RenderLayerGroup::RenderLayerIterator LayerIt = (*GroupIt).second->RenderLayerBegin() ; LayerIt != (*GroupIt).second->RenderLayerEnd() ; ++LayerIt )
1070  {
1071  XML::Node CurrLayerNode = CurrGroupNode.AppendChild( "RenderLayer" );
1072 
1073  if( CurrLayerNode.AppendAttribute( "Index" ).SetValue( (*LayerIt).second->GetIndex() ) == false ) {
1074  SerializeError("Create XML Attribute Values","Index",true);
1075  }
1076  if( CurrLayerNode.AppendAttribute( "ZOrder" ).SetValue( (*GroupIt).first ) == false ) {
1077  SerializeError("Create XML Attribute Values","ZOrder",true);
1078  }
1079  }
1080  }else{
1081  SerializeError("Create XML Attribute Values","Name",true);
1082  }
1083  }
1084  }
1085 
1087  {
1088  XML::Node ChildrenNode = SelfRoot.AppendChild( "Children" );
1089  if( ChildrenNode.AppendAttribute("Version").SetValue("1") ) {
1090  for( ConstChildIterator ChildIt = this->ChildWidgets.begin() ; ChildIt != this->ChildWidgets.end() ; ++ChildIt )
1091  {
1092  (*ChildIt)->ProtoSerialize(ChildrenNode);
1093  }
1094  }else{
1095  SerializeError("Create XML Version Attribute","Children",true);
1096  }
1097  }
1098 
1100  {
1101  this->ProtoDeSerializeImpl(SelfRoot);
1102 
1103  // Child quads update is always last
1104  this->ProtoDeSerializeChildQuads(SelfRoot);
1105  }
1106 
1108  {
1110 
1111  XML::Attribute CurrAttrib;
1112  XML::Node PropertiesNode = SelfRoot.GetChild( QuadRenderable::GetSerializableName() + "Properties" );
1113 
1114  if( !PropertiesNode.Empty() ) {
1115  if(PropertiesNode.GetAttribute("Version").AsInt() == 1) {
1116  // Get the single data type properties
1117  CurrAttrib = PropertiesNode.GetAttribute("MousePassthrough");
1118  if( !CurrAttrib.Empty() )
1119  this->MousePassthrough = StringTools::ConvertToBool( CurrAttrib.AsString() );
1120 
1121  CurrAttrib = PropertiesNode.GetAttribute("ManualTransformUpdates");
1122  if( !CurrAttrib.Empty() )
1124 
1125  CurrAttrib = PropertiesNode.GetAttribute("ZOrder");
1126  if( !CurrAttrib.Empty() )
1127  this->ZOrder = CurrAttrib.AsWhole();
1128 
1129  CurrAttrib = PropertiesNode.GetAttribute("VertexCache");
1130  if( !CurrAttrib.Empty() )
1132 
1133  String ActiveRenderGroup = PropertiesNode.GetAttribute("ActiveGroupName").AsString();
1134  if( !ActiveRenderGroup.empty() )
1135  this->SetActiveGroup(ActiveRenderGroup);
1136 
1137  // Get the properties that need their own nodes
1138  XML::Node DimsNode = PropertiesNode.GetChild("Dimensions").GetFirstChild();
1139  if( !DimsNode.Empty() )
1140  this->ActDims.ProtoDeSerialize(DimsNode);
1141 
1142  XML::Node PositioningNode = PropertiesNode.GetChild("PositioningPolicy").GetFirstChild();
1143  if( !PositioningNode.Empty() )
1144  this->PositioningPolicy.ProtoDeSerialize(PositioningNode);
1145 
1146  XML::Node SizingNode = PropertiesNode.GetChild("SizingPolicy").GetFirstChild();
1147  if( !SizingNode.Empty() )
1148  this->SizingPolicy.ProtoDeSerialize(SizingNode);
1149  }else{
1150  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + (QuadRenderable::GetSerializableName() + "Properties") + ": Not Version 1.");
1151  }
1152  }else{
1153  MEZZ_EXCEPTION(Exception::II_IDENTITY_NOT_FOUND_EXCEPTION,QuadRenderable::GetSerializableName() + "Properties" + " was not found in the provided XML node, which was expected.");
1154  }
1155  }
1156 
1158  {
1160  this->DestroyAllRenderLayers();
1161  XML::Attribute CurrAttrib;
1162  XML::Node LayersNode = SelfRoot.GetChild( "RenderLayers" );
1163 
1164  if( !LayersNode.Empty() ) {
1165  if(LayersNode.GetAttribute("Version").AsInt() == 1) {
1166  for( XML::NodeIterator LayerNodeIt = LayersNode.begin() ; LayerNodeIt != LayersNode.end() ; ++LayerNodeIt )
1167  {
1168  RenderLayer* CurrLayer = NULL;
1169 
1170  if( (*LayerNodeIt).Name() == String("ImageLayer") ) {
1171  CurrLayer = new ImageLayer(this);
1172  CurrLayer->ProtoDeSerialize( (*LayerNodeIt) );
1173  this->ResizeLayers( CurrLayer->GetIndex() );
1174  this->RenderLayers[ CurrLayer->GetIndex() ] = CurrLayer;
1175  }else if( (*LayerNodeIt).Name() == String("SingleLineTextLayer") ) {
1176  CurrLayer = new SingleLineTextLayer(this);
1177  CurrLayer->ProtoDeSerialize( (*LayerNodeIt) );
1178  this->ResizeLayers( CurrLayer->GetIndex() );
1179  this->RenderLayers[ CurrLayer->GetIndex() ] = CurrLayer;
1180  }else if( (*LayerNodeIt).Name() == String("MultiLineTextLayer") ) {
1181  CurrLayer = new MultiLineTextLayer(this);
1182  CurrLayer->ProtoDeSerialize( (*LayerNodeIt) );
1183  this->ResizeLayers( CurrLayer->GetIndex() );
1184  this->RenderLayers[ CurrLayer->GetIndex() ] = CurrLayer;
1185  }else{
1186  MEZZ_EXCEPTION(Exception::II_IDENTITY_INVALID_EXCEPTION,"Unknown render layer name provided when deserializing.");
1187  }
1188  }
1189  }else{
1190  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for RenderLayers: Not Version 1.");
1191  }
1192  }
1193  }
1194 
1196  {
1198  XML::Attribute CurrAttrib;
1199  XML::Node GroupsNode = SelfRoot.GetChild( "RenderLayerGroups" );
1200 
1201  if( !GroupsNode.Empty() ) {
1202  if(GroupsNode.GetAttribute("Version").AsInt() == 1) {
1203  for( XML::NodeIterator GroupNodeIt = GroupsNode.begin() ; GroupNodeIt != GroupsNode.end() ; ++GroupNodeIt )
1204  {
1205  RenderLayerGroup* CurrGroup = NULL;
1206 
1207  CurrAttrib = (*GroupNodeIt).GetAttribute("Name");
1208  if( !CurrAttrib.Empty() )
1209  CurrGroup = this->CreateRenderLayerGroup( CurrAttrib.AsString() );
1210 
1211  if( CurrGroup ) {
1212  for( XML::NodeIterator LayerNodeIt = (*GroupNodeIt).begin() ; LayerNodeIt != (*GroupNodeIt).end() ; ++LayerNodeIt )
1213  {
1214  XML::Attribute IndexAttrib = (*LayerNodeIt).GetAttribute("Index");
1215  XML::Attribute ZOrderAttrib = (*LayerNodeIt).GetAttribute("ZOrder");
1216 
1217  if( IndexAttrib && ZOrderAttrib ) {
1218  CurrGroup->AddLayer( this->GetRenderLayer( IndexAttrib.AsWhole() ), ZOrderAttrib.AsWhole() );
1219  }else{
1220  MEZZ_EXCEPTION(Exception::II_IDENTITY_NOT_FOUND_EXCEPTION,"Index and/or ZOrder attributes were not found in the provided XML node, which was expected.");
1221  }
1222  }
1223  }
1224  }
1225  }else{
1226  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for RenderLayerGroups: Not Version 1.");
1227  }
1228  }
1229  }
1230 
1232  {
1233  XML::Node ChildrenNode = SelfRoot.GetChild( "Children" );
1234  if( !ChildrenNode.Empty() ) {
1235  if( ChildrenNode.GetAttribute("Version").AsInt() == 1 ) {
1236  for( XML::NodeIterator ChildNodeIt = ChildrenNode.begin() ; ChildNodeIt != ChildrenNode.end() ; ++ChildNodeIt )
1237  {
1238  this->AddChild( this->ParentScreen->CreateWidget( (*ChildNodeIt) ) );
1239  }
1240  }else{
1241  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for Children: Not Version 1.");
1242  }
1243  }
1244  }
1245 
1247  {
1249  }
1250 
1252  {
1253  return "QuadRenderable";
1254  }
1255 
1256  ///////////////////////////////////////////////////////////////////////////////
1257  // Internal Methods
1258 
1260  {
1261  this->ZOrder = Zorder;
1262  }
1263 
1265  {
1266  this->ParentQuad = NewParent;
1267  }
1268 
1270  {
1271  if( this->Dirty )
1272  return;
1273 
1274  this->Dirty = true;
1275  this->ParentQuad->_MarkDirty();
1276  }
1277 
1279  {
1280  this->_MarkDirty();
1281  for( ChildIterator It = this->ChildWidgets.begin() ; It != this->ChildWidgets.end() ; ++It )
1282  {
1283  (*It)->_MarkDirty();
1284  (*It)->_MarkAllChildrenDirty();
1285  }
1286  }
1287 
1289  {
1290  if( this->Dirty && this->AllLayersDirty )
1291  return;
1292 
1293  this->Dirty = true;
1294  this->AllLayersDirty = true;
1295  this->ParentQuad->_MarkDirty();
1296  }
1297 
1299  {
1300  if( this->GetVisible() ) {
1301  this->CleanLayers();
1302  switch(Priority)
1303  {
1304  case UI::RP_Low: this->AppendLayerVertices(RenderData.LowVertices); break;
1305  case UI::RP_Medium: this->AppendLayerVertices(RenderData.MediumVertices); break;
1306  case UI::RP_High: this->AppendLayerVertices(RenderData.HighVertices); break;
1307  }
1308  }
1309  }
1310 
1312  {
1313  if( this->VertexCache ) {
1314  if( this->Dirty || this->AllLayersDirty ) {
1315  this->VertexCache->Clear();
1317  for( ChildIterator ChildIt = this->ChildWidgets.begin() ; ChildIt != this->ChildWidgets.end() ; ++ChildIt )
1318  {
1319  if( (*ChildIt)->_HasAvailableRenderData() ) {
1320  (*ChildIt)->_AppendRenderDataCascading(*VertexCache);
1321  }
1322  }
1323  }
1324  RenderData.Append(*VertexCache);
1325  }else{
1326  this->_AppendRenderData(RenderData);
1327  for( ChildIterator It = this->ChildWidgets.begin() ; It != this->ChildWidgets.end() ; ++It )
1328  {
1329  if( (*It)->_HasAvailableRenderData() ) {
1330  (*It)->_AppendRenderDataCascading(RenderData);
1331  }
1332  }
1333  }
1334  }
1335 
1337  {
1338  return this->Visible;
1339  }
1340  }//UI
1341 }//Mezzanine
1342 
1343 #endif