00001 #include "gui_manager.hpp"
00002
00003 #include "gui_anchor.hpp"
00004 #include "gui_uiobject.hpp"
00005 #include "gui_frame.hpp"
00006 #include "gui_focusframe.hpp"
00007 #include "gui_layeredregion.hpp"
00008 #include "gui_sprite.hpp"
00009 #include "gui_rendertarget.hpp"
00010 #include "gui_material.hpp"
00011 #include "gui_font.hpp"
00012 #include "gui_event.hpp"
00013 #include "gui_out.hpp"
00014 #include "gui_eventmanager.hpp"
00015 #include "input.hpp"
00016
00017 #include <luapp_state.hpp>
00018 #include <utils_string.hpp>
00019 #include <utils_filesystem.hpp>
00020 #include <fstream>
00021 #include <sstream>
00022
00023 namespace gui
00024 {
00025 int l_set_key_binding(lua_State* pLua);
00026 int l_create_frame(lua_State* pLua);
00027 int l_delete_frame(lua_State* pLua);
00028 int l_get_locale(lua_State* pLua);
00029 int l_log(lua_State* pLua);
00030
00031 manager::manager(const input::handler& mInputHandler, const std::string& sLocale,
00032 uint uiScreenWidth, uint uiScreenHeight, utils::refptr<manager_impl> pImpl) :
00033 event_receiver(nullptr), sUIVersion_("0001"),
00034 uiScreenWidth_(uiScreenWidth), uiScreenHeight_(uiScreenHeight),
00035 bClearFontsOnClose_(true), pLua_(nullptr), pLuaRegs_(nullptr), bClosed_(true),
00036 bLoadingUI_(false), bFirstIteration_(true), bInputEnabled_(true),
00037 pInputManager_(new input::manager(mInputHandler)),
00038 pCurrentAddOn_(nullptr), bBuildStrataList_(false), bObjectMoved_(false),
00039 pOveredFrame_(nullptr), bUpdateOveredFrame_(false), pFocusedFrame_(nullptr),
00040 pMovedObject_(nullptr), pSizedObject_(nullptr), fMouseMovementX_(0.0f),
00041 fMouseMovementY_(0.0f), pMovedAnchor_(nullptr), iMovementStartPositionX_(0),
00042 iMovementStartPositionY_(0), mConstraint_(CONSTRAINT_NONE), uiResizeStartW_(0),
00043 uiResizeStartH_(0), bResizeWidth_(false), bResizeHeight_(false), bResizeFromRight_(false),
00044 bResizeFromBottom_(false), uiFrameNumber_(0), bEnableCaching_(true),
00045 pRenderTarget_(nullptr), sLocale_(sLocale), pImpl_(pImpl)
00046 {
00047 pEventManager_ = utils::refptr<event_manager>(new event_manager());
00048 event_receiver::pEventManager_ = pEventManager_.get();
00049 pInputManager_->register_event_manager(pEventManager_);
00050 register_event("KEY_PRESSED");
00051 pImpl_->set_parent(this);
00052 }
00053
00054 manager::~manager()
00055 {
00056 close_ui();
00057
00058 pEventManager_ = nullptr;
00059 event_receiver::pEventManager_ = nullptr;
00060 }
00061
00062 utils::wptr<manager_impl> manager::get_impl()
00063 {
00064 return pImpl_;
00065 }
00066
00067 uint manager::get_screen_width() const
00068 {
00069 return uiScreenWidth_;
00070 }
00071
00072 uint manager::get_screen_height() const
00073 {
00074 return uiScreenHeight_;
00075 }
00076
00077 void manager::add_addon_directory(const std::string& sDirectory)
00078 {
00079 if (utils::find(lGUIDirectoryList_, sDirectory) == lGUIDirectoryList_.end())
00080 lGUIDirectoryList_.push_back(sDirectory);
00081 }
00082
00083 void manager::clear_addon_directory_list()
00084 {
00085 lGUIDirectoryList_.clear();
00086 }
00087
00088 bool manager::check_uiobject_name(const std::string& sName) const
00089 {
00090 if (utils::is_number(sName[0]))
00091 {
00092 gui::out << gui::error << "gui::manager : "
00093 << "A widget's name can't start by a number : \"" << sName
00094 << "\" is forbidden." << std::endl;
00095 return false;
00096 }
00097
00098 size_t uiPos = sName.find("$");
00099 if (uiPos != sName.npos && uiPos != 0)
00100 {
00101 gui::out << gui::error << "gui::manager : "
00102 << "A widget's name can't contain the character '$' except at the begining : \""
00103 << sName << "\" is forbidden." << std::endl;
00104 return false;
00105 }
00106
00107 std::string::const_iterator iterName;
00108 foreach (iterName, sName)
00109 {
00110 char c = *iterName;
00111 if (!isalnum(c) && c != '_' && c != '$')
00112 {
00113 gui::out << gui::error << "gui::manager : "
00114 << "A widget's name can only contain alpha numeric symbols, or underscores : \""
00115 << sName << "\" is forbidden." << std::endl;
00116 return false;
00117 }
00118 }
00119
00120 return true;
00121 }
00122
00123 uiobject* manager::create_uiobject(const std::string& sClassName)
00124 {
00125 if (sClassName == "Frame")
00126 return new frame(this);
00127 else if (sClassName == "FocusFrame")
00128 return new focus_frame(this);
00129 else
00130 {
00131 auto iterFrame = lCustomFrameList_.find(sClassName);
00132 if (iterFrame != lCustomFrameList_.end())
00133 return (*iterFrame->second)(this);
00134
00135 auto iterRegion = lCustomRegionList_.find(sClassName);
00136 if (iterRegion != lCustomRegionList_.end())
00137 return (*iterRegion->second)(this);
00138
00139 gui::out << gui::warning << "gui::manager : Unknown uiobject class : \"" << sClassName << "\"." << std::endl;
00140 return nullptr;
00141 }
00142 }
00143
00144 frame* manager::create_frame(const std::string& sClassName)
00145 {
00146 if (sClassName == "Frame")
00147 return new frame(this);
00148 else if (sClassName == "FocusFrame")
00149 return new focus_frame(this);
00150 else
00151 {
00152 auto iterFrame = lCustomFrameList_.find(sClassName);
00153 if (iterFrame != lCustomFrameList_.end())
00154 return (*iterFrame->second)(this);
00155
00156 gui::out << gui::warning << "gui::manager : Unknown Frame class : \"" << sClassName << "\"." << std::endl;
00157 return nullptr;
00158 }
00159 }
00160
00161 frame* manager::create_frame(const std::string& sClassName, const std::string& sName,
00162 frame* pParent, const std::string& sInheritance)
00163 {
00164 if (!check_uiobject_name(sName))
00165 return nullptr;
00166
00167 frame* pNewFrame = create_frame(sClassName);
00168 if (!pNewFrame)
00169 return nullptr;
00170
00171 pNewFrame->set_parent(pParent);
00172 pNewFrame->set_name(sName);
00173
00174 if (get_uiobject_by_name(pNewFrame->get_name()))
00175 {
00176 gui::out << gui::error << "gui::manager : "
00177 << "An object with the name \"" << pNewFrame->get_name() << "\" already exists." << std::endl;
00178 delete pNewFrame;
00179 return nullptr;
00180 }
00181
00182 add_uiobject(pNewFrame);
00183 pNewFrame->create_glue();
00184
00185 if (pParent)
00186 {
00187 pParent->add_child(pNewFrame);
00188 pNewFrame->set_level(pParent->get_frame_level() + 1);
00189 }
00190 else
00191 pNewFrame->set_level(0);
00192
00193 if (!utils::has_no_content(sInheritance))
00194 {
00195 std::vector<std::string> lObjects = utils::cut(sInheritance, ",");
00196 std::vector<std::string>::iterator iter;
00197 foreach (iter, lObjects)
00198 {
00199 utils::trim(*iter, ' ');
00200 uiobject* pObj = get_uiobject_by_name(*iter, true);
00201 if (pObj)
00202 {
00203 if (pNewFrame->is_object_type(pObj->get_object_type()))
00204 {
00205
00206 pNewFrame->copy_from(pObj);
00207 }
00208 else
00209 {
00210 gui::out << gui::warning << "gui::manager : "
00211 << "\"" << pNewFrame->get_name() << "\" (" << pNewFrame->get_object_type()
00212 << ") cannot inherit from \"" << *iter << "\" (" << pObj->get_object_type()
00213 << "). Inheritance skipped." << std::endl;
00214 }
00215 }
00216 else
00217 {
00218 gui::out << gui::warning << "gui::manager : "
00219 << "Couldn't find inherited object \"" << *iter << "\". Inheritance skipped." << std::endl;
00220 }
00221 }
00222 }
00223
00224 pNewFrame->set_newly_created();
00225 pNewFrame->notify_loaded();
00226
00227 return pNewFrame;
00228 }
00229
00230 layered_region* manager::create_layered_region(const std::string& sClassName)
00231 {
00232 auto iterRegion = lCustomRegionList_.find(sClassName);
00233 if (iterRegion != lCustomRegionList_.end())
00234 return (*iterRegion->second)(this);
00235
00236 gui::out << gui::warning << "gui::manager : Unknown layered_region class : \"" << sClassName << "\"." << std::endl;
00237 return nullptr;
00238 }
00239
00240 utils::refptr<sprite> manager::create_sprite(utils::refptr<material> pMat) const
00241 {
00242 utils::refptr<sprite> pSprite = pImpl_->create_sprite(pMat);
00243 if (pSprite)
00244 return pSprite;
00245 else
00246 return utils::refptr<sprite>(new sprite(this, pMat));
00247 }
00248
00249 utils::refptr<sprite> manager::create_sprite(utils::refptr<material> pMat, float fWidth, float fHeight) const
00250 {
00251 utils::refptr<sprite> pSprite = pImpl_->create_sprite(pMat, fWidth, fHeight);
00252 if (pSprite)
00253 return pSprite;
00254 else
00255 return utils::refptr<sprite>(new sprite(this, pMat, fWidth, fHeight));
00256 }
00257
00258 utils::refptr<sprite> manager::create_sprite(utils::refptr<material> pMat,
00259 float fU, float fV, float fWidth, float fHeight) const
00260 {
00261 utils::refptr<sprite> pSprite = pImpl_->create_sprite(pMat, fU, fV, fWidth, fHeight);
00262 if (pSprite)
00263 return pSprite;
00264 else
00265 return utils::refptr<sprite>(new sprite(this, pMat, fU, fV, fWidth, fHeight));
00266 }
00267
00268 utils::refptr<material> manager::create_material(const std::string& sFileName) const
00269 {
00270 return pImpl_->create_material(sFileName);
00271 }
00272
00273 utils::refptr<material> manager::create_material(const color& mColor) const
00274 {
00275 return pImpl_->create_material(mColor);
00276 }
00277
00278 utils::refptr<material> manager::create_material(utils::refptr<render_target> pRenderTarget) const
00279 {
00280 return pImpl_->create_material(pRenderTarget);
00281 }
00282
00283 utils::refptr<render_target> manager::create_render_target(uint uiWidth, uint uiHeight) const
00284 {
00285 return pImpl_->create_render_target(uiWidth, uiHeight);
00286 }
00287
00288 utils::refptr<font> manager::create_font(const std::string& sFontFile, uint uiSize) const
00289 {
00290 return pImpl_->create_font(sFontFile, uiSize);
00291 }
00292
00293 bool manager::add_uiobject(uiobject* pObj)
00294 {
00295 std::map<std::string, uiobject*>* lNamedList;
00296 if (pObj->is_virtual())
00297 {
00298 if (pObj->get_parent())
00299 {
00300 uint i = 0;
00301 std::map<uint, uiobject*>::iterator iterObj = lObjectList_.find(i);
00302 while (iterObj != lObjectList_.end())
00303 {
00304 ++i;
00305 iterObj = lObjectList_.find(i);
00306 }
00307 lObjectList_[i] = pObj;
00308 pObj->set_id(i);
00309
00310 return true;
00311 }
00312 else
00313 lNamedList = &lNamedVirtualObjectList_;
00314 }
00315 else
00316 lNamedList = &lNamedObjectList_;
00317
00318 if (pObj)
00319 {
00320 std::map<std::string, uiobject*>::iterator iterNamedObj = lNamedList->find(pObj->get_name());
00321 if (iterNamedObj == lNamedList->end())
00322 {
00323 uint i = 0;
00324 std::map<uint, uiobject*>::iterator iterObj = lObjectList_.find(i);
00325 while (iterObj != lObjectList_.end())
00326 {
00327 ++i;
00328 iterObj = lObjectList_.find(i);
00329 }
00330
00331 lObjectList_[i] = pObj;
00332 (*lNamedList)[pObj->get_name()] = pObj;
00333 pObj->set_id(i);
00334
00335 if (!pObj->is_virtual())
00336 {
00337 if (!pObj->get_parent())
00338 {
00339 lMainObjectList_[i] = pObj;
00340 fire_build_strata_list();
00341 }
00342
00343 frame* pFrame = dynamic_cast<frame*>(pObj);
00344 if (pFrame)
00345 lFrameList_[i] = pFrame;
00346 }
00347
00348 return true;
00349 }
00350 else
00351 {
00352 gui::out << gui::warning << "gui::manager : "
00353 << "A " << std::string(pObj->is_virtual() ? "virtual" : "") << " widget with the name \""
00354 << pObj->get_name() << "\" already exists." << std::endl;
00355 return false;
00356 }
00357 }
00358 else
00359 {
00360 gui::out << gui::error << "gui::manager : Adding a null widget." << std::endl;
00361 return false;
00362 }
00363 }
00364
00365 void manager::remove_uiobject(uiobject* pObj)
00366 {
00367 if (!pObj)
00368 return;
00369
00370 lObjectList_.erase(pObj->get_id());
00371
00372 if (!pObj->is_virtual())
00373 {
00374 lNamedObjectList_.erase(pObj->get_name());
00375
00376 if (!pObj->get_parent())
00377 lMainObjectList_.erase(pObj->get_id());
00378
00379 frame* pFrame = dynamic_cast<frame*>(pObj);
00380 if (pFrame)
00381 lFrameList_.erase(pObj->get_id());
00382 }
00383 else
00384 lNamedVirtualObjectList_.erase(pObj->get_name());
00385
00386 if (!pObj->is_manually_rendered())
00387 fire_build_strata_list();
00388
00389 if (pMovedObject_ == pObj)
00390 stop_moving(pObj);
00391
00392 if (pSizedObject_ == pObj)
00393 stop_sizing(pObj);
00394
00395 lRemovedObjectList_.push_back(pObj);
00396 }
00397
00398 void manager::remove_uiobject_(uiobject* pObj)
00399 {
00400 if (!pObj)
00401 return;
00402
00403 delete pObj;
00404 }
00405
00406 void manager::notify_object_has_parent(uiobject* pObj)
00407 {
00408 lMainObjectList_.erase(pObj->get_id());
00409 }
00410
00411 const uiobject* manager::get_uiobject(uint uiID) const
00412 {
00413 std::map<uint, uiobject*>::const_iterator iter = lObjectList_.find(uiID);
00414 if (iter != lObjectList_.end())
00415 return iter->second;
00416 else
00417 return nullptr;
00418 }
00419
00420 uiobject* manager::get_uiobject(uint uiID)
00421 {
00422 std::map<uint, uiobject*>::iterator iter = lObjectList_.find(uiID);
00423 if (iter != lObjectList_.end())
00424 return iter->second;
00425 else
00426 return nullptr;
00427 }
00428
00429 const uiobject* manager::get_uiobject_by_name(const std::string& sName, bool bVirtual) const
00430 {
00431 if (bVirtual)
00432 {
00433 std::map<std::string, uiobject*>::const_iterator iter = lNamedVirtualObjectList_.find(sName);
00434 if (iter != lNamedVirtualObjectList_.end())
00435 return iter->second;
00436 else
00437 return nullptr;
00438 }
00439 else
00440 {
00441 std::map<std::string, uiobject*>::const_iterator iter = lNamedObjectList_.find(sName);
00442 if (iter != lNamedObjectList_.end())
00443 return iter->second;
00444 else
00445 return nullptr;
00446 }
00447 }
00448
00449 uiobject* manager::get_uiobject_by_name(const std::string& sName, bool bVirtual)
00450 {
00451 if (bVirtual)
00452 {
00453 std::map<std::string, uiobject*>::iterator iter = lNamedVirtualObjectList_.find(sName);
00454 if (iter != lNamedVirtualObjectList_.end())
00455 return iter->second;
00456 else
00457 return nullptr;
00458 }
00459 else
00460 {
00461 std::map<std::string, uiobject*>::iterator iter = lNamedObjectList_.find(sName);
00462 if (iter != lNamedObjectList_.end())
00463 return iter->second;
00464 else
00465 return nullptr;
00466 }
00467 }
00468
00469 utils::wptr<lua::state> manager::get_lua()
00470 {
00471 return pLua_;
00472 }
00473
00474 void manager::load_addon_toc_(const std::string& sAddOnName, const std::string& sAddOnDirectory)
00475 {
00476 std::map<std::string, addon>& lAddOns = lAddOnList_[sAddOnDirectory];
00477 if (lAddOns.find(sAddOnName) == lAddOns.end())
00478 {
00479 addon mAddOn;
00480 mAddOn.bEnabled = true;
00481 mAddOn.sMainDirectory = utils::cut(sAddOnDirectory, "/").back();
00482 mAddOn.sDirectory = sAddOnDirectory + "/" + sAddOnName;
00483
00484 std::string sTOCFile = mAddOn.sDirectory + "/" + sAddOnName + ".toc";
00485 std::ifstream mFile(sTOCFile);
00486
00487 if (mFile.is_open())
00488 {
00489 while (!mFile.eof())
00490 {
00491 std::string sLine; getline(mFile, sLine);
00492 utils::replace(sLine, "\r", "");
00493 if (sLine[0] == '#' && sLine[1] == '#')
00494 {
00495 sLine.erase(0, 2);
00496 utils::trim(sLine, ' ');
00497 std::vector<std::string> lArgs = utils::cut(sLine, ":", 1);
00498 if (lArgs.size() == 2)
00499 {
00500 std::string sKey = lArgs[0];
00501 utils::trim(sKey, ' ');
00502 std::string sValue = lArgs[1];
00503 utils::trim(sValue, ' ');
00504 if (sKey == "Interface")
00505 {
00506 mAddOn.sUIVersion = sValue;
00507
00508 if (mAddOn.sUIVersion == sUIVersion_)
00509 mAddOn.bEnabled = true;
00510 else
00511 {
00512 gui::out << gui::warning << "gui::manager : "
00513 << "Wrong UI version for \"" << sAddOnName << "\" (got : "
00514 << mAddOn.sUIVersion << ", expected : " << sUIVersion_
00515 << "). AddOn disabled." << std::endl;
00516 mAddOn.bEnabled = false;
00517 }
00518 }
00519 else if (sKey == "Title")
00520 mAddOn.sName = sValue;
00521 else if (sKey == "Version")
00522 mAddOn.sVersion = sValue;
00523 else if (sKey == "Author")
00524 mAddOn.sAuthor = sValue;
00525 else if (sKey == "SavedVariables")
00526 {
00527 std::vector<std::string> lVariables = utils::cut(sValue, ",");
00528 std::vector<std::string>::iterator iterVar;
00529 foreach (iterVar, lVariables)
00530 {
00531 utils::trim(*iterVar, ' ');
00532 if (!utils::has_no_content(*iterVar))
00533 mAddOn.lSavedVariableList.push_back(*iterVar);
00534 }
00535 }
00536 }
00537 }
00538 else
00539 {
00540 utils::trim(sLine, ' ');
00541 if (sLine.find(".lua") != sLine.npos || sLine.find(".xml") != sLine.npos)
00542 mAddOn.lFileList.push_back(mAddOn.sDirectory + "/" + sLine);
00543 }
00544 }
00545
00546 mFile.close();
00547
00548 if (mAddOn.sName == "")
00549 gui::out << gui::error << "gui::manager : Missing addon name in " << sTOCFile << "." << std::endl;
00550 else
00551 lAddOns[sAddOnName] = mAddOn;
00552 }
00553 }
00554 }
00555
00556 void manager::load_addon_files_(addon* pAddOn)
00557 {
00558 pCurrentAddOn_ = pAddOn;
00559 std::vector<std::string>::iterator iterFile;
00560 foreach (iterFile, pAddOn->lFileList)
00561 {
00562 if (iterFile->find(".lua") != iterFile->npos)
00563 {
00564 try { pLua_->do_file(*iterFile); }
00565 catch (lua::exception& e)
00566 {
00567 std::string sError = e.get_description();
00568
00569 gui::out << gui::error << sError << std::endl;
00570
00571 event mEvent("LUA_ERROR");
00572 mEvent.add(sError);
00573 pEventManager_->fire_event(mEvent);
00574 }
00575 }
00576 else if (iterFile->find(".xml") != iterFile->npos)
00577 this->parse_xml_file_(*iterFile, pAddOn);
00578 }
00579
00580 std::string sSavedVariablesFile = "saves/interface/"+pAddOn->sMainDirectory+"/"+pAddOn->sName+".lua";
00581 if (utils::file_exists(sSavedVariablesFile))
00582 {
00583 try { pLua_->do_file(sSavedVariablesFile); }
00584 catch (lua::exception& e)
00585 {
00586 std::string sError = e.get_description();
00587
00588 gui::out << gui::error << sError << std::endl;
00589
00590 event mEvent("LUA_ERROR");
00591 mEvent.add(sError);
00592 pEventManager_->fire_event(mEvent);
00593 }
00594 }
00595
00596 event mEvent("ADDON_LOADED");
00597 mEvent.add(pAddOn->sName);
00598 pEventManager_->fire_event(mEvent);
00599 }
00600
00601 void manager::load_addon_directory_(const std::string& sDirectory)
00602 {
00603 std::vector<std::string> lDirs = utils::get_directory_list(sDirectory);
00604
00605 for (auto dir : lDirs)
00606 this->load_addon_toc_(dir, sDirectory);
00607
00608 std::vector<addon*> lCoreAddOnStack;
00609 std::vector<addon*> lAddOnStack;
00610 bool bCore = false;
00611
00612 std::map<std::string, addon>& lAddOns = lAddOnList_[sDirectory];
00613
00614 std::ifstream mFile(sDirectory + "/addons.txt");
00615 if (mFile.is_open())
00616 {
00617 while (!mFile.eof())
00618 {
00619 std::string sLine; getline(mFile, sLine);
00620 utils::replace(sLine, "\r", "");
00621 if (sLine[0] == '#')
00622 {
00623 sLine.erase(0, 1);
00624 utils::trim(sLine, ' ');
00625 if (sLine == "Core")
00626 bCore = true;
00627 else
00628 bCore = false;
00629 }
00630 else
00631 {
00632 std::vector<std::string> lArgs = utils::cut(sLine, ":", 1);
00633 if (lArgs.size() == 2)
00634 {
00635 std::string sKey = lArgs[0];
00636 utils::trim(sKey, ' ');
00637 std::string sValue = lArgs[1];
00638 utils::trim(sValue, ' ');
00639 auto iter = lAddOns.find(sKey);
00640 if (iter != lAddOns.end())
00641 {
00642 if (bCore)
00643 lCoreAddOnStack.push_back(&iter->second);
00644 else
00645 lAddOnStack.push_back(&iter->second);
00646
00647 if (sValue != "1")
00648 iter->second.bEnabled = false;
00649 }
00650 }
00651 }
00652 }
00653 mFile.close();
00654 }
00655
00656 for (auto addon : lCoreAddOnStack)
00657 {
00658 if (addon->bEnabled)
00659 this->load_addon_files_(addon);
00660 }
00661
00662 for (auto addon : lAddOnStack)
00663 {
00664 if (addon->bEnabled)
00665 this->load_addon_files_(addon);
00666 }
00667
00668 pCurrentAddOn_ = nullptr;
00669 }
00670
00671 void manager::save_variables_(addon* pAddOn)
00672 {
00673 if (!pAddOn->lSavedVariableList.empty())
00674 {
00675 if (!utils::make_directory("saves/interface/"+pAddOn->sMainDirectory))
00676 {
00677 gui::out << gui::error << "gui::manager : "
00678 "unable to create directory 'saves/interface/" <<
00679 pAddOn->sMainDirectory << "'" << std::endl;
00680 return;
00681 }
00682
00683 std::ofstream mFile("saves/interface/"+pAddOn->sMainDirectory+"/"+pAddOn->sName+".lua");
00684 std::vector<std::string>::iterator iterVariable;
00685 foreach (iterVariable, pAddOn->lSavedVariableList)
00686 {
00687 std::string sVariable = pLua_->serialize_global(*iterVariable);
00688 if (!sVariable.empty())
00689 mFile << sVariable << "\n";
00690 }
00691 }
00692 }
00693
00694 void gui_out(const std::string& sMessage)
00695 {
00696 gui::out << sMessage << std::endl;
00697 }
00698
00699 void manager::create_lua(std::function<void()> pLuaRegs)
00700 {
00701 if (!pLua_)
00702 {
00703 pLua_ = utils::refptr<lua::state>(new lua::state());
00704 pLua_->set_print_error_function(gui_out);
00705
00706 register_lua_manager_();
00707 pLua_->reg<lua_virtual_glue>();
00708 pLua_->reg<lua_uiobject>();
00709 pLua_->reg<lua_frame>();
00710 pLua_->reg<lua_focus_frame>();
00711 pLua_->reg<lua_layered_region>();
00712
00713 pLua_->reg("set_key_binding", l_set_key_binding);
00714 pLua_->reg("create_frame", l_create_frame);
00715 pLua_->reg("delete_frame", l_delete_frame);
00716 pLua_->reg("get_locale", l_get_locale);
00717 pLua_->reg("log", l_log);
00718
00719 pLuaRegs_ = pLuaRegs;
00720 if (pLuaRegs_)
00721 pLuaRegs_();
00722 }
00723 }
00724
00725 void manager::read_files()
00726 {
00727 if (bClosed_)
00728 {
00729 bLoadingUI_ = true;
00730
00731 std::vector<std::string>::iterator iterDirectory;
00732 foreach (iterDirectory, lGUIDirectoryList_)
00733 this->load_addon_directory_(*iterDirectory);
00734
00735 if (bEnableCaching_)
00736 {
00737
00738 std::map<uint, frame*>::iterator iterFrame;
00739 foreach (iterFrame, lFrameList_)
00740 {
00741 frame* pFrame = iterFrame->second;
00742 if (!pFrame->is_manually_rendered())
00743 lStrataList_[pFrame->get_frame_strata()];
00744 }
00745
00746
00747 std::map<frame_strata, strata>::iterator iterStrata;
00748 foreach (iterStrata, lStrataList_)
00749 create_strata_render_target_(iterStrata->second);
00750 }
00751
00752 bLoadingUI_ = false;
00753 bClosed_ = false;
00754 }
00755 }
00756
00757 void manager::load_ui()
00758 {
00759 create_lua(pLuaRegs_);
00760 read_files();
00761 }
00762
00763 void manager::close_ui()
00764 {
00765 if (!bClosed_)
00766 {
00767 std::vector<std::string>::iterator iterDirectory;
00768 foreach (iterDirectory, lGUIDirectoryList_)
00769 {
00770 std::map<std::string, addon>::iterator iterAddOn;
00771 foreach (iterAddOn, lAddOnList_[*iterDirectory])
00772 save_variables_(&iterAddOn->second);
00773 }
00774
00775 std::map<uint, uiobject*>::iterator iterObj;
00776 foreach (iterObj, lMainObjectList_)
00777 delete iterObj->second;
00778
00779 lMainObjectList_.clear();
00780 lObjectList_.clear();
00781 lNamedObjectList_.clear();
00782
00783 std::vector<uiobject*>::iterator iterRemoved;
00784 foreach (iterRemoved, lRemovedObjectList_)
00785 remove_uiobject_(*iterRemoved);
00786
00787 lRemovedObjectList_.clear();
00788
00789 std::map<std::string, uiobject*>::iterator iterVirtual;
00790 foreach (iterVirtual, lNamedVirtualObjectList_)
00791 delete iterVirtual->second;
00792
00793 lNamedVirtualObjectList_.clear();
00794
00795 lFrameList_.clear();
00796
00797 std::map<frame_strata, strata>::iterator iterStrata;
00798 foreach (iterStrata, lStrataList_)
00799 {
00800 iterStrata->second.lLevelList.clear();
00801 iterStrata->second.bRedraw = true;
00802 }
00803
00804 lAddOnList_.clear();
00805
00806 lStrataList_.clear();
00807 bBuildStrataList_ = true;
00808
00809 pLua_ = nullptr;
00810
00811 pOveredFrame_ = nullptr;
00812 bUpdateOveredFrame_ = false;
00813 pFocusedFrame_ = nullptr;
00814 pMovedObject_ = nullptr;
00815 pSizedObject_ = nullptr;
00816 pMovedAnchor_ = nullptr;
00817 bObjectMoved_ = false;
00818 fMouseMovementX_ = 0.0f;
00819 fMouseMovementY_ = 0.0f;
00820 iMovementStartPositionX_ = 0;
00821 iMovementStartPositionY_ = 0;
00822 mConstraint_ = CONSTRAINT_NONE;
00823 uiResizeStartW_ = 0;
00824 uiResizeStartH_ = 0;
00825 bResizeWidth_ = false;
00826 bResizeHeight_ = false;
00827 bResizeFromRight_ = false;
00828 bResizeFromBottom_ = false;
00829
00830 uiFrameNumber_ = 0;
00831
00832 lKeyBindingList_.clear();
00833
00834 bClosed_ = true;
00835 bLoadingUI_ = false;
00836 pCurrentAddOn_ = nullptr;
00837 }
00838 }
00839
00840 void manager::reload_ui()
00841 {
00842 gui::out << "Closing UI..." << std::endl;
00843 close_ui();
00844 gui::out << "Done. Loading UI..." << std::endl;
00845 load_ui();
00846 gui::out << "Done." << std::endl;
00847 }
00848
00849 void manager::render_ui() const
00850 {
00851 if (bEnableCaching_)
00852 {
00853 if (pSprite_)
00854 {
00855 begin();
00856 pSprite_->render(0, 0);
00857 end();
00858 }
00859 }
00860 else
00861 {
00862 begin();
00863 std::map<frame_strata, strata>::const_iterator iterStrata;
00864 foreach (iterStrata, lStrataList_)
00865 {
00866 const strata& mStrata = iterStrata->second;
00867 std::map<int, level>::const_iterator iterLevel;
00868 foreach (iterLevel, mStrata.lLevelList)
00869 {
00870 const level& mLevel = iterLevel->second;
00871
00872 std::vector<frame*>::const_iterator iterFrame;
00873 foreach (iterFrame, mLevel.lFrameList)
00874 {
00875 frame* pFrame = *iterFrame;
00876 if (!pFrame->is_newly_created())
00877 pFrame->render();
00878 }
00879 }
00880
00881 ++mStrata.uiRedrawCount;
00882 }
00883 end();
00884 }
00885 }
00886
00887 void manager::render_quad(const quad& mQuad) const
00888 {
00889 pImpl_->render_quad(mQuad);
00890 }
00891
00892 void manager::render_quads(const quad& mQuad, const std::vector<std::array<vertex,4>>& lQuadList) const
00893 {
00894 pImpl_->render_quads(mQuad, lQuadList);
00895 }
00896
00897 void manager::create_strata_render_target(frame_strata mframe_strata)
00898 {
00899 create_strata_render_target_(lStrataList_[mframe_strata]);
00900 }
00901
00902 void manager::create_strata_render_target_(strata& mStrata)
00903 {
00904 if (!pRenderTarget_)
00905 {
00906 try
00907 {
00908 pRenderTarget_ = create_render_target(uiScreenWidth_, uiScreenHeight_);
00909 }
00910 catch (utils::exception& e)
00911 {
00912 gui::out << gui::error << "gui::manager : "
00913 << "Unable to create render_target for GUI caching :\n" << e.get_description() << std::endl;
00914
00915 bEnableCaching_ = false;
00916 return;
00917 }
00918
00919 pSprite_ = create_sprite(create_material(pRenderTarget_));
00920 }
00921
00922 if (!mStrata.pRenderTarget)
00923 {
00924 try
00925 {
00926 mStrata.pRenderTarget = create_render_target(uiScreenWidth_, uiScreenHeight_);
00927 }
00928 catch (utils::exception& e)
00929 {
00930 gui::out << gui::error << "gui::manager : "
00931 << "Unable to create render_target for strata " << mStrata.uiID << " :\n"
00932 << e.get_description() << std::endl;
00933
00934 bEnableCaching_ = false;
00935 return;
00936 }
00937
00938 mStrata.pSprite = create_sprite(create_material(mStrata.pRenderTarget));
00939 }
00940 }
00941
00942 void manager::render_strata_(strata& mStrata)
00943 {
00944 if (!mStrata.pRenderTarget)
00945 create_strata_render_target_(mStrata);
00946
00947 if (mStrata.pRenderTarget)
00948 {
00949 begin(mStrata.pRenderTarget);
00950 mStrata.pRenderTarget->clear(color::EMPTY);
00951
00952 std::map<int, level>::const_iterator iterLevel;
00953 foreach (iterLevel, mStrata.lLevelList)
00954 {
00955 const level& mLevel = iterLevel->second;
00956
00957 std::vector<frame*>::const_iterator iterFrame;
00958 foreach (iterFrame, mLevel.lFrameList)
00959 {
00960 frame* pFrame = *iterFrame;
00961 if (!pFrame->is_newly_created())
00962 pFrame->render();
00963 }
00964 }
00965
00966 end();
00967
00968 ++mStrata.uiRedrawCount;
00969 }
00970 }
00971
00972 bool manager::is_loading_ui() const
00973 {
00974 return bLoadingUI_;
00975 }
00976
00977 void manager::fire_build_strata_list()
00978 {
00979 bBuildStrataList_ = true;
00980 }
00981
00982 void manager::update(float fDelta)
00983 {
00984
00985 #define DEBUG_LOG(msg)
00986
00987 if (lRemovedObjectList_.size() != 0)
00988 {
00989 DEBUG_LOG(" Removing uiobjects...");
00990 std::vector<uiobject*>::iterator iterRemoved;
00991 foreach (iterRemoved, lRemovedObjectList_)
00992 remove_uiobject_(*iterRemoved);
00993
00994 lRemovedObjectList_.clear();
00995 }
00996
00997 DEBUG_LOG(" Input...");
00998 pInputManager_->update(fDelta);
00999
01000 if (pMovedObject_ || pSizedObject_)
01001 {
01002 DEBUG_LOG(" Moved object...");
01003 fMouseMovementX_ += pInputManager_->get_mouse_raw_dx();
01004 fMouseMovementY_ += pInputManager_->get_mouse_raw_dy();
01005 }
01006
01007 if (pMovedObject_)
01008 {
01009 switch (mConstraint_)
01010 {
01011 case CONSTRAINT_NONE :
01012 pMovedAnchor_->set_abs_offset(
01013 iMovementStartPositionX_ + int(fMouseMovementX_),
01014 iMovementStartPositionY_ + int(fMouseMovementY_)
01015 );
01016 break;
01017 case CONSTRAINT_X :
01018 pMovedAnchor_->set_abs_offset(
01019 iMovementStartPositionX_ + int(fMouseMovementX_),
01020 iMovementStartPositionY_
01021 );
01022 break;
01023 case CONSTRAINT_Y :
01024 pMovedAnchor_->set_abs_offset(
01025 iMovementStartPositionX_,
01026 iMovementStartPositionY_ + int(fMouseMovementY_)
01027 );
01028 break;
01029 default : break;
01030 }
01031
01032 if (pApplyConstraintFunc_)
01033 pApplyConstraintFunc_();
01034
01035 pMovedObject_->fire_update_borders();
01036 }
01037 else if (pSizedObject_)
01038 {
01039 if (bResizeWidth_)
01040 {
01041 uint uiWidth;
01042 if (bResizeFromRight_)
01043 uiWidth = std::max(0, int(uiResizeStartW_) + int(fMouseMovementX_));
01044 else
01045 uiWidth = std::max(0, int(uiResizeStartW_) - int(fMouseMovementX_));
01046
01047 pSizedObject_->set_abs_width(uiWidth);
01048 }
01049
01050 if (bResizeHeight_)
01051 {
01052 uint uiHeight;
01053 if (bResizeFromBottom_)
01054 uiHeight = std::max(0, int(uiResizeStartH_) + int(fMouseMovementY_));
01055 else
01056 uiHeight = std::max(0, int(uiResizeStartH_) - int(fMouseMovementY_));
01057
01058 pSizedObject_->set_abs_height(uiHeight);
01059 }
01060 }
01061
01062 DEBUG_LOG(" Update anchors...");
01063
01064 std::map<uint, uiobject*>::iterator iterObj;
01065 foreach (iterObj, lObjectList_)
01066 {
01067 if (!iterObj->second->is_virtual())
01068 iterObj->second->update_anchors();
01069 }
01070
01071 DEBUG_LOG(" Update widgets...");
01072
01073 foreach (iterObj, lMainObjectList_)
01074 {
01075 if (!iterObj->second->is_virtual())
01076 iterObj->second->update(fDelta);
01077 }
01078
01079 if (bBuildStrataList_)
01080 {
01081 DEBUG_LOG(" Build strata...");
01082 std::map<frame_strata, strata>::iterator iterStrata;
01083 foreach (iterStrata, lStrataList_)
01084 {
01085 iterStrata->second.lLevelList.clear();
01086 iterStrata->second.bRedraw = true;
01087 }
01088
01089 std::map<uint, frame*>::iterator iterFrame;
01090 foreach (iterFrame, lFrameList_)
01091 {
01092 frame* pFrame = iterFrame->second;
01093 if (!pFrame->is_manually_rendered())
01094 {
01095 strata& mStrata = lStrataList_[pFrame->get_frame_strata()];
01096 mStrata.lLevelList[pFrame->get_frame_level()].lFrameList.push_back(pFrame);
01097
01098 mStrata.uiID = pFrame->get_frame_strata();
01099 }
01100 }
01101 }
01102
01103 if (bEnableCaching_)
01104 {
01105 DEBUG_LOG(" Redraw strata...");
01106 bool bRedraw;
01107 std::map<frame_strata, strata>::iterator iterStrata;
01108 foreach (iterStrata, lStrataList_)
01109 {
01110 strata& mStrata = iterStrata->second;
01111
01112 if (mStrata.bRedraw)
01113 {
01114 render_strata_(mStrata);
01115 bRedraw = true;
01116 }
01117
01118 mStrata.bRedraw = false;
01119 }
01120
01121 if (bRedraw && pRenderTarget_)
01122 {
01123 begin(pRenderTarget_);
01124 pRenderTarget_->clear(color::EMPTY);
01125
01126 std::map<frame_strata, strata>::const_iterator iterStrata;
01127 foreach (iterStrata, lStrataList_)
01128 {
01129 if (iterStrata->second.pSprite)
01130 iterStrata->second.pSprite->render(0, 0);
01131 }
01132
01133 end();
01134 }
01135 }
01136
01137 if (bBuildStrataList_ || bObjectMoved_ ||
01138 (pInputManager_->get_mouse_raw_dx() != 0.0f) ||
01139 (pInputManager_->get_mouse_raw_dy() != 0.0f))
01140 bUpdateOveredFrame_ = true;
01141
01142 if (bUpdateOveredFrame_ && bInputEnabled_)
01143 {
01144 DEBUG_LOG(" Update overed frame...");
01145 int iX = pInputManager_->get_mouse_x();
01146 int iY = pInputManager_->get_mouse_y();
01147
01148 frame* pOveredFrame = nullptr;
01149
01150 std::map<frame_strata, strata>::const_iterator iterStrata = lStrataList_.end();
01151 while (iterStrata != lStrataList_.begin() && !pOveredFrame)
01152 {
01153 --iterStrata;
01154 const strata& mStrata = iterStrata->second;
01155
01156 std::map<int, level>::const_iterator iterLevel = mStrata.lLevelList.end();
01157 while (iterLevel != mStrata.lLevelList.begin() && !pOveredFrame)
01158 {
01159 --iterLevel;
01160 const level& mLevel = iterLevel->second;
01161
01162 std::vector<frame*>::const_iterator iterFrame;
01163 foreach (iterFrame, mLevel.lFrameList)
01164 {
01165 frame* pFrame = *iterFrame;
01166 if (pFrame->is_mouse_enabled() && pFrame->is_visible() && pFrame->is_in_frame(iX, iY))
01167 {
01168 pOveredFrame = pFrame;
01169 break;
01170 }
01171 }
01172 }
01173 }
01174
01175 set_overed_frame_(pOveredFrame, iX, iY);
01176
01177 bUpdateOveredFrame_ = false;
01178 }
01179
01180 bObjectMoved_ = false;
01181 bBuildStrataList_ = false;
01182
01183 if (bFirstIteration_)
01184 {
01185 DEBUG_LOG(" Entering world...");
01186 pEventManager_->fire_event(event("ENTERING_WORLD"));
01187 bFirstIteration_ = false;
01188 }
01189
01190 ++uiFrameNumber_;
01191 pEventManager_->frame_ended();
01192 }
01193
01194 void manager::set_overed_frame_(frame* pFrame, int iX, int iY)
01195 {
01196 if (pFrame && !pFrame->is_world_input_allowed())
01197 pInputManager_->block_input("WORLD");
01198 else
01199 pInputManager_->allow_input("WORLD");
01200
01201 if (pFrame != pOveredFrame_)
01202 {
01203 if (pOveredFrame_)
01204 pOveredFrame_->notify_mouse_in_frame(false, iX, iY);
01205
01206 pOveredFrame_ = pFrame;
01207 }
01208
01209 if (pOveredFrame_)
01210 pOveredFrame_->notify_mouse_in_frame(true, iX, iY);
01211 }
01212
01213 void manager::start_moving(uiobject* pObj, anchor* pAnchor, constraint mConstraint, std::function<void()> pApplyConstraintFunc)
01214 {
01215 pSizedObject_ = nullptr;
01216 pMovedObject_ = pObj;
01217 fMouseMovementX_ = 0.0f;
01218 fMouseMovementY_ = 0.0f;
01219
01220 if (pMovedObject_)
01221 {
01222 mConstraint_ = mConstraint;
01223 pApplyConstraintFunc_ = pApplyConstraintFunc;
01224 if (pAnchor)
01225 {
01226 pMovedAnchor_ = pAnchor;
01227 iMovementStartPositionX_ = pMovedAnchor_->get_abs_offset_x();
01228 iMovementStartPositionY_ = pMovedAnchor_->get_abs_offset_y();
01229 }
01230 else
01231 {
01232 pMovedObject_->clear_all_points();
01233 const std::array<int,4>& lBorders = pMovedObject_->get_borders();
01234 pMovedObject_->set_abs_point(
01235 ANCHOR_TOPLEFT, "", ANCHOR_TOPLEFT,
01236 lBorders[BORDER_LEFT], lBorders[BORDER_TOP]
01237 );
01238 pMovedAnchor_ = pMovedObject_->modify_point(ANCHOR_TOPLEFT);
01239
01240 iMovementStartPositionX_ = lBorders[BORDER_LEFT];
01241 iMovementStartPositionY_ = lBorders[BORDER_TOP];
01242 }
01243 }
01244 }
01245
01246 void manager::stop_moving(uiobject* pObj)
01247 {
01248 if (pMovedObject_ == pObj)
01249 {
01250 pMovedObject_ = nullptr;
01251 pMovedAnchor_ = nullptr;
01252 }
01253 }
01254
01255 bool manager::is_moving(uiobject* pObj) const
01256 {
01257 return (pMovedObject_ == pObj);
01258 }
01259
01260 void manager::start_sizing(uiobject* pObj, anchor_point mPoint)
01261 {
01262 pMovedObject_ = nullptr;
01263 pSizedObject_ = pObj;
01264 fMouseMovementX_ = 0.0f;
01265 fMouseMovementY_ = 0.0f;
01266
01267 if (pSizedObject_)
01268 {
01269 const std::array<int,4>& lBorders = pSizedObject_->get_borders();
01270
01271 anchor_point mOppositePoint = ANCHOR_CENTER;
01272 int iOffX = 0;
01273 int iOffY = 0;
01274 switch (mPoint)
01275 {
01276 case ANCHOR_TOPLEFT :
01277 case ANCHOR_TOP :
01278 mOppositePoint = ANCHOR_BOTTOMRIGHT;
01279 iOffX = lBorders[BORDER_RIGHT];
01280 iOffY = lBorders[BORDER_BOTTOM];
01281 bResizeFromRight_ = false;
01282 bResizeFromBottom_ = false;
01283 break;
01284 case ANCHOR_TOPRIGHT :
01285 case ANCHOR_RIGHT :
01286 mOppositePoint = ANCHOR_BOTTOMLEFT;
01287 iOffX = lBorders[BORDER_LEFT];
01288 iOffY = lBorders[BORDER_BOTTOM];
01289 bResizeFromRight_ = true;
01290 bResizeFromBottom_ = false;
01291 break;
01292 case ANCHOR_BOTTOMRIGHT :
01293 case ANCHOR_BOTTOM :
01294 mOppositePoint = ANCHOR_TOPLEFT;
01295 iOffX = lBorders[BORDER_LEFT];
01296 iOffY = lBorders[BORDER_TOP];
01297 bResizeFromRight_ = true;
01298 bResizeFromBottom_ = true;
01299 break;
01300 case ANCHOR_BOTTOMLEFT :
01301 case ANCHOR_LEFT :
01302 mOppositePoint = ANCHOR_TOPRIGHT;
01303 iOffX = lBorders[BORDER_RIGHT];
01304 iOffY = lBorders[BORDER_TOP];
01305 bResizeFromRight_ = false;
01306 bResizeFromBottom_ = true;
01307 break;
01308 case ANCHOR_CENTER :
01309 gui::out << gui::error << "gui::manager : "
01310 << "Can't resize \"" << pObj->get_name() << "\" from its center." << std::endl;
01311 pSizedObject_ = nullptr;
01312 return;
01313 }
01314
01315 pSizedObject_->clear_all_points();
01316 pSizedObject_->set_abs_point(mOppositePoint, "", ANCHOR_TOPLEFT, iOffX, iOffY);
01317
01318 uiResizeStartW_ = pSizedObject_->get_abs_width();
01319 uiResizeStartH_ = pSizedObject_->get_abs_height();
01320
01321 if (mPoint == ANCHOR_LEFT || mPoint == ANCHOR_RIGHT)
01322 {
01323 bResizeWidth_ = true;
01324 bResizeHeight_ = false;
01325 }
01326 else if (mPoint == ANCHOR_TOP || mPoint == ANCHOR_BOTTOM)
01327 {
01328 bResizeWidth_ = false;
01329 bResizeHeight_ = true;
01330 }
01331 else
01332 {
01333 bResizeWidth_ = true;
01334 bResizeHeight_ = true;
01335 }
01336 }
01337 }
01338
01339 void manager::stop_sizing(uiobject* pObj)
01340 {
01341 if (pSizedObject_ == pObj)
01342 pSizedObject_ = nullptr;
01343 }
01344
01345 bool manager::is_sizing(uiobject* pObj) const
01346 {
01347 return (pSizedObject_ == pObj);
01348 }
01349
01350 int manager::get_movement_x() const
01351 {
01352 return fMouseMovementX_;
01353 }
01354
01355 int manager::get_movement_y() const
01356 {
01357 return fMouseMovementY_;
01358 }
01359
01360 void manager::notify_object_moved()
01361 {
01362 bObjectMoved_ = true;
01363 }
01364
01365 void manager::fire_redraw(frame_strata mStrata) const
01366 {
01367 std::map<frame_strata, strata>::const_iterator iter = lStrataList_.find(mStrata);
01368 if (iter != lStrataList_.end())
01369 iter->second.bRedraw = true;
01370 }
01371
01372 void manager::toggle_caching()
01373 {
01374 bEnableCaching_ = !bEnableCaching_;
01375
01376 if (bEnableCaching_)
01377 {
01378 std::map<frame_strata, strata>::iterator iterStrata;
01379 foreach (iterStrata, lStrataList_)
01380 iterStrata->second.bRedraw = true;
01381 }
01382 }
01383
01384 void manager::enable_caching(bool bEnable)
01385 {
01386 if (bEnableCaching_ != bEnable)
01387 toggle_caching();
01388 }
01389
01390 bool manager::is_caching_enabled() const
01391 {
01392 return bEnableCaching_;
01393 }
01394
01395 void manager::enable_input(bool bEnable)
01396 {
01397 if (bInputEnabled_ != bEnable)
01398 toggle_input();
01399 }
01400
01401 void manager::toggle_input()
01402 {
01403 bInputEnabled_ = !bInputEnabled_;
01404
01405 if (bInputEnabled_)
01406 {
01407 bUpdateOveredFrame_ = true;
01408
01409 if (pFocusedFrame_)
01410 pInputManager_->set_focus(true, pFocusedFrame_);
01411 }
01412 else
01413 {
01414 set_overed_frame_(nullptr);
01415
01416 if (pFocusedFrame_)
01417 pInputManager_->set_focus(false);
01418 }
01419 }
01420
01421 bool manager::is_input_enabled() const
01422 {
01423 return bInputEnabled_;
01424 }
01425
01426 void manager::clear_fonts_on_close(bool bClear)
01427 {
01428 bClearFontsOnClose_ = bClear;
01429 }
01430
01431 const frame* manager::get_overed_frame() const
01432 {
01433 return pOveredFrame_;
01434 }
01435
01436 void manager::request_focus(focus_frame* pFocusFrame)
01437 {
01438 if (pFocusFrame == pFocusedFrame_)
01439 return;
01440
01441 if (pFocusedFrame_)
01442 pFocusedFrame_->notify_focus(false);
01443
01444 pFocusedFrame_ = pFocusFrame;
01445
01446 if (pFocusedFrame_)
01447 {
01448 pFocusedFrame_->notify_focus(true);
01449 pInputManager_->set_focus(true, pFocusedFrame_);
01450 }
01451 else
01452 pInputManager_->set_focus(false);
01453 }
01454
01455 void manager::set_key_binding(uint uiKey, const std::string& sLuaString)
01456 {
01457 lKeyBindingList_[uiKey][0][0] = sLuaString;
01458 }
01459
01460 void manager::set_key_binding(uint uiKey, uint uiModifier, const std::string& sLuaString)
01461 {
01462 lKeyBindingList_[uiKey][uiModifier][0] = sLuaString;
01463 }
01464
01465 void manager::set_key_binding(uint uiKey, uint uiModifier1, uint uiModifier2, const std::string& sLuaString)
01466 {
01467 lKeyBindingList_[uiKey][uiModifier1][uiModifier2] = sLuaString;
01468 }
01469
01470 void manager::remove_key_binding(uint uiKey)
01471 {
01472 std::map<uint, std::map<uint, std::map<uint, std::string> > >::iterator iter1 = lKeyBindingList_.find(uiKey);
01473 if (iter1 != lKeyBindingList_.end())
01474 {
01475 std::map<uint, std::map<uint, std::string> >::iterator iter2 = iter1->second.find(0);
01476 if (iter2 != iter1->second.end())
01477 {
01478 std::map<uint, std::string>::iterator iter3 = iter2->second.find(0);
01479 if (iter3 != iter2->second.end())
01480 {
01481 iter2->second.erase(iter3);
01482
01483 if (iter2->second.size() == 0)
01484 iter1->second.erase(iter2);
01485
01486 if (iter1->second.size() == 0)
01487 lKeyBindingList_.erase(iter1);
01488 }
01489 }
01490 }
01491 }
01492
01493 void manager::remove_key_binding(uint uiKey, uint uiModifier)
01494 {
01495 std::map<uint, std::map<uint, std::map<uint, std::string> > >::iterator iter1 = lKeyBindingList_.find(uiKey);
01496 if (iter1 != lKeyBindingList_.end())
01497 {
01498 std::map<uint, std::map<uint, std::string> >::iterator iter2 = iter1->second.find(uiModifier);
01499 if (iter2 != iter1->second.end())
01500 {
01501 std::map<uint, std::string>::iterator iter3 = iter2->second.find(0);
01502 if (iter3 != iter2->second.end())
01503 {
01504 iter2->second.erase(iter3);
01505
01506 if (iter2->second.size() == 0)
01507 iter1->second.erase(iter2);
01508
01509 if (iter1->second.size() == 0)
01510 lKeyBindingList_.erase(iter1);
01511 }
01512 }
01513 }
01514 }
01515
01516 void manager::remove_key_binding(uint uiKey, uint uiModifier1, uint uiModifier2)
01517 {
01518 std::map<uint, std::map<uint, std::map<uint, std::string> > >::iterator iter1 = lKeyBindingList_.find(uiKey);
01519 if (iter1 != lKeyBindingList_.end())
01520 {
01521 std::map<uint, std::map<uint, std::string> >::iterator iter2 = iter1->second.find(uiModifier1);
01522 if (iter2 != iter1->second.end())
01523 {
01524 std::map<uint, std::string>::iterator iter3 = iter2->second.find(uiModifier2);
01525 if (iter3 != iter2->second.end())
01526 {
01527 iter2->second.erase(iter3);
01528
01529 if (iter2->second.size() == 0)
01530 iter1->second.erase(iter2);
01531
01532 if (iter1->second.size() == 0)
01533 lKeyBindingList_.erase(iter1);
01534 }
01535 }
01536 }
01537 }
01538
01539 int manager::get_highest_level(frame_strata mFrameStrata) const
01540 {
01541 std::map<frame_strata, strata>::const_iterator iterStrata = lStrataList_.find(mFrameStrata);
01542 if (iterStrata != lStrataList_.end())
01543 {
01544 if (!iterStrata->second.lLevelList.empty())
01545 {
01546 std::map<int, level>::const_iterator iterLevel = iterStrata->second.lLevelList.end();
01547 --iterLevel;
01548 return iterLevel->first;
01549 }
01550 }
01551
01552 return 0;
01553 }
01554
01555 addon* manager::get_current_addon()
01556 {
01557 return pCurrentAddOn_;
01558 }
01559
01560 void manager::set_current_addon(addon* pAddOn)
01561 {
01562 pCurrentAddOn_ = pAddOn;
01563 }
01564
01565 std::string manager::parse_file_name(const std::string& sFileName) const
01566 {
01567 std::string sNewFile = sFileName;
01568 if (sNewFile[0] == '|')
01569 {
01570 sNewFile[0] = '/';
01571 if (pCurrentAddOn_)
01572 sNewFile = pCurrentAddOn_->sDirectory + sNewFile;
01573 }
01574
01575 return sNewFile;
01576 }
01577
01578 void manager::on_event(const event& mEvent)
01579 {
01580 if (mEvent.get_name() == "KEY_PRESSED")
01581 {
01582 uint uiKey = mEvent.get(0)->get<uint>();
01583 bool bCaptured;
01584
01585 std::map<uint, std::map<uint, std::map<uint, std::string> > >::const_iterator iter1 = lKeyBindingList_.find(uiKey);
01586 std::map<uint, std::map<uint, std::string> >::const_iterator iter2;
01587 std::map<uint, std::string>::const_iterator iter3;
01588
01589 if (iter1 != lKeyBindingList_.end())
01590 {
01591 foreach (iter2, iter1->second)
01592 {
01593 if (iter2->first == input::key::K_UNASSIGNED || !pInputManager_->key_is_down((input::key::code)iter2->first))
01594 continue;
01595
01596 foreach (iter3, iter2->second)
01597 {
01598 if (iter3->first == input::key::K_UNASSIGNED || !pInputManager_->key_is_down((input::key::code)iter3->first))
01599 continue;
01600
01601 try { pLua_->do_string(iter3->second); }
01602 catch (lua::exception& e)
01603 {
01604 gui::out << gui::error << "Binded action : "+pInputManager_->get_key_name(
01605 (input::key::code)uiKey, (input::key::code)iter2->first, (input::key::code)iter3->first
01606 ) << " : " << e.get_description() << std::endl;
01607 }
01608
01609 bCaptured = true;
01610 break;
01611 }
01612
01613 if (bCaptured)
01614 break;
01615
01616 iter3 = iter2->second.find(input::key::K_UNASSIGNED);
01617 if (iter3 != iter2->second.end())
01618 {
01619 try { pLua_->do_string(iter3->second); }
01620 catch (lua::exception& e)
01621 {
01622 gui::out << gui::error << "Binded action : "+pInputManager_->get_key_name(
01623 (input::key::code)uiKey, (input::key::code)iter2->first
01624 ) << " : " << e.get_description() << std::endl;
01625 }
01626 }
01627 }
01628
01629 iter2 = iter1->second.find(input::key::K_UNASSIGNED);
01630 if (iter2 != iter1->second.end())
01631 {
01632 iter3 = iter2->second.find(input::key::K_UNASSIGNED);
01633 if (iter3 != iter2->second.end())
01634 {
01635 try { pLua_->do_string(iter3->second); }
01636 catch (lua::exception& e)
01637 {
01638 gui::out << gui::error << "Binded action : "+pInputManager_->get_key_name((input::key::code)uiKey)
01639 << e.get_description() << std::endl;
01640 }
01641 }
01642 }
01643 }
01644 }
01645 }
01646
01647 void manager::begin(utils::refptr<render_target> pTarget) const
01648 {
01649 pImpl_->begin(pTarget);
01650 }
01651
01652 void manager::end() const
01653 {
01654 pImpl_->end();
01655 }
01656
01657 void manager::print_statistics()
01658 {
01659 gui::out << "GUI Statistics :" << std::endl;
01660 gui::out << " strata redraw percent :" << std::endl;
01661 std::map<frame_strata, strata>::const_iterator iterStrata;
01662 foreach (iterStrata, lStrataList_)
01663 {
01664 const strata& mStrata = iterStrata->second;
01665 gui::out << " - [" << mStrata.uiID << "] : "
01666 << utils::to_string(100.0f*float(mStrata.uiRedrawCount)/float(uiFrameNumber_), 2, 1) << "%" << std::endl;
01667 }
01668 }
01669
01670 std::string manager::print_ui() const
01671 {
01672 std::stringstream s;
01673
01674 if (lAddOnList_.size() >= 1)
01675 {
01676 s << "\n\n######################## Loaded addons ########################\n" << std::endl;
01677 std::map<std::string, std::map<std::string, addon>>::const_iterator iterDirectory;
01678 foreach (iterDirectory, lAddOnList_)
01679 {
01680 s << "# Directory : " << iterDirectory->first << "\n|-###" << std::endl;
01681 std::map<std::string, addon>::const_iterator iterAdd;
01682 foreach (iterAdd, iterDirectory->second)
01683 {
01684 if (iterAdd->second.bEnabled)
01685 s << "| # " << iterAdd->first << std::endl;
01686 }
01687 s << "|-###\n#" << std::endl;
01688 }
01689 }
01690 if (lObjectList_.size() >= 1)
01691 {
01692 s << "\n\n######################## UIObjects ########################\n\n########################\n" << std::endl;
01693 std::map<uint, uiobject*>::const_iterator iterObj;
01694 foreach (iterObj, lObjectList_)
01695 {
01696 if (!iterObj->second->is_virtual() && !iterObj->second->get_parent())
01697 s << iterObj->second->serialize("") << "\n########################\n" << std::endl;
01698 }
01699
01700 s << "\n\n#################### Virtual UIObjects ####################\n\n########################\n" << std::endl;
01701 foreach (iterObj, lObjectList_)
01702 {
01703 if (iterObj->second->is_virtual() && !iterObj->second->get_parent())
01704 s << iterObj->second->serialize("") << "\n########################\n" << std::endl;
01705 }
01706 }
01707
01708 return s.str();
01709 }
01710
01711 utils::wptr<event_manager> manager::get_event_manager()
01712 {
01713 return pEventManager_;
01714 }
01715
01716 utils::wptr<input::manager> manager::get_input_manager()
01717 {
01718 return pInputManager_;
01719 }
01720
01721 const std::string& manager::get_locale() const
01722 {
01723 return sLocale_;
01724 }
01725
01726 manager_impl::manager_impl()
01727 {
01728 }
01729
01730 manager_impl::~manager_impl()
01731 {
01732 }
01733
01734 utils::refptr<sprite> manager_impl::create_sprite(utils::refptr<material> pMat) const
01735 {
01736 return nullptr;
01737 }
01738
01739 utils::refptr<sprite> manager_impl::create_sprite(utils::refptr<material> pMat, float fWidth, float fHeight) const
01740 {
01741 return nullptr;
01742 }
01743
01744 utils::refptr<sprite> manager_impl::create_sprite(utils::refptr<material> pMat,
01745 float fU, float fV, float fWidth, float fHeight) const
01746 {
01747 return nullptr;
01748 }
01749
01750 void manager_impl::set_parent(manager* pParent)
01751 {
01752 pParent_ = pParent;
01753 }
01754
01755 strata::strata() : uiID(uint(-1)), bRedraw(true), uiRedrawCount(0u)
01756 {
01757 }
01758
01759 strata::~strata()
01760 {
01761 }
01762 }