The Battle for Wesnoth  1.19.5+dev
floating_label.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2024
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include "color.hpp"
19 #include "sdl/point.hpp"
20 #include "sdl/rect.hpp"
21 #include "sdl/surface.hpp"
22 #include "sdl/texture.hpp"
23 
24 #include <chrono>
25 #include <string>
26 
27 namespace font {
28 
29 /**
30  * structure which will hide all current floating labels, and cause floating labels
31  * instantiated after it is created to be displayed
32  */
34 {
37 };
38 
40 
42 
44 {
45  using clock = std::chrono::steady_clock;
46 
47 public:
48  floating_label(const std::string& text);
49 
50  void set_font_size(int font_size) {font_size_ = font_size;}
51 
52  // set the location on the screen to display the text.
53  void set_position(double xpos, double ypos){
54  xpos_ = xpos;
55  ypos_ = ypos;
56  }
57  // set the amount to move the text each frame
58  void set_move(double xmove, double ymove){
59  xmove_ = xmove;
60  ymove_ = ymove;
61  }
62  // set the number of frames to display the text for, or -1 to display until removed
63  void set_lifetime(const std::chrono::milliseconds& lifetime, const std::chrono::milliseconds& fadeout = std::chrono::milliseconds{100});
64  void set_color(const color_t& color) {color_ = color;}
65  void set_bg_color(const color_t& bg_color) {
66  bgcolor_ = bg_color;
67  }
68  void set_border_size(int border) {border_ = border;}
69  // set width for word wrapping (use -1 to disable it)
70  void set_width(int w) {width_ = w;}
71  void set_height(int h) { height_ = h; }
72  void set_clip_rect(const SDL_Rect& r) {clip_rect_ = r;}
73  void set_alignment(ALIGN align) {align_ = align;}
75  void use_markup(bool b) {use_markup_ = b;}
76 
77  /** Mark the last drawn location as requiring redraw. */
78  void undraw();
79  /** Change the floating label's position. */
80  void move(double xmove, double ymove);
81  /** Finalize draw position and alpha, and queue redrawing if changed. */
82  void update(const clock::time_point& time);
83  /** Draw the label to the screen. */
84  void draw();
85 
86  /**
87  * Ensure a texture for this floating label exists, creating one if needed.
88  *
89  * @returns true if the texture exists, false in the case of failure.
90  */
91  bool create_texture();
92 
93  void clear_texture();
94 
95  /** Return the size of the label in drawing coordinates */
96  SDL_Point get_draw_size() const
97  {
98  return get_bg_rect({0, 0, tex_.w(), tex_.h()}).size();
99  }
100 
101  bool expired(const clock::time_point& time) const
102  {
103  return lifetime_ >= std::chrono::milliseconds{0} && get_time_alive(time) > lifetime_ + fadeout_;
104  }
105 
106  void show(const bool value) { visible_ = value; }
107 
108  LABEL_SCROLL_MODE scroll() const { return scroll_; }
109 
110  // TODO: Might be good to have more getters, right?
111  auto get_fade_time() const { return fadeout_; }
112 
113 private:
114 
115  std::chrono::milliseconds get_time_alive(const clock::time_point& current_time) const;
116  int xpos(std::size_t width) const;
117  point get_pos(const clock::time_point& time);
118  uint8_t get_alpha(const clock::time_point& time);
119  rect get_bg_rect(const rect& text_rect) const;
122  uint8_t alpha_;
123  std::chrono::milliseconds fadeout_;
124  clock::time_point time_start_;
125  std::string text_;
129  std::chrono::milliseconds lifetime_;
131  SDL_Rect clip_rect_;
132  bool visible_;
134  int border_;
137 };
138 
139 
140 /**
141  * add a label floating on the screen above everything else.
142  * @returns a handle to the label which can be used with other label functions
143  */
144 int add_floating_label(const floating_label& flabel);
145 
146 
147 /** moves the floating label given by 'handle' by (xmove,ymove) */
148 void move_floating_label(int handle, double xmove, double ymove);
149 
150 /** moves all floating labels that have 'scroll_mode' set to ANCHOR_LABEL_MAP */
151 void scroll_floating_labels(double xmove, double ymove);
152 
153 /** removes the floating label given by 'handle' from the screen */
154 /** if fadeout is given, the label fades out over that duration */
155 /** if fadeout is less than 0, it uses the fadeout setting from the label */
156 void remove_floating_label(int handle, const std::chrono::milliseconds& fadeout = std::chrono::milliseconds{0});
157 
158 /** hides or shows a floating label */
159 void show_floating_label(int handle, bool show);
160 
161 SDL_Rect get_floating_label_rect(int handle);
162 void draw_floating_labels();
164 
165 } // end namespace font
SDL_Point get_draw_size() const
Return the size of the label in drawing coordinates.
std::chrono::milliseconds lifetime_
void show(const bool value)
void set_move(double xmove, double ymove)
rect get_bg_rect(const rect &text_rect) const
LABEL_SCROLL_MODE scroll_
LABEL_SCROLL_MODE scroll() const
auto get_fade_time() const
clock::time_point time_start_
bool create_texture()
Ensure a texture for this floating label exists, creating one if needed.
void set_position(double xpos, double ypos)
point get_pos(const clock::time_point &time)
floating_label(const std::string &text)
std::chrono::milliseconds get_time_alive(const clock::time_point &current_time) const
void set_alignment(ALIGN align)
int xpos(std::size_t width) const
void update(const clock::time_point &time)
Finalize draw position and alpha, and queue redrawing if changed.
void set_lifetime(const std::chrono::milliseconds &lifetime, const std::chrono::milliseconds &fadeout=std::chrono::milliseconds{100})
std::chrono::milliseconds fadeout_
void set_color(const color_t &color)
void set_border_size(int border)
uint8_t get_alpha(const clock::time_point &time)
void move(double xmove, double ymove)
Change the floating label's position.
void set_clip_rect(const SDL_Rect &r)
void set_bg_color(const color_t &bg_color)
void set_scroll_mode(LABEL_SCROLL_MODE scroll)
bool expired(const clock::time_point &time) const
std::chrono::steady_clock clock
void draw()
Draw the label to the screen.
void undraw()
Mark the last drawn location as requiring redraw.
void set_font_size(int font_size)
Wrapper class to encapsulate creation and management of an SDL_Texture.
Definition: texture.hpp:33
int w() const
The draw-space width of the texture, in pixels.
Definition: texture.hpp:105
int h() const
The draw-space height of the texture, in pixels.
Definition: texture.hpp:114
@ border
The border of the map.
int w
Graphical text output.
int add_floating_label(const floating_label &flabel)
add a label floating on the screen above everything else.
void show_floating_label(int handle, bool value)
hides or shows a floating label
void scroll_floating_labels(double xmove, double ymove)
moves all floating labels that have 'scroll_mode' set to ANCHOR_LABEL_MAP
SDL_Rect get_floating_label_rect(int handle)
void remove_floating_label(int handle, const std::chrono::milliseconds &fadeout)
removes the floating label given by 'handle' from the screen
void update_floating_labels()
void move_floating_label(int handle, double xmove, double ymove)
moves the floating label given by 'handle' by (xmove,ymove)
void draw_floating_labels()
@ CENTER_ALIGN
@ ANCHOR_LABEL_SCREEN
@ ANCHOR_LABEL_MAP
void show(const std::string &window_id, const t_string &message, const point &mouse, const SDL_Rect &source_rect)
Shows a tip.
Definition: tooltip.cpp:64
std::shared_ptr< halo_record > handle
Definition: halo.hpp:31
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:85
Contains the SDL_Rect helper code.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:59
structure which will hide all current floating labels, and cause floating labels instantiated after i...
Holds a 2D point.
Definition: point.hpp:25
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:47
#define h
#define b