(svn r8982) [cpp_gui] -Codechange: when moving Point by given offset, the offset can now be of different type (i.e. int16 vs. int32)
/* $Id$ */
#ifndef RECT_H
#define RECT_H
/** Template based point without ctor/dtor (raw) for use in unions */
template <typename T> struct PointRawT {
T x, y;
PointRawT operator -() const
{
PointRawT pt = {-x, -y};
return pt;
}
};
/** Template based point */
template <typename T> struct PointT : public PointRawT<T> {
typedef PointRawT<T> PointRaw;
PointT(T x_a = 0, T y_a = 0)
{
PointRaw::x = x_a;
PointRaw::y = y_a;
}
template <typename Ta> PointT(const PointRawT<Ta> &src)
{
PointRaw::x = (T)src.x;
PointRaw::y = (T)src.y;
}
PointT& operator =(const PointRaw &src)
{
PointRaw::x = (T)src.x;
PointRaw::y = (T)src.y;
return *this;
}
bool operator ==(const PointRaw &other) const
{
return PointRaw::x == other.x && PointRaw::y == other.y;
}
PointT operator -() const
{
return PointT(-PointRaw::x, -PointRaw::y);
}
void DoMove(T dx, T dy)
{
PointRaw::x += dx;
PointRaw::y += dy;
}
template <typename T2> void DoMove(const PointRawT<T2> &offset)
{
DoMove((T)offset.x, (T)offset.y);
}
template <typename T2> PointT operator +(const PointRawT<T2> &offset) const
{
PointT pt(*this);
pt.DoMove(offset);
return pt;
}
template <typename T2> PointT operator -(const PointRawT<T2> &offset) const
{
PointT pt(*this);
pt.DoMove(-offset);
return pt;
}
PointT& operator +=(const PointRaw &offset)
{
DoMove(offset);
return *this;
}
PointT& operator -=(const PointRaw &offset)
{
DoMove(-offset);
return *this;
}
PointT operator *(T coef) const
{
return PointT(PointRaw::x * coef, PointRaw::y * coef);
}
PointT operator /(T coef) const
{
return PointT(PointRaw::x / coef, PointRaw::y / coef);
}
};
/** Template based rectangle */
template <typename T> struct RectT
{
typedef PointRawT<T> PointRaw;
PointT<T> top_left, bottom_right;
RectT(T left = 0, T top = 0, T right = 0, T bottom = 0)
: top_left(left, top), bottom_right(right, bottom)
{}
template <typename Ta> RectT(const RectT<Ta> &src)
: top_left(src.top_left), bottom_right(src.bottom_right)
{}
T Left() const
{
return top_left.x;
}
T Top() const
{
return top_left.y;
}
T Right() const
{
return bottom_right.x;
}
T Bottom() const
{
return bottom_right.y;
}
T Width() const
{
return bottom_right.x - top_left.x + 1;
}
T Height() const
{
return bottom_right.y - top_left.y + 1;
}
const PointT<T>& TopLeft() const
{
return top_left;
}
const PointT<T>& BottomRight() const
{
return bottom_right;
}
PointT<T> Size() const
{
return (bottom_right - top_left + PointT<T>(1, 1));
}
PointT<T> CenterPt() const
{
return (top_left + bottom_right + PointT<T>(1, 1)) / 2;
}
void SetLeft(T val)
{
top_left.x = val;
}
void SetTop(T val)
{
top_left.y = val;
}
void SetRight(T val)
{
bottom_right.x = val;
}
void SetBottom(T val)
{
bottom_right.y = val;
}
void SetWidth(T val)
{
bottom_right.x = top_left.x + val - 1;
}
void SetHeight(T val)
{
bottom_right.y = top_left.y + val - 1;
}
void SetTopLeft(const PointRaw &pt)
{
top_left = pt;
}
void SetBottomRight(const PointRaw &pt)
{
bottom_right = pt;
}
void SetSize(const PointRaw &pt)
{
bottom_right = top_left + pt - PointT<T>(1, 1);
}
bool PtInRect(const PointRaw &pt) const
{
return (top_left.x <= pt.x && pt.x <= bottom_right.x && top_left.y <= pt.y && pt.y <= bottom_right.y);
}
RectT& operator =(const RectT &src)
{
top_left = src.top_left;
bottom_right = src.bottom_right;
return *this;
}
void DoMove(T dx, T dy)
{
DoMove(PointT<T>(dx, dy));
}
void DoMove(const PointRaw &offset)
{
top_left.DoMove(offset);
bottom_right.DoMove(offset);
}
RectT operator +(const PointRaw &offset) const
{
RectT r(*this);
r.DoMove(offset);
return r;
}
RectT operator -(const PointRaw &offset) const
{
RectT r(*this);
r.DoMove(-offset);
return r;
}
RectT& operator +=(const PointRaw &offset)
{
DoMove(offset);
return *this;
}
RectT& operator -=(const PointRaw &offset)
{
DoMove(-offset);
return *this;
}
void DoUnion(const PointRawT<T> &pt)
{
if (pt.x < top_left.x) {
top_left.x = pt.x;
} else if (pt.x > bottom_right.x) {
bottom_right.x = pt.x;
}
if (pt.y < top_left.y) {
top_left.y = pt.y;
} else if (pt.y > bottom_right.y) {
bottom_right.y = pt.y;
}
}
void DoUnion(const RectT &rc)
{
if (rc.top_left.x < top_left.x) {
top_left.x = rc.top_left.x;
} else if (rc.bottom_right.x > bottom_right.x) {
bottom_right.x = rc.bottom_right.x;
}
if (rc.top_left.y < top_left.y) {
top_left.y = rc.top_left.y;
} else if (rc.bottom_right.y > bottom_right.y) {
bottom_right.y = rc.bottom_right.y;
}
}
};
typedef PointRawT<int> PointRaw;
typedef PointT<int16> Point16;
typedef PointT<int32> Point32;
typedef PointT<int> Point;
typedef RectT<int16> Rect16;
typedef RectT<int32> Rect32;
#endif /*RECT_H*/