From 59c095e344cfbba0bbe2d67a5d7f82ccf536c7b2 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Mon, 11 Apr 2022 18:42:26 +0200 Subject: [PATCH 01/23] Refactored Ctrl texts --- autotest/CtrlInfoParts/CtrlInfoParts.upp | 10 +++++ autotest/CtrlInfoParts/etalon.log | 27 +++++++++++++ autotest/CtrlInfoParts/main.cpp | 51 ++++++++++++++++++++++++ uppsrc/CtrlCore/Ctrl.cpp | 46 +++++++++++++++++++-- uppsrc/CtrlCore/CtrlCore.h | 9 ++--- uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp | 8 ---- 6 files changed, 134 insertions(+), 17 deletions(-) create mode 100644 autotest/CtrlInfoParts/CtrlInfoParts.upp create mode 100644 autotest/CtrlInfoParts/etalon.log create mode 100644 autotest/CtrlInfoParts/main.cpp diff --git a/autotest/CtrlInfoParts/CtrlInfoParts.upp b/autotest/CtrlInfoParts/CtrlInfoParts.upp new file mode 100644 index 000000000..eee14521c --- /dev/null +++ b/autotest/CtrlInfoParts/CtrlInfoParts.upp @@ -0,0 +1,10 @@ +uses + CtrlLib; + +file + etalon.log, + main.cpp; + +mainconfig + "" = "GUI"; + diff --git a/autotest/CtrlInfoParts/etalon.log b/autotest/CtrlInfoParts/etalon.log new file mode 100644 index 000000000..4091b7e14 --- /dev/null +++ b/autotest/CtrlInfoParts/etalon.log @@ -0,0 +1,27 @@ +* C:\upp\out\gui_sizeof_autotest\CLANGx64.Debug.Debug_Full.Gui\CtrlInfoParts.exe 11.04.2022 18:41:30, user: cxl + +======================== +h.GetLayoutId() = just some literal +h.GetTip() = +h.GetDescription() = +h.GetHelpLine() = +======================== +h.GetLayoutId() = just some text +h.GetTip() = +h.GetDescription() = +h.GetHelpLine() = +======================== +h.GetLayoutId() = just some literal +h.GetTip() = +h.GetDescription() = +h.GetHelpLine() = some helpline +======================== +h.GetLayoutId() = just some text +h.GetTip() = +h.GetDescription() = +h.GetHelpLine() = some helpline +======================== +h.GetLayoutId() = just some literal +h.GetTip() = this is tip +h.GetDescription() = this is description +h.GetHelpLine() = some helpline diff --git a/autotest/CtrlInfoParts/main.cpp b/autotest/CtrlInfoParts/main.cpp new file mode 100644 index 000000000..f0e248186 --- /dev/null +++ b/autotest/CtrlInfoParts/main.cpp @@ -0,0 +1,51 @@ +#include + +using namespace Upp; + +GUI_APP_MAIN +{ + auto Print = [&](Ctrl& h) { + DLOG("========================"); + DDUMP(h.GetLayoutId()); + DDUMP(h.GetTip()); + DDUMP(h.GetDescription()); + DDUMP(h.GetHelpLine()); + }; + + { + Ctrl h; + h.LayoutIdLiteral("just some literal"); + Print(h); + } + + { + Ctrl h; + h.LayoutId(String("just some text")); + Print(h); + } + + { + Ctrl h; + h.LayoutIdLiteral("just some literal"); + h.HelpLine("some helpline"); + Print(h); + } + + { + Ctrl h; + h.LayoutId(String("just some text")); + h.HelpLine("some helpline"); + Print(h); + } + + { + Ctrl h; + h.LayoutIdLiteral("just some literal"); + h.Tip("this is tip"); + h.HelpLine("some helpline"); + h.Description("this is description"); + Print(h); + } + + CheckLogEtalon(); +} diff --git a/uppsrc/CtrlCore/Ctrl.cpp b/uppsrc/CtrlCore/Ctrl.cpp index ca00a80be..e29e64a77 100644 --- a/uppsrc/CtrlCore/Ctrl.cpp +++ b/uppsrc/CtrlCore/Ctrl.cpp @@ -390,9 +390,21 @@ void Ctrl::KillCaret() void Ctrl::SetInfoPart(int i, const char *txt) { - Vector f = Split(info, '\x7f', false); + Vector f; + if(info_ptr) { + if(layout_id_literal) + f.At(4) = info_ptr; + else { + f = Split(info_ptr, '\x7f', false); + delete[] info_ptr; + } + } f.At(i) = txt; - info = Join(f, "\x7f"); + String h = Join(f, "\x7f"); + char *s = new char[h.GetCount() + 1]; + memcpy(s, ~h, h.GetCount() + 1); + info_ptr = s; + layout_id_literal = false; } Ctrl& Ctrl::Tip(const char *txt) @@ -425,10 +437,24 @@ Ctrl& Ctrl::LayoutId(const char *txt) return *this; } +Ctrl& Ctrl::LayoutIdLiteral(const char *txt) +{ + if(info_ptr && !layout_id_literal) + LayoutId(txt); + else { + info_ptr = txt; + layout_id_literal = true; + } + return *this; +} + String Ctrl::GetInfoPart(int i) const { - Vector f = Split(info, '\x7f', false); - return i < f.GetCount() ? f[i] : String(); + if(info_ptr && !layout_id_literal) { + Vector f = Split(info_ptr, '\x7f', false); + return i < f.GetCount() ? f[i] : String(); + } + return String(); } String Ctrl::GetTip() const @@ -453,9 +479,18 @@ String Ctrl::GetHelpTopic() const String Ctrl::GetLayoutId() const { + if(info_ptr && layout_id_literal) + return info_ptr; return GetInfoPart(4); } +void Ctrl::ClearInfo() +{ + if(info_ptr && !layout_id_literal) + delete[] info_ptr; + info_ptr = nullptr; +} + bool Ctrl::SetWantFocus() { GuiLock __; if(IsWantFocus() && IsEnabled() && IsVisible() && IsOpen()) @@ -611,6 +646,8 @@ Ctrl::Ctrl() { popupgrab = false; fullrefresh = false; akv = false; + layout_id_literal = false; + info_ptr = nullptr; } void KillTimeCallbacks(void *id, void *idlim); @@ -693,6 +730,7 @@ Ctrl::~Ctrl() { parent->RemoveChild(this); Close(); KillTimeCallbacks(this, (byte *) this + sizeof(Ctrl)); + ClearInfo(); } Vector& Ctrl::mousehook() { static Vector h; return h; } diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index 28ef11e8b..dd5d93beb 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -496,7 +496,7 @@ private: LogPos pos;//8 Rect16 rect; Mitor frame;//16 - String info;//16 + const char *info_ptr; int16 caretx, carety, caretcx, caretcy;//8 byte overpaint; @@ -523,6 +523,7 @@ private: bool akv:1; bool destroying:1; + bool layout_id_literal:1; // info_ptr points to layout char * literal, no heap involved static Ptr eventCtrl; static Ptr mouseCtrl; @@ -1191,21 +1192,19 @@ public: Ctrl& NoTransparent() { return Transparent(false); } bool IsTransparent() const { return transparent; } - Ctrl& Info(const char *txt) { info = txt; return *this; } - String GetInfo() const { return info; } - Ctrl& Tip(const char *txt); Ctrl& HelpLine(const char *txt); Ctrl& Description(const char *txt); Ctrl& HelpTopic(const char *txt); Ctrl& LayoutId(const char *txt); + Ctrl& LayoutIdLiteral(const char *txt); String GetTip() const; String GetHelpLine() const; String GetDescription() const; String GetHelpTopic() const; String GetLayoutId() const; - void ClearInfo() { info.Clear(); } + void ClearInfo(); void Add(Ctrl& ctrl) { AddChild(&ctrl); } Ctrl& operator<<(Ctrl& ctrl) { Add(ctrl); return *this; } diff --git a/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp b/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp index ad9811287..037a33177 100644 --- a/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp +++ b/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp @@ -2240,14 +2240,6 @@ l]_[*@3 ax]_`=_[@(0.0.255) true])&] [s7;i1120;a17; [*/ Return value]-|Value of ActiveX flag.&] [s3;%- &] [s4;%- &] -[s5;:Ctrl`:`:Info`(const char`*`):%- [_^`:`:Ctrl^ Ctrl][@(0.0.255) `&]_[* Info]([@(0.0.255) c -onst]_[@(0.0.255) char]_`*[*@3 txt])&] -[s2;b17;a17; Sets Tip text of Ctrl. This text is displayed as tooltip -of Ctrl.&] -[s7;i1120;a17; [%-*C@3 txt]-|Text.&] -[s7;i1120;a17; [*/ Return value]-|`*this for method chaining.&] -[s3;%- &] -[s4;%- &] [s5;:Ctrl`:`:HelpLine`(const char`*`):%- [_^`:`:Ctrl^ Ctrl][@(0.0.255) `&]_[* HelpLine]([@(0.0.255) c onst]_[@(0.0.255) char]_`*[*@3 txt])&] [s2;b17;a17; Sets help topic link for Ctrl.&] From b97ddd71edc201ef222c27537058385cf5e87f2a Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Tue, 12 Apr 2022 09:39:10 +0200 Subject: [PATCH 02/23] CtrlCore: Ctrl::exitcode removed (4 bytes saved..) --- uppsrc/CtrlCore/Ctrl.cpp | 10 ++-------- uppsrc/CtrlCore/CtrlCore.h | 2 -- uppsrc/CtrlCore/TopWindow.h | 4 ++++ uppsrc/CtrlCore/lay0.h | 6 +++--- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/uppsrc/CtrlCore/Ctrl.cpp b/uppsrc/CtrlCore/Ctrl.cpp index e29e64a77..215c65ac7 100644 --- a/uppsrc/CtrlCore/Ctrl.cpp +++ b/uppsrc/CtrlCore/Ctrl.cpp @@ -629,7 +629,6 @@ Ctrl::Ctrl() { destroying = false; parent = prev = next = firstchild = lastchild = NULL; top = NULL; - exitcode = 0; frame.Add().frame = &NullFrame(); enabled = visible = wantfocus = initfocus = true; editable = true; @@ -1102,7 +1101,8 @@ void Ctrl::EndLoop(int code) { GuiLock __; ASSERT(!parent); - exitcode = code; + TopWindow *w = GetTopWindow(); + w->exitcode = code; EndLoop(); } @@ -1118,12 +1118,6 @@ bool Ctrl::InCurrentLoop() const return GetLoopCtrl() == this; } -int Ctrl::GetExitCode() const -{ - GuiLock __; - return exitcode; -} - #ifdef HAS_TopFrameDraw ViewDraw::ViewDraw(Ctrl *ctrl, const Rect& r) diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index dd5d93beb..c84e831b8 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -489,7 +489,6 @@ private: }; Top *top; - int exitcode; Ctrl *prev, *next; Ctrl *firstchild, *lastchild;//16 @@ -1255,7 +1254,6 @@ public: void EndLoop(int code); bool InLoop() const; bool InCurrentLoop() const; - int GetExitCode() const; static PasteClip& Clipboard(); static PasteClip& Selection(); diff --git a/uppsrc/CtrlCore/TopWindow.h b/uppsrc/CtrlCore/TopWindow.h index f6bd780e9..a2186c244 100644 --- a/uppsrc/CtrlCore/TopWindow.h +++ b/uppsrc/CtrlCore/TopWindow.h @@ -48,6 +48,8 @@ private: bool fullscreen; byte center:2; + + int exitcode = 0; void PlaceFocus(); void ActiveFocus0(Ctrl& ctrl); @@ -91,6 +93,8 @@ private: GUIPLATFORM_TOPWINDOW_DECLS #endif + friend class Ctrl; + public: virtual void ShutdownWindow(); diff --git a/uppsrc/CtrlCore/lay0.h b/uppsrc/CtrlCore/lay0.h index 28175f571..e2da1477b 100644 --- a/uppsrc/CtrlCore/lay0.h +++ b/uppsrc/CtrlCore/lay0.h @@ -54,9 +54,9 @@ #define LAYOUT(nm, x, y) template \ void InitLayout(UPP::Ctrl& parent, L& layout, D& uts, nm##__layid&) { \ - parent.LayoutId(#nm); -#define UNTYPED(var, param) uts.var.param; uts.var.LayoutId(#var); parent.Add(uts.var); -#define ITEM(clss, var, param) layout.var.param; layout.var.LayoutId(#var); parent.Add(layout.var); + parent.LayoutIdLiteral(#nm); +#define UNTYPED(var, param) uts.var.param; uts.var.LayoutIdLiteral(#var); parent.Add(uts.var); +#define ITEM(clss, var, param) layout.var.param; layout.var.LayoutIdLiteral(#var); parent.Add(layout.var); #define END_LAYOUT } #include LAYOUTFILE From a78517a6711ecfc89b966b381cd00b8e887e29e8 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Tue, 12 Apr 2022 11:31:31 +0200 Subject: [PATCH 03/23] CtrlCore: Refactored child tree structure to save 8 bytes in Ctrl --- autotest/CtrlChildren/CtrlChildren.upp | 10 +++++ autotest/CtrlChildren/etalon.log | 15 +++++++ autotest/CtrlChildren/main.cpp | 29 +++++++++++++ uppsrc/CtrlCore/Ctrl.cpp | 20 ++++----- uppsrc/CtrlCore/CtrlChild.cpp | 58 ++++++++++++-------------- uppsrc/CtrlCore/CtrlCore.h | 21 +++++----- uppsrc/CtrlCore/CtrlDraw.cpp | 48 ++++++++++----------- uppsrc/CtrlCore/CtrlKbd.cpp | 2 +- uppsrc/CtrlCore/CtrlMouse.cpp | 4 +- uppsrc/CtrlCore/CtrlPos.cpp | 8 ++-- uppsrc/CtrlLib/LabelBase.h | 36 ++++++++-------- 11 files changed, 149 insertions(+), 102 deletions(-) create mode 100644 autotest/CtrlChildren/CtrlChildren.upp create mode 100644 autotest/CtrlChildren/etalon.log create mode 100644 autotest/CtrlChildren/main.cpp diff --git a/autotest/CtrlChildren/CtrlChildren.upp b/autotest/CtrlChildren/CtrlChildren.upp new file mode 100644 index 000000000..eee14521c --- /dev/null +++ b/autotest/CtrlChildren/CtrlChildren.upp @@ -0,0 +1,10 @@ +uses + CtrlLib; + +file + etalon.log, + main.cpp; + +mainconfig + "" = "GUI"; + diff --git a/autotest/CtrlChildren/etalon.log b/autotest/CtrlChildren/etalon.log new file mode 100644 index 000000000..c8ee03a20 --- /dev/null +++ b/autotest/CtrlChildren/etalon.log @@ -0,0 +1,15 @@ +* C:\upp\out\gui_sizeof_autotest\CLANGx64.Debug.Debug_Full.Gui\CtrlChildren.exe 12.04.2022 11:30:36, user: cxl + +============================== +N3Upp5LabelE +N3Upp10EditMinMaxIiNS_10ConvertIntEEE +============================== +N3Upp5LabelE +N3Upp10StaticRectE +N3Upp10EditMinMaxIiNS_10ConvertIntEEE +============================== +N3Upp10StaticRectE +N3Upp10EditMinMaxIiNS_10ConvertIntEEE +============================== +N3Upp10StaticRectE +============================== diff --git a/autotest/CtrlChildren/main.cpp b/autotest/CtrlChildren/main.cpp new file mode 100644 index 000000000..f4d3cc10f --- /dev/null +++ b/autotest/CtrlChildren/main.cpp @@ -0,0 +1,29 @@ +#include + +using namespace Upp; + +GUI_APP_MAIN +{ + TopWindow top; + Label lbl; + EditInt edit; + StaticRect list; + auto Print = [&] { + DLOG("=============================="); + for(Ctrl& q : top) + DLOG(typeid(q).name()); + }; + + top << lbl << edit; + Print(); + top.AddChild(&list, &lbl); + Print(); + lbl.Remove(); + Print(); + edit.Ctrl::Remove(); + Print(); + list.Ctrl::Remove(); + Print(); + + CheckLogEtalon(); +} diff --git a/uppsrc/CtrlCore/Ctrl.cpp b/uppsrc/CtrlCore/Ctrl.cpp index 215c65ac7..eb8c1ff77 100644 --- a/uppsrc/CtrlCore/Ctrl.cpp +++ b/uppsrc/CtrlCore/Ctrl.cpp @@ -353,8 +353,8 @@ void Ctrl::ClearModifyDeep() { GuiLock __; ClearModify(); - for(Ctrl *q = firstchild; q; q = q->next) - q->ClearModifyDeep(); + for(Ctrl& q : *this) + q.ClearModifyDeep(); } @@ -368,8 +368,8 @@ bool Ctrl::IsModifiedDeep() const { GuiLock __; if(IsModified()) return true; - for(Ctrl *q = firstchild; q; q = q->next) - if(q->IsModified()) return true; + for(const Ctrl& q : *this) + if(q.IsModified()) return true; return false; } @@ -528,8 +528,8 @@ void Ctrl::UpdateActionRefresh() { void Ctrl::CancelModeDeep() { GuiLock __; CancelMode(); - for(Ctrl *q = firstchild; q; q = q->next) - q->CancelModeDeep(); + for(Ctrl& q : *this) + q.CancelModeDeep(); } String Ctrl::GetDesc() const @@ -585,11 +585,11 @@ void Ctrl::Dump(Stream& s) const { for(int i = 0; i < frame.GetCount(); i++) LG("Frame " << i << ": " << typeid(decltype(*frame[i].frame)).name() << " - " << frame[i].view); LG("Data: " << GetData().ToString()); - if(firstchild) { + if(children) { LG("Children"); s << LOG_BEGIN; - for(Ctrl *q = GetFirstChild(); q; q = q->GetNext()) { - q->Dump(s); + for(const Ctrl& q : *this) { + q.Dump(s); LG("------"); } s << LOG_END; @@ -627,8 +627,6 @@ Ctrl::Ctrl() { LLOG("Ctrl::Ctrl"); GuiPlatformConstruct(); destroying = false; - parent = prev = next = firstchild = lastchild = NULL; - top = NULL; frame.Add().frame = &NullFrame(); enabled = visible = wantfocus = initfocus = true; editable = true; diff --git a/uppsrc/CtrlCore/CtrlChild.cpp b/uppsrc/CtrlCore/CtrlChild.cpp index caf4a6624..67283171b 100644 --- a/uppsrc/CtrlCore/CtrlChild.cpp +++ b/uppsrc/CtrlCore/CtrlChild.cpp @@ -24,29 +24,22 @@ void Ctrl::AddChild(Ctrl *q, Ctrl *p) else q->parent->RemoveChild(q); } - q->parent = this; - if(p) { + + if(children) { + if(!p) p = GetLastChild(); ASSERT(p->parent == this); - q->prev = p; - q->next = p->next; - if(p == lastchild) - lastchild = q; - else - p->next->prev = q; - p->next = q; + q->prev_sibling = p; + q->next_sibling = p->next_sibling; + p->next_sibling->prev_sibling = q; + p->next_sibling = q; } - else - if(firstchild) { - q->prev = NULL; - q->next = firstchild; - firstchild->prev = q; - firstchild = q; - } - else { - ASSERT(lastchild == NULL); - firstchild = lastchild = q; - q->prev = q->next = NULL; - } + else { + ASSERT(!p); + children = q; + children->next_sibling = children->prev_sibling = children; + } + q->parent = this; + q->CancelModeDeep(); if(updaterect) q->UpdateRect(); @@ -58,13 +51,13 @@ void Ctrl::AddChild(Ctrl *q, Ctrl *p) void Ctrl::AddChild(Ctrl *child) { - AddChild(child, lastchild); + AddChild(child, GetLastChild()); } void Ctrl::AddChildBefore(Ctrl *child, Ctrl *insbefore) { if(insbefore) - AddChild(child, insbefore->prev); + AddChild(child, insbefore->GetPrev()); else AddChild(child); } @@ -75,15 +68,16 @@ void Ctrl::RemoveChild0(Ctrl *q) ChildRemoved(q); q->DoRemove(); q->parent = NULL; - if(q == firstchild) - firstchild = firstchild->next; - if(q == lastchild) - lastchild = lastchild->prev; - if(q->prev) - q->prev->next = q->next; - if(q->next) - q->next->prev = q->prev; - q->next = q->prev = NULL; + + if(q == children) { + children = q->next_sibling; + if(children == q) + children = NULL; + } + + q->prev_sibling->next_sibling = q->next_sibling; + q->next_sibling->prev_sibling = q->prev_sibling; + q->next_sibling = q->prev_sibling = NULL; } void Ctrl::RemoveChild(Ctrl *q) diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index c84e831b8..c2e8d0c54 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -464,7 +464,7 @@ private: Frame() { view.Clear(); } }; - Ctrl *parent; + Ctrl *parent = nullptr; struct Scroll : Moveable { Rect rect; @@ -488,14 +488,15 @@ private: Ptr owner; }; - Top *top; + Top *top = nullptr; - Ctrl *prev, *next; - Ctrl *firstchild, *lastchild;//16 + Ctrl *prev_sibling = nullptr; + Ctrl *next_sibling = nullptr; + Ctrl *children = nullptr;//16 LogPos pos;//8 Rect16 rect; Mitor frame;//16 - const char *info_ptr; + const char *info_ptr = nullptr; int16 caretx, carety, caretcx, caretcy;//8 byte overpaint; @@ -952,11 +953,11 @@ public: void AddChild(Ctrl *child, Ctrl *insafter); void AddChildBefore(Ctrl *child, Ctrl *insbefore); void RemoveChild(Ctrl *child); - Ctrl *GetParent() const { return parent; } - Ctrl *GetLastChild() const { return lastchild; } - Ctrl *GetFirstChild() const { return firstchild; } - Ctrl *GetPrev() const { return parent ? prev : NULL; } - Ctrl *GetNext() const { return parent ? next : NULL; } + Ctrl *GetParent() const { return parent; } + Ctrl *GetLastChild() const { return children ? children->prev_sibling : nullptr; } + Ctrl *GetFirstChild() const { return children; } + Ctrl *GetPrev() const { return parent && prev_sibling != parent->GetLastChild() ? prev_sibling : nullptr; } + Ctrl *GetNext() const { return parent && next_sibling != parent->children ? next_sibling : nullptr; } int GetChildIndex(const Ctrl *child) const; Ctrl *GetIndexChild(int i) const; int GetChildCount() const; diff --git a/uppsrc/CtrlCore/CtrlDraw.cpp b/uppsrc/CtrlCore/CtrlDraw.cpp index ca293d63b..ee816e140 100644 --- a/uppsrc/CtrlCore/CtrlDraw.cpp +++ b/uppsrc/CtrlCore/CtrlDraw.cpp @@ -287,20 +287,20 @@ void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip) { bool hasviewctrls = false; bool viewexcluded = false; bool hiddenbychild = false; - for(q = firstchild; q; q = q->next) - if(q->IsShown()) { - if(q->GetRect().Contains(orect) && !q->IsTransparent()) + for(Ctrl& q : *this) + if(q.IsShown()) { + if(q.GetRect().Contains(orect) && !q.IsTransparent()) hiddenbychild = true; - if(q->InFrame()) { - if(!viewexcluded && IsTransparent() && q->GetRect().Intersects(view)) { + if(q.InFrame()) { + if(!viewexcluded && IsTransparent() && q.GetRect().Intersects(view)) { w.Begin(); w.ExcludeClip(view); viewexcluded = true; } - LEVELCHECK(w, q); - Point off = q->GetRect().TopLeft(); + LEVELCHECK(w, &q); + Point off = q.GetRect().TopLeft(); w.Offset(off); - q->CtrlPaint(w, clip - off); + q.CtrlPaint(w, clip - off); w.End(); } else @@ -329,15 +329,15 @@ void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip) { if(hasviewctrls && !view.IsEmpty()) { Rect cl = clip & view; w.Clip(cl); - for(q = firstchild; q; q = q->next) - if(q->IsShown() && q->InView()) { - LEVELCHECK(w, q); - Rect qr = q->GetRect(); + for(Ctrl& q : *this) + if(q.IsShown() && q.InView()) { + LEVELCHECK(w, &q); + Rect qr = q.GetRect(); Point off = qr.TopLeft() + view.TopLeft(); Rect ocl = cl - off; if(ocl.Intersects(Rect(qr.GetSize()).Inflated(overpaint))) { w.Offset(off); - q->CtrlPaint(w, ocl); + q.CtrlPaint(w, ocl); w.End(); } } @@ -373,11 +373,11 @@ bool Ctrl::PaintOpaqueAreas(SystemDraw& w, const Rect& r, const Rect& clip, bool if(backpaint == EXCLUDEPAINT) return w.ExcludeClip(r); Rect cview = clip & (GetView() + off); - for(Ctrl *q = lastchild; q; q = q->prev) - if(!q->PaintOpaqueAreas(w, q->GetRect() + (q->InView() ? viewpos : off), - q->InView() ? cview : clip)) + for(Ctrl& q : *this) + if(!q.PaintOpaqueAreas(w, q.GetRect() + (q.InView() ? viewpos : off), + q.InView() ? cview : clip)) return false; - if(nochild && (lastchild || GetNext())) + if(nochild && (GetLastChild() || GetNext())) return true; Rect opaque = (GetOpaqueRect() + viewpos) & clip; if(opaque.IsEmpty()) @@ -461,11 +461,11 @@ void Ctrl::GatherTransparentAreas(Vector& area, SystemDraw& w, Rect r, con CombineArea(area, clip & Rect(notr.left, r.top, notr.right, notr.top)); CombineArea(area, clip & Rect(notr.left, notr.bottom, notr.right, r.bottom)); } - for(Ctrl *q = firstchild; q; q = q->next) { - Point qoff = q->InView() ? viewpos : off; - Rect qr = q->GetRect() + qoff; + for(Ctrl& q : *this) { + Point qoff = q.InView() ? viewpos : off; + Rect qr = q.GetRect() + qoff; if(clip.Intersects(qr)) - q->GatherTransparentAreas(area, w, qr, clip); + q.GatherTransparentAreas(area, w, qr, clip); } } } @@ -506,9 +506,9 @@ void Ctrl::ExcludeDHCtrls(SystemDraw& w, const Rect& r, const Rect& clip) return; } Rect cview = clip & (GetView() + off); - for(Ctrl *q = lastchild; q; q = q->prev) - q->ExcludeDHCtrls(w, q->GetRect() + (q->InView() ? viewpos : off), - q->InView() ? cview : clip); + for(Ctrl& q : *this) + q.ExcludeDHCtrls(w, q.GetRect() + (q.InView() ? viewpos : off), + q.InView() ? cview : clip); } void Ctrl::UpdateArea0(SystemDraw& draw, const Rect& clip, int backpaint) diff --git a/uppsrc/CtrlCore/CtrlKbd.cpp b/uppsrc/CtrlCore/CtrlKbd.cpp index d46778fad..24a448621 100644 --- a/uppsrc/CtrlCore/CtrlKbd.cpp +++ b/uppsrc/CtrlCore/CtrlKbd.cpp @@ -116,7 +116,7 @@ bool Ctrl::HotKey(dword key) GuiLock __; LLOG("HotKey " << GetKeyDesc(key) << " at " << Name(this)); if(!IsEnabled() || !IsVisible()) return false; - for(Ptr ctrl = firstchild; ctrl; ctrl = ctrl->next) + for(Ptr ctrl = GetFirstChild(); ctrl; ctrl = ctrl->GetNext()) { LLOG("Trying HotKey " << GetKeyDesc(key) << " at " << Name(ctrl)); if(ctrl->IsOpen() && ctrl->IsVisible() && ctrl->IsEnabled() && ctrl->HotKey(key)) diff --git a/uppsrc/CtrlCore/CtrlMouse.cpp b/uppsrc/CtrlCore/CtrlMouse.cpp index ac7fce29e..5bff62811 100644 --- a/uppsrc/CtrlCore/CtrlMouse.cpp +++ b/uppsrc/CtrlCore/CtrlMouse.cpp @@ -280,7 +280,7 @@ Ctrl *Ctrl::ChildFromPoint(Point& pt) const Rect view = GetView(); if(view.Contains(p)) { Point vp = p - view.TopLeft(); - for(q = GetLastChild(); q; q = q->prev) { + for(q = GetLastChild(); q; q = q->GetPrev()) { if(q->InView() && q->IsMouseActive()) { Rect r = q->GetRect(); if(r.Contains(vp)) { @@ -291,7 +291,7 @@ Ctrl *Ctrl::ChildFromPoint(Point& pt) const } return NULL; } - for(q = GetLastChild(); q; q = q->prev) { + for(q = GetLastChild(); q; q = q->GetPrev()) { if(q->InFrame() && q->IsMouseActive()) { Rect r = q->GetRect(); if(r.Contains(p)) { diff --git a/uppsrc/CtrlCore/CtrlPos.cpp b/uppsrc/CtrlCore/CtrlPos.cpp index 5a83c7b54..ef791533a 100644 --- a/uppsrc/CtrlCore/CtrlPos.cpp +++ b/uppsrc/CtrlCore/CtrlPos.cpp @@ -157,10 +157,10 @@ void Ctrl::SyncLayout(int force) if(q > overpaint) overpaint = q; } if(oview.Size() != view.Size() || force > 1) { - for(Ctrl *q = GetFirstChild(); q; q = q->next) { - q->rect = q->CalcRect(rect, view); - LLOG("Layout set rect " << q->Name() << " " << q->rect); - q->SyncLayout(force > 1 ? force : 0); + for(Ctrl& q : *this) { + q.rect = q.CalcRect(rect, view); + LLOG("Layout set rect " << q.Name() << " " << q.rect); + q.SyncLayout(force > 1 ? force : 0); } Refresh(); } diff --git a/uppsrc/CtrlLib/LabelBase.h b/uppsrc/CtrlLib/LabelBase.h index 1b6c1d381..3b5635e2b 100644 --- a/uppsrc/CtrlLib/LabelBase.h +++ b/uppsrc/CtrlLib/LabelBase.h @@ -29,30 +29,30 @@ Point GetDragScroll(Ctrl *ctrl, Point p, Size max); Point GetDragScroll(Ctrl *ctrl, Point p, int max = 16); struct DrawLabel { + PaintRect paintrect; + String text; + Image limg; + Image rimg; + Font font; + Color lcolor; + Color ink, disabledink; + Color rcolor; + + 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; - PaintRect paintrect; - Image limg; - Color lcolor; - int lspc; - String text; - Font font; - Color ink, disabledink; - Image rimg; - Color rcolor; - int rspc; - - int align, valign; - - bool nowrap; - - int accesskey; - int accesspos; - Size GetSize(int txtcx, Size sz1, int lspc, Size sz2, int rspc) const; Size GetSize(int txtcx = INT_MAX) const; Size Paint(Ctrl *ctrl, Draw& w, const Rect& r, bool visibleaccesskey = true) const; From f2a3723483acda81bc21da9b4666da8f2d45e244 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Wed, 13 Apr 2022 16:21:16 +0200 Subject: [PATCH 04/23] CtrlCore: sizeof(Ctrl) reduction - Frame --- uppsrc/CtrlCore/Ctrl.cpp | 8 ++- uppsrc/CtrlCore/CtrlCore.h | 52 ++++++++++---- uppsrc/CtrlCore/CtrlCore.upp | 1 + uppsrc/CtrlCore/CtrlDraw.cpp | 8 ++- uppsrc/CtrlCore/CtrlFrame.cpp | 127 ++++++++++++++++++++++++++++++++++ uppsrc/CtrlCore/CtrlPos.cpp | 103 +++------------------------ uppsrc/CtrlLib/HeaderCtrl.h | 4 +- uppsrc/CtrlLib/LabelBase.cpp | 1 - uppsrc/CtrlLib/LabelBase.h | 17 +++-- 9 files changed, 196 insertions(+), 125 deletions(-) create mode 100644 uppsrc/CtrlCore/CtrlFrame.cpp 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; From 2ae9a6f100fcdf0829bdc47891eade911f95f658 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Wed, 13 Apr 2022 17:51:49 +0200 Subject: [PATCH 05/23] CtrlCore: sizeof(Ctrl) optimisation - GetParent --- uppsrc/CtrlCore/Ctrl.cpp | 40 ++++++++++++++++++++-------- uppsrc/CtrlCore/CtrlChild.cpp | 50 +++++++++++++++++++++++++---------- uppsrc/CtrlCore/CtrlCore.h | 35 +++++++++++++++--------- uppsrc/CtrlCore/CtrlDraw.cpp | 19 ++++++++----- uppsrc/CtrlCore/CtrlKbd.cpp | 10 +++---- uppsrc/CtrlCore/CtrlMouse.cpp | 6 +++++ uppsrc/CtrlCore/CtrlPos.cpp | 23 ++++++++++++++-- uppsrc/CtrlCore/TopWin32.cpp | 1 + uppsrc/CtrlCore/Win32Ctrl.h | 2 +- uppsrc/CtrlCore/Win32Proc.cpp | 9 ++++--- uppsrc/CtrlCore/Win32Wnd.cpp | 19 ++++++++----- 11 files changed, 151 insertions(+), 63 deletions(-) diff --git a/uppsrc/CtrlCore/Ctrl.cpp b/uppsrc/CtrlCore/Ctrl.cpp index db68c6158..a751fc482 100644 --- a/uppsrc/CtrlCore/Ctrl.cpp +++ b/uppsrc/CtrlCore/Ctrl.cpp @@ -79,7 +79,9 @@ void Ctrl::Layout() {} void Ctrl::PostInput() { GuiLock __; - if(parent) parent->PostInput(); + Ctrl *parent = GetParent(); + if(parent) + parent->PostInput(); } void Ctrl::LeftDouble(Point p, dword keyflags) @@ -105,25 +107,33 @@ void Ctrl::RightTriple(Point p, dword keyflags) void Ctrl::ChildGotFocus() { GuiLock __; - if(parent) parent->ChildGotFocus(); + Ctrl *parent = GetParent(); + if(parent) + parent->ChildGotFocus(); } void Ctrl::ChildLostFocus() { GuiLock __; - if(parent) parent->ChildLostFocus(); + Ctrl *parent = GetParent(); + if(parent) + parent->ChildLostFocus(); } void Ctrl::ChildAdded(Ctrl *q) { GuiLock __; - if(parent) parent->ChildAdded(q); + Ctrl *parent = GetParent(); + if(parent) + parent->ChildAdded(q); } void Ctrl::ChildRemoved(Ctrl *q) { GuiLock __; - if(parent) parent->ChildRemoved(q); + Ctrl *parent = GetParent(); + if(parent) + parent->ChildRemoved(q); } void Ctrl::ParentChange() {} @@ -287,6 +297,7 @@ void Ctrl::Show(bool ashow) { visible = ashow; fullrefresh = false; RefreshFrame(); + Ctrl *parent = GetParent(); if(parent) StateH(SHOW); if(top) @@ -301,8 +312,9 @@ bool Ctrl::IsVisible() const { const Ctrl *q = this; for(;;) { if(!q->visible) return false; - if(!q->parent) break; - q = q->parent; + Ctrl *p = q->GetParent(); + if(!p) break; + q = p; } return q->visible; } @@ -312,7 +324,7 @@ void Ctrl::Enable(bool aenable) { if(enabled != aenable) { enabled = aenable; if(top) WndEnable(enabled); - if(!enabled && parent && HasFocusDeep()) + if(!enabled && GetParent() && HasFocusDeep()) IterateFocusForward(this, GetTopCtrl()); RefreshFrame(); StateH(ENABLE); @@ -322,6 +334,7 @@ void Ctrl::Enable(bool aenable) { bool Ctrl::IsShowEnabled() const { GuiLock __; + Ctrl *parent = GetParent(); return IsEnabled() && (!parent || parent->IsShowEnabled()); } @@ -646,6 +659,8 @@ Ctrl::Ctrl() { akv = false; layout_id_literal = false; info_ptr = nullptr; + top = false; + uparent = nullptr; } void KillTimeCallbacks(void *id, void *idlim); @@ -661,6 +676,7 @@ void Ctrl::DoRemove() { mouseCtrl = NULL; LLOG("DoRemove " << Name() << " focusCtrl: " << UPP::Name(focusCtrl)); GuiPlatformRemove(); + Ctrl *parent = GetParent(); if(HasFocusDeep()) { LLOG("DoRemove - HasFocusDeep"); if(destroying) { @@ -710,7 +726,7 @@ void Ctrl::Close() Ctrl *q = GetTopCtrl(); if(!q->top) return; DoRemove(); - if(parent) return; + if(GetParent()) return; StateH(CLOSE); USRLOG(" CLOSE " + Desc(this)); WndDestroy(); @@ -724,6 +740,7 @@ Ctrl::~Ctrl() { destroying = true; while(GetFirstChild()) RemoveChild(GetFirstChild()); + Ctrl *parent = GetParent(); if(parent) parent->RemoveChild(this); Close(); @@ -1072,7 +1089,7 @@ String Ctrl::Name0() const { String id = q->GetLayoutId(); if(id.GetCount()) path = '.' + q->GetLayoutId() + path; - q = q->parent; + q = q->GetParent(); } s << ' ' << path; #ifdef CPU_64 @@ -1080,6 +1097,7 @@ String Ctrl::Name0() const { #else s << " : " + Format("0x%x", (int) this); #endif + Ctrl *parent = GetParent(); if(IsChild()) s << " (parent " << CppDemangle(typeid(*parent).name()) << ")"; return s; @@ -1100,7 +1118,7 @@ void Ctrl::EndLoop() void Ctrl::EndLoop(int code) { GuiLock __; - ASSERT(!parent); + ASSERT(!GetParent()); TopWindow *w = GetTopWindow(); w->exitcode = code; EndLoop(); diff --git a/uppsrc/CtrlCore/CtrlChild.cpp b/uppsrc/CtrlCore/CtrlChild.cpp index 67283171b..2133d6bd7 100644 --- a/uppsrc/CtrlCore/CtrlChild.cpp +++ b/uppsrc/CtrlCore/CtrlChild.cpp @@ -4,6 +4,22 @@ namespace Upp { #define LLOG(x) // DLOG(x) +void Ctrl::DeleteTop() +{ + if(top && utop) + delete utop; +} + +void Ctrl::SetParent(Ctrl *parent) +{ + if(top && utop) { + Close(); + DeleteTop(); // if Close did not work as expected...: + } + uparent = parent; + top = false; +} + bool Ctrl::IsDHCtrl() const { return dynamic_cast(this); } @@ -15,19 +31,20 @@ void Ctrl::AddChild(Ctrl *q, Ctrl *p) LLOG("Add " << UPP::Name(q) << " to: " << Name()); if(p == q) return; bool updaterect = true; - if(q->parent) { + Ctrl *qparent = q->GetParent(); + if(qparent) { ASSERT(!q->inframe); - if(q->parent == this) { + if(qparent == this) { RemoveChild0(q); updaterect = false; } else - q->parent->RemoveChild(q); + qparent->RemoveChild(q); } if(children) { if(!p) p = GetLastChild(); - ASSERT(p->parent == this); + ASSERT(p->GetParent() == this); q->prev_sibling = p; q->next_sibling = p->next_sibling; p->next_sibling->prev_sibling = q; @@ -38,7 +55,7 @@ void Ctrl::AddChild(Ctrl *q, Ctrl *p) children = q; children->next_sibling = children->prev_sibling = children; } - q->parent = this; + q->SetParent(this); q->CancelModeDeep(); if(updaterect) @@ -67,7 +84,7 @@ void Ctrl::RemoveChild0(Ctrl *q) GuiLock __; ChildRemoved(q); q->DoRemove(); - q->parent = NULL; + q->SetParent(NULL); if(q == children) { children = q->next_sibling; @@ -83,7 +100,7 @@ void Ctrl::RemoveChild0(Ctrl *q) void Ctrl::RemoveChild(Ctrl *q) { GuiLock __; - if(q->parent != this) return; + if(q->GetParent() != this) return; q->RefreshFrame(); RemoveChild0(q); q->ParentChange(); @@ -94,6 +111,7 @@ void Ctrl::RemoveChild(Ctrl *q) void Ctrl::Remove() { GuiLock __; + Ctrl *parent = GetParent(); if(parent) parent->RemoveChild(this); } @@ -165,15 +183,16 @@ Ctrl * Ctrl::GetViewIndexChild(int ii) const bool Ctrl::HasChild(Ctrl *q) const { GuiLock __; - return q && q->IsChild() && q->parent == this; + return q && q->GetParent() == this; } bool Ctrl::HasChildDeep(Ctrl *q) const { GuiLock __; while(q && q->IsChild()) { - if(q->parent == this) return true; - q = q->parent; + Ctrl *qparent = q->GetParent(); + if(qparent == this) return true; + q = qparent; } return false; } @@ -254,9 +273,12 @@ Ctrl *Ctrl::GetTopCtrl() { GuiLock __; Ctrl *q = this; - while(q->parent) - q = q->parent; - return q; + for(;;) { + Ctrl *qparent = q->GetParent(); + if(!qparent) + return q; + q = qparent; + } } const Ctrl *Ctrl::GetTopCtrl() const { return const_cast(this)->GetTopCtrl(); } @@ -264,7 +286,7 @@ const Ctrl *Ctrl::GetOwner() const { return const_cast(this)->Get Ctrl *Ctrl::GetTopCtrlOwner() { return GetTopCtrl()->GetOwner(); } const Ctrl *Ctrl::GetTopCtrlOwner() const { return GetTopCtrl()->GetOwner(); } -Ctrl *Ctrl::GetOwnerCtrl() { GuiLock __; return !IsChild() && top ? top->owner : NULL; } +Ctrl *Ctrl::GetOwnerCtrl() { GuiLock __; return !IsChild() && top && utop ? utop->owner : NULL; } const Ctrl *Ctrl::GetOwnerCtrl() const { return const_cast(this)->GetOwnerCtrl(); } TopWindow *Ctrl::GetTopWindow() diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index 8420fc655..9ee1b864b 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -481,10 +481,6 @@ private: Rect GetView() const { return Rect16(view.left, view.top, view.right, view.bottom); } }; - Frame frame; - - Ctrl *parent = nullptr; - struct Scroll : Moveable { Rect rect; int dx; @@ -507,7 +503,13 @@ private: Ptr owner; }; - Top *top = nullptr; + + Frame frame; + + union { + Ctrl *uparent; + Top *utop; + }; Ctrl *prev_sibling = nullptr; Ctrl *next_sibling = nullptr; @@ -541,9 +543,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 + bool top:1; static Ptr eventCtrl; static Ptr mouseCtrl; @@ -719,6 +721,13 @@ private: void SysEndLoop(); String Name0() const; + + Top *GetTop() { return top ? utop : NULL; } + const Top *GetTop() const { return top ? utop : NULL; } + void DeleteTop(); + + void SetTop(Top *t) { utop = t; top = true; } + void SetParent(Ctrl *parent); 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; } @@ -979,11 +988,11 @@ public: void AddChild(Ctrl *child, Ctrl *insafter); void AddChildBefore(Ctrl *child, Ctrl *insbefore); void RemoveChild(Ctrl *child); - Ctrl *GetParent() const { return parent; } + Ctrl *GetParent() const { return top ? NULL : uparent; } Ctrl *GetLastChild() const { return children ? children->prev_sibling : nullptr; } Ctrl *GetFirstChild() const { return children; } - Ctrl *GetPrev() const { return parent && prev_sibling != parent->GetLastChild() ? prev_sibling : nullptr; } - Ctrl *GetNext() const { return parent && next_sibling != parent->children ? next_sibling : nullptr; } + Ctrl *GetPrev() const { Ctrl *parent = GetParent(); return parent && prev_sibling != parent->GetLastChild() ? prev_sibling : nullptr; } + Ctrl *GetNext() const { Ctrl *parent = GetParent(); return parent && next_sibling != parent->children ? next_sibling : nullptr; } int GetChildIndex(const Ctrl *child) const; Ctrl *GetIndexChild(int i) const; int GetChildCount() const; @@ -994,7 +1003,7 @@ public: int GetViewChildCount() const; Ctrl *GetViewIndexChild(int ii) const; - bool IsChild() const { return parent; } + bool IsChild() const { return GetParent(); } Ctrl *ChildFromPoint(Point& pt) const; @@ -1062,10 +1071,10 @@ public: void RefreshLayout() { SyncLayout(1); } void RefreshLayoutDeep() { SyncLayout(2); } - void RefreshParentLayout() { if(parent) parent->RefreshLayout(); } + void RefreshParentLayout(); void UpdateLayout() { SyncLayout(); } - void UpdateParentLayout() { if(parent) parent->UpdateLayout(); } + void UpdateParentLayout(); Ctrl& LeftPos(int a, int size = STDSIZE); Ctrl& RightPos(int a, int size = STDSIZE); diff --git a/uppsrc/CtrlCore/CtrlDraw.cpp b/uppsrc/CtrlCore/CtrlDraw.cpp index 9daa8fd21..d5cbfd2d5 100644 --- a/uppsrc/CtrlCore/CtrlDraw.cpp +++ b/uppsrc/CtrlCore/CtrlDraw.cpp @@ -22,6 +22,7 @@ void Ctrl::RefreshFrame(const Rect& r) { if(GuiPlatformRefreshFrameSpecial(r)) return; if(!top && !IsDHCtrl()) { + Ctrl *parent = GetParent(); if(InFrame()) parent->RefreshFrame(r + GetRect().TopLeft()); else @@ -83,6 +84,7 @@ void Ctrl::ScrollRefresh(const Rect& r, int dx, int dy) bool Ctrl::AddScroll(const Rect& sr, int dx, int dy) { GuiLock __; + Top *top = GetTop(); if(!top) return true; for(int i = 0; i < top->scroll.GetCount(); i++) { @@ -113,12 +115,12 @@ Rect Ctrl::GetClippedView() GuiLock __; Rect sv = GetScreenView(); Rect view = sv; - Ctrl *q = parent; + Ctrl *q = GetParent(); Ctrl *w = this; while(q) { view &= w->InFrame() ? q->GetScreenRect() : q->GetScreenView(); w = q; - q = q->parent; + q = q->GetParent(); } return view - GetScreenRect().TopLeft(); } @@ -178,7 +180,7 @@ void Ctrl::ScrollView(const Rect& _r, int dx, int dy) Rect r = _r & vsz; LLOG("ScrollView2 " << r << " " << dx << " " << dy); Ctrl *w; - for(w = this; w->parent; w = w->parent) + for(w = this; w->GetParent(); w = w->GetParent()) if(w->InFrame()) { Refresh(); return; @@ -191,12 +193,12 @@ void Ctrl::ScrollView(const Rect& _r, int dx, int dy) Refresh(); else { LTIMING("ScrollCtrls1"); - Top *top = GetTopCtrl()->top; + Top *top = GetTopCtrl()->GetTop(); for(Ctrl *q = GetFirstChild(); q; q = q->GetNext()) if(q->InView()) ScrollCtrl(top, q, r, q->GetRect(), dx, dy); - if(parent) - for(Ctrl *q = parent->GetFirstChild(); q; q = q->GetNext()) + if(GetParent()) + for(Ctrl *q = GetParent()->GetFirstChild(); q; q = q->GetNext()) if(q->InView() && q != this) ScrollCtrl(top, q, r, q->GetScreenRect() - GetScreenView().TopLeft(), dx, dy); } @@ -214,6 +216,7 @@ void Ctrl::ScrollView(int dx, int dy) { void Ctrl::SyncScroll() { GuiLock __; + Top *top = GetTop(); if(!top) return; Vector scroll = pick(top->scroll); @@ -599,6 +602,7 @@ Ctrl *Ctrl::GetTopRect(Rect& r, bool inframe, bool clip) r &= Rect(GetSize()); r.Offset(GetView().TopLeft()); } + Ctrl *parent = GetParent(); if(parent) { r.Offset(GetRect().TopLeft()); return parent->GetTopRect(r, InFrame(), clip); @@ -622,6 +626,7 @@ void Ctrl::Sync() { GuiLock __; LLOG("Sync " << Name()); + Ctrl *parent = GetParent(); if(top && IsOpen()) { LLOG("Sync UpdateWindow " << Name()); SyncScroll(); @@ -644,6 +649,7 @@ void Ctrl::Sync(const Rect& sr) void Ctrl::DrawCtrlWithParent(Draw& w, int x, int y) { GuiLock __; + Ctrl *parent = GetParent(); if(parent) { Rect r = GetRect(); Ctrl *top = parent->GetTopRect(r, inframe); @@ -676,6 +682,7 @@ void Ctrl::DrawCtrl(Draw& w, int x, int y) void Ctrl::SyncMoves() { GuiLock __; + Top *top = GetTop(); if(!top) return; for(int i = 0; i < top->move.GetCount(); i++) { diff --git a/uppsrc/CtrlCore/CtrlKbd.cpp b/uppsrc/CtrlCore/CtrlKbd.cpp index 24a448621..b812a302b 100644 --- a/uppsrc/CtrlCore/CtrlKbd.cpp +++ b/uppsrc/CtrlCore/CtrlKbd.cpp @@ -158,8 +158,8 @@ void Ctrl::DoKillFocus(Ptr pfocusCtrl, Ptr nfocusCtrl) LLOG("LostFocus: " << Name(pfocusCtrl)); pfocusCtrl->LostFocus(); } - if(pfocusCtrl && pfocusCtrl->parent && !pfocusCtrl->parent->destroying) - pfocusCtrl->parent->ChildLostFocus(); + if(pfocusCtrl && pfocusCtrl->GetParent() && !pfocusCtrl->GetParent()->destroying) + pfocusCtrl->GetParent()->ChildLostFocus(); SyncCaret(); } @@ -179,9 +179,9 @@ void Ctrl::DoSetFocus(Ptr pfocusCtrl, Ptr nfocusCtrl, bool activate) nfocusCtrl->GotFocus(); nfocusCtrl->StateH(FOCUS); } - if(focusCtrl == nfocusCtrl && nfocusCtrl && nfocusCtrl->parent && - !nfocusCtrl->parent->destroying) - nfocusCtrl->parent->ChildGotFocus(); + if(focusCtrl == nfocusCtrl && nfocusCtrl && nfocusCtrl->GetParent() && + !nfocusCtrl->GetParent()->destroying) + nfocusCtrl->GetParent()->ChildGotFocus(); SyncCaret(); } diff --git a/uppsrc/CtrlCore/CtrlMouse.cpp b/uppsrc/CtrlCore/CtrlMouse.cpp index 5bff62811..051e71fac 100644 --- a/uppsrc/CtrlCore/CtrlMouse.cpp +++ b/uppsrc/CtrlCore/CtrlMouse.cpp @@ -74,6 +74,7 @@ Image Ctrl::FrameMouseEventH(int event, Point p, int zdelta, dword keyflags) if(this_) LogMouseEvent("FRAME ", this, event, p, zdelta, keyflags); eventCtrl = this_; + Ctrl *parent = GetParent(); if(parent && this_) parent->ChildFrameMouseEvent(this, event, p, zdelta, keyflags); return this_ ? FrameMouseEvent(event, p, zdelta, keyflags) : Image(); @@ -93,6 +94,7 @@ Image Ctrl::MouseEvent0(int event, Point p, int zdelta, dword keyflags) bool pb = sPropagated; sPropagated = false; Image m = this_ ? MouseEvent(event, p, zdelta, keyflags) : Image(); + Ctrl *parent = this_ ? this_->GetParent() : NULL; if(event == MOUSEWHEEL && !sPropagated && this_ && parent) parent->ChildMouseEvent(this, event, p, zdelta, keyflags); sPropagated = pb; @@ -108,6 +110,7 @@ Image Ctrl::MouseEventH(int event, Point p, int zdelta, dword keyflags) return Image::Arrow(); if(this_) LogMouseEvent(NULL, this, event, p, zdelta, keyflags); + Ctrl *parent = this_ ? this_->GetParent() : NULL; if(this_ && parent && event != MOUSEWHEEL) parent->ChildMouseEvent(this, event, p, zdelta, keyflags); return MouseEvent0(event, p, zdelta, keyflags); @@ -115,6 +118,7 @@ Image Ctrl::MouseEventH(int event, Point p, int zdelta, dword keyflags) void Ctrl::MouseWheel(Point p, int zd, dword kf) { + Ctrl *parent = GetParent(); if(parent) { p += GetScreenView().TopLeft(); Rect r = parent->GetScreenView(); @@ -128,6 +132,7 @@ void Ctrl::MouseWheel(Point p, int zd, dword kf) void Ctrl::ChildFrameMouseEvent(Ctrl *child, int event, Point p, int zdelta, dword keyflags) { GuiLock __; + Ctrl *parent = GetParent(); if(parent) parent->ChildFrameMouseEvent(child, event, p, zdelta, keyflags); } @@ -135,6 +140,7 @@ void Ctrl::ChildFrameMouseEvent(Ctrl *child, int event, Point p, int zdelta, dwo void Ctrl::ChildMouseEvent(Ctrl *child, int event, Point p, int zdelta, dword keyflags) { GuiLock __; + Ctrl *parent = GetParent(); if(parent) parent->ChildMouseEvent(child, event, p, zdelta, keyflags); } diff --git a/uppsrc/CtrlCore/CtrlPos.cpp b/uppsrc/CtrlCore/CtrlPos.cpp index fed2a4026..49b6af21d 100644 --- a/uppsrc/CtrlCore/CtrlPos.cpp +++ b/uppsrc/CtrlCore/CtrlPos.cpp @@ -73,6 +73,7 @@ Rect Ctrl::GetScreenRect() const { GuiLock __; Rect r = GetRect(); + Ctrl *parent = GetParent(); if(parent) { Rect pr = inframe ? parent->GetScreenRect() : parent->GetScreenView(); r = r + pr.TopLeft(); @@ -92,6 +93,7 @@ Rect Ctrl::GetVisibleScreenRect() const { GuiLock __; Rect r = GetRect(); + Ctrl *parent = GetParent(); if(parent) { Rect pr = inframe ? parent->GetVisibleScreenRect() : parent->GetVisibleScreenView(); Rect pr1 = inframe ? parent->GetScreenRect() : parent->GetScreenView(); @@ -174,6 +176,20 @@ void Ctrl::SyncLayout(int force) RefreshFrame(); } +void Ctrl::RefreshParentLayout() +{ + Ctrl *parent = GetParent(); + if(parent) + parent->RefreshLayout(); +} + +void Ctrl::UpdateParentLayout() +{ + Ctrl *parent = GetParent(); + if(parent) + parent->UpdateLayout(); +} + int Ctrl::FindMoveCtrl(const VectorMap& m, Ctrl *x) { int q = m.Find(x); @@ -190,10 +206,11 @@ void Ctrl::SetPos0(LogPos p, bool _inframe) { GuiLock __; if(p == pos && inframe == _inframe) return; + Ctrl *parent = GetParent(); if(parent && !IsDHCtrl()) { if(!globalbackbuffer) { Rect from = GetRect().Size(); - Top *top = GetTopRect(from, true)->top; + Top *top = GetTopRect(from, true)->GetTop(); if(top) { LTIMING("SetPos0 MoveCtrl"); pos = p; @@ -229,6 +246,7 @@ void Ctrl::UpdateRect0(bool sync) { GuiLock __; LTIMING("UpdateRect0"); + Ctrl *parent = GetParent(); if(parent) rect = CalcRect(parent->GetRect(), parent->GetView()); else { @@ -249,12 +267,13 @@ void Ctrl::UpdateRect(bool sync) { GuiLock __; UpdateRect0(sync); - if(parent) RefreshFrame(); + if(GetParent()) RefreshFrame(); } Ctrl& Ctrl::SetPos(LogPos p, bool _inframe) { GuiLock __; + Ctrl *parent = GetParent(); if(p != pos || inframe != _inframe) { if(parent || !IsOpen()) SetPos0(p, _inframe); diff --git a/uppsrc/CtrlCore/TopWin32.cpp b/uppsrc/CtrlCore/TopWin32.cpp index f69a24c79..9a3a1a16b 100644 --- a/uppsrc/CtrlCore/TopWin32.cpp +++ b/uppsrc/CtrlCore/TopWin32.cpp @@ -273,6 +273,7 @@ void TopWindow::Open(Ctrl *owner) GuiLock __; LLOG("TopWindow::Open(Ctrl) -> " << UPP::Name(owner)); Open(owner ? owner->GetTopCtrl()->GetHWND() : NULL); + Top *top = GetTop(); if(IsOpen() && top) top->owner = owner; } diff --git a/uppsrc/CtrlCore/Win32Ctrl.h b/uppsrc/CtrlCore/Win32Ctrl.h index b429fe49d..ed90b60e1 100644 --- a/uppsrc/CtrlCore/Win32Ctrl.h +++ b/uppsrc/CtrlCore/Win32Ctrl.h @@ -66,7 +66,7 @@ public: virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam); virtual bool PreprocessMessage(MSG& msg); - HWND GetHWND() const { return parent ? NULL : top ? top->hwnd : NULL; } + HWND GetHWND() const { return GetParent() ? NULL : GetTop() ? GetTop()->hwnd : NULL; } HWND GetOwnerHWND() const; static Ctrl *CtrlFromHWND(HWND hwnd); diff --git a/uppsrc/CtrlCore/Win32Proc.cpp b/uppsrc/CtrlCore/Win32Proc.cpp index ea09c91f9..971508f2f 100644 --- a/uppsrc/CtrlCore/Win32Proc.cpp +++ b/uppsrc/CtrlCore/Win32Proc.cpp @@ -68,13 +68,14 @@ void Ctrl::DoCancelPreedit() { if(!focusCtrlWnd) return; - if(focusCtrlWnd->top) + Top *top = focusCtrl->GetTop(); + if(top) focusCtrl->HidePreedit(); - if(focusCtrlWnd->top && focusCtrlWnd->top->hwnd) { - HIMC himc = ImmGetContext(focusCtrlWnd->top->hwnd); + if(top && top->hwnd) { + HIMC himc = ImmGetContext(top->hwnd); if(himc && ImmGetOpenStatus(himc)) { ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); - ImmReleaseContext(focusCtrlWnd->top->hwnd, himc); + ImmReleaseContext(top->hwnd, himc); } } } diff --git a/uppsrc/CtrlCore/Win32Wnd.cpp b/uppsrc/CtrlCore/Win32Wnd.cpp index 3bd72d2b7..da1fb6bce 100644 --- a/uppsrc/CtrlCore/Win32Wnd.cpp +++ b/uppsrc/CtrlCore/Win32Wnd.cpp @@ -397,7 +397,7 @@ Vector Ctrl::GetTopCtrls() Vector v; VectorMap< HWND, Ptr >& w = Windows(); for(int i = 0; i < w.GetCount(); i++) - if(w.GetKey(i) && w[i] && !w[i]->parent) + if(w.GetKey(i) && w[i] && !w[i]->GetParent()) v.Add(w[i]); return v; } @@ -472,7 +472,8 @@ void Ctrl::Create(HWND parent, DWORD style, DWORD exstyle, bool savebits, int sh Rect r = GetRect(); AdjustWindowRectEx(r, style, FALSE, exstyle); isopen = true; - top = new Top; + Top *top = new Top; + SetTop(top); ASSERT(!parent || IsWindow(parent)); style &= ~WS_VISIBLE; dropshadow = false; @@ -501,6 +502,7 @@ void ReleaseUDropTarget(UDropTarget *dt); void Ctrl::WndFree() { GuiLock __; + Top *top = GetTop(); if(!top) return; RevokeDragDrop(GetHWND()); ReleaseUDropTarget(top->dndtgt); @@ -519,13 +521,13 @@ void Ctrl::WndFree() ::SetFocus(owner); } LLOG(LOG_END << "//Ctrl::WndFree() in " <hwnd) { HWND hwnd = top->hwnd; WndFree(); @@ -563,14 +565,16 @@ sWinMsg[] = { void Ctrl::NcCreate(HWND hwnd) { GuiLock __; - if(!parent) + Top *top = GetTop(); + if(top) top->hwnd = hwnd; } void Ctrl::NcDestroy() { GuiLock __; - if(!parent) + Top *top = GetTop(); + if(top) WndFree(); } @@ -947,7 +951,7 @@ void Ctrl::SetAlpha(byte alpha) { GuiLock __; HWND hwnd = GetHWND(); - if(!IsAlphaSupported() || parent || !top || !hwnd) + if(!IsAlphaSupported() || GetParent() || !top || !hwnd) return; if(alpha == 255) { SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) & ~0x80000); @@ -1234,6 +1238,7 @@ void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, boo popup = false; Ctrl *q = owner ? owner->GetTopCtrl() : GetActiveCtrl(); PopUpHWND(q ? q->GetHWND() : NULL, savebits, activate, dropshadow, topmost); + Top *top = GetTop(); if(top) top->owner = owner; } From 1b9382800a2d4a29b2775bd2709a2359eb70486d Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Thu, 14 Apr 2022 10:53:37 +0200 Subject: [PATCH 06/23] .autotest --- autotest/CtrlFrame/CtrlFrame.upp | 9 ++++++ autotest/CtrlFrame/main.cpp | 53 ++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 autotest/CtrlFrame/CtrlFrame.upp create mode 100644 autotest/CtrlFrame/main.cpp diff --git a/autotest/CtrlFrame/CtrlFrame.upp b/autotest/CtrlFrame/CtrlFrame.upp new file mode 100644 index 000000000..5872304d3 --- /dev/null +++ b/autotest/CtrlFrame/CtrlFrame.upp @@ -0,0 +1,9 @@ +uses + CtrlLib; + +file + main.cpp; + +mainconfig + "" = "GUI"; + diff --git a/autotest/CtrlFrame/main.cpp b/autotest/CtrlFrame/main.cpp new file mode 100644 index 000000000..c66d05e64 --- /dev/null +++ b/autotest/CtrlFrame/main.cpp @@ -0,0 +1,53 @@ +#include + +using namespace Upp; + +GUI_APP_MAIN +{ + NullFrameClass fr[50]; + for(int q = 0; q < 10000; q++) { + DLOG("=========="); + Ctrl h; + Vector h1; + int N = Random(40) + 1; + h1.Add(&NullFrame()); + for(int i = 0; i < N; i++) { + int pos = Random(h.GetFrameCount() + 1); + CtrlFrame& val = fr[Random(50)]; + h.InsertFrame(pos, val); + h1.Insert(pos, &val); + DDUMP(h.GetFrameCount()); + DDUMP(h1.GetCount()); + ASSERT(h1.GetCount() == h.GetFrameCount()); + for(int i = 0; i < h.GetFrameCount(); i++) + ASSERT(&h.GetFrame(i) == h1[i]); +#if 0 + DLOG("==========="); + DDUMP(pos); + DDUMP(val); + DDUMP(h.GetFrameCount()); + for(int i = 0; i < h.GetFrameCount(); i++) + DLOG(i << " " << h.GetFrame(i)); +#endif + } + while(h.GetFrameCount() > 1) { + int pos = Random(h.GetFrameCount()); + h.RemoveFrame(pos); + h1.Remove(pos); + DDUMP(h.GetFrameCount()); + DDUMP(h1.GetCount()); + ASSERT(h1.GetCount() == h.GetFrameCount()); + for(int i = 0; i < h.GetFrameCount(); i++) + ASSERT(&h.GetFrame(i) == h1[i]); +#if 0 + DLOG("==========="); + DDUMP(pos); + DDUMP(h.GetFrameCount()); + for(int i = 0; i < h.GetFrameCount(); i++) + DLOG(i << " " << h.GetFrame(i)); +#endif + } + } + + DLOG("================ OK"); +} From 2ebd16b1a1439fa36fa93ff45a038ed587af2562 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Mon, 18 Apr 2022 15:03:38 +0200 Subject: [PATCH 07/23] optimizing Ctrl::Top, LabelBase --- uppsrc/Core/Core.upp | 2 +- uppsrc/Core/Ptr.cpp | 21 ------------- uppsrc/Core/Ptr.h | 1 - uppsrc/CtrlCore/CtrlChild.cpp | 5 ++- uppsrc/CtrlCore/CtrlCore.h | 4 +-- uppsrc/CtrlCore/Win32Wnd.cpp | 3 +- uppsrc/CtrlLib/LabelBase.cpp | 30 +++++++++--------- uppsrc/CtrlLib/LabelBase.h | 59 ++++++++++++++++++++++------------- 8 files changed, 60 insertions(+), 65 deletions(-) diff --git a/uppsrc/Core/Core.upp b/uppsrc/Core/Core.upp index e02155dbc..b73ebc784 100644 --- a/uppsrc/Core/Core.upp +++ b/uppsrc/Core/Core.upp @@ -95,9 +95,9 @@ file Algo.h, CoAlgo.h, Sorted.h, - Sort.h, CoSort.h, Obsolete.h, + Sort.h, Vcont.h, BiCont.h, Other.h, diff --git a/uppsrc/Core/Ptr.cpp b/uppsrc/Core/Ptr.cpp index 2d6900d43..b812bec4c 100644 --- a/uppsrc/Core/Ptr.cpp +++ b/uppsrc/Core/Ptr.cpp @@ -2,27 +2,6 @@ namespace Upp { -/* Faster, but consuming more memory.... -PteBase::Prec *PteBase::PtrAdd() -{ - AtomicInc(prec->n); - return prec; -} - -void PteBase::PtrRelease(Prec *prec) -{ - if(prec && AtomicDec(prec->n) == 0) - delete prec; -} - -PteBase::PteBase() -{ - prec = new Prec; - prec->n = 1; - prec->ptr = this; -} -*/ - static StaticMutex sPteLock; PteBase::Prec *PteBase::PtrAdd() diff --git a/uppsrc/Core/Ptr.h b/uppsrc/Core/Ptr.h index 34ce16578..1c348e01e 100644 --- a/uppsrc/Core/Ptr.h +++ b/uppsrc/Core/Ptr.h @@ -11,7 +11,6 @@ protected: Prec *PtrAdd(); static void PtrRelease(Prec *prec); - static Prec *PtrAdd(const Uuid& uuid); PteBase(); ~PteBase(); diff --git a/uppsrc/CtrlCore/CtrlChild.cpp b/uppsrc/CtrlCore/CtrlChild.cpp index 2133d6bd7..a86af14ab 100644 --- a/uppsrc/CtrlCore/CtrlChild.cpp +++ b/uppsrc/CtrlCore/CtrlChild.cpp @@ -6,8 +6,11 @@ namespace Upp { void Ctrl::DeleteTop() { - if(top && utop) + if(top && utop) { delete utop; + utop = nullptr; + top = false; + } } void Ctrl::SetParent(Ctrl *parent) diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index 9ee1b864b..206f0217a 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -505,6 +505,8 @@ private: Frame frame; + LogPos pos;//8 + Rect16 rect; //8 union { Ctrl *uparent; @@ -514,8 +516,6 @@ private: Ctrl *prev_sibling = nullptr; Ctrl *next_sibling = nullptr; Ctrl *children = nullptr; - LogPos pos;//8 - Rect16 rect; //8 const char *info_ptr = nullptr; int16 caretx, carety, caretcx, caretcy;//8 diff --git a/uppsrc/CtrlCore/Win32Wnd.cpp b/uppsrc/CtrlCore/Win32Wnd.cpp index da1fb6bce..2c65b3d15 100644 --- a/uppsrc/CtrlCore/Win32Wnd.cpp +++ b/uppsrc/CtrlCore/Win32Wnd.cpp @@ -503,11 +503,10 @@ void Ctrl::WndFree() { GuiLock __; Top *top = GetTop(); - if(!top) return; RevokeDragDrop(GetHWND()); + if(!top) return; ReleaseUDropTarget(top->dndtgt); isopen = false; - if(!top) return; HWND owner = GetWindow(top->hwnd, GW_OWNER);// CXL 31.10.2003 z DoRemove bool focus = ::GetFocus() == top->hwnd; LLOG("Ctrl::WndDestroy owner " << (void *)owner diff --git a/uppsrc/CtrlLib/LabelBase.cpp b/uppsrc/CtrlLib/LabelBase.cpp index cceae5cdb..80c8f839a 100644 --- a/uppsrc/CtrlLib/LabelBase.cpp +++ b/uppsrc/CtrlLib/LabelBase.cpp @@ -115,19 +115,6 @@ int ChooseAccessKey(const char *text, dword used) return 0; } -DrawLabel::DrawLabel() -{ - push = focus = disabled = false; - lspc = rspc = 0; - limg_never_hide = false; - rimg_never_hide = false; - ink = disabledink = Null; - align = valign = ALIGN_CENTER; - accesskey = 0; - font = StdFont(); - nowrap = false; -} - Size DrawLabel::GetSize(int txtcx) const { return GetSize(txtcx, limg.GetSize(), lspc, rimg.GetSize(), rspc); @@ -288,7 +275,17 @@ Size DrawLabel::Paint(Draw& w, int x, int y, int cx, int cy, bool vak) const void LabelBase::LabelUpdate() {} +DrawLabel LabelBase::Make() const +{ + DrawLabel lx; + (DrawLabelBasic&)lx = lbl; + if(ext) + (DrawLabelExt&)lx = *ext; + return lx; +} + LabelBase& LabelBase::SetLeftImage(const Image& img, int spc, bool never_hide) { + DrawLabelExt& lbl = Ext(); lbl.limg = img; lbl.lspc = spc; lbl.limg_never_hide = never_hide; @@ -297,6 +294,7 @@ LabelBase& LabelBase::SetLeftImage(const Image& img, int spc, bool never_hide) { } LabelBase& LabelBase::SetRightImage(const Image& img, int spc, bool never_hide) { + DrawLabelExt& lbl = Ext(); lbl.rimg = img; lbl.rspc = spc; lbl.rimg_never_hide = never_hide; @@ -305,7 +303,7 @@ LabelBase& LabelBase::SetRightImage(const Image& img, int spc, bool never_hide) } LabelBase& LabelBase::SetPaintRect(const PaintRect& paintrect) { - lbl.paintrect = paintrect; + Ext().paintrect = paintrect; LabelUpdate(); return *this; } @@ -361,7 +359,7 @@ LabelBase& LabelBase::SetVAlign(int valign) { Size LabelBase::PaintLabel(Ctrl *ctrl, Draw& w, const Rect& r, bool disabled, bool push, bool focus, bool vak) { - DrawLabel lbl1 = lbl; + DrawLabel lbl1 = Make(); lbl1.disabled = disabled; lbl1.push = push; lbl1.focus = focus; @@ -386,7 +384,7 @@ Size LabelBase::PaintLabel(Draw& w, int x, int y, int cx, int cy, bool disabled, Size LabelBase::GetLabelSize() const { - return lbl.GetSize(); + return Make().GetSize(); } void LinkToolTipIn__(); diff --git a/uppsrc/CtrlLib/LabelBase.h b/uppsrc/CtrlLib/LabelBase.h index 2c14d1cdd..bb14a7481 100644 --- a/uppsrc/CtrlLib/LabelBase.h +++ b/uppsrc/CtrlLib/LabelBase.h @@ -28,29 +28,41 @@ void DrawVertDrop(Draw& w, int x, int y, int cy); Point GetDragScroll(Ctrl *ctrl, Point p, Size max); Point GetDragScroll(Ctrl *ctrl, Point p, int max = 16); -struct DrawLabel { - PaintRect paintrect; +struct DrawLabelBasic { String text; - Image limg; - Image rimg; Font font; - Color lcolor; - Color ink, disabledink; - Color rcolor; - - int rspc; - int lspc; + Color ink; + Color disabledink; int accesskey; - int align:4, valign:4; - + int align:4; + int valign:4; + bool nowrap:1; - bool push:1; - bool focus:1; - bool disabled:1; - bool limg_never_hide:1; - bool rimg_never_hide:1; + + DrawLabelBasic() { align = valign = ALIGN_CENTER; nowrap = false; accesskey = 0; font = StdFont(); } +}; + +struct DrawLabelExt { + PaintRect paintrect; + + Image limg; + Image rimg; + + Color lcolor; + int lspc = 0; + Color rcolor; + int rspc = 0; + + bool limg_never_hide = false; + bool rimg_never_hide = false; +}; + +struct DrawLabel : DrawLabelBasic, DrawLabelExt { + bool push = false; + bool focus = false; + bool disabled = false; Size GetSize(int txtcx, Size sz1, int lspc, Size sz2, int rspc) const; Size GetSize(int txtcx = INT_MAX) const; @@ -58,8 +70,6 @@ struct DrawLabel { Size Paint(Ctrl *ctrl, Draw& w, int x, int y, int cx, int cy, bool visibleaccesskey = true) const; Size Paint(Draw& w, const Rect& r, bool visibleaccesskey = true) const; Size Paint(Draw& w, int x, int y, int cx, int cy, bool visibleaccesskey = true) const; - - DrawLabel(); }; Image DisabledImage(const Image& img, bool disabled = true); @@ -69,7 +79,11 @@ class LabelBase { protected: virtual void LabelUpdate(); - DrawLabel lbl; + DrawLabelBasic lbl; + One ext; + + DrawLabelExt& Ext() { if(!ext) ext.Create() ; return *ext; } + DrawLabel Make() const; public: LabelBase& SetLeftImage(const Image& bmp1, int spc = 0, bool never_hide = false); @@ -93,7 +107,7 @@ public: int GetAlign() const { return lbl.align; } int GetVAlign() const { return lbl.valign; } - PaintRect GetPaintRect() const { return lbl.paintrect; } + PaintRect GetPaintRect() const { return ext ? ext->paintrect : PaintRect(); } String GetText() const { return lbl.text; } Font GetFont() const { return lbl.font; } Color GetInk() const { return lbl.ink; } @@ -107,6 +121,9 @@ public: Size PaintLabel(Draw& w, int x, int y, int cx, int cy, bool disabled = false, bool push = false, bool focus = false, bool vak = true); Size GetLabelSize() const; + + LabelBase(const LabelBase& src) { lbl = src.lbl; if(src.ext) ext = clone(src.ext); } + LabelBase() {} virtual ~LabelBase(); }; From bd695d2fb1686353f0314b06459f2b3088f110bd Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Tue, 19 Apr 2022 18:04:42 +0200 Subject: [PATCH 08/23] CtrlCore, CtrlLib: caret handling refactored --- uppsrc/CtrlCore/Ctrl.cpp | 13 +------------ uppsrc/CtrlCore/CtrlCore.h | 8 ++------ uppsrc/CtrlCore/CtrlKbd.cpp | 3 +-- uppsrc/CtrlCore/Win32Wnd.cpp | 19 +----------------- uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp | 27 -------------------------- uppsrc/CtrlLib/DocEdit.cpp | 7 ++++++- uppsrc/CtrlLib/EditCtrl.h | 5 +++-- uppsrc/CtrlLib/EditField.cpp | 11 +++-------- uppsrc/CtrlLib/LabelBase.cpp | 3 ++- uppsrc/CtrlLib/LineEdit.cpp | 12 ++++++++---- uppsrc/CtrlLib/TextEdit.h | 4 ++++ uppsrc/RichEdit/Editor.cpp | 11 ++++++++--- uppsrc/RichEdit/RichEdit.h | 2 ++ 13 files changed, 41 insertions(+), 84 deletions(-) diff --git a/uppsrc/CtrlCore/Ctrl.cpp b/uppsrc/CtrlCore/Ctrl.cpp index a751fc482..0944e0bc7 100644 --- a/uppsrc/CtrlCore/Ctrl.cpp +++ b/uppsrc/CtrlCore/Ctrl.cpp @@ -386,19 +386,9 @@ bool Ctrl::IsModifiedDeep() const return false; } -void Ctrl::SetCaret(const Rect& r) -{ - SetCaret(r.left, r.top, r.GetWidth(), r.GetHeight()); -} - Rect Ctrl::GetCaret() const { - return RectC(caretx, carety, caretcx, caretcy); -} - -void Ctrl::KillCaret() -{ - SetCaret(0, 0, 0, 0); + return Null; } void Ctrl::SetInfoPart(int i, const char *txt) @@ -647,7 +637,6 @@ Ctrl::Ctrl() { backpaint = IsCompositedGui() ? FULLBACKPAINT : TRANSPARENTBACKPAINT; inframe = false; ignoremouse = transparent = false; - caretcx = caretcy = caretx = carety = 0; pos.x = PosLeft(0, 0); pos.y = PosTop(0, 0); rect = Rect(0, 0, 0, 0); diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index 206f0217a..bf7d821ce 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -517,7 +517,6 @@ private: Ctrl *next_sibling = nullptr; Ctrl *children = nullptr; const char *info_ptr = nullptr; - int16 caretx, carety, caretcx, caretcy;//8 byte overpaint; @@ -931,6 +930,8 @@ public: virtual Point GetPreedit(); virtual Font GetPreeditFont(); + virtual Rect GetCaret() const; + virtual void DragAndDrop(Point p, PasteClip& d); virtual void FrameDragAndDrop(Point p, PasteClip& d); virtual void DragRepeat(Point p); @@ -1173,11 +1174,6 @@ public: void CancelModeDeep(); - void SetCaret(int x, int y, int cx, int cy); - void SetCaret(const Rect& r); - Rect GetCaret() const; - void KillCaret(); - static void CancelPreedit(); void CancelMyPreedit() { if(HasFocus()) CancelPreedit(); } diff --git a/uppsrc/CtrlCore/CtrlKbd.cpp b/uppsrc/CtrlCore/CtrlKbd.cpp index b812a302b..c7c28b9d9 100644 --- a/uppsrc/CtrlCore/CtrlKbd.cpp +++ b/uppsrc/CtrlCore/CtrlKbd.cpp @@ -344,8 +344,7 @@ void Ctrl::RefreshCaret() { GuiLock __; if(caretCtrl) - caretCtrl->Refresh(caretCtrl->caretx, caretCtrl->carety, - caretCtrl->caretcx, caretCtrl->caretcy); + caretCtrl->Refresh(caretCtrl->GetCaret()); } Ctrl *Ctrl::GetActiveWindow() diff --git a/uppsrc/CtrlCore/Win32Wnd.cpp b/uppsrc/CtrlCore/Win32Wnd.cpp index 2c65b3d15..07bd5d45a 100644 --- a/uppsrc/CtrlCore/Win32Wnd.cpp +++ b/uppsrc/CtrlCore/Win32Wnd.cpp @@ -883,24 +883,7 @@ void Ctrl::PaintCaret(SystemDraw& w) GuiLock __; LLOG("PaintCaret " << Name() << ", caretCtrl: " << caretCtrl << ", WndCaretVisible: " << WndCaretVisible); if(this == caretCtrl && WndCaretVisible) - w.DrawRect(caretx, carety, caretcx, caretcy, InvertColor); -} - -void Ctrl::SetCaret(int x, int y, int cx, int cy) -{ - GuiLock __; - LLOG("SetCaret " << Name() << " " << RectC(x, y, cx, cy)); - if(this == caretCtrl) - RefreshCaret(); - caretx = x; - carety = y; - caretcx = cx; - caretcy = cy; - if(this == caretCtrl) { - WndCaretTime = msecs(); - RefreshCaret(); - AnimateCaret(); - } + w.DrawRect(GetCaret(), InvertColor); } void Ctrl::SyncCaret() { diff --git a/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp b/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp index 037a33177..3e6b851f9 100644 --- a/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp +++ b/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp @@ -1978,33 +1978,6 @@ pointer to it.&] its descendants.&] [s3;%- &] [s4;%- &] -[s5;:Ctrl`:`:SetCaret`(int`,int`,int`,int`):%- [@(0.0.255) void]_[* SetCaret]([@(0.0.255) i -nt]_[*@3 x], [@(0.0.255) int]_[*@3 y], [@(0.0.255) int]_[*@3 cx], [@(0.0.255) int]_[*@3 cy])&] -[s2;b17;a17; Place caret rectangle block at given position in view -area. Caret rectangle is full flashing box and usually indicates -place where text is to entered. Ctrl can have just one caret. -Only Ctrl with focus has its caret displayed (also means that -you do not need to remove caret when Ctrl goes out of focus).&] -[s7;i1120;a17; [%-*C@3 x]-|X position.&] -[s7;i1120;a17; [%-*C@3 y]-|Y position.&] -[s7;i1120;a17; [%-*C@3 cx]-|Horizontal size.&] -[s7;i1120;a17; [%-*C@3 cy]-|Vertical size.&] -[s3;%- &] -[s4;%- &] -[s5;:Ctrl`:`:SetCaret`(const `:`:Rect`&`):%- [@(0.0.255) void]_[* SetCaret]([@(0.0.255) con -st]_[_^`:`:Rect^ Rect][@(0.0.255) `&]_[*@3 r])&] -[s2;b17;a17; Place caret rectangle block at given position in view -area. Caret rectangle is full flashing box and usually indicates -place where text is to entered. Ctrl can have just one caret. -Only Ctrl with focus has its caret displayed (also means that -you do not need to remove caret when Ctrl goes out of focus).&] -[s7;i1120;a17; [%-*C@3 r]-|Caret block rectangle.&] -[s3;%- &] -[s4;%- &] -[s5;:Ctrl`:`:KillCaret`(`):%- [@(0.0.255) void]_[* KillCaret]()&] -[s2;b17;a17; Removes caret from Ctrl.&] -[s3;%- &] -[s4;%- &] [s5;:Upp`:`:Ctrl`:`:CancelPreedit`(`):%- [@(0.0.255) void]_[* CancelPreedit]()&] [s2; Terminates any input method composition in progress, if possible. Text input widgets typically call this on status change, like diff --git a/uppsrc/CtrlLib/DocEdit.cpp b/uppsrc/CtrlLib/DocEdit.cpp index fac2d3a8e..06f607379 100644 --- a/uppsrc/CtrlLib/DocEdit.cpp +++ b/uppsrc/CtrlLib/DocEdit.cpp @@ -222,6 +222,11 @@ int DocEdit::GetCursorPos(Point p) { return GetLength32(); } +Rect DocEdit::GetCaret() const +{ + return caret; +} + void DocEdit::PlaceCaret(bool scroll) { Point cr = GetCaret((int)cursor); int fy = font.Info().GetLineHeight(); @@ -231,7 +236,7 @@ void DocEdit::PlaceCaret(bool scroll) { else sb.ScrollInto(cr.y, fy + 2); } - SetCaret(cr.x + 1, cr.y - sb, 1, fy); + caret = RectC(cr.x + 1, cr.y - sb, 1, fy); WhenSel(); } diff --git a/uppsrc/CtrlLib/EditCtrl.h b/uppsrc/CtrlLib/EditCtrl.h index f58d0deb2..e44a647a2 100644 --- a/uppsrc/CtrlLib/EditCtrl.h +++ b/uppsrc/CtrlLib/EditCtrl.h @@ -63,6 +63,7 @@ public: virtual void CancelMode(); virtual String GetSelectionData(const String& fmt) const; virtual void State(int); + virtual Rect GetCaret() const; public: struct Style : ChStyle