// Coords.h : type to manage windows POINT SIZE and RECTs
#pragma once
namespace GE_{namespace NWin{
struct SPoint;
struct SSize;
struct SRect;
struct SPoint: public POINT
{
SPoint() { x = y = 0; };
SPoint(LONG x_, LONG y_) { x = x_; y = y_; };
SPoint(const POINT& p) { x = p.x; y = p.y; }
SPoint(const SPoint& p) { x = p.x; y = p.y; };
SPoint& operator=(const POINT& p) { x = p.x; y = p.y; return *this;}
SPoint& operator=(const SPoint& p) { x = p.x; y = p.y; return *this;}
bool operator==(const POINT& p) const { return x == p.x && y == p.y; }
bool operator<(const POINT& p) const { return x<p.x || x==p.x && y<p.y; }
SPoint(const SIZE& p) { x = p.cx; y = p.cy; }
operator LPPOINT() { return this; }
SPoint operator-(const SIZE& s) const { return SPoint(x-s.cx, y-s.cy); }
SPoint operator+(const SIZE& s) const { return SPoint(x+s.cx, y+s.cy); }
SSize operator-(const POINT& p) const ; //forwarded
bool operator == (const RECT& r) const; //fowarded
SPoint& operator-=(const SIZE& s) { x-=s.cx, y-=s.cy; return *this; }
SPoint& operator+=(const SIZE& s) { x+=s.cx, y+=s.cy; return *this; }
};
struct SSize: public SIZE
{
SSize() { cx = cy = 0; };
SSize(LONG cx_, LONG cy_) { cx = cx_; cy = cy_; };
SSize(const SIZE& p) { cx = p.cx; cy = p.cy; }
SSize(const SSize& p) { cx = p.cx; cy = p.cy; };
SSize& operator=(const SIZE& p) { cx = p.cx; cy = p.cy; return *this;}
SSize& operator=(const SSize& p) { cx = p.cx; cy = p.cy; return *this;}
bool operator==(const SIZE& p) const { return cx == p.cx && cy == p.cy; }
bool operator<(const SIZE& p) const { return cx<p.cx || cx==p.cx && cy<p.cy; }
SSize(const POINT& p) { cx = p.x; cy = p.y; }
operator LPSIZE() { return this; }
SPoint operator+(const POINT& p) const { return SPoint(p.x+cx, p.y+cy); }
SSize operator+(const SIZE& s) const { return SSize(cx+s.cx, cy+s.cy); }
SSize operator-(const SIZE& s) const { return SSize(cx-s.cx, cy-s.cy); }
SSize operator*(const SIZE& s) const { return SSize(cx*s.cx, cy*s.cy); }
SSize operator/(const SIZE& s) const { return SSize(cx/s.cx, cy/s.cy); }
SSize operator*(LONG i) const { return SSize(cx*i, cy*i); }
SSize operator/(LONG i) const { return SSize(cx/i, cy/i); }
SSize& operator+=(const SIZE& s) { cx+=s.cx, cy+=s.cy; return *this; }
SSize& operator-=(const SIZE& s) { cx-=s.cx, cy-=s.cy; return *this; }
SSize& operator*=(const SIZE& s) { cx*=s.cx, cy*=s.cy; return *this; }
SSize& operator/=(const SIZE& s) { cx/=s.cx, cy/=s.cy; return *this; }
SSize& operator*=(LONG i) { cx*=i, cy*=i; return *this; }
SSize& operator/=(LONG i) { cx/=i, cy/=i; return *this; }
SSize operator+() const { return *this; }
SSize operator-() const { return SSize(-cx, -cy); }
};
struct SRect: public RECT
{
SRect() { ::SetRectEmpty(this); }
SRect(LONG l, LONG t, LONG r, LONG b) { left=l; top=t; right=r; bottom=b; }
SRect(const POINT& p, const SIZE& s) { left=p.x; top=p.y; right=left+s.cx; bottom=top+s.cy; }
SRect(const RECT& r) { ::CopyRect(this, &r); }
SRect(const SRect& r) { ::CopyRect(this, &r); }
SRect& operator=(const SRect& t) { ::CopyRect(this, &t); return *this; }
SRect& operator=(const RECT& t) { ::CopyRect(this, &t); return *this; }
SRect operator | (const RECT& r) const {SRect d; ::UnionRect(&d, this, &r); return d;}
SRect operator & (const RECT& r) const {SRect d; ::IntersectRect(&d, this, &r); return d;}
SRect operator + (const SIZE& s) const {SRect d(*this); ::OffsetRect(&d, s.cx, s.cy); return d;}
SRect operator - (const SIZE& s) const {SRect d(*this); ::OffsetRect(&d, -s.cx, -s.cy); return d;}
SRect operator - (const RECT& r) const {SRect d; ::SubtractRect(&d, this, &r); return d;}
SRect& operator |= (const RECT& r) {::UnionRect(this, this, &r); return *this;}
SRect& operator &= (const RECT& r) {::IntersectRect(this, this, &r); return *this;}
SRect& operator += (const SIZE& s) {::OffsetRect(this, s.cx, s.cy); return *this;}
SRect& operator -= (const SIZE& s) {::OffsetRect(this, -s.cx, -s.cy); return *this;}
SRect& operator -= (const RECT& r) {::SubtractRect(this, this, &r); return *this;}
bool operator!() const { return 0!=::IsRectEmpty(this); }
bool operator == (const RECT& r) const { return 0!=::EqualRect(this, &r); }
bool operator == (const POINT& p) const { return 0!=::PtInRect(this, p); }
bool operator < (const RECT& r) const //for collection sorting only: lexicographic ordering
{ for(int i=0; i<3; i++) if((&left)[i] != (&r.left)[i]) break; return (&left)[i] < (&r.left)[i]; }
void NormalizeRect()
{ if(right<left) std::swap(left,right); if(bottom<top) std::swap(top,bottom); }
operator LPRECT() { return this;}
operator LPCRECT() const {return this;}
LONG Width() const { return right-left; }
LONG Height() const { return bottom-top; }
SSize Size() const { return SSize(Width(), Height()); }
enum e_points {
pt_topleft, pt_topright, pt_bottomleft, pt_bottomright,
pt_centertop, pt_centerbottom, pt_centerleft, pt_centerright,
pt_center};
SPoint Point(e_points pt)
{
switch (pt)
{
case pt_topleft:
return SPoint(left,top);
case pt_topright:
return SPoint(right,top);
case pt_bottomleft:
return SPoint(left,bottom);
case pt_bottomright:
return SPoint(right,bottom);
case pt_centertop:
return SPoint((right-left)/2, top);
case pt_centerbottom:
return SPoint((right-left)/2, bottom);
case pt_centerleft:
return SPoint(left, (bottom-top)/2);
case pt_centerright:
return SPoint(right, (bottom-top)/2);
case pt_center:
return SPoint((right-left)/2, (bottom-top)/2);
};
return SPoint(0,0);
}
};
inline SSize SPoint::operator- (const POINT& p) const { return SSize(x-p.x, y-p.y); }
inline bool SPoint::operator == (const RECT& r) const { return 0!=::PtInRect(&r, *this); }
}}
inline GE_::NWin::SSize operator*(LONG i, const SIZE& s)
{ return GE_::NWin::SSize(i*s.cx, i*s.cy); }
inline GE_::NWin::SSize operator/(LONG i, const SIZE& s)
{ return GE_::NWin::SSize(i/s.cx, i/s.cy); }