The Battle for Wesnoth  1.17.8+dev
widget.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2022
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 #define GETTEXT_DOMAIN "wesnoth-lib"
17 
18 #include "draw.hpp"
19 #include "draw_manager.hpp"
20 #include "floating_label.hpp"
21 #include "widgets/widget.hpp"
22 #include "sdl/rect.hpp"
23 #include "tooltips.hpp"
24 
25 #include <cassert>
26 namespace {
27  const SDL_Rect EmptyRect {-1234,-1234,0,0};
28 }
29 
30 namespace gui {
31 
32 bool widget::mouse_lock_ = false;
33 
34 widget::widget(const bool auto_join)
35  : events::sdl_handler(auto_join), focus_(true), rect_(EmptyRect),
36  state_(UNINIT), enabled_(true), clip_(false),
37  clip_rect_(EmptyRect), has_help_(false), mouse_lock_local_(false)
38 {
39 }
40 
42 {
43  if (!hidden()) {
44  queue_redraw();
45  }
47 }
48 
50 {
51  assert(!mouse_lock_);
52  mouse_lock_ = true;
53  mouse_lock_local_ = true;
54 }
55 
57 {
59  {
60  mouse_lock_local_ = false;
61  mouse_lock_ = false;
62  }
63 }
64 
66 {
67  return mouse_lock_ && !mouse_lock_local_;
68 }
69 
70 void widget::set_location(const SDL_Rect& rect)
71 {
72  if(rect_ == rect) {
73  return;
74  }
75 
76  // If we were shown somewhere else, queue it to be cleared.
77  if(state_ == DIRTY || state_ == DRAWN) {
78  queue_redraw();
79  }
80 
81  if(state_ == UNINIT && rect.x != -1234 && rect.y != -1234)
82  state_ = DRAWN;
83 
84  rect_ = rect;
85  queue_redraw();
86  update_location(rect);
87 }
88 
90 {
91  // this basically happens in set_location, so there's nothing to do here.
92 }
93 
94 void widget::set_location(int x, int y)
95 {
96  set_location({x, y, rect_.w, rect_.h});
97 }
98 
100 {
101  set_location({rect_.x, rect_.y, w, rect_.h});
102 }
103 
105 {
106  set_location({rect_.x, rect_.y, rect_.w, h});
107 }
108 
110 {
111  set_location({rect_.x, rect_.y, w, h});
112 }
113 
114 int widget::width() const
115 {
116  return rect_.w;
117 }
118 
119 int widget::height() const
120 {
121  return rect_.h;
122 }
123 
124 const rect& widget::location() const
125 {
126  return rect_;
127 }
128 
130 {
131  if (focus)
132  events::focus_handler(this);
133  focus_ = focus;
134  queue_redraw();
135 }
136 
137 bool widget::focus(const SDL_Event* event)
138 {
139  return events::has_focus(this, event) && focus_;
140 }
141 
142 void widget::hide(bool value)
143 {
144  if (value) {
145  if (state_ == DIRTY || state_ == DRAWN) {
146  queue_redraw();
147  }
148  state_ = HIDDEN;
149  } else if (state_ == HIDDEN) {
150  state_ = DRAWN;
151  queue_redraw();
152  }
153 }
154 
155 void widget::set_clip_rect(const SDL_Rect& rect)
156 {
157  clip_rect_ = rect;
158  clip_ = true;
159  queue_redraw();
160 }
161 
162 bool widget::hidden() const
163 {
164  return (state_ == HIDDEN || state_ == UNINIT
165  || (clip_ && !rect_.overlaps(clip_rect_)));
166 }
167 
168 void widget::enable(bool new_val)
169 {
170  if (enabled_ != new_val) {
171  enabled_ = new_val;
172  queue_redraw();
173  }
174 }
175 
176 bool widget::enabled() const
177 {
178  return enabled_;
179 }
180 
182 {
183  if ((dirty && state_ != DRAWN) || (!dirty && state_ != DIRTY)) {
184  return;
185  }
186 
187  state_ = dirty ? DIRTY : DRAWN;
188 
189  if (dirty) {
190  queue_redraw();
191  }
192 }
193 
194 bool widget::dirty() const
195 {
196  return state_ == DIRTY;
197 }
198 
199 const std::string& widget::id() const
200 {
201  return id_;
202 }
203 
204 void widget::set_id(const std::string& id)
205 {
206  if (id_.empty()){
207  id_ = id;
208  }
209 }
210 
212 {
214 }
215 
217 {
219 }
220 
221 bool widget::expose(const rect& region)
222 {
223  if (hidden()) { return false; }
224  if (!rect_.overlaps(region)) { return false; }
225  if (clip_ && !clip_rect_.overlaps(region)) { return false; }
226 
227  draw();
228  return true;
229 }
230 
232 {
233  if (hidden()) {
234  return;
235  }
236 
237  if (clip_) {
238  auto clipper = draw::reduce_clip(clip_rect_);
239  draw_contents();
240  } else {
241  draw_contents();
242  }
243 
244  set_dirty(false);
245 }
246 
247 void widget::set_help_string(const std::string& str)
248 {
249  help_text_ = str;
250 }
251 
252 void widget::set_tooltip_string(const std::string& str)
253 {
254  tooltip_text_ = str;
255 }
256 
257 void widget::process_help_string(int mousex, int mousey)
258 {
259  if (!hidden() && rect_.contains(mousex, mousey)) {
260  if(!has_help_ && !help_text_.empty()) {
261  //PLAIN_LOG << "setting help string to '" << help_text_ << "'";
263  has_help_ = true;
264  }
265  } else if(has_help_) {
267  has_help_ = false;
268  }
269 }
270 
271 void widget::process_tooltip_string(int mousex, int mousey)
272 {
273  if (!hidden() && rect_.contains(mousex, mousey)) {
274  if (!tooltip_text_.empty())
276  }
277 }
278 
279 }
Drawing functions, for drawing things on the screen.
bool enabled() const
Definition: widget.cpp:176
virtual void draw_contents()
Definition: widget.hpp:90
int add_tooltip(const SDL_Rect &origin, const std::string &message, const std::string &action)
Definition: tooltips.cpp:237
void aquire_mouse_lock()
Definition: widget.cpp:49
virtual void enable(bool new_val=true)
Definition: widget.cpp:168
bool hidden() const
Definition: widget.cpp:162
void queue_redraw()
Indicate that the widget should be redrawn.
Definition: widget.cpp:216
void set_clip_rect(const SDL_Rect &rect)
Definition: widget.cpp:155
bool has_help_
Definition: widget.hpp:111
General purpose widgets.
enum gui::widget::@10 state_
void set_width(int w)
Definition: widget.cpp:99
void set_focus(bool focus)
Definition: widget.cpp:129
#define h
rect clip_rect_
Definition: widget.hpp:107
bool dirty() const
Definition: widget.cpp:194
widget(const bool auto_join=true)
Definition: widget.cpp:34
void set_help_string(const std::string &str)
Displays a help string with the given text.
bool contains(int x, int y) const
Whether the given point lies within the rectangle.
Definition: rect.cpp:54
static bool mouse_lock_
Definition: widget.hpp:115
virtual void layout() override
Called by draw_manager to validate layout.
Definition: widget.cpp:89
void rect(const SDL_Rect &rect)
Draw a rectangle.
Definition: draw.cpp:141
void set_measurements(int w, int h)
Definition: widget.cpp:109
void set_dirty(bool dirty=true)
Definition: widget.cpp:181
void clear_help_string()
Removes the help string.
void focus_handler(const sdl_handler *ptr)
Definition: events.cpp:404
bool focus(const SDL_Event *event)
Definition: widget.cpp:137
virtual void hide(bool value=true)
Definition: widget.cpp:142
void free_mouse_lock()
Definition: widget.cpp:56
const rect & location() const
Definition: widget.cpp:124
virtual void process_tooltip_string(int mousex, int mousey) override
Definition: widget.cpp:271
virtual void process_help_string(int mousex, int mousey) override
Definition: widget.cpp:257
virtual void set_location(const SDL_Rect &rect)
Definition: widget.cpp:70
bool mouse_lock_local_
Definition: widget.hpp:114
bool overlaps(const SDL_Rect &r) const
Whether the given rectangle and this rectangle overlap.
Definition: rect.cpp:74
void set_help_string(const std::string &str)
Definition: widget.cpp:247
virtual bool expose(const rect &region) override
Called by draw_manager when it believes a redraw is necessary.
Definition: widget.cpp:221
clip_setter reduce_clip(const SDL_Rect &clip)
Set the clipping area to the intersection of the current clipping area and the given rectangle...
Definition: draw.cpp:448
const std::string & id() const
Definition: widget.cpp:199
std::string id_
Definition: widget.hpp:112
bool focus_
Definition: widget.hpp:93
std::string help_text_
Definition: widget.hpp:109
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:46
rect rect_
Definition: widget.hpp:102
virtual void update_location(const SDL_Rect &)
Definition: widget.hpp:91
int width() const
Definition: widget.cpp:114
void draw()
Definition: widget.cpp:231
int w
int height() const
Definition: widget.cpp:119
bool enabled_
Definition: widget.hpp:105
bool mouse_locked() const
Definition: widget.cpp:65
void set_tooltip_string(const std::string &str)
Definition: widget.cpp:252
Handling of system events.
Definition: manager.hpp:43
void set_id(const std::string &id)
Definition: widget.cpp:204
Contains the SDL_Rect helper code.
bool clip_
Definition: widget.hpp:106
bool has_focus(const sdl_handler *hand, const SDL_Event *event)
Definition: events.cpp:411
virtual ~widget()
Definition: widget.cpp:41
void set_height(int h)
Definition: widget.cpp:104
void invalidate_region(const rect &region)
Mark a region of the screen as requiring redraw.
std::string tooltip_text_
Definition: widget.hpp:110