00001 #ifndef CCOMPONENT_H
00002 #define CCOMPONENT_H
00003
00011 #include <string>
00012 #include <list>
00013
00014 #include "citerator.h"
00015 #include "cevent.h"
00016 #include "cvideo.h"
00017 #include "cfont.h"
00018
00022 class ITickable {
00023 public:
00024 virtual void tick(unsigned long time) = 0;
00025 };
00026
00027 class CModel;
00028
00031 class IObserver {
00032 protected:
00033 IObserver() { }
00034 public:
00035 virtual ~IObserver() { }
00036
00039 virtual void update(CModel *model) = 0;
00040 };
00041
00045 class CModel {
00046 protected:
00048 std::list<IObserver *> observers;
00049
00050 public:
00052 virtual void attach(IObserver *o) { observers.push_back(o); o->update(this); }
00053
00055 virtual void detach(IObserver *o) { observers.remove(o); }
00056
00058 virtual void notify() {
00059 for (std::list<IObserver *>::iterator i = observers.begin(); i != observers.end(); i++) {
00060 (*i)->update(this);
00061 }
00062 }
00063 };
00064
00069 class CComponent {
00070 private:
00072 int is_visible;
00073
00074 protected:
00076 CComponent *parent;
00077
00078
00079 CRect absolute_bounding_rect;
00080
00081
00082 CRect local_bounding_rect;
00083
00087 virtual void do_draw(CSurface &surface, CRect &rect) { }
00088
00092 virtual int do_handle_event(CEvent &event) { return 0; }
00093
00094 CComponent(CComponent ©);
00095 virtual void add_dirty_rect(const CRect &r) { if (parent) parent->add_dirty_rect(r); }
00096
00097
00098
00099 void update_absolute_pos(CComponent *child) {
00100 child->set_absolute_pos(get_absolute_bounding_rect().pos + child->get_pos());
00101 }
00102
00103
00104
00105 void invalidate() { add_dirty_rect(get_absolute_bounding_rect()); }
00106
00107 public:
00108 CComponent() : is_visible(1), parent(0) { }
00109 virtual ~CComponent() { }
00110
00116 void redraw() { invalidate(); }
00117
00119 int visible() { return is_visible; }
00120
00122 void set_visible(int visibility) {
00123 if (is_visible != visibility) {
00124 is_visible = visibility;
00125 invalidate();
00126 }
00127 }
00128
00132 virtual void draw(CSurface &surface, CRect &rect) {
00133 if (is_visible && rect.intersects_with(get_absolute_bounding_rect())) {
00134 do_draw(surface, rect);
00135 }
00136 }
00137
00140 virtual int handle_event(CEvent &event) { return do_handle_event(event); }
00141
00143 virtual void set_pos(const CPoint &pos) {
00144
00145 invalidate();
00146
00147 local_bounding_rect.pos = pos;
00148 if (parent) parent->update_absolute_pos(this);
00149 redraw();
00150 }
00151
00156 virtual void set_absolute_pos(const CPoint &pos) {
00157 absolute_bounding_rect.pos = pos;
00158 }
00159
00161 void set_size(CPoint &size) {
00162 invalidate();
00163
00164 local_bounding_rect.size = absolute_bounding_rect.size = size;
00165 redraw();
00166 }
00167
00169 const CPoint &get_size() {
00170 return local_bounding_rect.size;
00171 }
00172
00174 void set_bounding_rect(CRect &rect) {
00175 set_pos(rect.pos);
00176 set_size(rect.size);
00177 }
00178
00180 const CPoint &get_absolute_pos() {
00181 return absolute_bounding_rect.pos;
00182 }
00183
00185 const CPoint &get_pos() {
00186 return local_bounding_rect.pos;
00187 }
00188
00191 const CRect &get_absolute_bounding_rect() {
00192 return absolute_bounding_rect;
00193 }
00194
00200 void set_parent(CComponent *n_parent) { this->parent = n_parent; }
00201 };
00202
00204 typedef std::deque<CComponent *> CComponentList;
00205
00214 class CPanel : public CComponent {
00215 protected:
00216
00217 CComponentList children;
00218
00219 public:
00222 virtual ~CPanel() { }
00223
00225 virtual void draw(CSurface &surface, CRect &rect);
00226
00228 virtual int handle_event(CEvent &event);
00229
00233 void add(CComponent &c) {
00234 c.set_parent(this);
00235 children.push_front(&c);
00236 update_absolute_pos(&c);
00237 c.redraw();
00238 }
00239
00241 virtual void set_pos(const CPoint &pos);
00242
00245 virtual void set_absolute_pos(const CPoint &pos);
00246 };
00247
00249 class CColoredPanel : public CPanel {
00250 private:
00251 CColor color;
00252
00253 public:
00255 CColoredPanel(CRect &bounding_rect, CColor color) : color(color) {
00256 set_bounding_rect(bounding_rect);
00257 }
00258
00260 void set_color(CColor color) {
00261 this->color = color;
00262 redraw();
00263 }
00264
00266 virtual void do_draw(CSurface &surface, CRect &rect) {
00267 surface.fill_rect(get_absolute_bounding_rect(), color);
00268 }
00269 };
00270
00272 class CTextLabel : public CComponent {
00273 private:
00274
00275 std::string text;
00276
00277
00278 CFont *font;
00279
00280 public:
00281 virtual ~CTextLabel() { }
00282
00284 CTextLabel(std::string str, CPoint &pos, CFont *font) : font(font) {
00285 set_pos(pos);
00286 set_text(str);
00287 }
00288
00291 void set_text(std::string str) {
00292 text = str;
00293
00294 CPoint new_size(font->get_string_size(text.c_str()));
00295
00296 set_size(new_size);
00297 }
00298
00301 virtual void do_draw(CSurface &surface, CRect &rect) {
00302
00303 font->draw_string(&surface, get_absolute_pos(), text.c_str());
00304 }
00305 };
00306
00307 #endif