abandoning this path...

This commit is contained in:
Mirek Fidler 2026-05-30 11:21:15 +02:00
parent 453784adab
commit 1ed630137d
9 changed files with 215 additions and 58 deletions

View file

@ -79,7 +79,7 @@ void Ctrl::Layout() {}
void Ctrl::PostInput()
{
GuiLock __;
Ctrl *parent = GetParent();
Ctrl *parent = GetParentI();
if(parent)
parent->PostInput();
}
@ -288,7 +288,7 @@ bool Ctrl::IsOpen() const
{
GuiLock __;
const Ctrl *q = GetTopCtrl();
return q->isopen && q->IsWndOpen();
return q->isopen && q->IsWndOpen() || virtual_popups && virtual_popup && GetOwner();
}
void Ctrl::Show(bool ashow) {
@ -559,6 +559,7 @@ Ctrl::Ctrl() {
top = false;
uparent = nullptr;
megarect = false;
virtual_popup = false;
}
void KillTimeCallbacks(void *id, void *idlim);
@ -574,7 +575,8 @@ void Ctrl::DoRemove() {
mouseCtrl = NULL;
LLOG("DoRemove " << Name() << " focusCtrl: " << UPP::Name(focusCtrl));
GuiPlatformRemove();
Ctrl *parent = GetParent();
virtual_popup = false;
Ctrl *parent = GetParentI();
if(HasFocusDeep()) {
LLOG("DoRemove - HasFocusDeep");
if(destroying) {
@ -618,27 +620,45 @@ void Ctrl::DoRemove() {
LLOG("//DoRemove " << Name() << " focusCtrl: " << UPP::Name(focusCtrl));
}
void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost)
{
if(virtual_popups) {
virtual_popup = true;
owner->AddChild(this);
DLOG("=====");
DDUMP(GetScreenRect());
DDUMP(GetRect());
DDUMP(Name(GetOwner()));
}
else
PopUp0(owner, savebits, activate, dropshadow, topmost);
}
void Ctrl::Close()
{
GuiLock __;
Ctrl *q = GetTopCtrl();
if(!q->top) return;
DoRemove();
if(GetParent()) return;
DoRemove();
StateH(CLOSE);
USRLOG(" CLOSE " + Desc(this));
WndDestroy();
if(virtual_popup)
Remove();
else
WndDestroy();
visible = true;
popup = false;
virtual_popup = false;
}
Ctrl::~Ctrl() {
GuiLock __;
LLOG("Ctrl::~Ctrl");
destroying = true;
while(GetFirstChild())
RemoveChild(GetFirstChild());
Ctrl *parent = GetParent();
while(GetFirstChildI())
RemoveChild(GetFirstChildI());
Ctrl *parent = GetParentI();
if(parent)
parent->RemoveChild(this);
Close();
@ -858,6 +878,11 @@ String Ctrl::GetAppName()
return appname;
}
void Ctrl::VirtualPopups(bool b)
{
virtual_popups = b;
}
static bool _ClickFocus;
bool Ctrl::ClickFocus() { return _ClickFocus; }
void Ctrl::ClickFocus(bool cf) { _ClickFocus = cf; }

View file

@ -34,7 +34,7 @@ void Ctrl::AddChild(Ctrl *q, Ctrl *p)
LLOG("Add " << UPP::Name(q) << " to: " << Name());
if(p == q) return;
bool updaterect = true;
Ctrl *qparent = q->GetParent();
Ctrl *qparent = q->GetParentI();
if(qparent) {
ASSERT(!q->inframe);
if(qparent == this) {
@ -85,9 +85,9 @@ void Ctrl::RemoveChild0(Ctrl *q)
{
GuiLock __;
ChildRemoved(q);
if(!q->GetParent()) return; // ChildRemoved can remove q
if(!q->GetParentI()) return; // ChildRemoved can remove q
q->DoRemove();
if(!q->GetParent()) return; // DoRemove can remove q
if(!q->GetParentI()) return; // DoRemove can remove q
q->SetParent(NULL);
if(q == children) {
@ -104,7 +104,7 @@ void Ctrl::RemoveChild0(Ctrl *q)
void Ctrl::RemoveChild(Ctrl *q)
{
GuiLock __;
if(q->GetParent() != this) return;
if(q->GetParentI() != this) return;
q->RefreshFrame();
RemoveChild0(q);
q->ParentChange();
@ -115,11 +115,53 @@ void Ctrl::RemoveChild(Ctrl *q)
void Ctrl::Remove()
{
GuiLock __;
Ctrl *parent = GetParent();
Ctrl *parent = GetParentI();
if(parent)
parent->RemoveChild(this);
}
Ctrl *Ctrl::GetParentI() const
{ // virtual popups included
return top ? NULL : uparent;
}
Ctrl *Ctrl::GetFirstChildI() const
{// virtual popups included
return children ? children : nullptr;
}
Ctrl *Ctrl::GetParent() const
{
if(virtual_popup)
return nullptr;
return top ? NULL : uparent;
}
Ctrl *Ctrl::GetLastChild() const
{
if(!children)
return nullptr;
Ctrl *p = children->prev_sibling;
for(;;) {
if(!p->virtual_popup)
return p;
if(p == children)
return nullptr;
p = p->prev_sibling;
}
}
Ctrl *Ctrl::GetFirstChild() const
{
return children && !children->virtual_popup ? children : nullptr;
}
Ctrl *Ctrl::GetPrev() const
{
Ctrl *parent = GetParent();
return parent && prev_sibling != parent->GetLastChild() && !prev_sibling->virtual_popup ? prev_sibling : nullptr;
}
int Ctrl::GetChildIndex(const Ctrl *child) const
{
GuiLock __;
@ -135,7 +177,7 @@ int Ctrl::GetChildCount() const
{
GuiLock __;
int n = 0;
for (Ctrl *c = GetFirstChild(); c; c = c->GetNext())
for (Ctrl *c = GetFirstChild(); c && !c->virtual_popup; c = c->GetNext())
n++;
return n;
}
@ -187,12 +229,14 @@ Ctrl * Ctrl::GetViewIndexChild(int ii) const
bool Ctrl::HasChild(Ctrl *q) const
{
GuiLock __;
return q && q->GetParent() == this;
return q && !q->virtual_popup && q->GetParent() == this;
}
bool Ctrl::HasChildDeep(Ctrl *q) const
{
GuiLock __;
if(q && q->virtual_popup)
return false;
while(q && q->IsChild()) {
Ctrl *qparent = q->GetParent();
if(qparent == this) return true;
@ -286,6 +330,14 @@ Ctrl *Ctrl::GetTopCtrl()
}
const Ctrl *Ctrl::GetTopCtrl() const { return const_cast<Ctrl *>(this)->GetTopCtrl(); }
Ctrl * Ctrl::GetOwner()
{
if(virtual_popups)
return top ? NULL : uparent->GetTopCtrl();
return GetOwner0();
}
const Ctrl *Ctrl::GetOwner() const { return const_cast<Ctrl *>(this)->GetOwner(); }
Ctrl *Ctrl::GetTopCtrlOwner() { return GetTopCtrl()->GetOwner(); }
const Ctrl *Ctrl::GetTopCtrlOwner() const { return GetTopCtrl()->GetOwner(); }
@ -328,4 +380,20 @@ const TopWindow *Ctrl::GetMainWindow() const
return const_cast<Ctrl *>(this)->GetMainWindow();
}
Vector<Ctrl *> Ctrl::GetTopCtrls()
{
Vector<Ctrl *> v;
for(Ctrl *q : GetTopCtrls0()) {
v.Add(q);
if(q->children) {
Ctrl *w = q->children->prev_sibling;
while(w != q->children && w->virtual_popup) {
v.Add(w);
w = w->prev_sibling;
}
}
}
return v;
}
}

View file

@ -556,6 +556,7 @@ private:
bool isopen:1;
bool popup:1;
bool popupgrab:1;
bool virtual_popup:1;
byte backpaint:2;//2
bool akv:1;
@ -568,6 +569,8 @@ private:
static bool was_fullrefresh; // indicates that some widgets might have fullrefresh true
static bool virtual_popups; // popups are emulated
static Ptr<Ctrl> eventCtrl;
static Ptr<Ctrl> mouseCtrl;
static Point mousepos;
@ -697,6 +700,7 @@ private:
void UpdateArea0(SystemDraw& draw, const Rect& clip, int backpaint);
void UpdateArea(SystemDraw& draw, const Rect& clip);
Ctrl *GetTopRect(Rect& r, bool inframe, bool clip = true);
Ctrl *GetTopRectI(Rect& r, bool inframe, bool clip = true);
void DoSync(Ctrl *q, Rect r, bool inframe);
Rect GetPreeditScreenRect();
@ -872,6 +876,15 @@ protected:
template <class T>
T GetAttr(int ii) const { void *p = GetVoidPtrAttr(ii); return p ? *(T *)p : T(); }
Ctrl *GetParentI() const;
Ctrl *GetFirstChildI() const;
Ctrl *GetNextI() const;
void PopUp0(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost);
Ctrl *GetOwner0();
static Vector<Ctrl *> GetTopCtrls0();
public:
enum StateReason {
FOCUS = 10,
@ -1073,11 +1086,11 @@ public:
void AddChild(Ctrl *child, Ctrl *insafter);
void AddChildBefore(Ctrl *child, Ctrl *insbefore);
void RemoveChild(Ctrl *child);
Ctrl *GetParent() const { return top ? NULL : uparent; }
Ctrl *GetLastChild() const { return children ? children->prev_sibling : nullptr; }
Ctrl *GetFirstChild() const { return children; }
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; }
Ctrl *GetParent() const;
Ctrl *GetLastChild() const;
Ctrl *GetFirstChild() const;
Ctrl *GetPrev() const;
Ctrl *GetNext() const;
int GetChildIndex(const Ctrl *child) const;
Ctrl *GetIndexChild(int i) const;
int GetChildCount() const;
@ -1437,6 +1450,8 @@ public:
static void GlobalBackPaint(bool b = true);
static void GlobalBackPaintHint();
static void GlobalBackBuffer(bool b = true);
static void VirtualPopups(bool b = true);
static void ReSkin();
static void PostReSkin();
@ -1875,6 +1890,20 @@ T *Ctrl::GetAscendant() const
return NULL;
}
inline
Ctrl * Ctrl::GetNextI() const
{ // this goes through virtual popups too
Ctrl *parent = GetParent();
return parent && next_sibling != parent->children ? next_sibling : nullptr;
}
inline
Ctrl * Ctrl::GetNext() const
{
Ctrl *parent = GetParent();
return parent && next_sibling != parent->children && !next_sibling->virtual_popup ? next_sibling : nullptr;
}
#ifdef HAS_TopFrameDraw
class ViewDraw : public TopFrameDraw {

View file

@ -9,6 +9,7 @@ bool Ctrl::globalbackpaint;
bool Ctrl::globalbackbuffer;
bool Ctrl::was_fullrefresh;
bool Ctrl::virtual_popups;
static void sCheckGuiLock()
{
@ -25,7 +26,7 @@ void Ctrl::RefreshFrame(const Rect& r) {
if(GuiPlatformRefreshFrameSpecial(r))
return;
if(!top && !IsDHCtrl()) {
Ctrl *parent = GetParent();
Ctrl *parent = GetParentI();
if(InFrame())
parent->RefreshFrame(r + GetRect().TopLeft());
else
@ -121,12 +122,12 @@ Rect Ctrl::GetClippedView()
GuiLock __;
Rect sv = GetScreenView();
Rect view = sv;
Ctrl *q = GetParent();
Ctrl *q = GetParentI();
Ctrl *w = this;
while(q) {
view &= w->InFrame() ? q->GetScreenRect() : q->GetScreenView();
w = q;
q = q->GetParent();
q = q->GetParentI();
}
return view - GetScreenRect().TopLeft();
}
@ -135,10 +136,10 @@ void Ctrl::ScrollCtrl(Top *top, Ctrl *q, const Rect& r, Rect cr, int dx, int dy)
{
if(top && r.Intersects(cr)) { // Uno: Contains -> Intersetcs
Rect to = cr;
GetTopRect(to, false);
GetTopRectI(to, false);
if(r.Intersects(cr.Offseted(-dx, -dy))) { // Uno's suggestion 06/11/26 Contains -> Intersetcs
Rect from = cr.Offseted(-dx, -dy);
GetTopRect(from, false);
GetTopRectI(from, false);
MoveCtrl *m = FindMoveCtrlPtr(top->move, q);
if(m && m->from == from && m->to == to) {
LLOG("ScrollView Matched " << from << " -> " << to);
@ -150,7 +151,7 @@ void Ctrl::ScrollCtrl(Top *top, Ctrl *q, const Rect& r, Rect cr, int dx, int dy)
if(r.Intersects(cr.Offseted(dx, dy))) { // Uno's suggestion 06/11/26 Contains -> Intersetcs
Rect from = to;
to = cr.Offseted(dx, dy);
GetTopRect(to, false);
GetTopRectI(to, false);
MoveCtrl& m = top->scroll_move.Add(q);
m.from = from;
m.to = to;
@ -186,7 +187,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->GetParent(); w = w->GetParent())
for(w = this; w->GetParentI(); w = w->GetParentI())
if(w->InFrame()) {
Refresh();
return;
@ -203,8 +204,8 @@ void Ctrl::ScrollView(const Rect& _r, int dx, int dy)
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext())
if(q->InView())
ScrollCtrl(top, q, r, q->GetRect(), dx, dy);
if(GetParent())
for(Ctrl *q = GetParent()->GetFirstChild(); q; q = q->GetNext())
if(GetParentI())
for(Ctrl *q = GetParent()->GetFirstChildI(); q; q = q->GetNextI())
if(q->InView() && q != this)
ScrollCtrl(top, q, r, q->GetScreenRect() - GetScreenView().TopLeft(), dx, dy);
}
@ -280,7 +281,7 @@ void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip) {
GuiLock __;
LEVELCHECK(w, this);
LTIMING("CtrlPaint");
LLOG("=== CtrlPaint " << UPP::Name(this) << ", clip: " << clip << ", rect: " << GetRect() << ", view: " << GetView());
DLOG("=== CtrlPaint " << UPP::Name(this) << ", clip: " << clip << ", rect: " << GetRect() << ", view: " << GetView());
Rect rect = GetRect().GetSize();
Rect orect = rect.Inflated(overpaint);
if(!IsShown() || orect.IsEmpty() || clip.IsEmpty() || !clip.Intersects(orect))
@ -297,20 +298,25 @@ void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip) {
bool hasviewctrls = false;
bool viewexcluded = false;
bool hiddenbychild = false;
for(Ctrl& q : *this)
if(q.IsShown()) {
if(q.GetRect().Contains(orect) && !q.IsTransparent())
DLOG("=== PAINT");
for(Ctrl *q = GetFirstChildI(); q; q = q->GetNextI())
DLOG(UPP::Name(q) << " shown: " << IsShown() << " view: " << q->InView() << " popup: " << q->virtual_popup << " parent: " << UPP::Name(this));
for(Ctrl *q = GetFirstChildI(); q; q = q->GetNextI())
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
@ -339,15 +345,15 @@ void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip) {
if(hasviewctrls && !view.IsEmpty()) {
Rect cl = clip & view;
w.Clip(cl);
for(Ctrl& q : *this)
if(q.IsShown() && q.InView()) {
LEVELCHECK(w, &q);
Rect qr = q.GetRect();
for(Ctrl *q = GetFirstChildI(); q; q = q->GetNextI())
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();
}
}
@ -402,9 +408,9 @@ void Ctrl::ExcludeDHCtrls(SystemDraw& w, const Rect& r, const Rect& clip)
return;
}
Rect cview = clip & (GetView() + off);
for(Ctrl& q : *this)
q.ExcludeDHCtrls(w, q.GetRect() + (q.InView() ? viewpos : off),
q.InView() ? cview : clip);
for(Ctrl *q = GetFirstChildI(); q; q = q->GetNextI())
q->ExcludeDHCtrls(w, q->GetRect() + (q->InView() ? viewpos : off),
q->InView() ? cview : clip);
}
void Ctrl::UpdateArea0(SystemDraw& draw, const Rect& clip, int backpaint)
@ -460,7 +466,7 @@ void Ctrl::RemoveFullRefresh()
{
GuiLock __;
fullrefresh = false;
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext())
for(Ctrl *q = GetFirstChildI(); q; q = q->GetNextI())
q->RemoveFullRefresh();
}
@ -490,12 +496,28 @@ Ctrl *Ctrl::GetTopRect(Rect& r, bool inframe, bool clip)
return this;
}
Ctrl *Ctrl::GetTopRectI(Rect& r, bool inframe, bool clip)
{ // because of virtual popups
GuiLock __;
if(!inframe) {
if(clip)
r &= Rect(GetSize());
r.Offset(GetView().TopLeft());
}
Ctrl *parent = GetParentI();
if(parent) {
r.Offset(GetRect().TopLeft());
return parent->GetTopRectI(r, InFrame(), clip);
}
return this;
}
void Ctrl::DoSync(Ctrl *q, Rect r, bool inframe)
{
GuiLock __;
ASSERT(q);
LLOG("DoSync " << UPP::Name(q) << " " << r);
Ctrl *top = q->GetTopRect(r, inframe);
Ctrl *top = q->GetTopRectI(r, inframe);
if(top && top->IsOpen()) {
top->SyncScroll();
top->WndUpdate(r);
@ -506,7 +528,7 @@ void Ctrl::Sync()
{
GuiLock __;
LLOG("Sync " << Name());
Ctrl *parent = GetParent();
Ctrl *parent = GetParentI();
if(top && IsOpen()) {
LLOG("Sync UpdateWindow " << Name());
SyncScroll();
@ -529,10 +551,10 @@ void Ctrl::Sync(const Rect& sr)
void Ctrl::DrawCtrlWithParent(Draw& w, int x, int y)
{
GuiLock __;
Ctrl *parent = GetParent();
Ctrl *parent = GetParentI();
if(parent) {
Rect r = GetRect();
Ctrl *top = parent->GetTopRect(r, inframe);
Ctrl *top = parent->GetTopRectI(r, inframe);
w.Clip(x, y, r.Width(), r.Height());
w.Offset(x - r.left, y - r.top);
SystemDraw *ws = dynamic_cast<SystemDraw *>(&w);

View file

@ -83,7 +83,7 @@ Rect Ctrl::GetScreenRect() const
{
GuiLock __;
Rect r = GetRect();
Ctrl *parent = GetParent();
Ctrl *parent = GetParentI();
if(parent) {
Rect pr = inframe ? parent->GetScreenRect() : parent->GetScreenView();
r = r + pr.TopLeft();
@ -103,7 +103,7 @@ Rect Ctrl::GetVisibleScreenRect() const
{
GuiLock __;
Rect r = GetRect();
Ctrl *parent = GetParent();
Ctrl *parent = GetParentI();
if(parent) {
Rect pr = inframe ? parent->GetVisibleScreenRect() : parent->GetVisibleScreenView();
Rect pr1 = inframe ? parent->GetScreenRect() : parent->GetScreenView();
@ -227,7 +227,7 @@ void Ctrl::SetPos0(LogPos p, bool _inframe)
inframe = _inframe;
Rect to = GetRect().Size();
UpdateRect0();
GetTopRect(to, true);
GetTopRectI(to, true);
MoveCtrl *s = FindMoveCtrlPtr(top->scroll_move, this);
if(s && s->from == from && s->to == to) {
s->ctrl = NULL;
@ -283,7 +283,7 @@ Ctrl& Ctrl::SetPos(LogPos p, bool _inframe)
GuiLock __;
Ctrl *parent = GetParent();
if(p != pos || inframe != _inframe) {
if(parent || !IsOpen())
if(parent || !IsOpen() || virtual_popup)
SetPos0(p, _inframe);
else {
ASSERT(p.x.GetAlign() == ALIGN_LEFT);
@ -292,6 +292,8 @@ Ctrl& Ctrl::SetPos(LogPos p, bool _inframe)
WndSetPos(OffsetMegaRect(CalcRect(p, pwa, pwa)));
StateH(POSITION);
}
if(virtual_popup)
StateH(POSITION);
}
return *this;
}

View file

@ -387,7 +387,7 @@ VectorMap< HWND, Ptr<Ctrl> >& Ctrl::Windows()
return map;
}
Vector<Ctrl *> Ctrl::GetTopCtrls()
Vector<Ctrl *> Ctrl::GetTopCtrls0()
{
Vector<Ctrl *> v;
VectorMap< HWND, Ptr<Ctrl> >& w = Windows();
@ -425,7 +425,7 @@ HWND Ctrl::GetOwnerHWND() const
return GetWindow(hwnd, GW_OWNER);
}
Ctrl *Ctrl::GetOwner()
Ctrl *Ctrl::GetOwner0()
{
GuiLock __;
HWND hwnd = GetOwnerHWND();
@ -1185,7 +1185,7 @@ void Ctrl::PopUpHWND(HWND owner, bool savebits, bool activate, bool dropshadow,
if(activate) SetFocus();
}
void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost)
void Ctrl::PopUp0(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost)
{
popup = false;
Ctrl *q = owner ? owner->GetTopCtrl() : GetActiveCtrl();

View file

@ -15,6 +15,7 @@ void Animate(Ctrl& c, const Rect& target, int type)
Rect r0 = c.GetRect();
dword time0 = msecs();
int anitime = 150;
DDUMP(target);
if(type)
for(;;) {
int t = int(msecs() - time0);
@ -47,6 +48,7 @@ void Animate(Ctrl& c, const Rect& target, int type)
Ctrl::GuiSleep(0);
}
c.SetRect(target);
DDUMP(c.GetRect());
c.SetAlpha(255);
}

View file

@ -305,6 +305,11 @@ void PopUpList::PopUp(Ctrl *owner, int x, int top, int bottom, int width) {
popup->ac.SetFocus();
}
DDUMP(popup->IsOpen());
DDUMP(popup->GetRect());
DDUMP(popup->GetScreenRect());
DDUMP(popup->GetOwner()->GetScreenRect());
popup->ac.SizePos(); // the size of popup can be slightly bigger than requested
inpopup--;
}

View file

@ -69,6 +69,7 @@ bool PopUpTable::Key(dword key, int n) {
void PopUpTable::PopUp(Ctrl *owner, int x, int top, int bottom, int width) {
if(inpopup)
return;
DLOG("**** PopUpTable::PopUp");
inpopup++;
DoClose();
int h = AddFrameSize(width, min(droplines * GetLineCy(), GetTotalCy())).cy;
@ -106,6 +107,9 @@ void PopUpTable::PopUp(Ctrl *owner, int x, int top, int bottom, int width) {
SetFocus();
open = true;
}
DDUMP(popup->IsOpen());
DDUMP(popup->GetScreenRect());
DDUMP(popup->GetOwner()->GetScreenRect());
SizePos(); // the size of popup can be slightly bigger than requested
inpopup--;
}