ultimatepp/bazaar/PointCtrl/PointCtrl.cpp

163 lines
3.2 KiB
C++

#include "PointCtrl.h"
CH_STYLE(PointCtrl, Style, StyleDefault)
{
backcol = SColorPaper();
linecol = Blue();
pointcol = LtRed();
linesize = 1;
pointsize = 4;
}
PointCtrl::PointCtrl()
: pressed(false), moving(false), di(-1)
{
style = &StyleDefault();
sxp.Clear();
xp.SetNull();
vsx.MinMax(0,100);
vsy.MinMax(0,100);
for(int i = 0; i < 10; i++)
vpd.Add().col = HsvColorf(i/(double)10, 1.0, 1.0);
Update();
}
void PointCtrl::Paint(Draw& w)
{
w.DrawRect(sz, style->backcol);
//points
for(int i = 0; i < vp.GetCount(); i++)
{
const XY& _dp = vp[i];
XY _p((int) psx(vsx, _dp.x), (int) psy(vsy, _dp.y));
const PData& pd = vpd.At(i);
Rect r(_p,_p); r.Inflate(pd.size);
w.DrawEllipse(r, pd.col);
}
//cross
if(!xp.IsNullInstance() && IsEnabled() && IsEditable())
{
w.DrawLine(xp.x-3,xp.y, xp.x+3+1,xp.y, style->linesize, style->linecol);
w.DrawLine(xp.x,xp.y-3, xp.x,xp.y+3+1, style->linesize, style->linecol);
//target lines
if(pressed && moving)
{
w.DrawLine(0,xp.y, sz.cx,xp.y, style->linesize, style->linecol);
w.DrawLine(xp.x,0, xp.x,sz.cy, style->linesize, style->linecol);
}
}
//square
Rect r(sxp, sxp); r.Inflate(style->pointsize);
Vector<Point> vp;
vp << r.TopLeft() << r.TopRight() << r.BottomRight() << r.BottomLeft() << r.TopLeft();
w.DrawPolyline(vp, style->linesize, style->pointcol);
//dot
w.DrawLine(sxp.x, sxp.y, sxp.x, sxp.y, 2, style->pointcol);
}
void PointCtrl::LeftDown(Point p, dword keyflags)
{
moving = false;
if(IsReadOnly() || !IsEnabled()) return;
SetCapture();
pressed = (keyflags & K_MOUSELEFT);
xp = p;
sxp = xp;
//point drag
for(int i = 0; i < vp.GetCount(); i++)
{
XY& _dp = vp[i];
Point _p(int(psx(vsx, _dp.x)), int(psy(vsy, _dp.y)));
Rect r(_p, _p); r.Inflate(4);
if(!r.Contains(p)) continue;
di = i; break;
}
UpdateActionRefresh();
}
void PointCtrl::LeftRepeat(Point p, dword keyflags)
{
if(moving) return;
if(IsReadOnly() || !IsEnabled()) return;
if(di<0 && !(keyflags & K_CTRL))
{
di = vp.GetCount();
XY& _dp = vp.Add(XY(vsx(psx, sxp.x), vsy(psy, sxp.y)));
WhenAddPoint();
}
else if(di>=0 && (keyflags & K_CTRL))
{
vp.Remove(di);
WhenRemovePoint(di);
di = -1;
moving = true;
}
else return;
Refresh();
}
void PointCtrl::MouseMove(Point p, dword keyflags)
{
if(IsReadOnly() || !IsEnabled()) return;
moving = true;
pressed = (keyflags & K_MOUSELEFT);
//clip
Point pp(minmax(p.x, 0, sz.cx), minmax(p.y, 0, sz.cy));
if(xp == pp) return;
xp = pp;
if(pressed)
{
sxp = xp;
if(di>=0)
{
vp[di] = XY(vsx(psx, sxp.x), vsy(psy, sxp.y));
WhenMovePoint(di);
}
UpdateActionRefresh();
}
else Refresh();
}
void PointCtrl::LeftUp(Point p, dword keyflags)
{
pressed = false;
moving = false;
if(IsReadOnly() || !IsEnabled()) return;
ReleaseCapture();
di = -1;
xp.SetNull();
Refresh();
}
void PointCtrl::Layout()
{
sz = GetSize();
psx.MinMax(0, sz.cx);
psy.MinMax(0, sz.cy);
UpdatedBack();
Refresh();
}
void PointCtrl::Updated()
{
vxp = XY(vsx(psx, sxp.x), vsy(psy, sxp.y));
}
void PointCtrl::UpdatedBack()
{
sxp = Point(int(psx(vsx, vxp.x)), int(psy(vsy, vxp.y)));
}