TurtleBrains  0.3.5
High quality, portable, C++ framework for rapid 2D game development.
tb_anchor_location.hpp
1 
9 #ifndef TurtleBrains_AnchorLocation_hpp
10 #define TurtleBrains_AnchorLocation_hpp
11 
12 #include <turtle_brains/core/tb_string_utilities.hpp>
13 #include <turtle_brains/core/tb_dynamic_structure.hpp>
14 
15 namespace TurtleBrains::Graphics
16 {
17 
21  enum class Anchor
22  {
23  Center = 0,
24  TopLeft,
25  TopCenter,
26  TopRight,
27  CenterLeft,
28  CenterRight,
29  BottomLeft,
30  BottomCenter,
31  BottomRight,
32  };
33 
34  using AnchorLocation = Anchor;
35 
36  inline std::ostream& operator<<(std::ostream& output, const AnchorLocation& anchor)
37  {
38  switch (anchor)
39  {
40  case Anchor::Center: output << "center"; break;
41  case Anchor::TopLeft: output << "top_left"; break;
42  case Anchor::TopCenter: output << "top_center"; break;
43  case Anchor::TopRight: output << "top_right"; break;
44  case Anchor::CenterLeft: output << "center_left"; break;
45  case Anchor::CenterRight: output << "center_right"; break;
46  case Anchor::BottomLeft: output << "bottom_left"; break;
47  case Anchor::BottomCenter: output << "bottom_center"; break;
48  case Anchor::BottomRight: output << "bottom_right"; break;
49  };
50 
51  return output;
52  }
53 
54  inline std::istream& operator>>(std::istream& input, AnchorLocation& anchor)
55  {
56  tbCore::String anchorString;
57  input >> anchorString;
58  tbCore::StringUtilities::LowercaseInPlace(anchorString);
59 
60  if ("center" == anchorString) { anchor = Anchor::Center; }
61  else if ("top_left" == anchorString || "topleft" == anchorString) { anchor = Anchor::TopLeft; }
62  else if ("top_center" == anchorString || "topcenter" == anchorString) { anchor = Anchor::TopCenter; }
63  else if ("top_right" == anchorString || "topright" == anchorString) { anchor = Anchor::TopRight; }
64  else if ("center_left" == anchorString || "centerleft" == anchorString) { anchor = Anchor::CenterLeft; }
65  else if ("center_right" == anchorString || "centerright" == anchorString) { anchor = Anchor::CenterRight; }
66  else if ("bottom_left" == anchorString || "bottomleft" == anchorString) { anchor = Anchor::BottomLeft; }
67  else if ("bottom_center" == anchorString || "bottomcenter" == anchorString) { anchor = Anchor::BottomCenter; }
68  else if ("bottom_right" == anchorString || "bottomright" == anchorString) { anchor = Anchor::BottomRight; }
69  else
70  {
71  tb_error("tbError: Unknown value '%s' to convert into an AnchorLocation.", anchorString.c_str());
72  anchor = Anchor::TopLeft;
73  }
74 
75  return input;
76  }
77 
78  //inline void FromDynamicStructure(const DynamicStructure& data, AnchorLocation& anchor);
79 
80 
81  //inline DynamicStructure ToDynamicStructure(const AnchorLocation& anchor)
82  //{
83  // return tbCore::DynamicStructure(Core::ToString(anchor));
84  //}
85 
86  //inline void FromDynamicStructure(const DynamicStructure& data, AnchorLocation& anchor)
87  //{
88  // anchor = Core::FromString<AnchorLocation>(data.AsString());
89  //}
90 
91  //template<typename Type> DynamicStructure ToDynamicStructure(const Type& object)
92  //{
93  // return tbCore::ToDynamicStructure(object);
94  //}
95 
96  //template<typename Type> Type FromDynamicStructure(const DynamicStructure& data)
97  //{
98  // return tbCore::FromDynamicStructure(data);
99  //}
100 
101  //template<> inline DynamicStructure ToDynamicStructure<AnchorLocation>(const AnchorLocation& anchor)
102  //{
103  // return tbCore::DynamicStructure(Core::ToString(anchor));
104  //}
105 
106  //template<> inline AnchorLocation FromDynamicStructure<AnchorLocation>(const DynamicStructure& data)
107  //{
108  // return Core::FromString<AnchorLocation>(data.AsString());
109  //}
110 
111 }; /* namespace TurtleBrains::Graphics */
112 
114 
115 // 2025-11-23: It doesn't feel right to extend the Core namespace like this from within the Graphics namespace or other
116 // TurtleBrains kits, but, doing so is one possible solution to the other problem. Without extending the Core kit like
117 // this we need to "re"define the ToDynamicStructure/FromDynamicStructure template within each individual namespace.
118 // That seems easy enough if there is a single location, but as soon as we add a To/FromDynStruct to ColorPalette etc
119 // then it becomes a little more tricky.
120 //
121 // Upon writing this I think I stumbled on the brilliant idea of putting the initial Core::ToDynamicStructure directly
122 // in the primary TurtleBrains namespace. DynamicStructure is Core enough that it exists there, so perhaps the template
123 // could as well, which would solve the problem. ... Ackshually, you can't. Because the specializations must exist
124 // in the same namespace as the template itself, meaning it can't jump into tbGraphics.
125 //
126 // Though we could combine the ideas which means we extend TurtleBrains namespace with extra To/FromDyn structs rather
127 // than TurtleBrains::Core, and I think that is at least slightly better than extending Core.
128 //
129 // Currently the least bad way seems to be extending TurtleBrains namespace.
130 //
131 // 2025-11-23: ikiwixz came up with a solution using "tags" and "invoke_tag" which I renamed to Implements() in the
132 // following: https://pastebin.com/VHEaYG2p which is based on https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf
133 // This seems like it punches through any of the namespace issues, but it is a little more convoluted to write because
134 // the implementation needs to deal with the tags, that passes down to the game/project level too.
135 
136 //namespace TurtleBrains::Core
137 //{
138 // template<> inline DynamicStructure ToDynamicStructure<Graphics::AnchorLocation>(const Graphics::AnchorLocation& anchor)
139 // {
140 // return tbCore::DynamicStructure(Core::ToString(anchor));
141 // }
142 //
143 // template<> inline Graphics::AnchorLocation FromDynamicStructure<Graphics::AnchorLocation>(const DynamicStructure& data)
144 // {
145 // return Core::FromString<Graphics::AnchorLocation>(data.AsString());
146 // }
147 //};
148 
149 namespace TurtleBrains
150 {
151  //Note: If we go this direction we need to move the ToDynamicStructure/FromDynamicStructure template functions into the
152  //TurtleBrains namespace from within tb_dynamic_structure.hpp.
153  template<> inline DynamicStructure ToDynamicStructure<Graphics::AnchorLocation>(const Graphics::AnchorLocation& anchor)
154  {
155  return DynamicStructure(Core::ToString(anchor));
156  }
157 
158  template<> inline Graphics::AnchorLocation FromDynamicStructure<Graphics::AnchorLocation>(const DynamicStructure& data)
159  {
160  return Core::FromString<Graphics::AnchorLocation>(data.AsString());
161  }
162 };
163 
164 #endif /* TurtleBrains_AnchorLocation_hpp */
#define tb_error(message,...)
Definition: tb_error.hpp:23
String ToString(const Type &object)
Definition: tb_string.hpp:317
std::string String
Definition: tb_string.hpp:302
Give the GameScene and Entities something to display, Text, Sprites and AnimatedSprites help bring th...
Anchor
Definition: tb_anchor_location.hpp:22
@ TopRight
This anchor will set the origin to the top and right most corner of the Sprite.
@ Center
This anchor will set the origin to the center of the Sprite horizontally and vertically.
@ BottomRight
This anchor will set the origin to the bottom and right most corner of the Sprite.
@ TopCenter
This anchor will set the origin to the top and horizontal center of the Sprite.
@ BottomLeft
This anchor will set the origin to the bottom and left most corner of the Sprite.
@ CenterLeft
This anchor will set the origin to the center vertically and left most edge of the Sprite.
@ CenterRight
This anchor will set the origin to the center vertically and right most edge of the Sprite.
@ TopLeft
This anchor will set the origin to the top-left corner, effectively: SetOrigin(0.0f,...
@ BottomCenter
This anchor will set the origin to the bottom edge and horizontal center of the Sprite.
Here is some information about the primary namespace.
Definition: tb_application_dialog.hpp:22