#include #include #include #include #include //#include //CUT!! #include #include #include #include #include #include #include #ifdef WASABI_COMPILE_COMPONENTS #include #endif #include #include #ifdef WASABI_COMPILE_WNDMGR #include #endif #include #include #include #ifdef WASABI_COMPILE_LOCALES #include #include #else #define _ #endif #include #include #ifdef _WIN32 extern HINSTANCE hInstance; #endif #define COLOR_WHITE (0xffffff) #define COLOR_BLACK (0x000000) #define COLOR_ERROR (0xff00ff) // with alpha #define COLOR_WHITEA (0xffffffff) #define COLOR_BLACKA (0xff000000) #define COLOR_ERRORA (0xffff00ff) xml_tag taglist[] = { {L"groupdef", XML_TAG_GROUPDEF, 1}, {L"group", XML_TAG_GROUP, 1}, {L"cfggroup", XML_TAG_CFGGROUP, 1}, {L"elements", XML_TAG_ELEMENTS, 1}, {L"snappoint", XML_TAG_SNAPPOINT, 0}, {L"script", XML_TAG_SCRIPT, 0}, {L"container", XML_TAG_CONTAINER, 1}, {L"layout", XML_TAG_LAYOUT, 1}, {L"elements", XML_ELEMENTTAG_ELEMENTS, 1}, {L"accelerators", XML_TAG_ACCELERATORS, 1}, {L"accelerator", XML_TAG_ACCELERATOR, 1}, {L"stringtable", XML_TAG_STRINGTABLE, 1}, {L"stringentry", XML_TAG_STRINGENTRY, 1}, }; BEGIN_STRINGDICTIONARY(_resizevalues) SDI(L"top", RESIZE_TOP); SDI(L"left", RESIZE_LEFT); SDI(L"right", RESIZE_RIGHT); SDI(L"bottom", RESIZE_BOTTOM); SDI(L"topleft", RESIZE_TOPLEFT); SDI(L"topright", RESIZE_TOPRIGHT); SDI(L"bottomleft", RESIZE_BOTTOMLEFT); SDI(L"bottomright", RESIZE_BOTTOMRIGHT); END_STRINGDICTIONARY(_resizevalues, resizevalues) BEGIN_STRINGDICTIONARY(_parsetypes) SDI(L"resize", PARSETYPE_RESIZE); SDI(L"color", PARSETYPE_COLOR); SDI(L"coloralpha", PARSETYPE_COLORALPHA); SDI(L"regionop", PARSETYPE_REGIONOP); SDI(L"internal_action", PARSETYPE_INTERNALACTION); SDI(L"group_inheritance", PARSETYPE_GROUPINHERITANCE); END_STRINGDICTIONARY(_parsetypes, parsetypes) BEGIN_STRINGDICTIONARY(_actionlist) SDI(L"none", ACTION_NONE); #ifdef WA3COMPATIBILITY SDI(L"about", ACTION_ABOUT); SDI(L"mb_forward", ACTION_MB_FORWARD); SDI(L"mb_back", ACTION_MB_BACK); SDI(L"mb_url", ACTION_MB_URL); SDI(L"mb_home", ACTION_MB_HOME); SDI(L"mb_stop", ACTION_MB_STOP); SDI(L"mb_refresh", ACTION_MB_REFRESH); SDI(L"text_larger", ACTION_TEXT_LARGER); SDI(L"text_smaller", ACTION_TEXT_SMALLER); SDI(L"preferences", ACTION_PREFERENCES); SDI(L"view_file_info", ACTION_VIEW_FILE_INFO); SDI(L"doublesize", ACTION_DOUBLESIZE); SDI(L"add_bookmark", ACTION_ADD_BOOKMARK); SDI(L"menu", ACTION_MENU); SDI(L"sysmenu", ACTION_SYSMENU); SDI(L"windowmenu", ACTION_WINDOWMENU); SDI(L"controlmenu", ACTION_CONTROLMENU); #endif // wa3compatibility #ifdef WASABI_WIDGETS_COMPBUCK SDI(L"cb_next", ACTION_CB_NEXT); SDI(L"cb_prev", ACTION_CB_PREV); SDI(L"cb_prevpage", ACTION_CB_PREVPAGE); SDI(L"cb_nextpage", ACTION_CB_NEXTPAGE); #endif #ifdef WASABI_COMPILE_WNDMGR SDI(L"endmodal", ACTION_ENDMODAL); SDI(L"minimize", ACTION_MINIMIZE); SDI(L"maximize", ACTION_MAXIMIZE); SDI(L"close", ACTION_CLOSE); SDI(L"close_window", ACTION_CLOSE_WINDOW); SDI(L"switch", ACTION_SWITCH); SDI(L"toggle", ACTION_TOGGLE); SDI(L"reload_skin", ACTION_RELOAD_SKIN); SDI(L"enforce_minmax", ACTION_ENFORCEMINMAX); SDI(L"toggle_always_on_top", ACTION_TOGGLE_ALWAYS_ON_TOP); #endif // wndmgr END_STRINGDICTIONARY(_actionlist, actionlist) #ifdef WASABI_COMPILE_MEDIACORE BEGIN_STRINGDICTIONARY(_displaylist) SDI(L"songname", DISPLAY_SONGNAME); SDI(L"songinfo", DISPLAY_SONGINFO); SDI(L"songartist", DISPLAY_SONGARTIST); SDI(L"songtitle", DISPLAY_SONGTITLE); SDI(L"songalbum", DISPLAY_SONGALBUM); SDI(L"songlength", DISPLAY_SONGLENGTH); SDI(L"time", DISPLAY_TIME); SDI(L"timeelapsed", DISPLAY_TIME); SDI(L"timeremaining", DISPLAY_TIME); SDI(L"componentbucket", DISPLAY_CB); SDI(L"songbitrate", DISPLAY_SONGBITRATE); SDI(L"songsamplerate", DISPLAY_SONGSAMPLERATE); SDI(L"songinfo_localise", DISPLAY_SONGINFO_TRANSLATED); END_STRINGDICTIONARY(_displaylist, displaylist) #endif // mediacore static GUID staticguid; void SkinParser::initialize() { if (!quickxmltaglist.getNumItems()) { for (int i = 0;i < sizeof(taglist) / sizeof(xml_tag);i++) quickxmltaglist.addItem(&taglist[i]); } // first two are for back compatibility skinXML.registerCallback(L"WinampAbstractionLayer", xmlReaderCallback); skinXML.registerCallback(L"WinampAbstractionLayer\f*", xmlReaderCallback); skinXML.registerCallback(L"WasabiXML", xmlReaderCallback); skinXML.registerCallback(L"WasabiXML\f*", xmlReaderCallback); guiTree = new GuiTree(); xuiCache = new SvcCacheT; } void SkinParser::shutdown() { skinXML.unregisterCallback((void*)xmlReaderCallback); delete guiTree; guiTree = NULL; delete xuiCache; xuiCache = NULL; } #ifdef WASABI_COMPILE_WNDMGR void SkinParser::setInitialFocus() { for (int i = 0;i < containers.getNumItems();i++) { if (containers[i]->isVisible()) { Layout *l = containers[i]->getCurrentLayout(); if (l) { l->setFocus(); return ; } } } #ifdef WIN32 #ifdef WA3COMPATIBILITY SetFocus(Main::gethWnd()); #endif //WA3COMPATIBILITY #else DebugString( "portme -- SkinParser::setInitialFocus\n" ); #endif //WIN32 } #endif #ifdef WASABI_COMPILE_WNDMGR // do not forget to popParserState(); before returning int SkinParser::loadContainers(const wchar_t *skin) { wchar_t olddir[WA_MAX_PATH] = {0}; Wasabi::Std::getCurDir(olddir, WA_MAX_PATH); Wasabi::Std::setCurDir(WASABI_API_APP->path_getAppPath()); int oldncontains = getNumContainers(); pushParserState(); allowscripts = 1; centerskin = 1; staticloading = 1; instantiatinggroup = 0; transcientcontainer = 0; inContainer = inLayout = 0; curGroup = NULL; recording_container = 0; recording_groupdef = 0; inElements = inGroup = inGroupDef = inAccelerators = inStringTable = 0; includepath = WASABI_API_SKIN->getSkinPath(); loading_main_skinfile = 0; SkinElementsMgr::onBeforeLoadingSkinElements(includepath); GammaMgr::onBeforeLoadingGammaGroups(); scriptId = WASABI_API_PALETTE->getSkinPartIterator(); int skinType = Skin::checkSkin(skin); int retcode = 0; loading_main_skinfile = 1; switch (skinType) { case Skin::CHKSKIN_UNKNOWN: popParserState(); break; #ifdef WA3COMPATIBILITY case Skin::CHKSKIN_ISWA2: retcode = XmlReader::loadFile("svc:wa2skinxml", includepath); break; #endif default: { retcode = skinXML.loadFile(StringPathCombine(includepath, L"skin.xml"), includepath); break; } } int n = guiTree->getNumObject(XML_TAG_CONTAINER); for (int i = 0;i < n;i++) { SkinItem *item = guiTree->getObject(XML_TAG_CONTAINER, i); if (item && item->getParams()) { if (item->getParams()->getItemValueInt(L"dynamic")) { if (item->getParams()->getItemValueInt(L"default_visible")) { const wchar_t *name = item->getParams()->getItemValue(L"name"); #ifdef ON_TWEAK_CONTAINER_NAMEW ON_TWEAK_CONTAINER_NAMEW(name); #endif wchar_t c[512]=L"-"; #ifdef WASABI_COMPILE_CONFIG WASABI_API_CONFIG->getStringPrivate(StringPrintfW(L"everloaded/%s", name), c, 511, L"-"); #endif c[510] = 0; if (c[0] == '-') { // never been created, create it now since it has default_visible staticloading = 0; /*Container *c = */instantiateDynamicContainer(item); staticloading = 1; } } } } } loading_main_skinfile = 0; Wasabi::Std::setCurDir(olddir); int ncontainersloaded = getNumContainers() - oldncontains; if (retcode == 0 || ncontainersloaded == 0) { return 0; } #ifdef WASABI_COMPILE_CONFIG WASABI_API_CONFIG->setStringPrivate(L"last_skin", Skin::getSkinName()); #endif ASSERT(tha != NULL); SkinElementsMgr::onAfterLoadingSkinElements(); GammaMgr::onAfterLoadingGammaGroups(); #ifdef WASABI_COMPILE_COMPONENTS ComponentManager::broadcastNotify(WAC_NOTIFY_SKINGUILOADED, WASABI_API_PALETTE->getSkinPartIterator()); #endif Skin::sendGuiLoadedCallback(); popParserState(); return ncontainersloaded; } void SkinParser::centerSkin() { RECT sr; if (centerskin && getSkinRect(&sr)) { int l = getNumContainers(); int w = (Wasabi::Std::getScreenWidth() - (sr.right - sr.left)) / 2; int h = (Wasabi::Std::getScreenHeight() - (sr.bottom - sr.top)) / 2; for (int i = 0;i < l;i++) { Container *c = enumContainer(i); if (!c->isVisible()) continue; Layout *l = c->getCurrentLayout(); RECT r; l->getWindowRect(&r); r.left += w; r.right += w; r.bottom += h; r.top += h; l->move(r.left, r.top); } } foreach(containers) containers.getfor()->savePositions(); endfor; } int SkinParser::getSkinRect(RECT *r, ifc_window *exclude) { if (!r) return 0; ZERO(*r); Container *cexcluded = NULL; if (exclude != NULL) { Layout *l = static_cast(exclude->getDesktopParent()); if (l != NULL) cexcluded = l->getParentContainer(); } int x = 99999, y = 99999, x2 = -1, y2 = -1; int l = getNumContainers(); for (int i = 0;i < l;i++) { Container *c = enumContainer(i); if (c == cexcluded) continue; if (!c->isInited()) c->onInit(); if (c->isDeleting() || !c->getCurrentLayout()) continue; int cx = c->getDefaultPositionX(); int cy = c->getDefaultPositionY(); if (cx == -1) cx = 0; if (cy == -1) cy = 0; RECT r; c->getWindowRect(&r); int cw = r.right - r.left; int ch = r.bottom - r.top; if (cx < x) x = cx; if (cy < y) y = cy; if ((cx + cw) > x2) x2 = cx + cw; if ((cy + ch) > y2) y2 = cy + ch; } if (x2 > 0 && y2 > 0 && x != 99999 && y != 99999) { Wasabi::Std::setRect(r, x, y, x2, y2); return 1; } return 0; } #endif // do not forget to popParserState(); before returning void SkinParser::loadScriptXml(const wchar_t *filename, int scriptid) { pushParserState(); allowscripts = 1; instantiatinggroup = 0; #ifdef WASABI_COMPILE_WNDMGR transcientcontainer = 0; inContainer = inLayout = 0; #endif staticloading = 1; recording_container = 0; recording_groupdef = 0; curGroup = NULL; inElements = inGroup = inGroupDef = inAccelerators = inStringTable = 0; scriptId = scriptid; //CUT char file[WA_MAX_PATH]; //CUT char drive[WA_MAX_PATH]; //CUT char dir[WA_MAX_PATH]; //CUT char fname[WA_MAX_PATH]; //CUT char ext[WA_MAX_PATH]; includepath.setValue(L""); wchar_t olddir[WA_MAX_PATH] = {0}; Wasabi::Std::getCurDir(olddir, WA_MAX_PATH); Wasabi::Std::setCurDir(WASABI_API_APP->path_getAppPath()); if (!WCSNICMP(filename, L"buf:", 4)) { skinXML.loadFile(filename, includepath); } else { //CUT DebugString("filename is %s\n", filename); includepath = filename; includepath.RemovePath(); skinXML.loadFile(filename /*file*/, includepath); } Wasabi::Std::setCurDir(olddir); popParserState(); } #ifdef WASABI_COMPILE_WNDMGR // do not forget to popParserState(); before returning Container *SkinParser::loadContainerForWindowHolder(const wchar_t *groupid, GUID g, int initit, int transcient, const wchar_t *containerid, int container_flag) { ASSERTPR((g == INVALID_GUID || groupid == NULL) && (g != INVALID_GUID || groupid != NULL), "sorry, one or the other, indulge aristotle"); pushParserState(); allowscripts = 1; instantiatinggroup = 0; transcientcontainer = transcient; staticloading = 0; recording_container = 0; recording_groupdef = 0; curContainer = NULL; lastCreatedContainer = NULL; curGroup = NULL; inContainer = inLayout = inElements = inGroup = inGroupDef = inAccelerators = inStringTable = 0; scriptId = -1; //WASABI_API_PALETTE->getSkinPartIterator(); SkinItem *found = NULL; SkinItem *generic = NULL; for (int i = guiTree->getNumObject(XML_TAG_CONTAINER) - 1;i >= 0 && found == NULL;i--) { SkinItem *item = guiTree->getObject(XML_TAG_CONTAINER, i); if (item == NULL) continue; ifc_xmlreaderparams *par = item->getParams(); if (!par) continue; if (g != INVALID_GUID) { for (size_t j = 0;found == NULL && j != par->getNbItems();j++) { const wchar_t *p = par->getItemName(j); if (!WCSICMP(p, L"component") || !WCSICMP(p, L"hold")) { ParamParser pp(par->getItemValue(j)); if (pp.hasGuid(g) && found == NULL) { found = item; break; } if (generic == NULL && (pp.hasGuid(GENERIC_GUID) || pp.hasString(L"@ALL@"))) { generic = item; } } } } else if (groupid != NULL) { for (size_t j = 0;j != par->getNbItems() && found == NULL;j++) { const wchar_t *p = par->getItemName(j); if (!WCSICMP(p, L"hold")) { ParamParser pp(par->getItemValue(j)); if (pp.hasString(groupid)) { found = item; break; } if (pp.hasString(L"@ALL@")) { generic = item; } } } } } if (found == NULL && generic == NULL) { popParserState(); return NULL; } if (!found) { if (containerid != NULL) { SkinItem *item = guiTree->getContainerById(containerid); if (item != NULL) { Container *c = instantiateDynamicContainer(item, initit); popParserState(); return c; } } else { if (container_flag != 0) return NULL; } } Container *c = instantiateDynamicContainer(found != NULL ? found : generic, initit); popParserState(); return c; } Container *SkinParser::instantiateDynamicContainer(SkinItem *containeritem, int initit) { int quit = 0; int guitreeid = guiTree->getObjectIdx(containeritem); for (int i = guitreeid;i < guiTree->getNumObject() && !quit;i++) { SkinItem *ii = guiTree->getList()->enumItem(i); ifc_xmlreaderparams *params = ii->getParams(); const wchar_t *path = ii->getXmlRootPath(); if (path) includepath = path; int object_type = guiTree->getObjectType(ii); const wchar_t *name = ii->getName(); if (!params) { if (object_type == XML_TAG_CONTAINER) quit = 1; _onXmlEndElement(object_type, name); } else { _onXmlStartElement(object_type, name, params); } } return lastCreatedContainer; } // do not forget to popParserState(); before returning Container *SkinParser::newDynamicContainer(const wchar_t *containerid, int transcient) { pushParserState(); allowscripts = 1; instantiatinggroup = 0; transcientcontainer = transcient; staticloading = 0; recording_container = 0; recording_groupdef = 0; curContainer = NULL; lastCreatedContainer = NULL; curGroup = NULL; inContainer = inLayout = inElements = inGroup = inGroupDef = inAccelerators = inStringTable = 0; scriptId = WASABI_API_PALETTE->getSkinPartIterator(); SkinItem *found = NULL; for (int i = guiTree->getNumObject(XML_TAG_CONTAINER) - 1;i >= 0 && found == NULL;i--) { SkinItem *item = guiTree->getObject(XML_TAG_CONTAINER, i); ifc_xmlreaderparams *par = item->getParams(); if (!par) continue; const wchar_t *p = par->getItemValue(L"id"); if (!WCSICMP(p, containerid)) { found = item; break; } } Container *c = NULL; if (found != NULL) c = instantiateDynamicContainer(found); popParserState(); return c; } #endif // do not forget to popParserState(); before returning void SkinParser::fillGroup(Group *group, const wchar_t *groupid, SkinItem *specific_item, int params_only, int no_params, int scripts_enabled) { ASSERT(group != NULL); pushParserState(); instantiatinggroup = 1; #ifdef WASABI_COMPILE_WNDMGR transcientcontainer = 0; #endif allowscripts = scripts_enabled; staticloading = 0; recording_container = 0; recording_groupdef = 0; lastCreatedGroup = NULL; scriptId = group->getSkinPartId(); SkinItem *found = NULL; PtrList ancestor_param_list; found = specific_item == NULL ? guiTree->getGroupDef(groupid) : specific_item; if (found == NULL) { popParserState(); return ; } curGroup = group; inGroup = 1; parseGroup(found, &ancestor_param_list, params_only); if (!no_params) { XmlObject *xo = static_cast(curGroup->getScriptObject()->vcpu_getInterface(xmlObjectGuid)); for (int i = ancestor_param_list.getNumItems() - 1;i >= 0;i--) initXmlObject(xo, ancestor_param_list.enumItem(i), 1); } popParserState(); } GuiObject *SkinParser::newDynamicGroup(const wchar_t *groupid, int grouptype, SkinItem *specific_item, int specific_scriptid, int scripts_enabled) { #ifdef WASABI_COMPILE_CONFIG int iscfggroup = (grouptype == GROUP_CFGGROUP); #endif #ifdef WASABI_COMPILE_WNDMGR int islayoutgroup = (grouptype == GROUP_LAYOUTGROUP); #endif Group *r = NULL; #ifdef WASABI_COMPILE_CONFIG if (!iscfggroup) { #endif #ifdef WASABI_COMPILE_WNDMGR if (!islayoutgroup) r = new Group; else { Layout *l = new Layout; r = l; l->setParentContainer(NULL); } #else // wndmgr r = new Group; #endif // wndmgr #ifdef WASABI_COMPILE_CONFIG } else r = new CfgGroup; #endif r->setSkinPartId(specific_scriptid > -1 ? specific_scriptid : WASABI_API_PALETTE->getSkinPartIterator()); if (r != NULL) { r->setXmlParam(L"id", groupid); r->setGroupContent(groupid, specific_item, scripts_enabled); fillGroup(r, groupid, specific_item, 1, 0, scripts_enabled); return r->getGuiObject(); } return NULL; } void SkinParser::pushParserState() { parser_status *p = new parser_status; #ifdef WASABI_COMPILE_WNDMGR p->curContainer = curContainer; p->curLayout = curLayout; p->inContainer = inContainer; p->inLayout = inLayout; p->transcientcontainer = transcientcontainer; #endif p->staticloading = staticloading; p->curGroup = curGroup; p->includepath = includepath; p->inElements = inElements; p->inGroup = inGroup; p->inGroupDef = inGroupDef; p->instantiatinggroup = instantiatinggroup; p->scriptid = scriptId; p->allowscripts = allowscripts; p->inAccelerators = inAccelerators; p->inStringTable = inStringTable; statusstack.addItem(p); } void SkinParser::popParserState() { ASSERT(statusstack.getNumItems() > 0); parser_status *p = statusstack.enumItem(statusstack.getNumItems() - 1); statusstack.removeByPos(statusstack.getNumItems() - 1); ASSERT(p != NULL); #ifdef WASABI_COMPILE_WNDMGR curContainer = p->curContainer; curLayout = p->curLayout; inContainer = p->inContainer; inLayout = p->inLayout; transcientcontainer = p->transcientcontainer; #endif curGroup = p->curGroup; includepath = p->includepath; inElements = p->inElements; inAccelerators = p->inAccelerators; inStringTable = p->inStringTable; inGroup = p->inGroup; inGroupDef = p->inGroupDef; staticloading = p->staticloading; instantiatinggroup = p->instantiatinggroup; scriptId = p->scriptid; allowscripts = p->allowscripts; delete p; } #ifdef WASABI_COMPILE_WNDMGR Container *SkinParser::getContainer(const wchar_t *id) { for (int i = 0;i < containers.getNumItems();i++) if (!WCSICMP(id, containers.enumItem(i)->getId())) return containers.enumItem(i); return NULL; } Layout *SkinParser::getLayout(const wchar_t *contlay) { PathParserW pp(contlay, L","); if (pp.getNumStrings() == 2) { Container *c = SkinParser::getContainer(pp.enumString(0)); if (c) { Layout *l = c->getLayout(pp.enumString(1)); if (l) { return l; } } } return NULL; } int SkinParser::script_getNumContainers() { return containers.getNumItems(); } Container *SkinParser::script_enumContainer(int n) { return containers.enumItem(n); } int SkinParser::isContainer(Container *c) { return containers.haveItem(c); } Container *SkinParser::script_getContainer(const wchar_t *id) { for (int i = 0;i < containers.getNumItems();i++) { Container *c = containers.enumItem(i); if (c) { const wchar_t *c_id = containers.enumItem(i)->getId(); if (c_id && !WCSICMP(id, c_id)) return containers.enumItem(i); } } return NULL; } void SkinParser::componentToggled(GUID *g, int visible) { for (int i = 0;i < containers.getNumItems();i++) containers[i]->componentToggled(g, visible); } void SkinParser::sendNotifyToAllContainers(int notifymsg, int param1, int param2) { for (int i = 0;i < containers.getNumItems();i++) containers[i]->sendNotifyToAllLayouts(notifymsg, param1, param2); } void SkinParser::toggleContainer(int num) { if (num < 0) return ; if (num > containers.getNumItems()) return ; Container *c = containers[num]; if (!c) return ; c->toggle(); } void SkinParser::startupContainers(int scriptid) { for (int i = 0;i < containers.getNumItems();i++) { if (scriptid == -1 || containers[i]->getScriptId() == scriptid && !containers[i]->isDynamic()) containers[i]->onInit(); } } void SkinParser::showContainer(int num, int show) { if (num < 0) return ; if (num > containers.getNumItems()) return ; Container *c = containers[num]; c->setVisible(show); } #endif // wndmgr int SkinParser::getHex(const wchar_t *p, int size) { int v = 0, i = 0; while (*p != 0 && *p != '-' && *p != '}') { unsigned int a = *p; if (a >= '0' && a <= '9') a -= '0'; if (a >= 'a' && a <= 'f') a -= 'a' -10; if (a >= 'A' && a <= 'F') a -= 'A' -10; v = (v * 16) + a; p++; i++; if (size != -1 && i == size) return v; } return v; } #ifdef WASABI_COMPILE_WNDMGR int SkinParser::getComponentGuid(GUID *g, const wchar_t *p) { g->Data1 = getHex(p); while (*p != 0 && *p != '-') p++; if (*p == '-') { p++; g->Data2 = getHex(p); while (*p != 0 && *p != '-') p++; if (*p == '-') { p++; g->Data3 = getHex(p); while (*p != 0 && *p != '-') p++; if (*p == '-') { p++; g->Data4[0] = getHex(p, 2); p += 2; g->Data4[1] = getHex(p, 2); p += 3; g->Data4[2] = getHex(p, 2); p += 2; g->Data4[3] = getHex(p, 2); p += 2; g->Data4[4] = getHex(p, 2); p += 2; g->Data4[5] = getHex(p, 2); p += 2; g->Data4[6] = getHex(p, 2); p += 2; g->Data4[7] = getHex(p, 2); return 1; } } } return 0; } GUID *SkinParser::getComponentGuid(const wchar_t *id) { static GUID g; g = nsGUID::fromCharW(id); if (g == INVALID_GUID) return NULL; return &g; } #endif int SkinParser::parse(const wchar_t *str, const wchar_t *what) { int a = parsetypes.getId(what); if (a < 0) return WTOI(str); switch (a) { case PARSETYPE_RESIZE: return parseResize(str); case PARSETYPE_COLOR: return parseColor(str); case PARSETYPE_COLORALPHA: return parseColorAlpha(str); case PARSETYPE_REGIONOP: return parseRegionOp(str); case PARSETYPE_INTERNALACTION: return getAction(str); case PARSETYPE_GROUPINHERITANCE: return parseGroupInheritance(str); } // todo: add svc_intParser return 0; } int SkinParser::parseGroupInheritance(const wchar_t *str) { if (WCSCASEEQLSAFE(str, L"1")) return GROUP_INHERIT_ALL; if (WCSCASEEQLSAFE(str, L"0")) return GROUP_INHERIT_NOTHING; ParamParser pp(str); int v = 0; for (int i = 0;i < pp.getNumItems();i++) { const wchar_t *s = pp.enumItem(i); if (WCSCASEEQLSAFE(s, L"xui")) v |= GROUP_INHERIT_XUIOBJECTS; if (WCSCASEEQLSAFE(s, L"scripts")) v |= GROUP_INHERIT_SCRIPTS; if (WCSCASEEQLSAFE(s, L"params")) v |= GROUP_INHERIT_PARAMS; } return v; } ARGB32 SkinParser::parseColor(const wchar_t *color, int *error) { if (color == NULL || *color == '\0') { if (error) *error = 1; return COLOR_ERROR; } if (!WCSICMP(color, L"white")) return COLOR_WHITE; if (!WCSICMP(color, L"black")) return COLOR_BLACK; if (wcschr(color, ',')) { int r = 0, g = 0, b = 0; if (swscanf(color, L"%d,%d,%d", &r, &g, &b) != 3) return COLOR_ERROR; return RGB(r, g, b); // our colors are reversed internally } if (*color == '#') { int r = 0, g = 0, b = 0; if (swscanf(color, L"#%02x%02x%02x", &r, &g, &b) != 3) return COLOR_ERROR; return RGB(r, g, b); } if (error) *error = 1; return COLOR_ERROR; } ARGB32 SkinParser::parseColorAlpha(const wchar_t *color) { if (color == NULL || *color == '\0') return COLOR_BLACKA; if (!WCSICMP(color, L"white")) return COLOR_WHITEA; if (!WCSICMP(color, L"black")) return COLOR_BLACKA; if (wcschr(color, ',')) { int r = 0, g = 0, b = 0, a = 255; // note that 3 params is ok if (swscanf(color, L"%d,%d,%d,%d", &r, &g, &b, &a) < 3) return COLOR_ERRORA; ARGB32 ret = RGB(r, g, b); // our colors are reversed internally ret |= ((a & 0xff) << 24); return ret; } if (*color == '#') { int r = 0, g = 0, b = 0, a = 255; if (swscanf(color, L"#%02x%02x%02x%02x", &r, &g, &b, &a) < 3) return COLOR_ERRORA; ARGB32 ret = RGB(r, g, b); // our colors are reversed internally ret |= ((a & 0xff) << 24); return ret; } return COLOR_ERRORA; } #ifdef WASABI_COMPILE_WNDMGR void SkinParser::toggleContainer(const wchar_t *id) { // component toggling GUID *g; if (g = getComponentGuid(id)) { GUID g2; MEMCPY(&g2, g, sizeof(GUID)); WASABI_API_WNDMGR->skinwnd_toggleByGuid(g2); return ; } for (int i = 0;i < containers.getNumItems();i++) if (!WCSICMP(id, containers[i]->getId())) toggleContainer(i); } void SkinParser::showContainer(const wchar_t *id, int show) { // component guid /* GUID *g; if (g = getComponentGuid(id)) { WASABI_API_WNDMGR->setComponentVisible(*g, show); return; }*/ foreach(containers) if (!WCSICMP(id, containers.getfor()->getId())) showContainer(foreach_index, show); endfor } #endif // wndmgr #pragma warning( disable : 4065 ) int SkinParser::getAction(const wchar_t *action, const wchar_t **name) { //CT> this should be a binary search for more efficiency if (name != NULL) *name = NULL; int a = actionlist.getId(action); if (a == -1) return ACTION_NONE; // these strings are for accessibility when no text has been assigned to the control that triggers these actions if (name != NULL) { switch (a) { #ifdef WASABI_COMPILE_WNDMGR case ACTION_RELOAD_SKIN: *name = _(L"Reload skin"); break; case ACTION_MINIMIZE: *name = _(L"Minimize window"); break; case ACTION_MAXIMIZE: *name = _(L"Maximize window"); break; case ACTION_CLOSE: *name = _(L"Close"); break; case ACTION_SWITCH: *name = _(L"Switch to"); break; case ACTION_TOGGLE: *name = _(L"Toggle"); break; case ACTION_CLOSE_WINDOW: *name = _(L"Close window"); break; #endif #ifdef WA3COMPATIBILITY case ACTION_ABOUT: *name = _(L"About"); break; case ACTION_SYSMENU: *name = _(L"Open system menu"); break; case ACTION_CONTROLMENU: *name = _(L"Open control menu"); break; case ACTION_MENU: *name = _(L"Open menu"); break; case ACTION_WINDOWMENU: *name = _(L"Window menu"); break; case ACTION_MB_FORWARD: *name = _(L"Forward"); break; case ACTION_MB_BACK: *name = _(L"Back"); break; case ACTION_MB_URL: *name = _(L"Url"); break; case ACTION_MB_HOME: *name = _(L"Home"); break; case ACTION_MB_STOP: *name = _(L"Stop loading"); break; case ACTION_MB_REFRESH: *name = _(L"Refresh"); break; case ACTION_TEXT_LARGER: *name = _(L"Increase text size"); break; case ACTION_TEXT_SMALLER: *name = _(L"Decrease text size"); break; case ACTION_PREFERENCES: *name = _(L"Preferences"); break; case ACTION_TOGGLE_ALWAYS_ON_TOP: *name = _(L"Toggle Always on top"); break; case ACTION_VIEW_FILE_INFO: *name = _(L"View file info"); break; case ACTION_ADD_BOOKMARK: *name = _(L"Add bookmark"); break; case ACTION_DOUBLESIZE: *name = _(L"Toggle double size mode"); break; #endif #ifdef WASABI_WIDGETS_COMPBUCK case ACTION_CB_NEXT: *name = _(L"More"); break; case ACTION_CB_PREV: *name = _(L"More"); break; #endif default: break; } } return a; } #pragma warning( default : 4065 ) #ifdef WASABI_COMPILE_MEDIACORE int SkinParser::getDisplay(const wchar_t *display) { int a = displaylist.getId(display); if (a == -1) return DISPLAY_SERVICE; return a; } #endif int SkinParser::getAlign(const wchar_t *align) { #ifdef _WIN32 if (!WCSICMP(align, L"LEFT")) return ALIGN_LEFT; if (!WCSICMP(align, L"CENTER")) return ALIGN_CENTER; if (!WCSICMP(align, L"RIGHT")) return ALIGN_RIGHT; if (!WCSICMP(align, L"TOP")) return ALIGN_TOP; if (!WCSICMP(align, L"BOTTOM")) return ALIGN_BOTTOM; #else #warning port me #endif return DISPLAY_NONE; } int SkinParser::getOrientation(const wchar_t *orient) { if (!WCSICMP(orient, L"V") || !WCSICMP(orient, L"VERTICAL")) return ORIENTATION_VERTICAL; return ORIENTATION_HORIZONTAL; } // link guiobject to guiobject void SkinParser::initGuiObject(GuiObject *g, Group *pgroup) { ASSERT(pgroup); pgroup->addObject(g); } // This sends the params to the script object through its XmlObject // interface. Try not to add code here, but instead in setXmlParam/XmlInit // in the object itself void SkinParser::initXmlObject(XmlObject *o, ifc_xmlreaderparams *params, int no_id) { ASSERT(o); if (params) for (size_t i = 0;i != params->getNbItems();i++) if (!no_id || WCSICMP(params->getItemName(i), L"id")) // don't pass along id="blah" stuff o->setXmlParam(params->getItemName(i), params->getItemValue(i)); // o->XmlInit(); //fg> now defered } #ifdef WASABI_COMPILE_WNDMGR // This sends the params to the script object through its XmlObject // interface. Try not to add code here, but instead in setXmlParam/XmlInit // in the object itself void SkinParser::initLayout(Layout *l, Container *pcont) { ASSERT(pcont); l->setParentContainer(pcont); pcont->addLayout(l); } #endif void SkinParser::xmlReaderCallback(int start, const wchar_t *xmltag, skin_xmlreaderparams *params) { if (start) onXmlStartElement(xmltag, params); else onXmlEndElement(xmltag); } void SkinParser::onXmlStartElement(const wchar_t *name, skin_xmlreaderparams *params) { xml_tag *i = quickxmltaglist.findItem(name); if (i) _onXmlStartElement(i->id, name, params); else _onXmlStartElement(XML_TAG_UNKNOWN, name, params); } void SkinParser::onXmlEndElement(const wchar_t *name) { xml_tag *i = quickxmltaglist.findItem(name); if (i) { if (i->needclosetag) _onXmlEndElement(i->id, name); } /*else _onXmlEndElement(XML_TAG_UNKNOWN, name);*/ // not needed yet } void SkinParser::parseGroup(SkinItem *groupitem, PtrList *ancestor_param_list, int params_only, int overriding_inheritance_flags) { ifc_xmlreaderparams *par = groupitem->getParams(); const wchar_t *groupid = par->getItemValue(L"id"); const wchar_t *ic = par->getItemValue(L"inherit_content"); const wchar_t *og = par->getItemValue(L"inherit_group"); const wchar_t *ip = par->getItemValue(L"inherit_params"); int inheritance_flags = parseGroupInheritance(ic); int inherit_params = 1; if (ip != NULL && *ip != 0) inherit_params = WTOI(ip); if ((og && *og) && (!ic || !*ic)) inheritance_flags = GROUP_INHERIT_ALLCONTENT; if (inherit_params) inheritance_flags |= GROUP_INHERIT_PARAMS; if (WCSCASEEQLSAFE(og, groupid)) og = NULL; if (inheritance_flags != GROUP_INHERIT_NOTHING) { SkinItem *prior_item = NULL; if (og != NULL && *og) prior_item = guiTree->getGroupDef(og); else prior_item = guiTree->getGroupDefAncestor(groupitem); if (prior_item != NULL) parseGroup(prior_item, ancestor_param_list, params_only, inheritance_flags); } if (overriding_inheritance_flags & GROUP_INHERIT_PARAMS) ancestor_param_list->addItem(groupitem->getParams()); if (!params_only) { int guitreeid = guiTree->getObjectIdx(groupitem); for (int i = guitreeid + 1;i < guiTree->getNumObject();i++) { SkinItem *item = guiTree->getList()->enumItem(i); ifc_xmlreaderparams *params = item->getParams();; const wchar_t *path = item->getXmlRootPath(); if (path) includepath = path; int object_type = guiTree->getObjectType(item); if (object_type == XML_TAG_GROUPDEF && !params) break; if (object_type == XML_TAG_SCRIPT && !(overriding_inheritance_flags & GROUP_INHERIT_SCRIPTS)) continue; if (object_type != XML_TAG_SCRIPT && !(overriding_inheritance_flags & GROUP_INHERIT_XUIOBJECTS)) continue; const wchar_t *name = item->getName(); if (!params) _onXmlEndElement(object_type, name); else _onXmlStartElement(object_type, name, params); } } } void SkinParser::_onXmlStartElement(int object_type, const wchar_t *object_name, ifc_xmlreaderparams *params) { GuiObject *g = NULL; // We'll need to build a GUI object XmlObject *x = NULL; Group *g_group = NULL; if (object_type == XML_TAG_UNKNOWN) { if (loading_main_skinfile && (!WCSICMP(object_name, L"WinampAbstractionLayer") || !WCSICMP(object_name, L"WasabiXML"))) { skinversion = WTOF(params->getItemValue(L"version")); } } /*#ifdef WASABI_COMPILE_WNDMGR int isacontainer = 0; #endif // wndmgr*/ if (object_type == XML_TAG_GROUPDEF) { if (staticloading) { recording_groupdef++; } inGroupDef++; } if (object_type == XML_TAG_ACCELERATORS) { const wchar_t *section = params->getItemValue(L"section"); if (!section) LocalesManager::setAcceleratorSection(L"general"); else LocalesManager::setAcceleratorSection(section); inAccelerators = 1; } if (object_type == XML_TAG_STRINGTABLE) { const wchar_t *section = params->getItemValue(L"id"); if (!section) LocalesManager::SetStringTable(L"nullsoft.wasabi"); else LocalesManager::SetStringTable(section); inStringTable = 1; } if (inStringTable && object_type == XML_TAG_STRINGENTRY) { const wchar_t *b = params->getItemValue(L"id"); const wchar_t *a = params->getItemValue(L"string"); if (b && a) { LocalesManager::AddString(WTOI(b), a); } } if (inAccelerators && object_type == XML_TAG_ACCELERATOR) { const wchar_t *b = params->getItemValue(L"bind"); const wchar_t *a = params->getItemValue(L"action"); if (b && a) { //LocalesManager::addAccelerator(b, a); //Martin> this is a temporary fix to protect skin.xml from overriding the language pack accels LocalesManager::addAcceleratorFromSkin(b, a); } } if ((!recording_container && !recording_groupdef) && !inGroupDef) { if (object_type == XML_TAG_SCRIPT) { // const char *id = params->getItemValue(L"id"); if (1) { if (allowscripts) { int vcpuid = Script::addScript(includepath, params->getItemValue(L"file"), params->getItemValue(L"id")); if (vcpuid != -1) { Script::setScriptParam(vcpuid, params->getItemValue(L"param")); Script::setParentGroup(vcpuid, curGroup); Script::setSkinPartId(vcpuid, scriptId); if (curGroup != NULL) curGroup->addScript(vcpuid); else // todo: schedule this for the end of skinparse, after all layouts are inited SOM::getSystemObjectByScriptId(vcpuid)->onLoad(); } } } } } #ifdef WASABI_COMPILE_WNDMGR if ((!recording_groupdef && !recording_container) && (inContainer || inGroup) && !inGroupDef) { // Am I in a container definition ? if (inLayout || inGroup) { // Am I in a layout or in a group ? #else // wndmgr if ((!recording_groupdef && !recording_container) && inGroup && !inGroupDef) { { // Am I in definition ? #endif // wndmgr // Create appropriate GuiObject descendant if (object_type == XML_TAG_GROUP || object_type == XML_TAG_CFGGROUP) { Group *old = curGroup; GuiObject *newgrp = newDynamicGroup(params->getItemValue(L"id"), (object_type == XML_TAG_CFGGROUP) ? GROUP_CFGGROUP : GROUP_GROUP); if (newgrp) { x = static_cast(newgrp->guiobject_getScriptObject()->vcpu_getInterface(xmlObjectGuid)); g = newgrp; } curGroup = old; } #ifdef WASABI_COMPILE_WNDMGR else if (object_type == XML_TAG_SNAPPOINT) { x = new SnapPoint(curLayout, curContainer); } #endif else if (object_type != XML_TAG_UNKNOWN) { g = NULL; } else { SkinItem *item = guiTree->getXuiGroupDef(object_name); if (item != NULL) { Group *old = curGroup; const wchar_t *grpid = NULL; if (item->getParams() != NULL) grpid = item->getParams()->getItemValue(L"id"); GuiObject *newgrp = NULL; if (grpid == NULL) newgrp = newDynamicGroup(params->getItemValue(L"id"), GROUP_GROUP, item); else newgrp = newDynamicGroup(grpid, GROUP_GROUP, NULL, -1, allowscripts); if (newgrp) { x = static_cast(newgrp->guiobject_getScriptObject()->vcpu_getInterface(xmlObjectGuid)); g = newgrp; } curGroup = old; } else { g = createExternalGuiObject(object_name, &x, params); } } } #ifdef WASABI_COMPILE_WNDMGR else { // if inlayout if (object_type == XML_TAG_LAYOUT) { // Now enters a new layout curLayout = new Layout; curGroup = curLayout; inLayout = 1; initLayout(curLayout, curContainer); x = static_cast(curLayout->getGuiObject()->guiobject_getScriptObject()->vcpu_getInterface(xmlObjectGuid)); } } #endif // wndmgr } #ifdef WASABI_COMPILE_WNDMGR else { // if inContainer if (inElements) { // do nothing } else if (object_type == XML_TAG_CONTAINER) { //isacontainer = 1; const wchar_t *d = params->getItemValue(L"dynamic"); int dyn = WASABI_WNDMGR_ALLCONTAINERSDYNAMIC ? 1 : (d ? WTOI(d) : 0); if (dyn && staticloading) { recording_container = 1; } else { inContainer = 1; curContainer = new Container(scriptId); curContainer->setId(params->getItemValue(L"id")); containers.addItem(curContainer); #ifdef _DEBUG DebugStringW(L"new Container - skinpartid = %d\n", scriptId); #endif if (transcientcontainer) curContainer->setTranscient(1); x = curContainer; } } else { if (object_type == XML_TAG_SCRIPTS) inScripts = 1; else if (object_type == XML_TAG_ELEMENTS) inElements = 1; } } // if container else #endif // wndmgr if (g_group) { curGroup = g_group; } else if (g) initGuiObject(g, curGroup); if (x) initXmlObject(x, params); if (recording_container || recording_groupdef) guiTree->addItem(object_type, object_name, params, scriptId, includepath.v()); } void SkinParser::_onXmlEndElement(int object_type, const wchar_t *name) { if (recording_container || recording_groupdef) guiTree->addItem(object_type, name, NULL, scriptId, includepath); if (object_type == XML_TAG_GROUPDEF) { lastCreatedGroup = curGroup; if (staticloading) recording_groupdef--; if (recording_groupdef < 0) recording_groupdef = 0; inGroup = 0; inGroupDef--; curGroup = NULL; } #ifdef WASABI_COMPILE_WNDMGR if (object_type == XML_TAG_CONTAINER) { if (inContainer) { //if (!curContainer->isDynamic()) containers.addItem(curContainer); //FG>script //containers.addItem(curContainer); lastCreatedContainer = curContainer; curContainer = NULL; inContainer = 0; } recording_container = 0; if (recording_groupdef) { WASABI_API_WNDMGR->messageBox(L"container closed but group still open, closing group", L"error in xml data", 0, NULL, NULL); recording_groupdef = 0; } } if (inLayout && object_type == XML_TAG_LAYOUT) { #ifdef WA3COMPATIBILITY curLayout->setForwardMsgWnd(WASABI_API_WND->main_getRootWnd()->gethWnd()); #endif curLayout->setAutoResizeAfterInit(1); #ifndef WA3COMPATIBILITY #ifdef _WIN32 curLayout->init(hInstance, curLayout->getCustomOwner() ? curLayout->getCustomOwner()->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd(), TRUE); #else #warning port me curLayout->init(0, curLayout->getCustomOwner() ? curLayout->getCustomOwner()->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd(), TRUE); #endif #else curLayout->init(hInstance, curLayout->getCustomOwner() ? curLayout->getCustomOwner()->gethWnd() : Main::gethWnd(), TRUE); #endif curLayout->getGuiObject()->guiobject_onStartup(); curLayout = NULL; inLayout = 0; curGroup = NULL; } #endif if (inScripts && object_type == XML_TAG_SCRIPTS) { inScripts = 0; } if (inElements && object_type == XML_TAG_ELEMENTS) { inElements = 0; } if (inAccelerators && object_type == XML_TAG_ACCELERATORS) { LocalesManager::setAcceleratorSection(L""); inAccelerators = 0; } if (inStringTable && object_type == XML_TAG_STRINGTABLE) { LocalesManager::SetStringTable(L""); inStringTable = 0; } } #ifdef WASABI_COMPILE_WNDMGR int SkinParser::verifyContainer(Container *c) { for (int i = 0;i < containers.getNumItems();i++) { if (containers.enumItem(i) == c) return 1; } return 0; } #endif int SkinParser::parseResize(const wchar_t *r) { int a = resizevalues.getId(r); if (a < 0) return WTOI(r); return a; } int SkinParser::parseRegionOp(const wchar_t *r) { if (!WCSICMP(r, L"or")) return REGIONOP_OR; if (!WCSICMP(r, L"and")) return REGIONOP_AND; if (!WCSICMP(r, L"sub")) return REGIONOP_SUB; if (!WCSICMP(r, L"sub2")) return REGIONOP_SUB2; return WTOI(r); } void SkinParser::cleanupScript(int scriptid) { if (scriptid == -1) scriptid = WASABI_API_PALETTE->getSkinPartIterator(); int i; for (i = 0;i < SOM::getNumSystemObjects();i++) { if (SOM::getSystemObject(i)->getSkinPartId() == scriptid) { int vcpu = SOM::getSystemObject(i)->getScriptId(); Script::unloadScript(vcpu); i--; } } #ifdef WASABI_COMPILE_WNDMGR for (i = 0;i < containers.getNumItems();i++) { Container *c = containers[i]; if (c->getScriptId() == scriptid) { c->setDeleting(); delete c; // c autodeletes from containers i--; } } #endif guiTree->removeSkinPart(scriptid); #ifdef WASABI_COMPILE_WNDMGR AutoPopup::removeSkinPart(scriptid); #endif } #ifdef WASABI_COMPILE_WNDMGR void SkinParser::unloadAllContainers() { foreach(containers) containers.getfor()->setDeleting(); endfor; containers.deleteAllSafe(); //script_containers.removeAll(); } #endif void SkinParser::cleanUp() { #ifdef WASABI_COMPILE_WNDMGR AutoPopup::removeAllAddons(); #endif Script::unloadAllScripts(); #ifdef WASABI_COMPILE_WNDMGR unloadAllContainers(); #endif guiTree->reset(); } #ifdef WASABI_COMPILE_WNDMGR int SkinParser::getNumContainers() { return containers.getNumItems(); } Container *SkinParser::enumContainer(int n) { return containers.enumItem(n); } #endif const wchar_t *SkinParser::getXmlRootPath() { return includepath; } #ifdef WASABI_COMPILE_WNDMGR const wchar_t *SkinParser::getCurrentContainerId() { if (curContainer) return curContainer->getId(); return NULL; } const wchar_t *SkinParser::getCurrentGroupId() { if (curGroup) return curGroup->getGuiObject()->guiobject_getId(); return NULL; } #endif GuiObject *SkinParser::createExternalGuiObject(const wchar_t *object_name, XmlObject **x, ifc_xmlreaderparams *params) { svc_xuiObject *svc = NULL; waServiceFactory *sf = xuiCache->findServiceFactory(object_name); if (sf != NULL) svc = castService(sf, FALSE); else { XuiObjectSvcEnum xose(object_name); svc = xose.getNext(FALSE); sf = xose.getLastFactory(); } if (svc != NULL) { GuiObject *go = svc->instantiate(object_name, params); if (!go) return NULL; go->guiobject_setXuiService(svc); go->guiobject_setXuiServiceFactory(sf); ScriptObject *so = go->guiobject_getScriptObject(); ASSERTPR(so != NULL, "tell francis to fix scriptobjectless xuiobjects"); if (x) *x = static_cast(so->vcpu_getInterface(xmlObjectGuid)); return go; } return NULL; } void SkinParser::destroyGuiObject(GuiObject *o) { svc_xuiObject *svc = o->guiobject_getXuiService(); if (!svc) { ScriptObject *so = o->guiobject_getScriptObject(); ASSERT(so != NULL); GuiObjectWnd *go = static_cast(so->vcpu_getInterface(guiObjectWndGuid)); ASSERT(go != NULL); delete go; } else { waServiceFactory *sf = o->guiobject_getXuiServiceFactory(); svc->destroy(o); sf->releaseInterface(svc); } } #ifdef WASABI_COMPILE_WNDMGR void SkinParser::focusFirst() { foreach(containers) for (int j = 0;j < containers.getfor()->getNumLayouts();j++) { Layout *l = containers.getfor()->enumLayout(j); if (l != NULL && l->isVisible()) { l->setFocus(); return ; } } endfor; } #ifdef WA3COMPATIBILITY // non portable, the skin might be missing/buggy as hell, we need to use the os' msgbox void SkinParser::emmergencyReloadDefaultSkin() { if (!Main::revert_on_error) { if (!STRCASEEQLSAFE("Default", WASABI_API_SKIN->getSkinName())) { WASABI_API_WND->appdeactivation_setbypass(1); Std::messageBox(StringPrintfW(L"Failed to load the skin (%s). Did you remove it ?\nThis could also be due to missing components (ie: wa2skin.wac for winamp 2 skins), please check the skin's documentation.\nReverting to default skin.", WASABI_API_SKIN->getSkinName()), "Error", 0); WASABI_API_WND->appdeactivation_setbypass(0); Skin::toggleSkin("Default"); } else { WASABI_API_WND->appdeactivation_setbypass(1); Std::messageBox("The default skin did not load any user interface! Ooch! What should I do ? Oh well, good luck...", "Danger Danger Will Robinson!", 0); WASABI_API_WND->appdeactivation_setbypass(0); } } } #endif #endif GuiObject *SkinParser::xui_new(const wchar_t *classname) { SkinItem *item = guiTree->getXuiGroupDef(classname); if (item != NULL) { Group *old = curGroup; const wchar_t *grpid = NULL; if (item->getParams() != NULL) grpid = item->getParams()->getItemValue(L"id"); GuiObject *newgrp = NULL; if (grpid != NULL) newgrp = newDynamicGroup(grpid, GROUP_GROUP); curGroup = old; if (newgrp != NULL) return newgrp; } return createExternalGuiObject(classname, NULL, NULL); } void SkinParser::xui_delete(GuiObject *o) { destroyGuiObject(o); } double SkinParser::getSkinVersion() { return skinversion; } void SkinParser::setAllLayoutsRatio(double ra) { foreach(containers) Container *c = containers.getfor(); int n = c->getNumLayouts(); for (int i = 0;i < n;i++) { Layout *l = c->enumLayout(i); if (l->getNoParent() != 1) l->setRenderRatio(ra); } endfor; } void SkinParser::setAllLayoutsTransparency(int v) { foreach(containers) Container *c = containers.getfor(); int n = c->getNumLayouts(); for (int i = 0;i < n;i++) { Layout *l = c->enumLayout(i); if (l->getNoParent() != 1) l->setAlpha(v); } endfor; } Layout *SkinParser::getMainLayout() { foreach(containers) Container *c = containers.getfor(); if (!c->isMainContainer()) continue; return c->enumLayout(0); endfor; return NULL; } /* void SkinParser::setAllLayoutsAutoOpacify(int ao, int force) { foreach(containers) Container *c = containers.getfor(); int n = c->getNumLayouts(); for (int i=0;ienumLayout(i); if (l->getNoParent() != 1) l->setAutoOpacify(ao, force); } endfor; } void SkinParser::setAllLayoutsOverrideAlpha(int oa) { foreach(containers) Container *c = containers.getfor(); int n = c->getNumLayouts(); for (int i=0;ienumLayout(i); if (l->isInited() && l->isTransparencySafe() && l->getTransparencyOverride() == -1) { if (l->getNoParent() != 1) l->setTransparency(oa); } } endfor; } */ Group *SkinParser::curGroup, *SkinParser::lastCreatedGroup; int SkinParser::inScripts = 0, SkinParser::inElements = 0, SkinParser::inGroupDef = 0, SkinParser::inGroup = 0, SkinParser::inAccelerators = 0, SkinParser::inStringTable = 0; int SkinParser::scriptId = 0; int SkinParser::recording_container = 0; int SkinParser::recording_groupdef = 0; int SkinParser::staticloading = 0; PtrList SkinParser::statusstack; int SkinParser::instantiatinggroup = 0; int SkinParser::allowscripts = 0; skin_xmlreaderparams *SkinParser::groupparams = NULL; PtrListQuickSorted SkinParser::quickxmltaglist; double SkinParser::skinversion = 0.0; #ifdef WASABI_COMPILE_WNDMGR Container *SkinParser::curContainer, *SkinParser::lastCreatedContainer; Layout *SkinParser::curLayout; int SkinParser::inContainer, SkinParser::inLayout; //PtrList SkinParser::script_containers; PtrList SkinParser::containers; int SkinParser::centerskin; int SkinParser::transcientcontainer; SvcCacheT *SkinParser::xuiCache; int SkinParser::loading_main_skinfile = 0; StringW SkinParser::includepath; #endif