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