Spinning Topp Logo BlackTopp Studios
inc
singleimagelayer.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 
41 #ifndef _uisingleimagelayer_cpp
42 #define _uisingleimagelayer_cpp
43 
44 #include "UI/singleimagelayer.h"
45 #include "UI/quadrenderable.h"
46 #include "UI/screen.h"
47 
48 namespace Mezzanine
49 {
50  namespace UI
51  {
53  ImageLayer(ParentRenderable),
54  LayerSprite(NULL)
55  {
56  this->FillColours[UI::QC_TopLeft] = ColourValue::White();
57  this->FillColours[UI::QC_TopRight] = ColourValue::White();
58  this->FillColours[UI::QC_BottomLeft] = ColourValue::White();
59  this->FillColours[UI::QC_BottomRight] = ColourValue::White();
60  }
61 
63  { }
64 
66  {
67  // Get the Texel Offsets
68  Real TexelOffsetX = this->Parent->GetScreen()->GetTexelOffsetX();
69  Real TexelOffsetY = this->Parent->GetScreen()->GetTexelOffsetY();
70 
71  // Get the parent rect and apply the scaling
72  Rect ActDims = this->GetAreaRect();
73 
74  // Apply the texel offsets
75  Vector2 RectCorners[4];
76  RectCorners[UI::QC_TopLeft].X = ActDims.Position.X + TexelOffsetX; RectCorners[UI::QC_TopLeft].Y = ActDims.Position.Y + TexelOffsetY;
77  RectCorners[UI::QC_TopRight].X = (ActDims.Position.X + ActDims.Size.X) + TexelOffsetX; RectCorners[UI::QC_TopRight].Y = ActDims.Position.Y + TexelOffsetY;
78  RectCorners[UI::QC_BottomLeft].X = ActDims.Position.X + TexelOffsetX; RectCorners[UI::QC_BottomLeft].Y = (ActDims.Position.Y + ActDims.Size.Y) + TexelOffsetY;
79  RectCorners[UI::QC_BottomRight].X = (ActDims.Position.X + ActDims.Size.X) + TexelOffsetX; RectCorners[UI::QC_BottomRight].Y = (ActDims.Position.Y + ActDims.Size.Y) + TexelOffsetY;
80 
81  // Border and rotation
82  if( 0.0 != this->BorderWidth ) {
83  Vector2 OuterBorder[4];
84  OuterBorder[UI::QC_TopLeft].X = RectCorners[UI::QC_TopLeft].X - BorderWidth; OuterBorder[UI::QC_TopLeft].Y = RectCorners[UI::QC_TopLeft].Y - BorderWidth;
85  OuterBorder[UI::QC_TopRight].X = RectCorners[UI::QC_TopRight].X + BorderWidth; OuterBorder[UI::QC_TopRight].Y = RectCorners[UI::QC_TopRight].Y - BorderWidth;
86  OuterBorder[UI::QC_BottomLeft].X = RectCorners[UI::QC_BottomLeft].X - BorderWidth; OuterBorder[UI::QC_BottomLeft].Y = RectCorners[UI::QC_BottomLeft].Y + BorderWidth;
87  OuterBorder[UI::QC_BottomRight].X = RectCorners[UI::QC_BottomRight].X + BorderWidth; OuterBorder[UI::QC_BottomRight].Y = RectCorners[UI::QC_BottomRight].Y + BorderWidth;
88 
89  this->RotationTransform(RectCorners);
90  this->RotationTransform(OuterBorder);
91  this->DrawBorder(RectCorners,OuterBorder);
92  }else{
93  this->RotationTransform(RectCorners);
94  }
95  // Fill
96  if( !this->IsCompletelyTransparent() ) {
97  this->DrawFill(RectCorners,this->LayerSprite,this->FillColours);
98  }
99  }
100 
101  ///////////////////////////////////////////////////////////////////////////////
102  // Utility
103 
105  { return UI::RLT_SingleImage; }
106 
107  ///////////////////////////////////////////////////////////////////////////////
108  // Fill Methods
109 
111  {
112  this->FillColours[UI::QC_TopLeft] = Colour;
113  this->FillColours[UI::QC_TopRight] = Colour;
114  this->FillColours[UI::QC_BottomLeft] = Colour;
115  this->FillColours[UI::QC_BottomRight] = Colour;
116  this->_MarkDirty();
117  }
118 
119  void SingleImageLayer::SetColour(const UI::QuadCorner Corner, const ColourValue& Colour)
120  {
121  this->FillColours[Corner] = Colour;
122  this->_MarkDirty();
123  }
124 
126  {
127  return this->FillColours[Corner];
128  }
129 
131  {
132  return ( 0 == this->FillColours[UI::QC_TopLeft].AlphaChannel &&
133  0 == this->FillColours[UI::QC_TopRight].AlphaChannel &&
134  0 == this->FillColours[UI::QC_BottomLeft].AlphaChannel &&
135  0 == this->FillColours[UI::QC_BottomRight].AlphaChannel );
136  }
137 
139  {
140  if( this->LayerSprite != NewSprite ) {
141  this->PriAtlas = ( NewSprite == NULL ? this->Parent->GetScreen()->GetPrimaryAtlas() : NewSprite->GetAtlasName() );
142  this->LayerSprite = NewSprite;
143  this->_MarkDirty();
144  }
145  }
146 
147  void SingleImageLayer::SetSprite(const String& SpriteName)
148  {
149  Sprite* NewSprite = this->Parent->GetScreen()->GetSprite(SpriteName,PriAtlas);
150  this->SetSprite(NewSprite);
151  }
152 
153  void SingleImageLayer::SetSprite(const String& SpriteName, const String& Atlas)
154  {
155  Sprite* NewSprite = this->Parent->GetScreen()->GetSprite(SpriteName,Atlas);
156  this->SetSprite(NewSprite);
157  }
158 
159  void SingleImageLayer::SetGradient(const UI::Gradient Grad, const ColourValue& ColourA, const ColourValue& ColourB)
160  {
161  switch(Grad)
162  {
163  case UI::Gradient_NorthSouth:
164  {
165  this->FillColours[UI::QC_TopLeft] = ColourA;
166  this->FillColours[UI::QC_TopRight] = ColourA;
167  this->FillColours[UI::QC_BottomRight] = ColourB;
168  this->FillColours[UI::QC_BottomLeft] = ColourB;
169  break;
170  }
171  case UI::Gradient_WestEast:
172  {
173  this->FillColours[UI::QC_TopLeft] = ColourA;
174  this->FillColours[UI::QC_BottomLeft] = ColourA;
175  this->FillColours[UI::QC_TopRight] = ColourB;
176  this->FillColours[UI::QC_BottomRight] = ColourB;
177  break;
178  }
179  case UI::Gradient_Diagonal_1:
180  {
181  ColourValue Average;
182  Average.RedChannel = (ColourA.RedChannel + ColourB.RedChannel) * 0.5f;
183  Average.GreenChannel = (ColourA.GreenChannel + ColourB.GreenChannel) * 0.5f;
184  Average.BlueChannel = (ColourA.BlueChannel + ColourB.BlueChannel) * 0.5f;
185  Average.AlphaChannel = (ColourA.AlphaChannel + ColourB.AlphaChannel) * 0.5f;
186  this->FillColours[UI::QC_TopLeft] = ColourA;
187  this->FillColours[UI::QC_TopRight] = Average;
188  this->FillColours[UI::QC_BottomRight] = ColourB;
189  this->FillColours[UI::QC_BottomLeft] = Average;
190  break;
191  }
192  case UI::Gradient_Diagonal_2:
193  {
194  ColourValue Average;
195  Average.RedChannel = (ColourA.RedChannel + ColourB.RedChannel) * 0.5f;
196  Average.GreenChannel = (ColourA.GreenChannel + ColourB.GreenChannel) * 0.5f;
197  Average.BlueChannel = (ColourA.BlueChannel + ColourB.BlueChannel) * 0.5f;
198  Average.AlphaChannel = (ColourA.AlphaChannel + ColourB.AlphaChannel) * 0.5f;
199  this->FillColours[UI::QC_TopLeft] = Average;
200  this->FillColours[UI::QC_TopRight] = ColourA;
201  this->FillColours[UI::QC_BottomRight] = Average;
202  this->FillColours[UI::QC_BottomLeft] = ColourB;
203  break;
204  }
205  }
206  this->_MarkDirty();
207  }
208 
209  ///////////////////////////////////////////////////////////////////////////////
210  // Serialization
211 
213  {
214  this->ImageLayer::ProtoSerializeProperties(SelfRoot);
215  XML::Node PropertiesNode = SelfRoot.AppendChild( SingleImageLayer::GetSerializableName() + "Properties" );
216 
217  if( PropertiesNode.AppendAttribute("Version").SetValue("1") &&
218  PropertiesNode.AppendAttribute("SpriteName").SetValue( this->LayerSprite ? this->LayerSprite->Name : "" ) &&
219  PropertiesNode.AppendAttribute("SpriteAtlas").SetValue( this->LayerSprite ? this->LayerSprite->GetAtlasName() : "" ) )
220  {
221  XML::Node FillColoursNode = PropertiesNode.AppendChild("FillColours");
222  XML::Node TopLeftFillNode = FillColoursNode.AppendChild("TopLeft");
223  this->FillColours[UI::QC_TopLeft].ProtoSerialize(TopLeftFillNode);
224 
225  XML::Node TopRightFillNode = FillColoursNode.AppendChild("TopRight");
226  this->FillColours[UI::QC_TopRight].ProtoSerialize(TopRightFillNode);
227 
228  XML::Node BottomLeftFillNode = FillColoursNode.AppendChild("BottomLeft");
229  this->FillColours[UI::QC_BottomLeft].ProtoSerialize(BottomLeftFillNode);
230 
231  XML::Node BottomRightFillNode = FillColoursNode.AppendChild("BottomRight");
232  this->FillColours[UI::QC_BottomRight].ProtoSerialize(BottomRightFillNode);
233 
234  return;
235  }else{
236  SerializeError("Create XML Attribute Values",SingleImageLayer::GetSerializableName() + "Properties",true);
237  }
238  }
239 
241  {
243  XML::Attribute CurrAttrib;
244  XML::Node PropertiesNode = SelfRoot.GetChild( SingleImageLayer::GetSerializableName() + "Properties" );
245 
246  if( !PropertiesNode.Empty() ) {
247  if(PropertiesNode.GetAttribute("Version").AsInt() == 1) {
248  String SpriteName, SpriteAtlas;
249 
250  CurrAttrib = PropertiesNode.GetAttribute("SpriteName");
251  if( !CurrAttrib.Empty() )
252  SpriteName = CurrAttrib.AsString();
253 
254  CurrAttrib = PropertiesNode.GetAttribute("SpriteAtlas");
255  if( !CurrAttrib.Empty() )
256  SpriteAtlas = CurrAttrib.AsString();
257 
258  this->SetSprite(SpriteName,SpriteAtlas);
259 
260  XML::Node FillColoursNode = PropertiesNode.GetChild("FillColours");
261  XML::Node TopLeftFillNode = FillColoursNode.GetChild("TopLeft").GetFirstChild();
262  if( !TopLeftFillNode.Empty() )
263  this->FillColours[UI::QC_TopLeft].ProtoDeSerialize(TopLeftFillNode);
264 
265  XML::Node TopRightFillNode = FillColoursNode.GetChild("TopRight").GetFirstChild();
266  if( !TopRightFillNode.Empty() )
267  this->FillColours[UI::QC_TopRight].ProtoDeSerialize(TopRightFillNode);
268 
269  XML::Node BottomLeftFillNode = FillColoursNode.GetChild("BottomLeft").GetFirstChild();
270  if( !BottomLeftFillNode.Empty() )
271  this->FillColours[UI::QC_BottomLeft].ProtoDeSerialize(BottomLeftFillNode);
272 
273  XML::Node BottomRightFillNode = FillColoursNode.GetChild("BottomRight").GetFirstChild();
274  if( !BottomRightFillNode.Empty() )
275  this->FillColours[UI::QC_BottomRight].ProtoDeSerialize(BottomRightFillNode);
276  }else{
277  MEZZ_EXCEPTION(ExceptionBase::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + (SingleImageLayer::GetSerializableName() + "Properties") + ": Not Version 1.");
278  }
279  }else{
280  MEZZ_EXCEPTION(ExceptionBase::II_IDENTITY_NOT_FOUND_EXCEPTION,SingleImageLayer::GetSerializableName() + "Properties" + " was not found in the provided XML node, which was expected.");
281  }
282  }
283 
286 
288  { return "SingleImageLayer"; }
289  }//UI
290 }//Mezzanine
291 
292 #endif
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
const String Name
The name of this sprite.
Definition: sprite.h:83
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
virtual String GetDerivedSerializableName() const
Gets the most derived serializable name of this Renderable.
virtual void RotationTransform(Vector2 &Point, const Vector2 &RotationCenter)
Applies rotation to a point in 2D space.
Definition: renderlayer.cpp:64
virtual void RedrawImpl(Boole Force)
Provides the class specific implementation for regenerating vertices for this renderable.
virtual Rect GetAreaRect() const
Gets a rect containing the actual position and size of this layer.
Vector2 Size
Vector2 representing the width and height of the rect.
Definition: rect.h:71
Thrown when the requested identity could not be found.
Definition: exception.h:94
QuadCorner
Used by Sprites and Glyphs for tracking their placement on a TextureAtlas.
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
String PriAtlas
This contains the name of the atlas that will be used as default when one isn't specified.
virtual ~SingleImageLayer()
Class destructor.
Thrown when a version is accessed/parsed/required and it cannot work correctly or is missing...
Definition: exception.h:112
static ColourValue White()
Creates a ColourValue representing the colour White.
const Char8 * AsString(const Char8 *def="") const
Attempts to convert the value of the attribute to a String and returns the results.
Screen * GetScreen() const
Gets the parent screen of this renderable.
Definition: renderable.cpp:80
This class represents a box shaped area on the screen.
Definition: rect.h:55
This is a simple class for holding 4 reals representing the colour any give object or lightsource can...
Definition: colourvalue.h:64
virtual void _MarkDirty()
Marks this renderable as well as all parent objects as dirty.
bool Empty() const
Is this storing anything at all?
static String GetSerializableName()
Get the name of the the XML tag the Renderable class will leave behind as its instances are serialize...
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.
virtual void ProtoSerializeProperties(XML::Node &SelfRoot) const
Convert the properties of this class to an XML::Node ready for serialization.
Real GreenChannel
Value from 0.0 to 1.0 representing the amount of green present in the colour. 1.0 if very green...
Definition: colourvalue.h:73
Value representing a SingleImageLayer.
Real Y
Coordinate on the Y vector.
Definition: vector2.h:69
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
Real X
Coordinate on the X vector.
Definition: vector2.h:67
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?
Gradient
Used by various basic renderables for applying a gradient effect to a colour or texture on a quad...
Real AlphaChannel
Value from 0.0 to 1.0 representing the transparency of the colours. 1.0 is opaque and 0...
Definition: colourvalue.h:79
Sprite * GetSprite(const String &SpriteName, const String &Atlas) const
Gets a sprite from an Atlas.
Definition: screen.cpp:886
void DrawBorder(const Vector2 *InnerRect, const Vector2 *OuterRect)
Draws the border, if any is set.
Definition: imagelayer.cpp:64
This layer is for placing images and basic colours in it's parents' quad space.
Definition: imagelayer.h:55
virtual void ProtoDeSerializeProperties(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite the properties of this object with it...
Real GetTexelOffsetX() const
Gets the X axis Texel Offset for the current rendersystem.
Definition: screen.cpp:898
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
virtual const ColourValue & GetColour(const UI::QuadCorner Corner) const
Gets the colour of a corner of this layer.
Sprite * LayerSprite
A pointer to the sprite that will be rendered by this layer.
virtual void SetColour(const ColourValue &Colour)
Sets the colour of the layer.
virtual void SetSprite(Sprite *NewSprite)
Sets the fill image(if provided in the atlas) of the layer.
virtual Boole IsCompletelyTransparent() const
Gets whether or not this layer is entirely transparent.
virtual String GetPrimaryAtlas()
Gets the currently set primary atlas.
Definition: screen.cpp:880
virtual UI::RenderLayerType GetLayerType() const
Gets the type of render layer this is.
RenderLayerType
This enum describes the type of RenderLayer this is for use in casting.
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
Real BlueChannel
Value from 0.0 to 1.0 representing the amount of blue present in the colour. 1.0 if very blue...
Definition: colourvalue.h:76
void ProtoSerialize(XML::Node &CurrentRoot) const
Convert this class to an XML::Node ready for serialization.
SingleImageLayer(QuadRenderable *ParentRenderable)
Class constructor.
Real RedChannel
Value from 0.0 to 1.0 representing the amount of red present in the colour. 1.0 if very red...
Definition: colourvalue.h:70
virtual void SetGradient(const UI::Gradient Grad, const ColourValue &ColourA, const ColourValue &ColourB)
Sets a colour gradient to be applied to this layer.
ColourValue FillColours[4]
An array of colours to be used for each corner section of this layer.
This represents a nestable quad for an object in a GUI layout.
Vector2 Position
Vector2 representing the top-left position of the rect.
Definition: rect.h:69
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.
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
Real GetTexelOffsetY() const
Gets the Y axis Texel Offset for the current rendersystem.
Definition: screen.cpp:901
const String & GetAtlasName() const
Gets the name of the atlas this sprite belongs to.
Definition: sprite.h:97
Attribute GetAttribute(const Char8 *Name) const
Attempt to get an Attribute on this Node with a given name.
Node GetChild(const Char8 *Name) const
Attempt to get a child Node with a given name.