ultimatepp/bazaar/RectCtrl/RectCtrl.cpp
kohait a49d80d46d bazaar: Major CtrlFinder/CtrlMover/CtrlPos fixes/changes and support for multiple controls find, marked with a RectTrack
added some comments for LogPosCtrl, some small fixes in RectCtrl

git-svn-id: svn://ultimatepp.org/upp/trunk@5426 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2012-10-13 22:12:43 +00:00

261 lines
6.4 KiB
C++

#include "RectCtrl.h"
#define IMAGECLASS Img
#define IMAGEFILE <RectCtrl/icons.iml>
#include <Draw/iml_source.h>
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<Point> 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();
}