MyGUI
3.2.0
|
00001 00006 /* 00007 This file is part of MyGUI. 00008 00009 MyGUI is free software: you can redistribute it and/or modify 00010 it under the terms of the GNU Lesser General Public License as published by 00011 the Free Software Foundation, either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 MyGUI is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 along with MyGUI. If not, see <http://www.gnu.org/licenses/>. 00021 */ 00022 #include "MyGUI_Precompiled.h" 00023 #include "MyGUI_PointerManager.h" 00024 #include "MyGUI_ResourceManager.h" 00025 #include "MyGUI_LayerManager.h" 00026 #include "MyGUI_CoordConverter.h" 00027 #include "MyGUI_WidgetManager.h" 00028 #include "MyGUI_XmlDocument.h" 00029 #include "MyGUI_Widget.h" 00030 #include "MyGUI_FactoryManager.h" 00031 #include "MyGUI_InputManager.h" 00032 #include "MyGUI_Gui.h" 00033 00034 #include "MyGUI_ResourceManualPointer.h" 00035 #include "MyGUI_ResourceImageSetPointer.h" 00036 00037 namespace MyGUI 00038 { 00039 00040 const std::string XML_TYPE("Pointer"); 00041 const std::string XML_TYPE_RESOURCE("Resource"); 00042 const std::string XML_TYPE_PROPERTY("Property"); 00043 const std::string RESOURCE_DEFAULT_NAME("Default"); 00044 00045 template <> PointerManager* Singleton<PointerManager>::msInstance = nullptr; 00046 template <> const char* Singleton<PointerManager>::mClassTypeName("PointerManager"); 00047 00048 PointerManager::PointerManager() : 00049 mVisible(false), 00050 mWidgetOwner(nullptr), 00051 mMousePointer(nullptr), 00052 mPointer(nullptr), 00053 mIsInitialise(false) 00054 { 00055 } 00056 00057 void PointerManager::initialise() 00058 { 00059 MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice"); 00060 MYGUI_LOG(Info, "* Initialise: " << getClassTypeName()); 00061 00062 Gui::getInstance().eventFrameStart += newDelegate(this, &PointerManager::notifyFrameStart); 00063 InputManager::getInstance().eventChangeMouseFocus += newDelegate(this, &PointerManager::notifyChangeMouseFocus); 00064 WidgetManager::getInstance().registerUnlinker(this); 00065 00066 ResourceManager::getInstance().registerLoadXmlDelegate(XML_TYPE) = newDelegate(this, &PointerManager::_load); 00067 00068 FactoryManager::getInstance().registerFactory<ResourceManualPointer>(XML_TYPE_RESOURCE); 00069 FactoryManager::getInstance().registerFactory<ResourceImageSetPointer>(XML_TYPE_RESOURCE); 00070 00071 mPointer = nullptr; 00072 mMousePointer = nullptr; 00073 mWidgetOwner = nullptr; 00074 mVisible = true; 00075 00076 mSkinName = "ImageBox"; 00077 00078 MYGUI_LOG(Info, getClassTypeName() << " successfully initialized"); 00079 mIsInitialise = true; 00080 } 00081 00082 void PointerManager::shutdown() 00083 { 00084 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised"); 00085 MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName()); 00086 00087 InputManager::getInstance().eventChangeMouseFocus -= newDelegate(this, &PointerManager::notifyChangeMouseFocus); 00088 Gui::getInstance().eventFrameStart -= newDelegate(this, &PointerManager::notifyFrameStart); 00089 00090 FactoryManager::getInstance().unregisterFactory<ResourceManualPointer>(XML_TYPE_RESOURCE); 00091 FactoryManager::getInstance().unregisterFactory<ResourceImageSetPointer>(XML_TYPE_RESOURCE); 00092 00093 // удаляем все виджеты 00094 _destroyAllChildWidget(); 00095 00096 mWidgetOwner = nullptr; 00097 00098 WidgetManager::getInstance().unregisterUnlinker(this); 00099 ResourceManager::getInstance().unregisterLoadXmlDelegate(XML_TYPE); 00100 00101 MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown"); 00102 mIsInitialise = false; 00103 } 00104 00105 void PointerManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version) 00106 { 00107 std::string pointer; 00108 std::string layer; 00109 00110 xml::ElementEnumerator node = _node->getElementEnumerator(); 00111 while (node.next()) 00112 { 00113 if (node->getName() == XML_TYPE) 00114 { 00115 layer = node->findAttribute("layer"); 00116 pointer = node->findAttribute("default"); 00117 00118 // сохраняем 00119 std::string shared_text = node->findAttribute("texture"); 00120 00121 // берем детей и крутимся, основной цикл 00122 xml::ElementEnumerator info = node->getElementEnumerator(); 00123 while (info.next("Info")) 00124 { 00125 std::string name = info->findAttribute("name"); 00126 if (name.empty()) continue; 00127 00128 std::string texture = info->findAttribute("texture"); 00129 00130 std::string type = (shared_text.empty() && texture.empty()) ? "ResourceImageSetPointer" : "ResourceManualPointer"; 00131 00132 xml::Document doc; 00133 xml::ElementPtr root = doc.createRoot("MyGUI"); 00134 xml::ElementPtr newnode = root->createChild("Resource"); 00135 newnode->addAttribute("type", type); 00136 newnode->addAttribute("name", name); 00137 00138 std::string tmp; 00139 if (info->findAttribute("point", tmp)) 00140 { 00141 xml::ElementPtr prop = newnode->createChild("Property"); 00142 prop->addAttribute("key", "Point"); 00143 prop->addAttribute("value", tmp); 00144 } 00145 00146 if (info->findAttribute("size", tmp)) 00147 { 00148 xml::ElementPtr prop = newnode->createChild("Property"); 00149 prop->addAttribute("key", "Size"); 00150 prop->addAttribute("value", tmp); 00151 } 00152 00153 if (info->findAttribute("resource", tmp)) 00154 { 00155 xml::ElementPtr prop = newnode->createChild("Property"); 00156 prop->addAttribute("key", "Resource"); 00157 prop->addAttribute("value", tmp); 00158 } 00159 00160 if (info->findAttribute("offset", tmp)) 00161 { 00162 xml::ElementPtr prop = newnode->createChild("Property"); 00163 prop->addAttribute("key", "Coord"); 00164 prop->addAttribute("value", tmp); 00165 } 00166 00167 if (!shared_text.empty() || !texture.empty()) 00168 { 00169 xml::ElementPtr prop = newnode->createChild("Property"); 00170 prop->addAttribute("key", "Texture"); 00171 prop->addAttribute("value", shared_text.empty() ? texture : shared_text); 00172 } 00173 00174 ResourceManager::getInstance().loadFromXmlNode(root, _file, _version); 00175 } 00176 00177 } 00178 else if (node->getName() == XML_TYPE_PROPERTY) 00179 { 00180 const std::string& key = node->findAttribute("key"); 00181 const std::string& value = node->findAttribute("value"); 00182 if (key == "Default") 00183 setDefaultPointer(value); 00184 else if (key == "Layer") 00185 setLayerName(value); 00186 else if (key == "Skin") 00187 mSkinName = value; 00188 } 00189 } 00190 00191 if (!layer.empty()) 00192 setLayerName(layer); 00193 00194 if (!pointer.empty()) 00195 setDefaultPointer(pointer); 00196 00197 } 00198 00199 void PointerManager::notifyFrameStart(float _time) 00200 { 00201 mPoint = InputManager::getInstance().getMousePosition(); 00202 if (nullptr != mMousePointer && mPointer != nullptr) 00203 mPointer->setPosition(mMousePointer, mPoint); 00204 } 00205 00206 void PointerManager::setVisible(bool _visible) 00207 { 00208 if (nullptr != mMousePointer) mMousePointer->setVisible(_visible); 00209 mVisible = _visible; 00210 } 00211 00212 void PointerManager::setPointer(const std::string& _name, Widget* _owner) 00213 { 00214 if (nullptr == mMousePointer) 00215 return; 00216 00217 IResource* result = getByName(_name); 00218 if (result == nullptr) 00219 { 00220 mPointer = nullptr; 00221 mMousePointer->setVisible(false); 00222 return; 00223 } 00224 00225 mMousePointer->setVisible(mVisible); 00226 mPointer = result->castType<IPointer>(); 00227 mPointer->setImage(mMousePointer); 00228 mPointer->setPosition(mMousePointer, mPoint); 00229 00230 mWidgetOwner = _owner; 00231 } 00232 00233 void PointerManager::_unlinkWidget(Widget* _widget) 00234 { 00235 if (_widget == mWidgetOwner) setPointer(mDefaultName, nullptr); 00236 else if (_widget == mMousePointer) mMousePointer = nullptr; 00237 } 00238 00239 void PointerManager::resetToDefaultPointer() 00240 { 00241 setPointer(mDefaultName, nullptr); 00242 } 00243 00244 // создает виджет 00245 Widget* PointerManager::baseCreateWidget(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer, const std::string& _name) 00246 { 00247 Widget* widget = WidgetManager::getInstance().createWidget(_style, _type, _skin, _coord, /*_align, */nullptr, nullptr, /*this, */_name); 00248 mWidgetChild.push_back(widget); 00249 00250 widget->setAlign(_align); 00251 00252 // присоединяем виджет с уровню 00253 if (!_layer.empty()) 00254 LayerManager::getInstance().attachToLayerNode(_layer, widget); 00255 return widget; 00256 } 00257 00258 // удяляет неудачника 00259 void PointerManager::_destroyChildWidget(Widget* _widget) 00260 { 00261 MYGUI_ASSERT(nullptr != _widget, "invalid widget pointer"); 00262 00263 VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget); 00264 if (iter != mWidgetChild.end()) 00265 { 00266 // сохраняем указатель 00267 MyGUI::Widget* widget = *iter; 00268 00269 // удаляем из списка 00270 mWidgetChild.erase(iter); 00271 00272 // отписываем от всех 00273 WidgetManager::getInstance().unlinkFromUnlinkers(_widget); 00274 00275 // непосредственное удаление 00276 WidgetManager::getInstance()._deleteWidget(widget); 00277 } 00278 else 00279 { 00280 MYGUI_EXCEPT("Widget '" << _widget->getName() << "' not found"); 00281 } 00282 } 00283 00284 // удаляет всех детей 00285 void PointerManager::_destroyAllChildWidget() 00286 { 00287 WidgetManager& manager = WidgetManager::getInstance(); 00288 while (!mWidgetChild.empty()) 00289 { 00290 // сразу себя отписывем, иначе вложенной удаление убивает все 00291 Widget* widget = mWidgetChild.back(); 00292 mWidgetChild.pop_back(); 00293 00294 // отписываем от всех 00295 manager.unlinkFromUnlinkers(widget); 00296 00297 // и сами удалим, так как его больше в списке нет 00298 WidgetManager::getInstance()._deleteWidget(widget); 00299 } 00300 } 00301 00302 void PointerManager::setDefaultPointer(const std::string& _value) 00303 { 00304 Update(); 00305 00306 mDefaultName = _value; 00307 setPointer(mDefaultName, nullptr); 00308 } 00309 00310 void PointerManager::setLayerName(const std::string& _value) 00311 { 00312 Update(); 00313 00314 mLayerName = _value; 00315 if (LayerManager::getInstance().isExist(_value)) 00316 LayerManager::getInstance().attachToLayerNode(mLayerName, mMousePointer); 00317 } 00318 00319 void PointerManager::Update() 00320 { 00321 if (mMousePointer == nullptr) 00322 mMousePointer = static_cast<ImageBox*>(baseCreateWidget(WidgetStyle::Overlapped, ImageBox::getClassTypeName(), mSkinName, IntCoord(), Align::Default, "", "")); 00323 } 00324 00325 IPointer* PointerManager::getByName(const std::string& _name) const 00326 { 00327 IResource* result = nullptr; 00328 if (!_name.empty() && _name != RESOURCE_DEFAULT_NAME) 00329 result = ResourceManager::getInstance().getByName(_name, false); 00330 00331 if (result == nullptr) 00332 result = ResourceManager::getInstance().getByName(mDefaultName, false); 00333 00334 return result ? result->castType<IPointer>(false) : nullptr; 00335 } 00336 00337 void PointerManager::notifyChangeMouseFocus(Widget* _widget) 00338 { 00339 std::string pointer = (_widget == nullptr || !_widget->getEnabled()) ? "" : _widget->getPointer(); 00340 if (pointer != mCurrentMousePointer) 00341 { 00342 mCurrentMousePointer = pointer; 00343 if (mCurrentMousePointer.empty()) 00344 { 00345 resetToDefaultPointer(); 00346 eventChangeMousePointer(mDefaultName); 00347 } 00348 else 00349 { 00350 setPointer(mCurrentMousePointer, _widget); 00351 eventChangeMousePointer(mCurrentMousePointer); 00352 } 00353 } 00354 } 00355 00356 void PointerManager::setPointer(const std::string& _name) 00357 { 00358 setPointer(_name, nullptr); 00359 } 00360 00361 bool PointerManager::isVisible() const 00362 { 00363 return mVisible; 00364 } 00365 00366 const std::string& PointerManager::getDefaultPointer() const 00367 { 00368 return mDefaultName; 00369 } 00370 00371 const std::string& PointerManager::getLayerName() const 00372 { 00373 return mLayerName; 00374 } 00375 00376 } // namespace MyGUI