widget.cpp

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

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs