mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 06:05:58 -06:00
CtrlCore: Window positions now 32 bit
This commit is contained in:
parent
a15023e1bb
commit
d08ae0e77f
8 changed files with 192 additions and 100 deletions
|
|
@ -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; }
|
||||
|
|
@ -118,6 +115,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); }
|
||||
|
||||
void SetString(int ii, const char *s) { SetData(ii, s, (int)strlen(s)); }
|
||||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
@ -454,6 +454,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); }
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
9
upptst/TopWindowSetRect/TopWindowSetRect.upp
Normal file
9
upptst/TopWindowSetRect/TopWindowSetRect.upp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
uses
|
||||
CtrlLib;
|
||||
|
||||
file
|
||||
main.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI";
|
||||
|
||||
46
upptst/TopWindowSetRect/main.cpp
Normal file
46
upptst/TopWindowSetRect/main.cpp
Normal 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
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue