From d29055412b9ba2f5d3a78d4ba3ae3ee7260b2df2 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Fri, 4 Oct 2024 13:23:05 +0200 Subject: [PATCH] CtrlCore: 'MegaRect' support for very large virtual screens (SetRect(x, y) now can be 32-bit) --- uppsrc/CtrlCore/Ctrl.cpp | 1 + uppsrc/CtrlCore/CtrlCore.h | 6 +++++ uppsrc/CtrlCore/CtrlPos.cpp | 47 ++++++++++++++++++++++++++++-------- upptst/MegaRect/MegaRect.upp | 9 +++++++ upptst/MegaRect/main.cpp | 18 ++++++++++++++ 5 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 upptst/MegaRect/MegaRect.upp create mode 100644 upptst/MegaRect/main.cpp diff --git a/uppsrc/CtrlCore/Ctrl.cpp b/uppsrc/CtrlCore/Ctrl.cpp index 2cbe37595..a2a27c457 100644 --- a/uppsrc/CtrlCore/Ctrl.cpp +++ b/uppsrc/CtrlCore/Ctrl.cpp @@ -553,6 +553,7 @@ Ctrl::Ctrl() { layout_id_literal = false; top = false; uparent = nullptr; + megarect = false; } void KillTimeCallbacks(void *id, void *idlim); diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index c15e83c67..02424abda 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -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 eventCtrl; static Ptr 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 }; diff --git a/uppsrc/CtrlCore/CtrlPos.cpp b/uppsrc/CtrlCore/CtrlPos.cpp index 24022a553..73f339794 100644 --- a/uppsrc/CtrlCore/CtrlPos.cpp +++ b/uppsrc/CtrlCore/CtrlPos.cpp @@ -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) diff --git a/upptst/MegaRect/MegaRect.upp b/upptst/MegaRect/MegaRect.upp new file mode 100644 index 000000000..5872304d3 --- /dev/null +++ b/upptst/MegaRect/MegaRect.upp @@ -0,0 +1,9 @@ +uses + CtrlLib; + +file + main.cpp; + +mainconfig + "" = "GUI"; + diff --git a/upptst/MegaRect/main.cpp b/upptst/MegaRect/main.cpp new file mode 100644 index 000000000..5f146234d --- /dev/null +++ b/upptst/MegaRect/main.cpp @@ -0,0 +1,18 @@ +#include + +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()); +}