1 /* 2 * This source file is part of MyGUI. For the latest info, see http://mygui.info/ 3 * Distributed under the MIT License 4 * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT) 5 */ 6 7 #ifndef MYGUI_WIDGET_H_ 8 #define MYGUI_WIDGET_H_ 9 10 #include "MyGUI_Prerequest.h" 11 #include "MyGUI_Any.h" 12 #include "MyGUI_ICroppedRectangle.h" 13 #include "MyGUI_WidgetUserData.h" 14 #include "MyGUI_WidgetInput.h" 15 #include "MyGUI_ResourceSkin.h" 16 #include "MyGUI_ResourceLayout.h" 17 #include "MyGUI_IObject.h" 18 #include "MyGUI_SkinItem.h" 19 #include "MyGUI_BackwardCompatibility.h" 20 21 namespace MyGUI 22 { 23 24 typedef delegates::CMultiDelegate3<Widget*, const std::string&, const std::string&> EventHandle_WidgetStringString; 25 26 /** \brief @wpage{Widget} 27 Widget widget description should be here. 28 */ 29 class MYGUI_EXPORT Widget : 30 public IObject, 31 public ICroppedRectangle, 32 public UserData, 33 public WidgetInput, 34 public delegates::IDelegateUnlink, 35 public SkinItem, 36 public MemberObsolete<Widget> 37 { 38 // для вызова закрытых деструкторов 39 friend class WidgetManager; 40 41 MYGUI_RTTI_DERIVED( Widget ) 42 43 public: 44 Widget(); 45 46 /** Create child widget 47 @param _type widget type 48 @param _skin widget skin 49 @param _coord int coordinates of widget (_left, _top, _width, _height) 50 @param _align widget align (possible values can be found in enum Align) 51 @param _name if needed (you can use it for finding widget by name later) 52 */ 53 Widget* createWidgetT(const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _name = ""); 54 55 /** See Widget::createWidgetT(const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _name = "") */ 56 Widget* createWidgetT(const std::string& _type, const std::string& _skin, int _left, int _top, int _width, int _height, Align _align, const std::string& _name = ""); 57 58 /** Create widget using coordinates relative to parent. see Widget::createWidgetT(const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _name = "") */ 59 Widget* createWidgetRealT(const std::string& _type, const std::string& _skin, const FloatCoord& _coord, Align _align, const std::string& _name = ""); 60 61 /** Create widget using coordinates relative to parent. see Widget::createWidgetT(const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _name = "") */ 62 Widget* createWidgetRealT(const std::string& _type, const std::string& _skin, float _left, float _top, float _width, float _height, Align _align, const std::string& _name = ""); 63 64 // templates for creating widgets by type 65 /** Same as Widget::createWidgetT but return T pointer instead of Widget* */ 66 template <typename T> 67 T* createWidget(const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _name = "") 68 { 69 return static_cast<T*>(createWidgetT(T::getClassTypeName(), _skin, _coord, _align, _name)); 70 } 71 72 /** Same as Widget::createWidgetT but return T pointer instead of Widget* */ 73 template <typename T> 74 T* createWidget(const std::string& _skin, int _left, int _top, int _width, int _height, Align _align, const std::string& _name = "") 75 { 76 return static_cast<T*>(createWidgetT(T::getClassTypeName(), _skin, IntCoord(_left, _top, _width, _height), _align, _name)); 77 } 78 79 /** Same as Widget::createWidgetRealT but return T* instead of Widget* */ 80 template <typename T> 81 T* createWidgetReal(const std::string& _skin, const FloatCoord& _coord, Align _align, const std::string& _name = "") 82 { 83 return static_cast<T*>(createWidgetRealT(T::getClassTypeName(), _skin, _coord, _align, _name)); 84 } 85 86 /** Same as Widget::createWidgetRealT but return T* instead of Widget* */ 87 template <typename T> 88 T* createWidgetReal(const std::string& _skin, float _left, float _top, float _width, float _height, Align _align, const std::string& _name = "") 89 { 90 return static_cast<T*>(createWidgetRealT(T::getClassTypeName(), _skin, _left, _top, _width, _height, _align, _name)); 91 } 92 93 /** Create child widget 94 @param _style Child, Popup or Overlapped widget style 95 @param _type widget type 96 @param _skin widget skin 97 @param _coord int coordinates of widget (_left, _top, _width, _height) 98 @param _align widget align (possible values can be found in enum Align) 99 @param _layer layer where widget will be created (all layers usually defined in core_layer.xml file). 100 @param _name optional widget name (you can use it for finding widget by name later) 101 */ 102 Widget* createWidgetT(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer = "", const std::string& _name = ""); 103 104 /** Same as Widget::createWidgetT but return T* instead of Widget* */ 105 template <typename T> 106 T* createWidget(WidgetStyle _style, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer = "", const std::string& _name = "") 107 { 108 return static_cast<T*>(createWidgetT(_style, T::getClassTypeName(), _skin, _coord, _align, _layer, _name)); 109 } 110 111 /** Set widget position (position of left top corner) */ 112 void setPosition(const IntPoint& _value) override; 113 /** Set widget size */ 114 void setSize(const IntSize& _value) override; 115 /** Set widget position and size */ 116 void setCoord(const IntCoord& _value) override; 117 118 /** See Widget::setPosition(const IntPoint& _pos) */ 119 void setPosition(int _left, int _top); 120 /** See Widget::setSize(const IntSize& _size) */ 121 void setSize(int _width, int _height); 122 /** See Widget::setCoord(const IntCoord& _coord) */ 123 void setCoord(int _left, int _top, int _width, int _height); 124 125 /** Set widget position (position of left top corner)*/ 126 void setRealPosition(const FloatPoint& _value); 127 /** Set widget size */ 128 void setRealSize(const FloatSize& _value); 129 /** Set widget position and size*/ 130 void setRealCoord(const FloatCoord& _value); 131 132 /** See Widget::setRealPosition(const FloatPoint& _point) */ 133 void setRealPosition(float _left, float _top); 134 /** See Widget::setRealSize(const FloatSize& _size) */ 135 void setRealSize(float _width, float _height); 136 /** See Widget::setRealPosition(const FloatCoord& _coord) */ 137 void setRealCoord(float _left, float _top, float _width, float _height); 138 139 //! Get name of widget 140 const std::string& getName() const; 141 142 /** Hide or show widget */ 143 virtual void setVisible(bool _value); 144 /** Return true if visible */ 145 bool getVisible() const; 146 147 /** Set child widget rendering depth for ordering child widgets. 148 Widget with higher depth is rendered below widget with lower depth. 149 Available only for child widgets. For root widgets use layer property instead. 150 */ 151 void setDepth(int _value); 152 /** Get child widget rendering depth */ 153 int getDepth() const; 154 155 /** Return widget's visibility based on it's and parents visibility. */ 156 bool getInheritedVisible() const; 157 158 /** Set align */ 159 virtual void setAlign(Align _value); 160 /** Get align */ 161 Align getAlign() const; 162 163 /** Set widget opacity */ 164 void setAlpha(float _value); 165 /** Get widget opacity */ 166 float getAlpha() const; 167 168 /** Enable or disable inherits alpha mode.\n 169 Inherits alpha mode: when enabled widget alpha is it's own 170 alpha value multiplied by parent's real alpha (that depend 171 on parent's parent and so on).\n 172 When disabled widget's alpha doesn't depend on parent's alpha. 173 So this is used when you need things like semi-transparent 174 window with non-transparent text on it and window's alpha 175 changes.\n 176 Enabled (true) by default. 177 */ 178 void setInheritsAlpha(bool _value); 179 /** Get inherits alpha mode flag */ 180 bool getInheritsAlpha() const; 181 182 void setColour(const Colour& _value); 183 184 // являемся ли мы рутовым виджетом 185 /** Is this widget is root widget (root == without parents) */ 186 bool isRootWidget() const; 187 188 /** Get parent widget or nullptr if no parent */ 189 Widget* getParent() const; 190 191 IntSize getParentSize() const; 192 193 /** Get child widgets Enumerator */ 194 EnumeratorWidgetPtr getEnumerator() const; 195 196 /** Get child count */ 197 size_t getChildCount(); 198 199 /** Get child by index (index from 0 to child_count - 1) */ 200 Widget* getChildAt(size_t _index); 201 202 /** Find widget by name. 203 Search recursively through all childs starting from this widget. 204 @return Return first found widget with given name 205 */ 206 Widget* findWidget(const std::string& _name); 207 208 /** Find all widgets with given name and add them into _result. 209 Search recursively through all childs starting from this widget. 210 */ 211 void findWidgets(const std::string& _name, VectorWidgetPtr& _result); 212 213 /** Enable or disable widget */ 214 virtual void setEnabled(bool _value); 215 /** Enable or disable widget without changing widget's state */ 216 void setEnabledSilent(bool _value); 217 /** Is widget enabled */ 218 bool getEnabled() const; 219 220 /** Is widget enabled and all it's parents in hierarchy are enabled. */ 221 bool getInheritedEnabled() const; 222 223 /** Get rectangle where child widgets placed */ 224 IntCoord getClientCoord(); 225 226 /** Get client area widget or nullptr if widget don't have client */ 227 Widget* getClientWidget(); 228 const Widget* getClientWidget() const; 229 230 /** Detach widget from widgets hierarchy 231 @param _layer Attach to specified layer (if any) 232 */ 233 void detachFromWidget(const std::string& _layer = ""); 234 235 /** Attach widget to parent 236 @param _parent New parent 237 @param _style New widget style (see WidgetStyle::Enum) 238 @param _layer Attach to specified layer (if any) 239 */ 240 void attachToWidget(Widget* _parent, WidgetStyle _style = WidgetStyle::Child, const std::string& _layer = ""); 241 242 /** Change widget skin */ 243 void changeWidgetSkin(const std::string& _skinName); 244 245 /** Set widget style. 246 @param _style New widget style (see WidgetStyle::Enum) 247 @param _layer Attach to specified layer (if any) 248 @note When choosing WidgetStyle::Popup style you also need attach widget to layer 249 */ 250 void setWidgetStyle(WidgetStyle _style, const std::string& _layer = ""); 251 /** Get widget style */ 252 WidgetStyle getWidgetStyle() const; 253 254 /** Set any widget property 255 @param _key Property name (for example Alpha or Enabled) 256 @param _value Value converted to string 257 */ 258 void setProperty(const std::string& _key, const std::string& _value); 259 260 261 /** Event : Widget property changed through setProperty (in code, or from layout)\n 262 signature : void method(MyGUI::Widget* _sender, const std::string& _key, const std::string& _value); 263 @param _sender widget that called this event 264 @param _key 265 @param _value 266 */ 267 EventHandle_WidgetStringString eventChangeProperty; 268 269 /** Event : Widget coordinate changed (widget was resized or moved).\n 270 signature : void method(MyGUI::Widget* _sender) 271 @param _sender widget that called this event 272 */ 273 EventHandle_WidgetVoid eventChangeCoord; 274 275 /*internal:*/ 276 // метод для запроса номера айтема и контейнера 277 virtual size_t _getItemIndex(Widget* _item); 278 279 // дает приоритет виджету при пиккинге 280 void _forcePick(Widget* _widget); 281 282 void _initialise(WidgetStyle _style, const IntCoord& _coord, const std::string& _skinName, Widget* _parent, ICroppedRectangle* _croppedParent, const std::string& _name); 283 void _shutdown(); 284 285 // удяляет неудачника 286 void _destroyChildWidget(Widget* _widget); 287 288 void _setContainer(Widget* _value); 289 Widget* _getContainer(); 290 291 void _setAlign(const IntSize& _oldsize, const IntSize& _newSize); 292 bool _checkPoint(int _left, int _top) const; 293 294 Widget* _createSkinWidget(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer = "", const std::string& _name = ""); 295 296 // сброс всех данных контейнера, тултипы и все остальное 297 virtual void _resetContainer(bool _update); 298 299 bool _setWidgetState(const std::string& _value); 300 301 // перерисовывает детей 302 void _updateChilds(); 303 304 protected: 305 // все создание только через фабрику 306 ~Widget() override = default; 307 308 virtual void shutdownOverride(); 309 virtual void initialiseOverride(); 310 311 void _updateView(); // обновления себя и детей 312 313 // создает виджет 314 Widget* baseCreateWidget(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer, const std::string& _name, bool _template); 315 316 // удаляет всех детей 317 void _destroyAllChildWidget(); 318 319 // запрашиваем у конейтера айтем по позиции мыши 320 virtual size_t _getContainerIndex(const IntPoint& _point); 321 322 virtual void baseUpdateEnable(); 323 324 // наследуемся он LayerInfo 325 ILayerItem* getLayerItemByPoint(int _left, int _top) const override; 326 const IntCoord& getLayerItemCoord() const override; 327 328 template <typename T> assignWidget(T * & _widget,const std::string & _name)329 void assignWidget(T*& _widget, const std::string& _name) 330 { 331 _widget = nullptr; 332 for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter) 333 { 334 Widget* find = (*iter)->findWidget(_name); 335 if (nullptr != find) 336 { 337 _widget = find->castType<T>(false); 338 break; 339 } 340 } 341 } 342 343 VectorWidgetPtr getSkinWidgetsByName(const std::string& _name); 344 345 void destroySkinWidget(Widget* _widget); 346 347 virtual void onWidgetCreated(Widget* _widget); 348 virtual void onWidgetDestroy(Widget* _widget); 349 350 void setWidgetClient(Widget* _widget); 351 /// If there is client widget return it, otherwise return this 352 Widget* _getClientWidget(); 353 354 virtual void setPropertyOverride(const std::string& _key, const std::string& _value); 355 356 private: 357 const WidgetInfo* initialiseWidgetSkinBase(ResourceSkin* _info, ResourceLayout* _templateInfo); 358 void shutdownWidgetSkinBase(); 359 360 void _updateAlpha(); 361 void _updateAbsolutePoint(); 362 363 // для внутреннего использования 364 void _updateVisible(); 365 366 void _updateEnabled(); 367 368 float _getRealAlpha() const; 369 370 void _createChildSkinWidget(ResourceSkin* _info); 371 void _destroyChildSkinWidget(); 372 373 void _parseSkinProperties(ResourceSkin* _info); 374 void _checkInheristProperties(); 375 376 void _linkChildWidget(Widget* _widget); 377 void _unlinkChildWidget(Widget* _widget); 378 379 void setSkinProperty(ResourceSkin* _info); 380 381 void resizeLayerItemView(const IntSize& _oldView, const IntSize& _newView) override; 382 383 void addWidget(Widget* _widget); 384 385 private: 386 // клиентская зона окна 387 // если виджет имеет пользовательские окна не в себе 388 // то обязательно проинициализировать Client 389 Widget* mWidgetClient; 390 391 // вектор всех детей виджетов 392 VectorWidgetPtr mWidgetChild; 393 394 // вектор детей скина 395 VectorWidgetPtr mWidgetChildSkin; 396 397 // доступен ли на виджет 398 bool mEnabled; 399 bool mInheritsEnabled; 400 // для иерархического скрытия 401 bool mInheritsVisible; 402 // прозрачность и флаг наследования альфы нашего оверлея 403 float mAlpha; 404 float mRealAlpha; 405 bool mInheritsAlpha; 406 // имя виджета 407 std::string mName; 408 409 // наш отец в иерархии виджетов 410 Widget* mParent; 411 412 // поведение виджета, перекрывающийся дочерний или всплывающий 413 WidgetStyle mWidgetStyle; 414 415 Widget* mContainer; 416 417 Align mAlign; 418 bool mVisible; 419 int mDepth; 420 }; 421 422 } // namespace MyGUI 423 424 #endif // MYGUI_WIDGET_H_ 425