mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 14:16:09 -06:00
317 lines
7.5 KiB
C++
317 lines
7.5 KiB
C++
#include "CtrlCore.h"
|
|
|
|
NAMESPACE_UPP
|
|
|
|
#define LLOG(x) // DLOG(x)
|
|
|
|
void LocalLoop::Run()
|
|
{
|
|
ASSERT(master);
|
|
master->AddChild(this);
|
|
Ptr<Ctrl> focus = GetFocusCtrl();
|
|
SetCapture();
|
|
SetFocus();
|
|
LLOG("LocalLoop::Run");
|
|
EventLoop(this);
|
|
LLOG("LocalLoop Finished");
|
|
Remove();
|
|
if(focus)
|
|
focus->SetFocus();
|
|
}
|
|
|
|
void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
|
Color color, uint64 pattern)
|
|
{
|
|
ViewDraw w(&q);
|
|
DrawDragRect(w, rect1, rect2, clip, n, color, pattern);
|
|
}
|
|
|
|
void RectTracker::LeftUp(Point, dword)
|
|
{
|
|
EndLoop();
|
|
}
|
|
|
|
void RectTracker::RightUp(Point, dword)
|
|
{
|
|
EndLoop();
|
|
}
|
|
|
|
Image RectTracker::CursorImage(Point, dword)
|
|
{
|
|
if(animation)
|
|
DrawRect(rect, rect);
|
|
return cursorimage;
|
|
}
|
|
|
|
static uint64 RectTracker_normal = I64(0x55aa55aa55aa55aa);
|
|
static uint64 RectTracker_dashed = I64(0xf0783c1e0f87c3e1);
|
|
static uint64 RectTracker_solid = I64(0);
|
|
|
|
RectTracker::RectTracker(Ctrl& master)
|
|
{
|
|
SetMaster(master);
|
|
Clip(Rect(0, 0, 100000, 100000));
|
|
width = 1;
|
|
minsize = Size(0, 0);
|
|
maxsize = Size(100000, 100000);
|
|
maxrect = Rect(-100000, -100000, 100000, 100000);
|
|
keepratio = false;
|
|
cursorimage = Image::Arrow();
|
|
color = SColorPaper;
|
|
pattern = RectTracker_normal;
|
|
animation = 0;
|
|
rounder = NULL;
|
|
}
|
|
|
|
RectTracker::~RectTracker() {}
|
|
|
|
RectTracker& RectTracker::Dashed() { pattern = RectTracker_dashed; return *this; }
|
|
RectTracker& RectTracker::Solid() { pattern = RectTracker_solid; return *this; }
|
|
|
|
static uint64 sGetAniPat(uint64 src, int pos)
|
|
{
|
|
uint64 out = 0;
|
|
pos &= 7;
|
|
for(int i = 8; --i >= 0;) {
|
|
byte sr = (byte)(src >> (8 * ((7 - i - pos) & 7)));
|
|
out = (out << 8) | (byte)((sr | (sr << 8)) >> pos);
|
|
}
|
|
return out;
|
|
}
|
|
|
|
void RectTracker::DrawRect(Rect r1, Rect r2)
|
|
{
|
|
if(ty < 0) {
|
|
r1.left = r1.right - 1;
|
|
r2.left = r2.right - 1;
|
|
}
|
|
if(tx < 0) {
|
|
r1.top = r1.bottom - 1;
|
|
r2.top = r2.bottom - 1;
|
|
}
|
|
Rect c = clip & GetMaster().GetSize();
|
|
if(animation) {
|
|
int nanim = (GetTickCount() / animation) % 8;
|
|
DrawDragRect(GetMaster(), Rect(0, 0, 0, 0), r2, c, width, color, sGetAniPat(pattern, nanim));
|
|
DrawDragRect(GetMaster(), r1, Rect(0, 0, 0, 0), c, width, color, sGetAniPat(pattern, panim));
|
|
panim = nanim;
|
|
}
|
|
else
|
|
DrawDragRect(GetMaster(), r1, r2, c, width, color, pattern);
|
|
}
|
|
|
|
Rect RectTracker::Track(const Rect& r, int _tx, int _ty)
|
|
{
|
|
rect = r;
|
|
tx = _tx;
|
|
ty = _ty;
|
|
org = rect;
|
|
o = rect;
|
|
op = GetMousePos();
|
|
GetMaster().Sync();
|
|
DrawRect(Rect(0, 0, 0, 0), rect);
|
|
Run();
|
|
DrawRect(o, Rect(0, 0, 0, 0));
|
|
return rect;
|
|
}
|
|
|
|
int RectTracker::TrackHorzLine(int x0, int y0, int cx, int line)
|
|
{
|
|
return Track(RectC(x0, y0, cx, line + 1), -1, ALIGN_BOTTOM).bottom - 1;
|
|
}
|
|
|
|
int RectTracker::TrackVertLine(int x0, int y0, int cy, int line)
|
|
{
|
|
return Track(RectC(x0, y0, line + 1, cy), ALIGN_RIGHT, -1).right - 1;
|
|
}
|
|
|
|
void RectTracker::MouseMove(Point, dword)
|
|
{
|
|
Point p = GetMousePos();
|
|
rect = org;
|
|
if(tx == ALIGN_CENTER && ty == ALIGN_CENTER) {
|
|
int x = org.left - op.x + p.x;
|
|
int y = org.top - op.y + p.y;
|
|
if(x + org.Width() > maxrect.right)
|
|
x = maxrect.right - org.Width();
|
|
if(x < maxrect.left)
|
|
x = maxrect.left;
|
|
if(y + org.Height() > maxrect.bottom)
|
|
y = maxrect.bottom - org.Height();
|
|
if(y < maxrect.top)
|
|
y = maxrect.top;
|
|
rect = RectC(x, y, org.Width(), org.Height());
|
|
}
|
|
else {
|
|
if(tx == ALIGN_LEFT) {
|
|
rect.left = max(org.left - op.x + p.x, maxrect.left);
|
|
rect.left = minmax(rect.left, rect.right - maxsize.cx, rect.right - minsize.cx);
|
|
}
|
|
if(tx == ALIGN_RIGHT) {
|
|
rect.right = min(org.right - op.x + p.x, maxrect.right);
|
|
rect.right = minmax(rect.right, rect.left + minsize.cx, rect.left + maxsize.cx);
|
|
}
|
|
if(ty == ALIGN_TOP) {
|
|
rect.top = max(org.top - op.y + p.y, maxrect.top);
|
|
rect.top = minmax(rect.top, rect.bottom - maxsize.cy, rect.bottom - minsize.cy);
|
|
}
|
|
if(ty == ALIGN_BOTTOM) {
|
|
rect.bottom = min(org.bottom - op.y + p.y, maxrect.bottom);
|
|
rect.bottom = minmax(rect.bottom, rect.top + minsize.cy, rect.top + maxsize.cy);
|
|
}
|
|
if(tx == ALIGN_NULL) {
|
|
rect.right = min(org.right - op.x + p.x, maxrect.right);
|
|
if (rect.right < rect.left) {
|
|
Swap(rect.right, rect.left);
|
|
rect.InflateHorz(1);
|
|
}
|
|
}
|
|
if(ty == ALIGN_NULL) {
|
|
rect.bottom = min(org.bottom - op.y + p.y, maxrect.bottom);
|
|
if (rect.bottom < rect.top) {
|
|
Swap(rect.bottom, rect.top);
|
|
rect.InflateVert(1);
|
|
}
|
|
}
|
|
if(keepratio) {
|
|
int cy = org.Width() ? rect.Width() * org.Height() / org.Width() : 0;
|
|
int cx = org.Height() ? rect.Height() * org.Width() / org.Height() : 0;
|
|
if(tx == ALIGN_BOTTOM && ty == ALIGN_RIGHT) {
|
|
Size sz = rect.Size();
|
|
if(cx > sz.cx)
|
|
rect.right = rect.left + cx;
|
|
else
|
|
rect.bottom = rect.top + cy;
|
|
}
|
|
else
|
|
if(tx == ALIGN_RIGHT)
|
|
rect.bottom = rect.top + cy;
|
|
else
|
|
if(ty == ALIGN_BOTTOM)
|
|
rect.right = rect.left + cx;
|
|
}
|
|
}
|
|
if(rect != o) {
|
|
rect = Round(rect);
|
|
if(rect != o) {
|
|
DrawRect(o, rect);
|
|
sync(rect);
|
|
o = rect;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
void RectTracker::MouseMove(Point, dword)
|
|
{
|
|
Point p = GetMousePos();
|
|
rect = org;
|
|
if(tx == ALIGN_CENTER && ty == ALIGN_CENTER) {
|
|
int x = org.left - op.x + p.x;
|
|
int y = org.top - op.y + p.y;
|
|
if(x + org.Width() > maxrect.right)
|
|
x = maxrect.right - org.Width();
|
|
if(x < maxrect.left)
|
|
x = maxrect.left;
|
|
if(y + org.Height() > maxrect.bottom)
|
|
y = maxrect.bottom - org.Height();
|
|
if(y < maxrect.top)
|
|
y = maxrect.top;
|
|
rect = RectC(x, y, org.Width(), org.Height());
|
|
}
|
|
else {
|
|
if(tx == ALIGN_LEFT) {
|
|
rect.left = max(org.left - op.x + p.x, maxrect.left);
|
|
rect.left = minmax(rect.left, rect.right - maxsize.cx, rect.right - minsize.cx);
|
|
}
|
|
if(tx == ALIGN_RIGHT) {
|
|
rect.right = min(org.right - op.x + p.x, maxrect.right);
|
|
rect.right = minmax(rect.right, rect.left + minsize.cx, rect.left + maxsize.cx);
|
|
}
|
|
if(ty == ALIGN_TOP) {
|
|
rect.top = max(org.top - op.y + p.y, maxrect.top);
|
|
rect.top = minmax(rect.top, rect.bottom - maxsize.cy, rect.bottom - minsize.cy);
|
|
}
|
|
if(ty == ALIGN_BOTTOM) {
|
|
rect.bottom = min(org.bottom - op.y + p.y, maxrect.bottom);
|
|
rect.bottom = minmax(rect.bottom, rect.top + minsize.cy, rect.top + maxsize.cy);
|
|
}
|
|
if(keepratio) {
|
|
int cy = org.Width() ? rect.Width() * org.Height() / org.Width() : 0;
|
|
int cx = org.Height() ? rect.Height() * org.Width() / org.Height() : 0;
|
|
if(tx == ALIGN_BOTTOM && ty == ALIGN_RIGHT) {
|
|
Size sz = rect.Size();
|
|
if(cx > sz.cx)
|
|
rect.right = rect.left + cx;
|
|
else
|
|
rect.bottom = rect.top + cy;
|
|
}
|
|
else
|
|
if(tx == ALIGN_RIGHT)
|
|
rect.bottom = rect.top + cy;
|
|
else
|
|
if(ty == ALIGN_BOTTOM)
|
|
rect.right = rect.left + cx;
|
|
}
|
|
}
|
|
if(rect != o) {
|
|
rect = Round(rect);
|
|
if(rect != o) {
|
|
DrawRect(o, rect);
|
|
sync(rect);
|
|
o = rect;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
class PointLooper : public LocalLoop {
|
|
const Vector<Image>& ani;
|
|
int ani_ms;
|
|
bool result;
|
|
|
|
public:
|
|
virtual void LeftUp(Point, dword);
|
|
virtual Image CursorImage(Point p, dword keyflags);
|
|
virtual bool Key(dword key, int);
|
|
|
|
operator bool() const { return result; }
|
|
|
|
PointLooper(Ctrl& ctrl, const Vector<Image>& ani, int ani_ms)
|
|
: ani(ani), ani_ms(ani_ms) { SetMaster(ctrl); }
|
|
};
|
|
|
|
void PointLooper::LeftUp(Point, dword)
|
|
{
|
|
result = true;
|
|
EndLoop();
|
|
}
|
|
|
|
Image PointLooper::CursorImage(Point p, dword keyflags)
|
|
{
|
|
return ani[int(GetTimeClick() / ani_ms % ani.GetCount())];
|
|
}
|
|
|
|
bool PointLooper::Key(dword key, int)
|
|
{
|
|
if(key == K_ESCAPE) {
|
|
result = false;
|
|
EndLoop();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool PointLoop(Ctrl& ctrl, const Vector<Image>& ani, int ani_ms)
|
|
{
|
|
PointLooper p(ctrl, ani, ani_ms);
|
|
p.Run();
|
|
return p;
|
|
}
|
|
|
|
bool PointLoop(Ctrl& ctrl, const Image& img)
|
|
{
|
|
Vector<Image> m;
|
|
m.Add(img);
|
|
return PointLoop(ctrl, m, 1);
|
|
}
|
|
|
|
END_UPP_NAMESPACE
|