1 // -*- C++ -*- 2 /* GG is a GUI for OpenGL. 3 Copyright (C) 2003-2008 T. Zachary Laine 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public License 7 as published by the Free Software Foundation; either version 2.1 8 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free 17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 02111-1307 USA 19 20 If you do not wish to comply with the terms of the LGPL please 21 contact the author as other terms are available for a fee. 22 23 Zach Laine 24 whatwasthataddress@gmail.com */ 25 26 /** \file PtRect.h \brief Contains the utility classes Pt and Rect. */ 27 28 #ifndef _GG_PtRect_h_ 29 #define _GG_PtRect_h_ 30 31 #include <GG/Base.h> 32 #include <GG/StrongTypedef.h> 33 #include <boost/functional/hash.hpp> 34 35 36 namespace GG { 37 38 /** \class GG::X 39 \brief The x-coordinate value type. 40 41 X has an underlying value type of int. \see GG_STRONG_INTEGRAL_TYPEDEF */ 42 GG_STRONG_INTEGRAL_TYPEDEF(X, int); 43 44 /** \class GG::Y 45 \brief The y-coordinate value type. 46 47 Y has an underlying value type of int. \see GG_STRONG_INTEGRAL_TYPEDEF */ 48 GG_STRONG_INTEGRAL_TYPEDEF(Y, int); 49 50 // some useful coordinate constants 51 extern GG_API const X X0; 52 extern GG_API const X X1; 53 extern GG_API const Y Y0; 54 extern GG_API const Y Y1; 55 56 /** \brief A GG screen coordinate class. */ 57 struct GG_API Pt 58 { 59 /** \name Structors */ ///@{ 60 Pt(); 61 62 Pt(X x_, Y y_); ///< Ctor that creates a Pt ( \a _x , \a y ). 63 Pt(X_d x_, Y y_); ///< Ctor that creates a Pt ( \a _x , \a y ). 64 Pt(X x_, Y_d y_); ///< Ctor that creates a Pt ( \a _x , \a y ). 65 Pt(X_d x_, Y_d y_); ///< Ctor that creates a Pt ( \a _x , \a y ). 66 //@} 67 68 /** \name Accessors */ ///@{ 69 /** Returns true if x < \a rhs.x or returns true if x == \a rhs.x and y 70 <\a rhs.y. This is useful for sorting Pts in STL containers and 71 algorithms. */ LessPt72 bool Less(const Pt& rhs) const 73 { return x < rhs.x ? true : (x == rhs.x ? (y < rhs.y ? true : false) : false); } 74 //@} 75 76 /** \name Mutators */ ///@{ 77 void operator+=(const Pt& rhs) { x += rhs.x; y += rhs.y; } ///< Adds \a rhs to Pt. 78 void operator-=(const Pt& rhs) { x -= rhs.x; y -= rhs.y; } ///< Subtracts \a rhs from Pt. 79 Pt operator-() const { return Pt(-x, -y); } ///< Negates Pt. 80 Pt operator/=(const double rhs) { return Pt(x / rhs, y / rhs); }///< Devides components of Pt by \a rhs 81 Pt operator*=(const double rhs) { return Pt(x * rhs, y * rhs); }///< Devides components of Pt by \a rhs 82 //@} 83 84 X x; ///< The x component. 85 Y y; ///< The y component. 86 }; 87 88 GG_API std::ostream& operator<<(std::ostream& os, const Pt& pt); 89 90 91 /** \brief A GG rectangle class. 92 93 This is essentially just two points that bound the rectangle. */ 94 struct GG_API Rect 95 { 96 /** \name Structors */ ///@{ 97 Rect(); 98 99 Rect(const Pt& pt1, const Pt& pt2); ///< ctor that constructs a Rect from two corners; any two opposing corners will do 100 Rect(X x1, Y y1, X x2, Y y2); ///< ctor that constructs a Rect from its left, upper, right, and bottom boundaries 101 //@} 102 103 /** \name Accessors */ ///@{ LeftRect104 X Left() const { return ul.x; } ///< returns the left boundary of the Rect RightRect105 X Right() const { return lr.x; } ///< returns the right boundary of the Rect TopRect106 Y Top() const { return ul.y; } ///< returns the top boundary of the Rect BottomRect107 Y Bottom() const { return lr.y; } ///< returns the bottom boundary of the Rect UpperLeftRect108 Pt UpperLeft() const { return ul; } ///< returns the upper-left corner of the Rect LowerRightRect109 Pt LowerRight() const { return lr; } ///< returns the lower-right corner of the Rect WidthRect110 X Width() const { return lr.x - ul.x; } ///< returns the width of the Rect HeightRect111 Y Height() const { return lr.y - ul.y; } ///< returns the height of the Rect MidXRect112 X MidX() const { return (lr.x + ul.x)/2; } ///< returns the horizontal mid-point of the Rect MidYRect113 Y MidY() const { return (lr.y + ul.y)/2; } ///< returns the vertical mid-point of the Rect 114 115 116 bool Contains(const Pt& pt) const; ///< returns true iff \a pt falls inside the Rect 117 //@} 118 119 /** \name Mutators */ ///@{ 120 void operator+=(const Pt& pt) { ul += pt; lr += pt; } ///< shifts the Rect by adding \a pt to each corner 121 void operator-=(const Pt& pt) { ul -= pt; lr -= pt; } ///< shifts the Rect by subtracting \a pt from each corner 122 //@} 123 124 Pt ul; ///< the upper-left corner of the Rect 125 Pt lr; ///< the lower-right corner of the Rect 126 }; 127 128 GG_API inline bool operator==(const Pt& lhs, const Pt& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; } ///< returns true if \a lhs is identical to \a rhs 129 GG_API inline bool operator!=(const Pt& lhs, const Pt& rhs) { return !(lhs == rhs); } ///< returns true if \a lhs differs from \a rhs 130 GG_API inline bool operator<(const Pt& lhs, const Pt& rhs) { return lhs.x < rhs.x && lhs.y < rhs.y; } ///< returns true if \a lhs.x and \a lhs.y are both less than the corresponding components of \a rhs 131 GG_API inline bool operator>(const Pt& lhs, const Pt& rhs) { return lhs.x > rhs.x && lhs.y > rhs.y; } ///< returns true if \a lhs.x and \a lhs.y are both greater than the corresponding components of \a rhs 132 GG_API inline bool operator<=(const Pt& lhs, const Pt& rhs) { return lhs.x <= rhs.x && lhs.y <= rhs.y; } ///< returns true if \a lhs.x and \a lhs.y are both less than or equal to the corresponding components of \a rhs 133 GG_API inline bool operator>=(const Pt& lhs, const Pt& rhs) { return lhs.x >= rhs.x && lhs.y >= rhs.y; } ///< returns true if \a lhs.x and \a lhs.y are both greater than or equal to the corresponding components of \a rhs 134 GG_API inline Pt operator+(const Pt& lhs, const Pt& rhs) { return Pt(lhs.x + rhs.x, lhs.y + rhs.y); } ///< returns the vector sum of \a lhs and \a rhs 135 GG_API inline Pt operator-(const Pt& lhs, const Pt& rhs) { return Pt(lhs.x - rhs.x, lhs.y - rhs.y); } ///< returns the vector difference of \a lhs and \a rhs 136 GG_API inline Pt operator*(const Pt& lhs, double rhs) { return Pt(lhs.x * rhs, lhs.y * rhs); } ///< returns the vector with components multiplied by \a rhs 137 GG_API inline Pt operator/(const Pt& lhs, double rhs) { return Pt(lhs.x / rhs, lhs.y / rhs); } ///< returns the vector with components divided by \a rhs 138 139 GG_API std::ostream& operator<<(std::ostream& os, const Pt& pt); ///< Pt stream-output operator for debug output 140 141 /** returns true if \a lhs is identical to \a rhs */ 142 GG_API inline bool operator==(const Rect& lhs, const Rect& rhs) { return lhs.ul.x == rhs.ul.x && lhs.lr.x == rhs.lr.x && lhs.ul.y == rhs.ul.y && lhs.lr.y == rhs.lr.y; } 143 144 /** returns true if \a lhs differs from \a rhs */ 145 GG_API inline bool operator!=(const Rect& lhs, const Rect& rhs) { return !(lhs == rhs); } 146 147 GG_API inline Rect operator+(const Rect& rect, const Pt& pt) { return Rect(rect.ul + pt, rect.lr + pt); } ///< returns \a rect shifted by adding \a pt to each corner 148 GG_API inline Rect operator-(const Rect& rect, const Pt& pt) { return Rect(rect.ul - pt, rect.lr - pt); } ///< returns \a rect shifted by subtracting \a pt from each corner 149 GG_API inline Rect operator+(const Pt& pt, const Rect& rect) { return rect + pt; } ///< returns \a rect shifted by adding \a pt to each corner 150 GG_API inline Rect operator-(const Pt& pt, const Rect& rect) { return rect - pt; } ///< returns \a rect shifted by subtracting \a pt from each corner 151 152 GG_API std::ostream& operator<<(std::ostream& os, const Rect& rect); ///< Rect stream-output operator for debug output 153 154 // Hash functions 155 // Replace with C++11 equilvalent when converted to C++11 hash_value(X const & x)156 GG_API inline std::size_t hash_value(X const& x) { return boost::hash<int>()(Value(x)); } hash_value(Y const & y)157 GG_API inline std::size_t hash_value(Y const& y) { return boost::hash<int>()(Value(y)); } hash_value(Pt const & pt)158 GG_API inline std::size_t hash_value(Pt const& pt) { 159 std::size_t seed(0); 160 boost::hash_combine(seed, pt.x); 161 boost::hash_combine(seed, pt.y); 162 return seed; 163 } hash_value(Rect const & r)164 GG_API inline std::size_t hash_value(Rect const& r) { 165 std::size_t seed(0); 166 boost::hash_combine(seed, r.ul); 167 boost::hash_combine(seed, r.lr); 168 return seed; 169 } 170 171 } // namepace GG 172 173 #endif 174