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