HoverRace  2.0
Hud.h
Go to the documentation of this file.
1 
2 // Hud.h
3 //
4 // Copyright (c) 2013-2015 Michael Imamura.
5 //
6 // Licensed under GrokkSoft HoverRace SourceCode License v1.0(the "License");
7 // you may not use this file except in compliance with the License.
8 //
9 // A copy of the license should have been attached to the package from which
10 // you have taken this file. If you can not find the license you can not use
11 // this file.
12 //
13 //
14 // The author makes no representations about the suitability of
15 // this software for any purpose. It is provided "as is" "AS IS",
16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
17 // implied.
18 //
19 // See the License for the specific language governing permissions
20 // and limitations under the License.
21 
22 #pragma once
23 
24 #include "../Util/OS.h"
25 #include "../Exception.h"
26 #include "HudCell.h"
27 #include "HudDecor.h"
28 
29 #include "BaseContainer.h"
30 
31 #if defined(_WIN32) && defined(HR_ENGINE_SHARED)
32 # ifdef MR_ENGINE
33 # define MR_DllDeclare __declspec( dllexport )
34 # else
35 # define MR_DllDeclare __declspec( dllimport )
36 # endif
37 #else
38 # define MR_DllDeclare
39 #endif
40 
41 namespace HoverRace {
42  namespace Display {
43  class Display;
44  }
45  namespace MainCharacter {
46  class MainCharacter;
47  }
48  namespace Model {
49  class Track;
50  }
51  namespace Player {
52  class Player;
53  }
54 }
55 
56 namespace HoverRace {
57 namespace Display {
58 
64 {
66 
67 public:
68  struct Props
69  {
70  enum {
71  PLAYER = SUPER::Props::NEXT_,
74  };
75  };
76  struct HudAlignment
77  {
78  enum type {
81  N,
82  NNE,
83  NE,
84  ENE,
85  E,
86  ESE,
87  SE,
88  SSE,
89  S,
90  SSW,
91  SW,
92  WSW,
93  W,
94  WNW,
95  NW,
96  NNW,
97  };
98  static const size_t NUM = NNW + 1;
99 
107  static type FromInt(int t) {
108  if (t < 0 || t > NNW) {
109  std::ostringstream oss;
110  oss << "Invalid HUD alignment: " << t;
111  throw Exception(oss.str());
112  }
113  return static_cast<type>(t);
114  }
115 
116  static bool IsCorner(type t) {
117  return t == NW || t == NE || t == SE || t == SW;
118  }
119 
121  switch (t) {
122  case ABOVE:
123  return Alignment::S;
124  case BELOW:
125  return Alignment::N;
126  case N:
127  return Alignment::N;
128  case NNE:
129  case NE:
130  case ENE:
131  return Alignment::NE;
132  case E:
133  return Alignment::E;
134  case ESE:
135  case SE:
136  case SSE:
137  return Alignment::SE;
138  case S:
139  return Alignment::S;
140  case SSW:
141  case SW:
142  case WSW:
143  return Alignment::SW;
144  case W:
145  return Alignment::W;
146  case WNW:
147  case NW:
148  case NNW:
149  default:
150  return Alignment::NW;
151  }
152  }
153  }; // HudAlignment
154 
155 protected:
157  {
158  HudChild(std::shared_ptr<HudDecor> decor);
159  HudChild(const HudChild&) = delete;
160  HudChild(HudChild &&other);
161 
162  HudChild &operator=(const HudChild&) = delete;
163  HudChild &operator=(HudChild &&other);
164 
165  std::shared_ptr<HudDecor> decor;
166  boost::signals2::scoped_connection sizeChangedConn;
167  };
168 
173  {
174  public:
175  HudLocProxy(Hud &hud, HudAlignment::type alignment) :
176  hud(hud), alignment(alignment)
177  { }
178  HudLocProxy(const HudLocProxy&) = default;
179  HudLocProxy(HudLocProxy&&) = default;
180 
181  public:
182  HudLocProxy &operator=(const HudLocProxy&) = delete;
183  HudLocProxy &operator=(HudLocProxy&&) = delete;
184 
185  public:
193  template<class T, class... Args>
194  typename std::enable_if<
195  std::is_base_of<HudDecor, T>::value,
196  std::shared_ptr<T>
197  >::type
198  NewChild(Args&&... args)
199  {
200  return hud.NewHudChild<T>(alignment, std::forward<Args>(args)...);
201  }
202 
203  private:
206  };
207 
208 public:
209  Hud(Display &display, std::shared_ptr<Player::Player> player,
210  std::shared_ptr<Model::Track> track,
211  uiLayoutFlags_t layoutFlags=0);
212  virtual ~Hud() { }
213 
214 /* Using the view for Container.
215 public:
216  virtual void AttachView(Display &disp) { AttachViewDynamic(disp, this); }
217 */
218 
219 public:
229  {
230  return { *this, alignment };
231  }
232 
233 private:
242  template<class T, class... Args>
243  typename std::enable_if<
244  std::is_base_of<HudDecor, T>::value,
245  std::shared_ptr<T>
246  >::type
247  NewHudChild(HudAlignment::type alignment, Args&&... args)
248  {
249  auto sharedChild = NewChild<T>(std::forward<Args>(args)...);
250  sharedChild->SetPlayer(player);
251  sharedChild->SetTrack(track);
252  sharedChild->SetHudScale(hudScale);
253 
254  // For corner elems, replace the elem instead of adding.
255  if (HudAlignment::IsCorner(alignment)) {
256  auto &elems = hudChildren[alignment];
257  if (!elems.empty()) {
258  RemoveChild(elems.back().decor);
259  elems.clear();
260  }
261  }
262 
263  sharedChild->SetAlignment(HudAlignment::AlignmentFor(alignment));
264 
265  auto &children = hudChildren[alignment];
266  children.emplace_back(sharedChild);
267 
268  // Trigger layout when the child changes size.
269  children.back().sizeChangedConn =
270  sharedChild->GetSizeChangedSignal().connect(
271  std::bind(&Hud::RequestLayout, this));
272 
273  RequestLayout();
274  return sharedChild;
275  }
276 
277 public:
278  virtual void Clear()
279  {
280  for (auto &children : hudChildren) {
281  children.clear();
282  }
283  SUPER::Clear();
284  }
285 
286 protected:
287  template<typename Fn>
288  void ForEachHudChild(Fn fn)
289  {
290  for (auto &children : hudChildren) {
291  for (auto &child : children) {
292  fn(child.decor);
293  }
294  }
295  }
296 
297 public:
298  void SetPlayer(std::shared_ptr<Player::Player> player);
299 
300  Model::Track *GetTrack() const { return track.get(); }
301  std::shared_ptr<Model::Track> ShareTrack() const { return track; }
302  void SetTrack(std::shared_ptr<Model::Track> track);
303 
304  HudCell GetCell() const { return cell; }
305  void SetCell(HudCell cell);
306 
307 public:
308  void OnScreenSizeChanged();
309 
310 private:
311  void LayoutStacked(HudAlignment::type align,
312  double startX, double startY,
313  double scaleX, double scaleY);
314  void LayoutCorner(HudAlignment::type alignCorner,
315  HudAlignment::type alignH, HudAlignment::type alignV,
316  double startX, double startY,
317  double scaleX, double scaleY);
318 protected:
319  virtual void Layout();
320 
321 public:
322  void Advance(Util::OS::timestamp_t tick);
323 
324 private:
325  std::shared_ptr<Model::Track> track;
326  std::shared_ptr<Player::Player> player;
329  typedef std::vector<HudChild> hudChildList_t;
330  std::array<hudChildList_t, HudAlignment::NUM> hudChildren;
331  boost::signals2::scoped_connection displayConfigChangedConn;
332 };
333 
334 } // namespace Display
335 } // namespace HoverRace
336 
337 #undef MR_DllDeclare
Southeast corner, stacked right-to-left.
Definition: Hud.h:88
HudCell GetCell() const
Definition: Hud.h:304
Northeast corner, stacked top-to-bottom.
Definition: Hud.h:84
Southeast corner, only top is visible.
Definition: Hud.h:87
static Alignment AlignmentFor(type t)
Definition: Hud.h:120
Hud & hud
Definition: Hud.h:204
std::shared_ptr< Model::Track > track
Definition: Hud.h:325
virtual ~Hud()
Definition: Hud.h:212
Base class for UI (2D) components.
Definition: UiViewModel.h:56
Upper-left quadrant.
Alignment
Imagine the component pinned to the container with a thumbtack.
Definition: UiViewModel.h:77
std::shared_ptr< HudDecor > decor
Definition: Hud.h:165
Northeast corner, only top is visible.
Definition: Hud.h:83
Center-west, stacked top-to-bottom.
Definition: Hud.h:93
Model::Track * GetTrack() const
Definition: Hud.h:300
Southwest corner, stacked bottom-to-top.
Definition: Hud.h:92
Upper-right quadrant.
HudLocProxy(Hud &hud, HudAlignment::type alignment)
Definition: Hud.h:175
Base class for widgets that contain other widgets.
Definition: BaseContainer.h:63
Centered in the top-half of the screen.
Definition: Hud.h:79
static bool IsCorner(type t)
Definition: Hud.h:116
Definition: Vec.h:38
#define MR_DllDeclare
Definition: Hud.h:38
MR_UInt32 uiLayoutFlags_t
Definition: UiLayoutFlags.h:53
Northeast corner, stacked right-to-left.
Definition: Hud.h:82
The container for the heads-up display.
Definition: Hud.h:63
First index for subclasses.
Definition: Hud.h:73
std::shared_ptr< Player::Player > player
Definition: Hud.h:326
Base class for display managers.
Definition: Display.h:73
boost::signals2::scoped_connection sizeChangedConn
Definition: Hud.h:166
Lower-left quadrant.
A track level.
Definition: Track.h:57
Center-east, stacked top-to-bottom.
Definition: Hud.h:85
Centered in the bottom-half of the screen.
Definition: Hud.h:80
std::vector< HudChild > hudChildList_t
Definition: Hud.h:329
virtual void Clear()
Remove all child elements.
Definition: Hud.h:278
Center-south, stacked left-to-right.
Definition: Hud.h:89
Center-north, stacked left-to-right.
Definition: Hud.h:81
boost::signals2::scoped_connection displayConfigChangedConn
Definition: Hud.h:331
std::array< hudChildList_t, HudAlignment::NUM > hudChildren
Definition: Hud.h:330
Southeast corner, stacked bottom-to-top.
Definition: Hud.h:86
Northwest corner, stacked left-to-right.
Definition: Hud.h:96
std::shared_ptr< Model::Track > ShareTrack() const
Definition: Hud.h:301
Definition: Announcement.h:24
Lower-right quadrant.
std::enable_if< std::is_base_of< HudDecor, T >::value, std::shared_ptr< T > >::type NewChild(Args &&...args)
Append a child element at this location.
Definition: Hud.h:198
HudCell cell
Definition: Hud.h:327
Base exception, providing constructors for setting the message.
Definition: Exception.h:42
Northwest corner, only top is visible.
Definition: Hud.h:95
A reference to a HUD location; useful for adding new HUD elements.
Definition: Hud.h:172
HudCell
Split-screen HUD grid locations.
Definition: HudCell.h:28
static type FromInt(int t)
Safely convert from an int.
Definition: Hud.h:107
HudLocProxy At(HudAlignment::type alignment)
Access a HUD location.
Definition: Hud.h:228
Northwest corner, stacked top-to-bottom.
Definition: Hud.h:94
Definition: Hud.h:68
std::enable_if< std::is_base_of< HudDecor, T >::value, std::shared_ptr< T > >::type NewHudChild(HudAlignment::type alignment, Args &&...args)
Append a child element to the end of the list.
Definition: Hud.h:247
Southwest corner, stacked left-to-right.
Definition: Hud.h:90
MR_Int64 timestamp_t
Definition: OS.h:55
HudAlignment::type alignment
Definition: Hud.h:205
void ForEachHudChild(Fn fn)
Definition: Hud.h:288
void RequestLayout()
Indicate that the current layout is out-of-date and needs to be adjusted.
Definition: ViewModel.h:79
Southwest corner, only top is visible.
Definition: Hud.h:91
Vec2 hudScale
Definition: Hud.h:328