Spinning Topp Logo BlackTopp Studios
inc
imagelayer.cpp
1 // © Copyright 2010 - 2016 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 _uiimagelayer_cpp
41 #define _uiimagelayer_cpp
42 
43 #include "UI/imagelayer.h"
44 #include "UI/quadrenderable.h"
45 #include "UI/screen.h"
46 
47 namespace Mezzanine
48 {
49  namespace UI
50  {
52  RenderLayer(ParentRenderable),
53  BorderWidth(0)
54  {
55  this->BorderColours[0] = ColourValue::Black();
56  this->BorderColours[1] = ColourValue::Black();
57  this->BorderColours[2] = ColourValue::Black();
58  this->BorderColours[3] = ColourValue::Black();
59  }
60 
62  { }
63 
64  void ImageLayer::DrawBorder(const Vector2* InnerRect, const Vector2* OuterRect)
65  {
67 
68  // North
69  if( 0 != this->BorderColours[UI::Border_North].AlphaChannel ) {
70  this->PushTriangle( InnerRect[UI::QC_TopLeft], OuterRect[UI::QC_TopRight], OuterRect[UI::QC_TopLeft], WP, this->BorderColours[UI::Border_North], this->PriAtlas );
71  this->PushTriangle( InnerRect[UI::QC_TopLeft], InnerRect[UI::QC_TopRight], OuterRect[UI::QC_TopRight], WP, this->BorderColours[UI::Border_North], this->PriAtlas );
72  }
73  // East
74  if( 0 != this->BorderColours[UI::Border_East].AlphaChannel ) {
75  this->PushTriangle( InnerRect[UI::QC_BottomRight], OuterRect[UI::QC_TopRight], InnerRect[UI::QC_TopRight], WP, this->BorderColours[UI::Border_East], this->PriAtlas );
76  this->PushTriangle( InnerRect[UI::QC_BottomRight], OuterRect[UI::QC_BottomRight], OuterRect[UI::QC_TopRight], WP, this->BorderColours[UI::Border_East], this->PriAtlas );
77  }
78  // South
79  if( 0 != this->BorderColours[UI::Border_South].AlphaChannel ) {
80  this->PushTriangle( OuterRect[UI::QC_BottomLeft], InnerRect[UI::QC_BottomRight], InnerRect[UI::QC_BottomLeft], WP, this->BorderColours[UI::Border_South], this->PriAtlas );
81  this->PushTriangle( OuterRect[UI::QC_BottomLeft], OuterRect[UI::QC_BottomRight], InnerRect[UI::QC_BottomRight], WP, this->BorderColours[UI::Border_South], this->PriAtlas );
82  }
83  // West
84  if( 0 != this->BorderColours[UI::Border_West].AlphaChannel ) {
85  this->PushTriangle( OuterRect[UI::QC_BottomLeft], InnerRect[UI::QC_TopLeft], OuterRect[UI::QC_TopLeft], WP, BorderColours[UI::Border_West], this->PriAtlas );
86  this->PushTriangle( OuterRect[UI::QC_BottomLeft], InnerRect[UI::QC_BottomLeft], InnerRect[UI::QC_TopLeft], WP, BorderColours[UI::Border_West], this->PriAtlas );
87  }
88  }
89 
90  void ImageLayer::DrawFill(const Vector2* FillRect, const Sprite* FillSprite, const ColourValue* FillColours)
91  {
92  Vector2 UVs[4];
93  if( FillSprite == NULL ) {
94  UVs[UI::QC_TopLeft] = UVs[UI::QC_TopRight] = UVs[UI::QC_BottomRight] = UVs[UI::QC_BottomLeft] = this->Parent->GetScreen()->GetWhitePixel(this->PriAtlas);
95  }else{
96  UVs[UI::QC_TopLeft] = FillSprite->GetRelativeAtlasCoords(UI::QC_TopLeft);
97  UVs[UI::QC_TopRight] = FillSprite->GetRelativeAtlasCoords(UI::QC_TopRight);
98  UVs[UI::QC_BottomRight] = FillSprite->GetRelativeAtlasCoords(UI::QC_BottomRight);
99  UVs[UI::QC_BottomLeft] = FillSprite->GetRelativeAtlasCoords(UI::QC_BottomLeft);
100  }
101 
102  // Triangle A
103  this->PushVertex( FillRect[UI::QC_BottomLeft].X, FillRect[UI::QC_BottomLeft].Y, UVs[UI::QC_BottomLeft], FillColours[UI::QC_BottomLeft], this->PriAtlas ); // Left/Bottom 3
104  this->PushVertex( FillRect[UI::QC_TopRight].X, FillRect[UI::QC_TopRight].Y, UVs[UI::QC_TopRight], FillColours[UI::QC_TopRight], this->PriAtlas ); // Right/Top 1
105  this->PushVertex( FillRect[UI::QC_TopLeft].X, FillRect[UI::QC_TopLeft].Y, UVs[UI::QC_TopLeft], FillColours[UI::QC_TopLeft], this->PriAtlas ); // Left/Top 0
106 
107  // Triangle B
108  this->PushVertex( FillRect[UI::QC_BottomLeft].X, FillRect[UI::QC_BottomLeft].Y, UVs[UI::QC_BottomLeft], FillColours[UI::QC_BottomLeft], this->PriAtlas ); // Left/Bottom 3
109  this->PushVertex( FillRect[UI::QC_BottomRight].X, FillRect[UI::QC_BottomRight].Y, UVs[UI::QC_BottomRight], FillColours[UI::QC_BottomRight], this->PriAtlas ); // Right/Bottom 2
110  this->PushVertex( FillRect[UI::QC_TopRight].X, FillRect[UI::QC_TopRight].Y, UVs[UI::QC_TopRight], FillColours[UI::QC_TopRight], this->PriAtlas ); // Right/Top 1
111  }
112 
113  ///////////////////////////////////////////////////////////////////////////////
114  // Border Methods
115 
117  {
118  this->BorderWidth = Width;
119  this->_MarkDirty();
120  }
121 
123  {
124  this->BorderColours[0] = Colour;
125  this->BorderColours[1] = Colour;
126  this->BorderColours[2] = Colour;
127  this->BorderColours[3] = Colour;
128  this->_MarkDirty();
129  }
130 
131  void ImageLayer::SetBorderColour(const UI::Border Side, const ColourValue& Colour)
132  {
133  this->BorderColours[Side] = Colour;
134  this->_MarkDirty();
135  }
136 
137  void ImageLayer::SetBorder(const Real Width, const ColourValue& Colour)
138  {
139  this->SetBorderWidth(Width);
140  this->SetBorderColour(Colour);
141  }
142 
143  void ImageLayer::SetBorder(const Real Width, const ColourValue& North, const ColourValue& South, const ColourValue& East, const ColourValue& West)
144  {
145  this->SetBorderWidth(Width);
146  this->BorderColours[UI::Border_North] = North;
147  this->BorderColours[UI::Border_South] = South;
148  this->BorderColours[UI::Border_East] = East;
149  this->BorderColours[UI::Border_West] = West;
150  }
151 
153  {
154  this->SetBorderWidth(0.0);
156  }
157 
159  {
160  return this->BorderWidth;
161  }
162 
164  {
165  return this->BorderColours[Side];
166  }
167 
168  ///////////////////////////////////////////////////////////////////////////////
169  // Serialization
170 
172  {
174  XML::Node PropertiesNode = SelfRoot.AppendChild( ImageLayer::GetSerializableName() + "Properties" );
175 
176  if( PropertiesNode.AppendAttribute("Version").SetValue("1") &&
177  PropertiesNode.AppendAttribute("BorderWidth").SetValue(this->BorderWidth) )
178  {
179  XML::Node BorderColoursNode = PropertiesNode.AppendChild("BorderColours");
180 
181  XML::Node TopLeftBorderNode = BorderColoursNode.AppendChild("TopLeft");
182  this->BorderColours[UI::QC_TopLeft].ProtoSerialize(TopLeftBorderNode);
183 
184  XML::Node TopRightBorderNode = BorderColoursNode.AppendChild("TopRight");
185  this->BorderColours[UI::QC_TopRight].ProtoSerialize(TopRightBorderNode);
186 
187  XML::Node BottomLeftBorderNode = BorderColoursNode.AppendChild("BottomLeft");
188  this->BorderColours[UI::QC_BottomLeft].ProtoSerialize(BottomLeftBorderNode);
189 
190  XML::Node BottomRightBorderNode = BorderColoursNode.AppendChild("BottomRight");
191  this->BorderColours[UI::QC_BottomRight].ProtoSerialize(BottomRightBorderNode);
192 
193  return;
194  }else{
195  SerializeError("Create XML Attribute Values",ImageLayer::GetSerializableName() + "Properties",true);
196  }
197  }
198 
200  {
202  XML::Attribute CurrAttrib;
203  XML::Node PropertiesNode = SelfRoot.GetChild( ImageLayer::GetSerializableName() + "Properties" );
204 
205  if( !PropertiesNode.Empty() ) {
206  if(PropertiesNode.GetAttribute("Version").AsInt() == 1) {
207  CurrAttrib = PropertiesNode.GetAttribute("BorderWidth");
208  if( !CurrAttrib.Empty() )
209  this->BorderWidth = CurrAttrib.AsReal();
210 
211  XML::Node BorderColoursNode = PropertiesNode.GetChild("BorderColours");
212  XML::Node TopLeftBorderNode = PropertiesNode.GetChild("TopLeft").GetFirstChild();
213  if( !TopLeftBorderNode.Empty() )
214  this->BorderColours[UI::QC_TopLeft].ProtoDeSerialize(TopLeftBorderNode);
215 
216  XML::Node TopRightBorderNode = PropertiesNode.GetChild("TopRight").GetFirstChild();
217  if( !TopRightBorderNode.Empty() )
218  this->BorderColours[UI::QC_TopRight].ProtoDeSerialize(TopRightBorderNode);
219 
220  XML::Node BottomLeftBorderNode = PropertiesNode.GetChild("BottomLeft").GetFirstChild();
221  if( !BottomLeftBorderNode.Empty() )
222  this->BorderColours[UI::QC_BottomLeft].ProtoDeSerialize(BottomLeftBorderNode);
223 
224  XML::Node BottomRightBorderNode = PropertiesNode.GetChild("BottomRight").GetFirstChild();
225  if( !BottomRightBorderNode.Empty() )
226  this->BorderColours[UI::QC_BottomRight].ProtoDeSerialize(BottomRightBorderNode);
227  }else{
228  MEZZ_EXCEPTION(ExceptionBase::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + (ImageLayer::GetSerializableName() + "Properties") + ": Not Version 1.");
229  }
230  }else{
231  MEZZ_EXCEPTION(ExceptionBase::II_IDENTITY_NOT_FOUND_EXCEPTION,ImageLayer::GetSerializableName() + "Properties" + " was not found in the provided XML node, which was expected.");
232  }
233  }
234 
236  { return ImageLayer::GetSerializableName(); }
237 
239  { return "ImageLayer"; }
240  }//UI
241 }//Mezzanine
242 
243 #endif
virtual void ProtoDeSerializeProperties(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite the properties of this object with it...
virtual void ProtoSerializeProperties(XML::Node &SelfRoot) const
Convert the properties of this class to an XML::Node ready for serialization.
Definition: imagelayer.cpp:171
Attribute AppendAttribute(const Char8 *Name)
Creates an Attribute and puts it at the end of this Nodes attributes.
virtual void ProtoDeSerialize(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite this object with it.
A light-weight handle for manipulating attributes in DOM tree.
Definition: attribute.h:74
virtual void SetBorderColour(const ColourValue &Colour)
Sets the colour of the border for this renderable.
Definition: imagelayer.cpp:122
virtual void PushTriangle(const Vector2 &A, const Vector2 &B, const Vector2 &C, const Vector2 &UV, const ColourValue &Colour, const String &Atlas)
Pushes vertex information for a triangle to a vector. Equivalent to calling "PushVertex" three times...
Thrown when the requested identity could not be found.
Definition: exception.h:94
Node GetFirstChild() const
Get the first child Node of this Node.
#define MEZZ_EXCEPTION(num, desc)
An easy way to throw exceptions with rich information.
Definition: exception.h:3048
QuadRenderable * Parent
A pointer to the parent of this RenderLayer.
Definition: renderlayer.h:67
virtual void ProtoSerializeProperties(XML::Node &SelfRoot) const
Convert the properties of this class to an XML::Node ready for serialization.
String PriAtlas
This contains the name of the atlas that will be used as default when one isn't specified.
static String GetSerializableName()
Get the name of the the XML tag the Renderable class will leave behind as its instances are serialize...
Definition: imagelayer.cpp:238
Thrown when a version is accessed/parsed/required and it cannot work correctly or is missing...
Definition: exception.h:112
Screen * GetScreen() const
Gets the parent screen of this renderable.
Definition: renderable.cpp:80
static ColourValue Black()
Creates a ColourValue representing the colour Black.
This is a simple class for holding 4 reals representing the colour any give object or lightsource can...
Definition: colourvalue.h:64
virtual String GetDerivedSerializableName() const
Gets the most derived serializable name of this Renderable.
Definition: imagelayer.cpp:235
virtual void _MarkDirty()
Marks this renderable as well as all parent objects as dirty.
bool Empty() const
Is this storing anything at all?
virtual void NoBorder()
Disables any border set on this renderable if one is currently set.
Definition: imagelayer.cpp:152
float Real
A Datatype used to represent a real floating point number.
Definition: datatypes.h:141
bool SetValue(const Char8 *rhs)
Set the value of this.
Vector2 GetWhitePixel(const String &Atlas) const
Gets the position of the white pixel from an Atlas.
Definition: screen.cpp:883
void DrawFill(const Vector2 *FillRect, const Sprite *FillSprite, const ColourValue *FillColours)
Draws the main rectangle.
Definition: imagelayer.cpp:90
A light-weight handle for manipulating nodes in DOM tree.
Definition: node.h:89
int AsInt(int def=0) const
Attempts to convert the value of the attribute to an int and returns the results. ...
This is used to represent a point on a 2 dimentional area, such as a screen.
Definition: vector2.h:63
bool Empty() const
Is this storing anything at all?
void DrawBorder(const Vector2 *InnerRect, const Vector2 *OuterRect)
Draws the border, if any is set.
Definition: imagelayer.cpp:64
virtual ~ImageLayer()
Class destructor.
Definition: imagelayer.cpp:61
Real AsReal(Real def=0) const
Attempts to convert the value of the attribute to a Real and returns the results. ...
virtual void SetBorder(const Real Width, const ColourValue &Colour)
Sets all parameters for enabling a border.
Definition: imagelayer.cpp:137
virtual Real GetBorderWidth() const
Gets the border width of this renderable.
Definition: imagelayer.cpp:158
virtual void ProtoDeSerializeProperties(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite the properties of this object with it...
Definition: imagelayer.cpp:199
Vector2 GetRelativeAtlasCoords(const UI::QuadCorner Corner) const
Gets the relative position on the Atlas of a corner belonging to this Sprite.
Definition: sprite.h:153
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
Real BorderWidth
The width of the border to render around this layer in pixels.
Definition: imagelayer.h:63
virtual const ColourValue & GetBorderColour(const UI::Border Side) const
Gets the colour of a border on this renderable.
Definition: imagelayer.cpp:163
void ProtoSerialize(XML::Node &CurrentRoot) const
Convert this class to an XML::Node ready for serialization.
ColourValue BorderColours[4]
An array of colours to be used for each corner section of the border being rendered with this layer...
Definition: imagelayer.h:60
virtual void SetBorderWidth(const Real Width)
Sets the width of the border for this renderable.
Definition: imagelayer.cpp:116
This represents a nestable quad for an object in a GUI layout.
void SerializeError(const String &FailedTo, const String &ClassName, Boole SOrD)
Simply does some string concatenation, then throws an Exception.
Node AppendChild(NodeType Type=NodeElement)
Creates a Node and makes it a child of this one.
Border
Used by various basic renderables for border effects.
Basic class used to describe a portion of a texture to be applied to a Quad.
Definition: sprite.h:55
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159
ImageLayer(QuadRenderable *ParentRenderable)
Class constructor.
Definition: imagelayer.cpp:51
Attribute GetAttribute(const Char8 *Name) const
Attempt to get an Attribute on this Node with a given name.
virtual void PushVertex(const Real &X, const Real &Y, const Vector2 &UV, const ColourValue &Colour, const String &Atlas)
Collects all the relevant information for a single vertex and pushes it to a vector.
This is the base class for the types of layers that can be added to a renderable. ...
Definition: renderlayer.h:58
Node GetChild(const Char8 *Name) const
Attempt to get a child Node with a given name.