void Control::SetParent(Control *newParent) { HwndWrapper *prevRoot = NULL; if (parent) prevRoot = GetRootHwndWnd(parent); HwndWrapper *newRoot = GetRootHwndWnd(newParent); CrashIf(!newRoot); parent = newParent; if (prevRoot) UnRegisterEventHandlers(prevRoot->evtMgr); RegisterEventHandlers(newRoot->evtMgr); }
// note: all derived classes must call Control::NotifyMouseLeave() // from their own NotifyMouseLeave(). void Control::NotifyMouseLeave() { // hide url tooltip HwndWrapper *hw = GetRootHwndWnd(this); HWND hwndParent = hw->hwndParent; ClearInfotip(hwndParent); }
// traverse tree upwards to find HWND that is ultimately backing // this window HWND GetHwndParent(const Control *c) { HwndWrapper *wHwnd = GetRootHwndWnd(c); if (wHwnd) return wHwnd->hwndParent; return NULL; }
Control::~Control() { delete layout; DeleteVecMembers(children); if (!parent) return; HwndWrapper *root = GetRootHwndWnd(parent); CrashIf(!root); UnRegisterEventHandlers(root->evtMgr); }
// note: all derived classes must call Control::NotifyMouseEnter() // from their own NotifyMouseEnter(). void Control::NotifyMouseEnter() { // show url as a tooltip HwndWrapper *hw = GetRootHwndWnd(this); HWND hwndParent = hw->hwndParent; int x = 0, y = 0; MapMyToRootPos(x, y); RECT pos = { x, y, 0, 0 }; pos.right = x + this->pos.Width; pos.bottom = y + this->pos.Height; CreateInfotipForLink(hwndParent, toolTip, pos); }
void Control::SetPosition(const Rect& p) { if (p.Equals(pos)) return; // perf optimization bool sizeChanged = (p.Width != pos.Width) || (p.Height != pos.Height); // when changing position we need to invalidate both // before and after position // TODO: not sure why I need this, but without it there // are drawing artifacts Rect p1(p); p1.Inflate(1,1); Rect p2(pos); p2.Inflate(1,1); RequestRepaint(this, &p1, &p2); pos = p; if (!sizeChanged) return; HwndWrapper *hwnd = GetRootHwndWnd(this); hwnd->evtMgr->NotifySizeChanged(this, p.Width, p.Height); }
// r1 and r2 are relative to w. If both are NULL, we invalidate the whole w void RequestRepaint(Control *c, const Rect *r1, const Rect *r2) { // we might be called when the control hasn't yet been // placed in the window hierarchy if (!c->parent) return; Rect wRect(0, 0, c->pos.Width, c->pos.Height); int offX = 0, offY = 0; c->MapMyToRootPos(offX, offY); while (c->parent) { c = c->parent; } HWND hwnd = c->hwndParent; CrashIf(!hwnd); HwndWrapper *wnd = GetRootHwndWnd(c); if (wnd) wnd->RequestRepaint(); // if we have r1 or r2, invalidate those, else invalidate w bool didInvalidate = false; if (r1) { InvalidateAtOff(hwnd, r1, offX, offY); didInvalidate = true; } if (r2) { InvalidateAtOff(hwnd, r2, offX, offY); didInvalidate = true; } if (didInvalidate) return; InvalidateAtOff(hwnd, &wRect, offX, offY); }
void RequestLayout(Control *c) { HwndWrapper *wnd = GetRootHwndWnd(c); if (wnd) wnd->RequestLayout(); }