diff --git a/uppsrc/CtrlCore/Ctrl.cpp b/uppsrc/CtrlCore/Ctrl.cpp index eb8c1ff77..db68c6158 100644 --- a/uppsrc/CtrlCore/Ctrl.cpp +++ b/uppsrc/CtrlCore/Ctrl.cpp @@ -582,8 +582,8 @@ void Ctrl::Dump(Stream& s) const { sFLAG(wantfocus) << sFLAG(editable) << sFLAG(IsModified()) << sFLAG(transparent)); LG("Rect: " << GetRect()); LG("View: " << GetView()); - for(int i = 0; i < frame.GetCount(); i++) - LG("Frame " << i << ": " << typeid(decltype(*frame[i].frame)).name() << " - " << frame[i].view); + for(int i = 0; i < GetFrameCount(); i++) + LG("Frame " << i << ": " << typeid(decltype(*GetFrame0(i).frame)).name() << " - " << GetFrame0(i).GetView()); LG("Data: " << GetData().ToString()); if(children) { LG("Children"); @@ -627,7 +627,8 @@ Ctrl::Ctrl() { LLOG("Ctrl::Ctrl"); GuiPlatformConstruct(); destroying = false; - frame.Add().frame = &NullFrame(); + multi_frame = false; + frame.frame = &NullFrame(); enabled = visible = wantfocus = initfocus = true; editable = true; backpaint = IsCompositedGui() ? FULLBACKPAINT : TRANSPARENTBACKPAINT; @@ -728,6 +729,7 @@ Ctrl::~Ctrl() { Close(); KillTimeCallbacks(this, (byte *) this + sizeof(Ctrl)); ClearInfo(); + FreeFrames(); } Vector& Ctrl::mousehook() { static Vector h; return h; } diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index c2e8d0c54..8420fc655 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -458,12 +458,31 @@ private: void operator=(Ctrl&); private: - struct Frame : Moveable { - CtrlFrame *frame; - Rect16 view; - - Frame() { view.Clear(); } + struct MultiFrame { // in case there are more than 1 CtrlFrames + int alloc; + int count; }; + + struct Rect16_ { // so that it can be in union + int16 left, top, right, bottom; + }; + + struct Frame { + union { + CtrlFrame *frame; + Frame *frames; + }; + union { + MultiFrame multi; + Rect16_ view; + }; + + void SetView(const Rect& r) { view.left = r.left; view.right = r.right; view.top = r.top; view.bottom = r.bottom; } + Rect GetView() const { return Rect16(view.left, view.top, view.right, view.bottom); } + }; + + Frame frame; + Ctrl *parent = nullptr; struct Scroll : Moveable { @@ -492,10 +511,9 @@ private: Ctrl *prev_sibling = nullptr; Ctrl *next_sibling = nullptr; - Ctrl *children = nullptr;//16 + Ctrl *children = nullptr; LogPos pos;//8 - Rect16 rect; - Mitor frame;//16 + Rect16 rect; //8 const char *info_ptr = nullptr; int16 caretx, carety, caretcx, caretcy;//8 @@ -523,7 +541,9 @@ private: bool akv:1; bool destroying:1; - bool layout_id_literal:1; // info_ptr points to layout char * literal, no heap involved + 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 static Ptr eventCtrl; static Ptr mouseCtrl; @@ -700,6 +720,12 @@ private: String Name0() const; + Frame& GetFrame0(int i) { ASSERT(i < GetFrameCount()); return multi_frame ? frame.frames[i] : frame; } + const Frame& GetFrame0(int i) const { ASSERT(i < GetFrameCount()); return multi_frame ? frame.frames[i] : frame; } + void FreeFrames() { if(multi_frame) MemoryFree(frame.frames); } + Frame AllocFrames(int alloc); + + static void InitTimer(); static String appname; @@ -994,13 +1020,13 @@ public: Ctrl& SetFrame(int i, CtrlFrame& frm); Ctrl& SetFrame(CtrlFrame& frm) { return SetFrame(0, frm); } Ctrl& AddFrame(CtrlFrame& frm); - const CtrlFrame& GetFrame(int i = 0) const { return *frame[i].frame; } - CtrlFrame& GetFrame(int i = 0) { return *frame[i].frame; } + const CtrlFrame& GetFrame(int i = 0) const { return *const_cast(this)->GetFrame0(i).frame; } + CtrlFrame& GetFrame(int i = 0) { return *GetFrame0(i).frame; } void RemoveFrame(int i); void RemoveFrame(CtrlFrame& frm); void InsertFrame(int i, CtrlFrame& frm); - int FindFrame(CtrlFrame& frm); - int GetFrameCount() const { return frame.GetCount(); } + int FindFrame(CtrlFrame& frm) const; + int GetFrameCount() const { return multi_frame ? frame.multi.count : frame.frame ? 1 : 0; } void ClearFrames(); bool IsOpen() const; diff --git a/uppsrc/CtrlCore/CtrlCore.upp b/uppsrc/CtrlCore/CtrlCore.upp index 07aba46dd..0035b087d 100644 --- a/uppsrc/CtrlCore/CtrlCore.upp +++ b/uppsrc/CtrlCore/CtrlCore.upp @@ -22,6 +22,7 @@ file CtrlMt.cpp, Ctrl.cpp, CtrlChild.cpp, + CtrlFrame.cpp, CtrlPos.cpp, CtrlDraw.cpp, CtrlMouse.cpp, diff --git a/uppsrc/CtrlCore/CtrlDraw.cpp b/uppsrc/CtrlCore/CtrlDraw.cpp index ee816e140..9daa8fd21 100644 --- a/uppsrc/CtrlCore/CtrlDraw.cpp +++ b/uppsrc/CtrlCore/CtrlDraw.cpp @@ -278,10 +278,12 @@ void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip) { return; Ctrl *q; Rect view = rect; - for(int i = 0; i < frame.GetCount(); i++) { + int n = GetFrameCount(); + for(int i = 0; i < n; i++) { LEVELCHECK(w, NULL); - frame[i].frame->FramePaint(w, view); - view = frame[i].view; + Frame& f = GetFrame0(i); + f.frame->FramePaint(w, view); + view = f.GetView(); } Rect oview = view.Inflated(overpaint); bool hasviewctrls = false; diff --git a/uppsrc/CtrlCore/CtrlFrame.cpp b/uppsrc/CtrlCore/CtrlFrame.cpp new file mode 100644 index 000000000..c0eef51e0 --- /dev/null +++ b/uppsrc/CtrlCore/CtrlFrame.cpp @@ -0,0 +1,127 @@ +#include "CtrlCore.h" + +#define LLOG(x) + +namespace Upp { + +Ctrl::Frame Ctrl::AllocFrames(int alloc) +{ + Frame m; + size_t sz0 = alloc * sizeof(Frame); + size_t sz = sz0; + m.frames = (Frame *)MemoryAllocSz(sz); + m.multi.alloc = alloc + (int)((sz - sz0) / sizeof(Frame)); + return m; +} + +void Ctrl::InsertFrame(int i, CtrlFrame& fr) +{ + GuiLock __; + int fc = GetFrameCount(); + ASSERT(i <= fc); + if(i == 0 && fc == 0) { + frame.frame = &fr; + multi_frame = false; + } + else { + if(!multi_frame) { + Frame h = AllocFrames(2); + h.frames[0].frame = frame.frame; + h.multi.count = 1; + frame = h; + multi_frame = true; + } + if(frame.multi.count + 1 > frame.multi.alloc) { + Frame h = AllocFrames(3 * frame.multi.count / 2 + 1); + memcpy(h.frames, frame.frames, i * sizeof(Frame)); + memcpy(h.frames + i + 1, frame.frames + i, (frame.multi.count - i) * sizeof(Frame)); + h.multi.count = frame.multi.count; + FreeFrames(); + frame = h; + } + else + memmove(frame.frames + i + 1, frame.frames + i, (frame.multi.count - i) * sizeof(Frame)); + frame.frames[i].frame = &fr; + frame.multi.count++; + } + fr.FrameAdd(*this); + SyncLayout(); + RefreshFrame(); +} + +Ctrl& Ctrl::AddFrame(CtrlFrame& fr) { + InsertFrame(GetFrameCount(), fr); + return *this; +} + +void Ctrl::RemoveFrame(int i) { + ASSERT(i < GetFrameCount()); + if(multi_frame) { + ASSERT(frame.multi.count > 1); + memmove(frame.frames + i, frame.frames + i + 1, (frame.multi.count - i - 1) * sizeof(Frame)); + frame.multi.count--; + if(frame.multi.count == 1) { + CtrlFrame *h = frame.frames[0].frame; + FreeFrames(); + multi_frame = false; + frame.frame = h; + } + else + if(3 * frame.multi.count < frame.multi.alloc) { + Frame h = AllocFrames(3 * frame.multi.count / 2 + 1); + memcpy(h.frames, frame.frames, frame.multi.count * sizeof(Frame)); + h.multi.count = frame.multi.count; + FreeFrames(); + frame = h; + } + } + else + frame.frame = nullptr; + if(GetFrameCount() == 0) + SetFrame(NullFrame()); + SyncLayout(); + RefreshFrame(); +} + +Ctrl& Ctrl::SetFrame(int i, CtrlFrame& fr) { + GuiLock __; + LLOG("SetFrame " << typeid(fr).name()); + while(GetFrameCount() <= i) + AddFrame(NullFrame()); + Frame& f = GetFrame0(i); + f.frame->FrameRemove(); + f.frame = &fr; + fr.FrameAdd(*this); + SyncLayout(); + RefreshFrame(); + return *this; +} + +void Ctrl::ClearFrames() { + GuiLock __; + FreeFrames(); + multi_frame = false; + frame.frame = &NullFrame(); + SyncLayout(); + RefreshFrame(); +} + +int Ctrl::FindFrame(CtrlFrame& frm) const +{ + GuiLock __; + int n = GetFrameCount(); + for(int i = 0; i < n; i++) + if(&GetFrame(i) == &frm) + return i; + return -1; +} + +void Ctrl::RemoveFrame(CtrlFrame& frm) +{ + GuiLock __; + int i = FindFrame(frm); + if(i >= 0) + RemoveFrame(i); +} + +}; \ No newline at end of file diff --git a/uppsrc/CtrlCore/CtrlPos.cpp b/uppsrc/CtrlCore/CtrlPos.cpp index ef791533a..fed2a4026 100644 --- a/uppsrc/CtrlCore/CtrlPos.cpp +++ b/uppsrc/CtrlCore/CtrlPos.cpp @@ -60,7 +60,8 @@ Rect Ctrl::GetRect() const Rect Ctrl::GetView() const { GuiLock __; - return frame.GetCount() == 0 ? Rect(Size(rect.Size())) : Rect(frame[frame.GetCount() - 1].view); + int n = GetFrameCount(); + return n == 0 ? Rect(Size(rect.Size())) : Rect(GetFrame0(n - 1).GetView()); } Size Ctrl::GetSize() const @@ -111,8 +112,8 @@ Size Ctrl::AddFrameSize(int cx, int cy) const { GuiLock __; Size sz = Size(cx, cy); - for(int i = frame.GetCount() - 1; i >= 0; i--) - frame[i].frame->FrameAddSize(sz); + for(int i = GetFrameCount() - 1; i >= 0; i--) + GetFrame0(i).frame->FrameAddSize(sz); return sz; } @@ -146,11 +147,12 @@ void Ctrl::SyncLayout(int force) Rect oview = GetView(); Rect view = GetRect().Size(); overpaint = OverPaint(); - for(int i = 0; i < frame.GetCount(); i++) { - Frame& f = frame[i]; + int n = GetFrameCount(); + for(int i = 0; i < n; i++) { + Frame& f = GetFrame0(i); f.frame->FrameLayout(view); - if(view != Rect(f.view)) { - f.view = view; + if(view != f.GetView()) { + f.SetView(view); refresh = true; } int q = f.frame->OverPaint(); @@ -336,93 +338,6 @@ void Ctrl::SetFrameRectY(int y, int cy) { SetFramePosY(PosTop(y, cy)); } -Ctrl& Ctrl::SetFrame(int i, CtrlFrame& fr) { - GuiLock __; - LLOG("SetFrame " << typeid(fr).name()); - while(frame.GetCount() <= i) - frame.Add().frame = &NullFrame(); - frame[i].frame->FrameRemove(); - frame[i].frame = &fr; - fr.FrameAdd(*this); - SyncLayout(); - RefreshFrame(); - return *this; -} - -Ctrl& Ctrl::AddFrame(CtrlFrame& fr) { - GuiLock __; - LLOG("AddFrame " << typeid(fr).name()); - frame.Add().frame = &fr; - fr.FrameAdd(*this); - SyncLayout(); - RefreshFrame(); - return *this; -} - -void Ctrl::ClearFrames() { - GuiLock __; - for(int i = 0; i < frame.GetCount(); i++) - frame[i].frame->FrameRemove(); - frame.Clear(); - frame.Add().frame = &NullFrame(); - RefreshFrame(); - SyncLayout(); -} - -void Ctrl::RemoveFrame(int i) { - GuiLock __; - int n = frame.GetCount(); - Mitor m; - if(n > 1) - for(int q = 0; q < n; q++) { - if(q != i) - m.Add().frame = frame[q].frame; - else - frame[q].frame->FrameRemove(); - } - frame = pick(m); - if(frame.GetCount() == 0) - frame.Add().frame = &NullFrame(); - RefreshFrame(); - SyncLayout(); -} - -int Ctrl::FindFrame(CtrlFrame& frm) -{ - GuiLock __; - for(int i = 0; i < frame.GetCount(); i++) - if(frame[i].frame == &frm) - return i; - return -1; -} - -void Ctrl::RemoveFrame(CtrlFrame& frm) -{ - GuiLock __; - int i = FindFrame(frm); - if(i >= 0) - RemoveFrame(i); -} - -void Ctrl::InsertFrame(int i, CtrlFrame& fr) -{ - GuiLock __; - ASSERT(i >= 0 && i <= frame.GetCount()); - int n = frame.GetCount(); - Mitor m; - if(n >= 1) - for(int q = 0; q < n; q++) { - if(q == i) m.Add().frame = &fr; - m.Add().frame = frame[q].frame; - } - if(i == n) - m.Add().frame = &fr; - frame = pick(m); - fr.FrameAdd(*this); - SyncLayout(); - RefreshFrame(); -} - Ctrl& Ctrl::LeftPos(int a, int size) { return SetPosX(PosLeft(a, size)); } diff --git a/uppsrc/CtrlLib/HeaderCtrl.h b/uppsrc/CtrlLib/HeaderCtrl.h index 035fafd89..73b8f5f9b 100644 --- a/uppsrc/CtrlLib/HeaderCtrl.h +++ b/uppsrc/CtrlLib/HeaderCtrl.h @@ -29,14 +29,14 @@ public: protected: virtual void LabelUpdate(); + String tip; HeaderCtrl *header; double ratio; - bool visible; int min, max; int margin; Color paper; int index; - String tip; + bool visible; void Paint(bool& first, Draw& w, int x, int y, int cx, int cy, bool disabled, bool push, bool hl); diff --git a/uppsrc/CtrlLib/LabelBase.cpp b/uppsrc/CtrlLib/LabelBase.cpp index 88259a131..cceae5cdb 100644 --- a/uppsrc/CtrlLib/LabelBase.cpp +++ b/uppsrc/CtrlLib/LabelBase.cpp @@ -124,7 +124,6 @@ DrawLabel::DrawLabel() ink = disabledink = Null; align = valign = ALIGN_CENTER; accesskey = 0; - accesspos = -1; font = StdFont(); nowrap = false; } diff --git a/uppsrc/CtrlLib/LabelBase.h b/uppsrc/CtrlLib/LabelBase.h index 3b5635e2b..2c14d1cdd 100644 --- a/uppsrc/CtrlLib/LabelBase.h +++ b/uppsrc/CtrlLib/LabelBase.h @@ -41,17 +41,16 @@ struct DrawLabel { int rspc; int lspc; - int align, valign; - int accesskey; - int accesspos; - bool nowrap; - bool push; - bool focus; - bool disabled; - bool limg_never_hide; - bool rimg_never_hide; + int align:4, valign:4; + + bool nowrap:1; + bool push:1; + bool focus:1; + bool disabled:1; + bool limg_never_hide:1; + bool rimg_never_hide:1; Size GetSize(int txtcx, Size sz1, int lspc, Size sz2, int rspc) const; Size GetSize(int txtcx = INT_MAX) const;