Crazy Eddie's GUI System
0.8.4
|
00001 /*********************************************************************** 00002 created: 18/8/2011 00003 author: Martin Preisler 00004 00005 purpose: Defines a class representing an item in a graph 00006 (deals with relative positions, relative dimensions, ...) 00007 *************************************************************************/ 00008 /*************************************************************************** 00009 * Copyright (C) 2004 - 2011 Paul D Turner & The CEGUI Development Team 00010 * 00011 * Permission is hereby granted, free of charge, to any person obtaining 00012 * a copy of this software and associated documentation files (the 00013 * "Software"), to deal in the Software without restriction, including 00014 * without limitation the rights to use, copy, modify, merge, publish, 00015 * distribute, sublicense, and/or sell copies of the Software, and to 00016 * permit persons to whom the Software is furnished to do so, subject to 00017 * the following conditions: 00018 * 00019 * The above copyright notice and this permission notice shall be 00020 * included in all copies or substantial portions of the Software. 00021 * 00022 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00023 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00024 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00025 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 00026 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00027 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00028 * OTHER DEALINGS IN THE SOFTWARE. 00029 ***************************************************************************/ 00030 00031 #ifndef _CEGUIElement_h_ 00032 #define _CEGUIElement_h_ 00033 00034 #include "CEGUI/Base.h" 00035 #include "CEGUI/PropertySet.h" 00036 #include "CEGUI/EventSet.h" 00037 #include "CEGUI/EventArgs.h" 00038 00039 #if defined(_MSC_VER) 00040 # pragma warning(push) 00041 # pragma warning(disable : 4251) 00042 #endif 00043 00044 namespace CEGUI 00045 { 00046 00052 enum HorizontalAlignment 00053 { 00058 HA_LEFT, 00063 HA_CENTRE, 00068 HA_RIGHT 00069 }; 00070 00071 template<> 00072 class PropertyHelper<HorizontalAlignment> 00073 { 00074 public: 00075 typedef HorizontalAlignment return_type; 00076 typedef return_type safe_method_return_type; 00077 typedef HorizontalAlignment pass_type; 00078 typedef String string_return_type; 00079 00080 static const String& getDataTypeName() 00081 { 00082 static String type("HorizontalAlignment"); 00083 00084 return type; 00085 } 00086 00087 static return_type fromString(const String& str) 00088 { 00089 if (str == "Centre") 00090 { 00091 return HA_CENTRE; 00092 } 00093 else if (str == "Right") 00094 { 00095 return HA_RIGHT; 00096 } 00097 else 00098 { 00099 return HA_LEFT; 00100 } 00101 } 00102 00103 static string_return_type toString(pass_type val) 00104 { 00105 if (val == HA_CENTRE) 00106 { 00107 return "Centre"; 00108 } 00109 else if (val == HA_RIGHT) 00110 { 00111 return "Right"; 00112 } 00113 else if (val == HA_LEFT) 00114 { 00115 return "Left"; 00116 } 00117 else 00118 { 00119 assert(false && "Invalid horizontal alignment"); 00120 return "Centre"; 00121 } 00122 } 00123 }; 00124 00130 enum VerticalAlignment 00131 { 00136 VA_TOP, 00141 VA_CENTRE, 00146 VA_BOTTOM 00147 }; 00148 00149 template<> 00150 class PropertyHelper<CEGUI::VerticalAlignment> 00151 { 00152 public: 00153 typedef VerticalAlignment return_type; 00154 typedef return_type safe_method_return_type; 00155 typedef VerticalAlignment pass_type; 00156 typedef String string_return_type; 00157 00158 static const String& getDataTypeName() 00159 { 00160 static String type("VerticalAlignment"); 00161 00162 return type; 00163 } 00164 00165 static return_type fromString(const String& str) 00166 { 00167 if (str == "Centre") 00168 { 00169 return VA_CENTRE; 00170 } 00171 else if (str == "Bottom") 00172 { 00173 return VA_BOTTOM; 00174 } 00175 else 00176 { 00177 return VA_TOP; 00178 } 00179 } 00180 00181 static string_return_type toString(pass_type val) 00182 { 00183 if (val == VA_CENTRE) 00184 { 00185 return "Centre"; 00186 } 00187 else if (val == VA_BOTTOM) 00188 { 00189 return "Bottom"; 00190 } 00191 else if (val == VA_TOP) 00192 { 00193 return "Top"; 00194 } 00195 else 00196 { 00197 assert(false && "Invalid vertical alignment"); 00198 return "Centre"; 00199 } 00200 } 00201 }; 00202 00210 class CEGUIEXPORT ElementEventArgs : public EventArgs 00211 { 00212 public: 00213 ElementEventArgs(Element* element): 00214 element(element) 00215 {} 00216 00218 Element* element; 00219 }; 00220 00242 class CEGUIEXPORT Element : 00243 public PropertySet, 00244 public EventSet, 00245 public AllocatedObject<Element> 00246 { 00247 public: 00249 static const String EventNamespace; 00250 00255 static const String EventSized; 00261 static const String EventParentSized; 00266 static const String EventMoved; 00272 static const String EventHorizontalAlignmentChanged; 00278 static const String EventVerticalAlignmentChanged; 00283 static const String EventRotated; 00288 static const String EventChildAdded; 00293 static const String EventChildRemoved; 00299 static const String EventZOrderChanged; 00305 static const String EventNonClientChanged; 00306 00314 class CachedRectf 00315 { 00316 public: 00323 typedef Rectf (Element::*DataGenerator)(bool) const; 00324 00325 CachedRectf(Element const* element, DataGenerator generator): 00326 d_element(element), 00327 d_generator(generator), 00328 // we don't have to initialise d_cachedData here, it will get 00329 // regenerated and reset anyways 00330 d_cacheValid(false) 00331 {} 00332 00336 inline const Rectf& get() const 00337 { 00338 if (!d_cacheValid) 00339 { 00340 regenerateCache(); 00341 } 00342 00343 return d_cachedData; 00344 } 00345 00352 inline Rectf getFresh(bool skipAllPixelAlignment = false) const 00353 { 00354 // if the cache is not valid we will use this chance to regenerate it 00355 // of course this is only applicable if we are allowed to use pixel alignment where applicable 00356 if (!d_cacheValid && !skipAllPixelAlignment) 00357 { 00358 return get(); 00359 } 00360 00361 return CEGUI_CALL_MEMBER_FN(*d_element, d_generator)(skipAllPixelAlignment); 00362 } 00363 00370 inline void invalidateCache() const 00371 { 00372 d_cacheValid = false; 00373 } 00374 00375 inline bool isCacheValid() const 00376 { 00377 return d_cacheValid; 00378 } 00379 00380 inline void regenerateCache() const 00381 { 00382 // false, since when we are caching we don't want to skip anything, we want everything to act 00383 // exactly as it was setup 00384 d_cachedData = CEGUI_CALL_MEMBER_FN(*d_element, d_generator)(false); 00385 00386 d_cacheValid = true; 00387 } 00388 00389 private: 00390 Element const* d_element; 00391 const DataGenerator d_generator; 00392 00393 mutable Rectf d_cachedData; 00394 mutable bool d_cacheValid; 00395 }; 00396 00400 Element(); 00401 00405 virtual ~Element(); 00406 00414 inline Element* getParentElement() const 00415 { 00416 return d_parent; 00417 } 00418 00438 virtual void setArea(const UVector2& pos, const USize& size); 00439 00441 inline void setArea(const UDim& xpos, const UDim& ypos, 00442 const UDim& width, const UDim& height) 00443 { 00444 setArea(UVector2(xpos, ypos), USize(width, height)); 00445 } 00446 00448 inline void setArea(const URect& area) 00449 { 00450 setArea(area.d_min, area.getSize()); 00451 } 00452 00467 inline const URect& getArea() const 00468 { 00469 return d_area; 00470 } 00471 00487 inline void setPosition(const UVector2& pos) 00488 { 00489 setArea_impl(pos, d_area.getSize()); 00490 } 00491 00493 inline void setXPosition(const UDim& pos) 00494 { 00495 setPosition(UVector2(pos, getYPosition())); 00496 } 00497 00499 inline void setYPosition(const UDim& pos) 00500 { 00501 setPosition(UVector2(getXPosition(), pos)); 00502 } 00503 00518 inline const UVector2& getPosition() const 00519 { 00520 return d_area.getPosition(); 00521 } 00522 00524 inline const UDim& getXPosition() const 00525 { 00526 return getPosition().d_x; 00527 } 00528 00530 inline const UDim& getYPosition() const 00531 { 00532 return getPosition().d_y; 00533 } 00534 00545 virtual void setHorizontalAlignment(const HorizontalAlignment alignment); 00546 00557 inline HorizontalAlignment getHorizontalAlignment() const 00558 { 00559 return d_horizontalAlignment; 00560 } 00561 00572 virtual void setVerticalAlignment(const VerticalAlignment alignment); 00573 00584 inline VerticalAlignment getVerticalAlignment() const 00585 { 00586 return d_verticalAlignment; 00587 } 00588 00600 inline void setSize(const USize& size) 00601 { 00602 setArea(d_area.getPosition(), size); 00603 } 00604 00606 inline void setWidth(const UDim& width) 00607 { 00608 setSize(USize(width, getSize().d_height)); 00609 } 00610 00612 inline void setHeight(const UDim& height) 00613 { 00614 setSize(USize(getSize().d_width, height)); 00615 } 00616 00628 inline USize getSize() const 00629 { 00630 return d_area.getSize(); 00631 } 00632 00634 inline UDim getWidth() const 00635 { 00636 return getSize().d_width; 00637 } 00638 00640 inline UDim getHeight() const 00641 { 00642 return getSize().d_height; 00643 } 00644 00662 void setMinSize(const USize& size); 00663 00677 inline const USize& getMinSize() const 00678 { 00679 return d_minSize; 00680 } 00681 00701 void setMaxSize(const USize& size); 00702 00716 inline const USize& getMaxSize() const 00717 { 00718 return d_maxSize; 00719 } 00720 00729 void setAspectMode(const AspectMode mode); 00730 00737 inline AspectMode getAspectMode() const 00738 { 00739 return d_aspectMode; 00740 } 00741 00755 void setAspectRatio(const float ratio); 00756 00763 inline float getAspectRatio() const 00764 { 00765 return d_aspectRatio; 00766 } 00767 00789 void setPixelAligned(const bool setting); 00790 00798 inline bool isPixelAligned() const 00799 { 00800 return d_pixelAligned; 00801 } 00802 00810 inline const Vector2f& getPixelPosition() const 00811 { 00812 return getUnclippedOuterRect().get().d_min; 00813 } 00814 00822 inline const Sizef& getPixelSize() const 00823 { 00824 return d_pixelSize; 00825 } 00826 00837 Sizef calculatePixelSize(bool skipAllPixelAlignment = false) const; 00838 00848 Sizef getParentPixelSize(bool skipAllPixelAlignment = false) const; 00849 00862 void setRotation(const Quaternion& rotation); 00863 00869 inline const Quaternion& getRotation() const 00870 { 00871 return d_rotation; 00872 } 00873 00894 void addChild(Element* element); 00895 00906 void removeChild(Element* element); 00907 00921 inline Element* getChildElementAtIdx(size_t idx) const 00922 { 00923 return d_children[idx]; 00924 } 00925 00929 inline size_t getChildCount() const 00930 { 00931 return d_children.size(); 00932 } 00933 00937 bool isChild(const Element* element) const; 00938 00952 bool isAncestor(const Element* element) const; 00953 00967 void setNonClient(const bool setting); 00968 00974 inline bool isNonClient() const 00975 { 00976 return d_nonClient; 00977 } 00978 00992 inline const CachedRectf& getUnclippedOuterRect() const 00993 { 00994 return d_unclippedOuterRect; 00995 } 00996 01010 inline const CachedRectf& getUnclippedInnerRect() const 01011 { 01012 return d_unclippedInnerRect; 01013 } 01014 01028 inline const CachedRectf& getUnclippedRect(const bool inner) const 01029 { 01030 return inner ? getUnclippedInnerRect() : getUnclippedOuterRect(); 01031 } 01032 01041 virtual const CachedRectf& getClientChildContentArea() const; 01042 01051 virtual const CachedRectf& getNonClientChildContentArea() const; 01052 01074 inline const CachedRectf& getChildContentArea(const bool non_client = false) const 01075 { 01076 return non_client ? getNonClientChildContentArea() : getClientChildContentArea(); 01077 } 01078 01092 virtual void notifyScreenAreaChanged(bool recursive = true); 01093 01103 virtual const Sizef& getRootContainerSize() const; 01104 01105 protected: 01110 void addElementProperties(); 01111 01142 virtual void setArea_impl(const UVector2& pos, const USize& size, 01143 bool topLeftSizing = false, bool fireEvents = true); 01144 01146 inline bool isInnerRectSizeChanged() const 01147 { 01148 const Sizef old_sz(d_unclippedInnerRect.get().getSize()); 01149 d_unclippedInnerRect.invalidateCache(); 01150 return old_sz != d_unclippedInnerRect.get().getSize(); 01151 } 01152 01164 virtual void setParent(Element* parent); 01165 01170 virtual void addChild_impl(Element* element); 01171 01176 virtual void removeChild_impl(Element* element); 01177 01179 virtual Rectf getUnclippedOuterRect_impl(bool skipAllPixelAlignment) const; 01181 virtual Rectf getUnclippedInnerRect_impl(bool skipAllPixelAlignment) const; 01182 01184 void fireAreaChangeEvents(const bool moved, const bool sized); 01185 void notifyChildrenOfSizeChange(const bool non_client, 01186 const bool client); 01187 01188 /************************************************************************* 01189 Event trigger methods 01190 *************************************************************************/ 01199 virtual void onSized(ElementEventArgs& e); 01200 01212 virtual void onParentSized(ElementEventArgs& e); 01213 01222 virtual void onMoved(ElementEventArgs& e); 01223 01234 virtual void onHorizontalAlignmentChanged(ElementEventArgs& e); 01235 01246 virtual void onVerticalAlignmentChanged(ElementEventArgs& e); 01247 01256 virtual void onRotated(ElementEventArgs& e); 01257 01266 virtual void onChildAdded(ElementEventArgs& e); 01267 01276 virtual void onChildRemoved(ElementEventArgs& e); 01277 01288 virtual void onNonClientChanged(ElementEventArgs& e); 01289 01290 /************************************************************************* 01291 Implementation Data 01292 *************************************************************************/ 01294 typedef std::vector<Element* 01295 CEGUI_VECTOR_ALLOC(Element*)> ChildList; 01296 01298 ChildList d_children; 01300 Element* d_parent; 01301 01303 bool d_nonClient; 01304 01306 URect d_area; 01308 HorizontalAlignment d_horizontalAlignment; 01310 VerticalAlignment d_verticalAlignment; 01312 USize d_minSize; 01314 USize d_maxSize; 01316 AspectMode d_aspectMode; 01318 float d_aspectRatio; 01320 bool d_pixelAligned; 01322 Sizef d_pixelSize; 01324 Quaternion d_rotation; 01325 01327 CachedRectf d_unclippedOuterRect; 01329 CachedRectf d_unclippedInnerRect; 01330 01331 private: 01332 /************************************************************************* 01333 May not copy or assign Element objects 01334 *************************************************************************/ 01335 Element(const Element&); 01336 01337 Element& operator=(const Element&) {return *this;} 01338 }; 01339 01340 } // End of CEGUI namespace section 01341 01342 01343 #if defined(_MSC_VER) 01344 # pragma warning(pop) 01345 #endif 01346 01347 #endif // end of guard _CEGUIElement_h_