00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "precomp.h"
00010 #include "API/Core/System/cl_assert.h"
00011 #include "API/GUI/gui_manager.h"
00012 #include "API/GUI/component_options.h"
00013 #include "component_generic.h"
00014 #include "component_manager_generic.h"
00015 #include <vector>
00016
00017 CL_Component::CL_Component(
00018 const CL_ComponentOptions &options,
00019 CL_Component *parent,
00020 CL_StyleManager *style)
00021 :
00022 impl(NULL)
00023 {
00024 impl = new CL_Component_Generic(this, CL_Rect(0,0,0,0), parent, style);
00025
00026 int x = 0, y = 0, width = 0, height = 0;
00027
00028 if (options.exists("x")) x = options.get_value_as_int("x");
00029 if (options.exists("y")) y = options.get_value_as_int("y");
00030 if (options.exists("width")) width = options.get_value_as_int("width");
00031 if (options.exists("height")) height = options.get_value_as_int("height");
00032
00033 set_position(CL_Rect(x, y, x + width, y + height));
00034
00035 if (options.exists("visible")) show(options.get_value_as_bool("visible"));
00036 if (options.exists("enabled")) enable(options.get_value_as_bool("enabled"));
00037
00038
00039
00040 if (get_style_manager() != NULL)
00041 get_style_manager()->connect_styles("component", options, this);
00042
00043 if (parent != NULL) parent->add_child(this);
00044 }
00045
00046 CL_Component::CL_Component(CL_Component *parent, CL_StyleManager *style)
00047 : impl(NULL)
00048 {
00049 impl = new CL_Component_Generic(this, CL_Rect(0,0,0,0), parent, style);
00050
00051 CL_ComponentOptions options;
00052 options.add_option_as_int("x", 0);
00053 options.add_option_as_int("y", 0);
00054 options.add_option_as_int("width", 0);
00055 options.add_option_as_int("height", 0);
00056
00057 if (style != NULL) style->connect_styles("component", options, this);
00058 if (parent != NULL) parent->add_child(this);
00059 }
00060
00061 CL_Component::CL_Component(const CL_Rect &pos, CL_Component *parent, CL_StyleManager *style)
00062 : impl(NULL)
00063 {
00064 impl = new CL_Component_Generic(this, pos, parent, style);
00065
00066 CL_ComponentOptions options;
00067 options.add_option_as_int("x", pos.x1);
00068 options.add_option_as_int("y", pos.y1);
00069 options.add_option_as_int("width", pos.x2 - pos.x1);
00070 options.add_option_as_int("height", pos.y2 - pos.y1);
00071
00072 if (style != NULL) style->connect_styles("component", options, this);
00073 if (parent != NULL) parent->add_child(this);
00074 }
00075
00076 CL_Component::~CL_Component()
00077 {
00078
00079 delete impl;
00080 }
00081
00082 CL_Component *CL_Component::get_parent() const
00083 {
00084 return impl->parent;
00085 }
00086
00087 bool CL_Component::has_child(CL_Component *component) const
00088 {
00089 for (
00090 std::list<CL_Component *>::iterator it = impl->children.begin();
00091 it != impl->children.end();
00092 it++)
00093 {
00094 if (*it == component || (*it)->has_child(component)) return true;
00095 }
00096
00097 return false;
00098 }
00099
00100 void CL_Component::add_components(CL_ComponentManager *component_manager)
00101 {
00102 std::vector<CL_Component *> components;
00103 ((CL_ComponentManager_Generic *) component_manager)->get_root_component_list(components);
00104
00105 for (
00106 std::vector<CL_Component *>::iterator it = components.begin();
00107 it != components.end();
00108 it++)
00109 {
00110 add_child(*it);
00111 }
00112 }
00113
00114 void CL_Component::add_child(CL_Component *child, bool delete_child)
00115 {
00116 if(has_child(child))
00117 return;
00118
00119 impl->children.push_back(child);
00120 child->set_parent(this);
00121
00122 if (delete_child) impl->delete_children.push_back(child);
00123
00124 impl->sig_child_add(child);
00125 }
00126
00127 void CL_Component::remove_child(CL_Component *child)
00128 {
00129 child->set_parent(NULL);
00130 impl->children.remove(child);
00131
00132 impl->sig_child_remove(child);
00133 }
00134
00135 CL_Rect CL_Component::get_children_rect()
00136 {
00137 CL_Rect rect(0, 0, 0, 0);
00138
00139 for (
00140 std::list<CL_Component *>::iterator it = impl->children.begin();
00141 it != impl->children.end();
00142 it++)
00143 {
00144 CL_Component *comp = (*it);
00145 CL_Rect childrect = comp->get_position();
00146
00147 if(childrect.x1 < rect.x1)
00148 rect.x1 = childrect.x1;
00149 if(childrect.y1 < rect.y1)
00150 rect.y1 = childrect.y1;
00151 if(childrect.x2 > rect.x2)
00152 rect.x2 = childrect.x2;
00153 if(childrect.y2 > rect.y2)
00154 rect.y2 = childrect.y2;
00155 }
00156
00157 return rect;
00158 }
00159
00160 void CL_Component::update()
00161 {
00162 impl->sig_begin_paint();
00163 impl->sig_paint();
00164
00165 for (
00166 std::list<CL_Component *>::iterator it = impl->children.begin();
00167 it != impl->children.end();
00168 it++)
00169 {
00170 if((*it)->is_visible()) (*it)->update();
00171 }
00172
00173 impl->sig_end_paint();
00174 }
00175
00176 CL_GUIManager *CL_Component::get_gui_manager() const
00177 {
00178 if (impl->gui != NULL) return impl->gui;
00179 if (impl->parent != NULL) return impl->parent->get_gui_manager();
00180 return NULL;
00181 }
00182
00183 CL_StyleManager *CL_Component::get_style_manager() const
00184 {
00185 return impl->style_manager;
00186 }
00187
00188 void CL_Component::set_gui_manager(CL_GUIManager *gui)
00189 {
00190 impl->gui = gui;
00191 }
00192
00193 CL_Component *CL_Component::get_root_parent()
00194 {
00195 if(impl->parent)
00196 return impl->parent->get_root_parent();
00197 else
00198 return this;
00199 }
00200
00201 bool CL_Component::is_visible() const
00202 {
00203 return impl->visible;
00204 }
00205
00206 void CL_Component::show(bool show)
00207 {
00208 impl->visible = show;
00209 }
00210
00211 bool CL_Component::is_enabled() const
00212 {
00213 return impl->enabled;
00214 }
00215
00216 void CL_Component::enable(bool enable)
00217 {
00218 impl->enabled = enable;
00219 }
00220
00221 void CL_Component::set_focus()
00222 {
00223 get_gui_manager()->set_focus(this);
00224 }
00225
00226 bool CL_Component::has_focus() const
00227 {
00228 return get_gui_manager()->get_focus() == this;
00229 }
00230
00231 CL_Rect CL_Component::get_screen_rect() const
00232 {
00233 if (impl->parent == NULL)
00234 {
00235 return impl->position;
00236 }
00237 else
00238 {
00239 CL_Rect r = impl->parent->get_screen_rect();
00240
00241 return CL_Rect(
00242 r.x1 + impl->position.x1,
00243 r.y1 + impl->position.y1,
00244 r.x1 + impl->position.x2,
00245 r.y1 + impl->position.y2);
00246 }
00247 }
00248
00249 bool CL_Component::is_mouse_captured() const
00250 {
00251 return impl->captured;
00252 }
00253
00254 void CL_Component::capture_mouse()
00255 {
00256 CL_GUIManager *gui = get_gui_manager();
00257 if (gui != NULL)
00258 {
00259 gui->gui_capture_mouse(this);
00260 impl->captured = true;
00261 }
00262 }
00263
00264 void CL_Component::release_mouse()
00265 {
00266 CL_GUIManager *gui = get_gui_manager();
00267 if (gui != NULL)
00268 {
00269 gui->gui_release_mouse();
00270 impl->captured = false;
00271 }
00272 }
00273
00274 void CL_Component::run(CL_GUIManager *parent)
00275 {
00276 CL_GUIManager modal_gui(parent, get_style_manager());
00277 modal_gui.add_child(this);
00278 modal_gui.run();
00279 }
00280
00281 int CL_Component::get_width() const
00282 {
00283 return impl->position.x2 - impl->position.x1;
00284 }
00285
00286 int CL_Component::get_height() const
00287 {
00288 return impl->position.y2 - impl->position.y1;
00289 }
00290
00291 bool CL_Component::is_popup() const
00292 {
00293 return impl->popup;
00294 }
00295
00296 void CL_Component::popup(bool popup)
00297 {
00298 impl->popup = popup;
00299 }
00300
00301 bool CL_Component::is_removeflag_set() const
00302 {
00303 return impl->removeflag;
00304 }
00305
00306 const CL_Rect &CL_Component::get_position() const
00307 {
00308 return impl->position;
00309 }
00310
00311 void CL_Component::set_position(const CL_Rect &new_pos)
00312 {
00313 impl->position = new_pos;
00314 }
00315
00316 void CL_Component::set_position(int new_x, int new_y)
00317 {
00318 impl->position.x2 = get_width() + new_x;
00319 impl->position.y2 = get_height() + new_y;
00320 impl->position.x1 = new_x;
00321 impl->position.y1 = new_y;
00322 }
00323
00324 void CL_Component::set_size(int new_width, int new_height)
00325 {
00326 int old_width = get_width();
00327 int old_height = get_height();
00328 impl->position.x2 = impl->position.x1 + new_width;
00329 impl->position.y2 = impl->position.y1 + new_height;
00330 impl->sig_resized(old_width, old_height);
00331 }
00332
00333 void CL_Component::set_parent(CL_Component *parent)
00334 {
00335 impl->parent = parent;
00336 }
00337
00338 void CL_Component::set_width(int width)
00339 {
00340 int old_width = get_width();
00341 impl->position.x2 = impl->position.x1 + width;
00342 impl->sig_resized(old_width, get_height());
00343 }
00344
00345 void CL_Component::set_height(int height)
00346 {
00347 int old_height = get_height();
00348 impl->position.y2 = impl->position.y1 + height;
00349 impl->sig_resized(get_width(), old_height);
00350 }
00351
00352 void CL_Component::quit()
00353 {
00354 get_gui_manager()->quit();
00355 }
00356
00357 void CL_Component::clear_removeflag()
00358 {
00359 impl->removeflag = false;
00360 }
00361
00362 void CL_Component::close()
00363 {
00364 show(false);
00365 impl->removeflag = true;
00366 set_gui_manager(NULL);
00367 }
00368
00369 CL_Component *CL_Component::get_component_at(int pos_x, int pos_y)
00370 {
00371 std::list<CL_Component *>::reverse_iterator it;
00372 for (it = impl->children.rbegin(); it != impl->children.rend(); it++)
00373 {
00374 CL_Component *cur_component = (*it);
00375 const CL_Rect &r = cur_component->get_position();
00376
00377 if (pos_x >= r.x1 && pos_x < r.x2 &&
00378 pos_y >= r.y1 && pos_y < r.y2)
00379 {
00380 return cur_component->get_component_at(pos_x - r.x1, pos_y - r.y1);
00381 }
00382 }
00383
00384 return this;
00385 }
00386
00387 std::list<CL_Component *> &CL_Component::get_children()
00388 {
00389 return impl->children;
00390 }
00391
00392 const std::list<CL_Component *> &CL_Component::get_children() const
00393 {
00394 return impl->children;
00395 }
00396
00397 void CL_Component::attach_style(CL_ComponentStyle *style)
00398 {
00399 impl->styles.push_back(style);
00400 }
00401
00402 void CL_Component::detach_style(CL_ComponentStyle *style)
00403 {
00404 impl->styles.remove(style);
00405 }
00406
00407
00408
00409 CL_Signal_v0 &CL_Component::sig_paint()
00410 {
00411 return impl->sig_paint;
00412 }
00413
00414 CL_Signal_v0 &CL_Component::sig_begin_paint()
00415 {
00416 return impl->sig_begin_paint;
00417 }
00418
00419 CL_Signal_v0 &CL_Component::sig_end_paint()
00420 {
00421 return impl->sig_end_paint;
00422 }
00423
00424 CL_Signal_v3<CL_Component *, CL_InputDevice *, CL_Key> &CL_Component::sig_key_down()
00425 {
00426 return impl->sig_key_down;
00427 }
00428
00429 CL_Signal_v3<CL_Component *, CL_InputDevice *, CL_Key> &CL_Component::sig_key_up()
00430 {
00431 return impl->sig_key_up;
00432 }
00433
00434 CL_Signal_v4<CL_Component *, CL_InputDevice *, int, int> &CL_Component::sig_mouse_moved()
00435 {
00436 return impl->sig_mouse_moved;
00437 }
00438
00439 CL_Signal_v0 &CL_Component::sig_got_focus()
00440 {
00441 return impl->sig_got_focus;
00442 }
00443
00444 CL_Signal_v0 &CL_Component::sig_lost_focus()
00445 {
00446 return impl->sig_lost_focus;
00447 }
00448
00449 CL_Signal_v2<int, int> &CL_Component::sig_resized()
00450 {
00451 return impl->sig_resized;
00452 }
00453
00454 CL_Signal_v0 &CL_Component::sig_mouse_entered()
00455 {
00456 return impl->sig_mouse_entered;
00457 }
00458
00459 CL_Signal_v0 &CL_Component::sig_mouse_left()
00460 {
00461 return impl->sig_mouse_left;
00462 }
00463
00464 CL_Signal_v2<int &, int &> &CL_Component::sig_transform_coords()
00465 {
00466 return impl->sig_transform_coords;
00467 }
00468
00469 CL_Signal_v1<CL_Component *> &CL_Component::sig_child_add()
00470 {
00471 return impl->sig_child_add;
00472 }
00473
00474 CL_Signal_v1<CL_Component *> &CL_Component::sig_child_remove()
00475 {
00476 return impl->sig_child_remove;
00477 }