00001 #include "gui_frame.hpp"
00002 #include "gui_backdrop.hpp"
00003 #include "gui_layeredregion.hpp"
00004 #include "gui_out.hpp"
00005
00006 #include <xml_document.hpp>
00007 #include <utils_string.hpp>
00008
00009 namespace gui
00010 {
00011 void frame::parse_block(xml::block* pBlock)
00012 {
00013 parse_attributes_(pBlock);
00014
00015 parse_size_block_(pBlock);
00016 parse_resize_bounds_block_(pBlock);
00017 parse_anchor_block_(pBlock);
00018 parse_title_region_block_(pBlock);
00019 parse_backdrop_block_(pBlock);
00020 parse_hit_rect_insets_block_(pBlock);
00021
00022 parse_layers_block_(pBlock);
00023 parse_frames_block_(pBlock);
00024 parse_scripts_block_(pBlock);
00025 }
00026
00027 void frame::parse_attributes_(xml::block* pBlock)
00028 {
00029 std::string sParent = pBlock->get_attribute("parent");
00030 bool bVirtual = utils::string_to_bool(pBlock->get_attribute("virtual"));
00031
00032 if (!sParent.empty())
00033 {
00034 if (!pParent_)
00035 {
00036 uiobject* pParent = pManager_->get_uiobject_by_name(sParent);
00037 std::string sName = pBlock->get_attribute("name");
00038 if (!pManager_->check_uiobject_name(sName))
00039 {
00040 throw exception(pBlock->get_location(),
00041 "Can't create an uiobject with an incorrect name. Skipped."
00042 );
00043 }
00044
00045 if (!utils::has_no_content(sName))
00046 {
00047 if (pParent)
00048 {
00049 set_parent(pParent);
00050 if (bVirtual || pParent->is_virtual())
00051 set_virtual();
00052 set_name(sName);
00053 }
00054 else
00055 {
00056 if (bVirtual)
00057 set_virtual();
00058 set_name(sName);
00059
00060 gui::out << gui::warning << pBlock->get_location() << " : "
00061 << "Can't find \"" << get_name() << "\"'s parent : \"" << sParent << "\". "
00062 "No parent given to that widget." << std::endl;
00063 }
00064 }
00065 else
00066 {
00067 throw exception(pBlock->get_location(),
00068 "Can't create an uiobject with a blank name. Skipped."
00069 );
00070 }
00071 }
00072 else
00073 {
00074 if (bVirtual || pParent_->is_virtual())
00075 set_virtual();
00076
00077 set_name(pBlock->get_attribute("name"));
00078
00079 gui::out << gui::warning << pBlock->get_location() << " : "
00080 << "Can't use the \"parent\" attribute on \"" << get_name() << "\", "
00081 "because it is a nested uiobject. Attribute ignored." << std::endl;
00082 }
00083 }
00084 else
00085 {
00086 if (bVirtual || (pParent_ && pParent_->is_virtual()))
00087 set_virtual();
00088
00089 set_name(pBlock->get_attribute("name"));
00090 }
00091
00092 if (pManager_->get_uiobject_by_name(sName_))
00093 {
00094 throw exception(pBlock->get_location(),
00095 std::string(bVirtual ? "A virtual" : "An")+" object with the name \""+
00096 sName_+"\" already exists. Skipped."
00097 );
00098 }
00099
00100 pManager_->add_uiobject(this);
00101
00102 create_glue();
00103
00104 if (pParentFrame_)
00105 {
00106 pParentFrame_->add_child(this);
00107 set_level(pParentFrame_->get_frame_level() + 1);
00108 }
00109 else
00110 set_level(0);
00111
00112 std::string sInheritance = pBlock->get_attribute("inherits");
00113 if (!utils::has_no_content(sInheritance))
00114 {
00115 std::vector<std::string> lObjects = utils::cut(sInheritance, ",");
00116 std::vector<std::string>::iterator iter;
00117 foreach (iter, lObjects)
00118 {
00119 utils::trim(*iter, ' ');
00120 uiobject* pObj = pManager_->get_uiobject_by_name(*iter, true);
00121 if (pObj)
00122 {
00123 if (is_object_type(pObj->get_object_type()))
00124 {
00125
00126 copy_from(pObj);
00127 }
00128 else
00129 {
00130 gui::out << gui::warning << pBlock->get_location() << " : "
00131 << "\"" << sName_ << "\" (" << "gui::" << lType_.back() << ") cannot inherit "
00132 << "from \"" << *iter << "\" (" << pObj->get_object_type()
00133 << "). Inheritance skipped." << std::endl;
00134 }
00135 }
00136 else
00137 {
00138 bool bNonVirtual = false;
00139 if (pManager_->get_uiobject_by_name(*iter))
00140 bNonVirtual = true;
00141
00142 gui::out << gui::warning << pBlock->get_location() << " : "
00143 << "Couldn't find inherited object \"" << *iter << "\""
00144 << std::string(bNonVirtual ? " (object is not virtual)" : "")
00145 << ". Inheritance skipped." << std::endl;
00146 }
00147 }
00148 }
00149
00150 if (pBlock->is_provided("hidden") || !bInherits_)
00151 set_shown(!utils::string_to_bool(pBlock->get_attribute("hidden")));
00152
00153 if ((pBlock->is_provided("setAllPoints") || !bInherits_) &&
00154 (utils::string_to_bool(pBlock->get_attribute("setAllPoints"))))
00155 set_all_points("$parent");
00156
00157 if (pBlock->is_provided("alpha") || !bInherits_)
00158 set_alpha(utils::string_to_float(pBlock->get_attribute("alpha")));
00159 if (pBlock->is_provided("topLevel") || !bInherits_)
00160 set_top_level(utils::string_to_bool(pBlock->get_attribute("topLevel")));
00161 if (pBlock->is_provided("movable") || !bInherits_)
00162 set_movable(utils::string_to_bool(pBlock->get_attribute("movable")));
00163 if (pBlock->is_provided("resizable") || !bInherits_)
00164 set_resizable(utils::string_to_bool(pBlock->get_attribute("resizable")));
00165 if (pBlock->is_provided("frameStrata") || !bInherits_)
00166 set_frame_strata(pBlock->get_attribute("frameStrata"));
00167 if (pBlock->is_provided("frameLevel"))
00168 {
00169 if (!bVirtual_)
00170 {
00171 std::string sFrameLevel = pBlock->get_attribute("frameLevel");
00172 if (sFrameLevel != "PARENT")
00173 set_level(utils::string_to_int(sFrameLevel));
00174 }
00175 else
00176 {
00177 gui::out << gui::warning << pBlock->get_location() << " : "
00178 << "\"frameLevel\" is not allowed for virtual widgets. Ignored." << std::endl;
00179 }
00180 }
00181 if (pBlock->is_provided("enableMouse") || !bInherits_)
00182 enable_mouse(utils::string_to_bool(pBlock->get_attribute("enableMouse")));
00183 if (pBlock->is_provided("enableMouseWheel") || !bInherits_)
00184 enable_mouse_wheel(utils::string_to_bool(pBlock->get_attribute("enableMouseWheel")));
00185 if (pBlock->is_provided("enableKeyboard") || !bInherits_)
00186 enable_keyboard(utils::string_to_bool(pBlock->get_attribute("enableKeyboard")));
00187 if (pBlock->is_provided("clampedToScreen") || !bInherits_)
00188 set_clamped_to_screen(utils::string_to_bool(pBlock->get_attribute("clampedToScreen")));
00189 }
00190
00191 void frame::parse_resize_bounds_block_(xml::block* pBlock)
00192 {
00193 xml::block* pResizeBoundsBlock = pBlock->get_block("ResizeBounds");
00194 if (pResizeBoundsBlock)
00195 {
00196 xml::block* pMinBlock = pResizeBoundsBlock->get_block("Min");
00197 if (pMinBlock)
00198 {
00199 xml::block* pDimBlock = pMinBlock->get_radio_block();
00200 if (pDimBlock->get_name() == "AbsDimension")
00201 {
00202 set_min_resize(
00203 utils::string_to_int(pDimBlock->get_attribute("x")),
00204 utils::string_to_int(pDimBlock->get_attribute("y"))
00205 );
00206 }
00207 else if (pDimBlock->get_name() == "RelDimension")
00208 {
00209 gui::out << gui::warning << pDimBlock->get_location() << " : "
00210 << "\"RelDimension\" for ResizeBounds:Min is not yet supported. Skipped." << std::endl;
00211 }
00212 }
00213
00214 xml::block* pMaxBlock = pResizeBoundsBlock->get_block("Max");
00215 if (pMaxBlock)
00216 {
00217 xml::block* pDimBlock = pMaxBlock->get_radio_block();
00218 if (pDimBlock->get_name() == "AbsDimension")
00219 {
00220 set_max_resize(
00221 utils::string_to_int(pDimBlock->get_attribute("x")),
00222 utils::string_to_int(pDimBlock->get_attribute("y"))
00223 );
00224 }
00225 else if (pDimBlock->get_name() == "RelDimension")
00226 {
00227 gui::out << gui::warning << pDimBlock->get_location() << " : "
00228 << "\"RelDimension\" for ResizeBounds:Max is not yet supported. Skipped." << std::endl;
00229 }
00230 }
00231 }
00232 }
00233
00234 void frame::parse_title_region_block_(xml::block* pBlock)
00235 {
00236 xml::block* pTitleRegionBlock = pBlock->get_block("TitleRegion");
00237 if (pTitleRegionBlock)
00238 {
00239 create_title_region();
00240
00241 if (pTitleRegion_)
00242 pTitleRegion_->parse_block(pTitleRegionBlock);
00243 }
00244 }
00245
00246 void frame::parse_backdrop_block_(xml::block* pBlock)
00247 {
00248 xml::block* pBackdropBlock = pBlock->get_block("Backdrop");
00249 if (pBackdropBlock)
00250 {
00251 utils::refptr<backdrop> pBackdrop(new backdrop(this));
00252
00253 pBackdrop->set_background(pManager_->parse_file_name(
00254 pBackdropBlock->get_attribute("bgFile")
00255 ));
00256 pBackdrop->set_edge(pManager_->parse_file_name(
00257 pBackdropBlock->get_attribute("edgeFile")
00258 ));
00259
00260 pBackdrop->set_backgrond_tilling(utils::string_to_bool(pBackdropBlock->get_attribute("tile")));
00261
00262 xml::block* pBGInsetsBlock = pBackdropBlock->get_block("BackgroundInsets");
00263 if (pBGInsetsBlock)
00264 {
00265 xml::block* pInsetBlock = pBGInsetsBlock->get_radio_block();
00266 if (pInsetBlock->get_name() == "AbsInset")
00267 {
00268 pBackdrop->set_background_insets(
00269 utils::string_to_int(pInsetBlock->get_attribute("left")),
00270 utils::string_to_int(pInsetBlock->get_attribute("right")),
00271 utils::string_to_int(pInsetBlock->get_attribute("top")),
00272 utils::string_to_int(pInsetBlock->get_attribute("bottom"))
00273 );
00274 }
00275 else
00276 {
00277 gui::out << gui::warning << pInsetBlock->get_location() << " : "
00278 << "RelInset for Backdrop:BackgroundInsets is not yet supported (" << sName_ << ")." << std::endl;
00279 }
00280 }
00281
00282 xml::block* pEdgeInsetsBlock = pBackdropBlock->get_block("EdgeInsets");
00283 if (pEdgeInsetsBlock)
00284 {
00285 xml::block* pInsetBlock = pEdgeInsetsBlock->get_radio_block();
00286 if (pInsetBlock->get_name() == "AbsInset")
00287 {
00288 pBackdrop->set_edge_insets(
00289 utils::string_to_int(pInsetBlock->get_attribute("left")),
00290 utils::string_to_int(pInsetBlock->get_attribute("right")),
00291 utils::string_to_int(pInsetBlock->get_attribute("top")),
00292 utils::string_to_int(pInsetBlock->get_attribute("bottom"))
00293 );
00294 }
00295 else
00296 {
00297 gui::out << gui::warning << pInsetBlock->get_location() << " : "
00298 << "RelInset for Backdrop:BackgroundInsets is not yet supported (" << sName_ << ")." << std::endl;
00299 }
00300 }
00301
00302 xml::block* pColorBlock = pBackdropBlock->get_block("BackgroundColor");
00303 if (pColorBlock)
00304 {
00305 pBackdrop->set_background_color(color(
00306 utils::string_to_float(pColorBlock->get_attribute("r")),
00307 utils::string_to_float(pColorBlock->get_attribute("g")),
00308 utils::string_to_float(pColorBlock->get_attribute("b")),
00309 utils::string_to_float(pColorBlock->get_attribute("a"))
00310 ));
00311 }
00312
00313 pColorBlock = pBackdropBlock->get_block("EdgeColor");
00314 if (pColorBlock)
00315 {
00316 pBackdrop->set_edge_color(color(
00317 utils::string_to_float(pColorBlock->get_attribute("r")),
00318 utils::string_to_float(pColorBlock->get_attribute("g")),
00319 utils::string_to_float(pColorBlock->get_attribute("b")),
00320 utils::string_to_float(pColorBlock->get_attribute("a"))
00321 ));
00322 }
00323
00324 xml::block* pEdgeSizeBlock = pBackdropBlock->get_block("EdgeSize");
00325 if (pEdgeSizeBlock)
00326 {
00327 xml::block* pSizeBlock = pEdgeSizeBlock->get_radio_block();
00328 if (pSizeBlock->get_name() == "AbsValue")
00329 {
00330 pBackdrop->set_edge_size(utils::string_to_uint(pSizeBlock->get_attribute("x")));
00331 }
00332 else
00333 {
00334 gui::out << gui::warning << pSizeBlock->get_location() << " : "
00335 << "RelValue for Backdrop:EdgeSize is not yet supported (" << sName_ << ")." << std::endl;
00336 }
00337 }
00338
00339 xml::block* pTileSizeBlock = pBackdropBlock->get_block("TileSize");
00340 if (pTileSizeBlock)
00341 {
00342 xml::block* pTileBlock = pTileSizeBlock->get_radio_block();
00343 if (pTileBlock->get_name() == "AbsValue")
00344 pBackdrop->set_tile_size(utils::string_to_uint(pTileBlock->get_attribute("x")));
00345 else
00346 {
00347 gui::out << gui::warning << pTileBlock->get_location() << " : "
00348 << "RelValue for Backdrop:TileSize is not yet supported (" << sName_ << ")." << std::endl;
00349 }
00350 }
00351
00352 set_backdrop(pBackdrop);
00353 }
00354 }
00355
00356 void frame::parse_hit_rect_insets_block_(xml::block* pBlock)
00357 {
00358 xml::block* pHitRectBlock = pBlock->get_block("HitRectInsets");
00359 if (pHitRectBlock)
00360 {
00361 xml::block* pInsetBlock = pHitRectBlock->get_radio_block();
00362 if (pInsetBlock->get_name() == "AbsInset")
00363 {
00364 set_abs_hit_rect_insets(
00365 utils::string_to_int(pInsetBlock->get_attribute("left")),
00366 utils::string_to_int(pInsetBlock->get_attribute("right")),
00367 utils::string_to_int(pInsetBlock->get_attribute("top")),
00368 utils::string_to_int(pInsetBlock->get_attribute("bottom"))
00369 );
00370 }
00371 else if (pInsetBlock->get_name() == "RelInset")
00372 {
00373 set_rel_hit_rect_insets(
00374 utils::string_to_float(pInsetBlock->get_attribute("left")),
00375 utils::string_to_float(pInsetBlock->get_attribute("right")),
00376 utils::string_to_float(pInsetBlock->get_attribute("top")),
00377 utils::string_to_float(pInsetBlock->get_attribute("bottom"))
00378 );
00379 }
00380 }
00381 }
00382
00383 void frame::parse_layers_block_(xml::block* pBlock)
00384 {
00385 xml::block* pLayersBlock = pBlock->get_block("Layers");
00386 if (pLayersBlock)
00387 {
00388 xml::block* pLayerBlock;
00389 foreach_block (pLayerBlock, pLayersBlock)
00390 {
00391 std::string sLevel = pLayerBlock->get_attribute("level");
00392 xml::block* pRegionBlock;
00393 foreach_block (pRegionBlock, pLayerBlock)
00394 {
00395 layered_region* pRegion = pManager_->create_layered_region(pRegionBlock->get_name());
00396 if (pRegion)
00397 {
00398 try
00399 {
00400 pRegion->set_parent(this);
00401 pRegion->set_draw_layer(sLevel);
00402 pRegion->parse_block(pRegionBlock);
00403 }
00404 catch (const exception& e)
00405 {
00406 delete pRegion;
00407 gui::out << gui::error << e.get_description();
00408 }
00409 catch (...)
00410 {
00411 delete pRegion;
00412 throw;
00413 }
00414 }
00415 }
00416 }
00417 }
00418 }
00419
00420 void frame::parse_frames_block_(xml::block* pBlock)
00421 {
00422 xml::block* pFramesBlock = pBlock->get_block("Frames");
00423 if (pFramesBlock)
00424 {
00425 xml::block* pElemBlock;
00426 foreach_block (pElemBlock, pFramesBlock)
00427 {
00428 frame* pFrame = pManager_->create_frame(pElemBlock->get_name());
00429 if (pFrame)
00430 {
00431 try
00432 {
00433 pFrame->set_addon(pManager_->get_current_addon());
00434 pFrame->set_parent(this);
00435 pFrame->parse_block(pElemBlock);
00436 pFrame->notify_loaded();
00437 }
00438 catch (const exception& e)
00439 {
00440 delete pFrame;
00441 gui::out << gui::error << e.get_description();
00442 }
00443 catch (...)
00444 {
00445 delete pFrame;
00446 throw;
00447 }
00448 }
00449 }
00450 }
00451 }
00452
00453 void frame::parse_scripts_block_(xml::block* pBlock)
00454 {
00455 xml::block* pScriptsBlock = pBlock->get_block("Scripts");
00456 if (pScriptsBlock)
00457 {
00458 xml::block* pScriptBlock;
00459 foreach_block (pScriptBlock, pScriptsBlock)
00460 {
00461 define_script(
00462 pScriptBlock->get_name(), pScriptBlock->get_value(),
00463 pScriptBlock->get_file(), pScriptBlock->get_line_nbr()
00464 );
00465 }
00466 }
00467 }
00468 }