widgets/widget.cpp

Go to the documentation of this file.
00001 /* $Id: widget.cpp 52533 2012-01-07 02:35:17Z shadowmaster $
00002 
00003    Copyright (C) 2003 - 2012 by David White <dave@whitevine.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
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         //this function should be able to be relied upon to update the rectangle,
00260         //so do that even if we don't restore
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             //std::cerr << "setting help string to '" << help_text_ << "'\n";
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:00 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs