00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00237
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
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 }