The Battle for Wesnoth  1.15.0+dev
widget.cpp
Go to the documentation of this file.
1 /*
2 
3  Copyright (C) 2003 - 2018 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 "widgets/widget.hpp"
19 #include "video.hpp"
20 #include "sdl/rect.hpp"
21 #include "tooltips.hpp"
22 
23 #include <cassert>
24 
25 namespace {
26  const SDL_Rect EmptyRect {-1234,-1234,0,0};
27 }
28 
29 namespace gui {
30 
31 bool widget::mouse_lock_ = false;
32 
33 widget::widget(CVideo& video, const bool auto_join)
34  : events::sdl_handler(auto_join), focus_(true), video_(&video), rect_(EmptyRect), needs_restore_(false),
35  state_(UNINIT), hidden_override_(false), enabled_(true), clip_(false),
36  clip_rect_(EmptyRect), volatile_(false), help_string_(0), mouse_lock_local_(false)
37 {
38 }
39 
41 {
42  bg_cancel();
44 }
45 
47 {
48  assert(!mouse_lock_);
49  mouse_lock_ = true;
50  mouse_lock_local_ = true;
51 }
52 
54 {
56  {
57  mouse_lock_local_ = false;
58  mouse_lock_ = false;
59  }
60 }
61 
63 {
64  return mouse_lock_ && !mouse_lock_local_;
65 }
66 
68 {
70  i_end = restorer_.end(); i != i_end; ++i)
71  i->cancel();
72  restorer_.clear();
73 }
74 
75 void widget::set_location(const SDL_Rect& rect)
76 {
77  if(rect_.x == rect.x && rect_.y == rect.y && rect_.w == rect.w && rect_.h == rect.h)
78  return;
79  if(state_ == UNINIT && rect.x != -1234 && rect.y != -1234)
80  state_ = DRAWN;
81 
82  bg_restore();
83  bg_cancel();
84  rect_ = rect;
85  set_dirty(true);
86  update_location(rect);
87 }
88 
89 void widget::update_location(const SDL_Rect& rect)
90 {
91  bg_register(rect);
92 }
93 
94 const SDL_Rect* widget::clip_rect() const
95 {
96  return clip_ ? &clip_rect_ : nullptr;
97 }
98 
99 void widget::bg_register(const SDL_Rect& rect)
100 {
101  restorer_.emplace_back(&video(), rect);
102 }
103 
104 void widget::set_location(int x, int y)
105 {
106  set_location({x, y, rect_.w, rect_.h});
107 }
108 
110 {
111  set_location({rect_.x, rect_.y, w, rect_.h});
112 }
113 
115 {
116  set_location({rect_.x, rect_.y, rect_.w, h});
117 }
118 
120 {
121  set_location({rect_.x, rect_.y, w, h});
122 }
123 
124 int widget::width() const
125 {
126  return rect_.w;
127 }
128 
129 int widget::height() const
130 {
131  return rect_.h;
132 }
133 
134 const SDL_Rect& widget::location() const
135 {
136  return rect_;
137 }
138 
140 {
141  if (focus)
142  events::focus_handler(this);
143  focus_ = focus;
144  set_dirty(true);
145 }
146 
147 bool widget::focus(const SDL_Event* event)
148 {
149  return events::has_focus(this, event) && focus_;
150 }
151 
152 void widget::hide(bool value)
153 {
154  if (value) {
155  if ((state_ == DIRTY || state_ == DRAWN) && !hidden_override_)
156  bg_restore();
157  state_ = HIDDEN;
158  } else if (state_ == HIDDEN) {
159  state_ = DRAWN;
160  if (!hidden_override_) {
161  bg_update();
162  set_dirty(true);
163  }
164  }
165 }
166 
167 void widget::hide_override(bool value) {
168  if (hidden_override_ != value) {
169  hidden_override_ = value;
170  if (state_ == DIRTY || state_ == DRAWN) {
171  if (value) {
172  bg_restore();
173  } else {
174  bg_update();
175  set_dirty(true);
176  }
177  }
178  }
179 }
180 
181 void widget::set_clip_rect(const SDL_Rect& rect)
182 {
183  clip_rect_ = rect;
184  clip_ = true;
185  set_dirty(true);
186 }
187 
188 bool widget::hidden() const
189 {
190  return (state_ == HIDDEN || hidden_override_ || state_ == UNINIT
192 }
193 
194 void widget::enable(bool new_val)
195 {
196  if (enabled_ != new_val) {
197  enabled_ = new_val;
198  set_dirty();
199  }
200 }
201 
202 bool widget::enabled() const
203 {
204  return enabled_;
205 }
206 
208 {
209  if ((dirty && (volatile_ || hidden_override_ || state_ != DRAWN)) || (!dirty && state_ != DIRTY))
210  return;
211 
212  state_ = dirty ? DIRTY : DRAWN;
213  if (!dirty)
214  needs_restore_ = true;
215 }
216 
217 bool widget::dirty() const
218 {
219  return state_ == DIRTY;
220 }
221 
222 const std::string& widget::id() const
223 {
224  return id_;
225 }
226 
227 void widget::set_id(const std::string& id)
228 {
229  if (id_.empty()){
230  id_ = id;
231  }
232 }
233 
235 {
237  i_end = restorer_.end(); i != i_end; ++i)
238  i->update();
239 }
240 
241 void widget::bg_restore() const
242 {
243  clip_rect_setter clipper(video().getSurface(), &clip_rect_, clip_);
244 
245  if (needs_restore_) {
246  for(std::vector< surface_restorer >::const_iterator i = restorer_.begin(),
247  i_end = restorer_.end(); i != i_end; ++i)
248  i->restore();
249  needs_restore_ = false;
250  }
251 }
252 
253 void widget::bg_restore(const SDL_Rect& rect) const
254 {
255  clip_rect_setter clipper(video().getSurface(), &clip_rect_, clip_);
256 
257  for(std::vector< surface_restorer >::const_iterator i = restorer_.begin(),
258  i_end = restorer_.end(); i != i_end; ++i)
259  i->restore(rect);
260 }
261 
262 void widget::set_volatile(bool val)
263 {
264  volatile_ = val;
265  if (volatile_ && state_ == DIRTY)
266  state_ = DRAWN;
267 }
268 
270 {
271  if (hidden() || !dirty())
272  return;
273 
274  bg_restore();
275 
276  clip_rect_setter clipper(video().getSurface(), &clip_rect_, clip_);
277 
278  draw_contents();
279 
280  set_dirty(false);
281 }
282 
284 {
285  if (!volatile_ || state_ != DRAWN || hidden_override_)
286  return;
287  state_ = DIRTY;
288  bg_update();
289  draw();
290 }
291 
293 {
294  if (!volatile_)
295  return;
296  bg_restore();
297 }
298 
299 void widget::set_help_string(const std::string& str)
300 {
301  help_text_ = str;
302 }
303 
304 void widget::set_tooltip_string(const std::string& str)
305 {
306  tooltip_text_ = str;
307 }
308 
309 void widget::process_help_string(int mousex, int mousey)
310 {
311  if (!hidden() && sdl::point_in_rect(mousex, mousey, rect_)) {
312  if(help_string_ == 0 && !help_text_.empty()) {
313  //std::cerr << "setting help string to '" << help_text_ << "'\n";
315  }
316  } else if(help_string_ > 0) {
318  help_string_ = 0;
319  }
320 }
321 
322 void widget::process_tooltip_string(int mousex, int mousey)
323 {
324  if (!hidden() && sdl::point_in_rect(mousex, mousey, rect_)) {
325  if (!tooltip_text_.empty())
327  }
328 }
329 
330 void widget::handle_event(const SDL_Event& event) {
331  if (event.type == DRAW_ALL_EVENT) {
332  set_dirty();
333  draw();
334  }
335 }
336 
337 void widget::handle_window_event(const SDL_Event& event) {
338  if (event.type == SDL_WINDOWEVENT) {
339  switch (event.window.event) {
340  case SDL_WINDOWEVENT_RESIZED:
341  case SDL_WINDOWEVENT_RESTORED:
342  case SDL_WINDOWEVENT_SHOWN:
343  case SDL_WINDOWEVENT_EXPOSED:
344  set_dirty();
345  }
346  }
347 }
348 
349 
350 }
void bg_cancel()
Definition: widget.cpp:67
bool enabled() const
Definition: widget.cpp:202
virtual void draw_contents()
Definition: widget.hpp:88
bool hidden_override_
Definition: widget.hpp:114
void aquire_mouse_lock()
Definition: widget.cpp:46
virtual void enable(bool new_val=true)
Definition: widget.cpp:194
void bg_update()
Definition: widget.cpp:234
bool hidden() const
Definition: widget.cpp:188
bool rects_overlap(const SDL_Rect &rect1, const SDL_Rect &rect2)
Tests whether two rectangles overlap.
Definition: rect.cpp:33
Definition: video.hpp:31
void set_clip_rect(const SDL_Rect &rect)
Definition: widget.cpp:181
General purpose widgets.
void set_width(int w)
Definition: widget.cpp:109
void set_focus(bool focus)
Definition: widget.cpp:139
SDL_Rect rect_
Definition: widget.hpp:110
#define h
bool dirty() const
Definition: widget.cpp:217
-file util.hpp
static bool mouse_lock_
Definition: widget.hpp:127
void set_measurements(int w, int h)
Definition: widget.cpp:119
virtual void process_help_string(int mousex, int mousey)
Definition: widget.cpp:309
widget(CVideo &video, const bool auto_join=true)
Definition: widget.cpp:33
void set_dirty(bool dirty=true)
Definition: widget.cpp:207
std::vector< surface_restorer > restorer_
Definition: widget.hpp:109
void focus_handler(const sdl_handler *ptr)
Definition: events.cpp:396
virtual void handle_event(const SDL_Event &)
Definition: widget.cpp:330
virtual void process_tooltip_string(int mousex, int mousey)
Definition: widget.cpp:322
bool focus(const SDL_Event *event)
Definition: widget.cpp:147
virtual void hide(bool value=true)
Definition: widget.cpp:152
const SDL_Rect & location() const
Definition: widget.cpp:134
enum gui::widget::@23 state_
void volatile_undraw()
Definition: widget.cpp:292
void free_mouse_lock()
Definition: widget.cpp:53
void volatile_draw()
Definition: widget.cpp:283
void bg_register(const SDL_Rect &rect)
Definition: widget.cpp:99
virtual void set_location(const SDL_Rect &rect)
Definition: widget.cpp:75
bool mouse_lock_local_
Definition: widget.hpp:126
bool point_in_rect(int x, int y, const SDL_Rect &rect)
Tests whether a point is inside a rectangle.
Definition: rect.cpp:22
#define DRAW_ALL_EVENT
Definition: events.hpp:29
void set_help_string(const std::string &str)
Definition: widget.cpp:299
std::size_t i
Definition: function.cpp:933
const std::string & id() const
Definition: widget.cpp:222
std::string id_
Definition: widget.hpp:124
bool focus_
Definition: widget.hpp:96
std::string help_text_
Definition: widget.hpp:121
int width() const
Definition: widget.cpp:124
virtual void draw()
Definition: widget.cpp:269
bool needs_restore_
Definition: widget.hpp:111
int w
int height() const
Definition: widget.cpp:129
bool enabled_
Definition: widget.hpp:115
void bg_restore() const
Definition: widget.cpp:241
bool mouse_locked() const
Definition: widget.cpp:62
void set_tooltip_string(const std::string &str)
Definition: widget.cpp:304
CVideo & video() const
Definition: widget.hpp:83
Handling of system events.
Definition: manager.hpp:41
bool volatile_
Definition: widget.hpp:119
int set_help_string(const std::string &str)
Displays a help string with the given text.
Definition: video.cpp:474
SDL_Rect clip_rect_
Definition: widget.hpp:117
void set_id(const std::string &id)
Definition: widget.cpp:227
Contains the SDL_Rect helper code.
bool clip_
Definition: widget.hpp:116
void set_volatile(bool val=true)
Definition: widget.cpp:262
bool has_focus(const sdl_handler *hand, const SDL_Event *event)
Definition: events.cpp:403
const SDL_Rect * clip_rect() const
Definition: widget.cpp:94
int help_string_
Definition: widget.hpp:123
virtual void update_location(const SDL_Rect &rect)
Definition: widget.cpp:89
virtual ~widget()
Definition: widget.cpp:40
void set_height(int h)
Definition: widget.cpp:114
int add_tooltip(const SDL_Rect &rect, const std::string &message, const std::string &action, bool use_markup, const surface &foreground)
Definition: tooltips.cpp:175
void hide_override(bool value=true)
Definition: widget.cpp:167
std::string::const_iterator iterator
Definition: tokenizer.hpp:24
virtual void handle_window_event(const SDL_Event &event)
Definition: widget.cpp:337
std::string tooltip_text_
Definition: widget.hpp:122
void clear_help_string(int handle)
Removes the help string with the given handle.
Definition: video.cpp:506