CtrlCore: Window positions now 32 bit

This commit is contained in:
Mirek Fidler 2024-10-03 02:03:27 +02:00
parent a15023e1bb
commit d08ae0e77f
8 changed files with 192 additions and 100 deletions

View file

@ -106,9 +106,6 @@ public:
class PackedData {
void *ptr = nullptr;
template <class T>
T Get(int ii, T def) const;
public:
void SetRawPtr(void *p) { ptr = p; }
void *GetRawPtr() const { return ptr; }
@ -117,6 +114,12 @@ public:
template <class F>
bool GetData(int ii, F out) const;
template <class T>
void Set(int ii, T val);
template <class T>
T Get(int ii, T def) const;
void SetNull(int ii) { SetData(ii, NULL, 0); }
@ -147,57 +150,6 @@ public:
~PackedData();
};
/*
template <class T, int N = 1>
struct Link {
T *link_prev[N];
T *link_next[N];
protected:
void LPN(int i) { link_prev[i]->link_next[i] = link_next[i]->link_prev[i] = (T *)this; }
public:
NOUBSAN T *GetPtr() { return (T *) this; }
const T *GetPtr() const { return (const T *) this; }
T *GetNext(int i = 0) { return link_next[i]; }
T *GetPrev(int i = 0) { return link_prev[i]; }
const T *GetNext(int i = 0) const { return link_next[i]; }
const T *GetPrev(int i = 0) const { return link_prev[i]; }
NOUBSAN void LinkSelf(int i = 0) { link_next[i] = link_prev[i] = (T *)this; }
void LinkSelfAll() { for(int i = 0; i < N; i++) LinkSelf(i); }
void Unlink(int i = 0) { link_next[i]->link_prev[i] = link_prev[i]; link_prev[i]->link_next[i] = link_next[i];
LinkSelf(i); }
void UnlinkAll() { for(int i = 0; i < N; i++) Unlink(i); }
NOUBSAN void LinkBefore(Link *n, int i = 0) { link_next[i] = (T *)n; link_prev[i] = link_next[i]->link_prev[i]; LPN(i); }
NOUBSAN void LinkAfter(Link *p, int i = 0) { link_prev[i] = (T *)p; link_next[i] = link_prev[i]->link_next[i]; LPN(i); }
T *InsertNext(int i = 0) { T *x = new T; x->LinkAfter(this, i); return x; }
T *InsertPrev(int i = 0) { T *x = new T; x->LinkBefore(this, i); return x; }
void DeleteList(int i = 0) { while(link_next[i] != GetPtr()) delete link_next[i]; }
bool InList(int i = 0) const { return link_next[i] != GetPtr(); }
bool IsEmpty(int i = 0) const { return !InList(i); }
Link() { LinkSelfAll(); }
~Link() { UnlinkAll(); }
private:
Link(const Link&);
void operator=(const Link&);
public:
#ifdef _DEBUG
void Dump() {
for(T *t = GetNext(); t != this; t = t->GetNext())
LOG(t);
LOG("-------------------------------------");
}
#endif
};
*/
template <int N = 1>
struct Link {
Link *link_prev[N];

View file

@ -24,9 +24,14 @@ bool PackedData::GetData(int ii, F out) const
}
template <class T>
T PackedData::Get(int ii, T def) const
void PackedData::Set(int ii, T val)
{
SetData(ii, &val, sizeof(T));
}
template <class T>
T PackedData::Get(int ii, T q) const
{
T q = def;
GetData(ii, [&](const char *ptr, int len) {
if(len) {
ASSERT(len == sizeof(T));

View file

@ -541,9 +541,7 @@ Ctrl::Ctrl() {
backpaint = IsCompositedGui() ? FULLBACKPAINT : TRANSPARENTBACKPAINT;
inframe = false;
ignoremouse = transparent = false;
pos.x = PosLeft(0, 0);
pos.y = PosTop(0, 0);
rect = Rect(0, 0, 0, 0);
packed_rect = Rect16(0, 0, 0, 0);
inloop = popup = isopen = false;
modify = false;
unicode = false;

View file

@ -162,6 +162,29 @@ int64 Ctrl::GetInt64Attr(int ii, int64 def) const
return attrs.GetInt64(ii, def);
}
void Ctrl::SetLogPosAttr(int ii, LogPos pos)
{
Attrs().Set(ii, pos);
}
Ctrl::LogPos Ctrl::GetLogPosAttr(int ii) const
{
if(layout_id_literal)
return LogPos();
return attrs.Get<LogPos>(ii, LogPos());
}
void Ctrl::SetRectAttr(int ii, const Rect& r)
{
Attrs().Set(ii, r);
}
Rect Ctrl::GetRectAttr(int ii) const
{
if(layout_id_literal)
return Null;
return attrs.Get<Rect>(ii, Rect(Null));
}
void Ctrl::SetVoidPtrAttr(int ii, const void *ptr)
{

View file

@ -428,24 +428,24 @@ public:
STDSIZE = -16382,
};
class Logc {
dword data;
struct Logc {
int align = LEFT;
int a = 0;
int b = 0;
static int LSGN(dword d) { return int16((d & 0x7fff) | ((d & 0x4000) << 1)); }
bool operator==(Logc q) const { return a == q.a && b == q.b && align == q.align; }
bool operator!=(Logc q) const { return !operator==(q); }
int GetAlign() const { return align; }
int GetA() const { return a; }
int GetB() const { return b; }
void SetAlign(int align_) { align = align_; }
void SetA(int a_) { a = a_; }
void SetB(int b_) { b = b_; }
bool IsEmpty() const { return align == SIZE ? b <= a : b <= 0; }
bool CanPack() const { return a >= -16000 && a <= 16000 && b >= -16000 && b <= 16000; }
public:
bool operator==(Logc q) const { return data == q.data; }
bool operator!=(Logc q) const { return data != q.data; }
int GetAlign() const { return (data >> 30) & 3; }
int GetA() const { return LSGN(data >> 15); }
int GetB() const { return LSGN(data); }
void SetAlign(int align) { data = (data & ~(3 << 30)) | (align << 30); }
void SetA(int a) { data = (data & ~(0x7fff << 15)) | ((a & 0x7fff) << 15); }
void SetB(int b) { data = (data & ~0x7fff) | (b & 0x7fff); }
bool IsEmpty() const;
Logc(int al, int a, int b) { data = (al << 30) | ((a & 0x7fff) << 15) | (b & 0x7fff); }
Logc() { data = 0xffffffff; }
Logc(int al, int a_, int b_) { align = al; a = a_; b = b_; }
Logc() {}
};
struct LogPos : Moveable<LogPos> {
@ -453,6 +453,8 @@ public:
bool operator==(LogPos b) const { return x == b.x && y == b.y; }
bool operator!=(LogPos b) const { return !(*this == b); }
bool CanPack() const { return x.CanPack() && y.CanPack(); }
LogPos(Logc x, Logc y) : x(x), y(y) {}
LogPos() {}
@ -466,6 +468,24 @@ public:
static Logc PosCenter(int size, int offset) { return Logc(CENTER, offset, size); }
static Logc PosCenter(int size) { return Logc(CENTER, 0, size); }
struct PackedLogc {
unsigned align:2;
int a:15;
int b:15;
operator Logc() const { return Logc(align, a, b); }
PackedLogc(const Logc& c) { align = c.align; a = c.a; b = c.b; }
PackedLogc() { align = LEFT; a = 0; b = 0; }
};
struct PackedLogPos : Moveable<LogPos> {
PackedLogc x, y;
operator LogPos() const { return LogPos(x, y); }
PackedLogPos(LogPos pos) { x = pos.x; y = pos.y; }
PackedLogPos() {}
};
typedef bool (*MouseHook)(Ctrl *ctrl, bool inframe, int event, Point p,
int zdelta, dword keyflags);
typedef bool (*KeyHook)(Ctrl *ctrl, dword key, int count);
@ -525,8 +545,12 @@ private:
Frame frame;
LogPos pos;//8
Rect16 rect; //8
PackedLogPos packed_pos;//8
Rect16 packed_rect; //8
void LogPosSet(LogPos p);
void RectSet(const Rect& r);
union {
Ctrl *uparent;
@ -828,6 +852,8 @@ protected:
ATTR_HELPLINE,
ATTR_DESCRIPTION,
ATTR_HELPTOPIC,
ATTR_RECT,
ATTR_LOGPOS,
ATTR_LAST
};
@ -847,6 +873,12 @@ protected:
void SetInt64Attr(int ii, int64 val);
int64 GetInt64Attr(int ii, int64 def = Null) const;
void SetLogPosAttr(int ii, LogPos pos);
LogPos GetLogPosAttr(int ii) const;
void SetRectAttr(int ii, const Rect& r);
Rect GetRectAttr(int ii) const;
void SetVoidPtrAttr(int ii, const void *ptr);
void *GetVoidPtrAttr(int ii) const;
@ -1134,7 +1166,7 @@ public:
bool InFrame() const { return inframe; }
bool InView() const { return !inframe; }
LogPos GetPos() const { return pos; }
LogPos GetPos() const;
void RefreshLayout() { SyncLayout(1); }
void RefreshLayoutDeep() { SyncLayout(2); }

View file

@ -5,8 +5,40 @@ namespace Upp {
#define LLOG(x) // DLOG(x)
#define LTIMING(x) // RTIMING(x)
bool Ctrl::Logc::IsEmpty() const {
return GetAlign() == SIZE ? GetB() <= GetA() : GetB() <= 0;
void Ctrl::LogPosSet(LogPos p)
{
if(p.CanPack()) {
packed_pos = p;
}
else {
packed_pos.x.a = 16001;
SetLogPosAttr(Ctrl::ATTR_LOGPOS, p);
}
}
Ctrl::LogPos Ctrl::GetPos() const
{
if(packed_pos.x.a == 16001)
return GetLogPosAttr(Ctrl::ATTR_LOGPOS);
return packed_pos;
}
void Ctrl::RectSet(const Rect& r)
{
auto CanPack = [](int a) { return a >= -32000 && a <= 32000; };
if(CanPack(r.left) && CanPack(r.right) && CanPack(r.top) && CanPack(r.bottom))
packed_rect = r;
else {
SetRectAttr(Ctrl::ATTR_RECT, r);
packed_rect.left = 32001;
}
}
Rect Ctrl::GetRect() const
{
if(packed_rect.left == 32001)
return GetRectAttr(Ctrl::ATTR_RECT);
return packed_rect;
}
Size Ctrl::PosVal(int v) const {
@ -49,19 +81,15 @@ Rect Ctrl::CalcRect(LogPos pos, const Rect& prect, const Rect& pview) const
Rect Ctrl::CalcRect(const Rect& prect, const Rect& pview) const
{
return CalcRect(pos, prect, pview);
}
Rect Ctrl::GetRect() const
{
return rect;
return CalcRect(GetPos(), prect, pview);
}
Rect Ctrl::GetView() const
{
GuiLock __;
int n = GetFrameCount();
return n == 0 ? Rect(Size(rect.Size())) : Rect(GetFrame0(n - 1).GetView());
Rect vr = GetRect().Size();
return n == 0 ? vr : GetFrame0(n - 1).GetView();
}
Size Ctrl::GetSize() const
@ -162,7 +190,7 @@ void Ctrl::SyncLayout(int force)
}
if(oview.Size() != view.Size() || force > 1) {
for(Ctrl& q : *this) {
q.rect = q.CalcRect(rect, view);
q.RectSet(q.CalcRect(GetRect(), view));
LLOG("Layout set rect " << q.Name() << " " << q.rect);
q.SyncLayout(force > 1 ? force : 0);
}
@ -205,7 +233,7 @@ Ctrl::MoveCtrl *Ctrl::FindMoveCtrlPtr(VectorMap<Ctrl *, MoveCtrl>& m, Ctrl *x)
void Ctrl::SetPos0(LogPos p, bool _inframe)
{
GuiLock __;
if(p == pos && inframe == _inframe) return;
if(p == GetPos() && inframe == _inframe) return;
Ctrl *parent = GetParent();
if(parent && !IsDHCtrl()) {
if(!globalbackbuffer) {
@ -213,7 +241,7 @@ void Ctrl::SetPos0(LogPos p, bool _inframe)
Top *top = GetTopRect(from, true)->GetTop();
if(top) {
LTIMING("SetPos0 MoveCtrl");
pos = p;
LogPosSet(p);
inframe = _inframe;
Rect to = GetRect().Size();
UpdateRect0();
@ -236,7 +264,7 @@ void Ctrl::SetPos0(LogPos p, bool _inframe)
}
RefreshFrame();
}
pos = p;
LogPosSet(p);
inframe = _inframe;
UpdateRect();
StateH(POSITION);
@ -248,13 +276,13 @@ void Ctrl::UpdateRect0(bool sync)
LTIMING("UpdateRect0");
Ctrl *parent = GetParent();
if(parent)
rect = CalcRect(parent->GetRect(), parent->GetView());
RectSet(CalcRect(parent->GetRect(), parent->GetView()));
else {
static Rect pwa;
ONCELOCK {
pwa = GetPrimaryWorkArea();
}
rect = CalcRect(pwa, pwa);
RectSet(CalcRect(pwa, pwa));
}
LLOG("UpdateRect0 " << Name() << " to " << rect);
LTIMING("UpdateRect0 SyncLayout");
@ -274,7 +302,7 @@ Ctrl& Ctrl::SetPos(LogPos p, bool _inframe)
{
GuiLock __;
Ctrl *parent = GetParent();
if(p != pos || inframe != _inframe) {
if(p != GetPos() || inframe != _inframe) {
if(parent || !IsOpen())
SetPos0(p, _inframe);
else {
@ -293,12 +321,12 @@ Ctrl& Ctrl::SetPos(LogPos p)
Ctrl& Ctrl::SetPosX(Logc x)
{
return SetPos(LogPos(x, pos.y));
return SetPos(LogPos(x, GetPos().y));
}
Ctrl& Ctrl::SetPosY(Logc y)
{
return SetPos(LogPos(pos.x, y));
return SetPos(LogPos(GetPos().x, y));
}
Ctrl& Ctrl::SetFramePos(LogPos p)
@ -307,18 +335,17 @@ Ctrl& Ctrl::SetFramePos(LogPos p)
}
Ctrl& Ctrl::SetFramePosX(Logc x) {
return SetPos(LogPos(x, pos.y), true);
return SetPos(LogPos(x, GetPos().y), true);
}
Ctrl& Ctrl::SetFramePosY(Logc y) {
return SetPos(LogPos(pos.x, y), true);
return SetPos(LogPos(GetPos().x, y), true);
}
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)));
SetPos(PosLeft(x, cx), PosTop(y, cy));
}
void Ctrl::SetWndRect(const Rect& r)

View file

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

View file

@ -0,0 +1,46 @@
#include <CtrlLib/CtrlLib.h>
using namespace Upp;
GUI_APP_MAIN
{
DDUMP(sizeof(Ctrl::PackedLogPos));
TopWindow win;
win.SetRect(0, 0, 200, 200);
Ctrl a;
win << a;
for(int pass = 0; pass < 2; pass++) {
DLOG("=================");
DDUMP(win.GetRect());
DDUMP(a.LeftPos(10, 100).TopPos(10, 100).GetRect());
DDUMP(a.GetScreenRect());
DDUMP(a.RightPos(10, 100).BottomPos(10, 100).GetRect());
DDUMP(a.GetScreenRect());
DDUMP(a.VSizePos(10, 10).HSizePos(10, 10).GetRect());
DDUMP(a.GetScreenRect());
DDUMP(a.HCenterPos(100).VCenterPos(100).GetRect());
DDUMP(a.GetScreenRect());
win.SetRect(100000, 100000, 30000, 30000);
}
#if 0
{
Ctrl x;
x.LeftPos(10, 100).TopPos(10, 100);
Ctrl::Logc p = x.GetPos().x;
DDUMP(p.GetAlign());
DDUMP(p.GetA());
DDUMP(p.GetB());
}
PromptOK("Test");
TopWindow win;
win.SetRect(100000, 100000, 200, 200);
DDUMP(win.GetRect());
Rect r(1234567, 8, 9, 10);
win.SetRectAttr(Ctrl::ATTR_RECT, r);
DDUMP(win.GetRectAttr(Ctrl::ATTR_RECT));
#endif
}