CtrlCore: RectTracker improvements

git-svn-id: svn://ultimatepp.org/upp/trunk@14458 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2020-05-12 13:30:54 +00:00
parent 69b774a57e
commit 0af98b4d73
3 changed files with 77 additions and 19 deletions

View file

@ -1520,6 +1520,7 @@ protected:
Rect Round(const Rect& r);
virtual void RefreshRect(const Rect& old, const Rect& r);
virtual void DrawRect(Draw& w, Rect r1);
public:
@ -1543,9 +1544,10 @@ public:
Rect Get() { return rect; }
Rect Track(const Rect& r, int tx = ALIGN_RIGHT, int ty = ALIGN_BOTTOM);
int TrackHorzLine(int x0, int y0, int cx, int line);
int TrackVertLine(int x0, int y0, int cy, int line);
Rect Track(const Rect& r, int tx = ALIGN_RIGHT, int ty = ALIGN_BOTTOM);
int TrackHorzLine(int x0, int y0, int cx, int line);
int TrackVertLine(int x0, int y0, int cy, int line);
Point TrackLine(int x0, int y0);
RectTracker(Ctrl& master);
};

View file

@ -27,6 +27,19 @@ void LocalLoop::CancelMode()
EndLoop();
}
static void sPaintView(Draw& w, Ctrl& m)
{
m.Paint(w);
for(Ctrl *q = m.GetFirstChild(); q; q = q->GetNext()) {
Rect r = q->GetRect();
if(q->IsShown() && q->InView() && w.IsPainting(r)) {
w.Offset(r.TopLeft());
sPaintView(w, *q);
w.End();
}
}
}
RectTracker::RectTracker(Ctrl& master)
{
op = GetMousePos();
@ -35,7 +48,7 @@ RectTracker::RectTracker(Ctrl& master)
LTIMESTOP("--- snapshot");
LDUMP(master.GetSize());
ImageDraw iw(master.GetSize());
master.Paint(iw);
sPaintView(iw, master);
master_image = iw;
}
Clip(Rect(0, 0, 100000, 100000));
@ -68,6 +81,22 @@ Image RectTracker::CursorImage(Point, dword)
return cursorimage;
}
void RectTracker::RefreshRect(const Rect& old, const Rect& r)
{
if(r.Normalized() == r && (tx >= 0 || ty >= 0)) {
auto Ref = [&](const Rect& r) {
Refresh(r.left, r.top, r.Width(), width);
Refresh(r.left, r.top, width, r.GetHeight());
Refresh(r.left, r.bottom - width, r.Width(), width);
Refresh(r.right - width, r.top, width, r.GetHeight());
};
Ref(old);
Ref(r);
}
else
Refresh();
}
void RectTracker::DrawRect(Draw& w, Rect r)
{
DrawDragFrame(w, r, width, pattern, color, animation ? (msecs() / animation) % 8 : 0);
@ -81,14 +110,25 @@ void RectTracker::Paint(Draw& w)
}
w.Clip(clip & GetMaster().GetSize());
Rect r = rect;
if(ty < 0)
r.left = r.right - 1;
else
if(tx < 0)
r.top = r.bottom - 1;
else
r.Normalize();
DrawRect(w, r);
if(tx < 0 && ty < 0) {
if(width > 1 || pattern == DRAWDRAGRECT_SOLID)
w.DrawLine(r.TopLeft(), r.BottomRight(), width, color);
else {
Color color2 = IsDark(color) ? White() : Black();
w.DrawLine(r.TopLeft(), r.BottomRight(), 1, color2);
w.DrawLine(r.TopLeft(), r.BottomRight(), pattern == DRAWDRAGRECT_DASHED ? PEN_DASH : PEN_DOT, color);
}
}
else {
if(ty < 0)
r.left = r.right - 1;
else
if(tx < 0)
r.top = r.bottom - 1;
else
r.Normalize();
DrawRect(w, r);
}
w.End();
}
@ -113,6 +153,11 @@ int RectTracker::TrackVertLine(int x0, int y0, int cy, int line)
return Track(RectC(x0, y0, line + 1, cy), ALIGN_RIGHT, -1).right - 1;
}
Point RectTracker::TrackLine(int x0, int y0)
{
return Track(Rect(x0, y0, x0, y0), -1, -1).BottomRight();
}
Rect RectTracker::Round(const Rect& r)
{
Rect h = r;
@ -121,11 +166,16 @@ Rect RectTracker::Round(const Rect& r)
return rounder ? rounder->Round(h) : h;
}
void RectTracker::MouseMove(Point, dword)
void RectTracker::MouseMove(Point mp, dword)
{
Point p = GetMousePos();
rect = org;
if(tx == ALIGN_CENTER && ty == ALIGN_CENTER) {
if(tx < 0 && ty < 0) { // free line mode
rect.right = mp.x;
rect.bottom = mp.y;
}
else
if(tx == ALIGN_CENTER && ty == ALIGN_CENTER) { // move rectangle
int x = org.left - op.x + p.x;
int y = org.top - op.y + p.y;
if(x + org.Width() > maxrect.right)
@ -190,7 +240,7 @@ void RectTracker::MouseMove(Point, dword)
if(rect != o) {
rect = Round(rect);
if(rect != o) {
Refresh();
RefreshRect(rect, o);
sync(rect);
o = rect;
}

View file

@ -90,7 +90,7 @@ lor]([_^Color^ Color]_[*@3 c])&]
[s3;%% &]
[s4; &]
[s5;:RectTracker`:`:Normal`(`): [_^RectTracker^ RectTracker][@(0.0.255) `&]_[* Normal]()&]
[s2;%% Same as Pattern(DRAWDRAGRECT`_NORMAL).&]
[s2;%% Same as Pattern(DRAWDRAGRECT`_NORMAL). This is default.&]
[s3; &]
[s4; &]
[s5;:RectTracker`:`:Animation`(int`): [_^RectTracker^ RectTracker][@(0.0.255) `&]_[* Animat
@ -156,7 +156,7 @@ specify which edge or corner of rectangle is being changed:&]
[s5;:RectTracker`:`:TrackHorzLine`(int`,int`,int`,int`): [@(0.0.255) int]_[* TrackHorzLin
e]([@(0.0.255) int]_[*@3 x0], [@(0.0.255) int]_[*@3 y0], [@(0.0.255) int]_[*@3 cx],
[@(0.0.255) int]_[*@3 line])&]
[s2;%% Performs tracking look of horizontal line. [%-*@3 x0], [%-*@3 y0]
[s2;%% Performs tracking loop of horizontal line. [%-*@3 x0], [%-*@3 y0]
is base point, [%-*@3 cx] the width of line, [%-*@3 line] the current
position. Returns the new position.&]
[s3;%% &]
@ -164,11 +164,17 @@ position. Returns the new position.&]
[s5;:RectTracker`:`:TrackVertLine`(int`,int`,int`,int`): [@(0.0.255) int]_[* TrackVertLin
e]([@(0.0.255) int]_[*@3 x0], [@(0.0.255) int]_[*@3 y0], [@(0.0.255) int]_[*@3 cy],
[@(0.0.255) int]_[*@3 line])&]
[s2;%% Performs tracking look of vertical line. [%-*@3 x0], [%-*@3 y0]
is base point, [%-*@3 cy] the height of line, [%-*@3 line] the current
[s2;%% Performs tracking loop of vertical line. [%-*@3 x0], [%-*@3 y0]
is base point, [%-*@3 cy] the width of line, [%-*@3 line] the current
position. Returns the new position.&]
[s3;%% &]
[s4; &]
[s5;:Upp`:`:RectTracker`:`:TrackLine`(int`,int`): [_^Upp`:`:Point^ Point]_[* TrackLine]([@(0.0.255) i
nt]_[*@3 x0], [@(0.0.255) int]_[*@3 y0])&]
[s2;%% Performs tracking loop of line from the point [%-*@3 x0] [%-*@3 y0].
Returns the new endpoint.&]
[s3;%% &]
[s4; &]
[s5;:RectTracker`:`:RectTracker`(Ctrl`&`): [* RectTracker]([_^Ctrl^ Ctrl][@(0.0.255) `&]_[*@3 m
aster])&]
[s2;%% Constructs RectTracker, the view area of [%-*@3 master] is used