Spinning Topp Logo BlackTopp Studios
inc
textcursor.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 _uitextcursor_cpp
42 #define _uitextcursor_cpp
43 
44 #include "UI/textcursor.h"
45 #include "UI/textline.h"
46 #include "UI/character.h"
47 #include "MathTools/mathtools.h"
48 #include "stringtool.h"
49 #include "XML/xml.h"
50 
51 namespace Mezzanine
52 {
53  namespace UI
54  {
56  IndexPosition(0),
57  Layer(Creator),
58  Visibility(true)
59  { this->CursorColour = ColourValue::Black(); }
60 
62  { }
63 
64  ///////////////////////////////////////////////////////////////////////////////
65  // Utility Methods
66 
68  { this->Visibility = Visible; }
69 
71  { return this->Visibility; }
72  //{ return ( this->GetFlicker() ? ( this->FlickerTimer.GetCurrentTimeInMilliseconds() / 500 ) % 2 : this->Visibility ); }
73 
74  /*void TextCursor::SetFlicker(Boole Flicker)
75  {
76  if( Flicker ) this->FlickerTimer->Start();
77  else this->FlickerTimer->Stop();
78  }
79 
80  Boole TextCursor::GetFlicker() const
81  { return !( this->FlickerTimer->IsStopped() ); }// */
82 
84  {
85  if( this->IndexPosition != Index ) {
86  this->IndexPosition = Index;
87  this->Layer->_MarkDirty();
88  }
89  }
90 
92  {
93  return this->IndexPosition;
94  }
95 
97  {
98  TextLayer::CharIndexPair ResultPair = this->Layer->GetIndexAtOffset(Offset);
99  if( ResultPair.first ) {
100  this->SetCursorIndex( ResultPair.second );
101  }
102  }
103 
105  { return this->Layer->GetOffsetAtIndex(this->IndexPosition); }
106 
108  {
109  Rect Ret;
110  if( this->IndexPosition < 0 || static_cast<Whole>( this->IndexPosition ) >= Layer->GetNumCharacters() ) {
112 
113  if( (*Last)->GetNumCharacters() > 0 ) {
114  Ret.Size.Y = (*Last)->GetLineHeight();
115  Ret.Size.X = MathTools::Floor( Ret.Size.Y * 0.1 ) + 1.0;
116  Ret.Position.Y = (*Last)->GetPositionOffset();
117  Ret.Position.X = (*Last)->GetOffsetAtIndex(-1);
118  }else{
119  Ret.Size.Y = this->Layer->GetDesiredLineHeight();
120  Ret.Size.X = MathTools::Floor( Ret.Size.Y * 0.1 ) + 1.0;
121  Ret.Position.Y = ( (*Last)->GetPositionOffset() + ( Ret.Size.Y * 0.5 ) );
122  Ret.Position.X = (*Last)->GetOffsetAtIndex(-1);
123  }
124  }else{
125  Integer IndexCount = 0;
126 
128  while( LineIt != Layer->EndTextLine() && IndexCount + static_cast<Integer>( (*LineIt)->GetNumCharacters() ) < this->IndexPosition )
129  {
130  IndexCount += (*LineIt)->GetNumCharacters();
131  ++LineIt;
132  }
133 
134  if( (*LineIt)->GetNumCharacters() > 0 ) {
135  Ret.Size.Y = (*LineIt)->GetLineHeight();
136  Ret.Size.X = MathTools::Floor( Ret.Size.Y * 0.1 ) + 1.0;
137  Ret.Position.Y = (*LineIt)->GetPositionOffset();
138  Ret.Position.X = (*LineIt)->GetOffsetAtIndex( this->IndexPosition - IndexCount );
139  }else{
140  Ret.Size.Y = this->Layer->GetDesiredLineHeight();
141  Ret.Size.X = MathTools::Floor( Ret.Size.Y * 0.1 ) + 1.0;
142  Ret.Position.Y = ( (*LineIt)->GetPositionOffset() + ( Ret.Size.Y * 0.5 ) );
143  Ret.Position.X = (*LineIt)->GetOffsetAtIndex( this->IndexPosition - IndexCount );
144  }
145  }
146  return Ret;
147  }
148 
149  void TextCursor::SetColour(const ColourValue& Colour)
150  {
151  if( this->CursorColour != Colour ) {
152  this->CursorColour = Colour;
153  this->Layer->_MarkDirty();
154  }
155  }
156 
158  {
159  return this->CursorColour;
160  }
161 
162  ///////////////////////////////////////////////////////////////////////////////
163  // Left and Right Methods
164 
166  {
167  if( this->IndexPosition > 0 ) {
168  --(this->IndexPosition);
169  this->Layer->_MarkDirty();
170  }else if( this->IndexPosition == -1 ) {
171  Whole NumChars = this->Layer->GetNumCharacters();
172  this->IndexPosition = NumChars - 1;
173  this->Layer->_MarkDirty();
174  }
175  }
176 
178  {
179  Whole NumChars = this->Layer->GetNumCharacters();
180  if( this->IndexPosition >= 0 && static_cast<Whole>( this->IndexPosition ) < NumChars ) {
181  ++(this->IndexPosition);
182  this->Layer->_MarkDirty();
183  }
184  }
185 
187  {
188  Integer Added = this->Layer->InsertCharacterAtIndex(this->IndexPosition,GlyphID);
189  if( this->IndexPosition >= 0 ) {
190  this->IndexPosition += Added;
191  }
192  }
193 
194  void TextCursor::InsertCharactersAtCursor(const Char8* Characters, const UInt32 BufSize)
195  {
196  Integer Added = this->Layer->InsertCharactersAtIndex(this->IndexPosition,Characters,BufSize);
197  if( this->IndexPosition >= 0 ) {
198  this->IndexPosition += Added;
199  }
200  }
201 
202  void TextCursor::InsertCharactersAtCursor(const UInt32* Characters, const UInt32 BufSize)
203  {
204  Integer Added = this->Layer->InsertCharactersAtIndex(this->IndexPosition,Characters,BufSize);
205  if( this->IndexPosition >= 0 ) {
206  this->IndexPosition += Added;
207  }
208  }
209 
211  {
212  UInt32 NumChars = this->Layer->GetNumCharacters();
213  if( NumChars > 0 ) {
214  if( this->IndexPosition < 0 || static_cast<Whole>( this->IndexPosition ) > this->Layer->GetNumCharacters() ) {
215  this->Layer->RemoveCharacterAtIndex( NumChars - 1 );
216  }else{
217  this->Layer->RemoveCharacterAtIndex(--(this->IndexPosition));
218  }
219  }
220  }
221 
223  {
224  Whole NumChars = this->Layer->GetNumCharacters();
225  if( NumChars > 0 ) {
226  if( this->IndexPosition < 0 || static_cast<Whole>( this->IndexPosition ) > NumChars ) {
227  // Nothing to be done, may fill out other logic later.
228  }else{
230  }
231  }
232  }
233 
234  ///////////////////////////////////////////////////////////////////////////////
235  // Serialization
236 
237  void TextCursor::ProtoSerialize(XML::Node& ParentNode) const
238  {
239  XML::Node SelfRoot = ParentNode.AppendChild( this->TextCursor::GetSerializableName() );
240 
241  if( SelfRoot.AppendAttribute("Version").SetValue("1") &&
242  SelfRoot.AppendAttribute("IndexPosition").SetValue(this->IndexPosition) &&
243  SelfRoot.AppendAttribute("Visibility").SetValue( ( this->Visibility ? "True" : "False" ) ) )
244  {
245  XML::Node CursorColourNode = SelfRoot.AppendChild("CursorColour");
246  this->CursorColour.ProtoSerialize( CursorColourNode );
247 
248  return;
249  }else{
250  SerializeError("Create XML Attribute Values",TextCursor::GetSerializableName(),true);
251  }
252  }
253 
255  {
256  XML::Attribute CurrAttrib;
257 
258  if( !SelfRoot.Empty() ) {
259  if( SelfRoot.GetAttribute("Version").AsInt() == 1 ) {
260  CurrAttrib = SelfRoot.GetAttribute("IndexPosition");
261  if( !CurrAttrib.Empty() )
262  this->IndexPosition = CurrAttrib.AsWhole();
263 
264  CurrAttrib = SelfRoot.GetAttribute("Visibility");
265  if( !CurrAttrib.Empty() )
266  this->Visibility = StringTools::ConvertToBool( CurrAttrib.AsString() );
267 
268  XML::Node CursorColourNode = SelfRoot.GetChild("CursorColour").GetFirstChild();
269  if( !CursorColourNode.Empty() )
270  this->CursorColour.ProtoDeSerialize(CursorColourNode);
271  }else{
272  MEZZ_EXCEPTION(ExceptionBase::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + TextCursor::GetSerializableName() + ": Not Version 1.");
273  }
274  }else{
275  MEZZ_EXCEPTION(ExceptionBase::II_IDENTITY_NOT_FOUND_EXCEPTION,TextCursor::GetSerializableName() + " was not found in the provided XML node, which was expected.");
276  }
277  }
278 
280  { return "TextCursor"; }
281  }//UI
282 }//Mezzanine
283 
284 #endif
virtual Integer InsertCharacterAtIndex(const Integer Index, const UInt32 GlyphID)
Creates a character from a Glyph ID and inserts it into the layer at the specified index...
Definition: textlayer.cpp:840
std::pair< Boole, Vector2 > CharOffsetPair
An std::pair type used as a return for index-offset conversions.
Definition: textlayer.h:88
Attribute AppendAttribute(const Char8 *Name)
Creates an Attribute and puts it at the end of this Nodes attributes.
virtual TextLineIterator BeginTextLine()
Gets an iterator to the first TextLine.
Definition: textlayer.cpp:747
A light-weight handle for manipulating attributes in DOM tree.
Definition: attribute.h:74
Boole Visibility
Stores the cursors current visibility state.
Definition: textcursor.h:76
virtual TextLineIterator EndTextLine()
Gets an iterator to one passed the last TextLine.
Definition: textlayer.cpp:750
Integer IndexPosition
The index of the character this TextCursor is to the left of.
Definition: textcursor.h:70
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
virtual ~TextCursor()
Class destructor.
Definition: textcursor.cpp:61
Vector2 Size
Vector2 representing the width and height of the rect.
Definition: rect.h:71
virtual void InsertCharacterAtCursor(const UInt32 GlyphID)
Creates a character from a Glyph ID and inserts it at the cursor position.
Definition: textcursor.cpp:186
virtual void ProtoSerialize(XML::Node &ParentNode) const
Convert this class to an XML::Node ready for serialization.
Definition: textcursor.cpp:237
Thrown when the requested identity could not be found.
Definition: exception.h:94
virtual void MoveCursorLeft()
Decrements this cursors index position, moving it to the left.
Definition: textcursor.cpp:165
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
int Integer
A datatype used to represent any integer close to.
Definition: datatypes.h:154
Thrown when a version is accessed/parsed/required and it cannot work correctly or is missing...
Definition: exception.h:112
const Char8 * AsString(const Char8 *def="") const
Attempts to convert the value of the attribute to a String and returns the results.
virtual void MoveCursorRight()
Increments this cursors index position, moving it to the right.
Definition: textcursor.cpp:177
This class represents a box shaped area on the screen.
Definition: rect.h:55
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 void _MarkDirty()
Marks this renderable as well as all parent objects as dirty.
bool Empty() const
Is this storing anything at all?
TextLineContainer::iterator TextLineIterator
Iterator type for TextLine instances stored by this class.
Definition: textlayer.h:82
ColourValue CursorColour
The colour to be given to the TextCursor.
Definition: textcursor.h:64
TextCursor(TextLayer *Creator)
Class constructor.
Definition: textcursor.cpp:55
std::pair< Boole, Integer > CharIndexPair
An std::pair type used as a return for index-offset conversions.
Definition: textlayer.h:86
char Char8
A datatype to represent one character.
Definition: datatypes.h:169
virtual void SetColour(const ColourValue &Colour)
Sets the colour that the Text Cursor should be rendered as.
Definition: textcursor.cpp:149
virtual Rect GetCursorRect() const
Gets a rect representing this cursors dimentions.
Definition: textcursor.cpp:107
bool SetValue(const Char8 *rhs)
Set the value of this.
virtual Integer RemoveCharacterAtIndex(const Integer Index)
Removes a character from the layer at the specified index.
Definition: textlayer.cpp:873
Whole AsWhole(Whole def=0) const
Attempts to convert the value of the attribute to a Whole and returns the results.
Boole ConvertToBool(const String &ToConvert, const Boole Default)
Converts a string into a Boole.
Definition: stringtool.cpp:379
Real Y
Coordinate on the Y vector.
Definition: vector2.h:69
virtual void RemoveLeftCharacter()
Removes the character to the left (and decrements the index position) of this cursor.
Definition: textcursor.cpp:210
virtual CharIndexPair GetIndexAtOffset(const Vector2 &Offset)
Gets the index of the character at the specified offset position.
Definition: textlayer.cpp:393
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. ...
uint32_t UInt32
An 32-bit unsigned integer.
Definition: datatypes.h:126
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?
virtual Integer GetCursorIndex() const
Gets the index position of this cursor.
Definition: textcursor.cpp:91
virtual Real GetDesiredLineHeight() const
Gets the height in pixels this layer is configured to render it's text.
Definition: textlayer.cpp:378
virtual Boole GetVisible() const
Gets the visibility of this cursor.
Definition: textcursor.cpp:70
virtual void SetOffsetPosition(const Vector2 &Offset)
Sets the offset position of this cursor to the nearest appropriate point.
Definition: textcursor.cpp:96
virtual CharOffsetPair GetOffsetAtIndex(const Integer Index)
Gets the offset position of the character at the provided index.
Definition: textlayer.cpp:403
virtual Integer InsertCharactersAtIndex(const Integer Index, const Char8 *Characters, const UInt32 BufSize)
Creates a series of characters from a UTF-8 encoded string to be inserted into this layer...
Definition: textlayer.cpp:851
virtual void InsertCharactersAtCursor(const Char8 *Characters, const UInt32 BufSize)
Creates a series of characters from a UTF-8 encoded string to be inserted at the cursor position...
Definition: textcursor.cpp:194
virtual Whole GetNumCharacters() const
Gets the number of characters being rendered by this TextLayer.
Definition: textlayer.cpp:835
virtual TextLayer::CharOffsetPair GetOffsetPosition() const
Gets the current offset position of this cursor.
Definition: textcursor.cpp:104
virtual void RemoveRightCharacter()
Removes the character to the right of this cursor.
Definition: textcursor.cpp:222
void ProtoDeSerialize(const XML::Node &OneNode)
Take the data stored in an XML and overwrite this instance of this object with it.
virtual void SetCursorIndex(const Integer &Index)
Sets the index position of this cursor.
Definition: textcursor.cpp:83
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
unsigned long Whole
Whole is an unsigned integer, it will be at least 32bits in size.
Definition: datatypes.h:151
virtual void ProtoDeSerialize(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite this object with it.
Definition: textcursor.cpp:254
void ProtoSerialize(XML::Node &CurrentRoot) const
Convert this class to an XML::Node ready for serialization.
static String GetSerializableName()
Get the name of the the XML tag the Renderable class will leave behind as its instances are serialize...
Definition: textcursor.cpp:279
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.
TextLayer * Layer
The layer this TextCursor belongs to.
Definition: textcursor.h:73
virtual const ColourValue & GetColour() const
Gets the colour that the Text Cursor will be rendered as.
Definition: textcursor.cpp:157
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159
virtual void SetVisible(Boole Visible)
Sets the visibility of this cursor.
Definition: textcursor.cpp:67
This is a base class for render layers that render text.
Definition: textlayer.h:64
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.