diff options
Diffstat (limited to 'Src/Wasabi/api/wnd/virtualwnd.cpp')
-rw-r--r-- | Src/Wasabi/api/wnd/virtualwnd.cpp | 672 |
1 files changed, 672 insertions, 0 deletions
diff --git a/Src/Wasabi/api/wnd/virtualwnd.cpp b/Src/Wasabi/api/wnd/virtualwnd.cpp new file mode 100644 index 00000000..dd45da11 --- /dev/null +++ b/Src/Wasabi/api/wnd/virtualwnd.cpp @@ -0,0 +1,672 @@ +#include <precomp.h> +#include "virtualwnd.h" +#include <tataki/region/api_region.h> + +#include <api/wnd/usermsg.h> +#include <api/wnd/accessible.h> + +VirtualWnd::VirtualWnd() +{ + virtualX = virtualY = virtualH = virtualW = 0; + bypassvirtual = 0; + focus = 0; + resizecount = 0; + lastratio = 1; +} + +VirtualWnd::~VirtualWnd() +{} + +int VirtualWnd::init(ifc_window *parWnd, int nochild) +{ + if (!bypassvirtual) + setParent(parWnd); + + return (VIRTUALWND_PARENT::init(parWnd, nochild)); +} + +int VirtualWnd::init(OSMODULEHANDLE moduleHandle, OSWINDOWHANDLE parent, int nochild) +{ + if (!bypassvirtual) + { + ASSERTPR(getParent() != NULL, "Virtual window created without specifying BaseWnd parent"); + + if (getStartHidden()) + this_visible = 0; + else + this_visible = 1; + + onInit(); + + onPostOnInit(); + + if (isVisible()) + onSetVisible(1); + + return 1; + } + else + return VIRTUALWND_PARENT::init(moduleHandle, parent, nochild); +} + +OSWINDOWHANDLE VirtualWnd::getOsWindowHandle() +{ + // ASSERTPR(getParent() != NULL, "Virtual window used as base parent !"); + if (!bypassvirtual) + { + if (!getParent()) + return INVALIDOSWINDOWHANDLE; + + return getParent()->getOsWindowHandle(); + } + else + { + return VIRTUALWND_PARENT::getOsWindowHandle(); + } +} + +OSMODULEHANDLE VirtualWnd::getOsModuleHandle() +{ + if (!bypassvirtual) + { + if (!getParent()) + return INVALIDOSMODULEHANDLE; + + return getParent()->getOsModuleHandle(); + } + else + return VIRTUALWND_PARENT::getOsModuleHandle(); +} + +void VirtualWnd::resize(RECT *r, int wantcb) +{ + if (!bypassvirtual) + { + resize(r->left, r->top, r->right - r->left, r->bottom - r->top, wantcb); + } + else + { + VIRTUALWND_PARENT::resize( r, wantcb ); + + //virtualX = rx; + //virtualY = ry; + //virtualW = rwidth; + //virtualH = rheight; + } +} + +// fg> the resizecount > 1 is a hack, it should be 0 but i need more time to fix this thing, at least this way we don't lose the optim +void VirtualWnd::resize(int x, int y, int w, int h, int wantcb) +{ + if (!bypassvirtual) + { + if (x == NOCHANGE) + x = virtualX; + + if (y == NOCHANGE) + y = virtualY; + + if (w == NOCHANGE) + w = virtualW; + + if (h == NOCHANGE) + h = virtualH; + + double thisratio = getRenderRatio(); + + if (resizecount > 1 && virtualX == x && virtualY == y && virtualW == w && virtualH == h && lastratio == thisratio) + return ; + + lastratio = thisratio; + + if (isVisible()) + { + RECT r; + getNonClientRect(&r); + invalidateRect(&r); + } + + virtualX = x; + virtualY = y; + virtualW = w; + virtualH = h; + + if (isVisible()) + { + RECT r; + getNonClientRect(&r); + invalidateRect(&r); + } + + setRSize(x, y, w, h); + + if (wantcb && isPostOnInit()) + { + resizecount = MIN(resizecount + 1, 2); + onResize(); + } + } + else + { + VIRTUALWND_PARENT::resize( x, y, w, h, wantcb ); + + //virtualX = rx; + //virtualY = ry; + //virtualW = rwidth; + //virtualH = rheight; + } +} + +//CUTvoid VirtualWnd::resize(RECT *r) { +//CUT resize(r->left, r->top, r->right-r->left, r->bottom-r->top); +//CUT} + +void VirtualWnd::move(int x, int y) +{ + //DebugStringW( L"VirtualWnd::move( x = %d, y = %d )\n", x, y ); + + if (!bypassvirtual) + { + if (isVisible()) + { + RECT r; + getNonClientRect(&r); + invalidateRect(&r); + } + + virtualX = x; + virtualY = y; + + if (isVisible()) + { + RECT r; + getNonClientRect(&r); + invalidateRect(&r); + } + } + else + { + VIRTUALWND_PARENT::move( x, y ); + + //virtualX = x; + //virtualY = y; + } +} + +void VirtualWnd::invalidate() +{ + if (!bypassvirtual) + { + if (!getRootParent()) return ; + RECT r(clientRect()); + getRootParent()->invalidateRectFrom(&r, this); + // VIRTUALWND_PARENT::invalidate(); + } + else + VIRTUALWND_PARENT::invalidate(); +} + +void VirtualWnd::invalidateRect(RECT *r) +{ + if (!bypassvirtual) + { + if (!getRootParent()) return ; + getRootParent()->invalidateRectFrom(r, this); + } + else + VIRTUALWND_PARENT::invalidateRect(r); +} + +void VirtualWnd::invalidateRgn(api_region *reg) +{ + if (!bypassvirtual) + { + if (!getRootParent()) return ; + getRootParent()->invalidateRgnFrom(reg, this); + } + else + VIRTUALWND_PARENT::invalidateRgn(reg); +} + +void VirtualWnd::validate() +{ + if (!bypassvirtual) + { + if (!getRootParent()) return ; + RECT r; + getClientRect(&r); + getRootParent()->validateRect(&r); + } + else + VIRTUALWND_PARENT::validate(); +} + +void VirtualWnd::validateRect(RECT *r) +{ + if (!bypassvirtual) + { + if (!getRootParent()) + return ; + + getRootParent()->validateRect(r); + } + else + VIRTUALWND_PARENT::validateRect( r ); +} + +void VirtualWnd::validateRgn(api_region *reg) +{ + if (!bypassvirtual) + { + if (!getRootParent()) return ; + getRootParent()->validateRgn(reg); + } + else + VIRTUALWND_PARENT::validateRgn(reg); +} + +void VirtualWnd::getClientRect(RECT *rect) +{ + if (!bypassvirtual) + { + // CT:getClientRect behaves differently here for virtual windows + // so we can use onPaint directly on the destination canvas + // without using another temporary canvas. + Wasabi::Std::setRect(rect, virtualX, virtualY, virtualX + virtualW, virtualY + virtualH); + // rect->left=0; rect->right=virtualW; + // rect->top=0; rect->bottom=virtualH; + } + else + VIRTUALWND_PARENT::getClientRect(rect); +} + +void VirtualWnd::getNonClientRect(RECT *rect) +{ + VirtualWnd::getClientRect(rect); +} + +void VirtualWnd::getWindowRect(RECT *rect) +{ + if (!bypassvirtual) + { + RECT a; + getRootParent()->getWindowRect(&a); + + int x = virtualX, y = virtualY, w = virtualW, h = virtualH; + + if (renderRatioActive()) + { + multRatio(&x, &y); + multRatio(&w, &h); + } + + rect->left = a.left + x; rect->right = rect->left + w; + rect->top = a.top + y; rect->bottom = rect->top + h; + } + else + VIRTUALWND_PARENT::getWindowRect(rect); +} + +int VirtualWnd::beginCapture() +{ + if (!bypassvirtual) + { + disable_tooltip_til_recapture = 0; + getRootParent()->setVirtualChildCapture(this); + return 1; + } + else + return VIRTUALWND_PARENT::beginCapture(); +} + +int VirtualWnd::endCapture() +{ + if (!bypassvirtual) + { + if (getRootParent() == NULL) return 0; + getRootParent()->setVirtualChildCapture(NULL); + return 1; + } + else + return VIRTUALWND_PARENT::endCapture(); +} + +int VirtualWnd::getCapture() +{ + if (!bypassvirtual) + { + if (getRootParent() == NULL) return 0; + return getRootParent()->getVirtualChildCapture() == this; + } + else + return VIRTUALWND_PARENT::getCapture(); +} + +void VirtualWnd::setVirtualChildCapture(BaseWnd *child) +{ + if (!bypassvirtual) + { + getParent()->setVirtualChildCapture(child); + } + else + VIRTUALWND_PARENT::setVirtualChildCapture(child); +} + +// eek +void VirtualWnd::repaint() +{ + if (!bypassvirtual) + { + if (!getParent()) return ; + getParent()->repaint(); + } + else + VIRTUALWND_PARENT::repaint(); +} + +/*int VirtualWnd::focusNextSibbling(int dochild) { + return 1; +} + +int VirtualWnd::focusNextVirtualChild(BaseWnd *child) { + return 1; +}*/ + +int VirtualWnd::cascadeRepaint(int pack) +{ + if (!bypassvirtual) + { + if (getRootParent()) + { + RECT r; + VirtualWnd::getNonClientRect(&r); + getRootParent()->cascadeRepaintRectFrom(&r, this, pack); + } + return 1; + } + else + return VIRTUALWND_PARENT::cascadeRepaint(pack); +} + +int VirtualWnd::cascadeRepaintRect(RECT *r, int pack) +{ + if (!bypassvirtual) + { + if (getRootParent()) + { + getRootParent()->cascadeRepaintRectFrom(r, this, pack); + } + return 1; + } + else + return VIRTUALWND_PARENT::cascadeRepaintRect(r, pack); +} + +int VirtualWnd::cascadeRepaintRgn(api_region *r, int pack) +{ + if (!bypassvirtual) + { + if (getRootParent()) + { + getRootParent()->cascadeRepaintRgnFrom(r, this, pack); + } + return 1; + } + else + return VIRTUALWND_PARENT::cascadeRepaintRgn(r, pack); +} + +/*api_window *VirtualWnd::getWindowBehindMyself(int x, int y) { + RECT r; + if (!bypassvirtual) { + if (!getParent()) return NULL; + int n = getParent()->getNumVirtuals(); + + api_window *c = NULL; + + for (int i=n-1;i>=0;i++) { + c = getParent()->getVirtualChild(i); + if (c == this) break; + } + + i--; + if (i < 0) return getParent(); + + for (;i>=0; i--) { + c = getParent()->getVirtualChild(i); + c->getNonClientRect(&r); + if (x>=r.left&&x<=r.right&&y>=r.top&&y<=r.bottom) + return c; + } + return getParent(); + } else + return NULL; +}*/ + +ifc_window *VirtualWnd::rootWndFromPoint(POINT *pt) +{ + if (!bypassvirtual) + { + if (!getParent()) return NULL; + return getParent()->rootWndFromPoint(pt); + } + else + return VIRTUALWND_PARENT::rootWndFromPoint(pt); +} + +double VirtualWnd::getRenderRatio() +{ + if (!bypassvirtual) + { + if (!getParent()) return 1.0; + return getParent()->getRenderRatio(); + } + else + return VIRTUALWND_PARENT::getRenderRatio(); +} + +void VirtualWnd::bringToFront() +{ + if (!bypassvirtual) + { + if (!getParent()) return ; + //getParent()->bringVirtualToFront(this); TODO: FIX!!! + } + else + VIRTUALWND_PARENT::bringToFront(); +} + +void VirtualWnd::bringToBack() +{ + if (!bypassvirtual) + { + if (!getParent()) return ; + //getParent()->bringVirtualToBack(this); TODO: FIX!!! + } + else + VIRTUALWND_PARENT::bringToBack(); +} + +void VirtualWnd::bringAbove(BaseWnd *o) +{ + if (!bypassvirtual) + { + if (!getParent()) return ; + getParent()->bringVirtualAbove(this, o); + } /* else + VIRTUALWND_PARENT::bringAbove();*/ +} + +void VirtualWnd::bringBelow(BaseWnd *o) +{ + if (!bypassvirtual) + { + if (!getParent()) return ; + getParent()->bringVirtualBelow(this, o); + } /* else + VIRTUALWND_PARENT::bringBelow();*/ +} + +int VirtualWnd::reparent(ifc_window *newparent) +{ + if (!bypassvirtual) + { + if (getParent()) + getParent()->unregisterRootWndChild(this); + parentWnd = NULL; + newparent->registerRootWndChild(this); + onSetParent(newparent); + newparent->invalidate(); + return 1; + } + else + { + return VIRTUALWND_PARENT::reparent(newparent); + } +} + +int VirtualWnd::setVirtual(int i) +{ + // ASSERT(!isInited()); // cut + + if (isInited()) return 0; + bypassvirtual = !i; + return 1; +} + +ifc_window *VirtualWnd::getRootParent() +{ + if (!bypassvirtual) + { + if (!getParent()) return NULL; + ifc_window *t = this; + while (t->isVirtual()) + { + if (!t->getParent()) return NULL; + t = t->getParent(); + } + return t; + } + else + { + return VIRTUALWND_PARENT::getRootParent(); + } +} + +int VirtualWnd::gotFocus() +{ + if (!bypassvirtual) + return focus; + else + return VIRTUALWND_PARENT::gotFocus(); +} + +int VirtualWnd::onGetFocus() +{ + if (!bypassvirtual) + { + focus = 1; + getRootParent()->onSetRootFocus(this); + invalidate(); + Accessible *a = getAccessibleObject(); + if (a != NULL) + a->onGetFocus(); + } + else + return VIRTUALWND_PARENT::onGetFocus(); + return 1; +} + +int VirtualWnd::onKillFocus() +{ + if (!bypassvirtual) + { + focus = 0; + invalidate(); + } + else + return VIRTUALWND_PARENT::onKillFocus(); + return 1; +} + +void VirtualWnd::setFocus() +{ + ifc_window *f = this; + if (!f->wantFocus() && f->getParent()) + { + while (f) + { + ifc_window *rp = f->getRootParent(); + if (rp == f) rp = f->getParent(); + f = rp; + if (f && (!f->getParent() || f->wantFocus() || f == WASABI_API_WND->main_getRootWnd())) + { + f->setFocus(); + break; + } + } + } + else + { + if (!bypassvirtual) + { + if (getParent()) + { + getParent()->setVirtualChildFocus(this); + } + } + else + VIRTUALWND_PARENT::setFocus(); + } +} + +void VirtualWnd::setVirtualChildFocus(ifc_window *child) +{ + if (!bypassvirtual) + { + getParent()->setVirtualChildFocus(child); + } + else + VIRTUALWND_PARENT::setVirtualChildFocus(child); +} + +int VirtualWnd::onActivate() +{ + if (bypassvirtual) + return VIRTUALWND_PARENT::onActivate(); + return 1; +} + +int VirtualWnd::onDeactivate() +{ + if (bypassvirtual) + return VIRTUALWND_PARENT::onDeactivate(); + return 1; +} + +void VirtualWnd::setAllowDeactivation(int allow) +{ + ifc_window *w = getDesktopParent(); + if (w != NULL && w != this) + w->setAllowDeactivation(allow); + else VIRTUALWND_PARENT::setAllowDeactivation(allow); +} + +int VirtualWnd::allowDeactivation() +{ + ifc_window *w = getDesktopParent(); + if (w != NULL && w != this) + return w->allowDeactivation(); + return VIRTUALWND_PARENT::allowDeactivation(); +} + + + +/* todo: setCursor + + + real childs going invisible should deferedInvalidate their rect on their parent window if it has a virtualCanvas +*/ + + + +// No need for screenToClient/clientToScreen overrides since the virtual's origin is the same as it's parent |