#include "RectCtrl.h" #define IMAGECLASS Img #define IMAGEFILE #include CH_STYLE(RectCtrl, Style, StyleDefault) { rectcol = Cyan; handcol = SColorHighlight(); handsize = 2; framecol = SColorHighlight(); framesize = 1; textcol = SColorPaper(); } Rect RectCtrl::HandleAt(const Point& p, int size) { Rect q(p,p); q.Inflate(size); return q; } void RectCtrl::DrawHandle(Draw& w, const Rect& r, const Color& col, int size) { w.DrawRect(HandleAt(r.CenterPoint(), size), col); w.DrawRect(HandleAt(r.TopLeft(), size), col); w.DrawRect(HandleAt(r.BottomRight(), size), col); w.DrawRect(HandleAt(r.TopRight(), size), col); w.DrawRect(HandleAt(r.BottomLeft(), size), col); w.DrawRect(HandleAt(r.CenterLeft(), size), col); w.DrawRect(HandleAt(r.CenterRight(), size), col); w.DrawRect(HandleAt(r.TopCenter(), size), col); w.DrawRect(HandleAt(r.BottomCenter(), size), col); } void RectCtrl::DrawHandleFrame(Draw& w, const Rect& _r, const Color& col, int size) { Rect r(_r); --r.right; --r.bottom; Vector vp; vp << r.TopLeft() << r.TopRight() << r.BottomRight() << r.BottomLeft() << r.TopLeft(); w.DrawPolyline(vp, size, col); } void RectCtrl::DrawRectInfo(Draw& w, const Point& p, const Rect&r, const Color& framecol, const Color& textcol) { String t = AsString(r); Size tsz = GetTextSize(t, StdFont()); w.DrawRect(p.x-2, p.y-2, tsz.cx+4, tsz.cy+4, framecol); w.DrawText(p.x, p.y, t, StdFont(), textcol); } int RectCtrl::GetMode(const Rect& r, const Point& p, dword keyflags, int handsize) { int size = handsize+2; Rect q = r; q.Inflate(size); if(!q.Contains(p)) return NONE; if(HandleAt(r.CenterPoint(), size).Contains(p)) return CENTER; if(HandleAt(r.TopLeft(), size).Contains(p)) return LEFTTOP; if(HandleAt(r.BottomRight(), size).Contains(p)) return RIGHTBOTTOM; if(HandleAt(r.TopRight(), size).Contains(p)) return RIGHTTOP; if(HandleAt(r.BottomLeft(), size).Contains(p)) return LEFTBOTTOM; if(HandleAt(r.CenterLeft(), size).Contains(p)) return LEFT; if(HandleAt(r.CenterRight(), size).Contains(p)) return RIGHT; if(HandleAt(r.TopCenter(), size).Contains(p)) return TOP; if(HandleAt(r.BottomCenter(), size).Contains(p)) return BOTTOM; return MOVE; } void RectCtrl::CalcRect(Rect& r, const Point& dp, dword keyflags, int mode, const Point& g) { if(mode == NONE) return; Point p = dp; int m = mode; if(!(keyflags & K_ALT)) m |= GRID; if(m & GRIDX) p.x = p.x/g.x*g.x; if(m & GRIDY) p.y = p.y/g.y*g.y; if(keyflags & K_CTRL) { double dYdX = double(r.Height())/r.Width(); switch(m & ALL) { case LEFTTOP: case RIGHTBOTTOM: p.y = int(p.x*double(r.Height())/r.Width()); break; case RIGHTTOP: case LEFTBOTTOM: p.y = -int(p.x*double(r.Height())/r.Width()); break; case LEFT: m |= TOP; p.y = int(p.x*double(r.Height())/r.Width()); break; case BOTTOM: m |= RIGHT; p.x = int(p.y*double(r.Width())/r.Height()); break; case RIGHT: m |= BOTTOM; p.y = int(p.x*double(r.Height())/r.Width()); break; case TOP: m |= LEFT; p.x = int(p.y*double(r.Width())/r.Height()); break; } } if(keyflags & K_SHIFT) { if(m & LEFT) m |= _RIGHT; if(m & RIGHT) m |= _LEFT; if(m & TOP) m |= _BOTTOM; if(m & BOTTOM)m |= _TOP; } if(m & LEFT) r.left += p.x; if(m & RIGHT) r.right += p.x; if(m & TOP) r.top += p.y; if(m & BOTTOM) r.bottom += p.y; if(m & _LEFT) r.left -= p.x; if(m & _RIGHT) r.right -= p.x; if(m & _TOP) r.top -= p.y; if(m & _BOTTOM)r.bottom -= p.y; } Image RectCtrl::SetCursor(unsigned m, dword keyflags, const Image& old) { switch(m & (ALL | _ALL)) { case LEFTTOP: return OverrideCursor(Img::ltrb()); case RIGHTBOTTOM: return OverrideCursor(Img::ltrb()); case RIGHTTOP: return OverrideCursor(Img::rtlb()); case LEFTBOTTOM: return OverrideCursor(Img::rtlb()); case LEFT: return OverrideCursor(Img::lr()); case BOTTOM: return OverrideCursor(Img::tb()); case RIGHT: return OverrideCursor(Img::lr()); case TOP: return OverrideCursor(Img::tb()); case CENTER: return OverrideCursor(Img::fr()); case ALL: if(keyflags & K_MOUSELEFT) return OverrideCursor(Img::mv()); //fall through default: OverrideCursor(old); return Null; } } void RectCtrl::Paint(Draw& w) { Size sz = GetSize(); if(r.IsNullInstance()) return; if(IsEnabled()) w.DrawRect(r, style->rectcol); DrawHandleFrame(w, r, style->framecol, style->framesize); if(!IsEnabled() || IsReadOnly()) return; DrawHandle(w, r, style->handcol, style->handsize); if(pressed)// && moving) DrawRectInfo(w, Point(10,10), r, style->framecol, style->textcol); } void RectCtrl::LeftDown(Point p, dword keyflags) { if(IsReadOnly() || !IsEnabled()) return; SetCapture(); moving = false; pressed = (keyflags & K_MOUSELEFT); xr = r; xp = p; mode = GetMode(r, p, keyflags, style->handsize); c = SetCursor(mode, keyflags, c); if(mode == NONE) WhenMissed(p, keyflags); Refresh(); } void RectCtrl::MouseMove(Point p, dword keyflags) { if(IsReadOnly() || !IsEnabled()) return; moving = true; pressed = (keyflags & K_MOUSELEFT); if(pressed && mode != NONE) { r = xr; CalcRect(r, p-xp, keyflags, mode, g); r.Normalize(); //if flipped UpdateActionRefresh(); } else { int m = GetMode(r, p, keyflags, style->handsize); if(m != mode) { mode = m; c = SetCursor(mode, keyflags, c); } } } void RectCtrl::LeftUp(Point p, dword keyflags) { ReleaseCapture(); pressed = false; moving = false; xr.SetNull(); xp.SetNull(); mode = NONE; if(IsReadOnly() || !IsEnabled()) return; c = SetCursor(mode, keyflags, c); Refresh(); } void RectCtrl::RightDown(Point p, dword keyflags) { //cancel ReleaseCapture(); int m = mode; mode = NONE; if(IsReadOnly() || !IsEnabled()) return; c = SetCursor(mode, keyflags, c); if(pressed) { if(m != NONE) { r = xr; UpdateActionRefresh(); } } else { pressed = false; moving = false; xr.SetNull(); xp.SetNull(); //mode = NONE; RectTracker tr(*this); r = tr.Track(Rect(p,p)); UpdateActionRefresh(); } } void RectCtrl::Updated() { } RectCtrl::RectCtrl() : pressed(false), moving(false), mode(NONE), g(4,4) { Transparent(); //BackPaint(); style = &StyleDefault(); r.SetNull(); xr.SetNull(); xp.SetNull(); }