aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/api/wndmgr
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/api/wndmgr')
-rw-r--r--Src/Wasabi/api/wndmgr/alphamgr.cpp661
-rw-r--r--Src/Wasabi/api/wndmgr/alphamgr.h136
-rw-r--r--Src/Wasabi/api/wndmgr/animate.cpp96
-rw-r--r--Src/Wasabi/api/wndmgr/animate.h11
-rw-r--r--Src/Wasabi/api/wndmgr/api_wndmgr.cpp47
-rw-r--r--Src/Wasabi/api/wndmgr/api_wndmgr.h305
-rw-r--r--Src/Wasabi/api/wndmgr/appcmds.cpp61
-rw-r--r--Src/Wasabi/api/wndmgr/appcmds.h89
-rw-r--r--Src/Wasabi/api/wndmgr/autopopup.cpp157
-rw-r--r--Src/Wasabi/api/wndmgr/autopopup.h76
-rw-r--r--Src/Wasabi/api/wndmgr/container.cpp919
-rw-r--r--Src/Wasabi/api/wndmgr/container.h231
-rw-r--r--Src/Wasabi/api/wndmgr/gc.cpp24
-rw-r--r--Src/Wasabi/api/wndmgr/gc.h19
-rw-r--r--Src/Wasabi/api/wndmgr/guistatuscb.cpp15
-rw-r--r--Src/Wasabi/api/wndmgr/guistatuscb.h83
-rw-r--r--Src/Wasabi/api/wndmgr/layout.cpp2586
-rw-r--r--Src/Wasabi/api/wndmgr/layout.h465
-rw-r--r--Src/Wasabi/api/wndmgr/msgbox.cpp251
-rw-r--r--Src/Wasabi/api/wndmgr/msgbox.h49
-rw-r--r--Src/Wasabi/api/wndmgr/resize.cpp383
-rw-r--r--Src/Wasabi/api/wndmgr/resize.h48
-rw-r--r--Src/Wasabi/api/wndmgr/skinembed.cpp733
-rw-r--r--Src/Wasabi/api/wndmgr/skinembed.h76
-rw-r--r--Src/Wasabi/api/wndmgr/skinwnd.cpp99
-rw-r--r--Src/Wasabi/api/wndmgr/skinwnd.h42
-rw-r--r--Src/Wasabi/api/wndmgr/snappnt.cpp181
-rw-r--r--Src/Wasabi/api/wndmgr/snappnt.h49
-rw-r--r--Src/Wasabi/api/wndmgr/wndmgrapi.cpp279
-rw-r--r--Src/Wasabi/api/wndmgr/wndmgrapi.h59
30 files changed, 8230 insertions, 0 deletions
diff --git a/Src/Wasabi/api/wndmgr/alphamgr.cpp b/Src/Wasabi/api/wndmgr/alphamgr.cpp
new file mode 100644
index 00000000..0bcf7fe0
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/alphamgr.cpp
@@ -0,0 +1,661 @@
+#include <precomp.h>
+#include "alphamgr.h"
+#include <api/wndmgr/layout.h>
+#include <api/skin/skinparse.h>
+#ifdef _WIN32
+#include <tataki/blending/blending.h>
+#endif
+#include <bfc/util/profiler.h>
+#include <bfc/wasabi_std_wnd.h>
+
+#ifndef PI
+#define PI 3.1415926536
+#endif
+
+#define ALPHAMGR_HOVERCHECK 100
+#define ALPHAMGR_UPDATEALPHA 200
+
+AlphaMgr::AlphaMgr() {
+ overlayout = NULL;
+ timerclient_setTimer(ALPHAMGR_HOVERCHECK, 200);
+ alllinked = 0;
+ autoopacify = 0;
+ fast_timer_on = 0;
+ big_curtransparency = 0;
+ big_status = STATUS_UNKNOWN;
+ big_startalpha = 0;
+ big_lasttimein = 0;
+ extend_px = 0;
+ global_alpha = 0;
+ big_enterleave_time = 0;
+ fadein_ms = 1;
+ fadeout_ms = 1;
+ holdtime_ms = 1;
+}
+
+AlphaMgr::~AlphaMgr()
+{
+ timerclient_killTimer(ALPHAMGR_HOVERCHECK);
+}
+
+void AlphaMgr::addLayout(Layout *l)
+{
+ checkTimer();
+
+ if (layouts.findItem((const wchar_t *)l))
+ return;
+
+ layouts.addItem(new AlphaMgrEntry(l));
+}
+
+void AlphaMgr::removeLayout(Layout *l) {
+ int p=-1;
+ AlphaMgrEntry *e = layouts.findItem((const wchar_t *)l, &p);
+ if (p != -1) {
+ if (e->getStatus() == STATUS_IN_FADINGON || e->getStatus() == STATUS_IN_ON) {
+ updateInList(e, 0);
+ checkTimer();
+ }
+ layouts.removeByPos(p);
+ in_layouts.removeItem(e);
+ delete e;
+ checkTimer();
+ }
+}
+
+// gets the currently needed transparency, according to layout overrides and global link, and then applies this
+// transparency to the layout, it does not change anything in any data structure, this is only a visual update function
+void AlphaMgr::updateTransparency(Layout *l) {
+ if (!l) return;
+ if (l->isInited()) {
+ if (l->isTransparencySafe()) {
+ int a = l->getTransparencyOverride();
+ if (a == -1) {
+ if (l->getNoParent()!=1) {
+ if (a == -1 && hasAutoOpacity(l))
+ a = getTransparency(l);
+ else if (a == -1 && getAllLinked())
+ a = getGlobalAlpha();
+ }
+ if (a == -1) {
+ /* why the hell would it care if it's alllinked if it's an independent window ?? (noparent=1)
+ if (getAllLinked())
+ a = getGlobalAlpha();
+ else
+ */
+ a = l->getPaintingAlpha();
+ }
+ }
+ l->setTransparency(a);
+ } else {
+ l->setTransparency(255);
+ }
+ }
+}
+
+// returns the alpha value for this slot, that's not necessarily the transparency that should be applied to the layout
+// since overrides & calculations in updateTransparency and getTransparency should apply.
+int AlphaMgr::getAlpha(AlphaMgrEntry *e) {
+ if (alllinked && e->getLayout()->getNoParent() != 1) return getGlobalAlpha();
+ return e->getLayout()->getAlpha();
+}
+
+int AlphaMgr::getAlpha(Layout *l) {
+ int p=-1;
+ AlphaMgrEntry *e = layouts.findItem((const wchar_t *)l, &p);
+ if (p != -1) return getAlpha(e);
+ return l->getAlpha();
+}
+
+int AlphaMgr::getGlobalAlpha() {
+ return global_alpha;
+}
+
+void AlphaMgr::updateAllTransparency() {
+ foreach(layouts)
+ updateTransparency(layouts.getfor()->getLayout());
+ endfor;
+}
+
+void AlphaMgr::setGlobalAlpha(int a) {
+ global_alpha = a;
+ updateAllTransparency();
+}
+
+int AlphaMgr::getCurve(AlphaMgrEntry *e) {
+ int n;
+ int status = e ? e->getStatus() : getBigStatus();
+ if (e == NULL) {
+ n = MulDiv(Wasabi::Std::getTickCount()-getBigEnterLeaveTime(),256,status == STATUS_IN_FADINGON ? fadein_ms : fadeout_ms);
+ if (n > 255) n = 255; if (n < 0) n = 0;
+ } else {
+ if (e->getEnterLeaveTime() == -1) return -1;
+ n = MulDiv(Wasabi::Std::getTickCount()-e->getEnterLeaveTime(),256,status == STATUS_IN_FADINGON ? fadein_ms : fadeout_ms);
+ if (n > 255) n = 255; if (n < 0) n = 0;
+ }
+ return n;
+}
+
+// returns the value of the transparency if no override applies, you still need to check overrides (see updatetransparency)
+int AlphaMgr::getTransparency(Layout *l) {
+ if (getAutoOpacify())
+ l = NULL;
+ if (l == NULL) {
+ if (getBigStatus() == STATUS_UNKNOWN) {
+ setBigStatus(STATUS_OUT_OFF);
+ Layout *main = SkinParser::getMainLayout();
+ if (main)
+ big_curtransparency = main->getTransparency();
+ else
+ big_curtransparency = 255;
+ }
+ }
+ AlphaMgrEntry *e = NULL;
+ if (l) e = layouts.findItem((const wchar_t *)l);
+ int s = e ? e->getStatus() : getBigStatus();
+ if (e && s == STATUS_UNKNOWN) {
+ initStatus(e);
+ s = e->getStatus();
+ }
+ switch (s) {
+ case STATUS_IN_OFF: return e ? getAlpha(e) : getGlobalAlpha();
+ case STATUS_OUT_OFF: return e ? getAlpha(e) : getGlobalAlpha();
+ case STATUS_IN_ON: return 255;
+ case STATUS_OUT_FADINGOUT: {
+ int n = e ? getCurve(e) : getCurve(NULL);
+ float sintrans = (float)(sin(((float)n/255)*PI-PI/2)/2+0.5);
+ int na;
+ if (e)
+ na = (int)(((float)(getAlpha(e) - e->getStartAlpha()) * sintrans) + e->getStartAlpha());
+ else
+ na = (int)(((float)(getGlobalAlpha() - getBigStartAlpha()) * sintrans) + getBigStartAlpha());
+ return na;
+ }
+ case STATUS_IN_FADINGON: {
+ int n = e ? getCurve(e) : getCurve(NULL);
+ float sintrans = (float)(sin(((float)n/255)*PI-PI/2)/2+0.5);
+ int na;
+ if (e)
+ na = (int)(((float)(255 - e->getStartAlpha()) * sintrans) + e->getStartAlpha());
+ else
+ na = (int)(((float)(255 - getBigStartAlpha()) * sintrans) + getBigStartAlpha());
+ return na;
+ }
+ default: return e ? getAlpha(e) : getGlobalAlpha();
+ }
+}
+
+int AlphaMgr::hasAutoOpacityOnHover(Layout *l) {
+ AlphaMgrEntry *e = layouts.findItem((const wchar_t *)l);
+ if (e) return hasAutoOpacityOnHover(e);
+ return 0;
+}
+
+int AlphaMgr::hasAutoOpacity(Layout *l) {
+ AlphaMgrEntry *e = layouts.findItem((const wchar_t *)l);
+ if (e) return hasAutoOpacity(e);
+ return 0;
+}
+
+int AlphaMgr::hasAutoOpacityOnFocus(Layout *l) {
+ AlphaMgrEntry *e = layouts.findItem((const wchar_t *)l);
+ if (e) return hasAutoOpacityOnFocus(e);
+ return 0;
+}
+
+int AlphaMgr::hasAutoOpacityOnFocus(AlphaMgrEntry *e) {
+ if (alllinked) return autoopacify == 2;
+ return e->getLayout()->getAutoOpacify() == 2 && e->getLayout()->getNoParent() != 1;
+}
+
+int AlphaMgr::hasAutoOpacityOnHover(AlphaMgrEntry *e) {
+ if (alllinked) return autoopacify == 1;
+ return e->getLayout()->getAutoOpacify() == 1 && e->getLayout()->getNoParent() != 1;
+}
+
+int AlphaMgr::hasAutoOpacity(AlphaMgrEntry *e) {
+ if (alllinked) return autoopacify;
+ return e->getLayout()->getAutoOpacify() && e->getLayout()->getNoParent() != 1;
+}
+
+// we got a new layout to manage, and its status flags is not set, we should init it to something safe
+void AlphaMgr::initStatus(AlphaMgrEntry *l, int applytransparency) {
+ if (isMouseInLayout(l->getLayout())) {
+ l->setEnterLeaveTime((uint32_t)-1);
+ if (hasAutoOpacity(l)) {
+ l->setStatus(STATUS_IN_FADINGON);
+ l->onEnterLeave();
+ l->setStartAlpha(l->getLayout()->getTransparency());
+ checkTimer();
+ } else {
+ l->setStatus(STATUS_IN_OFF);
+ }
+ l->getLayout()->onMouseEnterLayout();
+ } else {
+ if (hasAutoOpacityOnHover(l)) {
+ l->setStartAlpha(l->getLayout()->getTransparency());
+ l->onEnterLeave();
+ l->setStatus(STATUS_OUT_FADINGOUT);
+ checkTimer();
+ } else {
+ l->setStatus(STATUS_OUT_OFF);
+ }
+ l->getLayout()->onMouseLeaveLayout();
+ }
+ if (applytransparency) updateTransparency(l->getLayout());
+}
+
+int AlphaMgr::isPointInLayout(Layout *l, int x, int y, api_region **rgn)
+{
+ api_region *rg = NULL;
+ if (!l) return 0;
+ if (!l->isVisible()) return 0;
+ RECT r,r2;
+ l->getClientRect(&r);
+ if (l->renderRatioActive()) l->multRatio(&r);
+ l->getWindowRect(&r2);
+ Wasabi::Std::offsetRect(&r, r2.left, r2.top);
+// OffsetRect(&r, r2.left, r2.top);
+ if (x < r.left || x > r.right || y < r.top || y > r.bottom) return 0;
+ if (rgn) {
+ if (!*rgn) {
+ rg = l->getComposedRegion();
+ *rgn = rg;
+ } else {
+ rg = *rgn;
+ }
+ } else {
+ rg = l->getComposedRegion();
+ }
+ if (!rgn) return 1;
+ x -= r.left; y -= r.top;
+ POINT pt={x,y};
+ if (l->renderRatioActive()) l->divRatio((int*)&pt.x, (int*)&pt.y);
+ if (l->getComposedRegion()->ptInRegion(&pt)) return 1;
+ return 0;
+}
+
+int AlphaMgr::isFocusInLayout(Layout *l) {
+ if (l->gotFocus()) return 1;
+ OSWINDOWHANDLE fw = Wasabi::Std::Wnd::getFocus();
+ while (fw)
+ {
+ if (fw == l->gethWnd()) return 1;
+ fw = Wasabi::Std::Wnd::getParent(fw);
+ }
+ return 0;
+}
+
+int AlphaMgr::isMouseInLayout(Layout *l) {
+ int isin = 0;
+ if (hasAutoOpacityOnFocus(l)) {
+ return isFocusInLayout(l);
+ } else {
+ int x, y;
+ api_region *r = NULL;
+ Wasabi::Std::getMousePos(&x, &y);
+ isin = isPointInLayout(l, x, y, &r);
+ int ext = getExtendAutoOpacity();
+ if (!isin && ext > 0) {
+ isin = isPointInLayout(l, x-ext, y, &r);
+ if (!isin) isin = isPointInLayout(l, x-ext, y-ext, &r);
+ if (!isin) isin = isPointInLayout(l, x, y-ext, &r);
+ if (!isin) isin = isPointInLayout(l, x+ext, y-ext, &r);
+ if (!isin) isin = isPointInLayout(l, x+ext, y, &r);
+ if (!isin) isin = isPointInLayout(l, x+ext, y+ext, &r);
+ if (!isin) isin = isPointInLayout(l, x, y+ext, &r);
+ if (!isin) isin = isPointInLayout(l, x-ext, y+ext, &r);
+ if (!isin) isin = isPointInLayout(l, x-ext, y, &r);
+ }
+ }
+ return isin;
+}
+
+int AlphaMgr::needForcedTransparencyFlag(Layout *l) {
+ if (!l->isTransparencySafe()) return 0;
+ if (l->isAlphaForced()) return 1;
+ if (l->getTransparencyOverride() > 0) return 1; // should not be testing for < 255 here
+ AlphaMgrEntry *e = layouts.findItem((const wchar_t *)l);
+ if (hasAutoOpacity(e) && getAlpha(e) < 255) return 1;
+ return 0;
+}
+
+void AlphaMgr::checkTimer() {
+ int fading = 0;
+ foreach(layouts)
+ AlphaMgrEntry *e = layouts.getfor();
+ if (e->getStatus() == STATUS_IN_FADINGON || e->getStatus() == STATUS_OUT_FADINGOUT) { fading++; break; }
+ endfor;
+ if (getAutoOpacify() && getBigStatus() == STATUS_IN_FADINGON || getBigStatus() == STATUS_OUT_FADINGOUT)
+ fading++;
+ if (fading && !fast_timer_on) {
+ timerclient_setTimer(ALPHAMGR_UPDATEALPHA, 20);
+ fast_timer_on = 1;
+ } else if (!fading && fast_timer_on) {
+ timerclient_killTimer(ALPHAMGR_UPDATEALPHA);
+ fast_timer_on = 0;
+ }
+}
+
+void AlphaMgr::doEndCheck(AlphaMgrEntry *e) {
+ if (getCurve(e) == 255) {
+ switch (e ? e->getStatus() : getBigStatus()) {
+ case STATUS_IN_FADINGON:
+ if (e) e->setStatus(STATUS_IN_ON); else setBigStatus(STATUS_IN_ON);
+ break;
+ case STATUS_OUT_FADINGOUT:
+ if (e) e->setStatus(STATUS_OUT_OFF); else setBigStatus(STATUS_OUT_OFF);
+ break;
+ }
+ checkTimer();
+ }
+}
+
+void AlphaMgr::updateInList(AlphaMgrEntry *e, int isin) {
+ if (isin) {
+ if (in_layouts.searchItem(e) == -1)
+ in_layouts.addItem(e);
+ } else {
+ in_layouts.removeItem(e);
+ }
+
+ int big_isin = in_layouts.getNumItems() > 0;
+
+ if (getAutoOpacify()) {
+ if (big_isin) {
+ // mouse is in a layout, autoopacity is on
+ switch (getBigStatus()) {
+ case STATUS_OUT_OFF:
+ case STATUS_OUT_FADINGOUT:
+ case STATUS_IN_OFF: {
+ setBigStartAlpha(e->getLayout()->getTransparency());
+ onBigEnterLeave();
+ setBigStatus(STATUS_IN_FADINGON);
+ checkTimer();
+ break;
+ }
+ case STATUS_IN_FADINGON:
+ doEndCheck(NULL);
+ break;
+ }
+ } else {
+ // mouse out of all layouts, autoopacity is on
+ switch (getBigStatus()) {
+ case STATUS_IN_FADINGON:
+ case STATUS_IN_ON: {
+ setBigStartAlpha(getTransparency(NULL));
+ onBigEnterLeave();
+ setBigStatus(STATUS_OUT_FADINGOUT);
+ checkTimer();
+ break;
+ }
+ case STATUS_OUT_FADINGOUT:
+ doEndCheck(NULL);
+ break;
+ }
+ }
+ } else {
+ if (big_isin) {
+ // mouse is in a layout, no autoopacity
+ setBigStatus(STATUS_IN_OFF);
+ } else {
+ // mouse is out of all layouts, no autoopacity
+ setBigStatus(STATUS_OUT_OFF);
+ }
+ }
+}
+
+int AlphaMgr::isFocusingExternalWindow()
+{
+ OSWINDOWHANDLE fw = Wasabi::Std::Wnd::getFocus();
+ if (isOurExternalWindow(fw)) return 1;
+ return 0;
+}
+
+int AlphaMgr::isOverExternalWindow()
+{
+ int x, y;
+ Wasabi::Std::getMousePos(&x, &y);
+ int ext = getExtendAutoOpacity();
+
+ POINT pt;
+ pt.x = x; pt.y = y;
+ OSWINDOWHANDLE w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x-ext; pt.y = y-ext;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x; pt.y = y-ext;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x+ext; pt.y = y-ext;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x+ext; pt.y = y;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x+ext; pt.y = y+ext;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x; pt.y = y+ext;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x-ext; pt.y = y+ext;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x-ext; pt.y = y;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ return 0;
+}
+
+int AlphaMgr::isWasabiWindow(OSWINDOWHANDLE w)
+{
+#ifdef _WIN32
+ wchar_t classname[256]=L"";
+ GetClassNameW(w, classname, 255);
+ return (w == WASABI_API_WND->main_getRootWnd()->gethWnd() || !wcscmp(classname, BASEWNDCLASSNAME));
+#else
+#warning port me
+ return 1;
+#endif
+}
+
+int AlphaMgr::isMenuWindow(OSWINDOWHANDLE w)
+{
+#ifdef _WIN32
+ char classname[256]="";
+ GetClassNameA(w, classname, 255);
+ return STRCASEEQL(classname, "#32768");
+#else
+ return 0;
+#warning port me
+#endif
+}
+
+int AlphaMgr::isOurExternalWindow(OSWINDOWHANDLE w)
+{
+ OSWINDOWHANDLE wnd = w;
+ if (isWasabiWindow(w))
+ return 0;
+
+ if (isMenuWindow(wnd)) {
+ wnd = Wasabi::Std::Wnd::getFocus();
+ if (isWasabiWindow(wnd) || isOurExternalWindow(wnd))
+ return 1;
+ }
+
+ while (wnd)
+ {
+ if (Wasabi::Std::Wnd::isPopup(wnd))
+ {
+ if (isWasabiWindow(wnd))
+ return 0;
+ OSWINDOWHANDLE _w = Wasabi::Std::Wnd::getParent(wnd);
+#ifdef _WIN32
+ if (!_w) _w = GetWindow(wnd, GW_OWNER);
+#else
+#warning port me
+#endif
+ if (!wnd) _w = wnd;
+ return (_w == WASABI_API_WND->main_getRootWnd()->gethWnd() || isWasabiWindow(_w) || isOurExternalWindow(_w));
+ }
+ wnd = Wasabi::Std::Wnd::getParent(wnd);
+ }
+ return 0;
+}
+
+void AlphaMgr::preHoverCheck(AlphaMgrEntry *e) {
+ int isin = isMouseInLayout(e->getLayout());
+ uint32_t last = e->getLastTimeIn();
+ uint32_t lastbig = getBigLastTimeIn();
+ if (isin) { e->onLastIn(); onBigLastIn(); }
+ if (!getAutoOpacify()) {
+ if (!isin && last != 0 && (last > Wasabi::Std::getTickCount() - holdtime_ms))
+ isin = 1;
+ } else {
+ if (!isin && lastbig != 0 && (lastbig > Wasabi::Std::getTickCount() - holdtime_ms))
+ isin = 1;
+ }
+ if (!isin) {
+ if (hasAutoOpacityOnFocus(e)) {
+ if (isFocusingExternalWindow()) isin = 1;
+ } else {
+ if (isOverExternalWindow()) isin = 1;
+ }
+ }
+ e->setNextIn(isin);
+ updateInList(e, isin);
+}
+
+void AlphaMgr::hoverCheck(Layout *l) {
+ AlphaMgrEntry *e = layouts.findItem((const wchar_t *)l);
+ if (e) hoverCheck(e);
+}
+
+void AlphaMgr::hoverCheck(AlphaMgrEntry *e, int applytransparency) {
+ if (e->getStatus() == STATUS_UNKNOWN)
+ initStatus(e);
+
+ int isin = e->getNextIn();
+
+ if (getAutoOpacify()) {
+ isin = big_status == STATUS_IN_FADINGON || big_status == STATUS_IN_ON || big_status == STATUS_IN_OFF;
+ }
+ if (hasAutoOpacity(e)) {
+ if (isin) {
+ // mouse is in, autoopacity is on
+ switch (e->getStatus()) {
+ case STATUS_OUT_OFF:
+ case STATUS_OUT_FADINGOUT:
+ case STATUS_IN_OFF:
+ e->setStartAlpha(e->getLayout()->getTransparency());
+ e->onEnterLeave();
+ e->setStatus(STATUS_IN_FADINGON);
+ checkTimer();
+ e->getLayout()->onMouseEnterLayout();
+ break;
+ case STATUS_IN_FADINGON:
+ doEndCheck(e);
+ break;
+ }
+ } else {
+ // mouse is out, autoopacity is on
+ switch (e->getStatus()) {
+ case STATUS_IN_FADINGON:
+ case STATUS_IN_ON:
+ e->setStartAlpha(e->getLayout()->getTransparency());
+ e->onEnterLeave();
+ e->setStatus(STATUS_OUT_FADINGOUT);
+ checkTimer();
+ e->getLayout()->onMouseLeaveLayout();
+ break;
+ case STATUS_OUT_FADINGOUT:
+ doEndCheck(e);
+ break;
+ }
+ }
+ } else {
+ if (isin) {
+ // mouse is in, no autoopacity
+ e->setStatus(STATUS_IN_OFF);
+ } else {
+ // mouse is out, no autoopacity
+ e->setStatus(STATUS_OUT_OFF);
+ }
+ }
+// if (applytransparency) updateTransparency(e->getLayout());
+}
+
+void AlphaMgr::timerclient_timerCallback(int id) {
+ switch(id) {
+ case ALPHAMGR_HOVERCHECK: {
+ foreach(layouts)
+ AlphaMgrEntry *e = layouts.getfor();
+ preHoverCheck(e);
+ endfor;
+ foreach(layouts)
+ AlphaMgrEntry *e = layouts.getfor();
+ hoverCheck(e);
+ endfor;
+ }
+ break;
+ case ALPHAMGR_UPDATEALPHA: {
+ foreach(layouts)
+ AlphaMgrEntry *e = layouts.getfor();
+ if (e->getStatus() == STATUS_IN_FADINGON || e->getStatus() == STATUS_OUT_FADINGOUT) updateTransparency(e->getLayout());
+ endfor;
+ }
+ break;
+ }
+}
+
+int AlphaMgr::getBigCurTransparency() {
+ switch (getBigStatus()) {
+ case STATUS_IN_FADINGON:
+ case STATUS_OUT_FADINGOUT:
+ return getTransparency(NULL);
+ case STATUS_IN_ON:
+ return 255;
+ case STATUS_IN_OFF:
+ case STATUS_OUT_OFF:
+ return getGlobalAlpha();
+ default: return getTransparency(NULL);
+ }
+}
+
+void AlphaMgr::setBigStartAlpha(int a) {
+ big_startalpha = a;
+}
+
+void AlphaMgr::setBigStatus(int s) {
+ big_status = s;
+}
+
+void AlphaMgr::onBigEnterLeave() {
+ big_enterleave_time = Wasabi::Std::getTickCount();
+}
+
+uint32_t AlphaMgr::getBigEnterLeaveTime() {
+ return big_enterleave_time;
+}
+
+void AlphaMgr::setAutoOpacify(int l) {
+ autoopacify = l;
+ resetTimer();
+ if (l == 0) {
+ foreach(layouts)
+ if (layouts.getfor()->getStatus() == STATUS_IN_FADINGON) layouts.getfor()->setStatus(STATUS_IN_OFF);
+ if (layouts.getfor()->getStatus() == STATUS_OUT_FADINGOUT) layouts.getfor()->setStatus(STATUS_OUT_OFF);
+ endfor;
+ }
+ updateAllTransparency();
+}
+
+void AlphaMgr::resetTimer() {
+ timerclient_killTimer(ALPHAMGR_HOVERCHECK);
+ if (autoopacify == 1 && alllinked)
+ timerclient_setTimer(ALPHAMGR_HOVERCHECK, 99);
+ else
+ timerclient_setTimer(ALPHAMGR_HOVERCHECK, 300);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/wndmgr/alphamgr.h b/Src/Wasabi/api/wndmgr/alphamgr.h
new file mode 100644
index 00000000..240485dd
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/alphamgr.h
@@ -0,0 +1,136 @@
+#ifndef _ALPHAMGR_H
+#define _ALPHAMGR_H
+
+#include <api/timer/timerclient.h>
+
+class Layout;
+
+#define STATUS_UNKNOWN -1
+#define STATUS_OUT_OFF 0
+#define STATUS_IN_ON 1
+#define STATUS_OUT_FADINGOUT 2
+#define STATUS_IN_FADINGON 3
+#define STATUS_IN_OFF 4 // when no autoopacity
+
+class AlphaMgrEntry {
+ public:
+ AlphaMgrEntry(Layout *l) : layout(l), status(STATUS_UNKNOWN), fade_val(-1), startalpha(-1), lasttime_in(0), next_in(-1) {}
+ virtual ~AlphaMgrEntry() { }
+
+ Layout *getLayout() { return layout; }
+ int getStatus() { return status; }
+
+ void onEnterLeave() { enterleave_time = Wasabi::Std::getTickCount(); }
+ int getEnterLeaveTime() { return enterleave_time; }
+ void setEnterLeaveTime(uint32_t t) { enterleave_time = t; }
+ void setStatus(int s) { status = s; }
+ int getStartAlpha() { return startalpha; }
+ void setStartAlpha(int s) { startalpha = s; }
+ uint32_t getLastTimeIn() { return lasttime_in; }
+ void onLastIn() { lasttime_in = Wasabi::Std::getTickCount(); }
+ void setNextIn(int i) { next_in = i; }
+ int getNextIn() { return next_in; }
+
+ private:
+ Layout *layout;
+ int status;
+ int fade_val;
+ uint32_t enterleave_time;
+ int startalpha;
+ uint32_t lasttime_in;
+ int next_in;
+};
+
+class AlphaMgrEntryComparator {
+public:
+ static int compareItem(AlphaMgrEntry *p1, AlphaMgrEntry* p2) {
+ return CMP3((void*)p1->getLayout(), (void *)p2->getLayout());
+ }
+ static int compareAttrib(const wchar_t *attrib, AlphaMgrEntry *item) {
+ return CMP3((void *)attrib, (void *)item->getLayout());
+ }
+};
+
+class AlphaMgr : public TimerClientDI {
+ public:
+ AlphaMgr();
+ virtual ~AlphaMgr();
+
+ void addLayout(Layout *l);
+ void removeLayout(Layout *l);
+
+ virtual void timerclient_timerCallback(int id);
+
+ void updateTransparency(Layout *l);
+ int getTransparency(Layout *l);
+ int getGlobalAlpha();
+ void setGlobalAlpha(int a);
+ int isFocusInLayout(Layout *l);
+ int isMouseInLayout(Layout *l);
+ int isPointInLayout(Layout *l, int x, int y, api_region **rgn=NULL);
+ int needForcedTransparencyFlag(Layout *l);
+ int hasAutoOpacity(Layout *l);
+ int hasAutoOpacityOnHover(Layout *l);
+ int hasAutoOpacityOnFocus(Layout *l);
+
+ void setAllLinked(int l) { alllinked = l; resetTimer(); updateAllTransparency(); }
+ void setAutoOpacify(int l);
+ int getAllLinked() { return alllinked; }
+ int getAutoOpacify() { return (autoopacify && alllinked) ? autoopacify : 0; }
+ void setExtendAutoOpacity(int n) { extend_px = n; }
+ int getExtendAutoOpacity() { return extend_px; }
+ int getBigCurTransparency();
+
+ void setFadeInTime(int ms) { fadein_ms = MAX(ms, 1); }
+ void setFadeOutTime(int ms) { fadeout_ms = MAX(ms, 1); }
+ void setHoldTime(int ms) { holdtime_ms = ms; }
+ void hoverCheck(Layout *l);
+ int getAlpha(Layout *l);
+
+ private:
+ void updateAllTransparency();
+ void updateInList(AlphaMgrEntry *e, int isin);
+ void setBigStartAlpha(int a);
+ int getBigStartAlpha() { return big_startalpha; }
+ void onBigEnterLeave();
+ uint32_t getBigEnterLeaveTime();
+ void setBigStatus(int s);
+ int getBigStatus() { return big_status; }
+ void initStatus(AlphaMgrEntry *e, int applytransparency=0);
+ int getAlpha(AlphaMgrEntry *e);
+ int hasAutoOpacityOnHover(AlphaMgrEntry *e);
+ int hasAutoOpacityOnFocus(AlphaMgrEntry *e);
+ int hasAutoOpacity(AlphaMgrEntry *e);
+ void checkTimer();
+ void hoverCheck(AlphaMgrEntry *e, int applytransparency=1);
+ void preHoverCheck(AlphaMgrEntry *e);
+ int getCurve(AlphaMgrEntry *e);
+ void doEndCheck(AlphaMgrEntry *e);
+ void onBigLastIn() { big_lasttimein = Wasabi::Std::getTickCount(); }
+ uint32_t getBigLastTimeIn() { return big_lasttimein; }
+ int isFocusingExternalWindow();
+ int isOverExternalWindow();
+ int isOurExternalWindow(OSWINDOWHANDLE w);
+ int isWasabiWindow(OSWINDOWHANDLE w);
+ int isMenuWindow(OSWINDOWHANDLE w);
+ void resetTimer();
+
+ PtrListQuickSorted<AlphaMgrEntry, AlphaMgrEntryComparator> layouts;
+ PtrListQuickSortedByPtrVal<AlphaMgrEntry> in_layouts;
+ Layout *overlayout;
+ int alllinked;
+ int autoopacify;
+ int global_alpha;
+ int fast_timer_on;
+ int big_status;
+ int big_curtransparency;
+ int big_startalpha;
+ uint32_t big_enterleave_time;
+ int big_lasttimein;
+ int fadein_ms;
+ int fadeout_ms;
+ int holdtime_ms;
+ int extend_px;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/animate.cpp b/Src/Wasabi/api/wndmgr/animate.cpp
new file mode 100644
index 00000000..c5f789b7
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/animate.cpp
@@ -0,0 +1,96 @@
+#include <precomp.h>
+#include <wasabicfg.h>
+#include "animate.h"
+
+#include <api/config/items/cfgitem.h>
+
+//---------------------------------------------------------------------------
+void AnimatedRects::draw(const RECT *source, const RECT *dest, int steps)
+{
+#ifdef WASABI_COMPILE_CONFIG
+ // {280876CF-48C0-40bc-8E86-73CE6BB462E5}
+ const GUID options_guid =
+ { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
+ if (!_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid), L"Animated rects")) return;
+#else
+ if (!WASABI_WNDMGR_ANIMATEDRECTS) return;
+#endif
+
+ //FG> Not anymore, old code, old bugs
+ //BU you're so cool, Francis
+ //FG> thank you, you're not too bad either :)
+ int sizex=source->right-source->left-(dest->right-dest->left);
+ int sizey=source->bottom-source->top-(dest->bottom-dest->top);
+ int diffx=source->left-dest->left;
+ int diffy=(source->top)-dest->top;
+
+#ifdef WIN32
+ HDC dc;
+ dc=GetDC(0);
+ HBRUSH brush = CreateSolidBrush(0xFFFFFF);
+ HPEN pen = CreatePen(PS_SOLID,0,0xFFFFFF);
+ HBRUSH obrush = (HBRUSH)SelectObject(dc, brush);
+ HPEN open = (HPEN)SelectObject(dc, pen);
+ int oldrop = SetROP2(dc,R2_XORPEN);
+#endif
+#ifdef LINUX
+ HDC dc = (HDC)MALLOC( sizeof( hdc_typ ) );
+ XGCValues gcv;
+ gcv.foreground = 0xffffff;
+ gcv.function = GXxor;
+ gcv.subwindow_mode = IncludeInferiors;
+ dc->gc = XCreateGC( Linux::getDisplay(), Linux::RootWin(), GCForeground | GCFunction | GCSubwindowMode, &gcv );
+#endif
+//PORTME
+
+ for(int i=0;i<steps;i++) {
+ int x=dest->left+diffx-((diffx*i)/steps);
+ int y=dest->top+diffy-((diffy*i)/steps);
+ int maxx=(source->right-source->left)-((sizex*i)/steps);
+ int maxy=(source->bottom-source->top)-((sizey*i)/steps);
+
+#ifdef WIN32
+ int p1x=x,p1y=y;
+ int p2x=x+maxx,p2y=y;
+ int p3x=x+maxx,p3y=y+maxy;
+ int p4x=x,p4y=y+maxy;
+ MoveToEx(dc,p1x,p1y,NULL);
+ LineTo(dc,p2x,p2y);
+ LineTo(dc,p3x,p3y);
+ LineTo(dc,p4x,p4y);
+ LineTo(dc,p1x,p1y);
+#endif
+#ifdef LINUX
+ XDrawRectangle( Linux::getDisplay(), Linux::RootWin(), dc->gc,
+ x, y, maxx, maxy );
+#endif
+//PORTME
+ Wasabi::Std::usleep(5);
+#ifdef WIN32
+ MoveToEx(dc,p1x,p1y,NULL);
+ LineTo(dc,p2x,p2y);
+ LineTo(dc,p3x,p3y);
+ LineTo(dc,p4x,p4y);
+ LineTo(dc,p1x,p1y);
+#endif
+#ifdef LINUX
+ XDrawRectangle( Linux::getDisplay(), Linux::RootWin(), dc->gc,
+ x, y, maxx, maxy );
+#endif
+//PORTME
+ }
+#ifdef WIN32
+ SetROP2(dc, oldrop);
+ SelectObject(dc, open);
+ SelectObject(dc, obrush);
+ DeleteObject(brush);
+ DeleteObject(pen);
+ ReleaseDC(0,dc);
+#endif
+#ifdef LINUX
+ XFreeGC( Linux::getDisplay(), dc->gc );
+ FREE( dc );
+#endif
+//PORTME
+}
+
diff --git a/Src/Wasabi/api/wndmgr/animate.h b/Src/Wasabi/api/wndmgr/animate.h
new file mode 100644
index 00000000..23a98318
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/animate.h
@@ -0,0 +1,11 @@
+#ifndef _ANIMATE_H
+#define _ANIMATE_H
+
+#include <bfc/wasabi_std.h>
+
+class AnimatedRects {
+public:
+ static void draw(const RECT *src, const RECT *dst, int nsteps=5);
+};
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/api_wndmgr.cpp b/Src/Wasabi/api/wndmgr/api_wndmgr.cpp
new file mode 100644
index 00000000..c2206aeb
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/api_wndmgr.cpp
@@ -0,0 +1,47 @@
+#include <precomp.h>
+#include "api_wndmgr.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+#define CBCLASS wndmgr_apiI
+START_DISPATCH;
+ VCB(WNDMGR_API_WNDTRACKADD, wndTrackAdd);
+ VCB(WNDMGR_API_WNDTRACKREMOVE, wndTrackRemove);
+ CB(WNDMGR_API_WNDTRACKDOCK, wndTrackDock);
+ CB(WNDMGR_API_WNDTRACKDOCK2, wndTrackDock2);
+ VCB(WNDMGR_API_WNDTRACKSTARTCOOPERATIVE, wndTrackStartCooperative);
+ VCB(WNDMGR_API_WNDTRACKENDCOOPERATIVE, wndTrackEndCooperative);
+ CB(WNDMGR_API_WNDTRACKWASCOOPERATIVE, wndTrackWasCooperative);
+ VCB(WNDMGR_API_WNDTRACKINVALIDATEALL, wndTrackInvalidateAll);
+ CB(WNDMGR_API_SKINWND_TOGGLEBYGUID, skinwnd_toggleByGuid);
+ CB(WNDMGR_API_SKINWND_TOGGLEBYGROUPID, skinwnd_toggleByGroupId);
+ CB(WNDMGR_API_SKINWND_CREATEBYGUID, skinwnd_createByGuid);
+ CB(WNDMGR_API_SKINWND_CREATEBYGROUPID, skinwnd_createByGroupId);
+ VCB(WNDMGR_API_SKINWND_DESTROY, skinwnd_destroy);
+ CB(WNDMGR_API_SKINWND_GETNUMBYGUID, skinwnd_getNumByGuid);
+ CB(WNDMGR_API_SKINWND_ENUMBYGUID, skinwnd_enumByGuid);
+ CB(WNDMGR_API_SKINWND_GETNUMBYGROUPID, skinwnd_getNumByGroupId);
+ CB(WNDMGR_API_SKINWND_ENUMBYGROUPID, skinwnd_enumByGroupId);
+ VCB(WNDMGR_API_SKINWND_ATTACHTOSKIN, skinwnd_attachToSkin);
+ //CB(WNDMGR_API_SKIN_GETCONTAINER, skin_getContainer);
+ //CB(WNDMGR_API_SKIN_GETLAYOUT, skin_getLayout);
+ VCB(WNDMGR_API_WNDHOLDER_REGISTER, wndholder_register);
+ VCB(WNDMGR_API_WNDHOLDER_UNREGISTER, wndholder_unregister);
+ CB(WNDMGR_API_MESSAGEBOX, messageBox);
+ CB(WNDMGR_API_GETMODALWND, getModalWnd);
+ VCB(WNDMGR_API_PUSHMODALWND, pushModalWnd);
+ VCB(WNDMGR_API_POPMODALWND, popModalWnd);
+ VCB(WNDMGR_API_DRAWANIMATEDRECTS, drawAnimatedRects);
+ CB(WNDMGR_API_AUTOPOPUP_REGISTERGUID, autopopup_registerGuid);
+ CB(WNDMGR_API_AUTOPOPUP_REGISTERGROUPID, autopopup_registerGroupId);
+ VCB(WNDMGR_API_AUTOPOPUP_UNREGISTER, autopopup_unregister);
+ CB(WNDMGR_API_AUTOPOPUP_GETNUMGUIDS, autopopup_getNumGuids);
+ CB(WNDMGR_API_AUTOPOPUP_ENUMGUID, autopopup_enumGuid);
+ CB(WNDMGR_API_AUTOPOPUP_GETNUMGROUPS, autopopup_getNumGroups);
+ CB(WNDMGR_API_AUTOPOPUP_ENUMGROUPS, autopopup_enumGroup);
+ CB(WNDMGR_API_AUTOPOPUP_ENUMGUIDDESC, autopopup_enumGuidDescription);
+ CB(WNDMGR_API_AUTOPOPUP_ENUMGROUPDESC, autopopup_enumGroupDescription);
+ CB(WNDMGR_API_VARMGR_TRANSLATE, varmgr_translate);
+ CB(WNDMGR_API_NEWDYNAMICCONTAINER, newDynamicContainer);
+END_DISPATCH;
diff --git a/Src/Wasabi/api/wndmgr/api_wndmgr.h b/Src/Wasabi/api/wndmgr/api_wndmgr.h
new file mode 100644
index 00000000..667ddd38
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/api_wndmgr.h
@@ -0,0 +1,305 @@
+#ifndef __WNDMGR_API_H
+#define __WNDMGR_API_H
+
+#include <bfc/dispatch.h>
+#include <bfc/nsguid.h>
+
+class ifc_window;
+class WindowHolder;
+class Container;
+class ScriptObject;
+
+#ifndef MODALWND_DEF
+#define MODALWND_DEF
+ifc_window *const MODALWND_NOWND = reinterpret_cast<ifc_window*>(-1);
+#endif
+
+class wndmgr_api : public Dispatchable {
+ public:
+ void wndTrackAdd(ifc_window *wnd);
+ void wndTrackRemove(ifc_window *wnd);
+ bool wndTrackDock(ifc_window *wnd, RECT *r, int mask);
+ bool wndTrackDock(ifc_window *wnd, RECT *r, RECT *orig_r, int mask);
+ void wndTrackStartCooperative(ifc_window *wnd);
+ void wndTrackEndCooperative();
+ int wndTrackWasCooperative();
+ void wndTrackInvalidateAll();
+ int skinwnd_toggleByGuid(GUID g, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0);
+ int skinwnd_toggleByGroupId(const wchar_t *groupid, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0);
+ ifc_window *skinwnd_createByGuid(GUID g, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0, int starthidden = 0, int *isnew = NULL);
+ ifc_window *skinwnd_createByGroupId(const wchar_t *groupid, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0, int starthidden = 0, int *isnew = NULL);
+ void skinwnd_destroy(ifc_window *w, RECT *destanimrect = NULL);
+ int skinwnd_getNumByGuid(GUID g);
+ ifc_window *skinwnd_enumByGuid(GUID g, int n);
+ int skinwnd_getNumByGroupId(const wchar_t *groupid);
+ ifc_window *skinwnd_enumByGroupId(const wchar_t *groupid, int n);
+ void skinwnd_attachToSkin(ifc_window *w, int side, int size);
+ //ScriptObject *skin_getContainer(const wchar_t *container_name);
+ //ScriptObject *skin_getLayout(ScriptObject *container, const wchar_t *layout_name);
+ void wndholder_register(WindowHolder *wh);
+ void wndholder_unregister(WindowHolder *wh);
+ int messageBox(const wchar_t *txt, const wchar_t *title, int flags, const wchar_t *not_anymore_identifier, ifc_window *parenwnt);
+ ifc_window *getModalWnd();
+ void pushModalWnd(ifc_window *w = MODALWND_NOWND);
+ void popModalWnd(ifc_window *w = MODALWND_NOWND);
+ void drawAnimatedRects(const RECT *r1, const RECT *r2);
+ int autopopup_registerGuid(GUID g, const wchar_t *desc, const wchar_t *prefered_container = NULL, int container_flag = 0);
+ int autopopup_registerGroupId(const wchar_t *groupid, const wchar_t *desc, const wchar_t *prefered_container = NULL, int container_flag = 0);
+ void autopopup_unregister(int id);
+ int autopopup_getNumGuids();
+ GUID autopopup_enumGuid(int n);
+ int autopopup_getNumGroups();
+ const wchar_t *autopopup_enumGroup(int n);
+ const wchar_t *autopopup_enumGuidDescription(int n);
+ const wchar_t *autopopup_enumGroupDescription(int n);
+ const wchar_t *varmgr_translate(const wchar_t *str);
+ //Container *newDynamicContainer(const wchar_t *containername, int transcient = 1);
+
+ enum {
+ WNDMGR_API_WNDTRACKADD = 0,
+ WNDMGR_API_WNDTRACKREMOVE = 10,
+ WNDMGR_API_WNDTRACKDOCK = 20,
+ WNDMGR_API_WNDTRACKDOCK2 = 30,
+ WNDMGR_API_WNDTRACKSTARTCOOPERATIVE = 40,
+ WNDMGR_API_WNDTRACKENDCOOPERATIVE = 50,
+ WNDMGR_API_WNDTRACKWASCOOPERATIVE = 60,
+ WNDMGR_API_WNDTRACKINVALIDATEALL = 70,
+ WNDMGR_API_SKINWND_TOGGLEBYGUID = 80,
+ WNDMGR_API_SKINWND_TOGGLEBYGROUPID = 90,
+ WNDMGR_API_SKINWND_CREATEBYGUID = 100,
+ WNDMGR_API_SKINWND_CREATEBYGROUPID = 110,
+ WNDMGR_API_SKINWND_DESTROY = 120,
+ WNDMGR_API_SKINWND_GETNUMBYGUID = 130,
+ WNDMGR_API_SKINWND_ENUMBYGUID = 140,
+ WNDMGR_API_SKINWND_GETNUMBYGROUPID = 150,
+ WNDMGR_API_SKINWND_ENUMBYGROUPID = 160,
+ WNDMGR_API_SKINWND_ATTACHTOSKIN = 170,
+ //WNDMGR_API_SKIN_GETCONTAINER = 180,
+ WNDMGR_API_SKIN_GETLAYOUT = 190,
+ WNDMGR_API_WNDHOLDER_REGISTER = 200,
+ WNDMGR_API_WNDHOLDER_UNREGISTER = 210,
+ WNDMGR_API_MESSAGEBOX = 220,
+ WNDMGR_API_GETMODALWND = 230,
+ WNDMGR_API_PUSHMODALWND = 240,
+ WNDMGR_API_POPMODALWND = 250,
+ WNDMGR_API_DRAWANIMATEDRECTS = 260,
+ WNDMGR_API_AUTOPOPUP_REGISTERGUID = 270,
+ WNDMGR_API_AUTOPOPUP_REGISTERGROUPID = 280,
+ WNDMGR_API_AUTOPOPUP_UNREGISTER = 290,
+ WNDMGR_API_VARMGR_TRANSLATE = 300,
+ WNDMGR_API_NEWDYNAMICCONTAINER = 310,
+ WNDMGR_API_AUTOPOPUP_GETNUMGUIDS = 320,
+ WNDMGR_API_AUTOPOPUP_ENUMGUID = 330,
+ WNDMGR_API_AUTOPOPUP_GETNUMGROUPS = 340,
+ WNDMGR_API_AUTOPOPUP_ENUMGROUPS = 350,
+ WNDMGR_API_AUTOPOPUP_ENUMGUIDDESC = 360,
+ WNDMGR_API_AUTOPOPUP_ENUMGROUPDESC = 370,
+ };
+};
+
+inline void wndmgr_api::wndTrackAdd(ifc_window *wnd) {
+ _voidcall(WNDMGR_API_WNDTRACKADD, wnd);
+}
+
+inline void wndmgr_api::wndTrackRemove(ifc_window *wnd) {
+ _voidcall(WNDMGR_API_WNDTRACKREMOVE, wnd);
+}
+
+inline bool wndmgr_api::wndTrackDock(ifc_window *wnd, RECT *r, int mask) {
+ return _call(WNDMGR_API_WNDTRACKDOCK, (bool)FALSE, wnd, r, mask);
+}
+
+inline bool wndmgr_api::wndTrackDock(ifc_window *wnd, RECT *r, RECT *orig_r, int mask) {
+ return _call(WNDMGR_API_WNDTRACKDOCK2, (bool)FALSE, wnd, r, orig_r, mask);
+}
+
+inline void wndmgr_api::wndTrackStartCooperative(ifc_window *wnd) {
+ _voidcall(WNDMGR_API_WNDTRACKSTARTCOOPERATIVE, wnd);
+}
+
+inline void wndmgr_api::wndTrackEndCooperative() {
+ _voidcall(WNDMGR_API_WNDTRACKENDCOOPERATIVE);
+}
+
+inline int wndmgr_api::wndTrackWasCooperative() {
+ return _call(WNDMGR_API_WNDTRACKWASCOOPERATIVE, (int)0);
+}
+
+inline void wndmgr_api::wndTrackInvalidateAll() {
+ _voidcall(WNDMGR_API_WNDTRACKINVALIDATEALL);
+}
+
+inline int wndmgr_api::skinwnd_toggleByGuid(GUID g, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient) {
+ return _call(WNDMGR_API_SKINWND_TOGGLEBYGUID, (int)0, g, prefered_container, container_flag, sourceanimrect, transcient);
+}
+
+inline int wndmgr_api::skinwnd_toggleByGroupId(const wchar_t *groupid, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient) {
+ return _call(WNDMGR_API_SKINWND_TOGGLEBYGROUPID, (int)0, groupid, prefered_container, container_flag, sourceanimrect, transcient);
+}
+
+inline ifc_window *wndmgr_api::skinwnd_createByGuid(GUID g, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient, int starthidden, int *isnew) {
+ return _call(WNDMGR_API_SKINWND_CREATEBYGUID, (ifc_window *)NULL, g, prefered_container, container_flag, sourceanimrect, transcient, starthidden, isnew);
+}
+
+inline ifc_window *wndmgr_api::skinwnd_createByGroupId(const wchar_t *groupid, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient, int starthidden, int *isnew) {
+ return _call(WNDMGR_API_SKINWND_CREATEBYGROUPID, (ifc_window *)NULL, groupid, prefered_container, container_flag, sourceanimrect, transcient, starthidden, isnew);
+}
+
+inline void wndmgr_api::skinwnd_destroy(ifc_window *w, RECT *destanimrect) {
+ _voidcall(WNDMGR_API_SKINWND_DESTROY, w, destanimrect);
+}
+
+inline int wndmgr_api::skinwnd_getNumByGuid(GUID g) {
+ return _call(WNDMGR_API_SKINWND_GETNUMBYGUID, (int)0, g);
+}
+
+inline ifc_window *wndmgr_api::skinwnd_enumByGuid(GUID g, int n) {
+ return _call(WNDMGR_API_SKINWND_ENUMBYGUID, (ifc_window *)NULL, g, n);
+}
+
+inline int wndmgr_api::skinwnd_getNumByGroupId(const wchar_t *groupid) {
+ return _call(WNDMGR_API_SKINWND_GETNUMBYGROUPID, (int)0, groupid);
+}
+
+inline ifc_window *wndmgr_api::skinwnd_enumByGroupId(const wchar_t *groupid, int n) {
+ return _call(WNDMGR_API_SKINWND_ENUMBYGROUPID, (ifc_window *)NULL, groupid, n);
+}
+
+inline void wndmgr_api::skinwnd_attachToSkin(ifc_window *w, int side, int size) {
+ _voidcall(WNDMGR_API_SKINWND_ATTACHTOSKIN, w, side, size);
+}
+/*
+inline ScriptObject *wndmgr_api::skin_getContainer(const wchar_t *container_name) {
+ return _call(WNDMGR_API_SKIN_GETCONTAINER, (ScriptObject *)NULL, container_name);
+}
+*/
+/*
+inline ScriptObject *wndmgr_api::skin_getLayout(ScriptObject *container, const wchar_t *layout_name) {
+ return _call(WNDMGR_API_SKIN_GETLAYOUT, (ScriptObject *)NULL, container, layout_name);
+}
+*/
+inline void wndmgr_api::wndholder_register(WindowHolder *wh) {
+ _voidcall(WNDMGR_API_WNDHOLDER_REGISTER, wh);
+}
+
+inline void wndmgr_api::wndholder_unregister(WindowHolder *wh) {
+ _voidcall(WNDMGR_API_WNDHOLDER_UNREGISTER, wh);
+}
+
+inline int wndmgr_api::messageBox(const wchar_t *txt, const wchar_t *title, int flags, const wchar_t *not_anymore_identifier, ifc_window *parenwnt) {
+ return _call(WNDMGR_API_MESSAGEBOX, (int)0, txt, title, flags, not_anymore_identifier, parenwnt);
+}
+
+inline ifc_window *wndmgr_api::getModalWnd() {
+ return _call(WNDMGR_API_GETMODALWND, (ifc_window *)NULL);
+}
+
+inline void wndmgr_api::pushModalWnd(ifc_window *w) {
+ _voidcall(WNDMGR_API_PUSHMODALWND, w);
+}
+
+inline void wndmgr_api::popModalWnd(ifc_window *w) {
+ _voidcall(WNDMGR_API_POPMODALWND, w);
+}
+
+inline void wndmgr_api::drawAnimatedRects(const RECT *r1, const RECT *r2) {
+ _voidcall(WNDMGR_API_DRAWANIMATEDRECTS, r1, r2);
+}
+
+inline int wndmgr_api::autopopup_registerGuid(GUID g, const wchar_t *desc, const wchar_t *prefered_container, int container_flag) {
+ return _call(WNDMGR_API_AUTOPOPUP_REGISTERGUID, (int)0, g, desc, prefered_container, container_flag);
+}
+
+inline int wndmgr_api::autopopup_registerGroupId(const wchar_t *groupid, const wchar_t *desc, const wchar_t *prefered_container, int container_flag) {
+ return _call(WNDMGR_API_AUTOPOPUP_REGISTERGROUPID, (int)0, groupid, desc, prefered_container, container_flag);
+}
+
+inline void wndmgr_api::autopopup_unregister(int id) {
+ _voidcall(WNDMGR_API_AUTOPOPUP_UNREGISTER, id);
+}
+
+inline const wchar_t *wndmgr_api::varmgr_translate(const wchar_t *str) {
+ return _call(WNDMGR_API_VARMGR_TRANSLATE, (const wchar_t *)0, str);
+}
+/*
+inline Container *wndmgr_api::newDynamicContainer(const wchar_t *containername, int transcient) {
+ return _call(WNDMGR_API_NEWDYNAMICCONTAINER, (Container *)NULL, containername, transcient);
+}
+*/
+inline int wndmgr_api::autopopup_getNumGuids() {
+ return _call(WNDMGR_API_AUTOPOPUP_GETNUMGUIDS, 0);
+}
+
+inline GUID wndmgr_api::autopopup_enumGuid(int n) {
+ return _call(WNDMGR_API_AUTOPOPUP_ENUMGUID, INVALID_GUID, n);
+}
+
+
+inline int wndmgr_api::autopopup_getNumGroups() {
+ return _call(WNDMGR_API_AUTOPOPUP_GETNUMGROUPS, 0);
+}
+
+inline const wchar_t *wndmgr_api::autopopup_enumGroup(int n) {
+ return _call(WNDMGR_API_AUTOPOPUP_ENUMGROUPS, (const wchar_t*)NULL, n);
+}
+
+inline const wchar_t *wndmgr_api::autopopup_enumGuidDescription(int n) {
+ return _call(WNDMGR_API_AUTOPOPUP_ENUMGUIDDESC, (const wchar_t *)NULL, n);
+}
+
+inline const wchar_t *wndmgr_api::autopopup_enumGroupDescription(int n) {
+ return _call(WNDMGR_API_AUTOPOPUP_ENUMGROUPDESC, (const wchar_t *)NULL, n);
+}
+
+class wndmgr_apiI : public wndmgr_api {
+ public:
+ virtual void wndTrackAdd(ifc_window *wnd)=0;
+ virtual void wndTrackRemove(ifc_window *wnd)=0;
+ virtual bool wndTrackDock(ifc_window *wnd, RECT *r, int mask)=0;
+ virtual bool wndTrackDock2(ifc_window *wnd, RECT *r, RECT *orig_r, int mask)=0;
+ virtual void wndTrackStartCooperative(ifc_window *wnd)=0;
+ virtual void wndTrackEndCooperative()=0;
+ virtual int wndTrackWasCooperative()=0;
+ virtual void wndTrackInvalidateAll()=0;
+ virtual int skinwnd_toggleByGuid(GUID g, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0)=0;
+ virtual int skinwnd_toggleByGroupId(const wchar_t *groupid, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0)=0;
+ virtual ifc_window *skinwnd_createByGuid(GUID g, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0, int starthidden = 0, int *isnew=NULL)=0;
+ virtual ifc_window *skinwnd_createByGroupId(const wchar_t *groupid, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0, int starthidden = 0, int *isnew=NULL)=0;
+ virtual void skinwnd_destroy(ifc_window *w, RECT *destanimrect = NULL)=0;
+ virtual int skinwnd_getNumByGuid(GUID g)=0;
+ virtual ifc_window *skinwnd_enumByGuid(GUID g, int n)=0;
+ virtual int skinwnd_getNumByGroupId(const wchar_t *groupid)=0;
+ virtual ifc_window *skinwnd_enumByGroupId(const wchar_t *groupid, int n)=0;
+ virtual void skinwnd_attachToSkin(ifc_window *w, int side, int size)=0;
+ virtual ScriptObject *skin_getContainer(const wchar_t *container_name)=0;
+ virtual ScriptObject *skin_getLayout(ScriptObject *container, const wchar_t *layout_name)=0;
+ virtual void wndholder_register(WindowHolder *wh)=0;
+ virtual void wndholder_unregister(WindowHolder *wh)=0;
+ virtual int messageBox(const wchar_t *txt, const wchar_t *title, int flags, const wchar_t *not_anymore_identifier, ifc_window *parenwnt)=0;
+ virtual ifc_window *getModalWnd()=0;
+ virtual void pushModalWnd(ifc_window *w = MODALWND_NOWND)=0;
+ virtual void popModalWnd(ifc_window *w = MODALWND_NOWND)=0;
+ virtual void drawAnimatedRects(const RECT *r1, const RECT *r2)=0;
+ virtual int autopopup_registerGuid(GUID g, const wchar_t *desc, const wchar_t *prefered_container = NULL, int container_flag = 0)=0;
+ virtual int autopopup_registerGroupId(const wchar_t *groupid, const wchar_t *desc, const wchar_t *prefered_container = NULL, int container_flag = 0)=0;
+ virtual void autopopup_unregister(int id)=0;
+ virtual int autopopup_getNumGuids()=0;
+ virtual GUID autopopup_enumGuid(int n)=0;
+ virtual int autopopup_getNumGroups()=0;
+ virtual const wchar_t *autopopup_enumGroup(int n)=0;
+ virtual const wchar_t *varmgr_translate(const wchar_t *str)=0;
+ virtual Container *newDynamicContainer(const wchar_t *containername, int transcient = 1)=0;
+ virtual const wchar_t *autopopup_enumGuidDescription(int n)=0;
+ virtual const wchar_t *autopopup_enumGroupDescription(int n)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+// {038A3567-1530-4062-BA87-CCB4F01DA3E9}
+static const GUID wndMgrApiServiceGuid =
+{ 0x38a3567, 0x1530, 0x4062, { 0xba, 0x87, 0xcc, 0xb4, 0xf0, 0x1d, 0xa3, 0xe9 } };
+
+extern wndmgr_api *wndManagerApi;
+
+#endif //wndmgr_api_h
diff --git a/Src/Wasabi/api/wndmgr/appcmds.cpp b/Src/Wasabi/api/wndmgr/appcmds.cpp
new file mode 100644
index 00000000..93b6ab6d
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/appcmds.cpp
@@ -0,0 +1,61 @@
+#include <precomp.h>
+#include "appcmds.h"
+
+#define CBCLASS AppCmdsI
+START_DISPATCH;
+CB(APPCMDS_GETNUMCMDS, appcmds_getNumCmds);
+CB(APPCMDS_ENUMCMD, appcmds_enumCmd);
+VCB(APPCMDS_ONCOMMAND, appcmds_onCommand);
+END_DISPATCH;
+#undef CBCLASS
+
+AppCmdsI::~AppCmdsI()
+{
+ foreach(cmds)
+ if (cmds.getfor()->autodelete)
+ delete cmds.getfor();
+ endfor
+}
+
+void AppCmdsI::appcmds_addCmd(CmdRec *cmdrec)
+{
+ cmds.addItem(cmdrec);
+}
+
+void AppCmdsI::appcmds_addCmd(const wchar_t *name, int id, int side)
+{
+ cmds.addItem(new CmdRec(name, id, side, TRUE));
+}
+
+void AppCmdsI::appcmds_deleteAll()
+{
+ foreach(cmds)
+ if (cmds.getfor()->autodelete) delete cmds.getfor();
+ endfor
+ cmds.removeAll();
+}
+
+int AppCmdsI::appcmds_getNumCmds()
+{
+ return cmds.getNumItems();
+}
+
+const wchar_t *AppCmdsI::appcmds_enumCmd(int n, int *side, int *id)
+{
+ CmdRec *cr = cmds[n];
+ if (cr == NULL) return NULL;
+ if (side != NULL) *side = cr->side;
+ if (id != NULL) *id = cr->id;
+ return cr->cmdname;
+}
+
+void AppCmdsI::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
+{
+ foreach(cmds)
+ if (cmds.getfor()->id == id)
+ {
+ cmds.getfor()->onCommand(buttonRect, which_button);
+ break;
+ }
+ endfor
+}
diff --git a/Src/Wasabi/api/wndmgr/appcmds.h b/Src/Wasabi/api/wndmgr/appcmds.h
new file mode 100644
index 00000000..fc3f3ec5
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/appcmds.h
@@ -0,0 +1,89 @@
+#ifndef _APPCMDS_H
+#define _APPCMDS_H
+
+#include <bfc/dispatch.h>
+#include <bfc/depend.h>
+#include <bfc/common.h>
+#include <bfc/string/StringW.h>
+#include <bfc/ptrlist.h>
+
+class DragItem;
+
+// this will be fully dispatched later on
+class AppCmds : public Dispatchable
+{
+public:
+
+ int appcmds_getNumCmds();
+
+ const wchar_t *appcmds_enumCmd(int n, int *side, int *id);
+
+ enum {
+ SIDE_LEFT = 0, SIDE_RIGHT = 1
+ };
+
+ enum {
+ LEFT_CLICK = 0,
+ RIGHT_CLICK = 1,
+ };
+
+ void appcmds_onCommand(int id, const RECT *buttonRect, int which_button); //onscreen coords
+
+ enum {
+ APPCMDS_GETNUMCMDS = 100,
+ APPCMDS_ENUMCMD = 200,
+ APPCMDS_ONCOMMAND = 300,
+ };
+};
+
+inline int AppCmds::appcmds_getNumCmds()
+{
+ return _call(APPCMDS_GETNUMCMDS, 0);
+}
+
+inline const wchar_t *AppCmds::appcmds_enumCmd(int n, int *side, int *id)
+{
+ return _call(APPCMDS_ENUMCMD, (const wchar_t *)NULL, n, side, id);
+}
+
+inline void AppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
+{
+ _voidcall(APPCMDS_ONCOMMAND, id, buttonRect, which_button);
+}
+
+class CmdRec
+{
+public:
+ CmdRec(const wchar_t *name, int _id, int _side, int _autodelete = 0) : cmdname(name), id(_id), side(_side), autodelete(_autodelete) {}
+ virtual ~CmdRec() {}
+ StringW cmdname;
+ int id, side;
+ int autodelete;
+
+ virtual void onCommand(const RECT *buttonRect, int which_button) {}}
+;
+
+class AppCmdsI : public AppCmds
+{
+public:
+ AppCmdsI() { }
+ virtual ~AppCmdsI();
+
+protected:
+ void appcmds_addCmd(CmdRec *cmdrec);
+ void appcmds_addCmd(const wchar_t *name, int id, int side = SIDE_LEFT);
+ void appcmds_deleteAll(); //calls delete on each one
+
+public:
+ virtual int appcmds_getNumCmds();
+ virtual const wchar_t *appcmds_enumCmd(int n, int *side, int *id);
+
+ // override this and catch your commands, otherwise it'll call the CmdRec
+ virtual void appcmds_onCommand(int id, const RECT *buttonRect, int which_button);
+
+protected:
+ RECVS_DISPATCH;
+ PtrList<CmdRec> cmds;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/autopopup.cpp b/Src/Wasabi/api/wndmgr/autopopup.cpp
new file mode 100644
index 00000000..58212998
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/autopopup.cpp
@@ -0,0 +1,157 @@
+#include <precomp.h>
+#include "autopopup.h"
+
+static PtrListQuickSorted<AutoPopupEntry, AutoPopupEntrySort> entries;
+static int nid=0;
+
+int AutoPopup::registerGuid(int skinpartid, GUID g, const wchar_t *desc, const wchar_t *prefered_container, int required)
+{
+ if (desc == NULL || !*desc) desc = L"[????]";
+ AutoPopupEntry *ape = new AutoPopupEntry(skinpartid, g, NULL, desc, prefered_container, required);
+ entries.addItem(ape);
+ return ape->getNid();
+}
+
+int AutoPopup::registerGroupId(int skinpartid, const wchar_t *groupid, const wchar_t *desc, const wchar_t *prefered_container, int required) {
+ if (desc == NULL || !*desc) desc = L"[????]";
+ AutoPopupEntry *ape = new AutoPopupEntry(skinpartid, INVALID_GUID, groupid, desc, prefered_container, required);
+ entries.addItem(ape);
+ return ape->getNid();
+}
+
+int AutoPopup::getNumItems() { return entries.getNumItems(); }
+AutoPopupEntry *AutoPopup::enumItem(int n) { return entries.enumItem(n); }
+
+int AutoPopup::getNumGroups() {
+ int n = 0;
+ foreach(entries)
+ AutoPopupEntry *e = entries.getfor();
+ if (e->getGroupId() != NULL && e->getGuid() == INVALID_GUID) n++;
+ endfor;
+ return n;
+}
+
+int AutoPopup::getNumGuids() {
+ int n = 0;
+ foreach(entries)
+ AutoPopupEntry *e = entries.getfor();
+ if (e->getGroupId() == NULL && e->getGuid() != INVALID_GUID) n++;
+ endfor;
+ return n;
+}
+
+const wchar_t *AutoPopup::enumGroup(int n) {
+ int c = 0;
+ foreach(entries)
+ AutoPopupEntry *e = entries.getfor();
+ if (e->getGroupId() != NULL && e->getGuid() == INVALID_GUID) {
+ if (c == n) return e->getGroupId();
+ c++;
+ }
+ endfor;
+ return NULL;
+}
+
+GUID AutoPopup::enumGuid(int n) {
+ int c = 0;
+ foreach(entries)
+ AutoPopupEntry *e = entries.getfor();
+ if (e->getGroupId() == NULL && e->getGuid() != INVALID_GUID) {
+ if (c == n) return e->getGuid();
+ c++;
+ }
+ endfor;
+ return INVALID_GUID;
+}
+
+const wchar_t *AutoPopup::enumGroupDescription(int n) {
+ int c = 0;
+ foreach(entries)
+ AutoPopupEntry *e = entries.getfor();
+ if (e->getGroupId() != NULL && e->getGuid() == INVALID_GUID) {
+ if (c == n) return e->getDescription();
+ c++;
+ }
+ endfor;
+ return NULL;
+}
+
+const wchar_t *AutoPopup::enumGuidDescription(int n) {
+ int c = 0;
+ foreach(entries)
+ AutoPopupEntry *e = entries.getfor();
+ if (e->getGroupId() == NULL && e->getGuid() != INVALID_GUID) {
+ if (c == n) return e->getDescription();
+ c++;
+ }
+ endfor;
+ return NULL;
+}
+
+
+AutoPopupEntry *AutoPopup::getByDesc(const wchar_t *desc) {
+ foreach(entries)
+ if (!WCSICMP(desc, entries.getfor()->getDescription()))
+ return entries.getfor();
+ endfor;
+ return NULL;
+}
+
+void AutoPopup::reset() { entries.deleteAll(); nid = 0; }
+
+const wchar_t *AutoPopup::getDefaultContainerParams(const wchar_t *groupid, GUID g, int *flag) {
+ if (groupid == NULL) { // guid
+ for (int i=entries.getNumItems()-1;i>=0;i--) {
+ if (entries.enumItem(i)->getGuid() == g) {
+ if (flag != NULL) *flag = entries.enumItem(i)->getContainerHow();
+ return entries.enumItem(i)->getPreferedContainer();
+ }
+ }
+ } else { // groupid
+ for (int i=entries.getNumItems()-1;i>=0;i--)
+ {
+ if (WCSCASEEQLSAFE(entries.enumItem(i)->getGroupId(), groupid))
+ {
+ if (flag != NULL) *flag = entries.enumItem(i)->getContainerHow();
+ return entries.enumItem(i)->getPreferedContainer();
+ }
+ }
+ }
+ return NULL;
+}
+
+void AutoPopup::unregister(int id) {
+ for (int i=0;i<entries.getNumItems();i++) {
+ AutoPopupEntry *ape = entries.enumItem(i);
+ if (ape->getNid() == id) {
+ delete ape;
+ entries.removeByPos(i);
+ i--;
+ continue;
+ }
+ }
+}
+
+void AutoPopup::removeSkinPart(int id) {
+ for (int i=0;i<entries.getNumItems();i++) {
+ AutoPopupEntry *ape = entries.enumItem(i);
+ if (ape->getSkinpart() == id) {
+ delete ape;
+ entries.removeByPos(i);
+ i--;
+ }
+ }
+}
+
+int AutoPopup::allocNid() { return nid++; }
+
+void AutoPopup::removeAllAddons() {
+ for (int i=0;i<entries.getNumItems();i++) {
+ AutoPopupEntry *ape = entries.enumItem(i);
+ if (ape->getSkinpart() != SKINPARTID_NONE) {
+ delete ape;
+ entries.removeByPos(i);
+ i--;
+ }
+ }
+}
diff --git a/Src/Wasabi/api/wndmgr/autopopup.h b/Src/Wasabi/api/wndmgr/autopopup.h
new file mode 100644
index 00000000..c37bd122
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/autopopup.h
@@ -0,0 +1,76 @@
+#ifndef __AUTOPOPUP_H
+#define __AUTOPOPUP_H
+
+#include <bfc/ptrlist.h>
+#include <bfc/string/StringW.h>
+
+class AutoPopupEntry;
+class AutoPopupEntrySort;
+
+#define SKINPARTID_NONE -1
+
+class AutoPopup {
+
+ public:
+
+ static int registerGuid(int skinpartid/*SKINPARTID_NONE*/, GUID g, const wchar_t *desc, const wchar_t *prefered_container=NULL, int required=FALSE);
+ static int registerGroupId(int skinpartid/*SKINPARTID_NONE*/, const wchar_t *groupid, const wchar_t *desc, const wchar_t *prefered_container=NULL, int required=FALSE);
+ static void unregister(int id);
+
+ static int getNumItems();
+ static AutoPopupEntry *enumItem(int n);
+ static AutoPopupEntry *getByDesc(const wchar_t *desc);
+
+ static void reset();
+ static void removeSkinPart(int id);
+
+ static int allocNid();
+ static void removeAllAddons();
+
+ static int getNumGuids();
+ static GUID enumGuid(int n);
+ static int getNumGroups();
+ static const wchar_t *enumGroup(int n);
+ static const wchar_t *enumGuidDescription(int n);
+ static const wchar_t *enumGroupDescription(int n);
+
+ static const wchar_t *getDefaultContainerParams(const wchar_t *groupid, GUID g, int *flag);
+};
+
+class AutoPopupEntry {
+
+ public:
+
+ AutoPopupEntry(int skinpartid, GUID g, const wchar_t *grpid, const wchar_t *description, const wchar_t *prefered_container=NULL, int required=TRUE) : guid(g), groupid(grpid), desc(description), container(prefered_container), container_how(required), skinpart(skinpartid) { nid = AutoPopup::allocNid(); }
+ virtual ~AutoPopupEntry() { }
+
+ GUID getGuid() { return guid; }
+ const wchar_t *getGroupId() { return groupid; }
+ const wchar_t *getDescription() { return desc; }
+ int getNid() { return nid; }
+ const wchar_t *getPreferedContainer() { return container; }
+ int getContainerHow() { return container_how; }
+ int getSkinpart() { return skinpart; }
+
+ private:
+
+ GUID guid;
+ StringW groupid;
+ StringW desc;
+ int nid;
+ StringW container;
+ int container_how;
+ int skinpart;
+};
+
+class AutoPopupEntrySort {
+public:
+ static int compareItem(AutoPopupEntry *p1, AutoPopupEntry *p2) {
+ return WCSICMP(p1->getDescription(), p2->getDescription());
+ }
+ static int compareAttrib(const wchar_t *attrib, AutoPopupEntry *item) {
+ return WCSICMP(attrib, item->getDescription());
+ }
+};
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/container.cpp b/Src/Wasabi/api/wndmgr/container.cpp
new file mode 100644
index 00000000..cfa7485e
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/container.cpp
@@ -0,0 +1,919 @@
+#include <precomp.h>
+#include "wasabicfg.h"
+#include <api/wndmgr/container.h>
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/config/items/attrbool.h>
+#include <api/config/items/cfgitem.h>
+#include <api/skin/skinparse.h>
+#include <api/wac/compon.h>
+#include <api/wnd/wndtrack.h>
+#include <api/skin/skin.h>
+#include <api/wndmgr/skinembed.h>
+#include <api/syscb/callbacks/wndcb.h>
+#include <bfc/string/stringdict.h>
+#include <api/skin/widgets/xuiwndholder.h> // TODO: cut, but we need XuiWindowHolder::parseGUID for now
+#include <bfc/platform/guid.h>
+
+#ifdef WIN32
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+#endif
+
+BEGIN_STRINGDICTIONARY(_containerparams)
+SDI(L"name", CONTAINERPARAM_NAME);
+SDI(L"id", CONTAINERPARAM_ID);
+SDI(L"dynamic", CONTAINERPARAM_DYNAMIC);
+SDI(L"default_x", CONTAINERPARAM_DEFAULTX);
+SDI(L"default_y", CONTAINERPARAM_DEFAULTY);
+SDI(L"default_visible", CONTAINERPARAM_DEFAULTVISIBLE);
+SDI(L"canclose", CONTAINERPARAM_CANCLOSE);
+SDI(L"nomenu", CONTAINERPARAM_NOMENU);
+SDI(L"nofocusapponclose", CONTAINERPARAM_NOFOCUSAPPONCLOSE);
+SDI(L"primarycomponent", CONTAINERPARAM_CONTENT);
+END_STRINGDICTIONARY(_containerparams, containerparams);
+
+Container::Container(int script_id)
+{
+ getScriptObject()->vcpu_setInterface(containerGuid, (void *)static_cast<Container *>(this));
+ getScriptObject()->vcpu_setClassName(L"Container");
+ getScriptObject()->vcpu_setController(containerController);
+ scriptid = script_id;
+ currentLayout = -1;
+ default_visible = TRUE;
+ loaded_default_visible = TRUE;
+ dynamic = 0;
+ MEMCPY(&myGUID, &INVALID_GUID, sizeof(GUID));
+ lastLayout = -1;
+ refocusapponclose = 1;
+ canclose = 1;
+ inited = 0;
+ deleting = 0;
+ transcient = 0;
+ switching_layout = 0;
+ nomenu = 0;
+ prevent_save_visibility = 0;
+ contentGuid = INVALID_GUID;
+ hasContentGuid=false;
+}
+
+
+void Container::setName(const wchar_t *name)
+{
+#ifdef ON_TWEAK_CONTAINER_NAMEW
+ ON_TWEAK_CONTAINER_NAMEW(name);
+#endif
+ containerName = name ? name : CONTAINER_UNDEFINED_NAME;
+ foreach(layouts)
+ Layout *l = layouts.getfor();
+ if (l->getRootWndName() == NULL)
+ {
+ l->setOSWndName(name);
+ }
+ endfor;
+ updateDefaultVisible();
+
+ dependent_sendEvent(Container::depend_getClassGuid(), Event_NAMECHANGE, 0, this);
+}
+
+void Container::resetLayouts()
+{
+ updateDefaultVisible();
+
+ foreach(layouts)
+ layouts.getfor()->loadSavedState();
+ endfor;
+}
+
+void Container::setId(const wchar_t *id)
+{
+ containerId = id ? id : L"undefined";
+ ismain = !WCSICMP(id, L"main");
+}
+
+int Container::setXmlParam(const wchar_t *paramname, const wchar_t *strvalue)
+{
+ switch (containerparams.getId(paramname))
+ {
+ case CONTAINERPARAM_NAME:
+ setName(strvalue);
+ return 1;
+ case CONTAINERPARAM_ID:
+ setId(strvalue);
+ return 1;
+ case CONTAINERPARAM_DYNAMIC:
+ setDynamic(WTOI(strvalue));
+ return 1;
+ case CONTAINERPARAM_DEFAULTX:
+ default_x = WTOI(strvalue);
+ return 1;
+ case CONTAINERPARAM_DEFAULTY:
+ default_y = WTOI(strvalue);
+ return 1;
+ case CONTAINERPARAM_DEFAULTVISIBLE:
+ default_visible = WTOI(strvalue);
+ updateDefaultVisible();
+ return 1;
+ case CONTAINERPARAM_CANCLOSE:
+ canclose = WTOI(strvalue);
+ return 1;
+ case CONTAINERPARAM_NOMENU:
+ nomenu = WTOI(strvalue);
+ return 1;
+ case CONTAINERPARAM_NOFOCUSAPPONCLOSE:
+ refocusapponclose = !WTOI(strvalue);
+ break;
+ case CONTAINERPARAM_CONTENT:
+ {
+ // TODO: move this out of XuiWindowHolder
+ GUID *g = XuiWindowHolder::parseGUID(strvalue);
+ contentGuid = *g;
+ hasContentGuid=true;
+
+ break;
+ }
+
+ }
+ return 0;
+}
+
+Container::~Container()
+{
+ containerCallback(CONT_CB_HIDDEN);
+ layouts.deleteAll();
+ contents.deleteAll();
+ SkinParser::containers.removeItem(this);
+}
+
+void Container::getWindowRect(RECT *r)
+{
+ Layout *l = getCurrentLayout();
+ if (l)
+ l->getWindowRect(r);
+}
+
+void Container::addLayout(Layout *layout)
+{
+ layouts.addItem(layout);
+}
+
+const wchar_t *Container::getName()
+{
+ return containerName;
+}
+
+const wchar_t *Container::getId()
+{
+ return containerId;
+}
+
+int Container::getDefaultPositionX(void)
+{
+ return default_x;
+}
+
+int Container::getDefaultPositionY(void)
+{
+ return default_y;
+}
+
+void Container::onInit(int noshow)
+{
+ if (inited) return ;
+ inited++;
+ loadFromDefaults(noshow);
+}
+
+void Container::loadFromDefaults(int noshow)
+{
+#ifdef WASABI_COMPILE_CONFIG
+ if (last_layout.isempty())
+ {
+ StringPrintfW tmp(L"container_%s|active", getName());
+ wchar_t c[512] = {0};
+ WASABI_API_CONFIG->getStringPrivate(tmp, c, 511, L"");
+ c[510] = 0;
+ last_layout = c;
+ }
+#endif
+
+ if (loaded_default_visible)
+ {
+ showDefaultLayout(noshow);
+ }
+}
+
+void Container::setDefaultLayout(const wchar_t *name)
+{
+ last_layout = name;
+}
+
+void Container::showDefaultLayout(int noshow)
+{
+ Layout *l = getLayout(last_layout);
+
+ if (!l)
+ l = layouts.enumItem(0);
+
+ if (l)
+ {
+ currentLayout = layouts.searchItem(l);
+
+ if (!noshow)
+ l->setVisible(1);
+
+ containerCallback(CONT_CB_VISIBLE); // since we set currentLayout prior to showing the layout, the callback will not be processed in onChildSetLayoutVisible
+ }
+}
+
+void Container::setVisible(int sh)
+{
+ if (!sh && !canclose)
+ return ;
+
+ int is = isVisible();
+
+ if (!!sh == !!is)
+ return ;
+
+ Layout *l = getCurrentLayout();
+
+ if (!l && lastLayout != -1)
+ l = layouts[lastLayout];
+
+ if (sh)
+ {
+ if (!l)
+ showDefaultLayout();
+ else
+ {
+ l->setVisible(1);
+ }
+ }
+ else
+ {
+ if (l)
+ l->setVisible(0);
+ }
+}
+
+int Container::isVisible()
+{
+ if (switching_layout) return 1;
+ Layout *l = getCurrentLayout();
+ if (!l) return 0;
+ return l->isVisible();
+}
+
+void Container::onChildSetLayoutVisible(Layout *l, int v)
+{
+ for (int i = 0;i < layouts.getNumItems();i++)
+ {
+ if (layouts[i] == l)
+ {
+ if (v)
+ {
+ if (currentLayout != i)
+ {
+ Layout *l = NULL;
+ if (currentLayout >= 0)
+ l = layouts[currentLayout];
+ if (l) l->setVisible(0);
+ containerCallback(CONT_CB_VISIBLE);
+ currentLayout = i;
+ l = layouts[currentLayout];
+#ifdef WASABI_COMPILE_CONFIG
+ if (!isTranscient() && !prevent_save_visibility)
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"container_%s|active", getName()), l->getGuiObject()->guiobject_getId());
+#endif
+#ifdef WA3COMPATIBILITY
+ l->setForwardMsgWnd(WASABI_API_WND->main_getRootWnd()->gethWnd());
+#endif
+ if (l->wantActivation())
+ {
+ l->bringToFront();
+ l->setFocus();
+ }
+ l->invalidate();
+ }
+#ifdef WASABI_COMPILE_CONFIG
+ if (!isTranscient() && !isDynamic() && !prevent_save_visibility)
+ WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"activated/%s", getName()), v);
+ WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"everloaded/%s", getName()), 1);
+#endif
+
+ }
+ else
+ {
+ if (i == currentLayout)
+ {
+ if (!isDeleting() && !isTranscient() && !isDynamic())
+ {
+#ifdef WASABI_COMPILE_CONFIG
+ WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"activated/%s", getName()), v);
+#endif
+ lastLayout = currentLayout;
+ currentLayout = -1;
+ }
+ containerCallback(CONT_CB_HIDDEN);
+ }
+ }
+ return ;
+ }
+ }
+}
+
+void Container::containerCallback(int msg)
+{
+ switch (msg)
+ {
+ case CONT_CB_VISIBLE:
+ {
+ foreach(contents)
+ ContentEntry *e = contents.getfor();
+ WndInfo i;
+ i.groupid = e->groupid;
+ i.guid = e->guid;
+ i.c = this;
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::WINDOW, WndCallback::SHOWWINDOW, reinterpret_cast<intptr_t>(&i));
+ endfor
+ WndInfo i;
+ i.groupid = getId();
+ i.guid = INVALID_GUID;
+ i.c = this;
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::WINDOW, WndCallback::SHOWWINDOW, reinterpret_cast<intptr_t>(&i));
+ }
+ break;
+ case CONT_CB_HIDDEN:
+ {
+ foreach(contents)
+ ContentEntry *e = contents.getfor();
+ WndInfo i;
+ i.groupid = e->groupid;
+ i.guid = e->guid;
+ i.c = this;
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::WINDOW, WndCallback::HIDEWINDOW, reinterpret_cast<intptr_t>(&i));
+ endfor
+ WndInfo i;
+ i.groupid = getId();
+ i.guid = INVALID_GUID;
+ i.c = this;
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::WINDOW, WndCallback::HIDEWINDOW, reinterpret_cast<intptr_t>(&i));
+ }
+ break;
+ }
+}
+
+void Container::close()
+{
+ int norefocs = !wantRefocusApp();
+ if (norefocs) WASABI_API_WND->appdeactivation_push_disallow(NULL);
+ if (!canclose) return ;
+ if (isDynamic())
+ {
+ setVisible(0);
+ skinEmbedder->destroyContainer(this); // deferred
+ }
+ else
+ setVisible(0);
+ if (norefocs) WASABI_API_WND->appdeactivation_pop_disallow(NULL);
+}
+
+void Container::toggle()
+{
+ if (isVisible()) close(); else setVisible(1); // close has special function hide/destroy depending on dynamic status
+}
+
+void Container::switchToLayout(const wchar_t *name, int moveit)
+{
+ int l = -1;
+ getLayout(name, &l);
+
+ if (l == -1)
+ {
+ // Layout not found, reverting to first in the list
+ if (layouts.getNumItems() > 0) l = 0;
+ else
+ return ; // none found, abort
+ }
+
+ switching_layout = 1;
+ if (l != currentLayout)
+ {
+ int old = currentLayout;
+ RECT r = {0};
+ Layout *oldlayout = old >= 0 ? layouts[old] : NULL;
+ Layout *newlayout = layouts[l];
+ onBeforeSwitchToLayout(oldlayout, newlayout);
+ if (oldlayout)
+ {
+ oldlayout->getWindowRect(&r);
+ oldlayout->endCapture();
+ }
+ int unlinked = layouts[l]->isUnlinked();
+ unlinked |= oldlayout ? oldlayout->isUnlinked() : 0;
+ if (moveit && !unlinked && oldlayout)
+ layouts[l]->move(r.left, r.top);
+#ifdef WASABI_COMPILE_CONFIG
+ // {9149C445-3C30-4e04-8433-5A518ED0FDDE}
+ const GUID uioptions_guid =
+ { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
+ if (_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid), L"Link layouts scale"))
+ {
+#else
+ if (WASABI_WNDMGR_LINKLAYOUTSCALES)
+ {
+#endif
+ if (oldlayout)
+ {
+ double _r = oldlayout->getRenderRatio();
+ newlayout->setRenderRatio(_r);
+ }
+ }
+#ifdef WASABI_COMPILE_CONFIG
+ if (_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid), L"Link layouts alpha"))
+ {
+#else
+ if (WASABI_WNDMGR_LINKLAYOUTSALPHA)
+ {
+#endif
+ if (oldlayout)
+ {
+ int a = layouts[old]->getAlpha();
+ newlayout->setAlpha(a);
+ int autoopacify = layouts[old]->getAutoOpacify();
+ newlayout->setAutoOpacify(autoopacify);
+ }
+ }
+
+ WindowTracker::layoutChanged(oldlayout, newlayout);
+#ifdef ON_LAYOUT_CHANGED
+ ON_LAYOUT_CHANGED;
+#endif
+ layouts[l]->setVisible(1);
+ foreach(SkinParser::containers)
+ SkinParser::containers.getfor()->savePositions();
+ endfor
+ onSwitchToLayout(newlayout);
+ }
+ switching_layout = 0;
+}
+
+void Container::savePositions()
+{
+ foreach (layouts)
+ layouts.getfor()->savePosition();
+ endfor
+}
+
+Layout *Container::getLayout(const wchar_t *name, int *pos)
+{
+ for ( int i = 0; i < getNumLayouts(); i++ )
+ {
+ if ( WCSCASEEQLSAFE( enumLayout( i )->getGuiObject()->guiobject_getId(), name ) )
+ {
+ if (pos)
+ {
+ *pos = i;
+ }
+
+ return enumLayout( i );
+
+ }
+ }
+
+ return NULL;
+}
+
+Layout *Container::getCurrentLayout()
+{
+ if (currentLayout < 0)
+ return NULL;
+
+ return layouts.enumItem(currentLayout);
+}
+
+void Container::otherContainerToggled(const wchar_t *id, int visible)
+{
+ for (int i = 0;i < layouts.getNumItems();i++)
+ layouts[i]->containerToggled(id, visible);
+}
+
+void Container::componentToggled(GUID *g, int visible)
+{
+ for (int i = 0;i < layouts.getNumItems();i++)
+ layouts[i]->componentToggled(g, visible);
+}
+
+void Container::sendNotifyToAllLayouts(int notifymsg, int param1, int param2)
+{
+ for (int i = 0;i < layouts.getNumItems();i++)
+ layouts[i]->sendNotifyToAllChildren(notifymsg, param1, param2);
+}
+
+int Container::isMainContainer()
+{
+ return ismain;
+}
+
+void Container::sysMenu()
+{
+ POINT p;
+ Wasabi::Std::getMousePos(&p);
+ layouts.enumItem(currentLayout)->onRightButtonDown(p.x, p.y);
+}
+
+void Container::setDynamic(int i)
+{
+ dynamic = i;
+ if (!containerId.isempty())
+ setId(containerId);
+}
+
+int Container::isDynamic()
+{
+ return dynamic;
+}
+
+void Container::onSwitchToLayout(Layout *l)
+{
+ ScriptObject *ls = l ? l->getGuiObject()->guiobject_getScriptObject() : NULL;
+ script_onSwitchToLayout(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(ls));
+}
+
+void Container::onBeforeSwitchToLayout(Layout *oldl, Layout *newl)
+{
+ ScriptObject *olds = oldl ? oldl->getGuiObject()->guiobject_getScriptObject() : NULL;
+ ScriptObject *news = newl ? newl->getGuiObject()->guiobject_getScriptObject() : NULL;
+ script_onBeforeSwitchToLayout(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(olds), MAKE_SCRIPT_OBJECT(news));
+}
+
+
+void Container::onHideLayout(Layout *l)
+{
+ script_onHideLayout(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(l->getGuiObject()->guiobject_getScriptObject()));
+}
+
+void Container::onShowLayout(Layout *l)
+{
+ script_onShowLayout(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(l->getGuiObject()->guiobject_getScriptObject()));
+}
+
+int Container::getNumLayouts()
+{
+ return layouts.getNumItems();
+}
+
+Layout *Container::enumLayout(int n)
+{
+ return layouts.enumItem(n);
+}
+
+const wchar_t *Container::getDescriptor()
+{
+ static wchar_t d[256];
+ // if we've tweaked the container names then when saving out we can see and attempt to 'untweak'
+ // so that things like Winamp Modern's ML will be correctly positioned irrespective of language
+ int untweak = 0;
+ wchar_t tweaked[96] = {0};
+ // Martin> We need to check the containerName against null - dunno why some skins cause this string to be null
+ if(containerName.v() != NULL && !_wcsicmp(containerName.v(), WASABI_API_LNGSTRINGW_BUF(IDS_MEDIA_LIBRARY,tweaked,96))){
+ untweak = 1;
+ }
+ WCSNPRINTF(d, 256,L"%s/%s", getId(), (!untweak ? containerName.v() : L"Media Library"));
+ return d;
+}
+
+void Container::updateDefaultVisible()
+{
+ if (!canclose)
+ {
+ loaded_default_visible = 1;
+ return ;
+ }
+#ifdef WASABI_COMPILE_CONFIG
+ loaded_default_visible = WASABI_API_CONFIG->getIntPrivate(StringPrintfW(L"activated/%s", getName()), default_visible);
+#else
+ loaded_default_visible = default_visible;
+#endif
+}
+
+int Container::getScriptId()
+{
+ return scriptid;
+}
+
+void Container::notifyAddContent(ifc_window *w, const wchar_t *id, GUID g)
+{
+ contents.addItem(new ContentEntry(id, g, w));
+ ScriptObject *_w = w ? w->getGuiObject()->guiobject_getScriptObject() : NULL;
+ wchar_t guidstr[256] = {0};
+ nsGUID::toCharW(g, guidstr);
+ script_onAddContent(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(_w), MAKE_SCRIPT_STRING(id), MAKE_SCRIPT_STRING(guidstr));
+}
+
+void Container::notifyRemoveContent(ifc_window *w)
+{
+ foreach(contents)
+ ContentEntry *e = contents.getfor();
+ if (e->wnd == w)
+ {
+ contents.removeItem(e);
+ delete e;
+ return ;
+ }
+ endfor;
+}
+
+int Container::hasContent(GUID g)
+{
+ foreach(contents)
+ ContentEntry *e = contents.getfor();
+ if (e->guid == g)
+ {
+ return 1;
+ }
+ endfor;
+ return 0;
+}
+
+GUID Container::getDefaultContent()
+{
+ if (hasContentGuid)
+ return contentGuid;
+ if (contents.getNumItems() > 0) return contents.enumItem(0)->guid;
+ return INVALID_GUID;
+}
+
+ContainerScriptController _containerController;
+ContainerScriptController *containerController = &_containerController;
+
+
+// -- Functions table -------------------------------------
+function_descriptor_struct ContainerScriptController::exportedFunction[] = {
+ {L"onSwitchToLayout", 1, (void*)Container::script_onSwitchToLayout },
+ {L"onBeforeSwitchToLayout", 2, (void*)Container::script_onBeforeSwitchToLayout },
+ {L"onHideLayout", 1, (void*)Container::script_onHideLayout },
+ {L"onShowLayout", 1, (void*)Container::script_onShowLayout },
+ {L"getLayout", 1, (void*)Container::script_getLayout },
+ {L"getNumLayouts", 0, (void*)Container::script_getNumLayouts },
+ {L"enumLayout", 1, (void*)Container::script_enumLayout },
+ {L"getCurLayout", 0, (void*)Container::script_getCurrentLayout},
+ {L"switchToLayout", 1, (void*)Container::script_switchToLayout },
+ {L"isDynamic", 0, (void*)Container::script_isDynamic },
+ {L"show", 0, (void*)Container::script_show },
+ {L"hide", 0, (void*)Container::script_hide },
+ {L"close", 0, (void*)Container::script_close},
+ {L"toggle", 0, (void*)Container::script_toggle },
+ {L"setName", 1, (void*)Container::script_setName },
+ {L"getName", 0, (void*)Container::script_getName },
+ {L"getGuid", 0, (void*)Container::script_getGuid },
+ {L"setXmlParam", 2, (void*)Container::script_setXmlParam},
+ {L"onAddContent", 3, (void*)Container::script_onAddContent},
+ };
+// --------------------------------------------------------
+
+/*SET_HIERARCHY(Container, SCRIPT_CONTAINER);
+SET_HIERARCHY2(Container, SCRIPT_CONTAINER, CONTAINER_SCRIPTPARENT);*/
+
+const wchar_t *ContainerScriptController::getClassName()
+{
+ return L"Container";
+}
+
+const wchar_t *ContainerScriptController::getAncestorClassName()
+{
+ return L"Object";
+}
+
+ScriptObjectController *ContainerScriptController::getAncestorController()
+{
+ return rootScriptObjectController;
+}
+
+int ContainerScriptController::getInstantiable()
+{
+ return 1;
+}
+
+ScriptObject *ContainerScriptController::instantiate()
+{
+ Container *c = new Container;
+ return c->getScriptObject();
+}
+
+void ContainerScriptController::destroy(ScriptObject *o)
+{
+ //ASSERTALWAYS("be nice, don't do that");
+ Container *c = (Container *)o->vcpu_getInterface(containerGuid);
+ delete c;
+}
+
+void *ContainerScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL;
+}
+
+void ContainerScriptController::deencapsulate(void *o)
+{}
+
+
+int ContainerScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *ContainerScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID ContainerScriptController::getClassGuid()
+{
+ return containerGuid;
+}
+
+//-----------------------------------------------------------------------
+
+scriptVar Container::script_onSwitchToLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, containerController, l);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, l);
+}
+
+scriptVar Container::script_onBeforeSwitchToLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar oldl, scriptVar newl)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS2(o, containerController, oldl, newl);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, oldl, newl);
+}
+
+scriptVar Container::script_onHideLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, containerController, l);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, l);
+}
+
+scriptVar Container::script_onShowLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, containerController, l);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, l);
+}
+
+// Get an layout from its ID
+scriptVar Container::script_getLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(obj.type == SCRIPT_STRING); // compiler discarded
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c)
+ {
+ for (int i = 0;i < c->layouts.getNumItems();i++)
+ if (!WCSICMP(obj.data.sdata, c->layouts.enumItem(i)->getGuiObject()->guiobject_getId()))
+ {
+ return MAKE_SCRIPT_OBJECT(c->layouts.enumItem(i)->getGuiObject()->guiobject_getScriptObject());
+ }
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Container::script_show(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) c->setVisible(1);
+ RETURN_SCRIPT_VOID;
+}
+scriptVar Container::script_hide(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) c->setVisible(0);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Container::script_close(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) c->close();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Container::script_toggle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) c->toggle();
+ RETURN_SCRIPT_VOID;
+}
+
+// Switch to another layout
+scriptVar Container::script_switchToLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c)
+ c->switchToLayout(GET_SCRIPT_STRING(l));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Container::script_getNumLayouts(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) return MAKE_SCRIPT_INT(c->getNumLayouts());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Container::script_enumLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&n)); // compiler discarded
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ Layout *l = NULL;
+ if (c) l = c->enumLayout(SOM::makeInt(&n));
+ return MAKE_SCRIPT_OBJECT(l ? l->getScriptObject() : NULL);
+}
+
+scriptVar Container::script_getCurrentLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ Layout *l = c->getCurrentLayout();
+ return MAKE_SCRIPT_OBJECT(l ? l->getScriptObject() : NULL);
+}
+
+// Switch to another layout
+scriptVar Container::script_vcpu_getId(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+
+ if (c)
+ return MAKE_SCRIPT_STRING(c->getId());
+
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar Container::script_isDynamic(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) return MAKE_SCRIPT_INT(c->isDynamic());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Container::script_setName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) c->setName(GET_SCRIPT_STRING(name));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Container::script_getName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) return MAKE_SCRIPT_STRING(c->getName());
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar Container::script_getGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c)
+ {
+ static wchar_t guidstr[256];
+ nsGUID::toCharW(c->getGUID(), guidstr);
+ return MAKE_SCRIPT_STRING(guidstr);
+ }
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar Container::script_setXmlParam(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p, scriptVar v)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) c->setXmlParam(GET_SCRIPT_STRING(p), GET_SCRIPT_STRING(v));
+ RETURN_SCRIPT_VOID;
+}
+
+//void Container::notifyAddContent(ifc_window *w, const wchar_t *id, GUID g)
+scriptVar Container::script_onAddContent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar window, scriptVar id, scriptVar g)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS3(o, containerController, window, id, g);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT3(o, window, id, g);
+}
+
diff --git a/Src/Wasabi/api/wndmgr/container.h b/Src/Wasabi/api/wndmgr/container.h
new file mode 100644
index 00000000..0078057d
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/container.h
@@ -0,0 +1,231 @@
+#ifdef WASABI_COMPILE_WNDMGR
+#ifndef __CONTAINER_H
+#define __CONTAINER_H
+
+class Container;
+class Layout;
+
+#include <bfc/ptrlist.h>
+#include <api/skin/xmlobject.h>
+
+#ifdef WASABI_WIDGETS_GUIOBJECT
+#include <api/script/objects/guiobj.h>
+#endif
+#include <api/script/script.h>
+#include <api/script/scriptobj.h>
+#include <api/script/objcontroller.h>
+#include <api/script/objects/rootobj.h>
+
+
+#define CONTAINER_UNDEFINED_NAME L"undefined container name"
+
+enum {
+ CONTAINERPARAM_NAME = 0,
+ CONTAINERPARAM_ID,
+ CONTAINERPARAM_DYNAMIC,
+ CONTAINERPARAM_DEFAULTX,
+ CONTAINERPARAM_DEFAULTY,
+ CONTAINERPARAM_DEFAULTVISIBLE,
+ CONTAINERPARAM_CANCLOSE,
+ CONTAINERPARAM_NOMENU,
+ CONTAINERPARAM_NOFOCUSAPPONCLOSE,
+ CONTAINERPARAM_CONTENT,
+};
+
+class ContainerScriptController: public ScriptObjectControllerI
+{
+public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+ virtual int getInstantiable();
+
+private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+class ContentEntry
+{
+public:
+ ContentEntry(const wchar_t *gid, GUID g, ifc_window *w) : groupid(gid), guid(g), wnd(w) { }
+
+ GUID guid;
+ StringW groupid;
+ ifc_window *wnd;
+};
+
+extern ContainerScriptController *containerController;
+
+#define CONTAINER_SCRIPTPARENT RootObjectInstance
+
+class Container : public CONTAINER_SCRIPTPARENT, public XmlObjectI, public DependentI
+{
+
+public:
+ Container(int scriptid = -1);
+ virtual ~Container();
+
+ virtual void setName(const wchar_t *name);
+ virtual void setId(const wchar_t *id);
+
+ virtual const wchar_t *getName();
+ virtual const wchar_t *getId();
+
+ virtual int setXmlParam(const wchar_t *p, const wchar_t *v);
+
+ virtual void onInit(int noshow = 0);
+
+ virtual void addLayout(Layout *layout);
+ virtual void resetLayouts();
+
+ virtual void setVisible(int sh);
+ virtual int isVisible();
+
+ virtual void switchToLayout(const wchar_t *name, int moveit = 1);
+ virtual void toggle();
+ virtual void close();
+ virtual void sysMenu();
+ virtual int getNumLayouts();
+ virtual Layout *enumLayout(int n);
+ virtual Layout *getLayout(const wchar_t *name, int *pos = NULL);
+ virtual int getScriptId();
+ virtual void savePositions();
+ void setDefaultLayout(const wchar_t *name);
+ void loadFromDefaults(int noshow = 0);
+ int isTranscient() { return transcient; }
+ void setTranscient(int is) { transcient = is; }
+
+ // player callbacks to notify that container/component
+ // has been set visible/invisible
+ virtual void otherContainerToggled(const wchar_t *id, int visible);
+ virtual void componentToggled(GUID *g, int visible);
+
+ virtual int isMainContainer();
+ virtual int isDynamic();
+
+ virtual void onSwitchToLayout(Layout *l);
+ virtual void onBeforeSwitchToLayout(Layout *oldl, Layout *newl);
+ virtual void onHideLayout(Layout *l);
+ virtual void onShowLayout(Layout *l);
+ virtual Layout *getCurrentLayout();
+ virtual int getDefaultPositionX(void);
+ virtual int getDefaultPositionY(void);
+ virtual void onChildSetLayoutVisible(Layout *l, int v);
+
+ virtual void notifyAddContent(ifc_window *w, const wchar_t *groupid, GUID guid = INVALID_GUID);
+ virtual void notifyRemoveContent(ifc_window *w);
+ virtual int hasContent(GUID g);
+ virtual GUID getDefaultContent();
+
+ const wchar_t *getDescriptor(void);
+
+ virtual void getWindowRect(RECT *r);
+
+ virtual void sendNotifyToAllLayouts(int notifymsg, int param1, int param2);
+ void setDynamic(int i);
+
+ void updateDefaultVisible();
+ void setDeleting() { deleting = 1; }
+ int isDeleting() { return deleting; }
+ int isInited() { return inited; }
+
+ int canClose() { return canclose; }
+ void setCanClose(int c) { canclose = c; }
+ GUID getGUID() { return myGUID; }
+
+ int getNoMenu() { return nomenu; }
+
+ void setPreventSaveVisibility(int p) { prevent_save_visibility = p; }
+ int wantRefocusApp() { return refocusapponclose; }
+ void setWantRefocusApp(int rf) { refocusapponclose = rf; }
+
+ public:
+ // ifc_dependent stuff
+
+ static const GUID *depend_getClassGuid() {
+ // {C439D9F4-34F5-453c-B947-448ED20203FC}
+ static const GUID ret =
+ { 0xc439d9f4, 0x34f5, 0x453c, { 0xb9, 0x47, 0x44, 0x8e, 0xd2, 0x2, 0x3, 0xfc } };
+
+ return &ret;
+ }
+ enum
+ {
+ Event_NAMECHANGE = 0,
+ };
+
+
+private:
+ void containerCallback(int msg);
+ StringW containerName;
+ StringW containerId;
+ PtrList<Layout> layouts;
+ int currentLayout;
+ StringW last_layout;
+ int canclose;
+ int lastLayout;
+ int default_visible, loaded_default_visible;
+ int ismain;
+ int dynamic;
+ int default_x = -1;
+ int default_y = -1;
+ int default_w = -1;
+ int default_h = -1;
+ int scriptid;
+ int inited;
+ int deleting;
+ int transcient;
+ PtrList<ContentEntry> contents;
+ int switching_layout;
+ int nomenu;
+ int prevent_save_visibility;
+ int refocusapponclose;
+ GUID contentGuid;
+ bool hasContentGuid;
+
+private:
+ GUID myGUID;
+ void showDefaultLayout(int noshow = 0);
+
+public:
+ static scriptVar script_vcpu_getId(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_onSwitchToLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l);
+ static scriptVar script_onBeforeSwitchToLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar oldl, scriptVar newl);
+ static scriptVar script_onHideLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l);
+ static scriptVar script_onShowLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l);
+ static scriptVar script_getLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj);
+ static scriptVar script_switchToLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s);
+ static scriptVar script_getCurrentLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_show(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_hide(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_close(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_toggle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_getNumLayouts(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_enumLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n);
+ static scriptVar script_isDynamic(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_setName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name);
+ static scriptVar script_getName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_getGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_setXmlParam(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p, scriptVar v);
+ static scriptVar script_onAddContent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar window, scriptVar id, scriptVar g);
+
+};
+
+enum {
+ CONT_CB_NONE,
+ CONT_CB_VISIBLE,
+ CONT_CB_HIDDEN
+};
+
+#endif
+#endif
diff --git a/Src/Wasabi/api/wndmgr/gc.cpp b/Src/Wasabi/api/wndmgr/gc.cpp
new file mode 100644
index 00000000..c312b9ea
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/gc.cpp
@@ -0,0 +1,24 @@
+#include <precomp.h>
+#include "gc.h"
+
+GarbageCollector *garbageCollector=NULL;
+
+GarbageCollector::GarbageCollector() {
+ last = 0;
+ WASABI_API_SYSCB->syscb_registerCallback(this);
+}
+
+GarbageCollector::~GarbageCollector() {
+ WASABI_API_SYSCB->syscb_deregisterCallback(this);
+}
+
+int GarbageCollector::gccb_onGarbageCollect() {
+ uint32_t tc = Wasabi::Std::getTickCount();
+ if (tc < last + 10000) return 0;
+
+ last = tc;
+#ifdef WIN32
+ //SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1);
+#endif
+ return 0;
+}
diff --git a/Src/Wasabi/api/wndmgr/gc.h b/Src/Wasabi/api/wndmgr/gc.h
new file mode 100644
index 00000000..a57d24b4
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/gc.h
@@ -0,0 +1,19 @@
+#ifndef __GARBAGECOLLECT_H
+#define __GARBAGECOLLECT_H
+
+#include <api/syscb/callbacks/gccb.h>
+
+class GarbageCollector : public GarbageCollectCallbackI {
+ public:
+ GarbageCollector();
+ virtual ~GarbageCollector();
+
+ virtual int gccb_onGarbageCollect();
+
+ private:
+ uint32_t last;
+};
+
+extern GarbageCollector *garbageCollector;
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/guistatuscb.cpp b/Src/Wasabi/api/wndmgr/guistatuscb.cpp
new file mode 100644
index 00000000..761a18a1
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/guistatuscb.cpp
@@ -0,0 +1,15 @@
+#include <precomp.h>
+#include "guistatuscb.h"
+
+#define CBCLASS GuiStatusCallbackI
+START_DISPATCH;
+ CB(STATUS_GETDEP, status_getDependencyPtr);
+ VCB(STATUS_ONSETTEXT, onSetStatusText);
+ VCB(STATUS_ADDCTXTCMDS, onAddAppCmds);
+ VCB(STATUS_REMCTXTCMDS, onRemoveAppCmds);
+ VCB(STATUS_PUSHCOMPLETED, pushCompleted);
+ VCB(STATUS_INCCOMPLETED, incCompleted);
+ VCB(STATUS_SETCOMPLETED, setCompleted);
+ VCB(STATUS_POPCOMPLETED, popCompleted);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/wndmgr/guistatuscb.h b/Src/Wasabi/api/wndmgr/guistatuscb.h
new file mode 100644
index 00000000..f35a4d9f
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/guistatuscb.h
@@ -0,0 +1,83 @@
+#ifndef _GUISTATUSCB_H
+#define _GUISTATUSCB_H
+
+#include <bfc/dispatch.h>
+
+class AppCmds;
+class ifc_dependent;
+
+class GuiStatusCallback : public Dispatchable {
+ public:
+ void onSetStatusText(const wchar_t *text, int overlay);
+ void onAddAppCmds(AppCmds *commands);
+ void onRemoveAppCmds(AppCmds *commands);
+ void pushCompleted(int max=100);
+ void incCompleted(int add=1);
+ void setCompleted(int pos);
+ void popCompleted();
+
+ api_dependent *status_getDependencyPtr();
+ enum {
+ STATUS_ONSETTEXT = 101,
+ STATUS_GETDEP = 200,
+ STATUS_ADDCTXTCMDS = 300,
+ STATUS_REMCTXTCMDS = 400,
+ STATUS_PUSHCOMPLETED = 500,
+ STATUS_INCCOMPLETED = 600,
+ STATUS_SETCOMPLETED = 700,
+ STATUS_POPCOMPLETED = 800,
+ };
+};
+
+inline void GuiStatusCallback ::onSetStatusText(const wchar_t *text, int overlay) {
+ _voidcall(STATUS_ONSETTEXT, text, overlay);
+}
+
+inline api_dependent *GuiStatusCallback ::status_getDependencyPtr() {
+ return _call(STATUS_GETDEP, (api_dependent *)NULL);
+}
+
+inline void GuiStatusCallback ::onAddAppCmds(AppCmds *commands) {
+ _voidcall(STATUS_ADDCTXTCMDS, commands);
+}
+
+inline void GuiStatusCallback ::onRemoveAppCmds(AppCmds *commands) {
+ _voidcall(STATUS_REMCTXTCMDS, commands);
+}
+
+inline
+void GuiStatusCallback::pushCompleted(int max) {
+ _voidcall(STATUS_PUSHCOMPLETED, max);
+}
+
+inline
+void GuiStatusCallback::incCompleted(int add) {
+ _voidcall(STATUS_INCCOMPLETED, add);
+}
+
+inline
+void GuiStatusCallback::setCompleted(int pos) {
+ _voidcall(STATUS_SETCOMPLETED, pos);
+}
+
+inline
+void GuiStatusCallback::popCompleted() {
+ _voidcall(STATUS_POPCOMPLETED);
+}
+
+class GuiStatusCallbackI : public GuiStatusCallback {
+ public:
+ virtual void onSetStatusText(const wchar_t *text, int overlay)=0;
+ virtual api_dependent *status_getDependencyPtr()=0;
+ virtual void onAddAppCmds(AppCmds *commands)=0;
+ virtual void onRemoveAppCmds(AppCmds *commands)=0;
+ virtual void pushCompleted(int max=100)=0;
+ virtual void incCompleted(int add=1)=0;
+ virtual void setCompleted(int pos)=0;
+ virtual void popCompleted()=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/layout.cpp b/Src/Wasabi/api/wndmgr/layout.cpp
new file mode 100644
index 00000000..006a953d
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/layout.cpp
@@ -0,0 +1,2586 @@
+#include <precomp.h>
+#include <api/skin/widgets/mb/scriptbrowser.h>
+#include <tataki/bitmap/bitmap.h>
+#include <api/wnd/popup.h>
+#include <api/wndmgr/msgbox.h>
+#include <api/skin/widgets/group.h>
+#include "layout.h"
+#include <api/skin/skinparse.h>
+#include <api/skin/widgets/button.h>
+#include <api/core/buttons.h>
+#include <api/wnd/wndtrack.h>
+//#include <api/wac/main.h> //CUT!
+#include <api/skin/widgets/compbuck2.h>
+#include <api/wac/compon.h>
+#include <api/skin/skin.h>
+#include <api/wnd/notifmsg.h>
+#include <api/config/items/intarray.h>
+#include <api/config/items/cfgitem.h>
+#include <api/config/options.h>
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <bfc/parse/pathparse.h>
+#include <api/skin/groupmgr.h>
+#include <api/wndmgr/skinembed.h>
+#include <api/skin/skinparse.h>
+#include <api/service/svcs/svc_action.h>
+#include <api/config/items/attrbool.h>
+#include <api/config/items/attrint.h>
+#include <api/wndmgr/alphamgr.h>
+#include <bfc/wasabi_std_wnd.h>
+#include <api/wnd/PaintCanvas.h>
+#ifdef _WIN32
+#include <windowsx.h> // for SetWindowRedraw
+#endif
+
+#ifdef WASABINOMAINAPI
+#include <api/wndmgr/gc.h>
+#include <api/syscb/callbacks/gccb.h>
+#endif
+
+#ifndef WM_MOUSEWHEEL
+#define WM_MOUSEWHEEL 0x20A
+#endif
+
+#define TIMER_SETTINGCHANGED 0x8791
+#define TIMER_AUTOOPACIFY 0x8792
+#define TIMER_AUTOOPACIFY2 0x8793
+#define TIMER_OFFSCREENCHECK 0x8794
+#define TIMER_TRANSPARENCY_AUTOON 0x8795
+#define TIMER_SAVE_POSITION 0x8796
+#define TIMER_SAVE_ALL_POSITIONS 0x8797
+
+#ifdef WASABI_COMPILE_CONFIG
+extern _bool cfg_uioptions_linkallalpha;
+extern _bool cfg_uioptions_linkallratio;
+extern _int cfg_uioptions_autoopacitylinked;
+extern _int cfg_uioptions_autoopacitytime;
+extern _int cfg_uioptions_extendautoopacity;
+extern _int cfg_uioptions_autoopacityfadein;
+extern _int cfg_uioptions_autoopacityfadeout;
+extern _int cfg_uioptions_linkedalpha;
+extern _bool cfg_options_appbarondrag;
+#endif
+
+AlphaMgr *alphaMgr = NULL;
+XMLParamPair Layout::params[] =
+ {
+ {LAYOUT_SETALPHA, L"ALPHA"},
+ {LAYOUT_SETALPHABACKGROUND, L"ALPHABACKGROUND"},
+ {LAYOUT_SETDESKTOPALPHA, L"DESKTOPALPHA"},
+ {LAYOUT_FORCEALPHA, L"FORCEALPHA"},
+ {LAYOUT_SETINDESKTOP, L"INDESKTOP"},
+ {LAYOUT_SETLINKHEIGHT, L"LINKHEIGHT"},
+ {LAYOUT_SETLINKWIDTH, L"LINKWIDTH"},
+ {LAYOUT_SETLOCKTO, L"LOCKTO"},
+ {LAYOUT_SETNOACTIVATION, L"NOACTIVATION"},
+ {LAYOUT_NODOCK, L"NODOCK"},
+ {LAYOUT_NOOFFSCREENCHECK, L"NOOFFSCREENCHECK"},
+ {LAYOUT_NOPARENT, L"NOPARENT"},
+ {LAYOUT_SETONTOP, L"ONTOP"},
+ {LAYOUT_SETOSFRAME, L"OSFRAME"},
+ {LAYOUT_SETOWNER, L"OWNER"},
+ {LAYOUT_SNAPADJUSTBOTTOM, L"SNAPADJUSTBOTTOM"},
+ {LAYOUT_SNAPADJUSTLEFT, L"SNAPADJUSTLEFT"},
+ {LAYOUT_SNAPADJUSTRIGHT, L"SNAPADJUSTRIGHT"},
+ {LAYOUT_SNAPADJUSTTOP, L"SNAPADJUSTTOP"},
+ {LAYOUT_UNLINKED, L"UNLINKED"},
+ {LAYOUT_RESIZABLE, L"RESIZABLE"},
+ {LAYOUT_SCALABLE, L"SCALABLE"},
+ };
+
+Layout::Layout()
+{
+ getScriptObject()->vcpu_setInterface(layoutGuid, (void *)static_cast<Layout *>(this));
+ getScriptObject()->vcpu_setInterface(guiResizableGuid, (void *)static_cast<GuiResizable *>(this));
+ getScriptObject()->vcpu_setClassName(L"Layout");
+ getScriptObject()->vcpu_setController(layoutController);
+#ifdef _WIN32
+ forwardMsgWnd = INVALIDOSWINDOWHANDLE;
+#endif
+ transparency_reenabled_at = 0;
+ transparency_autooff = 0;
+ captured = 0; resizing = 0;
+ m_forceunlink = 0;
+ inresize = 0;
+ autoopacify = 0;
+ x = 0; y = 0;
+#ifdef USEAPPBAR
+ appbar_want_autohide = 1;
+ appbar_want_alwaysontop = 1;
+ m_allowsavedock = 0;
+#endif
+ size_w = 0; size_h = 0;
+ reg = NULL;
+ //subregionlayers = new PtrList<Layer>;
+ setStartHidden(TRUE);
+ moving = 0;
+ setVirtual(0);
+ indesktop = 0;
+ p_container = NULL;
+ alpha = 255;
+ linkedheight = NULL;
+ linkedwidth = NULL;
+ inlinkwidth = 0;
+ inlinkheight = 0;
+ wantactiv = 1;
+ wantdesktopalpha = 0;
+ alllayouts.addItem(this);
+ galphadisabled = 0;
+ lockedto = NULL;
+ osframe = 0;
+ scalelocked = 0;
+ initontop = 0;
+ wantredrawonresize = 1;
+ getGuiObject()->guiobject_setMover(1);
+ snap_adjust_left = snap_adjust_right = snap_adjust_top = snap_adjust_bottom = 0;
+ disable_auto_alpha = 0;
+ unlinked = 0;
+ scaling = 0;
+ transparencyoverride = -1;
+ noparent = 0;
+ forcealpha = 0;
+ nodock = 0;
+ resizable = 1;
+ scalable = 1;
+ nooffscreencheck = 0;
+ m_w = m_h = m_endmovesize = 0;
+
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+
+ if (!alphaMgr)
+ {
+ alphaMgr = new AlphaMgr();
+ #ifdef WASABI_COMPILE_CONFIG
+ alphaMgr->setAllLinked(cfg_uioptions_linkallalpha.getValueAsInt());
+ alphaMgr->setAutoOpacify(cfg_uioptions_autoopacitylinked.getValueAsInt());
+ alphaMgr->setGlobalAlpha(cfg_uioptions_linkedalpha.getValueAsInt());
+ alphaMgr->setHoldTime(cfg_uioptions_autoopacitytime.getValueAsInt());
+ alphaMgr->setFadeInTime(cfg_uioptions_autoopacityfadein.getValueAsInt());
+ alphaMgr->setFadeOutTime(cfg_uioptions_autoopacityfadeout.getValueAsInt());
+ alphaMgr->setExtendAutoOpacity(cfg_uioptions_extendautoopacity.getValueAsInt());
+#endif
+ }
+ alphaMgr->addLayout(this);
+}
+
+void Layout::CreateXMLParameters(int master_handle)
+{
+ //LAYOUT_SCRIPTPARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+Layout::~Layout()
+{
+ if (transparency_reenabled_at) killTimer(TIMER_TRANSPARENCY_AUTOON);
+ alphaMgr->removeLayout(this);
+ killTimer(TIMER_OFFSCREENCHECK);
+ if (lockedto) lockedto->removeLockedLayout(this);
+ WASABI_API_WNDMGR->wndTrackRemove(this);
+ if (reg) delete reg;
+ alllayouts.removeItem(this);
+}
+
+int Layout::setXuiParam(int _xuihandle, int attrid, const wchar_t *paramname, const wchar_t *strvalue)
+{
+ if (xuihandle != _xuihandle) return LAYOUT_PARENT::setXuiParam(_xuihandle, attrid, paramname, strvalue);
+ switch (attrid)
+ {
+ case LAYOUT_SETDESKTOPALPHA:
+ setWantDesktopAlpha(WTOI(strvalue));
+ break;
+ case LAYOUT_SETINDESKTOP:
+ setInDesktop(WTOI(strvalue));
+ break;
+ case LAYOUT_SETALPHA:
+ setAlpha(WTOI(strvalue));
+ break;
+ case LAYOUT_SETLINKWIDTH:
+ setLinkWidth(strvalue);
+ if (*strvalue && isPostOnInit() && isVisible()) onResize();
+ break;
+ case LAYOUT_SETLINKHEIGHT:
+ setLinkHeight(strvalue);
+ if (*strvalue && isPostOnInit() && isVisible()) onResize();
+ break;
+ case LAYOUT_SETOWNER:
+ owner = strvalue;
+ break;
+ case LAYOUT_NOPARENT:
+ setNoParent(WTOI(strvalue));
+ break;
+ case LAYOUT_FORCEALPHA:
+ forcealpha = WTOI(strvalue);
+ break;
+ case LAYOUT_SETLOCKTO:
+ lockto = strvalue;
+ break;
+ case LAYOUT_SETOSFRAME:
+ osframe = WTOI(strvalue);
+ break;
+ case LAYOUT_SETALPHABACKGROUND:
+ setAlphaBackground(strvalue);
+ setWantDesktopAlpha(1);
+ setDrawBackground(1);
+ break;
+ case LAYOUT_SETNOACTIVATION:
+ wantactiv = WTOI(strvalue) ? 0 : 1;
+ break;
+ case LAYOUT_SETONTOP:
+ initontop = WTOI(strvalue);
+ if (isPostOnInit()) updateOnTop();
+ break;
+ case LAYOUT_SNAPADJUSTLEFT:
+ snap_adjust_left = WTOI(strvalue);
+ script_vcpu_onSnapAdjustChanged(SCRIPT_CALL, getScriptObject());
+#ifdef USEAPPBAR
+ if (appbar_isDocked()) appbar_posChanged();
+#endif
+ break;
+ case LAYOUT_SNAPADJUSTTOP:
+ snap_adjust_top = WTOI(strvalue);
+ script_vcpu_onSnapAdjustChanged(SCRIPT_CALL, getScriptObject());
+ #ifdef USEAPPBAR
+ if (appbar_isDocked()) appbar_posChanged();
+#endif
+ break;
+ case LAYOUT_SNAPADJUSTRIGHT:
+ snap_adjust_right = WTOI(strvalue);
+ script_vcpu_onSnapAdjustChanged(SCRIPT_CALL, getScriptObject());
+ #ifdef USEAPPBAR
+ if (appbar_isDocked()) appbar_posChanged();
+#endif
+ break;
+ case LAYOUT_SNAPADJUSTBOTTOM:
+ snap_adjust_bottom = WTOI(strvalue);
+ script_vcpu_onSnapAdjustChanged(SCRIPT_CALL, getScriptObject());
+ #ifdef USEAPPBAR
+ if (appbar_isDocked()) appbar_posChanged();
+#endif
+ break;
+ case LAYOUT_UNLINKED:
+ unlinked = WTOI(strvalue);
+ if (!unlinked && isPostOnInit() && isVisible()) onResize();
+ break;
+ case LAYOUT_NODOCK:
+ setNoDock(WTOI(strvalue));
+ break;
+ case LAYOUT_NOOFFSCREENCHECK:
+ setNoOffscreenCheck(WTOI(strvalue));
+ break;
+ case LAYOUT_RESIZABLE:
+ resizable = WTOI(strvalue);
+ break;
+ case LAYOUT_SCALABLE:
+ scalable = WTOI(strvalue);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void Layout::setLinkHeight(const wchar_t *layoutid)
+{
+ linkedheight = layoutid;
+}
+
+void Layout::setLinkWidth(const wchar_t *layoutid)
+{
+ linkedwidth = layoutid;
+}
+
+int Layout::onPostedMove()
+{
+ updateLockedLayouts();
+ int r = LAYOUT_PARENT::onPostedMove();
+ Container *c = getParentContainer();
+ if (isVisible() && c && c->isMainContainer())
+ {
+#ifdef WASABI_ON_MAIN_MOVE
+ WASABI_ON_MAIN_MOVE(gethWnd());
+#endif
+
+ }
+ return r;
+}
+
+void Layout::cancelCapture()
+{
+ if (getCapture())
+ endCapture();
+ captured = 0;
+}
+
+int Layout::isOffscreen(ifc_window *w)
+{
+ if (!w->isVisible()) return 0;
+ if (nooffscreencheck) return 0;
+#ifdef USEAPPBAR
+ if (appbar_isDocked()) return 0;
+#endif
+ if (lockedto) return 0;
+ RECT wr;
+ w->getWindowRect(&wr);
+ windowTracker->snapAdjustWindowRect(w, &wr);
+ RECT r;
+
+ int isontop = 0;
+ if (w->getGuiObject())
+ {
+ isontop = WTOI(w->getGuiObject()->guiobject_getXmlParam(L"ontop"));
+#ifndef EXPERIMENTAL_INDEPENDENT_AOT
+ if (WTOI(w->getGuiObject()->guiobject_getXmlParam(L"noparent")) == 0)
+ isontop = 0;
+#endif
+
+ }
+ if (!isontop)
+ {
+#ifdef WASABI_COMPILE_CONFIG
+ extern _bool cfg_options_alwaysontop;
+ isontop |= cfg_options_alwaysontop.getValueAsInt();
+#endif
+ }
+ Wasabi::Std::getViewport(&r, NULL, &wr, NULL, isontop);
+ if (wr.right < r.left + 10 ||
+ wr.bottom < r.top + 10 ||
+ wr.left > r.right - 10 ||
+ wr.top > r.bottom - 10)
+ {
+ return 1;
+ } //////TO CONTINUE
+ return 0;
+}
+
+void Layout::offscreenCheck()
+{
+ int disabled = 0;
+#ifdef WASABI_CHECK_OFFSCREENCHECK_DISABLE
+ WASABI_CHECK_OFFSCREENCHECK_DISABLE(disabled);
+#endif
+ if (disabled) return ;
+ if (!isVisible()) return ;
+ if (moving || scaling || resizing) return ;
+ if (isOffscreen(this))
+ {
+ windowTracker->startCooperativeMove(this);
+ for (int i = 0;i < windowTracker->getNumDocked();i++)
+ {
+ ifc_window *w = windowTracker->enumDocked(i);
+ Layout *l = static_cast<Layout*>(w->getInterface(layoutGuid));
+ if (l != NULL)
+ {
+ if (l->getParentContainer() && l->getParentContainer()->isMainContainer())
+ {
+ if (!isOffscreen(l))
+ {
+ windowTracker->endCooperativeMove();
+ return ;
+ }
+ }
+ }
+ }
+ windowTracker->endCooperativeMove();
+ RECT wr;
+ getWindowRect(&wr);
+ RECT nr = windowTracker->findOpenRect(wr);
+ move(nr.left, nr.top);
+ }
+}
+
+/**
+ * This one only prevents UI resizings from layers!
+ */
+int Layout::getResizable ()
+{
+ return this->resizable;
+}
+
+/**
+ * This one only prevents UI scalings from layers!
+ */
+int Layout::getScalable ()
+{
+ return this->scalable;
+}
+
+void Layout::setTransparencyOverride(int v)
+{
+ transparencyoverride = v;
+ if (v != -1) setTransparency(v); else updateTransparency();
+}
+
+#ifndef PI
+#define PI 3.1415926536
+#endif
+
+void Layout::timerCallback(int id)
+{
+ if (id == TIMER_TRANSPARENCY_AUTOON)
+ {
+ if (!isTransparencySafe(1))
+ {
+ transparency_reenabled_at = 0;
+ return ;
+ }
+ int n = Wasabi::Std::getTickCount() - transparency_reenabled_at;
+ if (n < 1000) return ;
+ else
+ {
+ killTimer(TIMER_TRANSPARENCY_AUTOON);
+ transparency_autooff = 0;
+ updateTransparency();
+ transparency_reenabled_at = 0;
+ }
+ return ;
+ }
+ else if (id == TIMER_OFFSCREENCHECK)
+ {
+ offscreenCheck();
+ return ;
+ }
+ else if (id == TIMER_SETTINGCHANGED)
+ {
+ killTimer(TIMER_SETTINGCHANGED);
+#ifdef _WIN32
+ HWND parent;
+ webserver = INVALIDOSWINDOWHANDLE;
+ listview = INVALIDOSWINDOWHANDLE;
+ getExplorerWindows(&parent, &listview, &webserver);
+ if (!webserver) // active desktop now off, reposition this window zorder otherwise it will be behind the icons
+#ifdef WIN32
+ SetWindowPos(gethWnd(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE);
+#else
+ bringToFront();
+#endif
+#endif
+ }
+ else if (id == TIMER_SAVE_ALL_POSITIONS)
+ {
+ killTimer(TIMER_SAVE_ALL_POSITIONS);
+ saveAllPositions();
+ // TODO: benski> not 100% sure we want to call into the script on the timer (maybe do it in endMove)
+ //script_vcpu_onEndMove(SCRIPT_CALL, getScriptObject());
+ return;
+ }
+ else if (id == TIMER_SAVE_POSITION)
+ {
+ killTimer(TIMER_SAVE_POSITION);
+ savePosition();
+ // TODO: benski> not 100% sure we want to call into the script on the timer (maybe do it in endMove)
+ //script_vcpu_onEndMove(SCRIPT_CALL, getScriptObject());
+ return;
+ }
+ else LAYOUT_PARENT::timerCallback(id);
+}
+
+void Layout::onMouseEnterLayout()
+{
+ script_vcpu_onMouseEnterLayout(SCRIPT_CALL, getScriptObject());
+}
+
+void Layout::onMouseLeaveLayout()
+{
+ script_vcpu_onMouseLeaveLayout(SCRIPT_CALL, getScriptObject());
+}
+
+void Layout::beginMove()
+{
+ moving = 1;
+}
+
+void Layout::beginScale()
+{
+ scaling = 1;
+}
+
+void Layout::beginResize()
+{
+ resizing = 1;
+}
+
+void Layout::endMove()
+{
+ if (m_endmovesize)
+ {
+ m_endmovesize = 0;
+ RECT r;
+ guiresizable_getRootWnd()->getWindowRect(&r);
+ r.right = r.left + m_w;
+ r.bottom = r.top + m_h;
+ guiresizable_getRootWnd()->resizeToRect(&r);
+ }
+ moving = 0;
+ // TODO: benski> do this on a resetable timer so it doesn't go so slowly
+ if (WASABI_API_WNDMGR->wndTrackWasCooperative())
+ setTimer(TIMER_SAVE_ALL_POSITIONS, 1000);
+// saveAllPositions();
+ else
+ setTimer(TIMER_SAVE_POSITION, 1000);
+ //savePosition();
+ // TODO: benski> not 100% sure we want to call into the script on the timer (maybe do it in endMove)
+ script_vcpu_onEndMove(SCRIPT_CALL, getScriptObject());
+}
+
+void Layout::endScale()
+{
+ scaling = 0;
+ savePosition();
+ fixPosition();
+}
+
+void Layout::endResize()
+{
+ resizing = 0;
+ RECT r;
+ getClientRect(&r);
+ RECT wr;
+ getWindowRect(&wr);
+ script_vcpu_onUserResize(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(wr.left), MAKE_SCRIPT_INT(wr.top), MAKE_SCRIPT_INT(r.right - r.left), MAKE_SCRIPT_INT(r.bottom - r.top));
+ savePosition();
+}
+
+void Layout::onMove()
+{
+ script_vcpu_onMove(SCRIPT_CALL, getScriptObject());
+}
+
+void Layout::setAutoOpacify(int a)
+{
+ if (autoopacify == a) return ;
+ autoopacify = a != -1 ? a : autoopacify;
+ if (getParentContainer() && !getParentContainer()->isTranscient())
+ {
+ StringW tmp;
+ tmp.printf(L"Skin:%s/Container:%s/Layout:%s/autoopacify", WASABI_API_SKIN->getSkinName(), getParentContainer()->getDescriptor(), getGuiObject()->guiobject_getId());
+ IntArray::write(tmp, autoopacify);
+ }
+ updateTransparency();
+}
+
+void Layout::controlMenu()
+{
+ PopupMenu pop;
+ int x = 1;
+#ifdef WASABI_CHECK_CAN_EXIT
+ WASABI_CHECK_CAN_EXIT(x)
+#endif
+ if (getParentContainer() && getParentContainer()->isMainContainer())
+ {
+ if (x)
+ {
+ pop.addCommand(StringPrintfW(L"Exit %s", WASABI_API_APP->main_getAppName()), ACTION_CLOSE);
+ pop.addSeparator();
+ }
+ }
+ else
+ {
+ if (!getParentContainer() || getParentContainer()->canClose())
+ {
+ pop.addCommand(L"Close window", ACTION_CLOSE_WINDOW);
+ pop.addSeparator();
+ }
+ }
+ PopupMenu *scalemenu = new PopupMenu();
+ scalemenu->addCommand(L"50%", ACTION_SCALE_50);
+ scalemenu->addCommand(L"75%", ACTION_SCALE_75, FALSE, FALSE);
+ scalemenu->addCommand(L"100%", ACTION_SCALE_100);
+ scalemenu->addCommand(L"125%", ACTION_SCALE_125);
+ scalemenu->addCommand(L"150%", ACTION_SCALE_150);
+ scalemenu->addCommand(L"200%", ACTION_SCALE_200);
+ scalemenu->addCommand(L"400%", ACTION_SCALE_400, FALSE, FALSE);
+ pop.addSubMenu(scalemenu, L"Scale");
+
+ PopupMenu *opaqmenu = new PopupMenu();
+ opaqmenu->addCommand(L"Auto-fade", ACTION_AUTOOPACIFY, getAutoOpacify(), FALSE);
+ opaqmenu->addSeparator();
+ opaqmenu->addCommand(L"100%", ACTION_ALPHA_100, FALSE, FALSE);
+ opaqmenu->addCommand(L"90%", ACTION_ALPHA_90, FALSE, FALSE);
+ opaqmenu->addCommand(L"80%", ACTION_ALPHA_80, FALSE, FALSE);
+ opaqmenu->addCommand(L"70%", ACTION_ALPHA_70, FALSE, FALSE);
+ opaqmenu->addCommand(L"60%", ACTION_ALPHA_60, FALSE, FALSE);
+ opaqmenu->addCommand(L"50%", ACTION_ALPHA_50, FALSE, FALSE);
+ opaqmenu->addCommand(L"40%", ACTION_ALPHA_40, FALSE, FALSE);
+ opaqmenu->addCommand(L"30%", ACTION_ALPHA_30, FALSE, FALSE);
+ opaqmenu->addCommand(L"20%", ACTION_ALPHA_20, FALSE, FALSE);
+ opaqmenu->addCommand(L"10%", ACTION_ALPHA_10, FALSE, FALSE);
+
+ pop.addSubMenu(opaqmenu, L"Opacity", !isTransparencySafe());
+
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ pop.addCommand(L"Always on top", ACTION_AOT, getAlwaysOnTop());
+#endif
+
+ int r = pop.popAtMouse();
+ if (r < 0) return ;
+ onActionNotify(r, 0);
+}
+
+void Layout::fixPosition()
+{
+ RECT r;
+ getWindowRect(&r);
+ RECT orig_r = r;
+
+ RECT vr;
+ RegionI reg;
+
+ int i = 0;
+ while (Wasabi::Std::enumViewports(i, &vr))
+ {
+ reg.addRect(&vr);
+ i++;
+ }
+
+ RECT full;
+ reg.getBox(&full);
+
+
+ int dif = r.bottom - full.bottom;
+ if (dif > 0) r.top -= dif;
+ dif = r.right - full.right;
+ if (dif > 0) r.left -= dif;
+ dif = full.top - r.top;
+ if (dif > 0) r.top += dif;
+ dif = full.left - r.left;
+ if (dif > 0) r.left += dif;
+
+ if (orig_r.left != r.left || orig_r.top != r.top)
+ resize(r.left, r.top, NOCHANGE, NOCHANGE);
+}
+
+void Layout::saveAllPositions()
+{
+ // The positions are saved from the lastest to the first one
+ // The 'Player' windows and the 'Main' windows are using the same prefix
+ // In saving in decreasing order we are sure the lastest saved is the one for the Player
+
+ for (int i = 0;i < SkinParser::script_getNumContainers();i++)
+ {
+ Container *c = SkinParser::script_enumContainer(i);
+ for (int j = c->getNumLayouts() - 1;j >= 0 ;--j)
+ {
+ Layout *l = c->enumLayout(j);
+ l->savePosition();
+ }
+ }
+}
+
+int Layout::forceTransparencyFlag()
+{
+ return alphaMgr->needForcedTransparencyFlag(this);
+}
+
+void Layout::savePosition()
+{
+#ifdef WASABI_COMPILE_CONFIG
+ if (!getParentContainer() || getParentContainer()->isTranscient())
+ return ;
+
+ if (!Wasabi::Std::Wnd::isValidWnd(getOsWindowHandle()))
+ return ;
+
+
+ StringW prefix = MakePrefix();
+ StringPrintfW tmp( L"%s/odim", prefix.v() );
+
+ SkinBitmap *baseTexture = getBaseTexture();
+
+ if ( baseTexture )
+ {
+ IntArray::write( tmp, baseTexture->getWidth(), baseTexture->getHeight() );
+ }
+ else
+ {
+ IntArray::write( tmp, -2, -2 );
+ }
+
+ RECT r, rs;
+ getClientRect(&r); // unscaled
+ //DebugStringW( L"\nLayout::savePosition() - x = %d, y = %d, w = %d, h = %d \n", r.left, r.top, r.right - r.left, r.bottom - r.top );
+
+ if (r.left == 0 && r.top == 0 && r.right == 0 && r.bottom == 0)
+ return ;
+
+ getWindowRect(&rs); // screen scaled (for x/y)
+ tmp.printf(L"%s/rect", prefix.v());
+ IntArray::write(tmp, rs.left, rs.top, r.right - r.left, r.bottom - r.top);
+ //DebugStringW( L"Layout::savePosition() rect - x = %d, y = %d, w = %d, h = %d \n", rs.left, rs.top, r.right - r.left, r.bottom - r.top );
+
+ getRestoredRect(&rs);
+ tmp.printf(L"%s/restoredrect", prefix.v());
+ IntArray::write(tmp, rs.left, rs.top, rs.right - rs.left, rs.bottom - rs.top);
+
+ //DebugStringW( L"Layout::savePosition() restoredrect - x = %d, y = %d, w = %d, h = %d \n", rs.left, rs.top, rs.right - rs.left, rs.bottom - rs.top );
+
+ tmp.printf(L"%s/maximized", prefix.v());
+ // DebugString("isMaximized = %d\n", isMaximized());
+ WASABI_API_CONFIG->setIntPrivate(tmp, isMaximized());
+
+ tmp.printf(L"%s/r", prefix.v());
+ WASABI_API_CONFIG->setStringPrivate(tmp, StringPrintfW(getRenderRatio()));
+
+ tmp.printf(L"%s/sm", prefix.v());
+ TextInfoCanvas textInfoCanvas(this);
+ WASABI_API_CONFIG->setStringPrivate(tmp, StringPrintfW(textInfoCanvas.getSystemFontScale()));
+
+ tmp.printf(L"%s/sl", prefix.v());
+ WASABI_API_CONFIG->setStringPrivate(tmp, StringPrintfW(scalelocked));
+
+ tmp.printf(L"%s/autoopacify", prefix.v());
+ IntArray::write(tmp, autoopacify);
+
+#ifdef USEAPPBAR
+ saveAppBarPosition();
+#endif
+
+#endif
+}
+#ifdef USEAPPBAR
+void Layout::saveAppBarPosition()
+{
+ if (m_allowsavedock)
+ {
+ StringW prefix = MakePrefix();
+ StringW wtmp = StringPrintfW(L"%s/appbar", prefix.v());
+ WASABI_API_CONFIG->setIntPrivate(wtmp, appbar_getSide());
+ wtmp.printf(L"%s/appbarontop", prefix.v());
+ WASABI_API_CONFIG->setIntPrivate(wtmp, appbar_wantAlwaysOnTop());
+ wtmp.printf(L"%s/appbarhidden", prefix.v());
+ WASABI_API_CONFIG->setIntPrivate(wtmp, appbar_isHiding());
+ wtmp.printf(L"%s/appbarisautohide", prefix.v());
+ WASABI_API_CONFIG->setIntPrivate(wtmp, appbar_isAutoHiding());
+ wtmp.printf(L"%s/appbarwantautohide", prefix.v());
+ WASABI_API_CONFIG->setIntPrivate(wtmp, appbar_wantAutoHide());
+ }
+}
+#endif
+void Layout::lockScale(int locked)
+{
+ scalelocked = locked;
+ StringW tmp;
+ StringW prefix = MakePrefix();
+ tmp.printf(L"%s/sl", prefix.v());
+ WASABI_API_CONFIG->setStringPrivate(tmp, StringPrintfW(scalelocked));
+}
+
+void Layout::resize(int x, int y, int w, int h, int wantcb)
+{
+ if (inresize) return ;
+ inresize = 1;
+ LAYOUT_PARENT::resize(x, y, w, h, wantcb);
+ if (!lockedto)
+ getGuiObject()->guiobject_setGuiPosition(&x, &y, &w, &h, NULL, NULL, NULL, NULL);
+ inresize = 0;
+}
+
+void Layout::move(int x, int y)
+{
+ //DebugStringW( L"Layout::move( x = %d, y = %d )\n", x, y );
+
+ LAYOUT_PARENT::move(x, y);
+ getGuiObject()->guiobject_setGuiPosition(&x, &y, NULL, NULL, NULL, NULL, NULL, NULL);
+}
+
+#define DC_CHECKLASTRESIZE 0x109
+#ifdef USEAPPBAR
+#define DC_LOADSAVEDDOCK 0x10A
+#endif
+#define DC_INVALIDATE 0x10B
+
+int Layout::onResize()
+{
+ LAYOUT_PARENT::onResize();
+ if (!abortSaving()) savePosition();
+ RECT r;
+ getClientRect(&r);
+ if (!linkedwidth.isempty())
+ {
+ if (!inlinkwidth)
+ {
+ inlinkwidth = 1;
+ RECT cr;
+ Layout *l = getParentContainer() ? getParentContainer()->getLayout(linkedwidth) : NULL;
+ if (l)
+ {
+ int _unlinked = l->isUnlinked();
+ _unlinked |= isUnlinked();
+ if (!_unlinked)
+ {
+ l->getClientRect(&cr);
+ POINT pt;
+ l->getPosition(&pt);
+ l->resize(pt.x, pt.y, r.right - r.left, cr.bottom - cr.top);
+ }
+ }
+ inlinkwidth = 0;
+ }
+ }
+ if (!linkedheight.isempty())
+ {
+ if (!inlinkheight)
+ {
+ inlinkheight = 1;
+ RECT cr;
+ Layout *l = getParentContainer() ? getParentContainer()->getLayout(linkedheight) : NULL;
+ if (l)
+ {
+ int _unlinked = l->isUnlinked();
+ _unlinked |= isUnlinked();
+ if (!_unlinked)
+ {
+ l->getClientRect(&cr);
+ POINT pt;
+ l->getPosition(&pt);
+ l->resize(pt.x, pt.y, cr.right - cr.left, r.bottom - r.top);
+ }
+ }
+ }
+ inlinkheight = 0;
+ }
+ updateLockedLayouts();
+
+ postDeferredCallback(DC_CHECKLASTRESIZE);
+
+ return 1;
+}
+
+int Layout::onDeferredCallback(intptr_t p1, intptr_t p2)
+{
+ /* if (p1 == DC_CHECKLASTRESIZE) {
+ RECT vr;
+ RECT r;
+ RECT wr;
+ Std::getViewport(&vr, NULL, NULL, gethWnd(), 1);
+ if (renderRatioActive())
+ divRatio(&vr);
+ getClientRect(&r);
+ r.bottom -= snap_adjust_bottom;
+ r.top += snap_adjust_top;
+ r.right -= snap_adjust_right;
+ r.left += snap_adjust_left;
+ getWindowRect(&wr);
+ int n = 0;
+ if (r.right-r.left > vr.right-vr.left) { r.right = r.left + vr.right-vr.left; n++; }
+ if (r.bottom-r.top > vr.bottom-vr.top) { r.bottom = r.top + vr.bottom-vr.top; n++; }
+ if (n) resize(wr.left, wr.top, r.right-r.left+snap_adjust_left+snap_adjust_right, r.bottom-r.top+snap_adjust_top+snap_adjust_bottom);
+ } else */
+#ifdef USEAPPBAR
+ if (p1 == DC_LOADSAVEDDOCK)
+ {}
+#endif
+
+ if (p1 == DC_INVALIDATE)
+ {
+ invalidate();
+ }
+ return LAYOUT_PARENT::onDeferredCallback(p1, p2);
+ // return 1;
+}
+
+void Layout::updateLockedLayouts()
+{
+ for (int i = 0;i < getNumLockedLayouts();i++)
+ {
+ Layout *l = enumLockedLayout(i);
+
+ if (l->getRenderRatio() != getRenderRatio())
+ l->setRenderRatio(getRenderRatio());
+
+ int x, y, w, h;
+ l->getGuiObject()->guiobject_getGuiPosition(&x, &y, &w, &h, NULL, NULL, NULL, NULL);
+ RECT r;
+ l->getClientRect(&r);
+ if (w == AUTOWH) w = r.right - r.left;
+ if (h == AUTOWH) h = r.bottom - r.top;
+ POINT pt;
+ l->getPosition(&pt);
+ if (x == AUTOWH) x = pt.x; else clientToScreen(&x, NULL);
+ if (y == AUTOWH) y = pt.y; else clientToScreen(NULL, &y);
+ RECT cr;
+ l->getWindowRect(&cr);
+ if (cr.left != x || cr.top != y || cr.right != cr.left + w || cr.bottom != cr.top + h)
+ l->Group::resize(x, y, w, h);
+ }
+}
+
+int Layout::isClickThrough()
+{
+ return 0;
+}
+#ifdef _WIN32
+LRESULT Layout::wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+
+#ifdef ON_CUSTOM_ALTF4
+ if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)
+ if (wParam == VK_F4)
+ if (GetAsyncKeyState(VK_MENU)&0x8000) ON_CUSTOM_ALTF4;
+#endif
+
+ if (uMsg == WM_KILLFOCUS || uMsg == WM_SETFOCUS)
+ {
+ alphaMgr->hoverCheck(this);
+ }
+
+ if (forwardMsgWnd != INVALIDOSWINDOWHANDLE)
+ {
+ switch (uMsg)
+ {
+ case WM_MOUSEWHEEL:
+ return (SendMessageW(forwardMsgWnd, uMsg, wParam, 0x31337)); // 0x31337 avoid main window callback
+ //case WM_DESTROY: //FG> commented out, makes wa quit when layout is destroyed
+ case WM_CLOSE:
+ return (SendMessageW(forwardMsgWnd, uMsg, wParam, lParam));
+
+ case WM_SETTINGCHANGE:
+ {
+ if (!indesktop) break;
+ setTimer(TIMER_SETTINGCHANGED, 1000);
+ }
+ break; //BU think this should be here eh
+
+#ifdef WIN32
+ case 0x0319:
+ { // hehe --BU
+ if (lParam & 0x20000)
+ FireAction(L"NEXT", NULL, 0, 0, NULL, 0, NULL, FALSE);
+ else
+ FireAction(L"PREV", NULL, 0, 0, NULL, 0, NULL, FALSE);
+ }
+ break;
+#endif
+ /*
+ WIP: This won't work anymore. What should we do about it? -- mig
+
+ childNotify(NULL, CHILD_NOTIFY_LEFTPUSH, ACTION_NEXT);
+ break;
+ */
+ }
+ }
+ return LAYOUT_PARENT::wndProc(hWnd, uMsg, wParam, lParam);
+}
+#else
+OSStatus Layout::eventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
+{
+ return LAYOUT_PARENT::eventHandler(inHandlerCallRef, inEvent, inUserData);
+}
+#warning port me
+#endif
+
+/*int Layout::onRightButtonDown(int x, int y) {
+ LAYOUT_PARENT::onRightButtonDown(x, y);
+// Main::appContextMenu(this, TRUE, isTransparencySafe());
+ return 1;
+}*/
+
+ifc_window *Layout::getCustomOwner()
+{
+ if (noparent) return NULL;
+ if (owner.isempty()) return NULL;
+ return SkinParser::getLayout(owner);
+}
+
+void Layout::addLockedLayout(Layout *l)
+{
+ locked.addItem(l);
+ updateLockedLayouts();
+}
+
+void Layout::removeLockedLayout(Layout *l)
+{
+ locked.removeItem(l);
+}
+
+int Layout::getNumLockedLayouts()
+{
+ return locked.getNumItems();
+}
+
+Layout *Layout::enumLockedLayout(int n)
+{
+ return locked.enumItem(n);
+}
+
+int Layout::isLocked()
+{
+ return (!lockto.isempty()
+ #ifdef USEAPPBAR
+ || cfg_options_appbarondrag == 0 && appbar_isDocked()
+#endif
+ );
+}
+
+void Layout::lockTo(Layout *t)
+{
+ if (t == NULL) return ;
+ if (lockedto) lockedto->removeLockedLayout(this);
+ lockedto = t;
+ t->addLockedLayout(this);
+}
+
+Layout *Layout::getLockedTo()
+{
+ return lockedto;
+}
+
+int Layout::reinit(OSMODULEHANDLE inst, OSWINDOWHANDLE parent, int nochild)
+{
+ StringW osname = getOSWndName();
+ ASSERTPR(!indesktop, "in desktop reinit failed");
+ if (noparent)
+ parent = NULL;
+ int r = LAYOUT_PARENT::reinit(inst, parent, nochild);
+ setOSWndName(osname);
+ return r;
+}
+
+int Layout::init(OSMODULEHANDLE inst, OSWINDOWHANDLE parent, int nochild)
+{
+ if (noparent) parent = NULL;
+ if (!indesktop) return LAYOUT_PARENT::init(inst, parent, nochild);
+
+#ifdef _WIN32
+ webserver = INVALIDOSWINDOWHANDLE;
+ listview = INVALIDOSWINDOWHANDLE;
+
+ getExplorerWindows(&parent, &listview, &webserver);
+
+ if (!parent)
+ {
+ indesktop = 0;
+ return LAYOUT_PARENT::init(inst, parent, nochild);
+ }
+#endif
+ nochild = 0;
+
+#ifdef _WIN32
+ // if active desktop is off, that's all we can do, we'll be on top of the icons
+ // if active desktop is on, but listview is not, we'll be on top of active desktop
+ if (!webserver || !listview) return LAYOUT_PARENT::init(inst, parent, nochild);
+#endif
+
+#ifdef WIN32
+ // find who we're gonna sit on top of
+ HWND behind = listview;
+ if (GetWindow(listview, GW_HWNDPREV))
+ behind = GetWindow(listview, GW_HWNDPREV);
+#else
+ DebugString( "portme -- Layout::init\n" );
+#endif
+
+ int r = LAYOUT_PARENT::init(inst, parent, nochild);
+#ifdef WIN32
+ SetWindowPos(gethWnd(), behind, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE);
+#endif
+
+ return r;
+}
+
+#ifdef WIN32
+void Layout::getExplorerWindows(OSWINDOWHANDLE *parent, OSWINDOWHANDLE *listview, OSWINDOWHANDLE *webserver)
+{
+ *parent = NULL;
+ *listview = NULL;
+ *webserver = NULL;
+
+ char classname[256] = "";
+ HWND w;
+
+ // find explorer window. todo: litestep support ?
+ *parent = FindWindowA(NULL, "Program Manager");
+ if (!*parent) return ;
+
+ // find its first child for parenting
+ *parent = GetWindow(*parent, GW_CHILD);
+ if (!*parent) return ;
+
+ // find the children
+ w = GetWindow(*parent, GW_CHILD);
+
+ while (w)
+ {
+ GetClassNameA(w, classname, 255);
+ if (!*webserver && STRCASEEQL("Internet Explorer_Server", classname))
+ *webserver = w;
+ if (!*listview && STRCASEEQL("SysListView32", classname))
+ *listview = w;
+ w = GetWindow(w, GW_HWNDNEXT);
+ }
+}
+#endif
+
+int Layout::onInit()
+{
+ LAYOUT_PARENT::onInit();
+
+ Container *c = getParentContainer();
+ if (c != NULL)
+ {
+ const wchar_t *s = c->getName();
+ if (s != NULL)
+ {
+ setOSWndName(s);
+ }
+ }
+
+ loadSavedState();
+
+#ifdef WA3COMPATIBILITY
+ setIcon(WASABI_API_APP->main_getIcon(TRUE), TRUE);
+ setIcon(WASABI_API_APP->main_getIcon(FALSE), FALSE);
+#endif
+
+ WASABI_API_WNDMGR->wndTrackAdd(this);
+
+ if (wantDesktopAlpha() && isDesktopAlphaSafe())
+ desktopAlpha_autoTurnOn();
+
+ if (getBaseTexture())
+ {
+ //RECT r = {0, 0, getBaseTexture()->getWidth(), getBaseTexture()->getHeight()};
+ delete reg;
+#ifdef _WIN32
+ reg = new RegionI(getBaseTexture(), NULL, 0, 0, 0, 0, 0, 0, getDesktopAlpha() ? 1 : 255);
+ setRegion(reg);
+#else
+#warning port me
+#endif
+ }
+
+ SystemObject::onCreateLayout(this);
+
+ if (!lockto.isempty()) lockTo(SkinParser::getLayout(lockto));
+
+ updateOnTop();
+
+ setNoOffscreenCheck( -1);
+
+ return 1;
+}
+
+void Layout::updateOnTop()
+{
+ #ifdef USEAPPBAR
+ if (!appbar_isDocked())
+#endif
+ {
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ setAlwaysOnTop(initontop);
+#else
+ if (noparent)
+ {
+ int disable = 0;
+#ifdef WASABI_GET_TEMPDISABLE_AOT
+ WASABI_GET_TEMPDISABLE_AOT(disable);
+#endif
+#ifdef _WIN32
+ if (initontop && !disable) SetWindowPos(getOsWindowHandle(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
+ else SetWindowPos(getOsWindowHandle(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
+#else
+#warning port me
+#endif
+ }
+#endif
+
+ }
+}
+
+void Layout::loadSavedState()
+{
+#ifdef WASABI_COMPILE_CONFIG
+ StringW tmp;
+#endif
+ wchar_t t[64] = L"";
+
+ int ow = -1;
+ int oh = -1;
+ int ra = -1;
+
+#ifdef WASABI_COMPILE_CONFIG
+ if (getParentContainer() && !getParentContainer()->isTranscient())
+ {
+ StringW prefix = MakePrefix();
+ tmp.printf(L"%s/odim", prefix.v());
+ IntArray::read(tmp, &ow, &oh);
+
+ tmp.printf(L"%s/alpha", prefix.v());
+ IntArray::read(tmp, &ra);
+
+ tmp.printf(L"%s/autoopacify", prefix.v());
+ IntArray::read(tmp, &autoopacify);
+
+ }
+#endif
+
+ int from_scratch = 0;
+ if (Std::keyModifier(STDKEY_SHIFT) && Std::keyModifier(STDKEY_ALT) && Std::keyModifier(STDKEY_CONTROL)) from_scratch = 1;
+#ifdef WASABI_COMPILE_CONFIG
+ if (getParentContainer() && !getParentContainer()->isTranscient())
+ {
+ StringW prefix = MakePrefix();
+ tmp.printf(L"%s/sl", prefix.v());
+ WASABI_API_CONFIG->getStringPrivate(tmp, t, 63, L"0");
+ lockScale(WTOI(t));
+ }
+#endif
+
+ *t = 0;
+#ifdef WASABI_COMPILE_CONFIG
+ if (getParentContainer() && !getParentContainer()->isTranscient())
+ {
+ StringW prefix = MakePrefix();
+ tmp.printf(L"%s/sm", prefix.v());
+ }
+
+ WASABI_API_CONFIG->getStringPrivate(tmp, t, 63, L"1.");
+ //double sm = (float)WTOF(t);
+#else
+ //double sm = 1.0;
+#endif
+ /*if (ABS(sm - Canvas::getSystemFontScale()) > 0.001)
+ from_scratch = 1;*/
+
+ if (Group::getBaseTexture() && alphabackground.getBitmap() != NULL)
+ {
+ if (Group::getBaseTexture()->getWidth() != alphabackground.getWidth() || Group::getBaseTexture()->getHeight() != alphabackground.getHeight())
+ {
+ ASSERTPR(0, StringPrintf("layout %S should have same size for background and alphabackground", getGuiObject()->guiobject_getParentLayout()->getGuiObject()->guiobject_getId()));
+ }
+ }
+
+ if ((ow != -2 && oh != -2) && (ow == -1 || oh == -1 || (getBaseTexture() && (ow != getBaseTexture()->getWidth() || oh != getBaseTexture()->getHeight()))))
+ from_scratch = 1;
+
+ int w = 0, h = 0;
+ int findrect = 0;
+
+ if (from_scratch || (getParentContainer() && getParentContainer()->isTranscient()))
+ {
+ if (getParentContainer())
+ {
+ int _x = getParentContainer()->getDefaultPositionX();
+ int _y = getParentContainer()->getDefaultPositionY();
+ x = _x == -1 ? x : _x;
+ y = _y == -1 ? y : _y;
+ if (x == -1 && y == -1) findrect = 1;
+ }
+ else
+ {
+ int _x, _y;
+ getGuiObject()->guiobject_getGuiPosition(&_x, &_y, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (_x != AUTOWH && _x != NOCHANGE) x = _x;
+ if (_y != AUTOWH && _y != NOCHANGE) y = _y;
+ }
+ getGuiObject()->guiobject_getGuiPosition(NULL, NULL, &w, &h, NULL, NULL, NULL, NULL);
+ if (w == AUTOWH || h == AUTOWH)
+ {
+ w = getPreferences(SUGGESTED_W);
+ h = getPreferences(SUGGESTED_H);
+ int _minx = getPreferences(MINIMUM_W);
+ int _maxx = getPreferences(MAXIMUM_W);
+ int _miny = getPreferences(MINIMUM_H);
+ int _maxy = getPreferences(MAXIMUM_H);
+ if (_minx != AUTOWH && _maxx != AUTOWH && _minx > _maxx) _minx = _maxx;
+ if (_miny != AUTOWH && _maxy != AUTOWH && _miny > _maxy) _miny = _maxy;
+ if (w == AUTOWH && _minx != AUTOWH) w = _minx;
+ if (h == AUTOWH && _miny != AUTOWH) h = _miny;
+ TextInfoCanvas textInfoCanvas(this);
+ double fontScale = textInfoCanvas.getSystemFontScale();
+ if (w != AUTOWH && getGuiObject()->guiobject_getAutoSysMetricsW())
+ w = (int)((float)w * fontScale);
+ if (h != AUTOWH && getGuiObject()->guiobject_getAutoSysMetricsH())
+ h = (int)((float)h * fontScale);
+ }
+ }
+ else
+ {
+ if (getParentContainer())
+ {
+
+ if (getParentContainer()->isMainContainer()) //FG> could be a new component installed
+ SkinParser::noCenterSkin();
+
+#ifdef WASABI_COMPILE_CONFIG
+ StringW prefix = MakePrefix();
+
+ tmp.printf(L"%s/rect", prefix.v());
+ IntArray::read(tmp, &x, &y, &w, &h);
+
+ RECT rr;
+ tmp.printf(L"%s/restoredrect", prefix.v());
+ IntArray::read(tmp, (int*)&rr.left, (int*)&rr.top, (int*)&rr.right, (int*)&rr.bottom);
+ rr.right += rr.left;
+ rr.bottom += rr.top;
+
+ tmp.printf(L"%s/maximized", prefix.v());
+ if (WASABI_API_CONFIG->getIntPrivate(tmp, 0)) setRestoredRect(&rr);
+
+#endif
+
+ }
+ }
+
+ *t = 0;
+ double ratio = 1.0;
+
+ if (!from_scratch)
+ {
+ if (getParentContainer())
+ {
+#ifdef WASABI_COMPILE_CONFIG
+ StringW prefix = MakePrefix();
+ tmp.printf(L"%s/r", prefix.v());
+
+ WASABI_API_CONFIG->getStringPrivate(tmp, t, 63, L"1.");
+ ratio = WTOF(t);
+#else
+ ratio = 1.0f;
+#endif
+
+ }
+ }
+
+#ifdef ON_TWEAK_RENDER_RATIO
+ if (!scalelocked) ON_TWEAK_RENDER_RATIO(ratio);
+#endif
+
+ if (w == 0 || h == 0 || from_scratch)
+ {
+ int _w = getPreferences(SUGGESTED_W);
+ w = _w == AUTOWH ? w : _w;
+ int _h = getPreferences(SUGGESTED_H);
+ h = _h == AUTOWH ? h : _h;
+
+ TextInfoCanvas textInfoCanvas(this);
+ double fontScale = textInfoCanvas.getSystemFontScale();
+
+ if (getGuiObject()->guiobject_getAutoSysMetricsW())
+ w = (int)((float)w * fontScale);
+ if (getGuiObject()->guiobject_getAutoSysMetricsH())
+ h = (int)((float)h * fontScale);
+ if (w == 0 || h == 0)
+ {
+ w = getBaseTexture()->getWidth();
+ h = getBaseTexture()->getHeight();
+ }
+ RECT sr = {x, y, x + w, y + h};
+ if (findrect)
+ sr = windowTracker->findOpenRect(Wasabi::Std::makeRect(0, 0, (int)((float)w * getRenderRatio()), (int)((float)h * getRenderRatio())), this);
+ sr.right = sr.left + w;
+ sr.bottom = sr.top + h;
+ BaseWnd::resize(&sr);
+ }
+ else
+ {
+ RECT cr;
+ getClientRect(&cr);
+ RECT r = {x, y, x + w, y + h};
+ BaseWnd::resize(&r);
+ }
+
+ setAlpha(from_scratch || ra == -1 ? alpha : ((ra < 254) ? ra : 255));
+
+ Layout *main = SkinParser::getMainLayout();
+ if (main != this && main
+ #ifdef WASABI_COMPILE_CONFIG
+ && cfg_uioptions_linkallratio.getValueAsInt()
+#endif
+ && !noparent)
+ {
+ setRenderRatio(main->getRenderRatio());
+ }
+ else setRenderRatio(ratio);
+
+ setAutoOpacify(autoopacify);
+
+#ifdef USEAPPBAR
+ postDeferredCallback(DC_LOADSAVEDDOCK);
+
+ if (getParentContainer() && !getParentContainer()->isTranscient())
+ {
+ StringW prefix = MakePrefix();
+ StringW tmp = StringPrintfW(L"%s/appbar", prefix.v());
+ int side = WASABI_API_CONFIG->getIntPrivate(tmp, APPBAR_NOTDOCKED);
+ tmp.printf(L"%s/appbarisautohide", prefix.v());
+ int is_autohide = WASABI_API_CONFIG->getIntPrivate(tmp, 0);
+ tmp.printf(L"%s/appbarwantautohide", prefix.v());
+ appbar_want_autohide = is_autohide || WASABI_API_CONFIG->getIntPrivate(tmp, 1);
+ tmp.printf(L"%s/appbarontop", prefix.v());
+ appbar_want_alwaysontop = WASABI_API_CONFIG->getIntPrivate(tmp, 1);
+ tmp.printf(L"%s/appbarhidden",prefix.v());
+ int curside = appbar_getSide();
+ if (side != curside)
+ {
+ if (side == APPBAR_NOTDOCKED)
+ // starting up docked ??
+ appbar_dock(side);
+ else
+ {
+ setNoParent(2);
+ BaseWnd::reinit();
+ appbar_dock(side);
+ }
+ }
+ }
+ m_allowsavedock = 1;
+
+#endif
+}
+
+void Layout::setBaseTexture(const wchar_t *b, int regis)
+{
+ LAYOUT_PARENT::setBaseTexture(b, 0); // 0, not regis!
+ if (!getDesktopAlpha() || ((wantDesktopAlpha()) && alphabackground.getBitmap() == NULL))
+ {
+ if (regis) WASABI_API_WND->skin_unregisterBaseTextureWindow(this);
+ if (getBaseTexture())
+ {
+ //RECT r = {0, 0, getBaseTexture()->getWidth(), getBaseTexture()->getHeight()};
+ delete reg;
+#ifdef _WIN32
+ reg = new RegionI(getBaseTexture(), NULL, 0, 0, 0, 0, 0, 0, getDesktopAlpha() ? 1 : 255);
+ setRegion(reg);
+#else
+#warning port me
+#endif
+ }
+ if (regis)
+ WASABI_API_WND->skin_registerBaseTextureWindow(this, getBackgroundStr());
+ }
+}
+
+void Layout::setWantDesktopAlpha(int want)
+{
+ if (want && !Wasabi::Std::Wnd::isDesktopAlphaAvailable())
+ {
+ // WASABI_API_WNDMGR->messageBox("Desktop Alpha Blending is only available for Win2000/WinXP and above", "Sorry", MSGBOX_OK, NULL, NULL);
+ return ;
+ }
+ wantdesktopalpha = want;
+ if (wantdesktopalpha && isInited() && isDesktopAlphaSafe())
+ desktopAlpha_autoTurnOn();
+ else if (!wantdesktopalpha && getDesktopAlpha())
+ desktopAlpha_autoTurnOff();
+}
+
+int Layout::wantDesktopAlpha()
+{
+ return wantdesktopalpha;
+}
+
+int Layout::handleDesktopAlpha()
+{
+ return 1;
+}
+
+void Layout::onGuiObjectSetVisible(GuiObject *o, int visible)
+{
+ if (disable_auto_alpha) return ;
+ if (!o || !o->guiobject_getRootWnd()) return ;
+ if (visible)
+ {
+ if (getDesktopAlpha())
+ {
+ if (!o->guiobject_getRootWnd()->handleDesktopAlpha())
+ {
+ desktopAlpha_autoTurnOff();
+ }
+ }
+ if (!transparency_autooff)
+ {
+ if (!o->guiobject_getRootWnd()->handleTransparency())
+ {
+ transparency_autoTurnOff();
+ }
+ }
+ }
+ else
+ { // !visible
+ if (!getDesktopAlpha() && wantDesktopAlpha())
+ {
+ if (isDesktopAlphaSafe())
+ desktopAlpha_autoTurnOn();
+ }
+ if (transparency_autooff)
+ {
+ if (isTransparencySafe(1))
+ transparency_autoTurnOn();
+ }
+ }
+}
+
+void Layout::desktopAlpha_autoTurnOn()
+{
+
+ setDesktopAlpha(1);
+
+ WASABI_API_WND->skin_unregisterBaseTextureWindow(this);
+
+ if (getBaseTexture())
+ {
+ //RECT r = {0, 0, getBaseTexture()->getWidth(), getBaseTexture()->getHeight()};
+ delete reg;
+#ifdef _WIN32
+ reg = new RegionI(getBaseTexture(), NULL, 0, 0, 0, 0, 0, 0, 1);
+ setRegion(reg);
+#else
+#warning port me
+#endif
+ }
+
+ WASABI_API_WND->skin_registerBaseTextureWindow(this, alphabackground.getBitmap() ? alphabackgroundstr.getValue() : getBackgroundStr());
+
+ invalidate();
+}
+
+void Layout::desktopAlpha_autoTurnOff()
+{
+#ifdef WIN32
+ SetWindowRedraw(gethWnd(), FALSE);//LockWindowUpdate(gethWnd());
+ setDesktopAlpha(0);
+
+ WASABI_API_WND->skin_unregisterBaseTextureWindow(this);
+
+ if (getBaseTexture())
+ {
+ //RECT r = {0, 0, getBaseTexture()->getWidth(), getBaseTexture()->getHeight()};
+ delete reg;
+ reg = new RegionI(getBaseTexture(), NULL, 0, 0, 0, 0, 0, 0, 255);
+ setRegion(reg);
+ }
+
+ WASABI_API_WND->skin_registerBaseTextureWindow(this, getBackgroundStr());
+ SetWindowRedraw(gethWnd(), TRUE);//LockWindowUpdate(NULL);
+
+ invalidate();
+#else
+ DebugString( "portme -- Layout::init\n" );
+#endif
+}
+
+void Layout::transparency_autoTurnOn()
+{
+ transparency_reenabled_at = Wasabi::Std::getTickCount();
+ setTimer(TIMER_TRANSPARENCY_AUTOON, 500);
+}
+
+void Layout::transparency_autoTurnOff()
+{
+ transparency_autooff = 1;
+ killTimer(TIMER_TRANSPARENCY_AUTOON);
+ updateTransparency();
+}
+
+void Layout::onGlobalEnableDesktopAlpha(int enabled)
+{
+ foreach(alllayouts)
+ alllayouts.getfor()->globalEnableDesktopAlpha(enabled);
+ endfor
+#ifdef ON_TOGGLE_DESKTOPALPHA
+ ON_TOGGLE_DESKTOPALPHA(enabled);
+#endif
+}
+
+void Layout::globalEnableDesktopAlpha(int enabled)
+{
+ if (enabled)
+ {
+ galphadisabled = 0;
+ setWantDesktopAlpha(wantdesktopalpha);
+ }
+ else
+ {
+ galphadisabled = 1;
+ if (getDesktopAlpha())
+ desktopAlpha_autoTurnOff();
+ }
+}
+
+void Layout::setWantRedrawOnResize(int v)
+{
+ if (wantredrawonresize == v) return ;
+ wantredrawonresize = v;
+}
+
+PtrList<Layout> Layout::alllayouts;
+
+int Layout::onPaint(Canvas *canvas)
+{
+ PaintCanvas paintcanvas;
+ if (canvas == NULL)
+ {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+
+ RECT r;
+
+ if (!canvas->getClipBox(&r))
+ getClientRect(&r);
+
+ canvas->fillRect(&r, 0);
+
+ LAYOUT_PARENT::onPaint(canvas);
+
+ return 1;
+}
+
+/*WndHolder *Layout::getHolder() {
+ return this;
+}*/
+
+SkinBitmap *Layout::getBaseTexture()
+{
+#ifdef WASABI_COMPILE_CONFIG
+ // {9149C445-3C30-4e04-8433-5A518ED0FDDE}
+ const GUID uioptions_guid =
+ { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
+ int alphaenabled = _intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid), L"Enable desktop alpha");
+#else
+ int alphaenabled = WASABI_WNDMGR_DESKTOPALPHA;
+#endif
+ if (!alphabackground.getBitmap() || !getDesktopAlpha() || !alphaenabled) return LAYOUT_PARENT::getBaseTexture();
+ return alphabackground.getBitmap();
+}
+
+int Layout::runAction(int actionid, const wchar_t *param)
+{
+ switch (actionid)
+ {
+ case ACTION_SWITCH:
+ if (getParentContainer())
+ {
+ getParentContainer()->switchToLayout(param);
+ }
+ break;
+ case ACTION_TOGGLE:
+ SkinParser::toggleContainer(param);
+ break;
+#ifdef WA3COMPATIBILITY
+ case ACTION_MENU:
+ Main::doMenu(param);
+ break;
+#endif
+ case ACTION_ENDMODAL:
+ endModal(WTOI(param));
+ break;
+ case ACTION_CLOSE:
+ onActionNotify(ACTION_CLOSE);
+ break;
+#ifdef WA3COMPATIBILITY
+ default:
+ if (actionid != 0)
+ Main::doAction(actionid);
+ break;
+#else
+ case ACTION_MINIMIZE:
+#ifdef _WIN32
+ ShowWindow(WASABI_API_WND->main_getRootWnd()->gethWnd(), SW_MINIMIZE);
+#endif
+ break;
+#endif
+
+ }
+ return 0;
+}
+
+int Layout::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2)
+{
+ if (msg == ACTION_ENFORCEMINMAX)
+ {
+ loadSavedState();
+ return 0;
+ }
+ if (child != NULL)
+ {
+ int objId = child->getNotifyId();
+ if (msg == ChildNotify::BUTTON_LEFTPUSH)
+ {
+ switch (objId)
+ {
+ case ACTION_SWITCH:
+ case ACTION_TOGGLE:
+ case ACTION_MENU:
+ runAction(objId, ((Wasabi::Button *)child)->getParam());
+ break;
+ case ACTION_ENDMODAL:
+ {
+ StringPrintfW s(L"%d", (static_cast<ButtonWnd *>(child))->getModalRetCode());
+ runAction(ACTION_ENDMODAL, s);
+ }
+ break;
+ case ACTION_CLOSE:
+ runAction(ACTION_CLOSE);
+ break;
+ /*
+ #ifdef WA3COMPATIBILITY
+ case ACTION_EJECT:
+ runAction(ACTION_EJECT, "0");
+ break;
+ #endif
+ */
+ default:
+ runAction(objId);
+ break;
+ }
+ return 0;
+ }
+ if (msg == ChildNotify::BUTTON_RIGHTPUSH)
+ {
+ //FUCKO child->abortTip();
+ // POINT pt;
+ // Std::getMousePos(&pt);
+ // screenToClient(&pt);
+ // onRightButtonDown(pt.x, pt.y);
+#pragma warning (disable: 4060)
+ switch (objId)
+ {
+ /*
+ #ifdef WA3COMPATIBILITY
+ case ACTION_EJECT: {
+ runAction(ACTION_EJECT, "1");
+ }
+ break;
+ #endif
+ */
+ }
+#pragma warning (default: 4060)
+ return 0;
+ }
+ }
+ return LAYOUT_PARENT::childNotify(child, msg, param1, param2);
+}
+
+int Layout::onActionNotify(int action, intptr_t param)
+{
+ switch (action)
+ {
+#ifdef WA3COMPATIBILITY
+ case ACTION_SYSMENU:
+ Main::appContextMenu(this, TRUE, isDesktopAlphaSafe());
+ break;
+ case ACTION_CONTROLMENU:
+ controlMenu();
+ break;
+ case ACTION_WINDOWMENU:
+ Main::thingerContextMenu(this);
+ break;
+#elif defined(WASABI_CUSTOM_CONTEXTMENUS)
+ case ACTION_SYSMENU:
+ extern void appContextMenu(ifc_window *w);
+ appContextMenu(this);
+ break;
+ case ACTION_CONTROLMENU:
+ extern void appControlMenu(ifc_window *w);
+ appControlMenu(this);
+ break;
+#endif
+ case ACTION_SCALE_50: scaleTo(50); break;
+ case ACTION_SCALE_75: scaleTo(75); break;
+ case ACTION_SCALE_100: scaleTo(100); break;
+ case ACTION_SCALE_125: scaleTo(125); break;
+ case ACTION_SCALE_150: scaleTo(150); break;
+ case ACTION_SCALE_200: scaleTo(200); break;
+ case ACTION_SCALE_400: scaleTo(400); break;
+ case ACTION_ALPHA_10: setAlpha(25); break;
+ case ACTION_ALPHA_20: setAlpha(51); break;
+ case ACTION_ALPHA_30: setAlpha(76); break;
+ case ACTION_ALPHA_40: setAlpha(102); break;
+ case ACTION_ALPHA_50: setAlpha(127); break;
+ case ACTION_ALPHA_60: setAlpha(153); break;
+ case ACTION_ALPHA_70: setAlpha(178); break;
+ case ACTION_ALPHA_80: setAlpha(204); break;
+ case ACTION_ALPHA_90: setAlpha(229); break;
+ case ACTION_ALPHA_100: setAlpha(255); break;
+ case ACTION_AUTOOPACIFY: setAutoOpacify(!getAutoOpacify()); break;
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ case ACTION_AOT: setAlwaysOnTop(!getAlwaysOnTop()); break;
+#endif
+ case ACTION_CLOSE_WINDOW:
+ case ACTION_CLOSE:
+ if (getParentContainer() && getParentContainer()->isMainContainer())
+ {
+ int x = 1;
+#ifdef WASABI_CHECK_CAN_EXIT
+ WASABI_CHECK_CAN_EXIT(x)
+#endif
+ if (x)
+ {
+ WASABI_API_APP->main_shutdown();
+ }
+ }
+ else if (WASABI_API_WNDMGR->getModalWnd() != this)
+ {
+ if (!getParentContainer() || !getParentContainer()->isDynamic() || !getParentContainer()->canClose())
+ if (getParentContainer()) getParentContainer()->setVisible(FALSE); else setVisible(FALSE);
+ else
+ skinEmbedder->destroyContainer(getParentContainer());
+ }
+ else
+ {
+ endModal(MSGBOX_ABORTED);
+ }
+ break;
+ default: return 0;
+ }
+ return 1;
+}
+
+void Layout::containerToggled(const wchar_t *id, int visible)
+{
+ #ifdef _WIN32
+ sendNotifyToAllChildren(WM_WA_CONTAINER_TOGGLED, (intptr_t)id, visible);
+#else
+#warning port me
+#endif
+}
+
+void Layout::componentToggled(GUID *guid, int visible)
+{
+#ifdef _WIN32
+ sendNotifyToAllChildren(WM_WA_COMPONENT_TOGGLED, (intptr_t)guid, visible);
+#else
+#warning port me
+#endif
+}
+
+void Layout::setAlphaBackground(const wchar_t *b)
+{
+ alphabackgroundstr = b;
+ alphabackground.setBitmap(b);
+#ifdef _WIN32
+ RegionI r(alphabackground.getBitmap());
+ setRegion(&r);
+#else
+#warning port me
+#endif
+}
+
+/*void Layout::setWindowRegion(api_region *reg) {
+ LAYOUT_PARENT::setWindowRegion(reg);
+ if (getDesktopAlpha()) {
+ SetWindowRgn(gethWnd(), NULL, FALSE);
+ return;
+ }
+ if (!isInited()) return;
+ api_region *_r = getRegion();
+ if (getRenderRatio() != 1.0 && reg) {
+ api_region *clone = _r->clone();
+ clone->scale(getRenderRatio());
+ SetWindowRgn(gethWnd(), clone->makeWindowRegion(), TRUE);
+ _r->disposeClone(clone);
+ } else {
+ SetWindowRgn(gethWnd(), _r ? _r->makeWindowRegion() : NULL, TRUE);
+ }
+}*/
+
+void Layout::onSetDesktopAlpha(int a)
+{
+ invalidateWindowRegion();
+}
+
+void Layout::onShow(void)
+{
+ savePosition();
+ if (!WASABI_API_MAKI->vcpu_getComplete()) SystemObject::onShowLayout(this);
+}
+
+void Layout::onHide(void)
+{
+ savePosition();
+ if (!WASABI_API_MAKI->vcpu_getComplete()) SystemObject::onHideLayout(this);
+#ifndef WASABINOMAINAPI
+ api->hintGarbageCollect();
+#else
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::GC, GarbageCollectCallback::GARBAGECOLLECT);
+#endif
+ if (getParentContainer() && getParentContainer()->wantRefocusApp()) SkinParser::focusFirst();
+}
+
+#ifdef _WIN32
+LPARAM Layout::wndHolder_getParentParam(int i)
+{
+ switch (i)
+ {
+ case 0: return (LPARAM)gethWnd();
+ case 1: return (LPARAM)static_cast<BaseWnd*>(this);
+ }
+ return 0;
+}
+#endif
+
+void Layout::onSetVisible( int show )
+{
+ disable_auto_alpha = 1;
+ LAYOUT_PARENT::onSetVisible( show );
+
+ if ( show )
+ onShow();
+ else
+ onHide();
+
+ Container *p = getParentContainer();
+
+ if ( p )
+ p->onChildSetLayoutVisible( this, show );
+
+ disable_auto_alpha = 0;
+
+ if ( wantDesktopAlpha() && isDesktopAlphaSafe() )
+ desktopAlpha_autoTurnOn();
+}
+
+void Layout::scaleTo(int s)
+{
+ beginScale();
+ setRenderRatio((double)s / 100.0);
+ endScale();
+}
+
+void Layout::setRenderRatio(double s)
+{
+ if (isPostOnInit()
+ #ifdef WASABI_COMPILE_CONFIG
+ && cfg_uioptions_linkallratio.getValueAsInt() == 1
+#endif
+ && !broadcasting)
+ {
+ broadcasting = 1;
+ SkinParser::setAllLayoutsRatio(s);
+ broadcasting = 0;
+ return ;
+ }
+ if (getRenderRatio() == s) return ;
+ LAYOUT_PARENT::setRenderRatio(s);
+ if (reg) invalidateWindowRegion();
+ invalidate();
+ foreach(locked)
+ locked.getfor()->setRenderRatio(s);
+ endfor;
+ if (lockedto && lockedto->getRenderRatio() != getRenderRatio())
+ lockedto->setRenderRatio(getRenderRatio());
+ script_vcpu_onScale(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_DOUBLE(s));
+ if (!abortSaving()) savePosition();
+}
+
+void Layout::setAlpha(int a)
+{
+ int old = alpha;
+ alpha = a;
+ updateTransparency();
+#ifdef WASABI_COMPILE_CONFIG
+ if (old != alpha && getParentContainer())
+ {
+ StringPrintfW tmp(L"Skin:%s/Container:%s/Layout:%s/alpha", WASABI_API_SKIN->getSkinName(), getParentContainer()->getDescriptor(), getGuiObject()->guiobject_getId());
+ IntArray::write(tmp, alpha);
+ }
+#endif
+}
+
+int Layout::getAlpha()
+{
+ return alpha;
+}
+
+void Layout::setPaintingAlpha(int activealpha, int inactivealpha)
+{ // from basewnd, called by gui object
+ LAYOUT_PARENT::setAlpha(activealpha, inactivealpha);
+ updateTransparency();
+}
+
+int Layout::getPaintingAlpha()
+{ // from basewnd, called by gui object
+ return getAlpha();
+}
+
+int Layout::onActivate()
+{
+ LAYOUT_PARENT::onActivate();
+ // activateChildren(1);
+ updateTransparency();
+ return 1;
+}
+
+int Layout::onKillFocus()
+{
+ alphaMgr->hoverCheck(this);
+ int r = LAYOUT_PARENT::onKillFocus();
+ return r;
+}
+
+int Layout::onGetFocus()
+{
+ alphaMgr->hoverCheck(this);
+ int r = LAYOUT_PARENT::onGetFocus();
+ return r;
+}
+
+int Layout::onDeactivate()
+{
+ LAYOUT_PARENT::onDeactivate();
+ // activateChildren(0);
+ updateTransparency();
+ return 1;
+}
+
+void Layout::updateTransparency()
+{
+ alphaMgr->updateTransparency(this);
+}
+
+/*
+void Layout::activateChildren(int act) {
+ for (int i=0;i<gui_objects.getNumItems();i++) {
+ GuiObject *o = gui_objects.enumItem(i);
+ BaseWnd *b = NULL;
+ if (o)
+ b = o->getBaseWnd();
+ else
+ ASSERT(0);
+ if (b) {
+ if (act)
+ b->onActivate();
+ else
+ b->onDeactivate();
+ }
+ }
+}*/
+
+void Layout::center()
+{
+ RECT r;
+ getNonClientRect(&r);
+ RECT vw;
+ Wasabi::Std::getViewport(&vw, NULL, NULL, gethWnd());
+ int x = ((vw.right - vw.left) - (r.right - r.left)) / 2;
+ int y = ((vw.bottom - vw.top) - (r.bottom - r.top)) / 2;
+ move(x, y);
+}
+
+void Layout::setParentContainer(Container *c)
+{
+ p_container = c;
+}
+
+Container *Layout::getParentContainer()
+{
+ return p_container;
+}
+
+int Layout::isLayout()
+{
+ return 1;
+}
+
+void Layout::setInDesktop(int a)
+{
+ ASSERTPR(!isInited(), "cannot change indesktop after init");
+ indesktop = a;
+}
+
+int Layout::getInDesktop()
+{
+ return indesktop;
+}
+
+int Layout::isDesktopAlphaSafe()
+{
+#ifdef WASABI_COMPILE_CONFIG
+ if (galphadisabled) return 0;
+ // {9149C445-3C30-4e04-8433-5A518ED0FDDE}
+ const GUID uioptions_guid =
+ { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
+ if (!_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid), L"Enable desktop alpha")) return 0;
+#else
+ if (!WASABI_WNDMGR_DESKTOPALPHA) return 0;
+#endif
+ return LAYOUT_PARENT::isDesktopAlphaSafe();
+}
+
+void Layout::setStatusText(const wchar_t *txt, int overlay)
+{
+ foreach(statuscbs)
+ statuscbs.getfor()->onSetStatusText(txt, overlay);
+ endfor;
+}
+
+void Layout::addAppCmds(AppCmds *commands)
+{
+ foreach(statuscbs)
+ statuscbs.getfor()->onAddAppCmds(commands);
+ endfor;
+}
+
+void Layout::removeAppCmds(AppCmds *commands)
+{
+ foreach(statuscbs)
+ statuscbs.getfor()->onRemoveAppCmds(commands);
+ endfor;
+}
+
+void Layout::pushCompleted(int max)
+{
+ foreach(statuscbs)
+ statuscbs.getfor()->pushCompleted(max);
+ endfor;
+}
+void Layout::incCompleted(int add)
+{
+ foreach(statuscbs)
+ statuscbs.getfor()->incCompleted(add);
+ endfor;
+}
+void Layout::setCompleted(int pos)
+{
+ foreach(statuscbs)
+ statuscbs.getfor()->setCompleted(pos);
+ endfor;
+}
+void Layout::popCompleted()
+{
+ foreach(statuscbs)
+ statuscbs.getfor()->popCompleted();
+ endfor;
+}
+
+void Layout::registerStatusCallback(GuiStatusCallback *lcb)
+{
+ statuscbs.addItem(lcb);
+ viewer_addViewItem(lcb->status_getDependencyPtr());
+}
+
+int Layout::viewer_onItemDeleted(api_dependent *item)
+{
+ for (int i = 0;i < statuscbs.getNumItems();i++)
+ if (statuscbs.enumItem(i)->status_getDependencyPtr() == item)
+ {
+ statuscbs.removeByPos(i--);
+ }
+ return 1;
+}
+
+void Layout::snapAdjust(int left, int right, int top, int bottom)
+{
+ snap_adjust_left = left;
+ snap_adjust_top = top;
+ snap_adjust_right = right;
+ snap_adjust_bottom = bottom;
+ script_vcpu_onSnapAdjustChanged(SCRIPT_CALL, getScriptObject());
+ #ifdef USEAPPBAR
+ if (appbar_isDocked()) appbar_posChanged();
+#endif
+ if (forceTransparencyFlag() || getAlpha() < 255) postDeferredCallback(DC_INVALIDATE);
+}
+
+void Layout::getSnapAdjust(RECT *r)
+{
+ if (!r) return ;
+ r->left = snap_adjust_left;
+ r->top = snap_adjust_top;
+ r->right = snap_adjust_right;
+ r->bottom = snap_adjust_bottom;
+}
+
+int Layout::abortSaving()
+{
+ GuiObject *o = getGuiObject();
+ if (o->guiobject_movingToTarget()) return 1;
+ return 0;
+}
+
+void Layout::setNoOffscreenCheck(int nocheck)
+{
+ killTimer(TIMER_OFFSCREENCHECK);
+
+ if (nocheck != -1) nooffscreencheck = nocheck;
+
+ setTimer(TIMER_OFFSCREENCHECK, 2500);
+}
+
+#ifdef USEAPPBAR
+
+void Layout::onDock(int side)
+{
+ script_vcpu_onDock(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(side));
+}
+
+void Layout::onUnDock()
+{
+ script_vcpu_onUndock(SCRIPT_CALL, getScriptObject());
+}
+
+void Layout::appbar_onDock(int side)
+{
+ onDock(side);
+ savePosition();
+}
+
+void Layout::appbar_onUnDock()
+{
+ onUnDock();
+ savePosition();
+}
+
+void Layout::appbar_onSlide()
+{
+ savePosition();
+}
+
+int Layout::getAppBarAutoHide()
+{
+ return appbar_want_autohide;
+}
+
+void Layout::setAppBarAutoHide(int ah)
+{
+ appbar_want_autohide = ah;
+ if (appbar_isDocked()) appbar_updateAutoHide();
+ savePosition();
+}
+
+int Layout::getAppBarAlwaysOnTop()
+{
+ return appbar_want_alwaysontop;
+}
+
+void Layout::setAppBarAlwaysOnTop(int aot)
+{
+ appbar_want_alwaysontop = aot;
+ if (appbar_isDocked()) appbar_updateAlwaysOnTop();
+ savePosition();
+}
+#endif
+
+
+// ------------------------------------------------------------------------
+
+LayoutScriptController _layoutController;
+LayoutScriptController *layoutController = &_layoutController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct LayoutScriptController::exportedFunction[] = {
+ {L"onDock", 1, (void*)Layout::script_vcpu_onDock },
+ {L"onUndock", 0, (void*)Layout::script_vcpu_onUndock },
+ {L"getScale", 0, (void*)Layout::script_vcpu_getScale },
+ {L"setScale", 1, (void*)Layout::script_vcpu_setScale },
+ {L"onScale", 1, (void*)Layout::script_vcpu_onScale },
+ {L"setDesktopAlpha", 1, (void*)Layout::script_vcpu_setDesktopAlpha },
+ {L"getDesktopAlpha", 0, (void*)Layout::script_vcpu_getDesktopAlpha },
+ {L"isTransparencySafe", 0, (void*)Layout::script_vcpu_isTransparencySafe},
+ {L"isLayoutAnimationSafe", 0, (void*)Layout::script_vcpu_isLayoutAnimationSafe},
+ {L"getContainer", 0, (void*)Layout::script_vcpu_getContainer },
+ {L"center", 0, (void*)Layout::script_vcpu_center},
+ {L"onMove", 0, (void*)Layout::script_vcpu_onMove},
+ {L"onEndMove", 0, (void*)Layout::script_vcpu_onEndMove},
+ {L"snapAdjust", 4, (void*)Layout::script_vcpu_snapAdjust},
+ {L"getSnapAdjustTop", 0, (void*)Layout::script_vcpu_getSnapAdjustTop},
+ {L"getSnapAdjustLeft", 0, (void*)Layout::script_vcpu_getSnapAdjustLeft},
+ {L"getSnapAdjustRight", 0, (void*)Layout::script_vcpu_getSnapAdjustRight},
+ {L"getSnapAdjustBottom", 0, (void*)Layout::script_vcpu_getSnapAdjustBottom},
+ {L"onUserResize", 4, (void*)Layout::script_vcpu_onUserResize},
+ {L"setRedrawOnResize", 1, (void*)Layout::script_vcpu_setRedrawOnResize},
+ {L"beforeRedock", 0, (void*)Layout::script_vcpu_beforeRedock},
+ {L"redock", 0, (void*)Layout::script_vcpu_redock},
+ {L"onMouseEnterLayout", 0, (void*)Layout::script_vcpu_onMouseEnterLayout},
+ {L"onMouseLeaveLayout", 0, (void*)Layout::script_vcpu_onMouseLeaveLayout},
+ {L"onSnapAdjustChanged", 0, (void*)Layout::script_vcpu_onSnapAdjustChanged},
+ };
+// --------------------------------------------------------
+
+
+const wchar_t *LayoutScriptController::getClassName()
+{
+ return L"Layout";
+}
+
+const wchar_t *LayoutScriptController::getAncestorClassName()
+{
+ return L"Group";
+}
+
+int LayoutScriptController::getInstantiable()
+{
+ return 1;
+}
+
+ScriptObject *LayoutScriptController::instantiate()
+{
+ Layout *l = new Layout;
+ return l->getScriptObject();
+}
+
+void LayoutScriptController::destroy(ScriptObject *o)
+{
+ Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid));
+ if (g && GroupMgr::hasGroup(g))
+ {
+ GroupMgr::destroy(g);
+ return ;
+ }
+ ASSERTALWAYS("you cannot destroy a static layout");
+}
+
+void *LayoutScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL;
+}
+
+void LayoutScriptController::deencapsulate(void *o)
+{}
+
+int LayoutScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *LayoutScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID LayoutScriptController::getClassGuid()
+{
+ return layoutGuid;
+}
+
+// -------------------------------------------------------------------------
+
+scriptVar Layout::script_vcpu_onDock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar side)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, layoutController, side);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, side);
+}
+
+scriptVar Layout::script_vcpu_onUndock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, layoutController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Layout::script_vcpu_getScale(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ double r = 0;
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) r = l->getRenderRatio();
+ return MAKE_SCRIPT_DOUBLE(r);
+}
+
+scriptVar Layout::script_vcpu_setScale(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s)
+{
+ SCRIPT_FUNCTION_INIT
+ double a = GET_SCRIPT_DOUBLE(s);
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) l->setRenderRatio(a);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_onScale(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, layoutController, s);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, s);
+}
+
+scriptVar Layout::script_vcpu_setDesktopAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s)
+{
+ SCRIPT_FUNCTION_INIT
+ bool a = GET_SCRIPT_BOOLEAN(s);
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) l->setWantDesktopAlpha(a);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_getDesktopAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) return MAKE_SCRIPT_BOOLEAN(l->wantDesktopAlpha() && l->isDesktopAlphaSafe());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layout::script_vcpu_isTransparencySafe(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) return MAKE_SCRIPT_BOOLEAN(l->isTransparencySafe());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layout::script_vcpu_isLayoutAnimationSafe(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) return MAKE_SCRIPT_BOOLEAN(!l->forceTransparencyFlag() && (l->getAlphaMgr()->getAlpha(l) == 255));
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layout::script_vcpu_getContainer(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l)
+ {
+ Container *c = l->getParentContainer();
+ return MAKE_SCRIPT_OBJECT(c ? c->getScriptObject() : NULL);
+ }
+ return MAKE_SCRIPT_OBJECT(NULL);
+}
+
+scriptVar Layout::script_vcpu_center(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) l->center();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_setRedrawOnResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) l->setWantRedrawOnResize(GET_SCRIPT_INT(v));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_beforeRedock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) windowTracker->beforeRedock(l, &l->redock);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_redock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) windowTracker->afterRedock(l, &l->redock);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_onEndMove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, layoutController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Layout::script_vcpu_onMouseEnterLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, layoutController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Layout::script_vcpu_onMouseLeaveLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, layoutController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Layout::script_vcpu_onSnapAdjustChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, layoutController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Layout::script_vcpu_onUserResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y, scriptVar w, scriptVar h)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS4(o, layoutController, x, y, w, h);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT4(o, x, y, w, h);
+}
+
+scriptVar Layout::script_vcpu_onMove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, layoutController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Layout::script_vcpu_snapAdjust(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar left, scriptVar top, scriptVar right, scriptVar bottom)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) l->snapAdjust(GET_SCRIPT_INT(left), GET_SCRIPT_INT(top), GET_SCRIPT_INT(right), GET_SCRIPT_INT(bottom));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_getSnapAdjustLeft(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l)
+ {
+ RECT r;
+ l->getSnapAdjust(&r);
+ return MAKE_SCRIPT_INT(r.left);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_getSnapAdjustTop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l)
+ {
+ RECT r;
+ l->getSnapAdjust(&r);
+ return MAKE_SCRIPT_INT(r.top);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_getSnapAdjustRight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l)
+ {
+ RECT r;
+ l->getSnapAdjust(&r);
+ return MAKE_SCRIPT_INT(r.right);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_getSnapAdjustBottom(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l)
+ {
+ RECT r;
+ l->getSnapAdjust(&r);
+ return MAKE_SCRIPT_INT(r.bottom);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+int Layout::broadcasting = 0;
+
+StringW Layout::MakePrefix()
+{
+ return StringPrintfW(L"Skin:%s/Container:%s/Layout:%s", WASABI_API_SKIN->getSkinName(), getParentContainer()->getDescriptor(), getGuiObject()->guiobject_getId());
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/wndmgr/layout.h b/Src/Wasabi/api/wndmgr/layout.h
new file mode 100644
index 00000000..20a90504
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/layout.h
@@ -0,0 +1,465 @@
+#ifndef __LAYOUT_H
+#define __LAYOUT_H
+
+class Layout;
+class Group;
+class Container;
+class Layer;
+
+#include <bfc/tlist.h>
+#include <bfc/depend.h>
+#include <tataki/bitmap/bitmap.h>
+#include <api/wnd/wndclass/buttwnd.h>
+#include <tataki/region/region.h>
+#include <api/wndmgr/container.h>
+#include <api/skin/group.h>
+#include <api/skin/widgets/layer.h>
+#include <api/wndmgr/guistatuscb.h>
+#include <api/script/script.h>
+#include <api/script/scriptobj.h>
+#ifdef WASABI_WIDGETS_GUIOBJECT
+#include <api/script/objects/guiobj.h>
+#endif
+#include <api/wnd/accessible.h>
+#include <api/wndmgr/alphamgr.h>
+#include <api/wnd/resizable.h>
+
+class XmlObject;
+class Layout;
+
+extern AlphaMgr *alphaMgr;
+
+class LayoutScriptController : public GroupScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return groupController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual int getInstantiable();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern LayoutScriptController *layoutController;
+
+#ifndef _NOSTUDIO
+
+class AutoOpacityLinker;
+
+#define LAYOUT_PARENT Group
+#define LAYOUT_SCRIPTPARENT Group
+
+class Layout : public LAYOUT_SCRIPTPARENT, public DependentViewerI, public GuiResizable
+{
+
+public:
+ Layout();
+ virtual ~Layout();
+
+#ifdef _WIN32
+ virtual LRESULT wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+#else
+ virtual OSStatus eventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData);
+#endif
+
+// int onPaint(Canvas *canvas);
+ virtual int onInit();
+ virtual int init(OSMODULEHANDLE inst, OSWINDOWHANDLE parent, int nochild);
+ virtual int reinit(OSMODULEHANDLE inst, OSWINDOWHANDLE parent, int nochild);
+
+ virtual int childNotify(ifc_window *child, int msg, intptr_t param1=0, intptr_t param2=0);
+ virtual int onActionNotify(int action, intptr_t param=0);
+
+ virtual void resize(int x, int y, int w, int h, int wantcb=1);
+ virtual void move(int x, int y);
+
+// virtual int onRightButtonDown(int x, int y);
+// virtual int onLeftButtonDown(int x, int y);
+// virtual int onMouseMove(int x, int y);
+// virtual int onLeftButtonUp(int x, int y);
+ virtual int onResize();
+ virtual int onPostedMove();
+ virtual int onPaint(Canvas *canvas);
+ virtual void onSetDesktopAlpha(int a);
+ virtual int isLayout();
+ virtual void setAlphaBackground(const wchar_t *txture);
+ virtual SkinBitmap *getBaseTexture();
+ virtual void onGuiObjectSetVisible(GuiObject *o, int status); // called whenever a child shows/hide
+ virtual ifc_window *getCustomOwner();
+ virtual void addLockedLayout(Layout *l);
+ virtual void removeLockedLayout(Layout *l);
+ virtual int getNumLockedLayouts();
+ virtual Layout *enumLockedLayout(int n);
+ virtual int isLocked();
+ virtual void lockTo(Layout *l);
+ virtual Layout *getLockedTo();
+ void updateLockedLayouts();
+ virtual int onGetFocus();
+ virtual int onKillFocus();
+ virtual void snapAdjust(int left, int right, int top, int bottom);
+
+ virtual void onShow(void);
+ virtual void onHide(void);
+
+ virtual void center();
+
+ virtual int wantDesktopAlpha();
+ virtual void setWantDesktopAlpha(int want);
+ virtual int handleDesktopAlpha();
+
+ virtual int setXuiParam(int _xuihandle, int attribid, const wchar_t *paramname, const wchar_t *strvalue);
+
+ void setWindowRegion(api_region *reg);
+ virtual int allowResize() {
+ return !isLocked()
+#ifdef USEAPPBAR
+ && !appbar_isDocked()
+#endif
+ ;
+ }
+
+ // container/component callbacks to get notified that a container
+ // has been set visible/invisible
+ void containerToggled(const wchar_t *id,int visible);
+ void componentToggled(GUID *guid, int visible);
+
+ void setParentContainer(Container *c);
+ virtual Container *getParentContainer();
+
+ virtual int isClickThrough();
+
+ void onSetVisible(int show);
+ virtual void cancelCapture();
+
+ virtual int onActivate();
+ virtual int onDeactivate();
+
+ virtual int forceTransparencyFlag();
+
+ int x, y;
+
+#ifdef _WIN32
+ void setForwardMsgWnd(HWND wnd) { forwardMsgWnd = wnd; }
+
+ LPARAM wndHolder_getParentParam(int i=0);
+#endif
+
+ void scaleTo(int s);
+ virtual void setRenderRatio(double s);
+
+ virtual void beginMove();
+ virtual void beginScale();
+ virtual void beginResize();
+ virtual void endMove();
+ virtual void endScale();
+ virtual void endResize();
+
+ virtual void setEndMoveResize(int w, int h) {
+ m_w = w;
+ m_h = h;
+ m_endmovesize = 1;
+ };
+
+ virtual ifc_window *guiresizable_getRootWnd() { return (this); }
+
+
+ virtual void lockScale(int locked);
+ virtual int isScaleLocked() { return scalelocked; }
+
+ virtual void onMove();
+
+ virtual int isDesktopAlphaSafe();
+
+ void addSubRegionLayer(Layer *l);
+ void removeSubRegionLayer(Layer *l);
+
+ virtual void setInDesktop(int a);
+ virtual int getInDesktop();
+
+ virtual void setAlpha(int a);
+ virtual int getAlpha();
+ virtual int getPaintingAlpha();
+ virtual void timerCallback(int id);
+
+ virtual void setLinkWidth(const wchar_t *layoutid);
+ virtual void setLinkHeight(const wchar_t *layoutid);
+
+ virtual void setBaseTexture(const wchar_t *b, int regis=1);
+ virtual void setPaintingAlpha(int activealpha, int inactivealpha=-1);
+
+ static void onGlobalEnableDesktopAlpha(int enabled);
+
+ void savePosition();
+#ifdef USEAPPBAR
+ void saveAppBarPosition();
+#endif
+ virtual void setStatusText(const wchar_t *txt, int overlay=0);
+ virtual void addAppCmds(AppCmds *commands);
+ virtual void removeAppCmds(AppCmds *commands);
+
+ void pushCompleted(int max=100);
+ void incCompleted(int add=1);
+ void setCompleted(int pos);
+ void popCompleted();
+
+ virtual void registerStatusCallback(GuiStatusCallback *lcb);
+ virtual int viewer_onItemDeleted(api_dependent *item);
+ virtual int wantActivation() { return wantactiv && LAYOUT_PARENT::wantActivation(); }
+ void loadSavedState();
+ virtual void updateOnTop();
+
+ virtual int runAction(int actionid, const wchar_t *param=NULL);
+
+ virtual void getSnapAdjust(RECT *r);
+
+ virtual void updateTransparency();
+ virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
+ virtual int wantRedrawOnResize() { return wantredrawonresize; }
+ virtual void setWantRedrawOnResize(int v);
+
+#ifdef USEAPPBAR
+ virtual int appbar_wantAutoHide() { return getAppBarAutoHide(); }
+ virtual int appbar_wantAlwaysOnTop() { return getAppBarAlwaysOnTop(); }
+
+ virtual int getAppBarAutoHide();
+ virtual void setAppBarAutoHide(int ah);
+
+ virtual int getAppBarAlwaysOnTop();
+ virtual void setAppBarAlwaysOnTop(int aot);
+#endif
+
+ virtual void pushForceUnlink() { m_forceunlink++; }
+ virtual void popForceUnlink() { m_forceunlink--; }
+
+ virtual int isUnlinked() {
+#ifdef USEAPPBAR
+ return unlinked || appbar_isDocked() || m_forceunlink;
+#else
+ return unlinked || m_forceunlink;
+#endif
+ }
+
+ void setAutoOpacify(int a);
+ int getAutoOpacify() { return autoopacify; }
+
+ void offscreenCheck();
+ int isOffscreen(ifc_window *w);
+
+ int getResizable();
+ int getScalable();
+
+ void setTransparencyOverride(int v);
+ int getTransparencyOverride() { return transparencyoverride; }
+
+ enum {
+ LAYOUT_SETDESKTOPALPHA=0,
+ LAYOUT_SETINDESKTOP,
+ LAYOUT_SETALPHA,
+ LAYOUT_SETLINKWIDTH,
+ LAYOUT_SETLINKHEIGHT,
+ LAYOUT_SETOWNER,
+ LAYOUT_SETLOCKTO,
+ LAYOUT_SETOSFRAME,
+ LAYOUT_SETALPHABACKGROUND,
+ LAYOUT_SETNOACTIVATION,
+ LAYOUT_SETONTOP,
+ LAYOUT_SNAPADJUSTLEFT,
+ LAYOUT_SNAPADJUSTTOP,
+ LAYOUT_SNAPADJUSTRIGHT,
+ LAYOUT_SNAPADJUSTBOTTOM,
+ LAYOUT_UNLINKED,
+ LAYOUT_NOPARENT,
+ LAYOUT_FORCEALPHA,
+ LAYOUT_NODOCK,
+ LAYOUT_NOOFFSCREENCHECK,
+ LAYOUT_RESIZABLE,
+ LAYOUT_SCALABLE,
+ };
+
+
+ void onMouseEnterLayout();
+ void onMouseLeaveLayout();
+
+ int getNoParent() { return noparent; }
+ void setNoParent(int np) { noparent = np; }
+ int isAlphaForced() { return forcealpha; }
+
+ AlphaMgr *getAlphaMgr() { return alphaMgr; }
+
+ int getNoDock() { return nodock; }
+ void setNoDock(int nd) { nodock = nd; }
+ int isTransparencyForcedOff() { return transparency_autooff; }
+
+ void controlMenu();
+
+ void setNoOffscreenCheck(int nocheck);
+
+#ifdef USEAPPBAR
+ void onDock(int side);
+ void onUnDock();
+
+ virtual void appbar_onDock(int side);
+ virtual void appbar_onUnDock();
+ virtual void appbar_onSlide();
+#endif
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+/* virtual int dragEnter(ifc_window *sourceWnd);
+ virtual int dragOver(int x, int y, ifc_window *sourceWnd);
+ virtual int dragDrop(ifc_window *sourceWnd, int x, int y);
+ virtual int acceptExternalDrops() { return 1; }*/
+ virtual int wantClickWndAutoInvalidate() { return 0; }
+
+
+private:
+ StringW MakePrefix();
+ static XMLParamPair params[];
+ void fixPosition();
+ void saveAllPositions();
+ void activateChildren(int act);
+#ifdef _WIN32
+ void getExplorerWindows(HWND *parent, HWND *listview, HWND *webserver);
+#endif
+ void desktopAlpha_autoTurnOn();
+ void desktopAlpha_autoTurnOff();
+ void transparency_autoTurnOn();
+ void transparency_autoTurnOff();
+ void globalEnableDesktopAlpha(int enabled);
+
+#ifdef _WIN32
+ HWND forwardMsgWnd;
+#endif
+ int resizing;
+ int wantactiv;
+ int size_w,size_h;
+ int cX,cY;
+ int captured;
+ POINT mousepos;
+#ifdef _WIN32
+ HWND webserver;
+ HWND listview;
+#endif
+ int alphagoingon;
+ int alphagoingoff;
+ int scalelocked;
+ int wantredrawonresize;
+
+ int xuihandle;
+
+ RegionI *reg;
+ //PtrList<Layer> *subregionlayers;
+ Container *p_container;
+ StringW alphabackgroundstr;
+ ifc_window *wndholders;
+ int abortSaving();
+ int transparencyoverride;
+
+ int default_x;
+ int default_y;
+ int moving;
+ int scaling;
+ int mover;
+ int indesktop;
+ int alpha;
+ StringW linkedheight, linkedwidth;
+ int inlinkwidth, inlinkheight;
+ AutoSkinBitmap alphabackground;
+ int wantdesktopalpha;
+ int galphadisabled;
+ static PtrList<Layout> alllayouts;
+ StringW owner;
+ PtrList<Layout> locked;
+ StringW lockto;
+ Layout *lockedto;
+ int inpostedmove;
+ int osframe;
+ PtrList<GuiStatusCallback> statuscbs;
+ int initontop;
+// GarbageCollector gc;
+ PtrList<AppCmds> appcmds;
+ int inresize;
+ int unlinked;
+
+ int snap_adjust_left;
+ int snap_adjust_top;
+ int snap_adjust_right;
+ int snap_adjust_bottom;
+
+ int disable_auto_alpha;
+ int autoopacify;
+ int noparent;
+ int forcealpha;
+ redock_struct redock;
+ static int broadcasting;
+ int nodock;
+ uint32_t transparency_reenabled_at;
+ int transparency_autooff;
+ int nooffscreencheck;
+ int resizable;
+ int scalable;
+
+ int m_w, m_h;
+ int m_endmovesize;
+ int m_allowsavedock;
+ int m_forceunlink;
+#ifdef USEAPPBAR
+ int appbar_want_autohide;
+ int appbar_want_alwaysontop;
+#endif
+
+// FG>
+// -- SCRIPT -----------------------------------------------------
+public:
+
+ static scriptVar script_vcpu_onDock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar side);
+ static scriptVar script_vcpu_onUndock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getScale(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_setScale(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s);
+ static scriptVar script_vcpu_onScale(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s);
+ static scriptVar script_vcpu_setDesktopAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s);
+ static scriptVar script_vcpu_getDesktopAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_isTransparencySafe(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_isLayoutAnimationSafe(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getContainer(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_center(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onMove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onEndMove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onUserResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y, scriptVar w, scriptVar h);
+ static scriptVar script_vcpu_snapAdjust(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar left, scriptVar top, scriptVar right, scriptVar bottom);
+ static scriptVar script_vcpu_setRedrawOnResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar script_vcpu_beforeRedock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_redock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getSnapAdjustTop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getSnapAdjustLeft(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getSnapAdjustRight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getSnapAdjustBottom(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onMouseEnterLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onMouseLeaveLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onSnapAdjustChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+#else
+class Layout : public LAYOUT_SCRIPTPARENT {
+
+public:
+
+#endif
+
+// INSERT_SCRIPT_OBJECT_CONTROL
+
+
+};
+
+// END SCRIPT
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/msgbox.cpp b/Src/Wasabi/api/wndmgr/msgbox.cpp
new file mode 100644
index 00000000..4a32cf66
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/msgbox.cpp
@@ -0,0 +1,251 @@
+#include <precomp.h>
+#include "msgbox.h"
+#include <api/wndmgr/skinwnd.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/script/scriptguid.h>
+#include <api/script/objects/c_script/c_container.h>
+#include <api/script/objects/c_script/c_text.h>
+#include <api/script/objects/c_script/c_button.h>
+
+_btnstruct msgboxbtns[] =
+ {
+ { L"<<", MSGBOX_PREVIOUS },
+ { L"OK", MSGBOX_OK },
+ { L"Yes", MSGBOX_YES },
+ { L"All", MSGBOX_ALL },
+ { L"No", MSGBOX_NO },
+ { L">>", MSGBOX_NEXT },
+ { L"Cancel", MSGBOX_CANCEL },
+ };
+
+MsgBox::MsgBox(const wchar_t *_text, const wchar_t *_title, int _flags, const wchar_t *notanymore)
+{
+ text = _text;
+ title = _title;
+ flags = _flags;
+#ifdef WIN32
+#ifdef _DEBUG
+ DebugStringW(L"msgbox: %s: %s", title, text.getValue());
+#endif
+#endif
+ notanymore_id = notanymore;
+ sw = NULL;
+ if (flags == 0) flags = MSGBOX_OK;
+}
+
+MsgBox::~MsgBox()
+{
+ foreach(buttons)
+ WASABI_API_SKIN->xui_delete(buttons.getfor());
+ endfor
+}
+
+int MsgBox::run()
+{
+ int _r = -1;
+
+#ifdef WASABI_COMPILE_CONFIG
+ if (!notanymore_id.isempty())
+ {
+ StringPrintfW txt(L"msgbox_defaultvalue_%s", notanymore_id);
+ if ((GetKeyState(VK_SHIFT) & 0x8000))
+ WASABI_API_CONFIG->setIntPublic(txt, -1);
+ _r = WASABI_API_CONFIG->getIntPublic(txt, -1);
+ }
+#endif
+
+ if (_r == -1)
+ {
+ sw = new SkinWnd(L"msgbox.custom.group", L"modal", FALSE, NULL, 1, 1);
+ if (!sw->getWindow()) return -1;
+ ifc_window *grp = sw->getWindow();
+ ifc_window *l = grp->getDesktopParent();
+
+ GuiObject *_p = sw->findObject(L"msgbox.custom.group");
+ //CUT: api_window *p = _p->guiobject_getRootWnd();
+
+ C_Container cont(sw->getContainer());
+ cont.setName(title);
+
+ createButtons();
+ int min_w = reposButtons();
+
+ GuiObject *go_txt = sw->findObject(L"msgbox.text");
+ if (go_txt != NULL)
+ {
+ GuiObject *to = go_txt->guiobject_findObject(L"wasabi.text");
+ GuiObject *gto = sw->findObject(L"text");
+ if (to != NULL && gto != NULL)
+ {
+ go_txt->guiobject_setXmlParam(L"text", text);
+ C_GuiObject t(*go_txt);
+ int _w = t.getAutoWidth();
+ int _h = t.getAutoHeight();
+
+ to->guiobject_setXmlParam(L"w", StringPrintfW(_w));
+ to->guiobject_setXmlParam(L"h", StringPrintfW(_h));
+ to->guiobject_setXmlParam(L"relatw", L"0");
+ to->guiobject_setXmlParam(L"relath", L"0");
+
+ int x, rx, w, rw;
+ int y, ry, h, rh;
+ int gtow, gtoh;
+
+ go_txt->guiobject_getGuiPosition(&x, &y, &w, &h, &rx, &ry, &rw, &rh);
+ if (rw == 1)
+ _w += -w;
+ else
+ _w += x * 2;
+ if (rh == 1)
+ _h += -h;
+ else
+ _h += y * 2;
+
+ gtow = _w;
+ gtoh = _h;
+
+ GuiObject *grpo = grp->getGuiObject();
+ ASSERT(grpo != NULL);
+ gto->guiobject_getGuiPosition(&x, &y, &w, &h, &rx, &ry, &rw, &rh);
+ if (rw == 1)
+ _w += -w;
+ else
+ _w += x * 2;
+ if (rh == 1)
+ _h += -h;
+ else
+ _h += y * 2;
+
+ gto->guiobject_setXmlParam(L"w", StringPrintfW(gtow));
+ gto->guiobject_setXmlParam(L"h", StringPrintfW(gtoh));
+
+ grpo->guiobject_setXmlParam(L"w", StringPrintfW(_w));
+ grpo->guiobject_setXmlParam(L"h", StringPrintfW(_h));
+ grpo->guiobject_setXmlParam(L"lockminmax", L"1");
+ grpo->guiobject_setXmlParam(L"propagatesize", L"1");
+ XmlObject *xl = static_cast<XmlObject *>(l->getInterface(xmlObjectGuid));
+ xl->setXmlParam(L"minimum_h", StringPrintfW(L"%d", _h));
+ xl->setXmlParam(L"minimum_w", StringPrintfW(L"%d", (_w < min_w) ? min_w : _w));
+ }
+ }
+
+ if (!notanymore_id.isempty())
+ {
+ GuiObject *o = WASABI_API_SKIN->xui_new(L"Wasabi:CheckBox"); // that'll be deleted automatically when our parent group destroys
+ if (o != NULL)
+ {
+ ifc_window *w = o->guiobject_getRootWnd();
+ C_GuiObject go(*o);
+ go.init(_p->guiobject_getScriptObject());
+ o->guiobject_setXmlParam(L"text", L"Do not show this message anymore");
+ o->guiobject_setXmlParam(L"y", L"-50");
+ o->guiobject_setXmlParam(L"relaty", L"1");
+ o->guiobject_setXmlParam(L"x", L"12");
+ o->guiobject_setXmlParam(L"relatx", L"0");
+ o->guiobject_setXmlParam(L"w", L"-24");
+ o->guiobject_setXmlParam(L"relatw", L"1");
+ min_w = MAX(w->getPreferences(SUGGESTED_W), min_w);
+ }
+ }
+
+ sw->notifyMinMaxChanged();
+ reposButtons();
+ _r = sw->runModal(1);
+ }
+
+#ifdef WASABI_COMPILE_CONFIG
+ if (!notanymore_id.isempty() && _r != -1 && sw != NULL)
+ {
+ GuiObject *o = sw->findObject(L"checkbox.toggle");
+ if (o != NULL)
+ {
+ C_Button b(*o);
+ if (b.getActivated())
+ {
+ StringPrintfW txt(L"msgbox_defaultvalue_%s", notanymore_id);
+ WASABI_API_CONFIG->setIntPublic(txt, _r);
+ }
+ }
+ }
+#endif
+
+ if (sw) sw->destroy(); sw = NULL;
+
+ return _r;
+}
+
+void MsgBox::addButton(const wchar_t *text, int retcode)
+{
+ GuiObject *o = WASABI_API_SKIN->xui_new(L"Wasabi:Button"); // that wil NOT be deleted automatically when our parent group destroys because we did not init with guiobject
+ if (o != NULL)
+ {
+ o->guiobject_setXmlParam(L"action", L"endmodal");
+ o->guiobject_setXmlParam(L"retcode", StringPrintfW(retcode));
+ o->guiobject_setXmlParam(L"text", text);
+ buttons.addItem(o);
+ }
+}
+
+void MsgBox::createButtons()
+{
+ GuiObject *_p = sw->findObject(L"msgbox.custom.group");
+ if (!_p) return ;
+
+ ASSERT(buttons.getNumItems() == 0);
+ buttons.deleteAll();
+
+ for (int i = 0;i < sizeof(msgboxbtns) / sizeof(_btnstruct);i++)
+ {
+ if (flags & msgboxbtns[i].id)
+ {
+ addButton(msgboxbtns[i].txt, msgboxbtns[i].id);
+ }
+ }
+
+ ifc_window *p = _p->guiobject_getRootWnd();
+
+ foreach(buttons)
+ ifc_window *wnd = buttons.getfor()->guiobject_getRootWnd();
+ if (wnd != NULL)
+ {
+ wnd->setStartHidden(1);
+ wnd->setParent(p);
+ wnd->init(p);
+ }
+ endfor;
+}
+
+int MsgBox::reposButtons()
+{
+ RECT r;
+ GuiObject *_p = sw->findObject(L"msgbox.custom.group");
+ ifc_window *p = _p->guiobject_getRootWnd();
+ p->getClientRect(&r);
+
+ int shift = 0;
+
+ //CUT: int _w = 0;
+ //CUT: int _h = 0;
+ for (int i = buttons.getNumItems() - 1;i >= 0;i--)
+ {
+ ifc_window *wnd = buttons.enumItem(i)->guiobject_getRootWnd();
+ if (wnd != NULL)
+ {
+ int _w = wnd->getPreferences(SUGGESTED_W);
+ int _h = wnd->getPreferences(SUGGESTED_H);
+ if (_w == AUTOWH) _w = -1;
+ int w = MAX(_w, 64);
+ wnd->resize(r.right - w - 16 - shift, r.bottom - 8 - _h, w, _h);
+ _w = MAX(w, _w);
+ _h = MAX(_h, _h);
+ shift += w + 4;
+ }
+ }
+
+ foreach(buttons)
+ ifc_window *wnd = buttons.getfor()->guiobject_getRootWnd();
+ if (wnd != NULL)
+ wnd->setVisible(1);
+ endfor;
+ return shift;
+}
diff --git a/Src/Wasabi/api/wndmgr/msgbox.h b/Src/Wasabi/api/wndmgr/msgbox.h
new file mode 100644
index 00000000..41487835
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/msgbox.h
@@ -0,0 +1,49 @@
+#ifndef __MESSAGEBOX_H
+#define __MESSAGEBOX_H
+
+#include <bfc/string/bfcstring.h>
+#include <bfc/string/StringW.h>
+#include <bfc/ptrlist.h>
+
+#define MSGBOX_ABORTED 0 // NOT a flag, only a return code
+
+#define MSGBOX_OK 1
+#define MSGBOX_CANCEL 2
+#define MSGBOX_YES 4
+#define MSGBOX_NO 8
+#define MSGBOX_ALL 16
+#define MSGBOX_NEXT 32
+#define MSGBOX_PREVIOUS 64
+
+class GuiObject;
+class SkinWnd;
+
+
+typedef struct {
+ wchar_t *txt;
+ int id;
+} _btnstruct;
+
+class MsgBox {
+ public:
+
+ MsgBox(const wchar_t *text, const wchar_t *title=L"Alert", int flags=MSGBOX_OK, const wchar_t *notanymore=NULL);
+ virtual ~MsgBox();
+ virtual int run();
+
+
+ private:
+
+ void createButtons();
+ int reposButtons();
+ void addButton(const wchar_t *text, int retcode);
+
+ StringW text, title;
+ int flags;
+ PtrList<GuiObject> buttons;
+ GuiObject *checkbox;
+ SkinWnd *sw;
+ StringW notanymore_id;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wndmgr/resize.cpp b/Src/Wasabi/api/wndmgr/resize.cpp
new file mode 100644
index 00000000..959ece91
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/resize.cpp
@@ -0,0 +1,383 @@
+#include <precomp.h>
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <bfc/assert.h>
+#include <api/wndmgr/resize.h>
+#include <api/wnd/wndtrack.h>
+#include <api/wnd/basewnd.h>
+#include <api/wndmgr/layout.h>
+
+#define tag L"wa3_resizerclass"
+
+extern HINSTANCE hInstance;
+
+
+//----------------------------------------------------------------------
+resizeClass::resizeClass(ifc_window *wnd, int minx, int miny, int maxx, int maxy, int sugx, int sugy)
+{
+ screenWidth = Wasabi::Std::getScreenWidth();
+ screenHeight = Wasabi::Std::getScreenHeight();
+
+#if defined (_WIN32) || defined(_WIN64)
+ WNDCLASSW wc;
+ if (!GetClassInfoW(hInstance, tag, &wc))
+ {
+ MEMSET(&wc, 0, sizeof(wc));
+ wc.lpfnWndProc = resizeWndProc;
+ wc.hInstance = hInstance; // hInstance of DLL
+ wc.lpszClassName = tag; // our window class name
+ wc.style = 0;
+
+ int _r = RegisterClassW(&wc);
+ ASSERTPR(_r, "cannot create resizer wndclass");
+ }
+
+ hWnd = CreateWindowExW(0, tag, L"", 0, 0, 0, 1, 1, NULL, NULL, hInstance, NULL);
+
+ ASSERT(hWnd);
+
+ SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)this);
+
+ if (minx > maxx && maxx != -1) minx = maxx;
+ if (miny > maxy && maxy != -1) miny = maxy;
+#endif
+
+ minWinWidth = minx;
+ minWinHeight = miny;
+ maxWinWidth = maxx;
+ maxWinHeight = maxy;
+ sugWinWidth = sugx;
+ sugWinHeight = sugy;
+
+ if (wnd->getInterface(layoutGuid))
+ {
+ static_cast<Layout *>(wnd)->getSnapAdjust(&snapAdjust);
+ if (minWinWidth != -1) minWinWidth -= snapAdjust.left + snapAdjust.right;
+ if (minWinHeight != -1) minWinHeight -= snapAdjust.bottom + snapAdjust.top;
+ if (maxWinWidth != -1) maxWinWidth -= snapAdjust.left + snapAdjust.right;
+ if (maxWinHeight != -1) maxWinHeight -= snapAdjust.bottom + snapAdjust.top;
+ if (sugWinWidth != -1) sugWinWidth -= snapAdjust.left + snapAdjust.right;
+ if (sugWinHeight != -1) sugWinHeight -= snapAdjust.bottom + snapAdjust.top;
+ }
+
+ dc = NULL;
+#ifdef WIN32
+ oldB = NULL;
+ brush = NULL;
+ oldP = NULL;
+ pen = NULL;
+#endif
+}
+
+
+//----------------------------------------------------------------------
+resizeClass::~resizeClass()
+{
+#ifdef WIN32
+ if (dc)
+ {
+ SelectObject(dc, oldB);
+ SelectObject(dc, oldP);
+ SetROP2(dc, mix);
+ DeleteObject(pen);
+ DeleteObject(brush);
+ ReleaseDC(NULL, dc);
+ }
+
+ if (IsWindow(hWnd))
+ DestroyWindow(hWnd);
+ //BU win98 sucks UnregisterClass(tag, Main::gethInstance());
+#else
+ if (dc)
+ {
+ XFreeGC(Linux::getDisplay(), dc->gc);
+ FREE(dc);
+ }
+#endif
+}
+
+//----------------------------------------------------------------------
+BOOL CALLBACK invalidateChildren(HWND hwnd, LPARAM lParam)
+{
+ InvalidateRect(hwnd, NULL, FALSE);
+ return TRUE;
+}
+
+//----------------------------------------------------------------------
+BOOL CALLBACK invalidateAll(HWND hwnd, LPARAM lParam)
+{
+ EnumChildWindows(hwnd, invalidateChildren, 0);
+ InvalidateRect(hwnd, NULL, FALSE);
+ return TRUE;
+}
+
+//----------------------------------------------------------------------
+int resizeClass::resizeWindow(ifc_window *wnd, int way)
+{
+
+ // paintHookStart();
+
+ wnd->getWindowRect(&originalRect);
+
+ snapAdjust.left = 0;
+ snapAdjust.top = 0;
+ snapAdjust.right = 0;
+ snapAdjust.bottom = 0;
+
+ if (wnd->getInterface(layoutGuid))
+ {
+ static_cast<Layout *>(wnd)->getSnapAdjust(&snapAdjust);
+ if (wnd->getRenderRatio() != 1.0)
+ {
+ double rr = wnd->getRenderRatio();
+ snapAdjust.left = (int)((double)(snapAdjust.left) * rr);
+ snapAdjust.top = (int)((double)(snapAdjust.top) * rr);
+ snapAdjust.right = (int)((double)(snapAdjust.right) * rr);
+ snapAdjust.bottom = (int)((double)(snapAdjust.bottom) * rr);
+ }
+ originalRect.left += snapAdjust.left;
+ originalRect.top += snapAdjust.top;
+ originalRect.right -= snapAdjust.right;
+ originalRect.bottom -= snapAdjust.bottom;
+ }
+
+ curRect = originalRect;
+ resizeWay = way;
+ resizedWindow = wnd->gethWnd();
+ resizedWindowR = wnd;
+
+ POINT pt;
+ Wasabi::Std::getMousePos(&pt);
+ cX = pt.x;
+ cY = pt.y;
+
+#ifdef WIN32
+ SetCapture(hWnd);
+#endif
+ SetTimer(hWnd, 1, 100, NULL); // this timer will make sure that we never get interlock
+
+ drawFrame();
+
+ MSG msg;
+ cancelit = 1;
+ while (GetCapture() == hWnd && GetMessage( &msg, hWnd, 0, 0 ))
+ {
+ TranslateMessage( &msg );
+#ifdef LINUX
+ if ( msg.message == WM_LBUTTONUP || msg.message == WM_MOUSEMOVE )
+ wndProc( msg.hwnd, msg.message, msg.wParam, msg.lParam );
+ else
+#endif
+ DispatchMessage( &msg );
+ }
+
+ drawFrame();
+
+ // paintHookStop();
+
+ if (GetCapture() == hWnd) ReleaseCapture();
+ KillTimer(hWnd, 1);
+
+ if (!cancelit)
+ {
+ curRect.left -= snapAdjust.left;
+ curRect.top -= snapAdjust.top;
+ curRect.right += snapAdjust.right;
+ curRect.bottom += snapAdjust.bottom;
+ }
+ else
+ {
+ curRect = originalRect;
+ // evil, but less evil than InvalidateRect(NULL, NULL, FALSE);
+ EnumWindows(invalidateAll, 0);
+ }
+
+ return !cancelit;
+}
+
+
+//----------------------------------------------------------------------
+RECT resizeClass::getRect(void)
+{
+ return curRect;
+}
+
+//#define nifty
+
+//----------------------------------------------------------------------
+void resizeClass::drawFrame(void)
+{
+ RECT outRect;
+
+#ifdef WIN32
+ if (!dc)
+ {
+ dc = GetDC(NULL);
+ brush = CreateSolidBrush(0xFFFFFF);
+ pen = CreatePen(PS_SOLID, 0, 0xFFFFFF);
+ oldB = (HBRUSH)SelectObject(dc, brush);
+ oldP = (HPEN)SelectObject(dc, pen);
+ mix = SetROP2(dc, R2_XORPEN);
+ }
+
+ outRect = curRect;
+
+#ifndef nifty
+
+ DrawFocusRect(dc, &outRect);
+
+#else
+
+ RECT inRect;
+
+ inRect = outRect;
+ inRect.left += 10;
+ inRect.right -= 10;
+ inRect.top += 24;
+ inRect.bottom -= 10;
+
+ MoveToEx(dc, inRect.left, inRect.top, NULL);
+ LineTo(dc, inRect.right, inRect.top);
+ LineTo(dc, inRect.right, inRect.bottom);
+ LineTo(dc, inRect.left, inRect.bottom);
+ LineTo(dc, inRect.left, inRect.top);
+ MoveToEx(dc, outRect.left, 0, NULL);
+ LineTo(dc, outRect.left, screenHeight);
+ MoveToEx(dc, outRect.right, 0, NULL);
+ LineTo(dc, outRect.right, screenHeight);
+ MoveToEx(dc, 0, outRect.top, NULL);
+ LineTo(dc, screenWidth, outRect.top);
+ MoveToEx(dc, 0, outRect.bottom, NULL);
+ LineTo(dc, screenWidth, outRect.bottom);
+
+#endif
+#endif//WIN32
+#ifdef LINUX
+ outRect = curRect;
+
+ if ( ! dc )
+ {
+ dc = (HDC)MALLOC( sizeof( hdc_typ ) );
+ XGCValues gcv;
+ gcv.function = GXxor;
+ gcv.subwindow_mode = IncludeInferiors;
+ gcv.foreground = 0xffffff;
+ gcv.line_style = LineOnOffDash;
+ gcv.dashes = 1;
+ dc->gc = XCreateGC( Linux::getDisplay(), Linux::RootWin(), GCFunction | GCForeground | GCSubwindowMode, &gcv );
+ }
+
+ XDrawRectangle( Linux::getDisplay(), Linux::RootWin(), dc->gc,
+ outRect.left, outRect.top, outRect.right - outRect.left,
+ outRect.bottom - outRect.top );
+#endif
+ //PORTME
+}
+
+LRESULT resizeClass::wndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_LBUTTONUP:
+ cancelit = 0;
+ ReleaseCapture();
+ return 0;
+
+ case WM_MOUSEMOVE:
+ {
+ POINT pt;
+ int iX, iY;
+ Wasabi::Std::getMousePos(&pt);
+ iX = pt.x - cX;
+ iY = pt.y - cY;
+ drawFrame();
+
+ if (resizeWay & TOP)
+ curRect.top = originalRect.top + iY;
+ if (resizeWay & BOTTOM)
+ curRect.bottom = originalRect.bottom + iY;
+ if (resizeWay & LEFT)
+ curRect.left = originalRect.left + iX;
+ if (resizeWay & RIGHT)
+ curRect.right = originalRect.right + iX;
+
+ if (abs((curRect.right - curRect.left) - sugWinWidth) < 10)
+ if (resizeWay & RIGHT)
+ curRect.right = curRect.left + sugWinWidth;
+ else if (resizeWay & LEFT)
+ curRect.left = curRect.right - sugWinWidth;
+
+ if (abs((curRect.bottom - curRect.top) - sugWinHeight) < 10)
+ if (resizeWay & BOTTOM)
+ curRect.bottom = curRect.top + sugWinHeight;
+ else if (resizeWay & TOP)
+ curRect.top = curRect.bottom - sugWinHeight;
+
+ curRect.left -= snapAdjust.left;
+ curRect.top -= snapAdjust.top;
+ curRect.right += snapAdjust.right;
+ curRect.bottom += snapAdjust.bottom;
+
+ windowTracker->autoDock(resizedWindowR, &curRect, resizeWay);
+
+ curRect.left += snapAdjust.left;
+ curRect.top += snapAdjust.top;
+ curRect.right -= snapAdjust.right;
+ curRect.bottom -= snapAdjust.bottom;
+
+ if ((curRect.right - curRect.left) < minWinWidth)
+ if (resizeWay & RIGHT)
+ curRect.right = curRect.left + minWinWidth;
+ else if (resizeWay & LEFT)
+ curRect.left = curRect.right - minWinWidth;
+
+ if ((curRect.bottom - curRect.top) < minWinHeight)
+ if (resizeWay & BOTTOM)
+ curRect.bottom = curRect.top + minWinHeight;
+ else if (resizeWay & TOP)
+ curRect.top = curRect.bottom - minWinHeight;
+
+ if (maxWinWidth != -1 && (curRect.right - curRect.left) > maxWinWidth)
+ if (resizeWay & RIGHT)
+ curRect.right = curRect.left + maxWinWidth;
+ else if (resizeWay & LEFT)
+ curRect.left = curRect.right - maxWinWidth;
+
+ if (maxWinHeight != -1 && (curRect.bottom - curRect.top) > maxWinHeight)
+ if (resizeWay & BOTTOM)
+ curRect.bottom = curRect.top + maxWinHeight;
+ else if (resizeWay & TOP)
+ curRect.top = curRect.bottom - maxWinHeight;
+
+ drawFrame();
+ }
+ return 0;
+ }
+#ifdef WIN32
+ return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+#else
+ return 0;
+#endif
+}
+
+// Window Procedure
+//
+LRESULT CALLBACK resizeWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+#ifdef WIN32
+ resizeClass *gThis = (resizeClass *)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
+ if (!gThis)
+ return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+ else
+ return gThis->wndProc(hwnd, uMsg, wParam, lParam);
+#else
+ return 0;
+#endif
+}
+
+void resizeClass::setResizeCursor(int action)
+{}
+
+
diff --git a/Src/Wasabi/api/wndmgr/resize.h b/Src/Wasabi/api/wndmgr/resize.h
new file mode 100644
index 00000000..2d67e14c
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/resize.h
@@ -0,0 +1,48 @@
+#ifndef __RESIZE_H
+#define __RESIZE_H
+#ifdef _WIN32
+LRESULT CALLBACK resizeWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+#endif
+
+class resizeClass
+{
+#ifdef _WIN32
+ friend LRESULT CALLBACK resizeWndProc(HWND wnd, UINT uMsg, WPARAM wParam, LPARAM lParam); // heh, i really need this one ;)
+#endif
+private:
+ void drawFrame(void);
+ void setResizeCursor(int action);
+ int orientation(int a, int action);
+ OSWINDOWHANDLE hWnd;
+ OSWINDOWHANDLE resizedWindow;
+ ifc_window *resizedWindowR;
+ int resizeWay;
+ RECT curRect;
+ RECT originalRect;
+ int cX, cY;
+ int minWinWidth, minWinHeight;
+ int maxWinWidth, maxWinHeight;
+ int sugWinWidth, sugWinHeight;
+ int screenHeight, screenWidth;
+ bool cancelit;
+ RECT snapAdjust;
+
+#ifdef WIN32
+ HBRUSH oldB, brush;
+ HPEN oldP, pen;
+#endif
+ HDC dc;
+ int mix;
+
+public:
+ resizeClass(ifc_window *wnd, int minx, int miny, int maxx, int maxy, int sugx, int sugy);
+ ~resizeClass();
+ int resizeWindow(ifc_window *wnd, int way);
+#ifdef _WIN32
+ LRESULT wndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+#endif
+ RECT getRect(void);
+};
+
+#endif
+
diff --git a/Src/Wasabi/api/wndmgr/skinembed.cpp b/Src/Wasabi/api/wndmgr/skinembed.cpp
new file mode 100644
index 00000000..079bc688
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/skinembed.cpp
@@ -0,0 +1,733 @@
+#include <precomp.h>
+#include "skinembed.h"
+#include <api/wndmgr/layout.h>
+#include <api/wnd/wndclass/wndholder.h>
+#include <api/skin/skinparse.h>
+#include <api/wnd/wndtrack.h>
+#include <api/config/items/cfgitemi.h>
+#include <api/config/items/attrint.h>
+#include <bfc/named.h>
+#include <api/wndmgr/autopopup.h>
+#include <api/syscb/callbacks/wndcb.h>
+#include <api/wndmgr/skinwnd.h>
+#include <api/script/scriptmgr.h>
+#include <bfc/critsec.h>
+
+CriticalSection skinembed_cs;
+
+SkinEmbedder *skinEmbedder = NULL;
+
+SkinEmbedder::SkinEmbedder()
+{
+ ASSERTPR(skinEmbedder == NULL, "only one skin embedder please!");
+ skinEmbedder = this;
+}
+
+SkinEmbedder::~SkinEmbedder()
+{
+ inserted.deleteAll();
+ allofthem.deleteAll();
+}
+
+int SkinEmbedder::toggle(GUID g, const wchar_t *prefered_container, int container_flag, RECT *r, int transcient)
+{
+ ifc_window *w = enumItem(g, 0);
+ if (w != NULL)
+ {
+ destroy(w, r);
+ return 0;
+ }
+ ifc_window *wnd = create(g, NULL, prefered_container, container_flag, r, transcient);
+ if (wnd == NULL)
+ {
+#ifdef ON_CREATE_EXTERNAL_WINDOW_GUID
+ int y;
+ ON_CREATE_EXTERNAL_WINDOW_GUID(g, y);
+#endif
+
+ }
+ return 1;
+}
+
+int SkinEmbedder::toggle(const wchar_t *groupid, const wchar_t *prefered_container, int container_flag, RECT *r, int transcient)
+{
+ ifc_window *w = enumItem(groupid, 0);
+ if (w != NULL)
+ {
+ destroy(w, r);
+ return 0;
+ }
+ create(INVALID_GUID, groupid, prefered_container, container_flag, r, transcient);
+ return 1;
+}
+
+ifc_window *SkinEmbedder::create(GUID g, const wchar_t *prefered_container, int container_flag, RECT *r, int transcient, int starthidden, int *isnew)
+{
+ return create(g, NULL, prefered_container, container_flag, r, transcient, starthidden, isnew);
+}
+
+ifc_window *SkinEmbedder::create(const wchar_t *groupid, const wchar_t *prefered_container, int container_flag, RECT *r, int transcient, int starthidden, int *isnew)
+{
+ return create(INVALID_GUID, groupid, prefered_container, container_flag, r, transcient, starthidden, isnew);
+}
+
+WindowHolder *SkinEmbedder::getSuitableWindowHolder(GUID g, const wchar_t *group_id, Container *cont, Layout *lay, int _visible, int _dynamic, int _empty, int _hasself, int _autoavail)
+{
+ foreach(wndholders)
+ WindowHolder *h = wndholders.getfor();
+
+ ifc_window *w = h->getRootWndPtr()->getDesktopParent();
+ int dyn = 1;
+ int visible = 0;
+ int hasself = 0;
+ int empty = 0;
+ int autoavail = h->wndholder_isAutoAvailable();
+
+ Layout *l = (NULL != w) ? static_cast<Layout *>(w->getInterface(layoutGuid)) : NULL;
+ Container *c = NULL;
+
+ if (l)
+ {
+ c = l->getParentContainer();
+ if (c)
+ {
+ dyn = c->isDynamic();
+ }
+ }
+
+ if (NULL == w || !w->isInited()) visible = -1;
+ else
+ {
+ if (_visible == 1)
+ {
+ if (h->getRootWndPtr()->isVisible()) visible = 1;
+ }
+ else if (_visible == 0)
+ {
+ if (w->isVisible()) visible = 1;
+ }
+ }
+ if (!h->getCurRootWnd()) empty = 1;
+
+ if (g != INVALID_GUID)
+ {
+ if (g == h->getCurGuid())
+ hasself = 1;
+ }
+ else if (group_id && h->getCurGroupId())
+ {
+ if (!WCSICMP(group_id, h->getCurGroupId()))
+ hasself = 1;
+ }
+
+ if (_visible != -1)
+ {
+ if (visible != _visible) continue;
+ }
+ if (_dynamic != -1)
+ {
+ if (_dynamic != dyn) continue;
+ }
+ if (_empty != -1)
+ {
+ if (empty != _empty) continue;
+ }
+ if (_hasself != -1)
+ {
+ if (hasself != _hasself) continue;
+ }
+ if (_autoavail != -1)
+ {
+ if (autoavail != _autoavail) continue;
+ }
+
+ if (cont != NULL)
+ {
+ if (c != cont) continue;
+ }
+
+ if (lay != NULL)
+ {
+ if (l != lay) continue;
+ }
+
+ if (g != INVALID_GUID)
+ {
+ if (h->wantGuid(g)) return h;
+ }
+ else if (group_id)
+ {
+ if (h->wantGroup(group_id)) return h;
+ }
+ endfor;
+
+ return NULL;
+}
+
+ifc_window *SkinEmbedder::create(GUID g, const wchar_t *groupid, const wchar_t *prefered_container, int container_flag, RECT *r, int transcient, int starthidden, int *isnew)
+{
+ // InCriticalSection in_cs(&skinembed_cs);
+
+ foreach(in_deferred_callback)
+ SkinEmbedEntry *e = in_deferred_callback.getfor();
+ if ((e->guid != INVALID_GUID && e->guid == g) || WCSCASEEQLSAFE(groupid, e->groupid))
+ {
+#ifdef _DEBUG
+ DebugStringW(L"trying to show a window that is being destroyed, hm, try again later\n");
+#endif
+ // too soon! try later dude
+ return NULL;
+ }
+ endfor;
+
+ RECT destrect = {0};
+
+ if (isnew) *isnew = 0;
+
+ WindowHolder *wh = NULL;
+ // todo: get from c++ callback
+
+ if (SOM::checkAbortShowHideWindow(g, 1))
+ return NULL;
+
+ if (g != INVALID_GUID)
+ wh = SOM::getSuitableWindowHolderFromScript(g);
+
+ if (!wh) wh = getSuitableWindowHolder(g, groupid, NULL, NULL, 1 /*visible*/, 0 /*static*/, 1 /*empty*/, -1 /*donttest*/, -1 /*donttest*/);
+ if (!wh) wh = getSuitableWindowHolder(g, groupid, NULL, NULL, 0 /*hidden*/, 0 /*static*/, 0 /*notempty*/, 1 /*hasself*/, -1 /*donttest*/);
+ if (!wh) wh = getSuitableWindowHolder(g, groupid, NULL, NULL, 0 /*hidden*/, 0 /*static*/, 1 /*empty*/, -1 /*donttest*/, 1 /*autoavail*/);
+ if (!wh) wh = getSuitableWindowHolder(g, groupid, NULL, NULL, 1 /*visible*/, 1 /*dynamic*/, 1 /*empty*/, -1 /*donttest*/, -1 /*donttest*/);
+ ifc_window *whrw = wh ? wh->getRootWndPtr() : NULL;
+ Container *cont = NULL;
+ Layout *lay = NULL;
+ ifc_window *wnd = NULL;
+ int newcont = 0;
+
+ if (!wh)
+ { // no hidden static container, so lets create a dynamic one
+ if (isnew) *isnew = 1;
+ if (container_flag == 0 && (prefered_container == NULL || !*prefered_container))
+ {
+ prefered_container = AutoPopup::getDefaultContainerParams(groupid, g, &container_flag);
+ }
+ if (container_flag == 0 && (prefered_container == NULL || !*prefered_container))
+ {
+ prefered_container = WASABI_DEFAULT_STDCONTAINER;
+ }
+ cont = SkinParser::loadContainerForWindowHolder(groupid, g, 0, transcient, prefered_container, container_flag);
+ if (cont)
+ {
+ cont->setTranscient(transcient);
+ newcont = 1;
+ lay = cont->enumLayout(0);
+ /* if (prefered_layout) { // find its target layout
+ cont->setDefaultLayout(prefered_layout);
+ lay = cont->getLayout(prefered_layout);
+ if (!lay) {
+ if (!layout_flag) // see if we can fallback
+ lay = cont->enumLayout(0);
+ else {
+ destroyContainer(cont); // deferred
+ api->console_outputString(9, StringPrintf("could not find the requested layout (%s) to host the window", prefered_container));
+ return NULL;
+ }
+ }*/
+ }
+ else
+ {
+ DebugStringW(L"no container found to hold the window... not even a default one :/\n");
+ }
+ wh = getSuitableWindowHolder(g, groupid, cont, lay, -1 /*donttest*/, -1 /*donttest*/, 0 /*notempty*/, 1 /*hasself*/, -1 /*donttest*/);
+ if (!wh) wh = getSuitableWindowHolder(g, groupid, cont, lay, -1 /*donttest*/, -1 /*donttest*/, 1 /*empty*/, -1 /*donttest*/, -1 /*donttest*/);
+ whrw = wh ? wh->getRootWndPtr() : NULL;
+ }
+
+ if (wh)
+ {
+ GuiObject *o = static_cast<GuiObject *>(whrw->getInterface(guiObjectGuid));
+ ASSERT(o != NULL);
+ if (o)
+ {
+ lay = o->guiobject_getParentLayout();
+ if (lay)
+ cont = lay->getParentContainer();
+ }
+ if ((g != INVALID_GUID && (g == wh->getCurGuid())) || (groupid && (wh->getCurGroupId() == groupid)))
+ wnd = wh->getCurRootWnd();
+ else
+ {
+ if (wh->getCurRootWnd())
+ wh->onRemoveWindow();
+ wnd = wh->onInsertWindow(g, groupid);
+ }
+ }
+
+ if (!wnd)
+ {
+ if (cont)
+ {
+ if (!WCSCASEEQLSAFE(cont->getId(), L"main"))
+ cont->close();
+ }
+ return NULL;
+ }
+
+ //int anim = 1;
+ //if (wh && !whrw->getAnimatedRects()) anim = 0; // FIXME!!
+
+ if (lay && r)
+ {
+ lay->getWindowRect(&destrect);
+ }
+
+ if (cont /*&& cont->isDynamic()*/)
+ {
+ const wchar_t *text = wnd->getRootWndName();
+ cont->setTranscient(transcient);
+ if (text != NULL)
+ if (cont->isDynamic()) cont->setName(text);
+ if (cont->isDynamic() && !transcient) cont->resetLayouts();
+ if (newcont) cont->onInit(1);
+ }
+
+#ifdef WASABI_COMPILE_CONFIG
+ // {280876CF-48C0-40bc-8E86-73CE6BB462E5}
+ const GUID options_guid =
+ { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
+ CfgItem *cfgitem = WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid);
+ int findopenrect = _int_getValue(cfgitem, L"Find open rect");
+#else
+ int findopenrect = WASABI_WNDMGR_FINDOPENRECT;
+#endif
+
+ if (wh && findopenrect)
+ {
+ if (lay)
+ {
+ RECT rl;
+ lay->getWindowRect(&rl);
+ RECT nr = windowTracker->findOpenRect(rl, lay);
+ destrect = nr; // rewrite destrect
+ int w = rl.right - rl.left;
+ int h = rl.bottom - rl.top;
+ lay->divRatio(&w, &h);
+ nr.right = nr.left + w;
+ nr.bottom = nr.top + h;
+ lay->resizeToRect(&nr);
+ }
+ }
+
+ if (wh)
+ {
+ if (r)
+ /*if (anim)*/ WASABI_API_WNDMGR->drawAnimatedRects(r, &destrect);
+ /*else
+ {
+ RECT r;
+ r.left = destrect.left + (destrect.right - destrect.left) / 2 - 1;
+ r.top = destrect.top + (destrect.bottom - destrect.top) / 2 + 1;
+ r.right = r.left + 2;
+ r.bottom = r.top + 2;
+ if (anim) WASABI_API_WNDMGR->drawAnimatedRects(&r, &destrect);
+ }*/
+ }
+
+ if (!starthidden)
+ {
+ if (cont && cont->isVisible())
+ { // we were already shown, duh
+ // cont->setVisible(0);
+ }
+ else
+ {
+ if (cont) cont->setVisible(1);
+ else if (lay) lay->setVisible(1);
+ }
+ }
+
+ if (wnd && newcont && !transcient)
+ {
+ inserted.addItem(new SkinEmbedEntry(wnd->getDependencyPtr(), wnd, g, groupid, prefered_container, container_flag, cont, wh));
+ viewer_addViewItem(wnd->getDependencyPtr());
+ }
+
+ if (!transcient && wnd)
+ allofthem.addItem(new SkinEmbedEntry(wnd->getDependencyPtr(), wnd, g, groupid, prefered_container, container_flag, cont, wh));
+
+ return wnd;
+}
+
+void SkinEmbedder::destroy(ifc_window *w, RECT *r)
+{
+ int donecheck = 0;
+ SkinEmbedEntry *e = NULL;
+ for (int i = 0; i < allofthem.getNumItems();i++)
+ {
+ e = allofthem.enumItem(i);
+ if (e->wnd == w)
+ {
+ donecheck = 1;
+ if (SOM::checkAbortShowHideWindow(e->guid, 0))
+ return ;
+ break;
+ }
+ }
+ if (WASABI_API_WND->rootwndIsValid(w))
+ {
+ if (!donecheck)
+ {
+ ifc_window *ww = w->findWindowByInterface(windowHolderGuid);
+ if (ww)
+ {
+ WindowHolder *wh = static_cast<WindowHolder*>(ww->getInterface(windowHolderGuid));
+ if (wh)
+ {
+ GUID g = wh->getCurGuid();
+ if (g != INVALID_GUID)
+ {
+ donecheck = 1;
+ if (SOM::checkAbortShowHideWindow(g, 0))
+ return ;
+ }
+ }
+ }
+ }
+ }
+ // checkAbort can render w invalid !!! check again
+ if (WASABI_API_WND->rootwndIsValid(w))
+ {
+ ifc_window *wnd = w->getDesktopParent();
+ GuiObject *go = static_cast<GuiObject *>(wnd->getInterface(guiObjectGuid));
+ if (go)
+ {
+ Layout *l = go->guiobject_getParentLayout();
+ if (l)
+ {
+ Container *c = l->getParentContainer();
+ if (c)
+ {
+ if (!WCSCASEEQLSAFE(c->getId(), L"main"))
+ {
+ c->close(); // deferred if needed
+ }
+ else
+ {
+ softclose:
+ ifc_window *wnd = w->findWindowByInterface(windowHolderGuid);
+ if (wnd != NULL)
+ {
+ WindowHolder *wh = static_cast<WindowHolder *>(wnd->getInterface(windowHolderGuid));
+ if (wh != NULL)
+ {
+ wh->onRemoveWindow(1);
+ }
+ }
+ }
+ }
+ else goto softclose;
+ }
+ }
+ }
+}
+
+int SkinEmbedder::getNumItems(GUID g)
+{
+ int n = 0;
+ for (int i = 0;i < wndholders.getNumItems();i++)
+ if (wndholders.enumItem(i)->getRootWndPtr()->isVisible() && wndholders.enumItem(i)->getCurGuid() == g) n++;
+ return n;
+}
+
+int SkinEmbedder::getNumItems(const wchar_t *groupid)
+{
+ int n = 0;
+ for (int i = 0;i < wndholders.getNumItems();i++)
+ {
+ WindowHolder *wh = wndholders.enumItem(i);
+ if (wh->getRootWndPtr()->isVisible()
+ && WCSCASEEQLSAFE(wh->getCurGroupId(), groupid))
+ n++;
+ }
+ return n;
+}
+
+ifc_window *SkinEmbedder::enumItem(GUID g, int n)
+{
+ ASSERT(n >= 0);
+ for (int i = 0;i < wndholders.getNumItems();i++)
+ {
+ WindowHolder *wh = wndholders.enumItem(i);
+ if (wh->getCurGuid() == g)
+ {
+ ifc_window *w = wh->getRootWndPtr();
+ Container *c = NULL;
+ if (w)
+ {
+ w = w->getDesktopParent();
+ if (w)
+ {
+ Layout *l = static_cast<Layout *>(w->getInterface(layoutGuid));
+ if (l)
+ {
+ c = l->getParentContainer();
+ }
+ }
+ }
+ if (c && c->isVisible() || (!c && wndholders.enumItem(i)->getRootWndPtr()->isVisible()))
+ {
+ if (n == 0)
+ return wndholders.enumItem(i)->getCurRootWnd();
+ n--;
+ }
+ }
+ }
+ return NULL;
+}
+
+ifc_window *SkinEmbedder::enumItem(const wchar_t *groupid, int n)
+{
+ ASSERT(n >= 0);
+ for (int i = 0;i < wndholders.getNumItems();i++)
+ {
+ WindowHolder *wh = wndholders.enumItem(i);
+ const wchar_t *curgroupid = wndholders[i]->getCurGroupId();
+ if (WCSCASEEQLSAFE(curgroupid, groupid))
+ {
+ ifc_window *w = wh->getRootWndPtr();
+ Container *c = NULL;
+ if (w)
+ {
+ w = w->getDesktopParent();
+ if (w)
+ {
+ Layout *l = static_cast<Layout *>(w->getInterface(layoutGuid));
+ if (l)
+ {
+ c = l->getParentContainer();
+ }
+ }
+ }
+ if (c && c->isVisible() || (!c && wndholders.enumItem(i)->getRootWndPtr()->isVisible()))
+ {
+ if (n == 0)
+ return wndholders.enumItem(i)->getCurRootWnd();
+ n--;
+ }
+ }
+ }
+ return NULL;
+}
+
+void SkinEmbedder::registerWindowHolder(WindowHolder *wh)
+{
+ if (wndholders.haveItem(wh)) return ;
+ wndholders.addItem(wh);
+}
+
+void SkinEmbedder::unregisterWindowHolder(WindowHolder *wh)
+{
+ if (!wndholders.haveItem(wh)) return ;
+ wndholders.removeItem(wh);
+}
+
+int SkinEmbedder::viewer_onItemDeleted(api_dependent *item)
+{
+ foreach(in_deferred_callback)
+ if (in_deferred_callback.getfor()->dep == item)
+ in_deferred_callback.removeByPos(foreach_index);
+ endfor
+ foreach(inserted)
+ SkinEmbedEntry *e = inserted.getfor();
+ if (e->dep == item)
+ {
+ inserted.removeItem(e);
+ allofthem.removeItem(e);
+ delete e;
+ break;
+ }
+ endfor;
+ foreach(allofthem)
+ SkinEmbedEntry *e = allofthem.getfor();
+ if (e->dep == item)
+ {
+ allofthem.removeItem(e);
+ delete e;
+ break;
+ }
+ endfor;
+ return 1;
+}
+
+void SkinEmbedder::cancelDestroyContainer(Container *c)
+{
+ if (!cancel_deferred_destroy.haveItem(c)) cancel_deferred_destroy.addItem(c);
+}
+
+void SkinEmbedder::destroyContainer(Container *o)
+{
+ ASSERT(o);
+ //fg>disabled as of 11/4/2003, side effect of cancelling fullscreen video (ie, notifier while playing video fullscreen)
+ //delt with the problem in basewnd directly
+ //#ifdef WIN32
+ //SetFocus(NULL); // FG> this avoids Win32 calling directly WM_KILLFOCUS into a child's wndproc (couldn't they just have posted the damn msg ?), who would then call some of his parent's virtual functions while it is being deleted
+ // perhaps it would be good to add a generic way to disable most child wnd messages while the parent is being deleted
+ //#endif
+
+ cancel_deferred_destroy.removeItem(o);
+
+ foreach(inserted)
+ SkinEmbedEntry *e = inserted.getfor();
+ if (e->container == o)
+ {
+ if (!in_deferred_callback.haveItem(e))
+ in_deferred_callback.addItem(e);
+
+ break;
+ }
+ endfor
+ deferred_destroy.addItem(o);
+ timerclient_setTimer(CB_DESTROYCONTAINER, 20);
+ //o->setVisible(0);
+ //timerclient_postDeferredCallback(CB_DESTROYCONTAINER, (intptr_t)o);
+}
+
+void SkinEmbedder::timerclient_timerCallback(int id)
+{
+ if (id == CB_DESTROYCONTAINER)
+ {
+ foreach(deferred_destroy)
+ Container *c = deferred_destroy.getfor();
+ foreach(in_deferred_callback)
+ if (in_deferred_callback.getfor()->container == c)
+ {
+ in_deferred_callback.removeByPos(foreach_index);
+ }
+ endfor;
+ if (cancel_deferred_destroy.haveItem(c))
+ {
+ continue;
+ }
+ if (SkinParser::isContainer(c)) // otherwise i'ts already gone while we were waiting for the callback, duh!
+ delete c;
+ endfor
+ cancel_deferred_destroy.removeAll();
+ deferred_destroy.removeAll();
+ timerclient_killTimer(CB_DESTROYCONTAINER);
+ return ;
+ }
+ TimerClientDI::timerclient_timerCallback(id);
+}
+
+int SkinEmbedder::timerclient_onDeferredCallback(intptr_t p1, intptr_t p2)
+{
+ return TimerClientDI::timerclient_onDeferredCallback(p1, p2);
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+void SkinEmbedder::saveState()
+{
+ int i = 0;
+ wchar_t t[1024] = {0};
+ foreach(inserted)
+ SkinEmbedEntry *e = inserted.getfor();
+ if (e->guid != INVALID_GUID)
+ {
+ nsGUID::toCharW(e->guid, t);
+ }
+ else
+ {
+ WCSCPYN(t, e->groupid, 1024);
+ }
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"wndstatus/id/%d", i), t);
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"wndstatus/layout/%d", i), !e->layout.isempty() ? e->layout.getValue() : L"");
+ WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"wndstatus/flag/%d", i), e->required);
+ i++;
+ endfor;
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"wndstatus/id/%d", i), L"");
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"wndstatus/layout/%d", i), L"");
+ WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"wndstatus/flag/%d", i), 0);
+}
+
+void SkinEmbedder::restoreSavedState()
+{
+ int i = 0;
+ wchar_t t[1024] = {0};
+ wchar_t l[256] = {0};
+ while (1)
+ {
+ WASABI_API_CONFIG->getStringPrivate(StringPrintfW(L"wndstatus/id/%d", i), t, 1024, L"");
+ if (!*t) break;
+ WASABI_API_CONFIG->getStringPrivate(StringPrintfW(L"wndstatus/layout/%d", i), l, 256, L"");
+ int flag = WASABI_API_CONFIG->getIntPrivate(StringPrintfW(L"wndstatus/flag/%d", i), 0);
+ GUID g = nsGUID::fromCharW(t);
+ //ifc_window *created = NULL;
+ //int tried = 0;
+ if (g != INVALID_GUID)
+ {
+ ifc_window *w = enumItem(g, 0);
+ if (w == NULL)
+ {
+ //tried = 1;
+ /*created = */create(g, l, flag);
+ }
+ }
+ else
+ {
+ ifc_window *w = enumItem(t, 0);
+ if (w == NULL)
+ {
+ //tried = 1;
+ /*created = */create(t, l, flag);
+ }
+ }
+ /* if (tried && !created) {
+ for (int j=0;j<inserted.getNumItems();j++) {
+ SkinEmbedEntry *e = inserted.enumItem(j);
+ int yes = 0;
+ if (g != INVALID_GUID) {
+ if (e->guid == g && e->required == flag && STRCASEEQLSAFE(e->layout, l))
+ yes = 1;
+ } else {
+ if (STRCASEEQLSAFE(e->groupid, t) && e->required == flag && STRCASEEQLSAFE(e->layout, l))
+ yes = 1;
+ }
+ if (yes) {
+ inserted.removeByPos(j);
+ j--;
+ delete e;
+ }
+ }
+ }*/
+ i++;
+ }
+}
+#endif
+
+void SkinEmbedder::attachToSkin(ifc_window *w, int side, int size)
+{
+ RECT r;
+ if (w == NULL) return ;
+ ifc_window *_w = w->getDesktopParent();
+ if (_w == NULL) _w = w;
+ SkinParser::getSkinRect(&r, _w);
+
+ switch (side)
+ {
+ case SKINWND_ATTACH_RIGHT:
+ _w->resize(r.right, r.top, size, r.bottom - r.top);
+ break;
+ case SKINWND_ATTACH_TOP:
+ _w->resize(r.left, r.top - size, r.right - r.left, size);
+ break;
+ case SKINWND_ATTACH_LEFT:
+ _w->resize(r.left - size, r.top, size, r.bottom - r.top);
+ break;
+ case SKINWND_ATTACH_BOTTOM:
+ _w->resize(r.left, r.bottom, r.right - r.left, size);
+ break;
+ }
+}
+
+PtrList<SkinEmbedEntry> SkinEmbedder::in_deferred_callback;
+PtrList<Container> SkinEmbedder::cancel_deferred_destroy;
+PtrList<Container> SkinEmbedder::deferred_destroy;
diff --git a/Src/Wasabi/api/wndmgr/skinembed.h b/Src/Wasabi/api/wndmgr/skinembed.h
new file mode 100644
index 00000000..e33630ab
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/skinembed.h
@@ -0,0 +1,76 @@
+#ifndef __SKIN_EMBEDDER_H
+#define __SKIN_EMBEDDER_H
+
+#include <bfc/nsguid.h>
+#include <bfc/string/bfcstring.h>
+#include <bfc/string/StringW.h>
+#include <bfc/ptrlist.h>
+#include <bfc/depend.h>
+#include <api/timer/timerclient.h>
+
+#define CB_DESTROYCONTAINER 0x887
+
+class ifc_window;
+class WindowHolder;
+class Container;
+class Layout;
+
+class SkinEmbedEntry {
+ public:
+ SkinEmbedEntry(api_dependent *d, ifc_window *w, GUID g, const wchar_t *gid, const wchar_t *prefered_container, int container_flag, Container *c, WindowHolder *wh) : groupid(gid), guid(g), dep(d), wnd(w), required(container_flag), layout(prefered_container), container(c), wndholder(wh) { }
+ virtual ~SkinEmbedEntry() { }
+
+ StringW groupid;
+ GUID guid;
+ api_dependent *dep;
+ ifc_window *wnd;
+ int required;
+ StringW layout;
+ Container *container;
+ WindowHolder *wndholder;
+};
+
+class SkinEmbedder : public DependentViewerI, public TimerClientDI {
+ public:
+
+ SkinEmbedder();
+ virtual ~SkinEmbedder();
+
+ int toggle(GUID g, const wchar_t *prefered_container=NULL, int container_flag=0, RECT *r=NULL, int transcient=0);
+ int toggle(const wchar_t *groupid, const wchar_t *prefered_container=NULL, int container_flag=0, RECT *r=NULL, int transcient=0);
+ ifc_window *create(GUID g, const wchar_t *prefered_container=NULL, int container_flag=0, RECT *r=NULL, int transcient=0, int starthidden=0, int *isnew=NULL);
+ ifc_window *create(const wchar_t *groupid, const wchar_t *prefered_container=NULL, int container_flag=0, RECT *r=NULL, int transcient=0, int starthidden=0, int *isnew=NULL);
+ void destroy(ifc_window *w, RECT *r=NULL);
+ int getNumItems(GUID g);
+ int getNumItems(const wchar_t *groupid);
+ ifc_window *enumItem(GUID g, int n);
+ ifc_window *enumItem(const wchar_t *groupid, int n);
+ WindowHolder *getSuitableWindowHolder(GUID g, const wchar_t *group_id, Container *cont, Layout *lay, int visible, int dynamic, int empty, int has_self, int autoavail);
+ void registerWindowHolder(WindowHolder *w);
+ void unregisterWindowHolder(WindowHolder *w);
+ void destroyContainer(Container *o);
+ virtual int timerclient_onDeferredCallback(intptr_t param1, intptr_t param2);
+ virtual void timerclient_timerCallback(int id);
+#ifdef WASABI_COMPILE_CONFIG
+ void restoreSavedState();
+ void saveState();
+#endif
+ void attachToSkin(ifc_window *w, int side, int size);
+
+ virtual int viewer_onItemDeleted(api_dependent *item);
+ static void cancelDestroyContainer(Container *c);
+
+ private:
+ ifc_window *create(GUID g, const wchar_t *groupid, const wchar_t *prefered_container=NULL, int container_flag=0, RECT *r=NULL, int transcient=0, int starthidden=0, int *isnew=NULL);
+
+ PtrList<WindowHolder> wndholders;
+ PtrList<SkinEmbedEntry> inserted;
+ PtrList<SkinEmbedEntry> allofthem;
+ static PtrList<SkinEmbedEntry> in_deferred_callback;
+ static PtrList<Container> cancel_deferred_destroy;
+ static PtrList<Container> deferred_destroy;
+};
+
+extern SkinEmbedder *skinEmbedder;
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/skinwnd.cpp b/Src/Wasabi/api/wndmgr/skinwnd.cpp
new file mode 100644
index 00000000..5ac895a0
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/skinwnd.cpp
@@ -0,0 +1,99 @@
+#include <precomp.h>
+#include "skinwnd.h"
+#include <api/wnd/api_window.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/script/scriptguid.h>
+#include <api/script/objects/c_script/c_group.h>
+#include <api/script/objects/c_script/c_layout.h>
+#include <api/script/objects/c_script/c_container.h>
+#include <api/wnd/wndclass/wndholder.h>
+
+SkinWnd::SkinWnd(const wchar_t *group_id, const wchar_t *prefered_container, int container_flag, RECT *animated_rect_source, int transcient, int starthidden)
+{
+ isnew = 0;
+ wnd = WASABI_API_WNDMGR->skinwnd_createByGroupId(group_id, prefered_container, container_flag, animated_rect_source, transcient, starthidden, &isnew);
+ notifyMinMaxChanged();
+}
+
+SkinWnd::SkinWnd(GUID svc_or_group_guid, const wchar_t *prefered_container, int container_flag, RECT *animated_rect_source, int transcient, int starthidden)
+{
+ isnew = 0;
+ wnd = WASABI_API_WNDMGR->skinwnd_createByGuid(svc_or_group_guid, prefered_container, container_flag, animated_rect_source, transcient, starthidden, &isnew);
+ notifyMinMaxChanged();
+}
+
+SkinWnd::~SkinWnd()
+{}
+
+void SkinWnd::destroy(RECT *animated_rect_dest)
+{
+ if (wnd == NULL) return ;
+ if (!isnew)
+ {
+ ifc_window *w = wnd->findWindowByInterface(windowHolderGuid);
+ WindowHolder *wh = static_cast<WindowHolder*>(w->getInterface(windowHolderGuid));
+ if (wh != NULL)
+ {
+ wh->onRemoveWindow();
+ return ;
+ }
+ }
+ WASABI_API_WNDMGR->skinwnd_destroy(wnd, animated_rect_dest);
+}
+
+int SkinWnd::runModal(int center)
+{
+ if (wnd == NULL) return 0;
+ ifc_window *w = wnd->getDesktopParent();
+ if (center)
+ {
+ C_Layout l(getLayout());
+ l.center();
+ }
+ w->setVisible(1);
+ return w->runModal();
+}
+
+void SkinWnd::endModal(int retcode)
+{
+ if (wnd == NULL) return ;
+ wnd->endModal(retcode);
+}
+
+GuiObject *SkinWnd::findObject(const wchar_t *object_id)
+{
+ if (wnd == NULL) return NULL;
+ GuiObject *obj = NULL;
+ obj = static_cast<GuiObject *>(wnd->getInterface(guiObjectGuid));
+ return obj->guiobject_findObject(object_id);
+}
+
+ScriptObject *SkinWnd::getContainer()
+{
+ if (wnd == NULL) return NULL;
+ ifc_window *dw = wnd->getDesktopParent();
+ if (!dw) return NULL;
+ ScriptObject *o = static_cast<ScriptObject *>(dw->getInterface(scriptObjectGuid));
+ if (o != NULL)
+ {
+ return C_Layout(o).getContainer();
+ }
+ return NULL;
+}
+
+ScriptObject *SkinWnd::getLayout()
+{
+ if (wnd == NULL) return NULL;
+ ifc_window *dw = wnd->getDesktopParent();
+ if (!dw) return NULL;
+ ScriptObject *o = static_cast<ScriptObject *>(dw->getInterface(scriptObjectGuid));
+ return o;
+}
+
+void SkinWnd::notifyMinMaxChanged()
+{
+ if (wnd != NULL)
+ {
+ wnd->signalMinMaxEnforcerChanged();
+ }
+}
diff --git a/Src/Wasabi/api/wndmgr/skinwnd.h b/Src/Wasabi/api/wndmgr/skinwnd.h
new file mode 100644
index 00000000..e372fb56
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/skinwnd.h
@@ -0,0 +1,42 @@
+#ifndef __SKINWND_H
+#define __SKINWND_H
+
+#include <bfc/common.h>
+#include "api.h"
+#include <api/script/scriptobj.h>
+
+#define WASABISTDCONTAINER_RESIZABLE_STATUS "resizable_status"
+#define WASABISTDCONTAINER_RESIZABLE_NOSTATUS "resizable_nostatus"
+#define WASABISTDCONTAINER_STATIC "static"
+#define WASABISTDCONTAINER_MODAL "modal"
+
+#define SKINWND_ATTACH_LEFT 1
+#define SKINWND_ATTACH_TOP 2
+#define SKINWND_ATTACH_RIGHT 3
+#define SKINWND_ATTACH_BOTTOM 4
+
+class ifc_window;
+class GuiObject;
+
+class SkinWnd
+{
+ public:
+ SkinWnd(GUID svc_or_group_guid, const wchar_t *prefered_container=NULL, int container_flag=0, RECT *animated_rect_source=NULL, int transcient=0, int starthidden=0);
+ SkinWnd(const wchar_t *group_id, const wchar_t *prefered_container=NULL, int container_flag=0, RECT *animated_rect_source=NULL, int transcient=0, int starthidden=0);
+ virtual ~SkinWnd();
+ void destroy(RECT *animated_rect_dest=NULL);
+ ifc_window *getWindow() { return wnd; }
+ ScriptObject *getContainer();
+ ScriptObject *getLayout();
+ int runModal(int center=0);
+ void endModal(int retcode);
+ GuiObject *findObject(const wchar_t *object_id);
+ void notifyMinMaxChanged();
+ int isNewContainer() { return isnew; }
+
+ private:
+ ifc_window *wnd;
+ int isnew;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/snappnt.cpp b/Src/Wasabi/api/wndmgr/snappnt.cpp
new file mode 100644
index 00000000..93ad3df9
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/snappnt.cpp
@@ -0,0 +1,181 @@
+#include <precomp.h>
+#include "snappnt.h"
+#include <api/wndmgr/layout.h>
+#include <api/wnd/wndtrack.h>
+#include <api/config/items/cfgitem.h>
+
+SnapPoint::SnapPoint(Layout *l, Container *c)
+{
+ points.addItem(this);
+ setParentLayout(l);
+ setParentContainer(c);
+}
+
+SnapPoint::~SnapPoint()
+{
+ points.removeItem(this);
+}
+
+void SnapPoint::removeAll()
+{
+ points.deleteAllSafe();
+}
+
+int SnapPoint::setXmlParam(const wchar_t *paramname, const wchar_t *strvalue)
+{
+ if (!WCSICMP(paramname, L"id")) id = strvalue;
+ else if (!WCSICMP(paramname, L"x")) x = WTOI(strvalue);
+ else if (!WCSICMP(paramname, L"y")) y = WTOI(strvalue);
+ else if (!WCSICMP(paramname, L"relatx")) relatx = WTOI(strvalue);
+ else if (!WCSICMP(paramname, L"relaty")) relaty = WTOI(strvalue);
+ else return 0;
+ return 1;
+}
+
+void SnapPoint::setParentLayout(Layout *l)
+{
+ playout = l;
+}
+
+void SnapPoint::setParentContainer(Container *c)
+{
+ pcontainer = c;
+}
+
+Container *SnapPoint::getParentContainer()
+{
+ return pcontainer;
+}
+
+Layout *SnapPoint::getParentLayout()
+{
+ return playout;
+}
+
+const wchar_t *SnapPoint::getId()
+{
+ return id;
+}
+
+int SnapPoint::getX()
+{
+ if (getParentLayout())
+ return (int)((double)x * getParentLayout()->getRenderRatio());
+ return x;
+}
+
+int SnapPoint::getY()
+{
+ if (getParentLayout())
+ return (int)((double)y * getParentLayout()->getRenderRatio());
+ return y;
+}
+
+PtrList<SnapPoint> SnapPoint::points;
+
+int SnapPoint::match(ifc_window *master, RECT *z, ifc_window *slave, int flag, int *donex, int *doney, int w, int h)
+{
+ SnapPoint *pmast;
+ SnapPoint *pslav;
+
+ for (int i = 0;i < points.getNumItems();i++)
+ if (points.enumItem(i)->getParentLayout() == master)
+ {
+ pmast = points.enumItem(i);
+ for (int j = 0;j < points.getNumItems();j++)
+ if (points.enumItem(j)->getParentLayout() == slave)
+ {
+ pslav = points.enumItem(j);
+ int r = do_match(pmast, pslav, z, flag, donex, doney, w, h);
+ if (r)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int SnapPoint::do_match(SnapPoint *pmast, SnapPoint *pslav, RECT *z, int mask, int *donex, int *doney, int w, int h)
+{
+ //#if 0//BU> lone needs to make this work again
+ //fg> maybe it would have been a good idea to tell me about it... especially since it *works fine*
+
+ ASSERT(pmast);
+ ASSERT(pslav);
+ int f = 0;
+
+ if (((mask & KEEPSIZE) == 0) && !z)
+ {
+ ASSERTPR(0, "match resize with no rect");
+ }
+
+ if (!z)
+ { // just testing if docked
+
+ if (!WCSICMP(pmast->getId(), pslav->getId()))
+ {
+ BaseWnd *wm = pmast->getParentLayout();
+ BaseWnd *ws = pslav->getParentLayout();
+ if (ws && ws)
+ {
+ RECT pmr, psr;
+ wm->getWindowRect(&pmr);
+ ws->getWindowRect(&psr);
+ pmr.left += pmast->relatx ? pmast->getX() : (pmr.right - pmr.left + pmast->getX());
+ pmr.top += pmast->relaty ? pmast->getY() : (pmr.bottom - pmr.top + pmast->getY());
+ psr.left += pmast->relatx ? pslav->getX() : (psr.right - psr.left + pslav->getX());
+ psr.top += pmast->relaty ? pslav->getY() : (psr.bottom - psr.top + pslav->getY());
+ if (pmr.left == psr.left && pmr.top == psr.top)
+ {
+ if (donex) *donex = 1;
+ if (doney) *doney = 1;
+ return 1;
+ }
+ }
+ }
+ }
+ else
+ {
+
+ ASSERT(donex);
+ ASSERT(doney);
+
+ if (!WCSICMP(pmast->getId(), pslav->getId()))
+ {
+ //CUT: BaseWnd *wm = pmast->getParentLayout();
+ BaseWnd *ws = pslav->getParentLayout();
+ if (ws && ws)
+ {
+ RECT pmr, psr, osr, omr;
+ pmr = omr = *z;
+ ws->getWindowRect(&psr);
+ osr = psr;
+ pmr.left += pmast->relatx ? pmast->getX() : (pmr.right - pmr.left + pmast->getX());
+ pmr.top += pmast->relaty ? pmast->getY() : (pmr.bottom - pmr.top + pmast->getY());
+ psr.left += pmast->relatx ? pslav->getX() : (psr.right - psr.left + pslav->getX());
+ psr.top += pmast->relaty ? pslav->getY() : (psr.bottom - psr.top + pslav->getY());
+ if (pmr.left > psr.left - 10 && pmr.left < psr.left + 10 && (mask & LEFT) && ! *donex)
+ {
+ *donex = 1;
+ z->left = omr.left - (pmr.left - psr.left);
+ if (mask & KEEPSIZE)
+ z->right = z->left + w;
+ f++;
+ }
+ if (pmr.top > psr.top - 10 && pmr.top < psr.top + 10 && (mask & TOP) && ! *doney)
+ {
+ z->top = omr.top - (pmr.top - psr.top);
+ *doney = 1;
+ if (mask & KEEPSIZE)
+ z->bottom = z->top + h;
+ f++;
+ }
+ }
+ }
+
+ return f > 0;
+ }
+ return 0;
+}
+
+
+
diff --git a/Src/Wasabi/api/wndmgr/snappnt.h b/Src/Wasabi/api/wndmgr/snappnt.h
new file mode 100644
index 00000000..997e8fd7
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/snappnt.h
@@ -0,0 +1,49 @@
+#ifndef __SNAPPOINT_H
+#define __SNAPPOINT_H
+
+#include <bfc/ptrlist.h>
+#include <bfc/string/StringW.h>
+#include <api/skin/xmlobject.h>
+
+#define SNAPPOINT_XMLPARENT XmlObjectI
+
+class Container;
+class Layout;
+class SnapPoint;
+class ifc_window;
+
+class SnapPoint : public SNAPPOINT_XMLPARENT {
+
+public:
+ SnapPoint(Layout *l, Container *c);
+ virtual ~SnapPoint();
+
+ virtual int setXmlParam(const wchar_t *name, const wchar_t *strvalue);
+
+ virtual void setParentContainer(Container *c);
+ virtual void setParentLayout(Layout *l);
+ virtual Container *getParentContainer();
+ virtual Layout *getParentLayout();
+ virtual const wchar_t *getId();
+
+ virtual int getX();
+ virtual int getY();
+
+ static int match(ifc_window *master, RECT *z, ifc_window *slave, int flag, int *donex, int *doney, int w, int h);
+ static void removeAll();
+
+private:
+ int x;
+ int y;
+ int relatx;
+ int relaty;
+ StringW id;
+
+ Container *pcontainer;
+ Layout *playout;
+
+ static PtrList<SnapPoint> points;
+ static int do_match(SnapPoint *pmast, SnapPoint *pslav, RECT *z, int mask, int *donex, int *doney, int w, int h);
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wndmgr/wndmgrapi.cpp b/Src/Wasabi/api/wndmgr/wndmgrapi.cpp
new file mode 100644
index 00000000..7d77a792
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/wndmgrapi.cpp
@@ -0,0 +1,279 @@
+#include <precomp.h>
+#include "wndmgrapi.h"
+#include <api/wndmgr/autopopup.h>
+#include <api/wndmgr/skinembed.h>
+#include <api/wndmgr/animate.h>
+#include <api/wnd/wndtrack.h>
+#include <api/skin/skinparse.h>
+#include <api/wndmgr/msgbox.h>
+#include <api/util/varmgr.h>
+
+wndmgr_api *wndManagerApi = NULL;
+
+WndMgrApi::WndMgrApi()
+{
+ skinEmbedder = new SkinEmbedder();
+ windowTracker = new WindowTracker();
+}
+
+WndMgrApi::~WndMgrApi()
+{
+ delete skinEmbedder;
+ skinEmbedder = NULL;
+ delete windowTracker;
+ windowTracker = NULL;
+}
+
+void WndMgrApi::wndTrackAdd(ifc_window *wnd)
+{
+ if (wnd == NULL)
+ {
+ DebugString("wndTrackAdd, illegal param : wnd == NULL\n");
+ return ;
+ }
+ windowTracker->addWindow(wnd);
+}
+
+void WndMgrApi::wndTrackRemove(ifc_window *wnd)
+{
+ if (wnd == NULL)
+ {
+ DebugString("wndTrackAdd, illegal param : wnd == NULL\n");
+ return ;
+ }
+ windowTracker->removeWindow(wnd);
+}
+
+bool WndMgrApi::wndTrackDock(ifc_window *wnd, RECT *r, int mask)
+{
+ return windowTracker->autoDock(wnd, r, mask);
+}
+
+bool WndMgrApi::wndTrackDock2(ifc_window *wnd, RECT *r, RECT *orig_r, int mask)
+{
+ return windowTracker->autoDock(wnd, r, orig_r, mask);
+}
+
+void WndMgrApi::wndTrackStartCooperative(ifc_window *wnd)
+{
+ windowTracker->startCooperativeMove(wnd);
+}
+
+void WndMgrApi::wndTrackEndCooperative(void)
+{
+ windowTracker->endCooperativeMove();
+}
+
+int WndMgrApi::wndTrackWasCooperative(void)
+{
+ return windowTracker->wasCooperativeMove();
+}
+
+void WndMgrApi::wndTrackInvalidateAll()
+{
+ windowTracker->invalidateAllWindows();
+}
+
+int WndMgrApi::skinwnd_toggleByGuid(GUID g, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient)
+{
+ return skinEmbedder->toggle(g, prefered_container, container_flag, sourceanimrect, transcient);
+}
+
+int WndMgrApi::skinwnd_toggleByGroupId(const wchar_t *groupid, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient)
+{
+ return skinEmbedder->toggle(groupid, prefered_container, container_flag, sourceanimrect, transcient);
+}
+
+ifc_window *WndMgrApi::skinwnd_createByGuid(GUID g, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient, int starthidden, int *isnew)
+{
+ return skinEmbedder->create(g, prefered_container, container_flag, sourceanimrect, transcient, starthidden, isnew);
+}
+
+ifc_window *WndMgrApi::skinwnd_createByGroupId(const wchar_t *groupid, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient, int starthidden, int *isnew)
+{
+ return skinEmbedder->create(groupid, prefered_container, container_flag, sourceanimrect, transcient, starthidden, isnew);
+}
+
+void WndMgrApi::skinwnd_destroy(ifc_window *w, RECT *destanimrect)
+{
+ skinEmbedder->destroy(w, destanimrect);
+}
+
+int WndMgrApi::skinwnd_getNumByGuid(GUID g)
+{
+ return skinEmbedder->getNumItems(g);
+}
+
+ifc_window *WndMgrApi::skinwnd_enumByGuid(GUID g, int n)
+{
+ return skinEmbedder->enumItem(g, n);
+}
+
+int WndMgrApi::skinwnd_getNumByGroupId(const wchar_t *groupid)
+{
+ return skinEmbedder->getNumItems(groupid);
+}
+
+ifc_window *WndMgrApi::skinwnd_enumByGroupId(const wchar_t *groupid, int n)
+{
+ return skinEmbedder->enumItem(groupid, n);
+}
+
+void WndMgrApi::skinwnd_attachToSkin(ifc_window *w, int side, int size)
+{
+ skinEmbedder->attachToSkin(w, side, size);
+}
+
+ScriptObject *WndMgrApi::skin_getContainer(const wchar_t *container_name)
+{
+ Container *c = SkinParser::getContainer(container_name);
+ if (c != NULL) return c->getScriptObject();
+ return NULL;
+}
+
+ScriptObject *WndMgrApi::skin_getLayout(ScriptObject *container, const wchar_t *layout_name)
+{
+ ASSERT(container != NULL);
+ Container *c = static_cast<Container *>(container->vcpu_getInterface(containerGuid));
+ if (c != NULL)
+ {
+ Layout *l = c->getLayout(layout_name);
+ if (l != NULL) return l->getScriptObject();
+ }
+ return NULL;
+}
+
+void WndMgrApi::wndholder_register(WindowHolder *wh)
+{
+ skinEmbedder->registerWindowHolder(wh);
+}
+
+void WndMgrApi::wndholder_unregister(WindowHolder *wh)
+{
+ skinEmbedder->unregisterWindowHolder(wh);
+}
+
+int WndMgrApi::messageBox(const wchar_t *txt, const wchar_t *title, int flags, const wchar_t *not_anymore_identifier, ifc_window *parentwnd)
+{
+#ifdef WASABI_WNDMGR_OSMSGBOX
+ #ifdef WIN32
+
+ int f = 0;
+ if (flags & MSGBOX_OK) f |= MB_OK;
+ if (flags & MSGBOX_CANCEL) f |= MB_OKCANCEL;
+ if (flags & MSGBOX_YES) f |= MB_YESNO;
+ if ((flags & MSGBOX_YES) && (flags & MSGBOX_CANCEL)) f |= MB_YESNOCANCEL;
+
+ int r = MessageBoxW(parentwnd ? parentwnd->gethWnd() : NULL, txt, title, f);
+
+ if (r == IDOK) r = MSGBOX_OK;
+ if (r == IDCANCEL) r = MSGBOX_CANCEL;
+ if (r == IDYES) r = MSGBOX_YES;
+ if (r == IDNO) r = MSGBOX_NO;
+
+ return r;
+
+#else
+ // port me!
+#endif
+#else
+ MsgBox _mb(txt, title, flags, not_anymore_identifier);
+ return _mb.run();
+#endif
+}
+
+void WndMgrApi::drawAnimatedRects(const RECT *r1, const RECT *r2)
+{
+ if (r1 == NULL)
+ {
+ DebugString("drawAnimatedRects, illegal param : r1 == NULL\n");
+ return ;
+ }
+ if (r2 == NULL)
+ {
+ DebugString("drawAnimatedRects, illegal param : r2 == NULL\n");
+ return ;
+ }
+ AnimatedRects::draw(r1, r2);
+}
+
+int WndMgrApi::autopopup_registerGuid(GUID g, const wchar_t *desc, const wchar_t *prefered_container, int container_flag)
+{
+ return AutoPopup::registerGuid(SKINPARTID_NONE, g, desc, prefered_container, container_flag);
+}
+
+int WndMgrApi::autopopup_registerGroupId(const wchar_t *groupid, const wchar_t *desc, const wchar_t *prefered_container, int container_flag)
+{
+ return AutoPopup::registerGroupId(SKINPARTID_NONE, groupid, desc, prefered_container, container_flag);
+}
+
+void WndMgrApi::autopopup_unregister(int id)
+{
+ AutoPopup::unregister(id);
+}
+
+int WndMgrApi::autopopup_getNumGuids()
+{
+ return AutoPopup::getNumGuids();
+}
+
+GUID WndMgrApi::autopopup_enumGuid(int n)
+{
+ return AutoPopup::enumGuid(n);
+}
+
+int WndMgrApi::autopopup_getNumGroups()
+{
+ return AutoPopup::getNumGroups();
+}
+
+const wchar_t *WndMgrApi::autopopup_enumGroup(int n)
+{
+ return AutoPopup::enumGroup(n);
+}
+
+const wchar_t *WndMgrApi::autopopup_enumGuidDescription(int n)
+{
+ return AutoPopup::enumGuidDescription(n);
+}
+
+const wchar_t *WndMgrApi::autopopup_enumGroupDescription(int n)
+{
+ return AutoPopup::enumGroupDescription(n);
+}
+
+const wchar_t *WndMgrApi::varmgr_translate(const wchar_t *str)
+{
+ StringW *s = PublicVarManager::translate_nocontext(str);
+ if (s)
+ {
+ ret.swap(s);
+ delete s;
+ return ret.getValueSafe();
+ }
+ return str;
+}
+
+Stack<ifc_window*> WndMgrApi::modal_wnd_stack;
+
+ifc_window *WndMgrApi::getModalWnd()
+{
+ if (!modal_wnd_stack.peek()) return NULL;
+ return modal_wnd_stack.top();
+}
+
+void WndMgrApi::pushModalWnd(ifc_window *wnd)
+{
+ modal_wnd_stack.push(wnd);
+}
+
+void WndMgrApi::popModalWnd(ifc_window *wnd)
+{
+ if (getModalWnd() != wnd) return ;
+ modal_wnd_stack.pop();
+}
+
+Container *WndMgrApi::newDynamicContainer(const wchar_t *name, int transcient)
+{
+ return SkinParser::newDynamicContainer(name, transcient);
+}
diff --git a/Src/Wasabi/api/wndmgr/wndmgrapi.h b/Src/Wasabi/api/wndmgr/wndmgrapi.h
new file mode 100644
index 00000000..88637d49
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/wndmgrapi.h
@@ -0,0 +1,59 @@
+#ifndef __APIWNDMGR_H
+#define __APIWNDMGR_H
+
+#include <api/wndmgr/api_wndmgr.h>
+#include <bfc/stack.h>
+#include <bfc/string/StringW.h>
+
+class WndMgrApi : public wndmgr_apiI {
+ public:
+ WndMgrApi();
+ virtual ~WndMgrApi();
+
+ virtual void wndTrackAdd(ifc_window *wnd);
+ virtual void wndTrackRemove(ifc_window *wnd);
+ virtual bool wndTrackDock(ifc_window *wnd, RECT *r, int mask);
+ virtual bool wndTrackDock2(ifc_window *wnd, RECT *r, RECT *orig_r, int mask);
+ virtual void wndTrackStartCooperative(ifc_window *wnd);
+ virtual void wndTrackEndCooperative();
+ virtual int wndTrackWasCooperative();
+ virtual void wndTrackInvalidateAll();
+ virtual int skinwnd_toggleByGuid(GUID g, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0);
+ virtual int skinwnd_toggleByGroupId(const wchar_t *groupid, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0);
+ virtual ifc_window *skinwnd_createByGuid(GUID g, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0, int starthidden = 0, int *isnew=NULL);
+ virtual ifc_window *skinwnd_createByGroupId(const wchar_t *groupid, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0, int starthidden = 0, int *isnew=NULL);
+ virtual void skinwnd_destroy(ifc_window *w, RECT *destanimrect = NULL);
+ virtual int skinwnd_getNumByGuid(GUID g);
+ virtual ifc_window *skinwnd_enumByGuid(GUID g, int n);
+ virtual int skinwnd_getNumByGroupId(const wchar_t *groupid);
+ virtual ifc_window *skinwnd_enumByGroupId(const wchar_t *groupid, int n);
+ virtual void skinwnd_attachToSkin(ifc_window *w, int side, int size);
+ virtual ScriptObject *skin_getContainer(const wchar_t *container_name);
+ virtual ScriptObject *skin_getLayout(ScriptObject *container, const wchar_t *layout_name);
+ virtual void wndholder_register(WindowHolder *wh);
+ virtual void wndholder_unregister(WindowHolder *wh);
+ virtual int messageBox(const wchar_t *txt, const wchar_t *title, int flags, const wchar_t *not_anymore_identifier, ifc_window *parenwnt);
+ virtual ifc_window *getModalWnd();
+ virtual void pushModalWnd(ifc_window *w = MODALWND_NOWND);
+ virtual void popModalWnd(ifc_window *w = MODALWND_NOWND);
+ virtual void drawAnimatedRects(const RECT *r1, const RECT *r2);
+ virtual int autopopup_registerGuid(GUID g, const wchar_t *desc, const wchar_t *prefered_container = NULL, int container_flag = 0);
+ virtual int autopopup_registerGroupId(const wchar_t *groupid, const wchar_t *desc, const wchar_t *prefered_container = NULL, int container_flag = 0);
+ virtual void autopopup_unregister(int id);
+ virtual int autopopup_getNumGuids();
+ virtual GUID autopopup_enumGuid(int n);
+ virtual int autopopup_getNumGroups();
+ virtual const wchar_t *autopopup_enumGroup(int n);
+ virtual const wchar_t *varmgr_translate(const wchar_t *str);
+ virtual Container *newDynamicContainer(const wchar_t *name, int transcient);
+ virtual const wchar_t *autopopup_enumGuidDescription(int n);
+ virtual const wchar_t *autopopup_enumGroupDescription(int n);
+
+ private:
+
+ static Stack<ifc_window*> modal_wnd_stack;
+ StringW ret;
+};
+
+
+#endif // __APIWNDMGR_H