MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
screen.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 _uiscreen_cpp
41 #define _uiscreen_cpp
42 
43 #include "UI/uimanager.h"
44 #include "UI/screen.h"
45 #include "UI/textureatlas.h"
46 #include "UI/mousehoverstrategy.h"
47 #include "UI/brutestrategy.h"
48 #include "UI/layoutstrategy.h"
49 
50 #include "UI/button.h"
51 #include "UI/checkbox.h"
52 #include "UI/dropdownlist.h"
53 #include "UI/editbox.h"
54 #include "UI/gridcontainer.h"
55 #include "UI/horizontalcontainer.h"
56 #include "UI/horizontalscrollbar.h"
57 #include "UI/linelist.h"
58 #include "UI/listbox.h"
59 #include "UI/menubutton.h"
60 #include "UI/menuentry.h"
61 #include "UI/radiobutton.h"
62 #include "UI/scrollbar.h"
63 #include "UI/spinner.h"
64 #include "UI/tabset.h"
65 #include "UI/verticalcontainer.h"
66 #include "UI/verticalscrollbar.h"
67 #include "UI/widget.h"
68 #include "UI/window.h"
69 
70 #include "Graphics/gamewindow.h"
71 #include "Graphics/viewport.h"
72 #include "Graphics/cameramanager.h"
73 #include "Graphics/cameraproxy.h"
74 #include "Graphics/graphicsmanager.h"
75 #include "Graphics/scenemanager.h"
76 
77 #include "mathtool.h"
78 #include "exception.h"
79 
80 #include <OgreRoot.h>
81 #include <OgreMatrix4.h>
82 #include <OgreRenderSystem.h>
83 #include <OgreRenderOperation.h>
84 #include <OgreHardwareBufferManager.h>
85 #include <OgreHardwareVertexBuffer.h>
86 #include <OgreRenderQueueListener.h>
87 
88 namespace Mezzanine
89 {
90  namespace UI
91  {
92  ///////////////////////////////////////////////////////////////////////////////
93  // Child Processing Functors
94 
95  ///////////////////////////////////////////////////////////////////////////////
96  /// @class VertexCollectFunctor
97  /// @headerfile screen.cpp
98  /// @brief Simple functor for appending all vertices in the renderable tree to a vector.
99  ///////////////////////////////////////
101  {
102  public:
103  ScreenRenderData* Data;
104 
105  VertexCollectFunctor(ScreenRenderData* pData) : Data(pData) {}
107 
108  bool operator()(QuadRenderable* Quad)
109  {
110  Quad->_AppendRenderData(*Data);
111  return false;
112  }
113  };//VertexCollectFunctor
114 
115  ///////////////////////////////////////////////////////////////////////////////
116  // OgreVertex
117 
118  ///////////////////////////////////////////////////////////////////////////////
119  /// @struct OgreVertex
120  /// @headerfile screen.cpp
121  /// @brief Simple class that facilitates conversions when inserting vertex's into the video buffer.
122  ///////////////////////////////////////
123  struct OgreVertex
124  {
125  Ogre::Vector3 Position;
126  Ogre::ColourValue Colour;
127  Ogre::Vector2 UV;
128  };
129 
130  ///////////////////////////////////////////////////////////////////////////////
131  // ScreenRenderData Methods
132 
134  {
135  LowVertices.clear();
136  MediumVertices.clear();
137  HighVertices.clear();
138  }
139 
141  {
142  return LowVertices.size() + MediumVertices.size() + HighVertices.size();
143  }
144 
146  {
147  this->LowVertices.insert(this->LowVertices.end(),OtherData.LowVertices.begin(),OtherData.LowVertices.end());
148  this->MediumVertices.insert(this->MediumVertices.end(),OtherData.MediumVertices.begin(),OtherData.MediumVertices.end());
149  this->HighVertices.insert(this->HighVertices.end(),OtherData.HighVertices.begin(),OtherData.HighVertices.end());
150  }
151 
153  {
154  if( Index < LowVertices.size() )
155  return LowVertices[Index];
156  else if( Index < LowVertices.size() + MediumVertices.size() )
157  return MediumVertices[Index - LowVertices.size()];
158  else if( Index < LowVertices.size() + MediumVertices.size() + HighVertices.size() )
159  return HighVertices[Index - (LowVertices.size() + MediumVertices.size())];
160  else
161  { MEZZ_EXCEPTION(Exception::MM_OUT_OF_BOUNDS_EXCEPTION,"Out of bounds index requested in ScreenRenderData"); }
162  }
163 
164  ///////////////////////////////////////////////////////////////////////////////
165  // ScreenInternalData Methods
166 
167  ///////////////////////////////////////////////////////////////////////////////
168  /// @struct ScreenInternalData
169  /// @headerfile screen.cpp
170  /// @brief Basic struct holding some of the internal bits of this class that could not be placed on the class directly.
171  ///////////////////////////////////////
172  struct ScreenInternalData : public Ogre::RenderQueueListener
173  {
174  Screen* ParentScreen;
175  Ogre::RenderOperation RenderOp;
176  Ogre::RenderSystem* RenderSys;
177  Ogre::HardwareVertexBufferSharedPtr VertexBuffer;
178 
179  void renderQueueStarted(Ogre::uint8, const Ogre::String&, bool&) { }
180  void renderQueueEnded(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation)
181  {
182  if( this->RenderSys->_getViewport() != this->ParentScreen->GetViewport()->GetOgreViewport() || queueGroupId != Ogre::RENDER_QUEUE_OVERLAY )
183  return;
184  if( this->ParentScreen->IsVisible() )
185  this->ParentScreen->_RenderScreen();
186  }
187  };//ScreenInternalData
188 
189  ///////////////////////////////////////////////////////////////////////////////
190  // Screen Methods
191 
192  Screen::Screen(const String& RendName, const String& Atlas, Graphics::Viewport* WindowViewport, UIManager* Manager) :
193  QuadRenderable(RendName,this),
194 
195  PrimaryAtlas(Atlas),
196  Scale(1,1,1),
197  MouseHitPosition(-1,-1),
198 
199  UIMan(Manager),
200  GameViewport(WindowViewport),
201  MouseStrat(NULL),
202 
203  Orientation(Mezzanine::OM_Degree_0)
204  {
206  /*this->ActDims.Size.X = (Real)this->GameViewport->GetActualWidth();
207  this->ActDims.Size.Y = (Real)this->GameViewport->GetActualHeight();
208  this->InverseSize.X = 1 / this->ActDims.Size.X;
209  this->InverseSize.Y = 1 / this->ActDims.Size.Y;//*/
210 
211  this->SID = new ScreenInternalData();
212  this->SID->RenderSys = Ogre::Root::getSingletonPtr()->getRenderSystem();
213  this->SID->ParentScreen = this;
214 
215  Graphics::SceneManager* SceneMan = this->GetSceneManager();
216  if(SceneMan)
217  SceneMan->_GetGraphicsWorldPointer()->addRenderQueueListener(SID);
218 
219  this->VertexTransform.SetTransform(Vector3(0,0,0),this->Scale,Quaternion(0,0,0,1));
220  this->CreateVertexBuffer(32 * 6);
221 
222  this->SetMousePassthrough(true);
224 
225  this->LayoutStrat = new LayoutStrategy();
226  }
227 
228  Screen::Screen(const XML::Node& XMLNode, UIManager* Manager) :
229  QuadRenderable(this),
230  Scale(1,1,1),
231  MouseHitPosition(-1,-1),
232  UIMan(Manager),
233  GameViewport(NULL),
234  MouseStrat(NULL),
235  Orientation(Mezzanine::OM_Degree_0)
236  {
238 
239  this->SID = new ScreenInternalData();
240  this->SID->RenderSys = Ogre::Root::getSingletonPtr()->getRenderSystem();
241  this->SID->ParentScreen = this;
242 
243  Graphics::SceneManager* SceneMan = this->GetSceneManager();
244  if(SceneMan)
245  SceneMan->_GetGraphicsWorldPointer()->addRenderQueueListener(SID);
246 
247  this->CreateVertexBuffer(32 * 6);
249 
250  this->LayoutStrat = new LayoutStrategy();
251 
252  this->ProtoDeSerialize(XMLNode);
253  }
254 
256  {
257  this->DestroyAllWidgets();
258  }
259 
261  {
262  /// @todo This function exists (as opposed to storing a pointer that doesn't change) so that if changes in the
263  /// viewport configuration occur this will pick up on that. However the render queue listener that is added in
264  /// this class' constructor never gets re-assigned. This needs to be fixed. Until then if a change does occur
265  /// the UI will be rendered at a different time then it needs to be, potentially overwritten by the scene render.
266  if( GameViewport ) {
268  if( Cam ) {
269  Graphics::SceneManager* SceneMan = static_cast<Graphics::CameraManager*>( Cam->GetCreator() )->GetScene();
270  if( SceneMan ) return SceneMan;
271  else return NULL;
272  }else return NULL;
273  }else return NULL;
274  }
275 
277  {
278  WidgetFactoryIterator WidFactIt = this->WidgetFactories.find( WidgetTypeName );
279  if( WidFactIt != this->WidgetFactories.end() ) {
280  return (*WidFactIt).second;
281  }else{
282  MEZZ_EXCEPTION(Exception::INVALID_STATE_EXCEPTION,"Attempting to create a " + WidgetTypeName + " Widget without it's factory registered.");
283  }
284  }
285 
287  {
288  String WidgetName = ToInsert->GetName();
289  std::pair<WidgetIterator,Boolean> InsertReturn = this->Widgets.insert( std::pair<String,Widget*>(WidgetName,ToInsert) );
290  if( !InsertReturn.second )
291  { MEZZ_EXCEPTION(Exception::II_DUPLICATE_IDENTITY_EXCEPTION,"Widget with name \"" + Name + "\" already exists."); }
292  return ToInsert;
293  }
294 
296  {
297  this->SID->RenderSys->_setWorldMatrix( Ogre::Matrix4::IDENTITY );
298  this->SID->RenderSys->_setProjectionMatrix( Ogre::Matrix4::IDENTITY );
299  this->SID->RenderSys->_setViewMatrix( Ogre::Matrix4::IDENTITY );
301  if(SceneMan)
302  SceneMan->_GetGraphicsWorldPointer()->_setPass( UIManager::GetSingletonPtr()->GetAtlas(PrimaryAtlas)->_Get2DPass() );
303  }
304 
305  void Screen::CreateVertexBuffer(const Whole& InitialSize)
306  {
307  this->SID->RenderOp.vertexData = OGRE_NEW Ogre::VertexData;
308  this->SID->RenderOp.vertexData->vertexStart = 0;
309 
310  Ogre::VertexDeclaration* VertexDecl = this->SID->RenderOp.vertexData->vertexDeclaration;
311  size_t Offset = 0;
312 
313  // Position.
314  VertexDecl->addElement(0,0,Ogre::VET_FLOAT3,Ogre::VES_POSITION);
315  Offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
316 
317  // Colour
318  VertexDecl->addElement(0,Offset,Ogre::VET_FLOAT4,Ogre::VES_DIFFUSE);
319  Offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT4);
320 
321  // Texture Coordinates
322  VertexDecl->addElement(0,Offset,Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
323 
324  this->SID->VertexBuffer = Ogre::HardwareBufferManager::getSingletonPtr()->createVertexBuffer(
325  VertexDecl->getVertexSize(0),
326  InitialSize,
327  Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
328  false);
329 
330  this->SID->RenderOp.vertexData->vertexBufferBinding->setBinding(0,this->SID->VertexBuffer);
331  this->SID->RenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
332  this->SID->RenderOp.useIndexes = false;
333  }
334 
336  {
337  OGRE_DELETE this->SID->RenderOp.vertexData;
338  this->SID->RenderOp.vertexData = 0;
339  this->SID->VertexBuffer.setNull();
340  }
341 
342  void Screen::ResizeVertexBuffer(const Whole& RequestedSize)
343  {
344  if( this->SID->VertexBuffer.isNull() )
345  this->CreateVertexBuffer(RequestedSize);
346 
347  if(RequestedSize > this->SID->VertexBuffer->getNumVertices() )
348  {
349  // Update only by powers of 2
350  Whole NewVertexBufferSize = 1;
351  while(NewVertexBufferSize < RequestedSize)
352  NewVertexBufferSize <<= 1;
353 
354  this->SID->VertexBuffer = Ogre::HardwareBufferManager::getSingletonPtr()->createVertexBuffer(
355  this->SID->RenderOp.vertexData->vertexDeclaration->getVertexSize(0),
356  NewVertexBufferSize,
357  Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
358  false);
359  this->SID->RenderOp.vertexData->vertexStart = 0;
360  this->SID->RenderOp.vertexData->vertexBufferBinding->setBinding(0,this->SID->VertexBuffer);
361  }
362  }
363 
364  ///////////////////////////////////////////////////////////////////////////////
365  // Utility and Visibility Methods
366 
367  void Screen::SetVisible(Boolean CanSee)
368  { this->Visible = CanSee; }
369 
370  Boolean Screen::GetVisible() const
371  { return this->Visible; }
372 
373  Boolean Screen::IsVisible() const
374  { return this->Visible; }
375 
377  { this->SetVisible(true); }
378 
380  { this->SetVisible(false); }
381 
383  { return Renderable::RT_Screen; }
384 
386  { return this->ActDims.Size; }
387 
389  {
390  Vector2 CurrentSize((Real)this->GameViewport->GetActualWidth(),(Real)this->GameViewport->GetActualHeight());
391  if( this->ActDims.Size != CurrentSize || ( this->InverseSize.X == 0.0 || this->InverseSize.Y == 0.0 ) ) {
392  Rect OldRect(this->ActDims);
393  Rect NewRect(Vector2(0,0),CurrentSize);
394  this->UpdateDimensions(OldRect,NewRect);
395 
396  this->InverseSize.X = 1.0 / this->ActDims.Size.X;
397  this->InverseSize.Y = 1.0 / this->ActDims.Size.Y;
398  }
399  }
400 
402  { return this->GameViewport; }
403 
405  { return this->UIMan; }
406 
407  ///////////////////////////////////////////////////////////////////////////////
408  // Mouse Hover Methods
409 
411  {
412  if(this->MouseStrat) {
413  delete this->MouseStrat;
414  this->MouseStrat = NULL;
415  }
416  this->MouseStrat = Strategy;
417  this->MouseStrat->_SetScreen(this);
418  }
419 
421  {
422  return this->MouseStrat;
423  }
424 
426  {
427  Widget* Ret = this->MouseStrat->FindHoveredWidget(MousePos);
428  if( Ret != NULL ) this->MouseHitPosition = MousePos;
429  else this->MouseHitPosition.SetValues(-1,-1);
430 
431  return Ret;
432  }
433 
435  {
436  return this->MouseHitPosition;
437  }
438 
439  ///////////////////////////////////////////////////////////////////////////////
440  // WidgetFactory Management
441 
443  {
444  this->WidgetFactories.insert( std::pair<String,WidgetFactory*>(ToBeAdded->GetWidgetTypeName(),ToBeAdded) );
445  }
446 
448  {
449  this->RemoveWidgetFactory( ToBeRemoved->GetWidgetTypeName() );
450  }
451 
452  void Screen::RemoveWidgetFactory(const String& ImplName)
453  {
454  WidgetFactoryIterator FactIt = this->WidgetFactories.find( ImplName );
455  if( FactIt != this->WidgetFactories.end() ) {
456  this->WidgetFactories.erase(FactIt);
457  }
458  }
459 
461  {
462  this->DestroyWidgetFactory( ToBeDestroyed->GetWidgetTypeName() );
463  }
464 
465  void Screen::DestroyWidgetFactory(const String& ImplName)
466  {
467  WidgetFactoryIterator FactIt = this->WidgetFactories.find( ImplName );
468  if( FactIt != this->WidgetFactories.end() ) {
469  delete (*FactIt).second;
470  this->WidgetFactories.erase(FactIt);
471  }
472  }
473 
475  {
476  for( WidgetFactoryIterator FactIt = this->WidgetFactories.begin() ; FactIt != this->WidgetFactories.end() ; ++FactIt )
477  {
478  delete (*FactIt).second;
479  }
480  this->WidgetFactories.clear();
481  }
482 
484  {
485  WidgetFactoryIterator FactIt;
486  // Generic Widget
487  FactIt = this->WidgetFactories.find( Widget::TypeName );
488  if( FactIt == this->WidgetFactories.end() ) this->AddWidgetFactory( new GenericWidgetFactory() );
489  // Button
490  FactIt = this->WidgetFactories.find( Button::TypeName );
491  if( FactIt == this->WidgetFactories.end() ) this->AddWidgetFactory( new ButtonFactory() );
492  // MenuButton
493  FactIt = this->WidgetFactories.find( MenuButton::TypeName );
494  if( FactIt == this->WidgetFactories.end() ) this->AddWidgetFactory( new MenuButtonFactory() );
495  // RadioButton
496  FactIt = this->WidgetFactories.find( RadioButton::TypeName );
497  if( FactIt == this->WidgetFactories.end() ) this->AddWidgetFactory( new RadioButtonFactory() );
498  // CheckBox
499  FactIt = this->WidgetFactories.find( CheckBox::TypeName );
500  if( FactIt == this->WidgetFactories.end() ) this->AddWidgetFactory( new CheckBoxFactory() );
501  // HorizontalScrollbar
502  FactIt = this->WidgetFactories.find( HorizontalScrollbar::TypeName );
503  if( FactIt == this->WidgetFactories.end() ) this->AddWidgetFactory( new HorizontalScrollbarFactory() );
504  // VerticalScrollbar
505  FactIt = this->WidgetFactories.find( VerticalScrollbar::TypeName );
506  if( FactIt == this->WidgetFactories.end() ) this->AddWidgetFactory( new VerticalScrollbarFactory() );
507 
508  // MenuEntry
509  FactIt = this->WidgetFactories.find( MenuEntry::TypeName );
510  if( FactIt == this->WidgetFactories.end() ) this->AddWidgetFactory( new MenuEntryFactory() );
511 
512  // HorizontalContainer
513  FactIt = this->WidgetFactories.find( HorizontalContainer::TypeName );
514  if( FactIt == this->WidgetFactories.end() ) this->AddWidgetFactory( new HorizontalContainerFactory() );
515  // VerticalContainer
516  FactIt = this->WidgetFactories.find( VerticalContainer::TypeName );
517  if( FactIt == this->WidgetFactories.end() ) this->AddWidgetFactory( new VerticalContainerFactory() );
518  }
519 
520  ///////////////////////////////////////////////////////////////////////////////
521  // Widget Management
522 
524  {
525  String WidgetTypeName = WidgetNode.Name();
526  WidgetFactoryIterator FactIt = this->WidgetFactories.find( WidgetTypeName );
527  if( FactIt != this->WidgetFactories.end() ) {
528  return this->CheckAndInsertExcept( (*FactIt).second->CreateWidget(WidgetNode,this) );
529  }else{
530  MEZZ_EXCEPTION(Exception::II_IDENTITY_INVALID_EXCEPTION,"Attempting to create widget of type \"" + WidgetTypeName + "\", which has no factory registered.");
531  }
532  }
533 
535  {
536  WidgetIterator WidIt = this->Widgets.find(Name);
537  if( WidIt != this->Widgets.end() ) return (*WidIt).second;
538  else return NULL;
539  }
540 
542  {
543  return this->Widgets.size();
544  }
545 
546  void Screen::DestroyWidget(Widget* ToBeDestroyed)
547  {
548  // Remove the widget from the Widget container.
549  WidgetIterator WidIt = this->Widgets.find( ToBeDestroyed->GetName() );
550  if( WidIt != this->Widgets.end() )
551  this->Widgets.erase(WidIt);
552 
553  // Delete the Widget
554  WidgetFactoryIterator FactIt = this->WidgetFactories.find( ToBeDestroyed->GetTypeName() );
555  if( FactIt != this->WidgetFactories.end() ) {
556  (*FactIt).second->DestroyWidget( ToBeDestroyed );
557  }
558  }
559 
561  {
562  for( ChildIterator ChildIt = this->ChildWidgets.begin() ; ChildIt != this->ChildWidgets.end() ; ++ChildIt )
563  {
564  WidgetFactoryIterator FactIt = this->WidgetFactories.find( (*ChildIt)->GetTypeName() );
565  if( FactIt != this->WidgetFactories.end() ) {
566  (*FactIt).second->DestroyWidget( (*ChildIt) );
567  }
568  }
569  this->RemoveAllChildren();
570  this->Widgets.clear();
571  }
572 
573  ///////////////////////////////////////////////////////////////////////////////
574  // Convenience Widget Creation Methods
575 
577  {
578  Widget* NewWidget = static_cast<GenericWidgetFactory*>( this->GetWidgetFactoryExcept( Widget::TypeName ) )->CreateWidget( Name, this );
579  this->CheckAndInsertExcept( NewWidget );
580  return NewWidget;
581  }
582 
583  Widget* Screen::CreateWidget(const String& Name, const UnifiedRect& RendRect)
584  {
585  Widget* NewWidget = static_cast<GenericWidgetFactory*>( this->GetWidgetFactoryExcept( Widget::TypeName ) )->CreateWidget( Name, RendRect, this );
586  this->CheckAndInsertExcept( NewWidget );
587  return NewWidget;
588  }
589 
591  {
592  Button* NewButton = static_cast<ButtonFactory*>( this->GetWidgetFactoryExcept( Button::TypeName ) )->CreateButton( Name, this );
593  this->CheckAndInsertExcept( NewButton );
594  return NewButton;
595  }
596 
597  Button* Screen::CreateButton(const String& Name, const UnifiedRect& RendRect)
598  {
599  Button* NewButton = static_cast<ButtonFactory*>( this->GetWidgetFactoryExcept( Button::TypeName ) )->CreateButton( Name, RendRect, this );
600  this->CheckAndInsertExcept( NewButton );
601  return NewButton;
602  }
603 
605  {
606  MenuButton* NewButton = static_cast<MenuButtonFactory*>( this->GetWidgetFactoryExcept( MenuButton::TypeName ) )->CreateMenuButton( Name, this );
607  this->CheckAndInsertExcept( NewButton );
608  return NewButton;
609  }
610 
611  MenuButton* Screen::CreateMenuButton(const String& Name, const UnifiedRect& RendRect)
612  {
613  MenuButton* NewButton = static_cast<MenuButtonFactory*>( this->GetWidgetFactoryExcept( MenuButton::TypeName ) )->CreateMenuButton( Name, RendRect, this );
614  this->CheckAndInsertExcept( NewButton );
615  return NewButton;
616  }
617 
619  {
620  RadioButton* NewButton = static_cast<RadioButtonFactory*>( this->GetWidgetFactoryExcept( RadioButton::TypeName ) )->CreateRadioButton( Name, this );
621  this->CheckAndInsertExcept( NewButton );
622  return NewButton;
623  }
624 
626  {
627  RadioButton* NewButton = static_cast<RadioButtonFactory*>( this->GetWidgetFactoryExcept( RadioButton::TypeName ) )->CreateRadioButton( Name, RendRect, this );
628  this->CheckAndInsertExcept( NewButton );
629  return NewButton;
630  }
631 
633  {
634  CheckBox* NewCheckBox = static_cast<CheckBoxFactory*>( this->GetWidgetFactoryExcept( CheckBox::TypeName ) )->CreateCheckBox( Name, this );
635  this->CheckAndInsertExcept( NewCheckBox );
636  return NewCheckBox;
637  }
638 
639  CheckBox* Screen::CreateCheckBox(const String& Name, const UnifiedRect& RendRect)
640  {
641  CheckBox* NewCheckBox = static_cast<CheckBoxFactory*>( this->GetWidgetFactoryExcept( CheckBox::TypeName ) )->CreateCheckBox( Name, RendRect, this );
642  this->CheckAndInsertExcept( NewCheckBox );
643  return NewCheckBox;
644  }
645 
647  {
649  this->CheckAndInsertExcept( NewHScroll );
650  return NewHScroll;
651  }
652 
654  {
655  HorizontalScrollbar* NewHScroll = static_cast<HorizontalScrollbarFactory*>( this->GetWidgetFactoryExcept( HorizontalScrollbar::TypeName ) )->CreateHorizontalScrollbar( Name, RendRect, Style, this );
656  this->CheckAndInsertExcept( NewHScroll );
657  return NewHScroll;
658  }
659 
661  {
663  this->CheckAndInsertExcept( NewVScroll );
664  return NewVScroll;
665  }
666 
668  {
669  VerticalScrollbar* NewVScroll = static_cast<VerticalScrollbarFactory*>( this->GetWidgetFactoryExcept( VerticalScrollbar::TypeName ) )->CreateVerticalScrollbar( Name, RendRect, Style, this );
670  this->CheckAndInsertExcept( NewVScroll );
671  return NewVScroll;
672  }
673 
675  {
676  MenuEntry* NewEntry = static_cast<MenuEntryFactory*>( this->GetWidgetFactoryExcept( MenuEntry::TypeName ) )->CreateMenuEntry( Name, this );
677  this->CheckAndInsertExcept( NewEntry );
678  return NewEntry;
679  }
680 
681  MenuEntry* Screen::CreateMenuEntry(const String& Name, const UnifiedRect& RendRect)
682  {
683  MenuEntry* NewEntry = static_cast<MenuEntryFactory*>( this->GetWidgetFactoryExcept( MenuEntry::TypeName ) )->CreateMenuEntry( Name, RendRect, this );
684  this->CheckAndInsertExcept( NewEntry );
685  return NewEntry;
686  }
687 
689  {
691  this->CheckAndInsertExcept( NewHContain );
692  return NewHContain;
693  }
694 
696  {
698  this->CheckAndInsertExcept( NewHContain );
699  return NewHContain;
700  }
701 
703  {
705  this->CheckAndInsertExcept( NewVContain );
706  return NewVContain;
707  }
708 
710  {
712  this->CheckAndInsertExcept( NewVContain );
713  return NewVContain;
714  }
715 
716 
717  /*ListBox* Screen::CreateListBox(ConstString& Name, const Rect& RendRect, const UI::ScrollbarStyle& ScrollStyle)
718  {
719  return static_cast<ListBox*>( this->CheckAndInsert( RenderableFactory::CreateListBox(Name,RendRect,ScrollStyle) ) );
720  }
721 
722  Spinner* Screen::CreateSpinner(ConstString& Name, const Rect& RendRect, const UI::SpinnerStyle& SStyle, const Real& GlyphHeight)
723  {
724  return static_cast<Spinner*>( this->CheckAndInsert( RenderableFactory::CreateSpinner(Name,RendRect,SStyle,GlyphHeight) ) );
725  }
726 
727  ScrolledCellGrid* Screen::CreateScrolledCellGrid(ConstString& Name, const Rect& RendRect, const Real& Thickness, const UI::ScrollbarStyle& Style)
728  {
729  return static_cast<ScrolledCellGrid*>( this->CheckAndInsert( RenderableFactory::CreateScrolledCellGrid(Name,RendRect,Thickness,Style) ) );
730  }
731 
732  PagedCellGrid* Screen::CreatePagedCellGrid(ConstString& Name, const Rect& RendRect, const Rect& SpnRect, const UI::SpinnerStyle& SStyle, const Real& GlyphHeight)
733  {
734  return static_cast<PagedCellGrid*>( this->CheckAndInsert( RenderableFactory::CreatePagedCellGrid(Name,RendRect,SpnRect,SStyle,GlyphHeight) ) );
735  }
736 
737  DropDownList* Screen::CreateDropDownList(ConstString& Name, const Rect& RendRect, const Real& LineHeight, const UI::ScrollbarStyle& ScrollStyle)
738  {
739  return static_cast<DropDownList*>( this->CheckAndInsert( RenderableFactory::CreateDropDownList(Name,RendRect,LineHeight,ScrollStyle) ) );
740  }
741 
742  TabSet* Screen::CreateTabSet(ConstString& Name, const Rect& SetRect)
743  {
744  return static_cast<TabSet*>( this->CheckAndInsert( RenderableFactory::CreateTabSet(Name,SetRect) ) );
745  }
746 
747  Window* Screen::CreateWidgetWindow(ConstString& Name, const Rect& RendRect)
748  {
749  return static_cast<Window*>( this->CheckAndInsert( ExtendedRenderableFactory::CreateWidgetWindow(Name,RendRect) ) );
750  }//*/
751 
752  ///////////////////////////////////////////////////////////////////////////////
753  // Atlas Query
754 
755  void Screen::SetPrimaryAtlas(const String& Atlas)
756  { this->PrimaryAtlas = Atlas; }
757 
759  { return this->PrimaryAtlas; }
760 
762  { return this->GetAtlas(Atlas)->GetWhitePixel(); }
763 
764  Sprite* Screen::GetSprite(const String& SpriteName,const String& Atlas) const
765  { return this->GetAtlas(Atlas)->GetSprite(SpriteName); }
766 
767  FontData* Screen::GetFont(const String& FontName,const String& Atlas) const
768  { return this->GetAtlas(Atlas)->GetFont(FontName); }
769 
771  { return this->GetAtlas(Atlas)->GetTextureSize(); }
772 
773  TextureAtlas* Screen::GetAtlas(const String& Atlas) const
774  { return this->UIMan->GetAtlas(Atlas); }
775 
777  { return this->SID->RenderSys->getHorizontalTexelOffset(); }
778 
780  { return this->SID->RenderSys->getVerticalTexelOffset(); }
781 
782  ///////////////////////////////////////////////////////////////////////////////
783  // Other Query
784 
785  bool Screen::IsMarkupParserRegistered(const String& ParserName) const
786  { return this->UIMan->IsMarkupParserRegistered(ParserName); }
787 
788  MarkupParser* Screen::GetMarkupParser(const String& ParserName) const
789  { return this->UIMan->GetMarkupParser(ParserName); }
790 
791  ///////////////////////////////////////////////////////////////////////////////
792  // Serialization
793 
795  {
797  XML::Node PropertiesNode = SelfRoot.AppendChild( Screen::GetSerializableName() + "Properties" );
798 
799  if( PropertiesNode.AppendAttribute("Version").SetValue("1") &&
800  PropertiesNode.AppendAttribute("WindowTitle").SetValue( this->GameViewport->GetParentWindow()->GetWindowCaption() ) &&
801  PropertiesNode.AppendAttribute("ViewportZOrder").SetValue( this->GameViewport->GetZOrder() ) &&
802  PropertiesNode.AppendAttribute("PriAtlas").SetValue( this->PrimaryAtlas ) )
803  {
804  XML::Node VertexTransformNode = PropertiesNode.AppendChild("VertexTransform");
805  this->VertexTransform.ProtoSerialize( VertexTransformNode );
806  XML::Node ScaleNode = PropertiesNode.AppendChild("Scale");
807  this->Scale.ProtoSerialize( ScaleNode );
808 
809  return;
810  }else{
811  SerializeError("Create XML Attribute Values",Screen::GetSerializableName() + "Properties",true);
812  }
813  }
814 
816  {
818 
819  XML::Attribute CurrAttrib;
820  XML::Node PropertiesNode = SelfRoot.GetChild( Screen::GetSerializableName() + "Properties" );
821 
822  if( !PropertiesNode.Empty() ) {
823  if(PropertiesNode.GetAttribute("Version").AsInt() == 1) {
824  String WindowTitle;
825  Whole ViewZOrder = 0;
826 
827  // Get the single data type properties
828  CurrAttrib = PropertiesNode.GetAttribute("PriAtlas");
829  if( !CurrAttrib.Empty() )
830  this->PrimaryAtlas = CurrAttrib.AsString();
831 
832  CurrAttrib = PropertiesNode.GetAttribute("WindowTitle");
833  if( !CurrAttrib.Empty() )
834  WindowTitle = CurrAttrib.AsString();
835 
836  CurrAttrib = PropertiesNode.GetAttribute("ViewportZOrder");
837  if( !CurrAttrib.Empty() )
838  ViewZOrder = CurrAttrib.AsWhole();
839 
840  // Get the properties that need their own nodes
841  XML::Node VertexTransformNode = PropertiesNode.GetChild("VertexTransform").GetFirstChild();
842  if( !VertexTransformNode.Empty() )
843  this->VertexTransform.ProtoDeSerialize(VertexTransformNode);
844 
845  XML::Node ScaleNode = PropertiesNode.GetChild("Scale").GetFirstChild();
846  if( !ScaleNode.Empty() )
847  this->Scale.ProtoDeSerialize(ScaleNode);
848 
849  if( !WindowTitle.empty() ) {
851  Graphics::GameWindow* NamedWindow = GraphicsMan->GetGameWindow(WindowTitle);
852  if( NamedWindow != NULL ) {
853  this->GameViewport = NamedWindow->GetViewportByZOrder(ViewZOrder);
854  if( this->GameViewport != NULL ) {
855  this->ActDims.Size.X = (Real)this->GameViewport->GetActualWidth();
856  this->ActDims.Size.Y = (Real)this->GameViewport->GetActualHeight();
857  this->InverseSize.X = 1 / this->ActDims.Size.X;
858  this->InverseSize.Y = 1 / this->ActDims.Size.Y;
859  }else{
860  MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"The Viewport specified via ZOrder was not found in the named GameWindow.");
861  }
862  }else{
863  MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"The named GameWindow to be used by UI Screen was not found.");
864  }
865  }else{
866  MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"A GameWindow Title/Caption was not specified for UI Screen.");
867  }
868  }else{
869  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + (Screen::GetSerializableName() + "Properties") + ": Not Version 1.");
870  }
871  }else{
872  MEZZ_EXCEPTION(Exception::II_IDENTITY_NOT_FOUND_EXCEPTION,Screen::GetSerializableName() + "Properties" + " was not found in the provided XML node, which was expected.");
873  }
874  }
875 
877  { return Screen::GetSerializableName(); }
878 
880  { return "Screen"; }
881 
882  ///////////////////////////////////////////////////////////////////////////////
883  // Internal Functions
884 
886  {
887  this->Dirty = true;
889  }
890 
892  {
893  if( this->Dirty && this->AllLayersDirty )
894  return;
895 
896  this->Dirty = true;
897  this->AllLayersDirty = true;
898  }
899 
901  {
902  Boolean Force = false;
903  if(Orientation != this->GameViewport->GetOrientationMode() ) {
905  if(this->Orientation == Mezzanine::OM_Degree_90)
907  else if(this->Orientation == Mezzanine::OM_Degree_180)
909  else if(this->Orientation == Mezzanine::OM_Degree_270)
911  else
913  Force = true;
914  }
915  this->CheckViewportSize();
916  this->_RenderVertices(Force);
917  size_t KnownVertexCount = this->SID->RenderOp.vertexData->vertexCount;
918  if(this->SID->RenderOp.vertexData->vertexCount) {
919  if(this->TextureByVertex.size() == 0) {
920  AtlasAndPosition MyObject;
921  MyObject.RenderStart = 0;
922  MyObject.RenderEnd = KnownVertexCount;
923  MyObject.Atlas = this->PrimaryAtlas;
924  this->TextureByVertex.push_back(MyObject);
925  }
926  this->PrepareRenderSystem();
927  String CurrAtlas = this->PrimaryAtlas;
928  for( int i = 0 ; i < this->TextureByVertex.size() ; i++ )
929  {
930  String& CurrVertAtlas = this->TextureByVertex[i].Atlas;
931  if(CurrVertAtlas.empty()) {
932  CurrVertAtlas = this->PrimaryAtlas;
933  }
934  if(CurrVertAtlas != CurrAtlas) {
935  CurrAtlas = CurrVertAtlas;
936  Ogre::TexturePtr TextureUse = this->UIMan->GetAtlas(CurrAtlas)->_GetTexture();
937  this->SID->RenderSys->_setTexture(0,true,TextureUse);
938  }
939  this->SID->RenderOp.vertexData->vertexCount = this->TextureByVertex[i].RenderEnd - TextureByVertex[i].RenderStart;
940  this->SID->RenderOp.vertexData->vertexStart = this->TextureByVertex[i].RenderStart;
941  this->SID->RenderSys->_render(this->SID->RenderOp);
942  }
943  }
944  }
945 
947  {
948  this->Orientation = Mode;
949  if( this->Orientation == Mezzanine::OM_Degree_90 || this->Orientation == Mezzanine::OM_Degree_270 ) {
950  std::swap(this->ActDims.Size.X,this->ActDims.Size.Y);
951  std::swap(this->InverseSize.X,this->InverseSize.Y);
952  }
953  }
954 
955  void Screen::_Transform(ScreenRenderData& RenderData, const Whole& Begin, const Whole& End)
956  {
957  static const Matrix4x4 Iden;
958  Whole X;
959  if( Begin != End ) {
960  for( X = Begin ; X < End ; X++ )
961  {
962  RenderData[X].Vert.Position.X = ( ( RenderData[X].Vert.Position.X * this->InverseSize.X ) * 2 ) - 1;
963  RenderData[X].Vert.Position.Y = ( ( RenderData[X].Vert.Position.Y * this->InverseSize.Y ) * -2 ) + 1;
964  }
965  }
966  if( this->VertexTransform != Iden ) {
967  for( X = Begin ; X < End ; X++ )
968  RenderData[X].Vert.Position = this->VertexTransform * RenderData[X].Vert.Position;
969  }
970  }
971 
972  void Screen::_RenderVertices(bool Force)
973  {
974  if( !this->Dirty )
975  return;
976 
977  Whole KnownVertexCount = 0;
978  //Whole PreviousTally = 0;
979  String CurrentName = this->PrimaryAtlas;
980  AtlasAndPosition MyObject(this->PrimaryAtlas);
981  this->TextureByVertex.clear();
982 
983  ScreenRenderData TempVertexCache;
984  this->_AppendRenderDataCascading(TempVertexCache);
985  KnownVertexCount = TempVertexCache.Size();
986  this->_Transform(TempVertexCache,0,KnownVertexCount);
987 
988  this->ResizeVertexBuffer(KnownVertexCount);
989  //OgreVertex* WriteIterator = (OgreVertex*) this->SID->VertexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
990  Vertex* WriteIterator = (Vertex*) this->SID->VertexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
991  for( Whole Index = 0 ; Index < TempVertexCache.Size() ; ++Index )
992  {
993  if( TempVertexCache[Index].Atlas.empty() ) {
994  MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"Null or Empty String Atlas found when rendering UI.");
995  }
996  if( TempVertexCache[Index].Atlas != CurrentName ) {
997  if( Index != 0 ) {
998  MyObject.RenderEnd = Index;
999  this->TextureByVertex.push_back(MyObject);
1000  }
1001  MyObject.Atlas = TempVertexCache[Index].Atlas;
1002  MyObject.RenderStart = Index;
1003  CurrentName = TempVertexCache[Index].Atlas;
1004  }
1005 
1006  /*OgreVertex NewVertex;
1007  NewVertex.Position = TempVertexCache[Index].Vert.Position.GetOgreVector3();
1008  NewVertex.Colour = TempVertexCache[Index].Vert.Colour.GetOgreColourValue();
1009  NewVertex.UV = TempVertexCache[Index].Vert.UV.GetOgreVector2();
1010  *WriteIterator++ = NewVertex;// */
1011  const Vertex& NewVertex = TempVertexCache[Index].Vert;
1012  *WriteIterator++ = NewVertex;
1013  }
1014  MyObject.RenderEnd = KnownVertexCount;
1015  MyObject.Atlas = CurrentName;
1016  this->TextureByVertex.push_back(MyObject);
1017 
1018  this->SID->VertexBuffer->unlock();
1019  this->SID->RenderOp.vertexData->vertexCount = KnownVertexCount;
1020 
1021  this->Dirty = false;
1022  }
1023  }//UI
1024 }//Mezzanine
1025 
1026 #endif