00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #define GETTEXT_DOMAIN "wesnoth-lib"
00017
00018 #include "global.hpp"
00019
00020 #include "widgets/widget.hpp"
00021 #include "video.hpp"
00022
00023 #include <cassert>
00024
00025 namespace {
00026 const SDL_Rect EmptyRect = {-1234,-1234,0,0};
00027 }
00028
00029 namespace gui {
00030
00031 bool widget::mouse_lock_ = false;
00032
00033 widget::widget(const widget &o)
00034 : events::handler(), focus_(o.focus_), video_(o.video_), restorer_(o.restorer_), rect_(o.rect_),
00035 needs_restore_(o.needs_restore_), state_(o.state_), hidden_override_(o.hidden_override_),
00036 enabled_(o.enabled_), clip_(o.clip_), clip_rect_(o.clip_rect_), volatile_(o.volatile_),
00037 help_text_(o.help_text_), help_string_(o.help_string_), id_(o.id_), mouse_lock_local_(o.mouse_lock_local_)
00038 {
00039 }
00040
00041 widget::widget(CVideo& video, const bool auto_join)
00042 : handler(auto_join), focus_(true), video_(&video), rect_(EmptyRect), needs_restore_(false),
00043 state_(UNINIT), hidden_override_(false), enabled_(true), clip_(false),
00044 clip_rect_(EmptyRect), volatile_(false), help_string_(0), mouse_lock_local_(false)
00045 {
00046 }
00047
00048 widget::~widget()
00049 {
00050 bg_cancel();
00051 free_mouse_lock();
00052 }
00053
00054 void widget::aquire_mouse_lock()
00055 {
00056 assert(!mouse_lock_);
00057 mouse_lock_ = true;
00058 mouse_lock_local_ = true;
00059 }
00060
00061 void widget::free_mouse_lock()
00062 {
00063 if (mouse_lock_local_)
00064 {
00065 mouse_lock_local_ = false;
00066 mouse_lock_ = false;
00067 }
00068 }
00069
00070 bool widget::mouse_locked() const
00071 {
00072 return mouse_lock_ && !mouse_lock_local_;
00073 }
00074
00075 void widget::bg_cancel()
00076 {
00077 for(std::vector< surface_restorer >::iterator i = restorer_.begin(),
00078 i_end = restorer_.end(); i != i_end; ++i)
00079 i->cancel();
00080 restorer_.clear();
00081 }
00082
00083 void widget::set_location(SDL_Rect const &rect)
00084 {
00085 if(rect_.x == rect.x && rect_.y == rect.y && rect_.w == rect.w && rect_.h == rect.h)
00086 return;
00087 if(state_ == UNINIT && rect.x != -1234 && rect.y != -1234)
00088 state_ = DRAWN;
00089
00090 bg_restore();
00091 bg_cancel();
00092 rect_ = rect;
00093 set_dirty(true);
00094 update_location(rect);
00095 }
00096
00097 void widget::update_location(SDL_Rect const &rect)
00098 {
00099 bg_register(rect);
00100 }
00101
00102 const SDL_Rect* widget::clip_rect() const
00103 {
00104 return clip_ ? &clip_rect_ : NULL;
00105 }
00106
00107 void widget::bg_register(SDL_Rect const &rect)
00108 {
00109 restorer_.push_back(surface_restorer(&video(), rect));
00110 }
00111
00112 void widget::set_location(int x, int y)
00113 {
00114 set_location(create_rect(x, y, rect_.w, rect_.h));
00115 }
00116
00117 void widget::set_width(unsigned w)
00118 {
00119 set_location(create_rect(rect_.x, rect_.y, w, rect_.h));
00120 }
00121
00122 void widget::set_height(unsigned h)
00123 {
00124 set_location(create_rect(rect_.x, rect_.y, rect_.w, h));
00125 }
00126
00127 void widget::set_measurements(unsigned w, unsigned h)
00128 {
00129 set_location(create_rect(rect_.x, rect_.y, w, h));
00130 }
00131
00132 unsigned widget::width() const
00133 {
00134 return rect_.w;
00135 }
00136
00137 unsigned widget::height() const
00138 {
00139 return rect_.h;
00140 }
00141
00142 const SDL_Rect& widget::location() const
00143 {
00144 return rect_;
00145 }
00146
00147 void widget::set_focus(bool focus)
00148 {
00149 if (focus)
00150 events::focus_handler(this);
00151 focus_ = focus;
00152 set_dirty(true);
00153 }
00154
00155 bool widget::focus(const SDL_Event* event)
00156 {
00157 return events::has_focus(this, event) && focus_;
00158 }
00159
00160 void widget::hide(bool value)
00161 {
00162 if (value) {
00163 if ((state_ == DIRTY || state_ == DRAWN) && !hidden_override_)
00164 bg_restore();
00165 state_ = HIDDEN;
00166 } else if (state_ == HIDDEN) {
00167 state_ = DRAWN;
00168 if (!hidden_override_) {
00169 bg_update();
00170 set_dirty(true);
00171 }
00172 }
00173 }
00174
00175 void widget::hide_override(bool value) {
00176 if (hidden_override_ != value) {
00177 hidden_override_ = value;
00178 if (state_ == DIRTY || state_ == DRAWN) {
00179 if (value) {
00180 bg_restore();
00181 } else {
00182 bg_update();
00183 set_dirty(true);
00184 }
00185 }
00186 }
00187 }
00188
00189 void widget::set_clip_rect(const SDL_Rect& rect)
00190 {
00191 clip_rect_ = rect;
00192 clip_ = true;
00193 set_dirty(true);
00194 }
00195
00196 bool widget::hidden() const
00197 {
00198 return (state_ == HIDDEN || hidden_override_ || state_ == UNINIT
00199 || (clip_ && !rects_overlap(clip_rect_, rect_)));
00200 }
00201
00202 void widget::enable(bool new_val)
00203 {
00204 if (enabled_ != new_val) {
00205 enabled_ = new_val;
00206 set_dirty();
00207 }
00208 }
00209
00210 bool widget::enabled() const
00211 {
00212 return enabled_;
00213 }
00214
00215 void widget::set_dirty(bool dirty)
00216 {
00217 if ((dirty && (volatile_ || hidden_override_ || state_ != DRAWN)) || (!dirty && state_ != DIRTY))
00218 return;
00219
00220 state_ = dirty ? DIRTY : DRAWN;
00221 if (!dirty)
00222 needs_restore_ = true;
00223 }
00224
00225 bool widget::dirty() const
00226 {
00227 return state_ == DIRTY;
00228 }
00229
00230 const std::string& widget::id() const
00231 {
00232 return id_;
00233 }
00234
00235 void widget::set_id(const std::string& id)
00236 {
00237 if (id_.empty()){
00238 id_ = id;
00239 }
00240 }
00241
00242 void widget::bg_update()
00243 {
00244 for(std::vector< surface_restorer >::iterator i = restorer_.begin(),
00245 i_end = restorer_.end(); i != i_end; ++i)
00246 i->update();
00247 }
00248
00249 void widget::bg_restore() const
00250 {
00251 clip_rect_setter clipper(video().getSurface(), &clip_rect_, clip_);
00252
00253 if (needs_restore_) {
00254 for(std::vector< surface_restorer >::const_iterator i = restorer_.begin(),
00255 i_end = restorer_.end(); i != i_end; ++i)
00256 i->restore();
00257 needs_restore_ = false;
00258 } else {
00259
00260
00261 update_rect(rect_);
00262 }
00263 }
00264
00265 void widget::bg_restore(SDL_Rect const &rect) const
00266 {
00267 clip_rect_setter clipper(video().getSurface(), &clip_rect_, clip_);
00268
00269 for(std::vector< surface_restorer >::const_iterator i = restorer_.begin(),
00270 i_end = restorer_.end(); i != i_end; ++i)
00271 i->restore(rect);
00272 }
00273
00274 void widget::set_volatile(bool val)
00275 {
00276 volatile_ = val;
00277 if (volatile_ && state_ == DIRTY)
00278 state_ = DRAWN;
00279 }
00280
00281 void widget::draw()
00282 {
00283 if (hidden() || !dirty())
00284 return;
00285
00286 bg_restore();
00287
00288 clip_rect_setter clipper(video().getSurface(), &clip_rect_, clip_);
00289
00290 draw_contents();
00291
00292 update_rect(rect_);
00293 set_dirty(false);
00294 }
00295
00296 void widget::volatile_draw()
00297 {
00298 if (!volatile_ || state_ != DRAWN || hidden_override_)
00299 return;
00300 state_ = DIRTY;
00301 bg_update();
00302 draw();
00303 }
00304
00305 void widget::volatile_undraw()
00306 {
00307 if (!volatile_)
00308 return;
00309 bg_restore();
00310 }
00311
00312 void widget::set_help_string(const std::string& str)
00313 {
00314 help_text_ = str;
00315 }
00316
00317 void widget::process_help_string(int mousex, int mousey)
00318 {
00319 if (!hidden() && point_in_rect(mousex, mousey, rect_)) {
00320 if(help_string_ == 0 && help_text_ != "") {
00321
00322 help_string_ = video().set_help_string(help_text_);
00323 }
00324 } else if(help_string_ > 0) {
00325 video().clear_help_string(help_string_);
00326 help_string_ = 0;
00327 }
00328 }
00329
00330 }