aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/api/skin/widgets/xuioswndhost.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/api/skin/widgets/xuioswndhost.cpp')
-rw-r--r--Src/Wasabi/api/skin/widgets/xuioswndhost.cpp306
1 files changed, 306 insertions, 0 deletions
diff --git a/Src/Wasabi/api/skin/widgets/xuioswndhost.cpp b/Src/Wasabi/api/skin/widgets/xuioswndhost.cpp
new file mode 100644
index 00000000..4835271f
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuioswndhost.cpp
@@ -0,0 +1,306 @@
+#include <precomp.h>
+#include "xuioswndhost.h"
+#include <api/wnd/notifmsg.h>
+#include <bfc/parse/paramparser.h>
+#include <tataki/region/region.h>
+#include <api/wndmgr/layout.h>
+// -----------------------------------------------------------------------
+const wchar_t OSWndHostXuiObjectStr[] = L"OSWndHost"; // This is the xml tag
+char OSWndHostXuiSvcName[] = "OSWndHost xui object";
+
+XMLParamPair XuiOSWndHost::params[] = {
+ {XUIOSWNDHOST_SETHWND, L"HWND"},
+ {XUIOSWNDHOST_SETOFFSETS, L"OFFSETS"},
+ };
+// -----------------------------------------------------------------------
+XuiOSWndHost::XuiOSWndHost() {
+ hosted=false;
+ setStartHidden(1);
+ setVisible(0);
+ visible_start_state=1;
+ setVirtual(0); // we are a real window, with an hwnd and shit
+ hasregionrect = 0;
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+
+ ScriptObject *o = getGuiObject()->guiobject_getScriptObject();
+ o->vcpu_setInterface(osWndHostGuid, static_cast<OSWndHost *>(this));
+}
+
+void XuiOSWndHost::CreateXMLParameters(int master_handle)
+{
+ //XUIOSWNDHOST_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+// -----------------------------------------------------------------------
+XuiOSWndHost::~XuiOSWndHost() {
+}
+
+void XuiOSWndHost::onSetVisible(int show)
+{
+ visible_start_state = show;
+ XUIOSWNDHOST_PARENT::onSetVisible(show);
+}
+
+// -----------------------------------------------------------------------
+int XuiOSWndHost::onPaint(Canvas *c) {
+ XUIOSWNDHOST_PARENT::onPaint(c);
+ RECT r;
+ getClientRect(&r);
+ c->fillRect(&r, 0);
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int XuiOSWndHost::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return XUIOSWNDHOST_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid) {
+ case XUIOSWNDHOST_SETHWND: {
+#ifdef _WIN64
+ HWND wnd = (HWND)_wtoi64(value);
+#else
+ HWND wnd = (HWND)WTOI(value);
+#endif
+ if (IsWindow(wnd))
+ oswndhost_host(wnd);
+ break;
+ }
+ case XUIOSWNDHOST_SETOFFSETS: {
+ ParamParser pp(value, L",");
+ RECT r={0,0,0,0};
+ if (pp.getNumItems() > 0)
+ r.left = WTOI(pp.enumItem(0));
+ if (pp.getNumItems() > 1)
+ r.top = WTOI(pp.enumItem(1));
+ if (pp.getNumItems() > 2)
+ r.right = WTOI(pp.enumItem(2));
+ if (pp.getNumItems() > 3)
+ r.bottom = WTOI(pp.enumItem(3));
+ oswndhost_setRegionOffsets(&r);
+ break;
+ }
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void XuiOSWndHost::oswndhost_setRegionOffsets(RECT *r) {
+ if (r == NULL) {
+ hasregionrect = 0;
+ if (wnd != NULL && isPostOnInit()) {
+ SetWindowRgn(wnd, NULL, 0);
+ onResize();
+ }
+ return;
+ }
+ regionrect = *r;
+ hasregionrect = 1;
+ //if (isPostOnInit())
+ //onResize();
+}
+
+void XuiOSWndHost::doOnResize()
+{
+ if (wnd != NULL)
+ {
+ RECT r;
+ getClientRect(&r);
+ if (renderRatioActive())
+ {
+ //CUT: double ra = getRenderRatio();
+ multRatio(&r);
+ }
+
+ if (hasregionrect) {
+ r.left -= regionrect.left;
+ r.top -= regionrect.top;
+ r.right += regionrect.right;
+ r.bottom += regionrect.bottom;
+ }
+ SetWindowPos(wnd, NULL, r.left, r.top, r.right-r.left, r.bottom-r.top, SWP_NOZORDER|SWP_NOACTIVATE/*|SWP_NOCOPYBITS|SWP_NOREDRAW*/);
+
+ if (hasregionrect) {
+ RECT cr={0,0,r.right-r.left,r.bottom-r.top};
+ RECT wndr={cr.left+regionrect.left, cr.top+regionrect.top, cr.right-regionrect.right, cr.bottom-regionrect.bottom};
+
+ RegionI reg(&wndr);
+ SetWindowRgn(wnd, reg.makeWindowRegion(), TRUE);
+ //InvalidateRgn(wnd, reg.getOSHandle(), FALSE);
+ }
+ //else
+ //InvalidateRect(wnd, NULL, TRUE);
+
+ //UpdateWindow(wnd);
+ //repaint();
+ }
+}
+int XuiOSWndHost::onAfterResize()
+{
+ if (!XUIOSWNDHOST_PARENT::onAfterResize()) return 0;
+ doHost();
+ doOnResize();
+
+
+ return 1;
+}
+// -----------------------------------------------------------------------
+
+#define STYLE_FILTER (WS_OVERLAPPEDWINDOW | WS_POPUPWINDOW | WS_DLGFRAME | WS_CHILD)
+#define EXSTYLE_FILTER (WS_EX_OVERLAPPEDWINDOW | WS_EX_PALETTEWINDOW | WS_EX_CONTROLPARENT)
+
+void XuiOSWndHost::doHost()
+{
+ if (wnd && !hosted)
+ {
+ onBeforeReparent(1);
+ oldparent = GetAncestor(wnd, GA_PARENT);
+ /*
+ bool blah=false;
+ RECT r;
+ if (IsWindowVisible(wnd))
+ {
+
+ GetWindowRect(wnd, &r);
+ MapWindowPoints(HWND_DESKTOP, oldparent, (LPPOINT)&r, 2);
+ blah=true;
+ }
+*/
+ // remember if WS_POPUP or WS_CHILD was set so we can reset it when we unhost
+
+ DWORD style;
+ style = GetWindowLongPtrW(wnd, GWL_STYLE);
+ savedStyle = (style & STYLE_FILTER);
+ SetWindowLongPtrW(wnd, GWL_STYLE, (style & ~(STYLE_FILTER)) | WS_CHILD);
+ style = GetWindowLongPtrW(wnd, GWL_EXSTYLE);
+ savedExStyle = (style & EXSTYLE_FILTER);
+ SetWindowLongPtrW(wnd, GWL_EXSTYLE, (style & ~(EXSTYLE_FILTER)) | WS_EX_CONTROLPARENT);
+
+ GetWindowRect(wnd, &oldrect);
+
+ SetParent(wnd, gethWnd());
+ //if (blah)
+ //InvalidateRect(oldparent, &r, FALSE);
+ //UpdateWindow(oldparent);
+ SendMessageW(gethWnd(), 0x0127, MAKEWPARAM(3/*UIS_INITIALIZE*/, 3/*UISF_HIDEACCEL | UISF_HIDEFOCUS*/), 0L);
+ onAfterReparent(1);
+ dropVirtualCanvas(); // we don't need a canvas anymore, save the memory!
+ hosted=true;
+ doOnResize();
+ setVisible(visible_start_state);
+ }
+}
+
+// -----------------------------------------------------------------------
+void XuiOSWndHost::oswndhost_host(HWND oswnd)
+{
+ ASSERT(IsWindow(oswnd));
+ wnd = oswnd;
+ if (isPostOnInit())
+ doHost();
+}
+
+// -----------------------------------------------------------------------
+void XuiOSWndHost::oswndhost_unhost() {
+ if (wnd == NULL) return;
+ onBeforeReparent(0);
+
+ if (IsWindow(wnd)) {
+ // set back the old flags
+
+ DWORD style;
+ style = GetWindowLongPtrW(wnd, GWL_STYLE);
+ SetWindowLongPtrW(wnd, GWL_STYLE, ((style & ~STYLE_FILTER) | savedStyle));
+ style = GetWindowLongPtrW(wnd, GWL_EXSTYLE);
+ SetWindowLongPtrW(wnd, GWL_EXSTYLE, ((style & ~EXSTYLE_FILTER) | savedExStyle));
+
+ int config_aot = ((GetWindowLong(WASABI_API_WND->main_getRootWnd()->gethWnd(), GWL_EXSTYLE) & WS_EX_TOPMOST) != 0);
+
+ SetWindowPos(wnd, config_aot ? HWND_TOPMOST : HWND_NOTOPMOST,
+ oldrect.left, oldrect.top, oldrect.right-oldrect.left, oldrect.bottom-oldrect.top,
+ SWP_NOZORDER | (( 0 == config_aot) ? SWP_NOACTIVATE : 0));
+
+ SetParent(wnd, oldparent);
+
+ if (hasregionrect) SetWindowRgn(wnd, NULL, 0);
+// InvalidateRect(wnd, NULL, TRUE);
+ hosted=false;
+
+ }
+
+ onAfterReparent(0);
+
+ hasregionrect = 0;
+ wnd = NULL;
+}
+
+int XuiOSWndHost::onUserMessage(int msg, int w, int l, int *r) {
+ switch (msg) {
+ case OSWNDHOST_REQUEST_IDEAL_SIZE:
+ onDeferredCallback/*postDeferredCallback*/(DCB_OSWNDHOST_REQUEST_IDEAL_SIZE, (intptr_t)(new DCBIdealSize(w, l)));
+ *r = 1;
+ return 1;
+ }
+ return XUIOSWNDHOST_PARENT::onUserMessage(msg, w, l, r); // do default handling
+}
+
+int XuiOSWndHost::onDeferredCallback(intptr_t p1, intptr_t p2) {
+ switch (p1) {
+ case DCB_OSWNDHOST_REQUEST_IDEAL_SIZE:
+ {
+ DCBIdealSize *ideal = (DCBIdealSize *)p2;
+ if (ideal == NULL) break;
+
+ ifc_window *p=getDesktopParent(); // Gets the group/layout at the base of the wnd tree, the desktop hwnd
+ if (p == NULL) {
+ delete ideal;
+ break;
+ }
+ Layout *l = static_cast<Layout *>(p->getInterface(layoutGuid));
+ if (l)
+ l->beginResize();
+ RECT r,r2;
+ getClientRect(&r); // the size of this wnd
+ if (renderRatioActive()) multRatio(&r);
+
+ p->getWindowRect(&r2); // the size of the desktop parent
+
+ // take borders into account
+ int neww = ideal->m_idealwidth+((r2.right-r2.left)-(r.right-r.left));
+ int newh = ideal->m_idealheight+((r2.bottom-r2.top)-(r.bottom-r.top));
+
+ // take layout min/max values into account
+ int min_w = p->getPreferences(MINIMUM_W);
+ int min_h = p->getPreferences(MINIMUM_H);
+ int max_w = p->getPreferences(MAXIMUM_W);
+ int max_h = p->getPreferences(MAXIMUM_H);
+ if (min_w != AUTOWH) neww = MAX(min_w, neww);
+ if (min_h != AUTOWH) newh = MAX(min_h, newh);
+ if (max_w != AUTOWH) neww = MIN(max_w, neww);
+ if (max_h != AUTOWH) newh = MIN(max_h, newh);
+
+ //CUT: RECT res={r2.left,r2.top,neww,newh};
+ p->resize(r2.left, r2.top, neww, newh);
+ if (l)
+ l->endResize();
+ delete ideal;
+ return 1;
+ }
+
+ }
+ return XUIOSWNDHOST_PARENT::onDeferredCallback(p1, p2);
+}
+
+void XuiOSWndHost::onBeforeReparent(int i) {
+}
+
+void XuiOSWndHost::onAfterReparent(int i) {
+}
+