CtrlCore: 'MegaRect' support for very large virtual screens (SetRect(x, y) now can be 32-bit)

This commit is contained in:
Mirek Fidler 2024-10-04 13:23:05 +02:00
parent a15023e1bb
commit d29055412b
5 changed files with 71 additions and 10 deletions

View file

@ -553,6 +553,7 @@ Ctrl::Ctrl() {
layout_id_literal = false;
top = false;
uparent = nullptr;
megarect = false;
}
void KillTimeCallbacks(void *id, void *idlim);

View file

@ -565,6 +565,7 @@ private:
bool layout_id_literal:1; // info_ptr points to layout char * literal, no heap involved
bool multi_frame:1; // there is more than single frame, they are stored in heap
bool top:1;
bool megarect:1; // support for large virtual screen area - SetRect > 16000
static Ptr<Ctrl> eventCtrl;
static Ptr<Ctrl> mouseCtrl;
@ -756,6 +757,9 @@ private:
void FreeFrames() { if(multi_frame) MemoryFree(frame.frames); }
Frame AllocFrames(int alloc);
Rect OffsetMegaRect(Rect r) const;
void MegaRect(Rect& r);
PackedData& Attrs();
@ -828,6 +832,8 @@ protected:
ATTR_HELPLINE,
ATTR_DESCRIPTION,
ATTR_HELPTOPIC,
ATTR_MEGARECT_X,
ATTR_MEGARECT_Y,
ATTR_LAST
};

View file

@ -52,9 +52,19 @@ Rect Ctrl::CalcRect(const Rect& prect, const Rect& pview) const
return CalcRect(pos, prect, pview);
}
Rect Ctrl::OffsetMegaRect(Rect r) const
{
if(megarect)
r.Offset(GetIntAttr(ATTR_MEGARECT_X, 0), GetIntAttr(ATTR_MEGARECT_Y, 0));
return r;
}
Rect Ctrl::GetRect() const
{
return rect;
Rect r = rect;
if(megarect)
r = OffsetMegaRect(r);
return r;
}
Rect Ctrl::GetView() const
@ -250,11 +260,8 @@ void Ctrl::UpdateRect0(bool sync)
if(parent)
rect = CalcRect(parent->GetRect(), parent->GetView());
else {
static Rect pwa;
ONCELOCK {
pwa = GetPrimaryWorkArea();
}
rect = CalcRect(pwa, pwa);
Rect pwa = GetPrimaryWorkArea();
rect = OffsetMegaRect(CalcRect(pwa, pwa));
}
LLOG("UpdateRect0 " << Name() << " to " << rect);
LTIMING("UpdateRect0 SyncLayout");
@ -278,8 +285,10 @@ Ctrl& Ctrl::SetPos(LogPos p, bool _inframe)
if(parent || !IsOpen())
SetPos0(p, _inframe);
else {
Rect wa = GetWorkArea();
WndSetPos(CalcRect(p, wa, wa));
ASSERT(p.x.GetAlign() == ALIGN_LEFT);
ASSERT(p.y.GetAlign() == ALIGN_TOP);
Rect pwa = GetPrimaryWorkArea();
WndSetPos(OffsetMegaRect(CalcRect(p, pwa, pwa)));
StateH(POSITION);
}
}
@ -314,11 +323,29 @@ Ctrl& Ctrl::SetFramePosY(Logc y) {
return SetPos(LogPos(pos.x, y), true);
}
void Ctrl::MegaRect(Rect& r)
{ // support 32-bit position of window (not size - just clamp it)
Size sz = r.GetSize();
sz.cx = clamp(sz.cx, -16000, 16000);
sz.cy = clamp(sz.cy, -16000, 16000);
if(abs(r.left) > 16000 || abs(r.top) > 16000) {
megarect = true;
SetIntAttr(ATTR_MEGARECT_X, r.left);
SetIntAttr(ATTR_MEGARECT_Y, r.top);
r = sz;
}
else {
megarect = false;
r.SetSize(sz);
}
}
void Ctrl::SetRect(int x, int y, int cx, int cy)
{
LLOG("SetRect " << Name() << " rect: " << RectC(x, y, cx, cy));
auto clampc = [](int c) { return clamp(c, -32700, 32700); }; // Logc vals only have 15 bits
SetPos(PosLeft(clampc(x), clampc(cx)), PosTop(clampc(y), clampc(cy)));
Rect r = RectC(x, y, cx, cy);
MegaRect(r);
SetPos(LogPos(PosLeft(r.left, r.Width()), PosTop(r.top, r.Height())), false);
}
void Ctrl::SetWndRect(const Rect& r)

View file

@ -0,0 +1,9 @@
uses
CtrlLib;
file
main.cpp;
mainconfig
"" = "GUI";

18
upptst/MegaRect/main.cpp Normal file
View file

@ -0,0 +1,18 @@
#include <CtrlLib/CtrlLib.h>
using namespace Upp;
GUI_APP_MAIN
{
RDUMP(sizeof(Ctrl));
TopWindow win;
win.SetRect(100, 100, 100, 100);
DDUMP(win.GetRect());
win.SetRect(100000, 100000, 100, 100);
DDUMP(win.GetRect());
win.SetRect(100000, 100000, 100000, 100000);
DDUMP(win.GetRect());
win.SetRect(-100000, -100000, -100000, -100000);
DDUMP(win.GetRect());
}