#include #include #include #include #include //#include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef WM_MOUSEWHEEL #define WM_MOUSEWHEEL 0x20A #endif const wchar_t groupXuiObjectStr[] = L"Group"; // This is the xml tag char groupXuiSvcName[] = "Group xui object"; // this is the name of the xuiservice #ifdef WASABI_COMPILE_CONFIG const wchar_t cfgGroupXuiObjectStr[] = L"CfgGroup"; // This is the xml tag char cfgGroupXuiSvcName[] = "CfgGroup xui object"; // this is the name of the xuiservice #endif XMLParamPair Group::groupParams[] = { {XUIGROUP_AUTOHEIGHTSOURCE, L"AUTOHEIGHTSOURCE"}, {XUIGROUP_AUTOWIDTHSOURCE, L"AUTOWIDTHSOURCE"}, {XUIGROUP_BACKGROUND, L"BACKGROUND"}, {XUIGROUP_DRAWBACKGROUND, L"DRAWBACKGROUND"}, {XUIGROUP_DEFAULT_W, L"DEFAULT_W"}, {XUIGROUP_DEFAULT_H, L"DEFAULT_H"}, {XUIGROUP_DESIGN_H, L"DESIGN_H"}, {XUIGROUP_DESIGN_W, L"DESIGN_W"}, {XUIGROUP_EMBED_XUI, L"EMBED_XUI"}, {XUIGROUP_INHERIT_CONTENT, L"INHERIT_CONTENT"}, {XUIGROUP_INHERIT_GROUP, L"INHERIT_GROUP"}, {XUIGROUP_INSTANCEID, L"INSTANCEID"}, {XUIGROUP_LOCKMINMAX, L"LOCKMINMAX"}, {XUIGROUP_MAXIMUM_H, L"MAXIMUM_H"}, {XUIGROUP_MAXIMUM_W, L"MAXIMUM_W"}, {XUIGROUP_MINIMUM_H, L"MINIMUM_H"}, {XUIGROUP_MINIMUM_W, L"MINIMUM_W"}, {XUIGROUP_NAME, L"NAME"}, {XUIGROUP_PROPAGATESIZE, L"PROPAGATESIZE"}, {XUIGROUP_XUITAG, L"XUITAG"}, }; Group::Group() { scripts_enabled = 1; getScriptObject()->vcpu_setInterface(groupGuid, (void *)static_cast(this)); getScriptObject()->vcpu_setClassName(L"Group"); getScriptObject()->vcpu_setController(groupController); background = NULL; skinpart = 0; captured = 0; resizing = 0; x = 0; y = 0; size_w = 0; size_h = 0; lockminmax = 0; propagatesize = 0; reg = NULL; default_h = AUTOWH; default_w = AUTOWH; // allreg = NULL; // subregionlayers = new PtrList; // subregiongroups = new PtrList; deleting = 0; moving = 0; drawbackground = 0; groupmaxheight = AUTOWH; groupmaxwidth = AUTOWH; groupminheight = AUTOWH; groupminwidth = AUTOWH; // regionop = 0; // allsubreg = NULL; groups.addItem(this); scaledreg = NULL; scaledregionvalid = 0; autoregionop = 1; setRectRgn(0); disable_update_pos = 0; no_init_on_addchild = 0; lastheightsource = lastwidthsource = NULL; lastgetwidthbasedon = lastgetheightbasedon = AUTOWH; content_item = NULL; xuihandle = newXuiHandle(); CreateXMLParameters(xuihandle); design_w = AUTOWH; design_h = AUTOWH; } void Group::CreateXMLParameters(int master_handle) { //GROUP_PARENT::CreateXMLParameters(master_handle); int numParams = sizeof(groupParams) / sizeof(groupParams[0]); hintNumberOfParams(xuihandle, numParams); for (int i = 0;i < numParams;i++) { addParam(xuihandle, groupParams[i], XUI_ATTRIBUTE_IMPLIED); } } Group::~Group() { deleteScripts(); deleting = 1; WASABI_API_WND->skin_unregisterBaseTextureWindow(this); while (gui_objects.getNumItems() > 0) { SkinParser::destroyGuiObject(gui_objects.enumItem(0)); gui_objects.removeByPos(0); } delete background; delete reg; delete scaledreg; xuiparams.deleteAll(); /* subregionlayers->removeAll(); delete subregionlayers; subregiongroups->removeAll(); delete subregiongroups;*/ groups.removeItem(this); WASABI_API_SYSCB->syscb_deregisterCallback(static_cast(this)); } int Group::isGroup(Group *o) { return groups.haveItem(o); } int Group::setXmlParam(const wchar_t *paramname, const wchar_t *strvalue) { if (!WCSICMP(paramname, L"id") && !instanceid.isempty()) return GROUP_PARENT::setXmlParam(paramname, instanceid); return GROUP_PARENT::setXmlParam(paramname, strvalue); } int Group::setXuiParam(int _xuihandle, int xuiid, const wchar_t *paramname, const wchar_t *strvalue) { if (xuihandle == _xuihandle) { switch (xuiid) { case XUIGROUP_INSTANCEID: instanceid = strvalue; getGuiObject()->guiobject_setId(instanceid); return 1; case XUIGROUP_BACKGROUND: setBaseTexture(strvalue); setDrawBackground(1); return 1; case XUIGROUP_DRAWBACKGROUND: setDrawBackground(WTOI(strvalue)); return 1; case XUIGROUP_DEFAULT_W: { int w = WTOI(strvalue); //getGuiObject()->guiobject_setGuiPosition(NULL, NULL, &w, NULL, NULL, NULL, NULL, NULL); default_w = w; return 1; } case XUIGROUP_DEFAULT_H: { int h = WTOI(strvalue); //getGuiObject()->guiobject_setGuiPosition(NULL, NULL, NULL, &h, NULL, NULL, NULL, NULL); default_h = h; return 1; } case XUIGROUP_MAXIMUM_H: groupmaxheight = WTOI(strvalue); return 1; case XUIGROUP_MAXIMUM_W: groupmaxwidth = WTOI(strvalue); return 1; case XUIGROUP_MINIMUM_H: groupminheight = WTOI(strvalue); return 1; case XUIGROUP_MINIMUM_W: groupminwidth = WTOI(strvalue); return 1; case XUIGROUP_PROPAGATESIZE: propagatesize = WTOI(strvalue); return 1; case XUIGROUP_LOCKMINMAX: lockminmax = WTOI(strvalue); return 1; case XUIGROUP_NAME: setName(strvalue); return 1; case XUIGROUP_AUTOWIDTHSOURCE: setAutoWidthSource(strvalue); return 1; case XUIGROUP_AUTOHEIGHTSOURCE: setAutoHeightSource(strvalue); return 1; case XUIGROUP_EMBED_XUI: xui_embedded_id = strvalue; return 1; case XUIGROUP_XUITAG: return 1; case XUIGROUP_INHERIT_GROUP: return 1; case XUIGROUP_INHERIT_CONTENT: return 1; case XUIGROUP_DESIGN_W: setDesignWidth(WTOI(strvalue)); return 1; case XUIGROUP_DESIGN_H: setDesignHeight(WTOI(strvalue)); return 1; } } return GROUP_PARENT::setXuiParam(_xuihandle, xuiid, paramname, strvalue); } void Group::setDesignWidth(int w) { design_w = w; if (isPostOnInit()) onResize(); } void Group::setDesignHeight(int h) { design_h = h; if (isPostOnInit()) onResize(); } int Group::getDesignWidth() { return design_w; } int Group::getDesignHeight() { return design_h; } int Group::onPostedMove() { return GROUP_PARENT::onPostedMove(); } #ifdef WASABI_COMPILE_WNDMGR void Group::beginMove() { if (getGuiObject()->guiobject_getParentGroup()) getGuiObject()->guiobject_getParentGroup()->beginMove(); } void Group::beginScale() { if (getGuiObject()->guiobject_getParentGroup()) getGuiObject()->guiobject_getParentGroup()->beginScale(); } void Group::beginResize() { if (getGuiObject()->guiobject_getParentGroup()) getGuiObject()->guiobject_getParentGroup()->beginResize(); } void Group::endMove() { if (getGuiObject()->guiobject_getParentGroup()) getGuiObject()->guiobject_getParentGroup()->endMove(); } void Group::endScale() { if (getGuiObject()->guiobject_getParentGroup()) getGuiObject()->guiobject_getParentGroup()->endScale(); } void Group::endResize() { if (getGuiObject()->guiobject_getParentGroup()) getGuiObject()->guiobject_getParentGroup()->endResize(); } #endif void Group::onMinMaxEnforcerChanged() { if (!isPostOnInit()) return ; int min_x = getPreferences(MINIMUM_W); int min_y = getPreferences(MINIMUM_H); int max_x = getPreferences(MAXIMUM_W); int max_y = getPreferences(MAXIMUM_H); int sug_x = getPreferences(SUGGESTED_W); int sug_y = getPreferences(SUGGESTED_H); min_x = MAX(RESIZE_MINW, min_x); min_y = MAX(RESIZE_MINH, min_y); RECT r; POINT pt; getClientRect(&r); int w = r.right - r.left; int h = r.bottom - r.top; getPosition(&pt); if ((w < min_x || h < min_y || w > max_x || h > max_y) && (w != sug_x || h != sug_y)) { //DebugString("reapplying minmax constraints\n"); resize(pt.x, pt.y, sug_x, sug_y); } } #ifdef WASABI_COMPILE_WNDMGR void Group::mouseResize(int x, int y, int resizeway) { // screen coords! int min_x = getPreferences(MINIMUM_W); int min_y = getPreferences(MINIMUM_H); int max_x = getPreferences(MAXIMUM_W); int max_y = getPreferences(MAXIMUM_H); int sug_x = getPreferences(SUGGESTED_W); int sug_y = getPreferences(SUGGESTED_H); if (max_x != AUTOWH && min_x != AUTOWH && max_x < min_x) max_x = min_x; if (max_y != AUTOWH && min_y != AUTOWH && max_y < min_y) max_y = min_y; if (min_x != AUTOWH && max_x != AUTOWH && min_x > max_x) min_x = max_x; if (min_y != AUTOWH && max_y != AUTOWH && min_y > max_y) min_y = max_y; if (sug_x != AUTOWH && min_x != AUTOWH && sug_x < min_x) sug_x = min_x; if (sug_y != AUTOWH && min_y != AUTOWH && sug_y < min_y) sug_y = min_y; if (sug_x != AUTOWH && max_x != AUTOWH && sug_x > max_x) sug_x = max_x; if (sug_y != AUTOWH && max_y != AUTOWH && sug_y > max_y) sug_y = max_y; beginResize(); int mask = 0; if (resizeway & RESIZE_BOTTOM) { mask |= BOTTOM; } if (resizeway & RESIZE_RIGHT) { mask |= RIGHT; } if (resizeway & RESIZE_TOP) { mask |= TOP; } if (resizeway & RESIZE_LEFT) { mask |= LEFT; } min_x = MAX(RESIZE_MINW, min_x); min_y = MAX(RESIZE_MINH, min_y); if (renderRatioActive()) { if (min_x != AUTOWH) multRatio(&min_x); if (min_y != AUTOWH) multRatio(NULL, &min_y); if (max_x != AUTOWH) multRatio(&max_x); if (max_y != AUTOWH) multRatio(NULL, &max_y); if (sug_x != AUTOWH) multRatio(&sug_x); if (sug_y != AUTOWH) multRatio(NULL, &sug_y); } if (min_x == AUTOWH) min_x = -1; if (max_x == AUTOWH) max_x = -1; if (min_y == AUTOWH) min_y = -1; if (max_y == AUTOWH) max_y = -1; if (sug_x == AUTOWH) sug_x = -1; if (sug_y == AUTOWH) sug_y = -1; resizeClass rsize(this, min_x, min_y, max_x, max_y, sug_x, sug_y); if (rsize.resizeWindow(this, mask | NOINTERSECT)) { RECT r = rsize.getRect(); if (renderRatioActive()) { r.right = (int)(((double)(r.right - r.left) / getRenderRatio()) + r.left + 0.5f); r.bottom = (int)(((double)(r.bottom - r.top) / getRenderRatio()) + r.top + 0.5f); } int _min_x = getPreferences(MINIMUM_W); int _min_y = getPreferences(MINIMUM_H); int _max_x = getPreferences(MAXIMUM_W); int _max_y = getPreferences(MAXIMUM_H); if (_max_x != AUTOWH && _min_x != AUTOWH && _max_x < _min_x) _max_x = _min_x; if (_max_y != AUTOWH && _min_y != AUTOWH && _max_y < _min_y) _max_y = _min_y; if (_min_x != AUTOWH && _max_x != AUTOWH && _min_x > _max_x) _min_x = _max_x; if (_min_y != AUTOWH && _max_y != AUTOWH && _min_y > _max_y) _min_y = _max_y; if (r.right - r.left < _min_x) r.right = r.left + _min_x; if (r.bottom - r.top < _min_y) r.bottom = r.top + _min_y; if (r.right - r.left > _max_x) r.right = r.left + _max_x; if (r.bottom - r.top > _max_y) r.bottom = r.top + _max_y; resizeToRect(&r); invalidate(); endResize(); } } #endif void Group::setAutoWidthSource(const wchar_t *obj) { autowidthsource = obj; } void Group::setAutoHeightSource(const wchar_t *obj) { autoheightsource = obj; } int Group::getAutoWidth() { return default_w == AUTOWH ? GROUP_PARENT::getPreferences(SUGGESTED_W) : default_w; } int Group::getAutoHeight() { return default_h == AUTOWH ? GROUP_PARENT::getPreferences(SUGGESTED_H) : default_h; } int Group::getWidthBasedOn(GuiObject *o) { if (o == NULL) { if (lastwidthsource == NULL) { if (!autowidthsource.isempty()) { lastwidthsource = getObject(autowidthsource); } } o = lastwidthsource; } if (o == NULL) return AUTOWH; if (lastgetwidthbasedon != AUTOWH) return lastgetwidthbasedon; int x, rx, w, rw; o->guiobject_getGuiPosition(&x, NULL, &w, NULL, &rx, NULL, &rw, NULL); int p = o->guiobject_getAutoWidth(); if (w == AUTOWH) { w = p; rw = 0; } if (rx == 0 && rw == 1) lastgetwidthbasedon = p - w; else if (rx == 0 && rw == 0) lastgetwidthbasedon = p + x; else lastgetwidthbasedon = AUTOWH; return lastgetwidthbasedon; } int Group::getHeightBasedOn(GuiObject *o) { if (o == NULL) { if (lastheightsource == NULL) { if (!autoheightsource.isempty()) { lastheightsource = getObject(autoheightsource); } } o = lastheightsource; } if (o == NULL) return AUTOWH; if (lastgetheightbasedon != AUTOWH) return lastgetheightbasedon; int y, ry, h, rh; o->guiobject_getGuiPosition(NULL, &y, NULL, &h, NULL, &ry, NULL, &rh); int p = o->guiobject_getAutoHeight(); if (h == AUTOWH) { h = p; rh = 0; } if (ry == 0 && rh == 1) lastgetheightbasedon = p - h; else if (ry == 0 && rh == 0) lastgetheightbasedon = h + y; else lastgetheightbasedon = AUTOWH; return lastgetheightbasedon; } int Group::getPreferences(int what) { int _what = what; if (lockminmax) { if (_what == MAXIMUM_W || _what == MINIMUM_W) _what = SUGGESTED_W; if (_what == MAXIMUM_H || _what == MINIMUM_H) _what = SUGGESTED_H; } switch (_what) { case SUGGESTED_W: { int w, rw; getGuiObject()->guiobject_getGuiPosition(NULL, NULL, &w, NULL, NULL, NULL, &rw, NULL); if (w == AUTOWH) w = getWidthBasedOn(); if (w == AUTOWH || rw == 1) w = getAutoWidth(); if (w == AUTOWH && getBaseTexture()) w = getBaseTexture()->getWidth(); if (groupmaxwidth != AUTOWH) { if (groupminwidth != AUTOWH) { return MIN(groupmaxwidth, MAX(groupminwidth, w)); } else { return MIN(groupmaxwidth, w); } } else if (groupminwidth != AUTOWH) { return MAX(groupminwidth, w); } return w; } case SUGGESTED_H: { int h, rh; getGuiObject()->guiobject_getGuiPosition(NULL, NULL, NULL, &h, NULL, NULL, NULL, &rh); if (h == AUTOWH) h = getHeightBasedOn(); if (h == AUTOWH || rh == 1) h = getAutoHeight(); if (h == AUTOWH && getBaseTexture()) h = getBaseTexture()->getHeight(); if (groupmaxheight != AUTOWH) { if (groupminheight != AUTOWH) { return MIN(groupmaxheight, MAX(groupminheight, h)); } else { return MIN(groupmaxheight, h); } } else if (groupminheight != AUTOWH) { return MAX(groupminheight, h); } return h; } case MAXIMUM_H: { int h = GROUP_PARENT::getPreferences(what); if (h != AUTOWH) return MIN(h, groupmaxheight); return groupmaxheight; } case MAXIMUM_W: { int w = GROUP_PARENT::getPreferences(what); if (w != AUTOWH) return MIN(w, groupmaxwidth); return groupmaxwidth; } case MINIMUM_H: { int h = GROUP_PARENT::getPreferences(what); if (h != AUTOWH) return MAX(h, groupminheight); return groupminheight; } case MINIMUM_W: { int w = GROUP_PARENT::getPreferences(what); if (w != AUTOWH) return MAX(w, groupminwidth); return groupminwidth; } } return GROUP_PARENT::getPreferences(what); } void Group::updatePos(GuiObject *o, RECT *r2) { if (disable_update_pos) return ; RECT r; if (r2 == NULL) { getClientRect(&r); r2 = &r; } double d = getRenderRatio(); int w, h; int ox, oy, ow, oh, orx, ory, orw, orh; int ox1, ox2, oy1, oy2, oanchor; if (o->guiobject_getAnchoragePosition(&ox1, &oy1, &ox2, &oy2, &oanchor)) { // anchorage values have not been translated into native values yet, do it now int x, y, w, h, rx, ry, rw, rh; x = y = w = h = rx = ry = rw = rh = AUTOWH; int lw = ox2 - ox1; int lh = oy2 - oy1; int iw = getDesignWidth(); int ih = getDesignHeight(); if (iw == AUTOWH || ih == AUTOWH) { Wasabi::Std::messageBox(L"anchor coordinate system used without design size for the parent group.\nYour parent group needs the design_w/design_h parameters if you are using x1/y1/x2/y2/anchor parameters on one of its children\nDefaulting to 320x200", L"XML Error", 0); iw = 320; ih = 200; } int right_m = iw - ox2; int bottom_m = ih - oy2; if ((oanchor & ANCHOR_LEFT) == 0 && (oanchor & ANCHOR_RIGHT) == 0) oanchor |= ANCHOR_LEFT; if ((oanchor & ANCHOR_TOP) == 0 && (oanchor & ANCHOR_BOTTOM) == 0) oanchor |= ANCHOR_TOP; if (oanchor & ANCHOR_LEFT) { x = ox1; rx = 0; if (oanchor & ANCHOR_RIGHT) { w = -((iw - ox2) + ox1); rw = 1; } else { w = lw; rw = 0; } } else { if (oanchor & ANCHOR_RIGHT) { x = -(right_m + lw); rx = 1; w = lw; rw = 0; } } if (oanchor & ANCHOR_TOP) { y = oy1; ry = 0; if (oanchor & ANCHOR_BOTTOM) { h = -((ih - oy2) + oy1); rh = 1; } else { h = lh; rh = 0; } } else { if (oanchor & ANCHOR_BOTTOM) { y = -(bottom_m + lh); ry = 1; h = lh; rh = 0; } } disable_update_pos = 1; o->guiobject_setGuiPosition(&x, &y, &w, &h, &rx, &ry, &rw, &rh); o->guiobject_validateAnchorage(); disable_update_pos = 0; } o->guiobject_getGuiPosition(&ox, &oy, &ow, &oh, &orx, &ory, &orw, &orh); if (ow == AUTOWH) { ow = o->guiobject_getAutoWidth(); orw = 0; } if (oh == AUTOWH) { oh = o->guiobject_getAutoHeight(); orh = 0; } TextInfoCanvas fontInfoCanvas(this); double fontScale = fontInfoCanvas.getSystemFontScale(); if (o->guiobject_getAutoSysMetricsX()) ox = (int)((float)ox * fontScale); if (o->guiobject_getAutoSysMetricsY()) oy = (int)((float)oy * fontScale); if (o->guiobject_getAutoSysMetricsW()) ow = (int)((float)ow * fontScale); if (o->guiobject_getAutoSysMetricsH()) oh = (int)((float)oh * fontScale); if (!o->guiobject_getRootWnd()->handleRatio()) { if (orw == 1) w = (int)((float)(r2->right - r2->left + ow) * d); else if (orw == 2) w = (int)(((float)(r2->right - r2->left) * ((float)ow / 100.0f)) * d); else w = (int)((float)(ow) * d); if (orh == 1) h = (int)((float)(r2->bottom - r2->top + oh) * d); else if (orh == 2) h = (int)(((float)(r2->bottom - r2->top) * ((float)oh / 100.0f)) * d); else h = (int)((float)(oh) * d); if (orx == 1) x = (int)((float)(r2->right - r2->left + ox) * d); else if (orx == 2) x = (int)(((float)(r2->right - r2->left) * ((float)ox / 100.0f)) * d); else x = (int)((float)(ox) * d); if (ory == 1) y = (int)((float)(r2->bottom - r2->top + oy) * d); else if (ory == 2) y = (int)(((float)(r2->bottom - r2->top) * ((float)oy / 100.0f)) * d); else y = (int)((float)(oy) * d); x += (int)((float)(r2->left) * d); y += (int)((float)(r2->top) * d); } else { if (orw == 1) w = r2->right - r2->left + ow; else if (orw == 2) w = (int)((float)(r2->right - r2->left) * ((float)ow / 100.0f)); else w = ow; if (orh == 1) h = r2->bottom - r2->top + oh; else if (orh == 2) h = (int)((float)(r2->bottom - r2->top) * ((float)oh / 100.0f)); else h = oh; if (orx == 1) x = r2->right - r2->left + ox; else if (orx == 2) x = (int)((float)(r2->right - r2->left) * ((float)ox / 100.0f)); else x = ox; if (ory == 1) y = r2->bottom - r2->top + oy; else if (ory == 2) y = (int)((float)(r2->bottom - r2->top) * ((float)oy / 100.0f)); else y = oy; x += r2->left; y += r2->top; } o->guiobject_getRootWnd()->resize(x, y, w, h); } int Group::onResize() { GROUP_PARENT::onResize(); if (!isInited()) return 1; RECT wr; getWindowRect(&wr); RECT r2; getClientRect(&r2); size_w = r2.right - r2.left; size_h = r2.bottom - r2.top; for (int i = 0;i < gui_objects.getNumItems();i++) { GuiObject *o = gui_objects.enumItem(i); updatePos(o, &r2); } invalidateScaledReg(); return 1; } void Group::invalidateScaledReg() { scaledregionvalid = 0; invalidateWindowRegion(); } int Group::onInit() { GROUP_PARENT::onInit(); WASABI_API_SYSCB->syscb_registerCallback(static_cast(this)); disable_update_pos = 1; no_init_on_addchild = 1; const wchar_t *id = getGroupContentId(); SkinItem *item = getGroupContentSkinItem(); if ((id && *id) || item != NULL) { SkinParser::fillGroup(this, id, item, 0, 1, scripts_enabled); } disable_update_pos = 0; no_init_on_addchild = 0; onFillGroup(); return 1; } void Group::onFillGroup() { reloadDefaults(); if (xui_embedded_id.len() > 0) embeddedxui_onNewEmbeddedContent(); } int Group::onGroupChange(const wchar_t *id) { GROUP_PARENT::onGroupChange(id); if (!isInited()) return 1; const wchar_t *cid = getGroupContentId(); SkinItem *item = getGroupContentSkinItem(); if (!(cid && *cid) || item != NULL) return 1; if (!WCSICMP(id, cid)) return 1; deleteScripts(); WASABI_API_WND->skin_unregisterBaseTextureWindow(this); while (gui_objects.getNumItems() > 0) { SkinParser::destroyGuiObject(gui_objects.enumItem(0)); } delete background; background = NULL; delete reg; reg = NULL; delete scaledreg; scaledreg = NULL; disable_update_pos = 1; no_init_on_addchild = 1; SkinParser::fillGroup(this, cid, item, 0, 1, scripts_enabled); disable_update_pos = 0; no_init_on_addchild = 0; onFillGroup(); if (isInited()) onResize(); getGuiObject()->guiobject_onStartup(); return 1; } void Group::reloadDefaults() { getGuiObject()->guiobject_getGuiPosition(NULL, NULL, &size_w, &size_h, NULL, NULL, NULL, NULL); if (size_w == AUTOWH && size_h == AUTOWH) { /* if (!background) { size_w = 250; size_h = 100; } else { size_w = background->getWidth(); size_h = background->getHeight(); }*/ if (background) { setPreferences(SUGGESTED_W, background->getWidth()); setPreferences(SUGGESTED_H, background->getHeight()); } size_w = GROUP_PARENT::getPreferences(SUGGESTED_W); size_h = GROUP_PARENT::getPreferences(SUGGESTED_H); } //setName(getGuiObject()->guiobject_getId()); if (propagatesize) { Layout *l = getGuiObject()->guiobject_getParentLayout(); if (l) l->addMinMaxEnforcer(this); } int i; for (i = 0;i < gui_objects.getNumItems();i++) { GuiObject *o = gui_objects.enumItem(i); if (o->guiobject_getParentGroup()) { o->guiobject_getRootWnd()->setParent(o->guiobject_getParentGroup()); if (!o->guiobject_getRootWnd()->isInited()) { o->guiobject_getRootWnd()->init(o->guiobject_getParentGroup()); o->guiobject_getParentGroup()->onCreateObject(getGuiObject()); } } } /* if (getGuiObject()->guiobject_getParentGroup() && regionop) getGuiObject()->guiobject_getParentGroup()->addSubRegionGroup(this);*/ invalidateWindowRegion(); startScripts(); for (i = 0;i < gui_objects.getNumItems();i++) { GuiObject *o = gui_objects.enumItem(i); o->guiobject_onStartup(); } autoResize(); const wchar_t *name = getName(); if (name != NULL) onSetName(); } void Group::startScripts() { for (int i = 0;i < getNumScripts();i++) { int vcpuid = enumScript(i); SystemObject *o = SOM::getSystemObjectByScriptId(vcpuid); if (o != NULL) { o->onLoad(); foreach(xuiparams) XuiParam *p = xuiparams.getfor(); o->onSetXuiParam(p->param, p->value); endfor; } } } int Group::onPaint(Canvas *canvas) { PaintCanvas paintcanvas; if (canvas == NULL) { if (!paintcanvas.beginPaint(this)) return 0; canvas = &paintcanvas; } GROUP_PARENT::onPaint(canvas); RECT r; if (!canvas->getClipBox(&r)) getClientRect(&r); if (getDrawBackground()) RenderBaseTexture(canvas, r); return 1; } ifc_window *Group::getBaseTextureWindow() { if (reg && !reg->isEmpty()) return this; if (getParent()) return getParent()->getBaseTextureWindow(); return this; } void Group::autoResize() { int w = getWidthBasedOn(); int h = getHeightBasedOn(); if (h == AUTOWH && w == AUTOWH) return ; resize(NOCHANGE, NOCHANGE, w == AUTOWH ? NOCHANGE : w, h == AUTOWH ? NOCHANGE : h); } int Group::childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2) { if (msg == ChildNotify::AUTOWHCHANGED) { if (lastwidthsource && child == lastwidthsource->guiobject_getRootWnd() || lastheightsource && child == lastheightsource->guiobject_getRootWnd()) { lastgetwidthbasedon = AUTOWH; lastgetheightbasedon = AUTOWH; autoResize(); } } if (!getParent()) return 0; return getParent()->childNotify(child, msg, p1, p2); } void Group::sendNotifyToAllChildren(int notifymsg, intptr_t param1, intptr_t param2) { for (int i = 0;i < gui_objects.getNumItems();i++) gui_objects.enumItem(i)->guiobject_getRootWnd()->childNotify(this, notifymsg, param1, param2); } void Group::addScript(int scriptid) { scripts.addItem(scriptid); } int Group::getNumScripts() { return scripts.getNumItems(); } int Group::enumScript(int n) { return scripts.enumItem(n); } void Group::deleteScripts() { for (int i = 0;i < scripts.getNumItems();i++) Script::unloadScript(scripts.enumItem(i)); scripts.removeAll(); } SkinBitmap *Group::getBaseTexture() { if (!background) return NULL; return background->getBitmap(); } void Group::setBaseTexture(const wchar_t *b, int regis) { backgroundstr = b; if (regis) WASABI_API_WND->skin_unregisterBaseTextureWindow(this); delete background; background = NULL; if (b != NULL && *b) { background = new AutoSkinBitmap(); background->setBitmap(b); #ifdef _WIN32 RegionI r(background->getBitmap()); setRegion(&r); #else #warning port me! #endif if (regis) WASABI_API_WND->skin_registerBaseTextureWindow(this, b); } else { delete reg; reg = NULL; delete scaledreg; scaledreg = NULL; invalidateWindowRegion(); } } const wchar_t *Group::getBackgroundStr() { return backgroundstr; } int Group::onUnknownXuiParam(const wchar_t *xmlattributename, const wchar_t *value) { int r = GROUP_PARENT::onUnknownXuiParam(xmlattributename, value); if (r == 0) { if (!isInited()) { xuiparams.addItem(new XuiParam(xmlattributename, value)); } else { for (int i = 0;i < getNumScripts();i++) { int vcpuid = enumScript(i); SystemObject *o = SOM::getSystemObjectByScriptId(vcpuid); if (o != NULL) o->onSetXuiParam(xmlattributename, value); } } } return r; } api_region *Group::getRegion() { ensureScaledRegValid(); return scaledreg; } void Group::ensureScaledRegValid() { if (!scaledregionvalid) { scaledregionvalid = 1; if (!reg) return ; if (!scaledreg) scaledreg = new RegionI; scaledreg->empty(); scaledreg->addRegion(reg); RECT rr; getNonClientRect(&rr); if (background) { float w = (float)(rr.right - rr.left) / (float)background->getWidth(); float h = (float)(rr.bottom - rr.top) / (float)background->getHeight(); if (w && h && (ABS(w - 1.0f) > 0.01f || ABS(h - 1.0f) > 0.01f)) scaledreg->scale(w, h, 1); else if (w == 0 || h == 0) { RECT r = {0, 0, 0, 0}; scaledreg->setRect(&r); } } } } void Group::setRegion(api_region *r) { ASSERT(r != NULL); if (!reg) reg = new RegionI; reg->empty(); reg->addRegion(r); // background invalidateWindowRegion(); invalidateScaledReg(); } Container *Group::getParentContainer() { if (!getGuiObject()->guiobject_getParentGroup()) { ifc_window *r = getDesktopParent(); if (r != NULL) { //ASSERT(r != NULL); Layout *l = static_cast(r->getInterface(layoutGuid)); if (!l) return NULL; return l->getParentContainer(); } } Group *g = getGuiObject()->guiobject_getParentGroup(); if (g) return g->getParentContainer(); return NULL; } ifc_window *Group::enumObjects(int i) { if (i >= gui_objects.getNumItems()) return NULL; return gui_objects.enumItem(i)->guiobject_getRootWnd(); } int Group::getNumObjects() { return gui_objects.getNumItems(); } void Group::addChild(GuiObject *g) { gui_objects.addItem(g); script_objects.addItem((ScriptObject *)g); g->guiobject_setParentGroup(this); g->guiobject_getRootWnd()->setParent(this); if (!no_init_on_addchild && isInited() && !g->guiobject_getRootWnd()->isInited()) g->guiobject_getRootWnd()->init(this); } void Group::removeChild(GuiObject *g) { if (!deleting) gui_objects.removeItem(g); script_objects.removeItem((ScriptObject *)g); } void Group::onCreateObject(GuiObject *o) { script_vcpu_onCreateObject(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(o->guiobject_getScriptObject())); } int Group::getDrawBackground() { return drawbackground; } void Group::setDrawBackground(int t) { drawbackground = t; } int Group::isLayout() { return 0; } int Group::isDesktopAlphaSafe() { if (!Wasabi::Std::Wnd::isDesktopAlphaAvailable()) return 0; for (int i = 0;i < getNumObjects();i++) { ifc_window *w = enumObjects(i); Group *cg = static_cast(w); if (Group::isGroup(cg)) if (!cg->isDesktopAlphaSafe()) return 0; if (!w->handleDesktopAlpha()) return 0; } return 1; } int Group::isTransparencySafe(int excludeme) { if (!Wasabi::Std::Wnd::isTransparencyAvailable()) return 0; if (!excludeme && isTransparencyForcedOff()) return 0; for (int i = 0;i < getNumObjects();i++) { ifc_window *w = enumObjects(i); Group *cg = static_cast(w); if (Group::isGroup(cg)) if (!cg->isTransparencySafe()) return 0; if (!w->handleTransparency()) return 0; } return 1; } GuiObject *Group::getObject(const wchar_t *id) { for (int i = 0;i < script_objects.getNumItems();i++) { if (!WCSICMP(id, gui_objects.enumItem(i)->guiobject_getId())) { return gui_objects.enumItem(i); } } return NULL; } void Group::setGroupContent(const wchar_t *id, SkinItem *item, int allowscripts) { content_id = id; content_item = item; scripts_enabled = allowscripts; } const wchar_t *Group::getGroupContentId() { return content_id; } SkinItem *Group::getGroupContentSkinItem() { return content_item; } ScriptObject *Group::script_cast(GUID g) { GuiObject *o = embeddedxui_getEmbeddedObject(); if (o != NULL) { void *r = o->guiobject_getScriptObject()->vcpu_getInterface(g); if (r != NULL) { return o->guiobject_getScriptObject(); } } return NULL; } // ----------------------------------------------------------------------- GroupScriptController _groupController; GroupScriptController *groupController = &_groupController; // -- Functions table ------------------------------------- function_descriptor_struct GroupScriptController::exportedFunction[] = { {L"getObject", 1, (void*)Group::script_vcpu_getObject }, {L"enumObject", 1, (void*)Group::script_vcpu_enumObject }, {L"getNumObjects", 0, (void*)Group::script_vcpu_getNumObjects }, {L"onCreateObject", 1, (void*)Group::script_vcpu_onCreateObject }, {L"getMousePosX", 0, (void*)Group::script_vcpu_getMousePosX }, {L"getMousePosY", 0, (void*)Group::script_vcpu_getMousePosY }, {L"isLayout", 0, (void*)Group::script_vcpu_isLayout }, {L"autoResize", 0, (void*)Group::script_vcpu_autoResize}, }; // -------------------------------------------------------- ScriptObject *GroupScriptController::cast(ScriptObject *o, GUID g) { Group *grp = static_cast(o->vcpu_getInterface(groupGuid)); if (grp != NULL) return grp->script_cast(g); return NULL; } const wchar_t *GroupScriptController::getClassName() { return L"Group"; } const wchar_t *GroupScriptController::getAncestorClassName() { return L"GuiObject"; } int GroupScriptController::getInstantiable() { return 1; } ScriptObject *GroupScriptController::instantiate() { return NULL; } void GroupScriptController::destroy(ScriptObject *o) {} void *GroupScriptController::encapsulate(ScriptObject *o) { return NULL; } void GroupScriptController::deencapsulate(void *o) {} int GroupScriptController::getNumFunctions() { return sizeof(exportedFunction) / sizeof(function_descriptor_struct); } const function_descriptor_struct *GroupScriptController::getExportedFunctions() { return exportedFunction; } GUID GroupScriptController::getClassGuid() { return groupGuid; } const wchar_t *Group::vcpu_getClassName() { return L"Group"; } void Group::addObject(GuiObject *o) { addChild(o); } void Group::removeObject(GuiObject *o) { removeChild(o); } void Group::setRegionOp(int o) { GROUP_PARENT::setRegionOp(o); autoregionop = 0; } void Group::invalidateWindowRegion() { GROUP_PARENT::invalidateWindowRegion(); if (!isInited() || isLayout()) return ; if (autoregionop) { int yes = 0; for (int i = 0;i < gui_objects.getNumItems();i++) { if (gui_objects.enumItem(i)->guiobject_getRegionOp() != REGIONOP_NONE) { yes = 1; break; } } if (yes) GROUP_PARENT::setRegionOp(REGIONOP_OR); else GROUP_PARENT::setRegionOp(REGIONOP_NONE); } } // VCPU scriptVar Group::script_vcpu_onCreateObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar ob) { SCRIPT_FUNCTION_INIT; PROCESS_HOOKS1(o, groupController, ob); SCRIPT_FUNCTION_CHECKABORTEVENT; SCRIPT_EXEC_EVENT1(o, ob); } // Get an object from its ID scriptVar Group::script_vcpu_getObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj) { SCRIPT_FUNCTION_INIT ASSERT(obj.type == SCRIPT_STRING); // compiler discarded Group *g = static_cast(o->vcpu_getInterface(groupGuid)); GuiObject *ob = NULL; if (g) ob = g->getObject(GET_SCRIPT_STRING(obj)); return MAKE_SCRIPT_OBJECT(ob ? ob->guiobject_getScriptObject() : NULL); } scriptVar Group::script_vcpu_getMousePosX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { SCRIPT_FUNCTION_INIT Group *g = static_cast(o->vcpu_getInterface(groupGuid)); if (g) { POINT pt; Wasabi::Std::getMousePos(&pt); g->screenToClient(&pt); return MAKE_SCRIPT_INT(pt.x); } RETURN_SCRIPT_ZERO; } scriptVar Group::script_vcpu_getMousePosY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { SCRIPT_FUNCTION_INIT Group *g = static_cast(o->vcpu_getInterface(groupGuid)); if (g) { POINT pt; Wasabi::Std::getMousePos(&pt); g->screenToClient(&pt); return MAKE_SCRIPT_INT(pt.y); } RETURN_SCRIPT_ZERO; } scriptVar Group::script_vcpu_getNumObjects(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { SCRIPT_FUNCTION_INIT Group *g = static_cast(o->vcpu_getInterface(groupGuid)); if (g) return MAKE_SCRIPT_INT(g->getNumObjects()); RETURN_SCRIPT_ZERO; } scriptVar Group::script_vcpu_enumObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i) { SCRIPT_FUNCTION_INIT Group *g = static_cast(o->vcpu_getInterface(groupGuid)); GuiObject *obj = NULL; if (g) obj = g->gui_objects.enumItem(GET_SCRIPT_INT(i)); return MAKE_SCRIPT_OBJECT(obj ? obj->guiobject_getScriptObject() : NULL); } scriptVar Group::script_vcpu_isLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { SCRIPT_FUNCTION_INIT Group *g = static_cast(o->vcpu_getInterface(groupGuid)); return MAKE_SCRIPT_BOOLEAN(g ? g->isLayout() : NULL); } scriptVar Group::script_vcpu_autoResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { SCRIPT_FUNCTION_INIT Group *g = static_cast(o->vcpu_getInterface(groupGuid)); if (g != NULL) g->autoResize(); RETURN_SCRIPT_VOID } #ifdef WASABI_COMPILE_CONFIG int Group::isCfgGroup(Group *ptr) { CfgGroup *g = static_cast(ptr); return cfggrouplist.haveItem(g); } #endif PtrList Group::cfggrouplist; PtrList Group::groups; // --------------------------------------------------------------- // Config Groups #ifdef WASABI_COMPILE_CONFIG CfgGroup::CfgGroup() { getScriptObject()->vcpu_setInterface(cfgGroupGuid, (void *)static_cast(this)); getScriptObject()->vcpu_setClassName(L"CfgGroup"); getScriptObject()->vcpu_setController(cfgGroupController); cfgitem = NULL; cfggrouplist.addItem(this); } CfgGroup::~CfgGroup() { if (cfgitem) viewer_delViewItem(cfgitem); cfggrouplist.removeItem(this); } const wchar_t *CfgGroup::vcpu_getClassName() { return L"CfgGroup"; } void CfgGroup::setAttr(CfgItem *item, const wchar_t *name) { if (cfgitem) viewer_delViewItem(cfgitem); cfgitem = item; attrname = name; if (cfgitem != NULL) { wchar_t t[256] = L""; nsGUID::toCharW(cfgitem->getGuid(), t); cfgguid = t; } if (cfgitem) viewer_addViewItem(cfgitem); dataChanged(); } int CfgGroup::viewer_onEvent(CfgItem *item, int event, intptr_t param, void *ptr, size_t ptrlen) { dataChanged(); return 1; } int CfgGroup::onInit() { int r = Group::onInit(); dataChanged(); return r; } void CfgGroup::dataChanged() { script_vcpu_onCfgChanged(SCRIPT_CALL, getScriptObject()); } CfgItem *CfgGroup::getCfgItem() { return cfgitem; } const wchar_t *CfgGroup::getAttributeName() { return attrname; } scriptVar CfgGroup::script_vcpu_cfgGetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { SCRIPT_FUNCTION_INIT CfgGroup *cg = static_cast(o->vcpu_getInterface(cfgGroupGuid)); if (cg) { CfgItem *i = cg->getCfgItem(); const wchar_t *attrname = cg->getAttributeName(); if (o != NULL && attrname != NULL) return MAKE_SCRIPT_INT(i->getDataAsInt(attrname, 0)); } return MAKE_SCRIPT_INT(0); } scriptVar CfgGroup::script_vcpu_cfgSetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) { SCRIPT_FUNCTION_INIT ASSERT(SOM::isNumeric(&v)); CfgGroup *cg = static_cast(o->vcpu_getInterface(cfgGroupGuid)); if (cg) { CfgItem *i = cg->getCfgItem(); const wchar_t *attrname = cg->getAttributeName(); if (o != NULL && attrname != NULL) { i->setDataAsInt(attrname, GET_SCRIPT_INT(v)); } } RETURN_SCRIPT_VOID; } scriptVar CfgGroup::script_vcpu_cfgGetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { SCRIPT_FUNCTION_INIT CfgGroup *cg = static_cast(o->vcpu_getInterface(cfgGroupGuid)); if (cg) { CfgItem *i = cg->getCfgItem(); const wchar_t *a = cg->getAttributeName(); *txt = 0; if (!i || !a) return MAKE_SCRIPT_STRING(txt); if (o != NULL && a != NULL) { i->getData(a, txt, 512); } return MAKE_SCRIPT_STRING(txt); } return MAKE_SCRIPT_STRING(L""); } scriptVar CfgGroup::script_vcpu_cfgSetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) { SCRIPT_FUNCTION_INIT ASSERT(!SOM::isNumeric(&v)); CfgGroup *cg = static_cast(o->vcpu_getInterface(cfgGroupGuid)); if (cg) { CfgItem *i = cg->getCfgItem(); const wchar_t *a = cg->getAttributeName(); if (!i || !a) RETURN_SCRIPT_VOID; if (o != NULL && a != NULL) { i->setData(a, GET_SCRIPT_STRING(v)); } } RETURN_SCRIPT_VOID; } scriptVar CfgGroup::script_vcpu_cfgGetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { SCRIPT_FUNCTION_INIT CfgGroup *cg = static_cast(o->vcpu_getInterface(cfgGroupGuid)); if (cg) { CfgItem *i = cg->getCfgItem(); const wchar_t *attrname = cg->getAttributeName(); if (o != NULL && attrname != NULL) return MAKE_SCRIPT_FLOAT((float)i->getDataAsFloat(attrname, 0)); } return MAKE_SCRIPT_FLOAT(0); } scriptVar CfgGroup::script_vcpu_cfgSetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) { SCRIPT_FUNCTION_INIT ASSERT(SOM::isNumeric(&v)); CfgGroup *cg = static_cast(o->vcpu_getInterface(cfgGroupGuid)); if (cg) { CfgItem *i = cg->getCfgItem(); const wchar_t *attrname = cg->getAttributeName(); if (o != NULL && attrname != NULL) { i->setDataAsFloat(attrname, GET_SCRIPT_FLOAT(v)); } } RETURN_SCRIPT_VOID; } scriptVar CfgGroup::script_vcpu_cfgGetName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { SCRIPT_FUNCTION_INIT CfgGroup *cg = static_cast(o->vcpu_getInterface(cfgGroupGuid)); if (cg) { return MAKE_SCRIPT_STRING(cg->getAttributeName()); } return MAKE_SCRIPT_STRING(L""); } scriptVar CfgGroup::script_vcpu_cfgGetGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { SCRIPT_FUNCTION_INIT CfgGroup *cg = static_cast(o->vcpu_getInterface(cfgGroupGuid)); if (cg) return MAKE_SCRIPT_STRING(cg->getCfgGuid()); return MAKE_SCRIPT_STRING(L""); } scriptVar CfgGroup::script_vcpu_onCfgChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { SCRIPT_FUNCTION_INIT; PROCESS_HOOKS0(o, cfgGroupController); SCRIPT_FUNCTION_CHECKABORTEVENT; SCRIPT_EXEC_EVENT0(o); } CfgGroupScriptController _cfgGroupController; CfgGroupScriptController *cfgGroupController = &_cfgGroupController; // -- Functions table ------------------------------------- function_descriptor_struct CfgGroupScriptController::exportedFunction[] = { {L"cfgGetInt", 0, (void*)CfgGroup::script_vcpu_cfgGetInt }, {L"cfgSetInt", 1, (void*)CfgGroup::script_vcpu_cfgSetInt }, {L"cfgGetFloat", 0, (void*)CfgGroup::script_vcpu_cfgGetFloat }, {L"cfgSetFloat", 1, (void*)CfgGroup::script_vcpu_cfgSetFloat }, {L"cfgGetString", 0, (void*)CfgGroup::script_vcpu_cfgGetString }, {L"cfgSetString", 1, (void*)CfgGroup::script_vcpu_cfgSetString }, {L"onCfgChanged", 0, (void*)CfgGroup::script_vcpu_onCfgChanged }, {L"cfgGetName", 0, (void*)CfgGroup::script_vcpu_cfgGetName }, {L"cfgGetGuid", 0, (void*)CfgGroup::script_vcpu_cfgGetGuid}, }; /*SET_HIERARCHY(Group, SCRIPT_LAYOUT); SET_HIERARCHY2(Group, SCRIPT_LAYOUT, LAYOUT_SCRIPTPARENT);*/ const wchar_t *CfgGroupScriptController::getClassName() { return L"CfgGroup"; } const wchar_t *CfgGroupScriptController::getAncestorClassName() { return L"Group"; } int CfgGroupScriptController::getInstantiable() { return 1; } ScriptObject *CfgGroupScriptController::instantiate() { return NULL; } int CfgGroupScriptController::getNumFunctions() { return sizeof(exportedFunction) / sizeof(function_descriptor_struct); } const function_descriptor_struct *CfgGroupScriptController::getExportedFunctions() { return exportedFunction; } GUID CfgGroupScriptController::getClassGuid() { return cfgGroupGuid; } wchar_t CfgGroup::txt[512] = L""; #endif // config