diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Wasabi/api/skin | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Wasabi/api/skin')
225 files changed, 41573 insertions, 0 deletions
diff --git a/Src/Wasabi/api/skin/SkinElementAlias.cpp b/Src/Wasabi/api/skin/SkinElementAlias.cpp new file mode 100644 index 00000000..6c66d842 --- /dev/null +++ b/Src/Wasabi/api/skin/SkinElementAlias.cpp @@ -0,0 +1,8 @@ +#include <precomp.h> +#include "SkinElementAlias.h" +#include <api/skin/PaletteManager.h> + +SkinItem *SkinElementAlias::getAncestor() +{ + return paletteManager.getAliasAncestor(this); +} diff --git a/Src/Wasabi/api/skin/SkinElementAlias.h b/Src/Wasabi/api/skin/SkinElementAlias.h new file mode 100644 index 00000000..1957825c --- /dev/null +++ b/Src/Wasabi/api/skin/SkinElementAlias.h @@ -0,0 +1,65 @@ +#pragma once +#include <api/skin/skinitem.h> +#include <api/xml/xmlparamsi.h> +struct SkinElementAlias : public SkinItemI +{ +public: + + SkinElementAlias(const wchar_t *_aliasname, const wchar_t *_idtarget, int _scriptid = -1, int _secondarycounter = 0) + : aliasname(_aliasname), idtarget(_idtarget), scriptid(_scriptid), seccount(_secondarycounter) //, rootpath(path) + { + params = NULL; + /* + if (p != NULL) { + params = new XmlReaderParamsI(); + for (int i=0;i<p->getNbItems();i++) { + params->addItem(p->getItemName(i), p->getItemValue(i)); + } + } + */ + } + virtual ~SkinElementAlias() + { + delete params; + } + + const wchar_t *getAliasName() { return aliasname; } + const wchar_t *getTargetId() { return idtarget; } + int getSecCount() { return seccount; } + + virtual const wchar_t *getXmlRootPath() { return rootpath; } + virtual const wchar_t *getName() { return L"elementalias"; } + virtual ifc_xmlreaderparams *getParams() { return params; } + virtual int getSkinPartId() { return scriptid; } + virtual SkinItem *getAncestor(); + +private: + StringW aliasname; + StringW idtarget; + int scriptid; + int seccount; + XmlReaderParamsI *params; + StringW rootpath; +}; + +class SortSkinElementAlias +{ +public: + static int compareItem(SkinElementAlias *p1, SkinElementAlias *p2) + { + int r = WCSICMP(p1->getAliasName(), p2->getAliasName()); + if (!r) + { + if (p1->getSkinPartId() < p2->getSkinPartId()) return -1; + if (p1->getSkinPartId() > p2->getSkinPartId()) return 1; + if (p1->getSecCount() < p2->getSecCount()) return -1; + if (p1->getSecCount() > p2->getSecCount()) return 1; + return 0; + } + return r; + } + static int compareAttrib(const wchar_t *attrib, SkinElementAlias *item) + { + return WCSICMP(attrib, item->getAliasName()); + } +};
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/SkinVersion.cpp b/Src/Wasabi/api/skin/SkinVersion.cpp new file mode 100644 index 00000000..ae112c49 --- /dev/null +++ b/Src/Wasabi/api/skin/SkinVersion.cpp @@ -0,0 +1,42 @@ +#include <precomp.h> +#include "SkinVersion.h" +#include "../xml/obj_xml.h" +#include <api/service/waservicefactory.h> +#include <bfc/string/StringW.h> + +void LoadXmlFile(obj_xml *parser, const wchar_t *filename); + +SkinVersionXmlReader::SkinVersionXmlReader(const wchar_t *skinname) +{ + waServiceFactory *parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID); + if (parserFactory) + { + obj_xml *parser = (obj_xml *)parserFactory->getInterface(); + + if (parser) + { + parser->xmlreader_registerCallback(L"WinampAbstractionLayer", this); + parser->xmlreader_registerCallback(L"WasabiXML", this); + parser->xmlreader_open(); + + StringPathCombine fn(WASABI_API_SKIN->getSkinPath(), L"skin.xml"); + LoadXmlFile(parser, fn); + parser->xmlreader_unregisterCallback(this); + + parser->xmlreader_close(); + parserFactory->releaseInterface(parser); + parser = 0; + } + } +} + +void SkinVersionXmlReader::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params) +{ + const wchar_t *version = params->getItemValue(L"version"); + if (version) + walversion = version; +} +const wchar_t *SkinVersionXmlReader::getWalVersion() +{ + return walversion; +} diff --git a/Src/Wasabi/api/skin/SkinVersion.h b/Src/Wasabi/api/skin/SkinVersion.h new file mode 100644 index 00000000..baaf46a1 --- /dev/null +++ b/Src/Wasabi/api/skin/SkinVersion.h @@ -0,0 +1,18 @@ +#ifndef NULLSOFT_WASABI_SKINVERSION_H +#define NULLSOFT_WASABI_SKINVERSION_H + +#include "../xml/ifc_xmlreadercallbacki.h" +#include <bfc/string/StringW.h> + +class ifc_xmlreaderparams; +class SkinVersionXmlReader : public ifc_xmlreadercallbackI +{ +public: + SkinVersionXmlReader(const wchar_t *skinname); + void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params); + const wchar_t *getWalVersion(); +private: + StringW walversion; +}; + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/api_colorthemes.cpp b/Src/Wasabi/api/skin/api_colorthemes.cpp new file mode 100644 index 00000000..f346774b --- /dev/null +++ b/Src/Wasabi/api/skin/api_colorthemes.cpp @@ -0,0 +1,3 @@ +#include "api_colorthemes.h" + +/* benski> this file left intentionally blank */
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/api_colorthemes.h b/Src/Wasabi/api/skin/api_colorthemes.h new file mode 100644 index 00000000..b61c2eb2 --- /dev/null +++ b/Src/Wasabi/api/skin/api_colorthemes.h @@ -0,0 +1,161 @@ +#pragma once +#include <bfc/dispatch.h> +#include <api/skin/colorthemes.h> + +class api_colorthemes : public Dispatchable +{ +protected: + api_colorthemes(){} + ~api_colorthemes(){} +public: + /* Gamma Sets */ + size_t getNumGammaSets(); + const wchar_t *enumGammaSet(size_t n); + void deleteGammaSet(const wchar_t *set); + void deleteAllGammaSets(); + void resetGammaSet(const wchar_t *set); + void renameGammaSet(const wchar_t *set, const wchar_t *newname); + size_t newGammaSet(const wchar_t *set); // returns index of your new gamma group + void updateGammaSet(const wchar_t *set); + + /* Gamma Groups */ + int getNumGammaGroups(const wchar_t *gammaset); + const wchar_t *enumGammaGroup(const wchar_t *gammaset, int n); + ColorThemeGroup *enumColorThemeGroup(int colorset, int colorgroup); + ColorThemeGroup *getColorThemeGroup(const wchar_t *colorset, const wchar_t *colorgroup); + int getGammaForGroup(const wchar_t *group, int *r, int *g, int *b, int *gray, int *boost); + void addGammaGroup(const wchar_t *set, ColorThemeGroup *group); + void addGammaGroup(size_t gammaSetIndex, ColorThemeGroup *group); + + /* Active Gamma Set */ + const wchar_t *getGammaSet(); + void setGammaSet(const wchar_t *set); + + /* Call these if you are loading a whole bunch of color themes at once */ + void StartTransaction(); + void EndTransaction(); + + enum + { + API_COLORTHEMES_GETNUMGAMMASETS = 0, + API_COLORTHEMES_ENUMGAMMASET = 1, + API_COLORTHEMES_DELETEGAMMASET = 2, + API_COLORTHEMES_DELETEALLGAMMASETS = 3, + API_COLORTHEMES_RESETGAMMASET = 4, + API_COLORTHEMES_RENAMEGAMMASET = 5, + API_COLORTHEMES_NEWGAMMASET = 6, + API_COLORTHEMES_UPDATEGAMMASET = 7, + API_COLORTHEMES_GETNUMGAMMAGROUPS = 8, + API_COLORTHEMES_ENUMGAMMAGROUP = 9, + API_COLORTHEMES_ENUMCOLORTHEMEGROUP = 10, + API_COLORTHEMES_GETCOLORTHEMEGROUP = 11, + API_COLORTHEMES_GETGAMMAFORGROUP = 12, + API_COLORTHEMES_ADDGAMMAGROUP = 13, + API_COLORTHEMES_ADDGAMMAGROUP2 = 14, + API_COLORTHEMES_GETGAMMASET = 15, + API_COLORTHEMES_SETGAMMASET = 16, + API_COLORTHEMES_STARTTRANSACTION = 17, + API_COLORTHEMES_ENDTRANSACTION = 18, + }; +}; + +inline size_t api_colorthemes::getNumGammaSets() +{ + return _call(API_COLORTHEMES_GETNUMGAMMASETS, (size_t)0); +} + +inline const wchar_t *api_colorthemes::enumGammaSet(size_t n) +{ + return _call(API_COLORTHEMES_ENUMGAMMASET, (const wchar_t *)0, n); +} + +inline void api_colorthemes::deleteGammaSet(const wchar_t *set) +{ + _voidcall(API_COLORTHEMES_DELETEGAMMASET, set); +} + +inline void api_colorthemes::deleteAllGammaSets() +{ + _voidcall(API_COLORTHEMES_DELETEALLGAMMASETS); +} + +inline void api_colorthemes::resetGammaSet(const wchar_t *set) +{ + _voidcall(API_COLORTHEMES_RESETGAMMASET, set); +} + +inline void api_colorthemes::renameGammaSet(const wchar_t *set, const wchar_t *newname) +{ + _voidcall(API_COLORTHEMES_RENAMEGAMMASET, set, newname); +} + +inline size_t api_colorthemes::newGammaSet(const wchar_t *set) +{ + return _call(API_COLORTHEMES_NEWGAMMASET, (size_t)-1, set); +} + +inline void api_colorthemes::updateGammaSet(const wchar_t *set) +{ + _voidcall(API_COLORTHEMES_UPDATEGAMMASET, set); +} + +inline int api_colorthemes::getNumGammaGroups(const wchar_t *gammaset) +{ + return _call(API_COLORTHEMES_GETNUMGAMMAGROUPS, (int)0, gammaset); +} + +inline const wchar_t *api_colorthemes::enumGammaGroup(const wchar_t *gammaset, int n) +{ + return _call(API_COLORTHEMES_ENUMGAMMAGROUP, (const wchar_t *)0, gammaset, n); +} + +inline ColorThemeGroup *api_colorthemes::enumColorThemeGroup(int colorset, int colorgroup) +{ + return _call(API_COLORTHEMES_ENUMCOLORTHEMEGROUP, (ColorThemeGroup *)0, colorset, colorgroup); +} + +inline ColorThemeGroup *api_colorthemes::getColorThemeGroup(const wchar_t *colorset, const wchar_t *colorgroup) +{ + return _call(API_COLORTHEMES_GETCOLORTHEMEGROUP, (ColorThemeGroup *)0, colorset, colorgroup); +} + +inline int api_colorthemes::getGammaForGroup(const wchar_t *group, int *r, int *g, int *b, int *gray, int *boost) +{ + return _call(API_COLORTHEMES_GETGAMMAFORGROUP, (int)0, group, r, g, b, gray, boost); +} + +inline void api_colorthemes::addGammaGroup(const wchar_t *set, ColorThemeGroup *group) +{ + _voidcall(API_COLORTHEMES_ADDGAMMAGROUP, set, group); +} + +inline void api_colorthemes::addGammaGroup(size_t gammaSetIndex, ColorThemeGroup *group) +{ + _voidcall(API_COLORTHEMES_ADDGAMMAGROUP2, gammaSetIndex, group); +} + +inline const wchar_t *api_colorthemes::getGammaSet() +{ + return _call(API_COLORTHEMES_GETGAMMASET, (const wchar_t *)0); +} + +inline void api_colorthemes::setGammaSet(const wchar_t *set) +{ + _voidcall(API_COLORTHEMES_SETGAMMASET, set); +} + +inline void api_colorthemes::StartTransaction() +{ + _voidcall(API_COLORTHEMES_STARTTRANSACTION); +} + +inline void api_colorthemes::EndTransaction() +{ + _voidcall(API_COLORTHEMES_ENDTRANSACTION); +} + +// {A3AAB98E-1634-4763-81A7-8D397F9E3154} +static const GUID ColorThemesAPIGUID= +{ 0xa3aab98e, 0x1634, 0x4763, { 0x81, 0xa7, 0x8d, 0x39, 0x7f, 0x9e, 0x31, 0x54 } }; + +extern api_colorthemes *colorThemesApi; diff --git a/Src/Wasabi/api/skin/api_palette.cpp b/Src/Wasabi/api/skin/api_palette.cpp new file mode 100644 index 00000000..e02f8d42 --- /dev/null +++ b/Src/Wasabi/api/skin/api_palette.cpp @@ -0,0 +1 @@ +#include "api_palette.h" diff --git a/Src/Wasabi/api/skin/api_palette.h b/Src/Wasabi/api/skin/api_palette.h new file mode 100644 index 00000000..6f5361cc --- /dev/null +++ b/Src/Wasabi/api/skin/api_palette.h @@ -0,0 +1,273 @@ +#pragma once +#include <bfc/dispatch.h> +#include <api/skin/skinitem.h> +#include <api/skin/skin.h> +#include <tataki/region/region.h> + +class api_palette : public Dispatchable +{ +protected: + api_palette() {} + ~api_palette() {} +public: + void StartTransaction(); // if you add a bunch of stuff at once, it's faster to call this at the beginning + void EndTransaction(); // and this at the end. + + void Reset(); // clear everything + + const int *getSkinPartIteratorPtr(); // call this to get a pointer that's faster to check than calling getSkinPartIterator via Dispatchable + int newSkinPart(); // call this before adding your elements, let's you easily remove just your stuff via UnloadElements + int getSkinPartIterator(); // if this value changes, then something in the skin palette has changed + + void UnloadElements(int skinpart); // unload just your skin elements (get a skinpart value via newSkinPart) + + /* Aliases */ + void AddAlias(const wchar_t *id, const wchar_t *target); + const wchar_t *getElementAlias(const wchar_t *alias); + SkinItem *getAliasAncestor(SkinItem *item); + + /* Colors */ + void AddColor(const wchar_t *id, ARGB32 value, const wchar_t *colorgrp = NULL, const wchar_t *path = NULL, ifc_xmlreaderparams *p = NULL); + int getNumColorElements(); + const wchar_t *enumColorElement(int n); + ARGB32 *getColorElementRef(const wchar_t *type, const wchar_t **grp = NULL); + SkinItem *getColorAncestor(SkinItem *item); + ARGB32 getColorElement(const wchar_t *type, const wchar_t **grp = NULL); + + /* Cursors */ + void AddCursor(const wchar_t *id, const wchar_t *bitmapid, int x, int y, const wchar_t *path = NULL, ifc_xmlreaderparams *params = NULL); + int getCursorElement(const wchar_t *id); + OSCURSOR getCursor(const wchar_t *id); + SkinItem *getCursorAncestor(SkinItem *item); + const wchar_t *getSkinCursorBitmapId(const wchar_t *cursor); + + /* Bitmaps */ + void AddBitmap(const wchar_t *id, const wchar_t *filename, const wchar_t *path, int x, int y, int w, int h, ifc_xmlreaderparams *params = NULL, const wchar_t *colorgroup = NULL); + int getBitmapElement(const wchar_t *type); + SkinItem *getBitmapAncestor(SkinItem *item); + int getNumBitmapElement(); + const wchar_t *getSkinBitmapFilename(const wchar_t *id, int *x, int *y, int *w, int *h, const wchar_t **rootpath, ifc_xmlreaderparams **params); + const wchar_t *getGammaGroupFromId(const wchar_t *id); + int getLayerFromId(const wchar_t *id); + + /* Region Server (part of Bitmaps) */ + RegionServer *requestSkinRegion(const wchar_t *id); + void cacheSkinRegion(const wchar_t *id, api_region *r); + + enum + { + API_PALETTE_STARTTRANSACTION=0, + API_PALETTE_ENDTRANSACTION=1, + API_PALETTE_RESET=2, + API_PALETTE_GETSKINPARTITERATORPTR=3, + API_PALETTE_NEWSKINPART=4, + API_PALETTE_GETSKINPARTITERATOR=5, + API_PALETTE_UNLOADELEMENTS=6, + API_PALETTE_ADDALIAS=7, + API_PALETTE_GETELEMENTALIAS=8, + API_PALETTE_GETALIASANCESTOR=9, + API_PALETTE_ADDCOLOR=10, + API_PALETTE_GETNUMCOLORELEMENTS=11, + API_PALETTE_ENUMCOLORELEMENT=12, + API_PALETTE_GETCOLORELEMENTREF=13, + API_PALETTE_GETCOLORANCESTOR=14, + API_PALETTE_GETCOLORELEMENT=15, + API_PALETTE_ADDCURSOR=16, + API_PALETTE_GETCURSORELEMENT=17, + API_PALETTE_GETCURSOR=18, + API_PALETTE_GETCURSORANCESTOR=19, + API_PALETTE_GETSKINCURSORBITMAPID=20, + API_PALETTE_ADDBITMAP=21, + API_PALETTE_GETBITMAPELEMENT=22, + API_PALETTE_GETBITMAPANCESTOR=23, + API_PALETTE_GETNUMBITMAPELEMENT=24, + API_PALETTE_GETSKINBITMAPFILENAME=25, + API_PALETTE_GETGAMMAGROUPFROMID=26, + API_PALETTE_GETLAYERFROMID=27, + API_PALETTE_REQUESTSKINREGION=28, + API_PALETTE_CACHESKINREGION=29, + }; +}; + +inline void api_palette::StartTransaction() +{ + _voidcall(API_PALETTE_STARTTRANSACTION); +} + + +inline void api_palette::EndTransaction() +{ + _voidcall(API_PALETTE_ENDTRANSACTION); +} + + +inline void api_palette::Reset() +{ + _voidcall(API_PALETTE_RESET); +} + + +inline const int *api_palette::getSkinPartIteratorPtr() +{ + return _call(API_PALETTE_GETSKINPARTITERATORPTR, (const int *)0); +} + + +inline int api_palette::newSkinPart() +{ + return _call(API_PALETTE_NEWSKINPART, (int)0); +} + + +inline int api_palette::getSkinPartIterator() +{ + return _call(API_PALETTE_GETSKINPARTITERATOR, (int)0); +} + + +inline void api_palette::UnloadElements(int skinpart) +{ + _voidcall(API_PALETTE_UNLOADELEMENTS, skinpart); +} + + +inline void api_palette::AddAlias(const wchar_t *id, const wchar_t *target) +{ + _voidcall(API_PALETTE_ADDALIAS, id, target); +} + + +inline const wchar_t *api_palette::getElementAlias(const wchar_t *alias) +{ + return _call(API_PALETTE_GETELEMENTALIAS, (const wchar_t *)0, alias); +} + + +inline SkinItem *api_palette::getAliasAncestor(SkinItem *item) +{ + return _call(API_PALETTE_GETALIASANCESTOR, (SkinItem *)0, item); +} + + +inline void api_palette::AddColor(const wchar_t *id, ARGB32 value, const wchar_t *colorgrp, const wchar_t *path, ifc_xmlreaderparams *p) +{ + _voidcall(API_PALETTE_ADDCOLOR, id, value, colorgrp, path, p); +} + + +inline int api_palette::getNumColorElements() +{ + return _call(API_PALETTE_GETNUMCOLORELEMENTS, (int)0); +} + + +inline const wchar_t *api_palette::enumColorElement(int n) +{ + return _call(API_PALETTE_ENUMCOLORELEMENT, (const wchar_t *)0, n); +} + + +inline ARGB32 *api_palette::getColorElementRef(const wchar_t *type, const wchar_t **grp) +{ + return _call(API_PALETTE_GETCOLORELEMENTREF, (ARGB32 *)0, type, grp); +} + + +inline SkinItem *api_palette::getColorAncestor(SkinItem *item) +{ + return _call(API_PALETTE_GETCOLORANCESTOR, (SkinItem *)0, item); +} + + +inline ARGB32 api_palette::getColorElement(const wchar_t *type, const wchar_t **grp) +{ + return _call(API_PALETTE_GETCOLORELEMENT, (ARGB32)RGB(255, 0, 255), type, grp); +} + + +inline void api_palette::AddCursor(const wchar_t *id, const wchar_t *bitmapid, int x, int y, const wchar_t *path, ifc_xmlreaderparams *params) +{ + _voidcall(API_PALETTE_ADDCURSOR, id, bitmapid, x, y, path, params); +} + + +inline int api_palette::getCursorElement(const wchar_t *id) +{ + return _call(API_PALETTE_GETCURSORELEMENT, (int)-1, id); +} + + +inline OSCURSOR api_palette::getCursor(const wchar_t *id) +{ + return _call(API_PALETTE_GETCURSOR, INVALIDOSCURSORHANDLE, id); +} + + +inline SkinItem *api_palette::getCursorAncestor(SkinItem *item) +{ + return _call(API_PALETTE_GETCURSORANCESTOR, (SkinItem *)0, item); +} + + +inline const wchar_t *api_palette::getSkinCursorBitmapId(const wchar_t *cursor) +{ + return _call(API_PALETTE_GETSKINCURSORBITMAPID, (const wchar_t *)0, cursor); +} + + +inline void api_palette::AddBitmap(const wchar_t *id, const wchar_t *filename, const wchar_t *path, int x, int y, int w, int h, ifc_xmlreaderparams *params, const wchar_t *colorgroup) +{ + _voidcall(API_PALETTE_ADDBITMAP, id, filename, path, x, y, w, h, params, colorgroup); +} + + +inline int api_palette::getBitmapElement(const wchar_t *type) +{ + return _call(API_PALETTE_GETBITMAPELEMENT, (int)-1, type); +} + + +inline SkinItem *api_palette::getBitmapAncestor(SkinItem *item) +{ + return _call(API_PALETTE_GETBITMAPANCESTOR, (SkinItem *)0, item); +} + + +inline int api_palette::getNumBitmapElement() +{ + return _call(API_PALETTE_GETNUMBITMAPELEMENT, (int)0); +} + + +inline const wchar_t *api_palette::getSkinBitmapFilename(const wchar_t *id, int *x, int *y, int *w, int *h, const wchar_t **rootpath, ifc_xmlreaderparams **params) +{ + return _call(API_PALETTE_GETSKINBITMAPFILENAME, (const wchar_t *)0,id,x,y,w,h,rootpath, params); +} + + +inline const wchar_t *api_palette::getGammaGroupFromId(const wchar_t *id) +{ + return _call(API_PALETTE_GETGAMMAGROUPFROMID, (const wchar_t *)0, id); +} + + +inline int api_palette::getLayerFromId(const wchar_t *id) +{ + return _call(API_PALETTE_GETLAYERFROMID, (int)-1, id); +} + + +inline RegionServer *api_palette::requestSkinRegion(const wchar_t *id) +{ + return _call(API_PALETTE_REQUESTSKINREGION, (RegionServer *)0, id); +} + + +inline void api_palette::cacheSkinRegion(const wchar_t *id, api_region *r) +{ + _voidcall(API_PALETTE_CACHESKINREGION, id, r); +} + +// {DCA2E3C2-4C3E-4dd9-AB1A-1940F2CA31F7} +static const GUID PaletteManagerGUID = +{ 0xdca2e3c2, 0x4c3e, 0x4dd9, { 0xab, 0x1a, 0x19, 0x40, 0xf2, 0xca, 0x31, 0xf7 } }; diff --git a/Src/Wasabi/api/skin/api_skin.cpp b/Src/Wasabi/api/skin/api_skin.cpp new file mode 100644 index 00000000..ca441ede --- /dev/null +++ b/Src/Wasabi/api/skin/api_skin.cpp @@ -0,0 +1,63 @@ +#include <precomp.h> +#include "api_skin.h" + +#ifdef CBCLASS +#undef CBCLASS +#endif +#define CBCLASS api_skinI +START_DISPATCH; + CB(API_SKIN_SKIN_GETCOLORELEMENT, skin_getColorElement); + CB(API_SKIN_SKIN_GETCOLORELEMENTREF, skin_getColorElementRef); + CB(API_SKIN_SKIN_GETITERATOR, skin_getIterator); + VCB(API_SKIN_SKIN_SWITCHSKIN, skin_switchSkin); + VCB(API_SKIN_SKIN_UNLOADSKIN, skin_unloadSkin); + CB(API_SKIN_GETSKINNAME, getSkinName); + CB(API_SKIN_GETSKINPATH, getSkinPath); + CB(API_SKIN_GETSKINSPATH, getSkinsPath); + CB(API_SKIN_GETDEFAULTSKINPATH, getDefaultSkinPath); + CB(API_SKIN_IMGLDR_REQUESTSKINBITMAP, imgldr_requestSkinBitmap); + VCB(API_SKIN_IMGLDR_RELEASESKINBITMAP, imgldr_releaseSkinBitmap); + CB(API_SKIN_FILTERSKINCOLOR, filterSkinColor); + VCB(API_SKIN_REAPPLYSKINFILTERS, reapplySkinFilters); + CB(API_SKIN_COLORTHEME_GETNUMCOLORSETS, colortheme_getNumColorSets); + CB(API_SKIN_COLORTHEME_ENUMCOLORSET, colortheme_enumColorSet); + CB(API_SKIN_COLORTHEME_GETNUMCOLORGROUPS, colortheme_getNumColorGroups); + CB(API_SKIN_COLORTHEME_ENUMCOLORGROUPNAME, colortheme_enumColorGroupName); + CB(API_SKIN_COLORTHEME_ENUMCOLORGROUP, colortheme_enumColorGroup); + CB(API_SKIN_COLORTHEME_GETCOLORGROUP, colortheme_getColorGroup); + VCB(API_SKIN_COLORTHEME_SETCOLORSET, colortheme_setColorSet); + CB(API_SKIN_COLORTHEME_GETCOLORSET, colortheme_getColorSet); + VCB(API_SKIN_COLORTHEME_NEWCOLORSET, colortheme_newColorSet); + VCB(API_SKIN_COLORTHEME_UPDATECOLORSET, colortheme_updateColorSet); + VCB(API_SKIN_COLORTHEME_RENAMESET, colortheme_renameColorSet); + VCB(API_SKIN_COLORTHEME_DELETE, colortheme_deleteColorSet); + CB(API_SKIN_LOADSKINFILE, loadSkinFile); + CB(API_SKIN_LOADGROUPDEFDATA, loadGroupDefData); + VCB(API_SKIN_UNLOADSKINPART, unloadSkinPart); + CB(API_SKIN_GROUP_CREATE, group_create); +#ifdef WASABI_COMPILE_CONFIG + CB(API_SKIN_GROUP_CREATE_CFG, group_create_cfg); +#endif // WASABI_COMPILE_CONFIG +#ifdef WASABI_COMPILE_WNDMGR + CB(API_SKIN_GROUP_CREATE_LAYOUT, group_create_layout); +#endif //WASABI_COMPILE_WNDMGR + CB(API_SKIN_GROUP_DESTROY, group_destroy); + CB(API_SKIN_GROUP_EXISTS, group_exists); + CB(API_SKIN_PARSE, parse); + CB(API_SKIN_XUI_NEW, xui_new); + VCB(API_SKIN_XUI_DELETE, xui_delete); + CB(API_SKIN_CURSOR_REQUEST, cursor_request); + CB(API_SKIN_GETNUMGROUPS, getNumGroupDefs); + CB(API_SKIN_ENUMGROUP, enumGroupDef); + CB(API_SKIN_GROUP_CREATEBYITEM, group_createBySkinItem); + CB(API_SKIN_GETGROUPANCESTOR, getGroupDefAncestor); + CB(API_SKIN_GROUPDEF_GETNUMOBJECTS, groupdef_getNumObjects); + CB(API_SKIN_GROUPDEF_ENUMOBJECT, groupdef_enumObject); + VCB(API_SKIN_SETLOCKUI, skin_setLockUI); + CB(API_SKIN_GETLOCKUI, skin_getLockUI); + CB(API_SKIN_GETVERSION, skin_getVersion); +#ifdef WASABI_COMPILE_IMGLDR + CB(API_SKIN_GETBITMAPCOLOR, skin_getBitmapColor); +#endif + CB(API_SKIN_ISLOADED, skin_isLoaded); +END_DISPATCH; diff --git a/Src/Wasabi/api/skin/api_skin.h b/Src/Wasabi/api/skin/api_skin.h new file mode 100644 index 00000000..136712e9 --- /dev/null +++ b/Src/Wasabi/api/skin/api_skin.h @@ -0,0 +1,429 @@ +#ifndef __API_SKIN_H +#define __API_SKIN_H + +#include <wasabicfg.h> +#include <bfc/dispatch.h> + +class ifc_window; +class GuiObject; +class ColorThemeGroup; +class ifc_xmlreaderparams; +class SkinItem; + +#ifdef WASABI_COMPILE_CONFIG +class CfgItem; +#endif //WASABI_COMPILE_CONFIG + +#ifdef WASABI_COMPILE_WNDMGR +class CfgItem; +#endif //WASABI_COMPILE_WNDMGR + +#ifdef _WIN32 +#ifndef OSCURSOR +#define OSCURSOR HICON +#endif +#elif defined(__APPLE__) +#define OSCURSOR CGImageRef +#endif + +class NOVTABLE api_skin : public Dispatchable +{ + public: + // skin colors + ARGB32 skin_getColorElement(const wchar_t *type, const wchar_t **color_group = NULL); + const ARGB32 *skin_getColorElementRef(const wchar_t *type, const wchar_t **color_group = NULL); + const int *skin_getIterator(); + + // possibly make a svc_skinloader + void skin_switchSkin(const wchar_t *skin_name, const wchar_t *skin_path=NULL); + void skin_unloadSkin(); + int loadSkinFile(const wchar_t *xmlfile); + int loadGroupDefData(const wchar_t *groupdef, SkinItem **lastgroupitem); + void unloadSkinPart(int skinpartid); + const wchar_t *getSkinName(); + const wchar_t *getSkinPath(); + const wchar_t *getSkinsPath(); + const wchar_t *getDefaultSkinPath(); + + // skin bitmaps + ARGB32 *imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached); + void imgldr_releaseSkinBitmap(ARGB32 *bmpbits); +#ifdef WASABI_COMPILE_IMGLDR + ARGB32 skin_getBitmapColor(const wchar_t *bitmapid); +#endif + + // skin filters + ARGB32 filterSkinColor(ARGB32 color, const wchar_t *elementid, const wchar_t *groupname); + void reapplySkinFilters(); + int colortheme_getNumColorSets(); + const wchar_t *colortheme_enumColorSet(int n); + int colortheme_getNumColorGroups(const wchar_t *colorset); + const wchar_t *colortheme_enumColorGroupName(const wchar_t *colorset, int n); + ColorThemeGroup *colortheme_enumColorGroup(int colorset, int n); + ColorThemeGroup *colortheme_getColorGroup(const wchar_t *colorset, const wchar_t *colorgroup); + void colortheme_setColorSet(const wchar_t *colorset); + const wchar_t *colortheme_getColorSet(); + void colortheme_newColorSet(const wchar_t *set); + void colortheme_updateColorSet(const wchar_t *set); + void colortheme_renameColorSet(const wchar_t *set, const wchar_t *newname); + void colortheme_deleteColorSet(const wchar_t *set); + + // groups + ifc_window *group_create(const wchar_t *groupid, int scripts_enabled=1); + int group_exists(const wchar_t *groupid); +#ifdef WASABI_COMPILE_CONFIG + ifc_window *group_create_cfg(const wchar_t *groupid, CfgItem *cfgitem, const wchar_t *attributename, int scripts_enabled=1); +#endif // WASABI_COMPILE_CONFIG +#ifdef WASABI_COMPILE_WNDMGR + ifc_window *group_create_layout(const wchar_t *groupid, int scripts_enabled=1); +#endif //WASABI_COMPILE_WNDMGR + int group_destroy(ifc_window *group); + + int parse(const wchar_t *str, const wchar_t *how); + GuiObject *xui_new(const wchar_t *classname); + void xui_delete(GuiObject *o); + OSCURSOR cursor_request(const wchar_t *id); + int getNumGroupDefs(); + SkinItem *enumGroupDef(int n); + ifc_window *group_createBySkinItem(SkinItem *groupitem, int scripts_enabled=1); + SkinItem *getGroupDefAncestor(SkinItem *groupitem); + int groupdef_getNumObjects(SkinItem *groupitem); + SkinItem *groupdef_enumObject(SkinItem *item, int n); + void skin_setLockUI(int l); + int skin_getLockUI(); + double skin_getVersion(); + bool skin_isLoaded(); + + + enum { + API_SKIN_SKIN_GETCOLORELEMENT = 0, + API_SKIN_SKIN_GETCOLORELEMENTREF = 10, + API_SKIN_SKIN_GETITERATOR = 20, + API_SKIN_SKIN_SWITCHSKIN = 30, + API_SKIN_SKIN_UNLOADSKIN = 35, + API_SKIN_GETSKINNAME = 40, + API_SKIN_GETSKINPATH = 50, + API_SKIN_GETSKINSPATH = 60, + API_SKIN_GETDEFAULTSKINPATH = 70, + API_SKIN_IMGLDR_REQUESTSKINBITMAP = 80, + API_SKIN_IMGLDR_RELEASESKINBITMAP = 90, + API_SKIN_FILTERSKINCOLOR = 100, + API_SKIN_REAPPLYSKINFILTERS = 110, + API_SKIN_COLORTHEME_GETNUMCOLORSETS = 120, + API_SKIN_COLORTHEME_ENUMCOLORSET = 130, + API_SKIN_COLORTHEME_GETNUMCOLORGROUPS = 140, + API_SKIN_COLORTHEME_ENUMCOLORGROUPNAME = 150, + API_SKIN_COLORTHEME_ENUMCOLORGROUP = 160, + API_SKIN_COLORTHEME_GETCOLORGROUP = 165, + API_SKIN_COLORTHEME_SETCOLORSET = 170, + API_SKIN_COLORTHEME_GETCOLORSET = 180, + API_SKIN_COLORTHEME_NEWCOLORSET = 190, + API_SKIN_COLORTHEME_RENAMESET = 191, + API_SKIN_COLORTHEME_DELETE = 192, + API_SKIN_COLORTHEME_UPDATECOLORSET = 193, + API_SKIN_LOADSKINFILE = 200, + API_SKIN_UNLOADSKINPART = 210, + API_SKIN_GROUP_CREATE = 220, + API_SKIN_GROUP_EXISTS = 225, +#ifdef WASABI_COMPILE_CONFIG + API_SKIN_GROUP_CREATE_CFG = 230, +#endif // WASABI_COMPILE_CONFIG +#ifdef WASABI_COMPILE_WNDMGR + API_SKIN_GROUP_CREATE_LAYOUT = 240, +#endif //WASABI_COMPILE_WNDMGR + API_SKIN_GROUP_DESTROY = 250, + API_SKIN_PARSE = 260, + API_SKIN_XUI_NEW = 270, + API_SKIN_XUI_DELETE = 280, + API_SKIN_CURSOR_REQUEST = 290, + API_SKIN_GETNUMGROUPS = 300, + API_SKIN_ENUMGROUP = 310, + API_SKIN_GROUP_CREATEBYITEM = 320, + API_SKIN_GETGROUPANCESTOR = 330, + API_SKIN_GROUPDEF_GETNUMOBJECTS = 340, + API_SKIN_GROUPDEF_ENUMOBJECT = 350, + API_SKIN_LOADGROUPDEFDATA = 360, + API_SKIN_SETLOCKUI = 370, + API_SKIN_GETLOCKUI = 380, + API_SKIN_GETVERSION = 390, + API_SKIN_GETBITMAPCOLOR = 400, + API_SKIN_ISLOADED = 410, + }; +}; + +inline ARGB32 api_skin::skin_getColorElement(const wchar_t *type, const wchar_t **color_group) { + return _call(API_SKIN_SKIN_GETCOLORELEMENT, (ARGB32)NULL, type, color_group); +} + +inline const ARGB32 *api_skin::skin_getColorElementRef(const wchar_t *type, const wchar_t **color_group) { + return _call(API_SKIN_SKIN_GETCOLORELEMENTREF, (ARGB32 *)NULL, type, color_group); +} + +inline const int *api_skin::skin_getIterator() { + return _call(API_SKIN_SKIN_GETITERATOR, (const int *)0); +} + +inline void api_skin::skin_switchSkin(const wchar_t *skin_name, const wchar_t *skin_path) { + _voidcall(API_SKIN_SKIN_SWITCHSKIN, skin_name, skin_path); +} + +inline void api_skin::skin_unloadSkin() { + _voidcall(API_SKIN_SKIN_UNLOADSKIN); +} + +inline const wchar_t *api_skin::getSkinName() { + return _call(API_SKIN_GETSKINNAME, (const wchar_t *)0); +} + +inline const wchar_t *api_skin::getSkinPath() { + return _call(API_SKIN_GETSKINPATH, (const wchar_t *)0); +} + +inline const wchar_t *api_skin::getSkinsPath() { + return _call(API_SKIN_GETSKINSPATH, (const wchar_t *)0); +} + +inline const wchar_t *api_skin::getDefaultSkinPath() { + return _call(API_SKIN_GETDEFAULTSKINPATH, (const wchar_t *)0); +} + +inline ARGB32 *api_skin::imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached) { + return _call(API_SKIN_IMGLDR_REQUESTSKINBITMAP, (ARGB32 *)NULL, file, has_alpha, x, y, subw, subh, w, h, cached); +} + +inline void api_skin::imgldr_releaseSkinBitmap(ARGB32 *bmpbits) { + _voidcall(API_SKIN_IMGLDR_RELEASESKINBITMAP, bmpbits); +} + +inline ARGB32 api_skin::filterSkinColor(ARGB32 color, const wchar_t *elementid, const wchar_t *groupname) { + return _call(API_SKIN_FILTERSKINCOLOR, (ARGB32)NULL, color, elementid, groupname); +} + +inline void api_skin::reapplySkinFilters() { + _voidcall(API_SKIN_REAPPLYSKINFILTERS); +} + +inline int api_skin::colortheme_getNumColorSets() { + return _call(API_SKIN_COLORTHEME_GETNUMCOLORSETS, (int)0); +} + +inline const wchar_t *api_skin::colortheme_enumColorSet(int n) { + return _call(API_SKIN_COLORTHEME_ENUMCOLORSET, (const wchar_t *)0, n); +} + +inline int api_skin::colortheme_getNumColorGroups(const wchar_t *colorset) { + return _call(API_SKIN_COLORTHEME_GETNUMCOLORGROUPS, (int)0, colorset); +} + +inline const wchar_t *api_skin::colortheme_enumColorGroupName(const wchar_t *colorset, int n) { + return _call(API_SKIN_COLORTHEME_ENUMCOLORGROUPNAME, (const wchar_t *)0, colorset, n); +} + +inline ColorThemeGroup *api_skin::colortheme_enumColorGroup(int colorset, int n) { + return _call(API_SKIN_COLORTHEME_ENUMCOLORGROUP, (ColorThemeGroup *)NULL, colorset, n); +} + +inline ColorThemeGroup *api_skin::colortheme_getColorGroup(const wchar_t *colorset, const wchar_t *group) { + return _call(API_SKIN_COLORTHEME_GETCOLORGROUP, (ColorThemeGroup *)NULL, colorset, group); +} + +inline void api_skin::colortheme_setColorSet(const wchar_t *colorset) +{ + _voidcall(API_SKIN_COLORTHEME_SETCOLORSET, colorset); +} + +inline const wchar_t *api_skin::colortheme_getColorSet() +{ + return _call(API_SKIN_COLORTHEME_GETCOLORSET, (const wchar_t *)0); +} + +inline void api_skin::colortheme_newColorSet(const wchar_t *set) { + _voidcall(API_SKIN_COLORTHEME_NEWCOLORSET, set); +} + +inline void api_skin::colortheme_updateColorSet(const wchar_t *set) { + _voidcall(API_SKIN_COLORTHEME_UPDATECOLORSET, set); +} + +inline void api_skin::colortheme_renameColorSet(const wchar_t *set, const wchar_t *newname) { + _voidcall(API_SKIN_COLORTHEME_RENAMESET, set, newname); +} + +inline void api_skin::colortheme_deleteColorSet(const wchar_t *set) { + _voidcall(API_SKIN_COLORTHEME_DELETE, set); +} + + +inline int api_skin::loadSkinFile(const wchar_t *xmlfile) { + return _call(API_SKIN_LOADSKINFILE, (int)0, xmlfile); +} + +inline void api_skin::unloadSkinPart(int skinpartid) { + _voidcall(API_SKIN_UNLOADSKINPART, skinpartid); +} + +inline ifc_window *api_skin::group_create(const wchar_t *groupid, int scripts_enabled) { + return _call(API_SKIN_GROUP_CREATE, (ifc_window *)NULL, groupid, scripts_enabled); +} + +inline int api_skin::group_exists(const wchar_t *groupid) { + return _call(API_SKIN_GROUP_EXISTS, 1, groupid); +} + +#ifdef WASABI_COMPILE_CONFIG +inline ifc_window *api_skin::group_create_cfg(const wchar_t *groupid, CfgItem *cfgitem, const wchar_t *attributename, int scripts_enabled) { + return _call(API_SKIN_GROUP_CREATE_CFG, (ifc_window *)NULL, groupid, cfgitem, attributename, scripts_enabled); +} +#endif // WASABI_COMPILE_CONFIG + +#ifdef WASABI_COMPILE_WNDMGR +inline ifc_window *api_skin::group_create_layout(const wchar_t *groupid, int scripts_enabled) { + return _call(API_SKIN_GROUP_CREATE_LAYOUT, (ifc_window *)NULL, groupid, scripts_enabled); +} +#endif //WASABI_COMPILE_WNDMGR + +inline int api_skin::group_destroy(ifc_window *group) { + return _call(API_SKIN_GROUP_DESTROY, (int)0, group); +} + +inline int api_skin::parse(const wchar_t *str, const wchar_t *how) { + return _call(API_SKIN_PARSE, (int)0, str, how); +} + +inline GuiObject *api_skin::xui_new(const wchar_t *classname) { + return _call(API_SKIN_XUI_NEW, (GuiObject *)NULL, classname); +} + +inline void api_skin::xui_delete(GuiObject *o) { + _voidcall(API_SKIN_XUI_DELETE, o); +} + +inline OSCURSOR api_skin::cursor_request(const wchar_t *id) +{ + return _call(API_SKIN_CURSOR_REQUEST, (OSCURSOR)NULL, id); +} + +inline int api_skin::getNumGroupDefs() { + return _call(API_SKIN_GETNUMGROUPS, (int)0); +} + +inline SkinItem *api_skin::enumGroupDef(int n) { + return _call(API_SKIN_ENUMGROUP, (SkinItem *)NULL, n); +} + +inline ifc_window *api_skin::group_createBySkinItem(SkinItem *item, int scripts_enabled) { + return _call(API_SKIN_GROUP_CREATEBYITEM, (ifc_window *)NULL, item, scripts_enabled); +} + +inline SkinItem *api_skin::getGroupDefAncestor(SkinItem *item) { + return _call(API_SKIN_GETGROUPANCESTOR, (SkinItem *)NULL, item); +} + +inline int api_skin::groupdef_getNumObjects(SkinItem *groupitem) { + return _call(API_SKIN_GROUPDEF_GETNUMOBJECTS, 0, groupitem); +} + +inline SkinItem *api_skin::groupdef_enumObject(SkinItem *item, int n) { + return _call(API_SKIN_GROUPDEF_ENUMOBJECT, (SkinItem *)NULL, item, n); +} + +inline int api_skin::loadGroupDefData(const wchar_t *groupdef, SkinItem **lastgroupitem) { + return _call(API_SKIN_LOADGROUPDEFDATA, -1, groupdef, lastgroupitem); +} + +inline void api_skin::skin_setLockUI(int l) { + _voidcall(API_SKIN_SETLOCKUI, l); +} + +inline int api_skin::skin_getLockUI() { + return _call(API_SKIN_GETLOCKUI, 0); +} + +inline double api_skin::skin_getVersion() { + return _call(API_SKIN_GETVERSION, 0.8); +} + +#ifdef WASABI_COMPILE_IMGLDR +inline ARGB32 api_skin::skin_getBitmapColor(const wchar_t *bitmapid) { + return _call(API_SKIN_GETBITMAPCOLOR, 0xFFFF00FF, bitmapid); +} +#endif + +inline bool api_skin::skin_isLoaded() +{ + return _call(API_SKIN_ISLOADED, false); +} + +class api_skinI : public api_skin +{ + protected: + api_skinI() {} + virtual ~api_skinI() {} + + public: + virtual ARGB32 skin_getColorElement(const wchar_t *type, const wchar_t **color_group = NULL)=0; + virtual const ARGB32 *skin_getColorElementRef(const wchar_t *type, const wchar_t **color_group = NULL)=0; + virtual const int *skin_getIterator()=0; + virtual void skin_switchSkin(const wchar_t *skin_name, const wchar_t *skin_path=NULL)=0; + virtual void skin_unloadSkin()=0; + virtual const wchar_t *getSkinName()=0; + virtual const wchar_t *getSkinPath()=0; + virtual const wchar_t *getSkinsPath()=0; + virtual const wchar_t *getDefaultSkinPath()=0; + virtual ARGB32 *imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached)=0; + virtual void imgldr_releaseSkinBitmap(ARGB32 *bmpbits)=0; + virtual ARGB32 filterSkinColor(ARGB32 color, const wchar_t *elementid, const wchar_t *groupname)=0; + virtual void reapplySkinFilters()=0; + virtual int colortheme_getNumColorSets()=0; + virtual const wchar_t *colortheme_enumColorSet(int n)=0; + virtual int colortheme_getNumColorGroups(const wchar_t *colorset)=0; + virtual const wchar_t *colortheme_enumColorGroupName(const wchar_t *colorset, int n)=0; + virtual ColorThemeGroup *colortheme_enumColorGroup(int colorset, int n)=0; + virtual ColorThemeGroup *colortheme_getColorGroup(const wchar_t *colorset, const wchar_t *group)=0; + virtual void colortheme_setColorSet(const wchar_t *colorset)=0; + virtual const wchar_t *colortheme_getColorSet()=0; + virtual void colortheme_newColorSet(const wchar_t *set)=0; + virtual void colortheme_updateColorSet(const wchar_t *set)=0; + virtual void colortheme_renameColorSet(const wchar_t *set, const wchar_t *newname)=0; + virtual void colortheme_deleteColorSet(const wchar_t *set)=0; + virtual int loadSkinFile(const wchar_t *xmlfile)=0; + virtual int loadGroupDefData(const wchar_t *groupdef, SkinItem **lastgroupitem)=0; + virtual void unloadSkinPart(int skinpartid)=0; + virtual ifc_window *group_create(const wchar_t *groupid, int scripts_enabled=1)=0; + virtual int group_exists(const wchar_t *groupid)=0; +#ifdef WASABI_COMPILE_CONFIG + virtual ifc_window *group_create_cfg(const wchar_t *groupid, CfgItem *cfgitem, const wchar_t *attributename, int scripts_enabled=1)=0; +#endif // WASABI_COMPILE_CONFIG +#ifdef WASABI_COMPILE_WNDMGR + virtual ifc_window *group_create_layout(const wchar_t *groupid, int scripts_enabled=1)=0; +#endif //WASABI_COMPILE_WNDMGR + virtual int group_destroy(ifc_window *group)=0; + virtual int parse(const wchar_t *str, const wchar_t *how)=0; + virtual GuiObject *xui_new(const wchar_t *classname)=0; + virtual void xui_delete(GuiObject *o)=0; + virtual OSCURSOR cursor_request(const wchar_t *id)=0; + virtual int getNumGroupDefs()=0; + virtual SkinItem *enumGroupDef(int n)=0; + virtual ifc_window *group_createBySkinItem(SkinItem *item, int scripts_enabled=1)=0; + virtual SkinItem *getGroupDefAncestor(SkinItem *groupitem)=0; + virtual int groupdef_getNumObjects(SkinItem *groupitem)=0; + virtual SkinItem *groupdef_enumObject(SkinItem *groupitem, int n)=0; + virtual void skin_setLockUI(int l)=0; + virtual int skin_getLockUI()=0; + virtual double skin_getVersion()=0; +#ifdef WASABI_COMPILE_IMGLDR + virtual ARGB32 skin_getBitmapColor(const wchar_t *id)=0; +#endif + virtual bool skin_isLoaded()=0; + protected: + RECVS_DISPATCH; +}; + +// {F2398F09-63B0-4442-86C9-F8BC473F6DA7} +static const GUID skinApiServiceGuid = +{ 0xf2398f09, 0x63b0, 0x4442, { 0x86, 0xc9, 0xf8, 0xbc, 0x47, 0x3f, 0x6d, 0xa7 } }; + +extern api_skin *skinApi; + + +#endif diff --git a/Src/Wasabi/api/skin/colorthemes.h b/Src/Wasabi/api/skin/colorthemes.h new file mode 100644 index 00000000..fe11ec17 --- /dev/null +++ b/Src/Wasabi/api/skin/colorthemes.h @@ -0,0 +1,87 @@ +#ifndef __COLORTHEMEGROUP_H +#define __COLORTHEMEGROUP_H + +#include <bfc/dispatch.h> + +class ColorThemeGroup : public Dispatchable +{ + public: + const wchar_t *getName(); + int getRed(); + int getGreen(); + int getBlue(); + int getGray(); + int getBoost(); + + void setName(const wchar_t *name); + void setRed(int r); + void setGreen(int g); + void setBlue(int b); + void setGray(int g); + void setBoost(int b); + + enum { + COLORTHEMEGROUPGETNAME=10, + COLORTHEMEGROUPGETRED=20, + COLORTHEMEGROUPGETGREEN=30, + COLORTHEMEGROUPGETBLUE=40, + COLORTHEMEGROUPGETGRAY=50, + COLORTHEMEGROUPGETBOOST=60, + COLORTHEMEGROUPSETNAME=70, + COLORTHEMEGROUPSETRED=80, + COLORTHEMEGROUPSETGREEN=90, + COLORTHEMEGROUPSETBLUE=100, + COLORTHEMEGROUPSETGRAY=110, + COLORTHEMEGROUPSETBOOST=120, + }; +}; + +inline const wchar_t *ColorThemeGroup::getName() { + return _call(COLORTHEMEGROUPGETNAME, (const wchar_t *)NULL); +} + +inline int ColorThemeGroup::getRed() { + return _call(COLORTHEMEGROUPGETRED, 0); +} + +inline int ColorThemeGroup::getGreen() { + return _call(COLORTHEMEGROUPGETGREEN, 0); +} + +inline int ColorThemeGroup::getBlue() { + return _call(COLORTHEMEGROUPGETBLUE, 0); +} + +inline int ColorThemeGroup::getGray() { + return _call(COLORTHEMEGROUPGETGRAY, 0); +} + +inline int ColorThemeGroup::getBoost() { + return _call(COLORTHEMEGROUPGETBOOST, 0); +} + +inline void ColorThemeGroup::setName(const wchar_t *name) { + _voidcall(COLORTHEMEGROUPSETNAME, name); +} + +inline void ColorThemeGroup::setRed(int r) { + _voidcall(COLORTHEMEGROUPSETRED, r); +} + +inline void ColorThemeGroup::setGreen(int g) { + _voidcall(COLORTHEMEGROUPSETGREEN, g); +} + +inline void ColorThemeGroup::setBlue(int b) { + _voidcall(COLORTHEMEGROUPSETBLUE, b); +} + +inline void ColorThemeGroup::setGray(int g) { + _voidcall(COLORTHEMEGROUPSETGRAY, g); +} + +inline void ColorThemeGroup::setBoost(int b) { + _voidcall(COLORTHEMEGROUPSETBOOST, b); +} + +#endif diff --git a/Src/Wasabi/api/skin/cursormgr.cpp b/Src/Wasabi/api/skin/cursormgr.cpp new file mode 100644 index 00000000..bf5ab3e8 --- /dev/null +++ b/Src/Wasabi/api/skin/cursormgr.cpp @@ -0,0 +1,29 @@ +#include "precomp.h" +#include <api.h> +#include "cursormgr.h" +#include <api/skin/skinelem.h> + + + +OSCURSOR CursorMgr::requestCursor(const wchar_t *id) +{ + // Martin> Register os cursors, perhaps find a better way to do this in basewnd.cpp + if (_wcsicmp(id, L"IDC_ARROW") == 0) return LoadCursor(NULL, IDC_ARROW); + if (_wcsicmp(id, L"IDC_SIZENS") == 0) return LoadCursor(NULL, IDC_SIZENS); + if (_wcsicmp(id, L"IDC_SIZEWE") == 0) return LoadCursor(NULL, IDC_SIZEWE); + if (_wcsicmp(id, L"IDC_SIZENWSE") == 0) return LoadCursor(NULL, IDC_SIZENWSE); + if (_wcsicmp(id, L"IDC_SIZENESW") == 0) return LoadCursor(NULL, IDC_SIZENESW); + if (_wcsicmp(id, L"IDC_SIZEALL") == 0) return LoadCursor(NULL, IDC_SIZEALL); + if (_wcsicmp(id, L"IDC_IBEAM") == 0) return LoadCursor(NULL, IDC_IBEAM); + if (_wcsicmp(id, L"IDC_WAIT") == 0) return LoadCursor(NULL, IDC_WAIT); + if (_wcsicmp(id, L"IDC_CROSS") == 0) return LoadCursor(NULL, IDC_CROSS); + if (_wcsicmp(id, L"IDC_UPARROW") == 0) return LoadCursor(NULL, IDC_UPARROW); + if (_wcsicmp(id, L"IDC_NO") == 0) return LoadCursor(NULL, IDC_NO); + if (_wcsicmp(id, L"IDC_HAND") == 0) return LoadCursor(NULL, IDC_HAND); + if (_wcsicmp(id, L"IDC_APPSTARTING") == 0) return LoadCursor(NULL, IDC_APPSTARTING); + if (_wcsicmp(id, L"IDC_HELP") == 0) return LoadCursor(NULL, IDC_HELP); + + OSCURSOR cursor = WASABI_API_PALETTE->getCursor(id); + return cursor; +} + diff --git a/Src/Wasabi/api/skin/cursormgr.h b/Src/Wasabi/api/skin/cursormgr.h new file mode 100644 index 00000000..a70d6eaf --- /dev/null +++ b/Src/Wasabi/api/skin/cursormgr.h @@ -0,0 +1,18 @@ +#ifndef __CURSORMGR_H +#define __CURSORMGR_H + +#include <bfc/platform/platform.h> +#include <api/wnd/cursor.h> + +class ifc_window; + +class CursorMgr +{ + public: + CursorMgr() {} + virtual ~CursorMgr() {} + + static OSCURSOR requestCursor(const wchar_t *id); +}; + +#endif diff --git a/Src/Wasabi/api/skin/feeds/TextFeedEnum.h b/Src/Wasabi/api/skin/feeds/TextFeedEnum.h new file mode 100644 index 00000000..62405cfe --- /dev/null +++ b/Src/Wasabi/api/skin/feeds/TextFeedEnum.h @@ -0,0 +1,35 @@ +#ifndef NULLSOFT_WASABI_TEXTFEEDENUM_H +#define NULLSOFT_WASABI_TEXTFEEDENUM_H + + +#include <bfc/string/StringW.h> +#include <api/skin/feeds/api_textfeed.h> +// see helper class TextFeed + +#include <api/service/servicei.h> +template <class T> +class TextFeedCreatorSingle : public waServiceFactoryTSingle<svc_textFeed, T> +{ +public: + svc_textFeed *getFeed() + { + return getSingleService(); + } +}; + +#include <api/service/svc_enum.h> + +class TextFeedEnum : public SvcEnumT<svc_textFeed> +{ +public: + TextFeedEnum(const wchar_t *_feedid) : feedid(_feedid) {} +protected: + virtual int testService(svc_textFeed *svc) + { + return (svc->hasFeed(feedid)); + } +private: + StringW feedid; +}; + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/feeds/api_textfeed.cpp b/Src/Wasabi/api/skin/feeds/api_textfeed.cpp new file mode 100644 index 00000000..d7b3d2f1 --- /dev/null +++ b/Src/Wasabi/api/skin/feeds/api_textfeed.cpp @@ -0,0 +1,2 @@ +#include <precomp.h> +#include "api_textfeed.h"
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/feeds/api_textfeed.h b/Src/Wasabi/api/skin/feeds/api_textfeed.h new file mode 100644 index 00000000..fecde4d4 --- /dev/null +++ b/Src/Wasabi/api/skin/feeds/api_textfeed.h @@ -0,0 +1,66 @@ +#ifndef __WASABI_API_TEXTFEED_H +#define __WASABI_API_TEXTFEED_H + +#include <bfc/dispatch.h> +#include <bfc/platform/types.h> +#include <api/service/services.h> + +class ifc_dependent; + +// {A04E3420-CBA1-4ae1-B3C0-8DE127D2B861} +static const GUID textfeed_dependent_GUID = { 0xa04e3420, 0xcba1, 0x4ae1, { 0xb3, 0xc0, 0x8d, 0xe1, 0x27, 0xd2, 0xb8, 0x61 } }; + +class NOVTABLE svc_textFeed : public Dispatchable +{ +public: + static FOURCC getServiceType() { return WaSvc::TEXTFEED; } + static const GUID *depend_getClassGuid() + { + return &textfeed_dependent_GUID; + } + static const char *getServiceName() { return "Untitled Textfeed"; } + +public: + int hasFeed(const wchar_t *name); + const wchar_t *getFeedText(const wchar_t *name); + const wchar_t *getFeedDescription(const wchar_t *name); + ifc_dependent *getDependencyPtr(); + +public: + enum + { + Event_TEXTCHANGE = 100, // param is const char* to id, ptr points to new text + }; + + DISPATCH_CODES + { + SVCTEXTFEED_HASFEED = 10, + //20,30 retired + SVCTEXTFEED_GETFEEDTEXT = 40, + SVCTEXTFEED_GETFEEDDESC = 45, + SVCTEXTFEED_GETDEPENDENCYPTR = 100, + }; +}; + +inline int svc_textFeed::hasFeed(const wchar_t *name) +{ + return _call(SVCTEXTFEED_HASFEED, 0, name); +} + +inline const wchar_t *svc_textFeed::getFeedText(const wchar_t *name) +{ + return _call(SVCTEXTFEED_GETFEEDTEXT, (const wchar_t *)NULL, name); +} + +inline const wchar_t *svc_textFeed::getFeedDescription(const wchar_t *name) +{ + return _call(SVCTEXTFEED_GETFEEDDESC, (const wchar_t *)NULL, name); +} + +inline ifc_dependent *svc_textFeed::getDependencyPtr() +{ + return _call(SVCTEXTFEED_GETDEPENDENCYPTR, (ifc_dependent*)NULL); +} + + +#endif diff --git a/Src/Wasabi/api/skin/feeds/ezfeed.h b/Src/Wasabi/api/skin/feeds/ezfeed.h new file mode 100644 index 00000000..cc607d10 --- /dev/null +++ b/Src/Wasabi/api/skin/feeds/ezfeed.h @@ -0,0 +1,27 @@ +#ifndef _EZFEED_H +#define _EZFEED_H + +//#include <bfc/wasabi_std.h> +#include <api/service/waservicefactorybase.h> +#include <api/skin/feeds/textfeed.h> + +class EzFeed : public waServiceFactoryBase<svc_textFeed, EzFeed>, public TextFeed +{ +public: + EzFeed() : registered(0) { } + static const char *getServiceName() { return "EzTextFeed"; } + virtual svc_textFeed *newService() { return this; } + virtual int delService(svc_textFeed *service) { return TRUE; } + + virtual int svc_notify(int msg, int param1 = 0, int param2 = 0) + { + if (msg == SvcNotify::ONREGISTERED) registered = 1; + else if (msg == SvcNotify::ONDEREGISTERED) registered = 0; + return 1; + } + +private: + int registered; +}; + +#endif diff --git a/Src/Wasabi/api/skin/feeds/feedwatch.cpp b/Src/Wasabi/api/skin/feeds/feedwatch.cpp new file mode 100644 index 00000000..e200c20e --- /dev/null +++ b/Src/Wasabi/api/skin/feeds/feedwatch.cpp @@ -0,0 +1,90 @@ +#include <precomp.h> +#pragma warning(disable:4355) + +//<?#include "<class data="implementationheader"/>" +#include "feedwatch.h" +//?> + +#include <api/skin/feeds/TextFeedEnum.h> + + +FeedWatcher::FWDV::FWDV(FeedWatcher *_parent) : parent(_parent) { } + +int FeedWatcher::FWDV::viewer_onItemDeleted(ifc_dependent *item) { + return parent->fwdv_onItemDeleted(item); +} + +int FeedWatcher::FWDV::viewer_onEvent(ifc_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen) { + return parent->fwdv_onEvent(item, event, param, ptr, ptrlen); +} + +FeedWatcher::FeedWatcher() : + registered_syscb(0), textfeed(NULL), fwdv(this) +{ +} + + +FeedWatcher::~FeedWatcher() { + releaseFeed(); + if (registered_syscb) { + WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SvcCallbackI*>(this)); + DebugStringW(L"unreg syscb"); + } +} + +int FeedWatcher::setFeed(const wchar_t *feedid) +{ + if (!registered_syscb++) WASABI_API_SYSCB->syscb_registerCallback(static_cast<SvcCallbackI*>(this)); + + releaseFeed(); + + feed_id = feedid; + if (!feed_id.isempty()) textfeed = TextFeedEnum(feed_id).getFirst(); + + if (textfeed != NULL) { + fwdv.viewer_addViewItem(textfeed->getDependencyPtr()); + feedwatcher_onSetFeed(textfeed); +//CUT if (first_cb) feedwatcher_onFeedChange(textfeed->getFeedText(feed_id)); + } + + return 1; +} + +void FeedWatcher::releaseFeed() { + if (textfeed) { + fwdv.viewer_delViewItem(textfeed->getDependencyPtr()); + feed_id = L""; + SvcEnum::release(textfeed); + textfeed = NULL; + } +} + +const wchar_t *FeedWatcher::getFeedId() { + return feed_id; +} + +int FeedWatcher::fwdv_onItemDeleted(ifc_dependent *item) { + textfeed = NULL; + // send text change msg? dunno for sure + return 1; +} + +int FeedWatcher::fwdv_onEvent(ifc_dependent *item, int event, intptr_t param2, void *ptr, size_t ptrlen) { + if (textfeed && item == textfeed->getDependencyPtr() + && event == svc_textFeed::Event_TEXTCHANGE + && WCSCASEEQLSAFE((const wchar_t *)param2, feed_id)) { + feedwatcher_onFeedChange((const wchar_t *)ptr); + return 1; + } + return 0; +} + +void FeedWatcher::svccb_onSvcRegister(FOURCC type, waServiceFactory *svc) { + // brand new feed and we don't have one, try to register it +//CUT __asm int 3; + if (type == WaSvc::TEXTFEED && textfeed == NULL) { + if (!feed_id.isempty()) { + setFeed(feed_id); + } + } +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/feeds/feedwatch.h b/Src/Wasabi/api/skin/feeds/feedwatch.h new file mode 100644 index 00000000..3e3bd7a2 --- /dev/null +++ b/Src/Wasabi/api/skin/feeds/feedwatch.h @@ -0,0 +1,54 @@ +#ifndef __FEEDWATCH_H +#define __FEEDWATCH_H + +#include <bfc/wasabi_std.h> +#include <api/syscb/callbacks/svccbi.h> +#include "feedwatcherso.h" + +class svc_textFeed; +class ifc_dependent; + + + +class FeedWatcher : private SvcCallbackI, public FeedWatcherScriptObject { +public: + FeedWatcher(); + virtual ~FeedWatcher(); + + int setFeed(const wchar_t *feedid); + void releaseFeed(); + + const wchar_t *getFeedId(); + + virtual void feedwatcher_onSetFeed(svc_textFeed *svc) { } + virtual void feedwatcher_onFeedChange(const wchar_t *data) { } + +protected: + class FWDV : public DependentViewerI +{ +public: + friend class FeedWatcher; + + FWDV(FeedWatcher *parent); + + virtual int viewer_onItemDeleted(ifc_dependent *item); + virtual int viewer_onEvent(ifc_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen); + + FeedWatcher *parent; +}; + + // catches text feed change events + virtual int fwdv_onItemDeleted(ifc_dependent *item); + virtual int fwdv_onEvent(ifc_dependent *item, int event, intptr_t param2, void *ptr, size_t ptrlen); + +private: + // catches new feeds being registered + virtual void svccb_onSvcRegister(FOURCC type, waServiceFactory *svc); + + int registered_syscb; + StringW feed_id; + svc_textFeed *textfeed; + FWDV fwdv; +}; + +#endif diff --git a/Src/Wasabi/api/skin/feeds/feedwatcherso.cpp b/Src/Wasabi/api/skin/feeds/feedwatcherso.cpp new file mode 100644 index 00000000..af8d5ff0 --- /dev/null +++ b/Src/Wasabi/api/skin/feeds/feedwatcherso.cpp @@ -0,0 +1,136 @@ +// ---------------------------------------------------------------------------- +// Generated by ScriptObjectFactory [Sat Sep 27 01:24:57 2003] +// +// File : +// Class : FeedWatcherScriptObject +// class layer : Automatic Object Scripting +// ---------------------------------------------------------------------------- +#include "precomp.h" + +#include "feedwatch.h" +#include "FeedWatcherSO.h" +// ScriptController Instance +static FeedWatcherScriptController _feedWatcherScriptController;FeedWatcherScriptController *feedWatcherScriptController = &_feedWatcherScriptController; + +// Function Descriptor Table +function_descriptor_struct FeedWatcherScriptController::exportedFunctions[] = { + { L"setFeed", 1, script_setFeed }, + { L"releaseFeed", 0, script_releaseFeed }, + { L"onFeedChange", 1, script_feedwatcher_onFeedChange }, +}; + +// Script Object Methods +FeedWatcherScriptObject::FeedWatcherScriptObject() { + if (!getScriptObject()) return; + feedWatcherScriptObject_init(); +} + +FeedWatcherScriptObject::~FeedWatcherScriptObject() { +} + +void FeedWatcherScriptObject::feedWatcherScriptObject_init() { + // Assign the script interface to this instance. + getScriptObject()->vcpu_setInterface(FeedWatcherGuid, (void *)static_cast<FeedWatcher*>(this)); + // Assign the class name to this instance. + getScriptObject()->vcpu_setClassName(L"FeedWatcher"); + // Assign the controller instance to this script object instance. + getScriptObject()->vcpu_setController(feedWatcherScriptController); +} + +// Script Object Methods + +void FeedWatcherScriptObject::feedwatcher_onFeedChange(const wchar_t *data) { + FeedWatcherScriptController::script_feedwatcher_onFeedChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(data)); +} + +scriptVar /*int */ FeedWatcherScriptController::script_setFeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*const char **/ feedid) { + // Begin all script methods with the init block. + SCRIPT_FUNCTION_INIT; + // Find the proper pointer for the "this" object, _pSO. + FeedWatcher*_pObj = static_cast<FeedWatcher*>(_pSO->vcpu_getInterface(FeedWatcherGuid)); + if (_pObj) { + return MAKE_SCRIPT_INT(_pObj->setFeed(GET_SCRIPT_STRING(feedid))); + } + RETURN_SCRIPT_ZERO; +} + +scriptVar /*void */ FeedWatcherScriptController::script_releaseFeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) { + // Begin all script methods with the init block. + SCRIPT_FUNCTION_INIT; + // Find the proper pointer for the "this" object, _pSO. + FeedWatcher*_pObj = static_cast<FeedWatcher*>(_pSO->vcpu_getInterface(FeedWatcherGuid)); + if (_pObj) { + // Then properly call the hosted object; + _pObj->releaseFeed(); + } + RETURN_SCRIPT_VOID; +} + +scriptVar /*void */ FeedWatcherScriptController::script_feedwatcher_onFeedChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*const char **/ data) { + // Begin all script methods with the init block + SCRIPT_FUNCTION_INIT; + // Honnor C++ hooks + PROCESS_HOOKS1(_pSO, feedWatcherScriptController, data); + // If there are no script hooks to execute, we abort here. + SCRIPT_FUNCTION_CHECKABORTEVENT; + // Otherwise we execute the script methods by calling this. + SCRIPT_EXEC_EVENT1(_pSO, data); +} + +// Script Controller + +// This method returns the human readable name of the class in script files. +const wchar_t *FeedWatcherScriptController::getClassName() { + return L"FeedWatcher"; +} + +// This method returns the human readable name of the parent of this class. +const wchar_t *FeedWatcherScriptController::getAncestorClassName() { + return FEEDWATCHER_SCRIPTPARENTCLASS; +} + +// This method returns the controller object for the parent class. +ScriptObjectController *FeedWatcherScriptController::getAncestorController() { + /* XML-Template-TODO : Support inheritance */ + return NULL; +} + +// This method returns the number of methods this class publishes. +int FeedWatcherScriptController::getNumFunctions() { + return sizeof(exportedFunctions) / sizeof(function_descriptor_struct); +} + +// This method returns the block of published function descriptors. +const function_descriptor_struct *FeedWatcherScriptController::getExportedFunctions() { + return exportedFunctions; +} + +// This method returns the GUID assigned to this script class. +GUID FeedWatcherScriptController::getClassGuid() { + return FeedWatcherGuid; +} + +// This method creates and returns a new script class instance. +ScriptObject *FeedWatcherScriptController::instantiate() { + FeedWatcher*_pObj = new FeedWatcher(); + ASSERT(_pObj != NULL); + return _pObj->getScriptObject(); +} + +// This method deletes a given script class instance. +void FeedWatcherScriptController::destroy(ScriptObject *o) { + FeedWatcher*_pObj = static_cast<FeedWatcher*>(o->vcpu_getInterface(FeedWatcherGuid)); + ASSERT(_pObj != NULL); + delete _pObj; +} + +// This method returns an encapsulated interface for the given instance. +void *FeedWatcherScriptController::encapsulate(ScriptObject *o) { + // No automatic encapsulation + return NULL; +} + +// This method frees a previously encapsulated interface. +void FeedWatcherScriptController::deencapsulate(void *o) { +} + diff --git a/Src/Wasabi/api/skin/feeds/feedwatcherso.h b/Src/Wasabi/api/skin/feeds/feedwatcherso.h new file mode 100644 index 00000000..852964fa --- /dev/null +++ b/Src/Wasabi/api/skin/feeds/feedwatcherso.h @@ -0,0 +1,64 @@ +// ---------------------------------------------------------------------------- +// Generated by ScriptObjectFactory [Sat Sep 27 01:24:57 2003] +// +// File : +// Class : FeedWatcherScriptObject +// class layer : Automatic Object Scripting +// ---------------------------------------------------------------------------- + +#ifndef __FEEDWATCHERSCRIPTOBJECT_H +#define __FEEDWATCHERSCRIPTOBJECT_H + + +#include <api/script/objects/rootobj.h> +#include <api/script/objcontroller.h> + +#define FEEDWATCHER_SCRIPTPARENT RootObjectInstance +#define FEEDWATCHER_SCRIPTPARENTCLASS L"Object" + +class svc_textFeed; + +// ---------------------------------------------------------------------------- +// {A5376FA1-4E94-411a-83F6-05EC5EEA5F0A} +static const GUID FeedWatcherGuid = +{ 0xa5376fa1, 0x4e94, 0x411a, { 0x83, 0xf6, 0x5, 0xec, 0x5e, 0xea, 0x5f, 0xa } }; + +// ----------------------------------------------------------------------------- + +class FeedWatcherScriptObject : public FEEDWATCHER_SCRIPTPARENT { +public: + FeedWatcherScriptObject(); + virtual ~FeedWatcherScriptObject(); + + void feedWatcherScriptObject_init(); + +public: + virtual void feedwatcher_onFeedChange(const wchar_t *data); +}; + +// ----------------------------------------------------------------------------- +class FeedWatcherScriptController : 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); + + static scriptVar script_setFeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar feedid); + static scriptVar script_releaseFeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO); + static scriptVar script_feedwatcher_onFeedChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar data); + +private:static function_descriptor_struct exportedFunctions[]; +}; + +extern FeedWatcherScriptController *feedWatcherScriptController; +// ---------------------------------------------------------------------------- + +#endif // __FEEDWATCHERSCRIPTOBJECT_H diff --git a/Src/Wasabi/api/skin/feeds/textfeed.cpp b/Src/Wasabi/api/skin/feeds/textfeed.cpp new file mode 100644 index 00000000..feebe097 --- /dev/null +++ b/Src/Wasabi/api/skin/feeds/textfeed.cpp @@ -0,0 +1,116 @@ +#include <precomp.h> +#include "textfeed.h" +#include <bfc/pair.h> + +int TextFeed::registerFeed(const wchar_t *feedid, const wchar_t *initial_text, const wchar_t *description) +{ + //if (feeds.getItem(StringW(feedid))) + // return FALSE; + auto it = feeds.find(feedid); + if (feeds.end() != it) + { + return FALSE; + } + + //std::pair<std::wstring, std::wstring> pair(initial_text, description); + + feeds.insert({ feedid, {initial_text, description} }); + + dependent_sendEvent(svc_textFeed::depend_getClassGuid(), Event_TEXTCHANGE, (intptr_t)feedid, (void*)initial_text, wcslen(initial_text) + 1); + return TRUE; +} + +int TextFeed::sendFeed(const wchar_t *feedid, const wchar_t *text) +{ + //Pair <StringW, StringW> ft(L"", L""); + //if (!feeds.getItem(StringW(feedid), &ft)) + //{ + // //CUT ASSERTALWAYS("hey, you're trying to send a feed you didn't register. stop it."); + // DebugString("TextFeed::sendFeed(), feedid '%s' not registered", feedid); + // return FALSE; + //} + auto it = feeds.find(feedid); + if (feeds.end() == it) + { + return FALSE; + } + + //StringW id(feedid); + //feeds.getItem(id, &ft); + //ft.a = StringW(text); + //feeds.setItem(StringW(feedid), ft); + + auto &ft = feeds[feedid]; + ft.first = text; + + dependent_sendEvent(svc_textFeed::depend_getClassGuid(), Event_TEXTCHANGE, (intptr_t)feedid, (void*)text, wcslen(text) + 1); + return TRUE; +} + +const wchar_t *TextFeed::getFeedText(const wchar_t *name) +{ + //const Pair<StringW, StringW> *ft = feeds.getItemRef(StringW(name)); + //if (ft == NULL) + // return NULL; + //ft->a.getValue(); + + auto it = feeds.find(name); + if (it == feeds.end()) + { + return NULL; + } + auto& ft = it->second; + return ft.first.c_str(); +} + +const wchar_t *TextFeed::getFeedDescription(const wchar_t *name) +{ + //const Pair<StringW, StringW> *ft = feeds.getItemRef(StringW(name)); + //if (ft == NULL) return NULL; + //return ft->b.getValue(); + + auto it = feeds.find(name); + if (it == feeds.end()) + { + return NULL; + } + + auto& ft = it->second; + return ft.second.c_str(); +} + +int TextFeed::hasFeed(const wchar_t *name) +{ + return feeds.count(name); +} + +void TextFeed::dependent_onRegViewer(api_dependentviewer *viewer, int add) +{ + if (add) + { + //for (int i = 0; i < feeds.getNumItems(); i++) + //{ + // StringW a = feeds.enumIndexByPos(i, StringW(L"")); + // Pair<StringW, StringW> sp(L"", L""); + // StringW b = feeds.enumItemByPos(i, sp).a; + // dependent_sendEvent(svc_textFeed::depend_getClassGuid(), Event_TEXTCHANGE, (intptr_t)a.getValue(), (void*)b.getValue(), b.len() + 1, viewer); //send to this viewer only + //} + + for (auto it = feeds.begin(); it != feeds.end(); it++) + { + std::wstring key = it->first; + auto val = it->second; + std::wstring val_first = val.first; + dependent_sendEvent(svc_textFeed::depend_getClassGuid(), Event_TEXTCHANGE, (intptr_t)key.c_str(), (void*)val_first.c_str(), wcslen(val_first.c_str()) + 1, viewer); //send to this viewer only + } + } + + if (add) onRegClient(); + else onDeregClient(); +} + +void *TextFeed::dependent_getInterface(const GUID *classguid) +{ + HANDLEGETINTERFACE(svc_textFeed); + return NULL; +} diff --git a/Src/Wasabi/api/skin/feeds/textfeed.h b/Src/Wasabi/api/skin/feeds/textfeed.h new file mode 100644 index 00000000..1c2d9bc1 --- /dev/null +++ b/Src/Wasabi/api/skin/feeds/textfeed.h @@ -0,0 +1,57 @@ +#ifndef _TEXTFEED_H +#define _TEXTFEED_H + +#include <bfc/common.h> +#include <map> +#include <string> +#include <utility> +#include <bfc/depend.h> +#include <api/service/svcs/svc_textfeed.h> +#include <api/syscb/callbacks/corecbi.h> + +/** + This is the standard helper class for implementing a textfeed. + Be sure to check out class EzFeed in ezfeed.h, which combines this + class with a service factory. +*/ +class TextFeed : public svc_textFeedI, public DependentI +{ +public: +/** + Call this to register your feeds by id. Make the ids unique! + @see sendFeed() + @ret TRUE if succeeded, FALSE on error (i.e. nonunique id) +*/ + int registerFeed(const wchar_t *feedid, const wchar_t *initial_text=L"", const wchar_t *description=L""); + +/** + Call this to send text into a feed. + @see registerFeed() + @ret TRUE if succeeded, FALSE on error (i.e. feedid not registered) +*/ + int sendFeed(const wchar_t *feedid, const wchar_t *text); + +// Gives the most recently sent text on a feed. + virtual const wchar_t *getFeedText(const wchar_t *feedid); + +// Gives a description for the feed (used by accessibility). + virtual const wchar_t *getFeedDescription(const wchar_t *feedid); + +protected: + virtual api_dependent *getDependencyPtr() { return this; } + virtual void dependent_onRegViewer(api_dependentviewer *viewer, int add); + virtual void *dependent_getInterface(const GUID *classguid); + +/** + Called when someone subscribes to this feed. +*/ + virtual void onRegClient() { } + virtual void onDeregClient() { } + + virtual int hasFeed(const wchar_t *name); + +private: + std::map<std::wstring, std::pair<std::wstring, std::wstring> > feeds; +}; + +#endif diff --git a/Src/Wasabi/api/skin/feeds/textfeedcb.cpp b/Src/Wasabi/api/skin/feeds/textfeedcb.cpp new file mode 100644 index 00000000..61542fb3 --- /dev/null +++ b/Src/Wasabi/api/skin/feeds/textfeedcb.cpp @@ -0,0 +1,9 @@ +#include "precomp.h" +#if 0//CUT +#include "textfeedcb.h" + +#define CBCLASS TextFeedCallbackI +START_DISPATCH; + VCB(TEXTFEEDCB_ONRECEIVETEXT, textfeed_onReceiveText); +END_DISPATCH; +#endif diff --git a/Src/Wasabi/api/skin/feeds/textfeedcb.h b/Src/Wasabi/api/skin/feeds/textfeedcb.h new file mode 100644 index 00000000..da8d804a --- /dev/null +++ b/Src/Wasabi/api/skin/feeds/textfeedcb.h @@ -0,0 +1,34 @@ +#error this file is going away +#if 0 +#ifndef __TEXTFEEDCB_H +#define __TEXTFEEDCB_H + +#include "dispatch.h" +#include "../common/common.h" + +class TextFeedCallback : public Dispatchable { + public: + + void textfeed_onReceiveText(const wchar_t *text); + + enum { + TEXTFEEDCB_ONRECEIVETEXT = 10, + }; +}; + +inline void TextFeedCallback::textfeed_onReceiveText(const wchar_t *text) { + _voidcall(TEXTFEEDCB_ONRECEIVETEXT, text); +} + +class TextFeedCallbackI : public TextFeedCallback { + public: + TextFeedCallbackI() {} + virtual ~TextFeedCallbackI() {} + + virtual void textfeed_onReceiveText(const wchar_t *text)=0; + + protected: + RECVS_DISPATCH; +}; +#endif +#endif diff --git a/Src/Wasabi/api/skin/gammamgr.cpp b/Src/Wasabi/api/skin/gammamgr.cpp new file mode 100644 index 00000000..9df1c88e --- /dev/null +++ b/Src/Wasabi/api/skin/gammamgr.cpp @@ -0,0 +1,135 @@ +#include <precomp.h> +#include <api.h> +#include "gammamgr.h" +#include <api/service/servicei.h> +#include <api/skin/skinelem.h> +#include <api/syscb/callbacks/skincb.h> + + + +void GammaMgr::init() +{ + skinXML.registerCallback(L"WinampAbstractionLayer\fgammaset", &xmlreader); //back compat + skinXML.registerCallback(L"WinampAbstractionLayer\fgammaset\fgammagroup", &xmlreader); //back compat + skinXML.registerCallback(L"WasabiXML\fgammaset", &xmlreader); + skinXML.registerCallback(L"WasabiXML\fgammaset\fgammagroup", &xmlreader); + + curset = -1; +} + +void GammaMgr::deinit() +{ + WASABI_API_COLORTHEMES->deleteAllGammaSets(); + skinXML.unregisterCallback(&xmlreader); +} + +void GammaMgr::onBeforeLoadingGammaGroups() +{ + WASABI_API_COLORTHEMES->deleteAllGammaSets(); + curset = -1; +} + +void GammaMgr::onAfterLoadingGammaGroups() +{} + +void GammaMgr::loadDefault() +{ + WASABI_API_COLORTHEMES->StartTransaction(); +#ifdef ON_LOAD_EXTRA_COLORTHEMES + ON_LOAD_EXTRA_COLORTHEMES(); +#endif + WASABI_API_COLORTHEMES->EndTransaction(); + + if (WASABI_API_COLORTHEMES->getGammaSet() == NULL) + { + wchar_t txt[256] = {0}; + WASABI_API_CONFIG->getStringPrivate(StringPrintfW(L"Color Themes/%s", WASABI_API_SKIN->getSkinName()), txt, 256, L"Default"); + WASABI_API_COLORTHEMES->setGammaSet(txt); + } +} + +int GammaMgr::gammaEqual(const wchar_t *id1, const wchar_t *id2) +{ + const wchar_t *a = WASABI_API_PALETTE->getGammaGroupFromId(id1); + const wchar_t *b = WASABI_API_PALETTE->getGammaGroupFromId(id2); + if (!a || !b) return 1; + return !WCSICMP(a, b); +} + +void GammaMgrXmlReader::xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params) +{ + GammaMgr::xmlReaderOnStartElementCallback(xmltag, params); +} + +void GammaMgr::xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params) +{ + if (!WCSICMP(xmltag, L"gammaset")) + { + const wchar_t *id = params->getItemValue(L"id"); + WASABI_API_COLORTHEMES->resetGammaSet(id); + curset = WASABI_API_COLORTHEMES->newGammaSet(id); + } + else if (!WCSICMP(xmltag, L"gammagroup")) + { + const wchar_t *id = params->getItemValue(L"id"); + if (!id) // TODO: should we pop up a skin error msgbox? + return; + StringW value = params->getItemValue(L"value"); + int r = 0, g = 0, b = 0; + wchar_t *p = value.getNonConstVal(); + if (!p) // TODO: should we pop up a skin error msgbox? + return; + wchar_t *q = p; + while (q && *q && *q != ',') q++; + if (q && *q == ',') *q++ = 0; + r = WTOI(p); + if (*q) + { + p = q; + while (*q && *q != ',') q++; + if (*q == ',') *q++ = 0; + g = WTOI(p); + if (*q) b = WTOI(q); + } + + int makegray = params->getItemValueInt(L"gray"); + int boost = params->getItemValueInt(L"boost"); + if (!WCSICMP(id, L"General") && curset>=0) + { + ColorThemeGroup *generalgroup = WASABI_API_COLORTHEMES->enumColorThemeGroup(curset, -1); + if (generalgroup) + { + generalgroup->setRed(r); + generalgroup->setGreen(g); + generalgroup->setBlue(b); + generalgroup->setGray(makegray); + generalgroup->setBoost(boost); + } + } + else if (curset != -1) + { + ColorThemeGroupI new_group(id, r, g, b, makegray, boost); + WASABI_API_COLORTHEMES->addGammaGroup(curset, &new_group); + } + } + +} + +GammaMgrXmlReader GammaMgr::xmlreader; +int GammaMgr::curset; + +#define CBCLASS ColorThemeGroupI +START_DISPATCH; +CB(COLORTHEMEGROUPGETNAME, getName); +CB(COLORTHEMEGROUPGETRED, getRed); +CB(COLORTHEMEGROUPGETGREEN, getGreen); +CB(COLORTHEMEGROUPGETBLUE, getBlue); +CB(COLORTHEMEGROUPGETGRAY, getGray); +CB(COLORTHEMEGROUPGETBOOST, getBoost); +VCB(COLORTHEMEGROUPSETNAME, setName); +VCB(COLORTHEMEGROUPSETRED, setRed); +VCB(COLORTHEMEGROUPSETGREEN, setGreen); +VCB(COLORTHEMEGROUPSETBLUE, setBlue); +VCB(COLORTHEMEGROUPSETGRAY, setGray); +VCB(COLORTHEMEGROUPSETBOOST, setBoost); +END_DISPATCH;
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/gammamgr.h b/Src/Wasabi/api/skin/gammamgr.h new file mode 100644 index 00000000..1d09319e --- /dev/null +++ b/Src/Wasabi/api/skin/gammamgr.h @@ -0,0 +1,91 @@ +#ifndef _GAMMAMGR_H +#define _GAMMAMGR_H + +#include <api/xml/xmlreader.h> +#include <api/service/svcs/svc_skinfilter.h> + +#include <bfc/string/StringW.h> +#include <api/skin/colorthemes.h> + + +class ColorThemeGroupI : public ColorThemeGroup +{ +public: + ColorThemeGroupI(const wchar_t *pname, int pred, int pgreen, int pblue, int pgray, int pboost) + : name(pname), red(pred), green(pgreen), blue(pblue), make_grayscale(pgray), boost_levels(pboost) { } + ColorThemeGroupI(ColorThemeGroup ©_group) + { + name = copy_group.getName(); + red = copy_group.getRed(); + green = copy_group.getGreen(); + blue = copy_group.getBlue(); + make_grayscale = copy_group.getGray(); + boost_levels = copy_group.getBoost(); + } + virtual const wchar_t *getName() { return name; } + virtual int getRed() { return red; } + virtual int getGreen() { return green; } + virtual int getBlue() { return blue; } + virtual int getGray() { return make_grayscale; } + virtual int getBoost() { return boost_levels; } + virtual void setName(const wchar_t *pname) { name = pname; } + virtual void setRed(int r) { red = r; } + virtual void setGreen(int g) { green = g; } + virtual void setBlue(int b) { blue = b; } + virtual void setGray(int g) { make_grayscale = g; } + virtual void setBoost(int b) { boost_levels = b; } + + protected: + RECVS_DISPATCH; + + StringW name; + int red; + int green; + int blue; + int make_grayscale; + int boost_levels; +}; + + + + +class GammaMgrXmlReader : public XmlReaderCallbackI +{ +public: + void xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params); +}; + +class GammaMgr +{ +public: + static void init(); + static void deinit(); + + static void onBeforeLoadingGammaGroups(); + static void onAfterLoadingGammaGroups(); + static int gammaEqual(const wchar_t *id1, const wchar_t *id2); + + static void xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params); + + static int filterBitmap(uint8_t *bits, int w, int h, int bpp, const wchar_t *element_id, const wchar_t *forcegroup=NULL); + static ARGB32 filterColor(ARGB32 color, const wchar_t *element_id, const wchar_t *forcegroup=NULL); +/* + static void setGammaSet(const wchar_t *set); + static int getNumGammaSets(); + static const wchar_t *enumGammaSet(int n); + static int getNumGammaGroups(const wchar_t *gammaset); + static const wchar_t *enumGammaGroup(const wchar_t *gammaset, int n); + static ColorThemeGroup *enumColorThemeGroup(int colorset, int colorgroup); + static ColorThemeGroup *getColorThemeGroup(const wchar_t *colorset, const wchar_t *colorgroup); + static void newGammaSet(const wchar_t *set); + static void updateGammaSet(const wchar_t *set); + static void renameGammaSet(const wchar_t *set, const wchar_t *newname); + static void deleteGammaSet(const wchar_t *set);*/ + static void loadDefault(); + +private: + static void onGammaSet(); + static GammaMgrXmlReader xmlreader; + static int curset; // current while parsing xml +}; +#endif diff --git a/Src/Wasabi/api/skin/group.h b/Src/Wasabi/api/skin/group.h new file mode 100644 index 00000000..e4a9ad5f --- /dev/null +++ b/Src/Wasabi/api/skin/group.h @@ -0,0 +1,366 @@ +#include "widgets/group.h" +#if 0 // not in use +#ifndef __GROUP_H +#define __GROUP_H + +#ifndef _NOSTUDIO + +class Group; +class Container; +class Layout; +class CfgItem; +class CfgGroup; +class SRegion; + +#include <bfc/tlist.h> +#include <bfc/depview.h> +#include <api/wnd/wndclass/embeddedxui.h> +#include <api/wnd/wndclass/clickwnd.h> +#include <api/wnd/wndclass/buttwnd.h> +#include <tataki/bitmap/bitmap.h> +#include <tataki/region/region.h> +#ifdef WASABI_COMPILE_CONFIG +#include <api/config/items/cfgitem.h> +#endif // wasabi_compile_config + +#include <api/wndmgr/container.h> + +#endif // _nostudio + +#include <api/script/script.h> +#include <api/script/scriptobj.h> +#ifdef WASABI_WIDGETS_GUIOBJECT +#include <api/script/objects/guiobj.h> +#endif +// {80F0F8BD-1BA5-42a6-A093-3236A00C8D4A} +static const GUID cfgGroupGuid = +{ 0x80f0f8bd, 0x1ba5, 0x42a6, { 0xa0, 0x93, 0x32, 0x36, 0xa0, 0xc, 0x8d, 0x4a } }; + +#define RESIZE_MINW 96 +#define RESIZE_MINH 24 + +class XmlObject; + +class GroupScriptController : public GuiObjectScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + 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(); + virtual ScriptObject *cast(ScriptObject *, GUID g); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern GroupScriptController *groupController; + +class XuiParam { + public: + XuiParam(const wchar_t *_param, const wchar_t *_value) : param(_param), value(_value) {} + virtual ~XuiParam() {} + StringW param; + StringW value; +}; + +#define GROUP_PARENT EmbeddedXuiObject + +class Group : public GROUP_PARENT { + +public: + Group(); + virtual ~Group(); + + int onPaint(Canvas *canvas); + + virtual int onResize(); + virtual int onPostedMove(); + virtual int onInit(); + virtual Container *getParentContainer(); + virtual int childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2); + + virtual void setBaseTexture(const wchar_t *b, int regis=1); + virtual SkinBitmap *getBaseTexture(); + virtual ifc_window *getBaseTextureWindow(); + + virtual int setXmlParam(const wchar_t *paramname, const wchar_t *strvalue); + virtual int setXuiParam(int _xuihandle, int xuiid, const wchar_t *paramname, const wchar_t *strvalue); + virtual api_region *getRegion(); + virtual void setRegion(api_region *r); + void reloadDefaults(); + virtual int onGroupChange(const wchar_t *id); + virtual void autoResize(); + virtual void startScripts(); + + void onCreateObject(GuiObject *o); + GuiObject *getObject(const wchar_t *id); + + void sendNotifyToAllChildren(int notifymsg, int param1, int param2); + + int isDeleting() { return deleting; } + + void updatePos(GuiObject *o, RECT *r=NULL); + + AutoSkinBitmap *background; + int x, y; + + LPARAM wndHolder_getParentParam(int i=0); + + virtual void setDesignWidth(int w); + virtual void setDesignHeight(int h); + virtual int getDesignWidth(); + virtual int getDesignHeight(); + + virtual void invalidateWindowRegion(); + virtual void setRegionOp(int o); + virtual void setGroupContent(const wchar_t *id, SkinItem *specific_item, int scripts_enabled); + virtual const wchar_t *getGroupContentId(); + virtual SkinItem *getGroupContentSkinItem(); + virtual void setAutoWidthSource(const wchar_t *obj); + virtual void setAutoHeightSource(const wchar_t *obj); + + virtual void cancelCapture() {}; + virtual int getPreferences(int what); + + virtual const wchar_t *vcpu_getClassName(); + virtual ScriptObjectController *vcpu_getController() { return groupController; } + + int getNumObjects(); + ifc_window *enumObjects(int i); + + void addChild(GuiObject *g); + void removeChild(GuiObject *g); + +#ifdef WASABI_COMPILE_WNDMGR + virtual void mouseResize(int x, int y, int resizeway);// screen coords! + virtual void beginMove(); + virtual void beginScale(); + virtual void beginResize(); + virtual void endMove(); + virtual void endScale(); + virtual void endResize(); +#endif + + virtual int getAutoWidth(void); + virtual int getAutoHeight(void); + + virtual int isLayout(); + + void setDrawBackground(int t); + int getDrawBackground(void); + +#ifdef WASABI_COMPILE_CONFIG + static int isCfgGroup(Group *ptr); +#endif + + void addScript(int scriptid); + void deleteScripts(); + int enumScript(int n); + int getNumScripts(); + virtual int isDesktopAlphaSafe(); + virtual int isTransparencySafe(int excludeme=0); + + static int isGroup(Group *o); + const wchar_t *getBackgroundStr(); + int getWidthBasedOn(GuiObject *o=NULL); + int getHeightBasedOn(GuiObject *o=NULL); + + void fixPosition(); + + const wchar_t *embeddedxui_getEmbeddedObjectId() { return xui_embedded_id; } + virtual void onFillGroup(); + virtual int onUnknownXuiParam(const wchar_t *xmlattributename, const wchar_t *value); + + virtual ScriptObject *script_cast(GUID g); + + virtual void onMinMaxEnforcerChanged(); + virtual int isTransparencyForcedOff() { return 0; } + +protected: + static PtrList<CfgGroup> cfggrouplist; + +private: + StringW basetextureStr; + StringW xui_embedded_id; + + void invalidateScaledReg(); + void ensureScaledRegValid(); + + int resizing; + int size_w,size_h; + int cX,cY; + int captured; + POINT mousepos; + int propagatesize; + + PtrList<XuiParam> xuiparams; + + int moving; + int mover; + int drawbackground; + RECT oldRect; + int groupmaxheight; + int groupmaxwidth; + int groupminheight; + int groupminwidth; + int lockminmax; +// int regionop; + TList<int> scripts; + RegionI *subtractedreg; + static PtrList<Group> groups; + StringW backgroundstr; + StringW instanceid; + RegionI *reg; + RegionI *scaledreg; + int scaledregionvalid; + int autoregionop; + StringW content_id; + SkinItem *content_item; + int no_init_on_addchild; + StringW autoheightsource; + StringW autowidthsource; + GuiObject *lastheightsource; + GuiObject *lastwidthsource; + int lastgetwidthbasedon, lastgetheightbasedon; + + int default_w, default_h; + int design_w, design_h; + int scripts_enabled; + int xuihandle; + static XMLParamPair groupParams[]; +protected: + enum { + XUIGROUP_INSTANCEID=0, + XUIGROUP_BACKGROUND, + XUIGROUP_DRAWBACKGROUND, + XUIGROUP_DEFAULT_W, + XUIGROUP_DEFAULT_H, + XUIGROUP_MAXIMUM_H, + XUIGROUP_MAXIMUM_W, + XUIGROUP_MINIMUM_H, + XUIGROUP_MINIMUM_W, + XUIGROUP_PROPAGATESIZE, + XUIGROUP_LOCKMINMAX, + XUIGROUP_NAME, + XUIGROUP_AUTOWIDTHSOURCE, + XUIGROUP_AUTOHEIGHTSOURCE, + XUIGROUP_EMBED_XUI, + XUIGROUP_XUITAG, + XUIGROUP_INHERIT_GROUP, + XUIGROUP_INHERIT_CONTENT, + XUIGROUP_DESIGN_W, + XUIGROUP_DESIGN_H, + XUIGROUP_NUMPARAMS, + }; + +// FG> +// -- SCRIPT ----------------------------------------------------- +private: + PtrList<ScriptObject> script_objects; + PtrList<GuiObject> gui_objects; + int deleting; + int skinpart; + int alpha; + int disable_update_pos; + +public: + void addObject(GuiObject *o); + void removeObject(GuiObject *o); + void setSkinPartId(int i) { skinpart = i; } + int getSkinPartId() { return skinpart; } + + static scriptVar script_vcpu_getObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj); + static scriptVar script_vcpu_getNumObjects(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_enumObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i); + static scriptVar script_vcpu_onCreateObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar ob); + static scriptVar script_vcpu_getMousePosX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_getMousePosY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_subtractRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg); + static scriptVar script_vcpu_isLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_autoResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + + static void instantiate(Layout *l); + +}; + +extern const wchar_t groupXuiObjectStr[]; +extern char groupXuiSvcName[]; +class GroupXuiSvc : public XuiObjectSvc<Group, groupXuiObjectStr, groupXuiSvcName> {}; + + +#ifdef WASABI_COMPILE_CONFIG + +class CfgGroupScriptController : 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(); + + private: + + static function_descriptor_struct exportedFunction[]; +}; + +extern CfgGroupScriptController *cfgGroupController; + +class CfgGroup : public Group, public DependentViewerTPtr<CfgItem> { + public: + + CfgGroup(); + virtual ~CfgGroup(); + + void setAttr(CfgItem *item, const wchar_t *name); + const wchar_t *vcpu_getClassName(); + virtual ScriptObjectController *vcpu_getController() { return cfgGroupController; } + + virtual int viewer_onEvent(CfgItem *item, int event, intptr_t param, void *ptr, size_t ptrlen); + virtual void dataChanged(); + + CfgItem *getCfgItem(); + const wchar_t *getAttributeName(); + const wchar_t *getCfgGuid() { return cfgguid; } + virtual int onInit(); + + static scriptVar script_vcpu_cfgGetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_cfgSetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v); + static scriptVar script_vcpu_cfgGetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_cfgSetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v); + static scriptVar script_vcpu_cfgGetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_cfgSetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v); + static scriptVar script_vcpu_cfgGetName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_cfgGetGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_onCfgChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + + private: + + CfgItem *cfgitem; + StringW attrname; + StringW cfgguid; + static wchar_t txt[512]; +}; + +extern const wchar_t cfgGroupXuiObjectStr[]; +extern char cfgGroupXuiSvcName[]; +class CfgGroupXuiSvc : public XuiObjectSvc<CfgGroup, cfgGroupXuiObjectStr, cfgGroupXuiSvcName> {}; + +#endif // wasabi_compile_config + + +#endif // group.h +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/groupmgr.cpp b/Src/Wasabi/api/skin/groupmgr.cpp new file mode 100644 index 00000000..dea7672c --- /dev/null +++ b/Src/Wasabi/api/skin/groupmgr.cpp @@ -0,0 +1,51 @@ +#include <precomp.h> +#include <api/skin/groupmgr.h> +#include <api/skin/skinparse.h> +#include <api/skin/guitree.h> +#include <api/config/items/attrint.h> +#include <api/config/items/cfgitem.h> + +Group *GroupMgr::instantiate(const wchar_t *groupid, int grouptype, SkinItem *specific_item, int scripts_enabled) +{ + InCriticalSection in_cs(&cs_grp); + GuiObject *go = SkinParser::newDynamicGroup(groupid, grouptype, specific_item, 0, scripts_enabled); + Group *g = static_cast<Group *>(go->guiobject_getScriptObject()->vcpu_getInterface(groupGuid)); + if (!g) return NULL; + grouplist.addItem(g); + return g; +} + +#ifdef WASABI_COMPILE_CONFIG + +Group *GroupMgr::instantiate(const wchar_t *groupid, CfgItem *i, const wchar_t *name, int scripts_enabled) { + InCriticalSection in_cs(&cs_grp); + CfgGroup *g = static_cast<CfgGroup *>(instantiate(groupid, GROUP_CFGGROUP, NULL, scripts_enabled)); + ASSERTPR(g != NULL, StringPrintf("couldn't load groupid '%S'", groupid)); + g->setAttr(i, name); + grouplist.addItem(g); + return g; +} + +#endif + +int GroupMgr::destroy(Group *group) { + InCriticalSection in_cs(&cs_grp); + if (!grouplist.haveItem(group)) { + DebugStringW(L"you cannot destroy a group that you have not instatiated\n"); + return 0; + } + delete group; + grouplist.removeItem(group); + return 1; +} + +int GroupMgr::exists(const wchar_t *groupid) +{ + SkinItem *si = guiTree->getGroupDef(groupid); + if (si) return 1; + return 0; +} + + +PtrList<Group> GroupMgr::grouplist; +CriticalSection GroupMgr::cs_grp; diff --git a/Src/Wasabi/api/skin/groupmgr.h b/Src/Wasabi/api/skin/groupmgr.h new file mode 100644 index 00000000..4e4457ca --- /dev/null +++ b/Src/Wasabi/api/skin/groupmgr.h @@ -0,0 +1,42 @@ +#ifndef __GROUPMGR_H +#define __GROUPMGR_H + +#include <bfc/ptrlist.h> +#include <bfc/string/bfcstring.h> +#include <api/skin/skinparse.h> +#include <bfc/critsec.h> + +class Group; +class CfgItem; + +class ifc_window; +class SkinItem; + +class CfgGroupEntry +{ + public: + CfgGroupEntry(const wchar_t *_id, int _type) : id(_id), type(_type) {} + ~CfgGroupEntry() {} + + StringW id; + int type; +}; + +class GroupMgr +{ + public: + static Group *instantiate(const wchar_t *groupid, int grouptype=GROUP_GROUP, SkinItem *specific_item=NULL, int scripts_enabled=1); +#ifdef WASABI_COMPILE_CONFIG + static Group *instantiate(const wchar_t *groupid, CfgItem *i, const wchar_t *name, int scripts_enabled); +#endif + static int destroy(Group *group); + static int hasGroup(Group *g) { return grouplist.haveItem(g); } + static int getNumGroups() { return grouplist.getNumItems(); } + static int exists(const wchar_t *groupid); + + private: + static PtrList<Group> grouplist; + static CriticalSection cs_grp; +}; + +#endif diff --git a/Src/Wasabi/api/skin/groupwndcreate.cpp b/Src/Wasabi/api/skin/groupwndcreate.cpp new file mode 100644 index 00000000..adf5daa6 --- /dev/null +++ b/Src/Wasabi/api/skin/groupwndcreate.cpp @@ -0,0 +1,51 @@ +#include <precomp.h> + +#include "groupwndcreate.h" + +#include <api/skin/guitree.h> +#include <api/skin/groupmgr.h> + +// 5/15/2002, removed serving of groups by guid xui param, guid is 'non-overriden window guaranteed', groupid is 'allow override implicitly' + +/*int GroupWndCreateSvc::testGuid(GUID g) { + return (GuiTree::getGroupDef(g) >= 0); +} + +api_window *GroupWndCreateSvc::createWindowByGuid(GUID g, api_window *parent) { + int n = GuiTree::getGroupDef(g); + if (n < 0) return NULL; + + return createGuiTreeItem(n, parent); +}*/ + +ifc_window *GroupWndCreateSvc::createWindowOfType(const wchar_t *windowtype, ifc_window *parent, int i) +{ + SkinItem *item = guiTree->enumGroupDefOfType(windowtype, i); + if (item == NULL) return NULL; + + return createGuiTreeItem(item, parent); +} + +ifc_window *GroupWndCreateSvc::createGuiTreeItem(SkinItem*item, ifc_window *parent) +{ + ifc_window *wnd = GroupMgr::instantiate(NULL, GROUP_GROUP, item); + if (!wnd) return NULL; + wnd->setParent(parent); + group_list.addItem(wnd); + num_group_list = group_list.getNumItems(); + return wnd; +} + +int GroupWndCreateSvc::destroyWindow(ifc_window *w) +{ + if (group_list.haveItem(w)) + { + group_list.removeItem(w); + WASABI_API_SKIN->group_destroy(w); + num_group_list = group_list.getNumItems(); + return 1; + } + return 0; +} + +int GroupWndCreateSvc::num_group_list = 0; diff --git a/Src/Wasabi/api/skin/groupwndcreate.h b/Src/Wasabi/api/skin/groupwndcreate.h new file mode 100644 index 00000000..c142e2c4 --- /dev/null +++ b/Src/Wasabi/api/skin/groupwndcreate.h @@ -0,0 +1,25 @@ +#ifndef __WNDCREATE_H +#define __WNDCREATE_H + +#include <api/service/svcs/svc_wndcreate.h> +#include <bfc/ptrlist.h> + +class GroupWndCreateSvc : public svc_windowCreateI +{ +public: + static const char *getServiceName() { return "WindowType to Group window creator"; } + + virtual int testType(const wchar_t *windowtype) { return 1; } + // virtual int testGuid(GUID g) ; + // virtual ifc_window *createWindowByGuid(GUID g, ifc_window *parent); + virtual ifc_window *createWindowOfType(const wchar_t *windowtype, ifc_window *parent, int n); + virtual int destroyWindow(ifc_window *w); + + static int num_group_list; + +private: + ifc_window *createGuiTreeItem(SkinItem *item, ifc_window *parent); + PtrList<ifc_window> group_list; +}; + +#endif diff --git a/Src/Wasabi/api/skin/guitree.cpp b/Src/Wasabi/api/skin/guitree.cpp new file mode 100644 index 00000000..e5196f28 --- /dev/null +++ b/Src/Wasabi/api/skin/guitree.cpp @@ -0,0 +1,379 @@ +#include <precomp.h> +#include "guitree.h" +#include <api/skin/skinparse.h> +#include <api/syscb/callbacks/wndcb.h> +#ifdef WASABI_COMPILE_WNDMGR +#include <api/wndmgr/autopopup.h> +#endif +#include <api/skin/skin.h> +#include <bfc/bfc_assert.h> + +GuiTree *guiTree=NULL; + +GuiTreeItem::GuiTreeItem(int type, const wchar_t *name, ifc_xmlreaderparams *p, int scriptid, const wchar_t *path, GUID g, const wchar_t *windowtype, const wchar_t *xuitag) +{ + if (p) + { + for (size_t i=0;i!=p->getNbItems();i++) + params.addItem(p->getItemName(i), p->getItemValue(i)); + } + object_type = type; + object_name = name; + scriptId = scriptid; + rootpath = path; + guid = g; + idx=-1; + seccount = incrementor++; + wndtype = windowtype; + tag = xuitag; +} + +int GuiTreeItem::incrementor=0; + +GuiTreeItem::~GuiTreeItem() { +} + +int GuiTreeItem::getScriptId() { + return scriptId; +} + +ifc_xmlreaderparams *GuiTreeItem::getParams() +{ + // TODO: benski> helps replicate old logic.. we really fix the parts of the code that are assuming getValue() always succeeds with this returned object + if (params.getNbItems()) + return ¶ms; + else + return 0; +} + +const wchar_t *GuiTreeItem::getXmlRootPath() { + return rootpath; +} + + +int GuiTreeItem::getType() { + return object_type; +} + +const wchar_t *GuiTreeItem::getName() +{ + return object_name; +} + +SkinItem *GuiTreeItem::getAncestor() { + if (object_type == XML_TAG_GROUPDEF) + return guiTree->getGroupDefAncestor(this); + if (object_type == XML_TAG_CONTAINER) + return guiTree->getContainerAncestor(this); + return NULL; +} + +GuiTree::GuiTree() { + cached=-1; + cachedtype=-1; + cached_guid_idx=-1; + cached_guid=INVALID_GUID; + lastdefinedgroupdef = NULL; +} + +GuiTree::~GuiTree() { + list.deleteAll(); + groupdefs.removeAll(); + wndtypes.removeAll(); + //groupdefsbyguid.removeAll(); +} + +void GuiTree::addItem(int object_type, const wchar_t *name, ifc_xmlreaderparams *params, int scriptid, const wchar_t *rootpath) { + cached = -1; + cached_guid_idx = -1; + GUID guid=INVALID_GUID; + const wchar_t *wtype=NULL; + int has_ancestor=0; + const wchar_t *xuitag=NULL; + + const wchar_t *_id = NULL; + if (params) + { + _id = params->getItemValue(L"id"); + xuitag = params->getItemValue(L"xuitag"); +#ifdef WASABI_COMPILE_WNDMGR + if (params->getItemValueInt(L"register_autopopup")) + AutoPopup::registerGroupId(scriptid, _id, params->getItemValue(L"name")); +#endif + const wchar_t *strguid = params->getItemValue(L"guid"); + if (strguid) + guid = nsGUID::fromCharW(strguid); + wtype = params->getItemValue(L"windowtype"); + } + if (object_type == XML_TAG_GROUPDEF && params) + { + has_ancestor = (getGroupDef(_id) != NULL); + } + + GuiTreeItem *item = new GuiTreeItem(object_type, name, params, scriptid, rootpath, guid, wtype, xuitag); + item->setIdx(list.getNumItems()); + list.addItem(item); + + if (object_type == XML_TAG_GROUPDEF && params) { + lastdefinedgroupdef = item; +// groupdefsbyguid.setAutoSort(0); + groupdefs.addItem(item); +// groupdefsbyguid.addItem(item); + if (wtype && *wtype) { + wndtypes.addItem(item); + deferredInvalidateType(wtype); + } + if (xuitag && *xuitag) { + xuigroupdefs.addItem(item); + } + if (has_ancestor) + deferredInvalidateGroup(_id); + } else if (object_type == XML_TAG_CONTAINER && params && (params->getItemValueInt(L"dynamic", 0) == 1)) { + containers_by_id.setAutoSort(0); + containers_by_id.addItem(item); + } +} + +int GuiTree::getNumObject() { + return list.getNumItems(); +} + +int GuiTree::getNumObject(int object_type) { + if (cachedtype == object_type && cached != -1) return cached; + int n=0; + for (int i=0;i<list.getNumItems();i++) { + GuiTreeItem *it = list.enumItem(i); + if (it->getType() == object_type) + n++; + } + cachedtype = object_type; + cached = n; + return n; +} + +SkinItem *GuiTree::getObject(int object_type, int nth) { + int n=0; + for (int i=0;i<list.getNumItems();i++) { + GuiTreeItem *it = list.enumItem(i); + if (it && it->getType() == object_type) { + if (n++ == nth) return it; + } + } + return NULL; +} + +SkinItem *GuiTree::getGroupDef(const wchar_t *id) +{ + return groupdefs.findLastItem(id); +} + +SkinItem *GuiTree::getXuiGroupDef(const wchar_t *xuitag) +{ + xuigroupdefs.sort(); // doesn't sort if not necessary + return xuigroupdefs.findLastItem(xuitag); +} + +SkinItem *GuiTree::getGroupDefAncestor(SkinItem *_item) +{ + //groupdefs.sort(); // doesn't sort if not necessary + int pos = -1; + GuiTreeItem *item = static_cast<GuiTreeItem *>(_item); + if (!item) return NULL; + ASSERT(item->getParams() != NULL); + const wchar_t *iid = item->getParams()->getItemValue(L"id"); + + pos = groupdefs.searchItem(item); + if (pos <= 0) return NULL; + pos--; + + GuiTreeItem *ritem = groupdefs.enumItem(pos); + if (!ritem) return NULL; + ASSERT(ritem->getParams() != NULL); + if (WCSICMP(iid, ritem->getParams()->getItemValue(L"id"))) return NULL; + return ritem; +} + +SkinItem *GuiTree::getContainerAncestor(SkinItem *_item) { + int pos = -1; + GuiTreeItem *item = static_cast<GuiTreeItem *>(_item); + if (!item) return NULL; + ASSERT(item->getParams() != NULL); + const wchar_t *iid = item->getParams()->getItemValue(L"id"); + + pos = containers_by_id.searchItem(item); + + if (pos <= 0) return NULL; + pos--; + + GuiTreeItem *ritem = containers_by_id.enumItem(pos); + if (!ritem) return NULL; + ASSERT(ritem->getParams() != NULL); + if (WCSICMP(iid, ritem->getParams()->getItemValue(L"id"))) return NULL; + return ritem; +} + + +/*int GuiTree::getGroupDef(GUID guid) { + groupdefsbyguid.sort(); // doesn't sort if not necessary + GuiTreeItem *item = groupdefsbyguid.findItem(reinterpret_cast<const char *>(&guid)); + if (item) + return item->getIdx(); + return -1; +}*/ + +SkinItem *GuiTree::enumGroupDefOfType(const wchar_t *type, int n) { + int c = 0; + foreach(wndtypes) + GuiTreeItem *item = wndtypes.getfor(); + if (WCSCASEEQLSAFE(type, item->getWindowType())) { + if (c == n) { +/* if (item->getGuid() != INVALID_GUID) { // see if it has a GUID, in which case we need to instantiate the last overriden version + int n = getGroupDef(item->getGuid()); + if (n != -1) return n; + }*/ + // take its groupid and find its latest overriden version + ifc_xmlreaderparams *p = item->getParams(); + if (p) + { + const wchar_t *id = p->getItemValue(L"id"); + if (id) + { + SkinItem *m = getGroupDef(id); + if (m != NULL) return m; + } + } + return item; + } + c++; + } + endfor; + return NULL; +} + + +int GuiTree::getObjectType(SkinItem *item) { + GuiTreeItem *i = static_cast<GuiTreeItem *>(item); + return i->getType(); +} + +PtrList<GuiTreeItem> *GuiTree::getList() { + return &list; +} + +PtrList<GuiTreeItem> *GuiTree::getGroupList() { + return &groupdefs; +} + +SkinItem *GuiTree::getContainerById(const wchar_t *id) +{ + containers_by_id.sort(); // doesn't sort if not necessary + return containers_by_id.findLastItem(id); +} + +void GuiTree::removeSkinPart(int scriptid) { + for (int i=0;i<list.getNumItems();i++) { + GuiTreeItem *item = list.enumItem(i); + if (item->getScriptId() == scriptid) { + ifc_xmlreaderparams *par = item->getParams(); + if (item->getType() == XML_TAG_CONTAINER && par != NULL) { + int p = containers_by_id.searchItem(item); + if (p != -1) + containers_by_id.removeByPos(p); + } + if (item->getType() == XML_TAG_GROUPDEF && par != NULL) + { + const wchar_t *grpid = par->getItemValue(L"id"); + if (grpid) + { + int p = groupdefs.searchItem(item); + if (p != -1) + groupdefs.removeByPos(p); + p = xuigroupdefs.searchItem(item); + if (p != -1) + xuigroupdefs.removeByPos(p); + p = wndtypes.searchItem(item); + if (p != -1) { + deferredInvalidateType(item->getWindowType()); + wndtypes.removeByPos(p); + } + deferredInvalidateGroup(grpid); + } + } + delete item; + list.removeByPos(i); + i--; + } + } + foreach(list) + list.getfor()->setIdx(foreach_index); + endfor; +} + +void GuiTree::reset() { + list.deleteAll(); + groupdefs.removeAll(); + wndtypes.removeAll(); + xuigroupdefs.removeAll(); + containers_by_id.removeAll(); +} + +void GuiTree::deferredInvalidateGroup(const wchar_t *id) { + if (!Skin::isDynamicGroupReloadEnabled()) return; + if (!id || !*id) return; + StringW *s = new StringW; + s->setValue(id); + + GuiTreeCB *cb = new GuiTreeCB; + cb->cmd = INVALIDATEGRP; + cb->ptr = s; + + timerclient_postDeferredCallback(CB_GUITREE, reinterpret_cast<intptr_t>(cb)); +} + +void GuiTree::deferredInvalidateType(const wchar_t *type) { + if (!Skin::isDynamicGroupReloadEnabled()) return; + StringW *s = new StringW; + s->setValue(type); + + GuiTreeCB *cb = new GuiTreeCB; + cb->cmd = INVALIDATETYPE; + cb->ptr = s; + + timerclient_postDeferredCallback(CB_GUITREE, reinterpret_cast<intptr_t>(cb)); +} + +int GuiTree::timerclient_onDeferredCallback(intptr_t param1, intptr_t param2) +{ + if (param1 == CB_GUITREE) { + GuiTreeCB *c = reinterpret_cast<GuiTreeCB *>(param2); + switch (c->cmd) { + case INVALIDATEGRP: { + StringW *s = reinterpret_cast<StringW *>(c->ptr); + WndInfo wi; + wi.groupid = s->getValue(); + wi.wndtype = NULL; + wi.guid = INVALID_GUID; + WASABI_API_SYSCB->syscb_issueCallback(SysCallback::WINDOW, WndCallback::GROUPCHANGE, reinterpret_cast<intptr_t>(&wi)); + delete s; + break; + } + case INVALIDATETYPE: { + StringW *s = reinterpret_cast<StringW *>(c->ptr); + WndInfo wi; + ZERO(wi); + wi.wndtype = s->getValue(); + wi.guid = INVALID_GUID; + WASABI_API_SYSCB->syscb_issueCallback(SysCallback::WINDOW, WndCallback::TYPECHANGE, reinterpret_cast<intptr_t>(&wi)); + delete s; + break; + } + } + return 1; + } + return GUITREE_PARENT::timerclient_onDeferredCallback(param1, param2); +} + +int GuiTree::getObjectIdx(SkinItem *item) { + if (item == NULL) return -1; + return (static_cast<GuiTreeItem*>(item))->getIdx(); +} diff --git a/Src/Wasabi/api/skin/guitree.h b/Src/Wasabi/api/skin/guitree.h new file mode 100644 index 00000000..cdf74cf0 --- /dev/null +++ b/Src/Wasabi/api/skin/guitree.h @@ -0,0 +1,171 @@ +#ifndef __GUITREE_H +#define __GUITREE_H + +#include <bfc/string/bfcstring.h> +#include <bfc/ptrlist.h> +#include <bfc/nsguid.h> +#include <api/timer/timerclient.h> +#include <api/xml/xmlreader.h> +#include <api/xml/xmlparamsi.h> +#include <api/skin/skinitem.h> +#include <bfc/string/StringW.h> + +#define CB_GUITREE 0x987 + +#define INVALIDATEGRP 1 +#define INVALIDATETYPE 2 + +class GuiTreeCB { + public: + int cmd; + StringW *ptr; +}; + +class GuiTreeItem : public SkinItemI +{ + public: + GuiTreeItem(int type, const wchar_t *name, ifc_xmlreaderparams *p, int scriptid, const wchar_t *rootpath, GUID g, const wchar_t *windowtype, const wchar_t *xuitag); + virtual ~GuiTreeItem(); + virtual int getType(); + virtual const wchar_t *getName(); + virtual int getSkinPartId() { return getScriptId(); } + virtual int getScriptId(); + virtual ifc_xmlreaderparams *getParams(); + virtual const wchar_t *getXmlRootPath(); + virtual void setIdx(int i) { idx = i; } + virtual int getIdx() { return idx; } + virtual int getSecCount() { return seccount; } + virtual void setGuid(GUID g) { guid = g; } + virtual GUID getGuid() { return guid; } + virtual const wchar_t *getWindowType() { return wndtype; } + virtual const wchar_t *getXuiTag() { return tag; } + virtual void setXuiTag(const wchar_t *xuitag) { tag = xuitag; } + virtual SkinItem *getAncestor(); + + private: + XmlReaderParamsI params; + int object_type; + StringW object_name; + int scriptId; + StringW rootpath; + int idx; + int seccount; + GUID guid; + StringW wndtype; + StringW tag; + + static int incrementor; +}; + +class SortGuiTreeItem +{ +public: + static int compareItem(GuiTreeItem *p1, GuiTreeItem *p2) { + int r = WCSICMP(p1->getParams()->getItemValue(L"id"), p2->getParams()->getItemValue(L"id")); + if (!r) { + if (p1->getScriptId() < p2->getScriptId()) return -1; + if (p1->getScriptId() > p2->getScriptId()) return 1; + if (p1->getSecCount() < p2->getSecCount()) return -1; + if (p1->getSecCount() > p2->getSecCount()) return 1; + return 0; + } + return r; + } + static int compareAttrib(const wchar_t *attrib, GuiTreeItem *item) { + return WCSICMP(attrib, item->getParams()->getItemValue(L"id")); + } +}; + +class SortGuiTreeItemByXuiTag { +public: + static int compareItem(GuiTreeItem *p1, GuiTreeItem *p2) { + int r = WCSICMP(p1->getParams()->getItemValue(L"xuitag"), p2->getParams()->getItemValue(L"xuitag")); + if (!r) { + if (p1->getScriptId() < p2->getScriptId()) return -1; + if (p1->getScriptId() > p2->getScriptId()) return 1; + if (p1->getSecCount() < p2->getSecCount()) return -1; + if (p1->getSecCount() > p2->getSecCount()) return 1; + return 0; + } + return r; + } + static int compareAttrib(const wchar_t *attrib, GuiTreeItem *item) { + return WCSICMP(attrib, item->getParams()->getItemValue(L"xuitag")); + } +}; + +class SortGuiTreeItemByGuid +{ +public: + static int compareItem(GuiTreeItem *p1, GuiTreeItem *p2) { + GUID g1 = p1->getGuid(); + GUID g2 = p2->getGuid(); + if (g1 == g2) { + if (p1->getScriptId() < p2->getScriptId()) return -1; + if (p1->getScriptId() > p2->getScriptId()) return 1; + if (p1->getSecCount() < p2->getSecCount()) return -1; + if (p1->getSecCount() > p2->getSecCount()) return 1; + return 0; + } + return nsGUID::compare(g1, g2) < 0 ? -1 : 1; + } + static int compareAttrib(const wchar_t *attrib, GuiTreeItem *item) { + const GUID *g = reinterpret_cast<const GUID *>(attrib); + ASSERT(g); + GUID g1 = *g; + GUID g2 = item->getGuid(); + if (g1 == g2) return 0; + return nsGUID::compare(g1, g2) < 0 ? -1 : 1; + } +}; + +#define GUITREE_PARENT TimerClientDI +class GuiTree : public GUITREE_PARENT { + public: + + GuiTree(); + virtual ~GuiTree(); + + void addItem(int object_type, const wchar_t *object_name, ifc_xmlreaderparams *params, int scriptId, const wchar_t *rootpath); + SkinItem *getGroupDef(const wchar_t *id); + SkinItem *enumGroupDefOfType(const wchar_t *type, int n); + SkinItem *getGroupDefAncestor(SkinItem *item); + SkinItem *getContainerAncestor(SkinItem *item); + //int getGroupDef(GUID g); + SkinItem *getXuiGroupDef(const wchar_t *xuitag); + int getObjectType(SkinItem *item); + int getNumObject(); // total number of objects + int getNumObject(int object_type); // return the number of objects of this type + SkinItem *getObject(int object_type, int nth); // get nth object_type, return its index + SkinItem *getContainerById(const wchar_t *id); + int getObjectIdx(SkinItem *item); + void reset(void); + PtrList<GuiTreeItem> *getList();; + PtrList<GuiTreeItem> *getGroupList();; + void removeSkinPart(int scriptid); + void deferredInvalidateGroup(const wchar_t *id); + void deferredInvalidateType(const wchar_t *type); + int timerclient_onDeferredCallback(intptr_t param1, intptr_t param2); + SkinItem *getLastDefinedGroup() { return lastdefinedgroupdef; } + SkinItem *enumGroupDef(int n) { return groupdefs.enumItem(n); } + int getNumGroupDefs() { return groupdefs.getNumItems(); } + + + private: + int cached; + int cachedtype; + PtrList<GuiTreeItem> list; + PtrListInsertMultiSorted<GuiTreeItem, SortGuiTreeItem> groupdefs; +// PtrListQuickMultiSorted<GuiTreeItem, SortGuiTreeItemByGuid> groupdefsbyguid; + PtrListQuickMultiSorted<GuiTreeItem, SortGuiTreeItemByXuiTag> xuigroupdefs; + PtrListQuickMultiSorted<GuiTreeItem, SortGuiTreeItem> containers_by_id; + PtrList<GuiTreeItem> wndtypes; + int cached_guid_idx; + GUID cached_guid; + SkinItem *lastdefinedgroupdef; +}; + +extern GuiTree *guiTree; + +#endif + diff --git a/Src/Wasabi/api/skin/nakedobject.cpp b/Src/Wasabi/api/skin/nakedobject.cpp new file mode 100644 index 00000000..9e0a3a78 --- /dev/null +++ b/Src/Wasabi/api/skin/nakedobject.cpp @@ -0,0 +1,34 @@ +#include <precomp.h> +#include "nakedobject.h" + +NakedObject::NakedObject() { + reentry_onresize = 0; + reentry_onsetvisible = 0; +} + +int NakedObject::getPreferences(int what) { + return 0; +} + +int NakedObject::onResize() { + int rt = NAKEDOBJECT_PARENT::onResize(); + RECT r; + getClientRect(&r); + if (!reentry_onresize && r.left != r.right || r.top != r.bottom) { + reentry_onresize = 1; + resize(r.left, r.top, 0, 0); + reentry_onresize = 0; + } + return rt; +} + +void NakedObject::onSetVisible(int i) { + NAKEDOBJECT_PARENT::onSetVisible(i); + if (!i) return; + if (!reentry_onsetvisible) { + reentry_onsetvisible = 1; + setVisible(0); + reentry_onsetvisible = 0; + } +} + diff --git a/Src/Wasabi/api/skin/nakedobject.h b/Src/Wasabi/api/skin/nakedobject.h new file mode 100644 index 00000000..ad689533 --- /dev/null +++ b/Src/Wasabi/api/skin/nakedobject.h @@ -0,0 +1,24 @@ +#ifndef __NAKEDOBJECT_H +#define __NAKEDOBJECT_H + +#include <api/wnd/wndclass/guiobjwnd.h> + +// NakedObject, an invisible GuiObject + +#define NAKEDOBJECT_PARENT GuiObjectWnd + +class NakedObject : public GuiObjectWnd { + public: + NakedObject(); + virtual ~NakedObject() {} + + virtual int getPreferences(int what); + virtual int onResize(); + virtual void onSetVisible(int i); + + protected: + int reentry_onresize; + int reentry_onsetvisible; +}; + +#endif diff --git a/Src/Wasabi/api/skin/objectactuator.cpp b/Src/Wasabi/api/skin/objectactuator.cpp new file mode 100644 index 00000000..f9eb1ee1 --- /dev/null +++ b/Src/Wasabi/api/skin/objectactuator.cpp @@ -0,0 +1,106 @@ +#include <precomp.h> +#include "objectactuator.h" +#include <api/console/console.h> +#include <bfc/parse/paramparser.h> +#include <api/script/scriptguid.h> + +XMLParamPair ObjectActuator::params[]= +{ + {OBJECTACTUATOR_GROUP, L"GROUP"}, + {OBJECTACTUATOR_TARGET, L"TARGET"} +}; + +// ----------------------------------------------------------------------- +ObjectActuator::ObjectActuator() +{ + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); +} + +void ObjectActuator::CreateXMLParameters(int master_handle) +{ + //OBJECTACTUATOR_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +// ----------------------------------------------------------------------- +ObjectActuator::~ObjectActuator() { +} + +// ----------------------------------------------------------------------- +int ObjectActuator::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return OBJECTACTUATOR_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) { + case OBJECTACTUATOR_TARGET: + if (actuator_wantTargetParam()) + actuator_setTarget(value); + break; + case OBJECTACTUATOR_GROUP: + if (actuator_wantGroupParam()) + actuator_setGroup(value); + break; + default: + return 0; + } + return 1; +} + +// ----------------------------------------------------------------------- +void ObjectActuator::actuator_setTarget(const wchar_t *value) { + objectsid = value; + if (isInited() && actuator_wantAutoPerform()) + performActions(); +} + +// ----------------------------------------------------------------------- +void ObjectActuator::actuator_setGroup(const wchar_t *value) { + groupid = value; +} + +// ----------------------------------------------------------------------- +int ObjectActuator::onInit() { + int rt = OBJECTACTUATOR_PARENT::onInit(); + + if (actuator_wantAutoPerform()) performActions(); + + return rt; +} + + +// ----------------------------------------------------------------------- +void ObjectActuator::performActions() +{ + ifc_window *group = getParent(); + + if (!groupid.isempty()) + { + GuiObject *o = getGuiObject()->guiobject_findObject(groupid); + if (o != NULL) { + group = o->guiobject_getRootWnd(); + } + } + + GuiObject *go = static_cast<GuiObject *>(group->getInterface(guiObjectGuid)); + if (go == NULL) { + DebugStringW(L"%s:group:%s\n", getActuatorTag(), groupid.getValue()); + return; + } + + ParamParser pp(objectsid); + for (int i=0;i<pp.getNumItems();i++) { + GuiObject *target = go->guiobject_findObject(pp.enumItem(i)); + if (target != NULL) + actuator_onPerform(target); + else + DebugStringW(L"%s:%s/%s\n", getActuatorTag(), groupid.getValue(), objectsid.getValue()); + } +} + +const wchar_t *ObjectActuator::getActuatorTag() { + return L"ObjectActuator"; +} diff --git a/Src/Wasabi/api/skin/objectactuator.h b/Src/Wasabi/api/skin/objectactuator.h new file mode 100644 index 00000000..c5437a1c --- /dev/null +++ b/Src/Wasabi/api/skin/objectactuator.h @@ -0,0 +1,49 @@ +#ifndef __OBJECTACTUATOR_H +#define __OBJECTACTUATOR_H + +#include <api/skin/nakedobject.h> + +#define OBJECTACTUATOR_PARENT NakedObject + +// ----------------------------------------------------------------------- +// Your wnd object class +class ObjectActuator : public OBJECTACTUATOR_PARENT { + + public: + + ObjectActuator(); + virtual ~ObjectActuator(); + + virtual int onInit(); + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + virtual void actuator_setTarget(const wchar_t *value); + virtual void actuator_setGroup(const wchar_t *value); + + virtual int actuator_wantTargetParam() { return 1; } + virtual int actuator_wantGroupParam() { return 1; } + virtual int actuator_wantAutoPerform() { return 1; } + virtual void actuator_onPerform(GuiObject *target) { } // called back n times for n targets found (separated by ';'), guaranteed non NULL + + virtual const wchar_t *getActuatorTag(); // for error msgs purposes + + +protected: + void performActions(); +/*static */void CreateXMLParameters(int master_handle); + private: + static XMLParamPair params[]; + int myxuihandle; + + + enum { + OBJECTACTUATOR_TARGET= 0, + OBJECTACTUATOR_GROUP, + }; + + StringW groupid; + StringW objectsid; +}; + + +#endif diff --git a/Src/Wasabi/api/skin/regioncache.cpp b/Src/Wasabi/api/skin/regioncache.cpp new file mode 100644 index 00000000..68dc58aa --- /dev/null +++ b/Src/Wasabi/api/skin/regioncache.cpp @@ -0,0 +1,32 @@ +#include "precomp.h" +#include "regioncache.h" + + +RegionServer *RegionCache::requestSkinRegion(const wchar_t *filename) +{ + int n = -1; + cache.findItem(filename, &n); + if (n == -1) return NULL; + + RegionCacheItem *el = cache.enumItem(n); +// if (el->region != NULL) el->region->getRegion()->debug(); + return el->region; +} + +void RegionCache::cacheSkinRegion(const wchar_t *filename, api_region *r) +{ + int n = -1; + cache.findItem(filename, &n); + if (n == -1) return; + RegionCacheItem *el = cache.enumItem(n); + ASSERT(el != NULL); + if (el->region != NULL) { + DebugString("Trying to cache a region but cache is already set!\n"); + return; + } + el->region = new CacheRegionServer(r); + //el->region->getRegion()->debug(); +} + + +PtrListQuickSorted<RegionCacheItem, SortRegionCacheItem> RegionCache::cache; diff --git a/Src/Wasabi/api/skin/regioncache.h b/Src/Wasabi/api/skin/regioncache.h new file mode 100644 index 00000000..ea2df961 --- /dev/null +++ b/Src/Wasabi/api/skin/regioncache.h @@ -0,0 +1,53 @@ +#ifndef __REGIONCACHE_H +#define __REGIONCACHE_H + +#include <bfc/string/StringW.h> +#include <tataki/region/region.h> +#include <bfc/ptrlist.h> + +class CacheRegionServer : public RegionServerI { + public: + CacheRegionServer(api_region *r) { + reg = new RegionI(r->getOSHandle()); + } + ~CacheRegionServer() { + delete reg; + } + + virtual api_region *getRegion() { + return reg; + } + + private: + RegionI *reg; +}; + +struct RegionCacheItem { + RegionCacheItem(const wchar_t *filename) : region(NULL) { } + virtual ~RegionCacheItem() { } + StringW filename; + CacheRegionServer *region; +}; + +class SortRegionCacheItem { +public: + static int compareItem(RegionCacheItem *p1, RegionCacheItem *p2) { + return WCSICMP(p1->filename, p2->filename); + } + static int compareAttrib(const wchar_t *attrib, RegionCacheItem *item) { + return WCSICMP(attrib, item->filename); + } +}; + + +class RegionCache { + public: + + static RegionServer *requestSkinRegion(const wchar_t *id); + static void cacheSkinRegion(const wchar_t *id, api_region *r); + + static PtrListQuickSorted<RegionCacheItem, SortRegionCacheItem> cache; + static int getNumCaches() { return cache.getNumItems(); } +}; + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/skin.cpp b/Src/Wasabi/api/skin/skin.cpp new file mode 100644 index 00000000..9348d4c9 --- /dev/null +++ b/Src/Wasabi/api/skin/skin.cpp @@ -0,0 +1,812 @@ +#include <precomp.h> +#include <api.h> +#include "skin.h" +#include <api/skin/skinbmps.h> +#include <tataki/canvas/bltcanvas.h> +#include <api/wnd/basewnd.h> +#include <tataki/bitmap/bitmap.h> +#include <bfc/parse/pathparse.h> +#include <bfc/file/readdir.h> +//#include <api/wac/main.h> // CUT!! +#include <api/skin/skinparse.h> +#include <api/wac/compon.h> + +#ifdef WASABI_COMPILE_WNDMGR +#include <api/wndmgr/skinembed.h> +#endif + +#include <api/script/vcpu.h> +#include <api/skin/skinelem.h> +#include <api/application/wkc.h> +#include <api/skin/gammamgr.h> +#include <api/wnd/wndtrack.h> + +#ifdef WASABI_COMPILE_PAINTSETS +#include <api/wnd/paintset.h> +#endif + +#include <bfc/string/StringW.h> + +#ifdef WIN32 +#include "resource.h" +#include "../Agave/Language/api_language.h" +#endif + +// Version number has now a style of x.yz (same as gen_ff version) +#define SKIN_LEGACY_VERSION 80.f // oldest supported is 0.8 +#define SKIN_VERSION 136.f // current version is 1.36 + +Skin *tha = NULL; + + +static wchar_t *loadSkinList = NULL, skName[64]; + +Skin::Skin() +{ + if (deferedskinset == NULL) + { + deferedskinset = new SkinTimer(); + } + base = NULL; + scaled = NULL; + scale_x = 0; + scale_y = 0; + validRgn = NULL; + resizing = FALSE; +} + +Skin::~Skin() +{ + if (this == tha) + { + delete deferedskinset; + deferedskinset = NULL; + } + delete validRgn; + validRgn = NULL; + delete base; + delete scaled; + if (this == tha) + { + if (loadSkinList) + { + FREE(loadSkinList); + loadSkinList = NULL; + } + } +} + +Skin *Skin::getCurSkin() +{ + return tha; +} + +void Skin::setSkinName(const wchar_t *newskinname, const wchar_t *skinpath) +{ + if (newskinname) + skinName = newskinname; + else + skinName = WASABI_API_LNGSTRINGW_BUF(IDS_NO_SKIN_LOADED_,skName,64); + + if (skinpath == NULL) + { + skinPath = WASABI_API_SKIN->getSkinsPath(); + skinPath.AppendFolder(newskinname); + } + else + { + skinPath = skinpath; + skinPath.AddBackslash(); + } +} + +const wchar_t *Skin::getSkinName() +{ + return skinName.getValue(); +} + +const wchar_t *Skin::getSkinPath() +{ + return skinPath.getValue(); +} + +const wchar_t *Skin::getDefaultSkinPath() +{ + defSkinPath = WASABI_API_SKIN->getSkinsPath(); + defSkinPath.AppendFolder(L"Default"); + return defSkinPath; +} + +void Skin::setBaseTexture(const wchar_t *b) +{ + if (b == NULL) + { + delete base; + base = NULL; + return ; + } + base = new AutoSkinBitmap(); + base->setBitmap(b); +} + +void Skin::rescaleBaseTexture(int w, int h) +{ + /* if (scaled != NULL && scale_x == w && scale_y == h) + return; + if ((resizing && (w > m_x || h > m_y)) || (!resizing && (w != m_x || h != m_y))) + { + delete scaled; + int lw = resizing ? maxw : w; + int lh = resizing ? maxh : h; + scaled = new BltCanvas(lw , lh); + m_x = lw; m_y = lh; + api_region *reg = new api_region(0,0,lw,lh); + scaled->selectClipRgn(reg); + delete reg; + lastw = w; + lasth = h; + } + // Empty valid region + if (validRgn) + validRgn->empty(); + else + validRgn = new api_region(); + scale_x = w; + scale_y = h;*/ +} + +void Skin::invalidateBaseTexture(Skin *s) +{ //FG + if (!s) s = tha; + if (s) s->_invalidateBaseTexture(); +} + +void Skin::invalidateAllBaseTextures() +{ //FG + tha->_invalidateBaseTexture(); + for (int i = 0;i < skinList.getNumItems();i++) + { + Skin *s = skinList.enumItem(i); + s->_invalidateBaseTexture(); + } +} + +void Skin::unloadAllBaseTextures() +{ + if (tha) tha->_unloadBaseTexture(); + for (int i = 0;i < skinList.getNumItems();i++) + { + Skin *s = skinList.enumItem(i); + s->_unloadBaseTexture(); + } +} + +void Skin::reloadAllBaseTextures() +{ + if (tha) tha->_reloadBaseTexture(); + for (int i = 0;i < skinList.getNumItems();i++) + { + Skin *s = skinList.enumItem(i); + s->_reloadBaseTexture(); + } + invalidateAllBaseTextures(); +} + +void Skin::_unloadBaseTexture() +{ + if (base) + base->reset(); +} + +void Skin::_reloadBaseTexture() +{ + if (!tha) return ; + + if (base) + base->reload(); +} + +void Skin::_invalidateBaseTexture(void) +{ //FG + if (validRgn) + validRgn->empty(); +} + +void Skin::registerBaseSkin(Skin *s, ifc_window *b) +{ + skinList.addItem(s); + baseList.addItem(b); +} + +Skin *Skin::unregisterBaseSkin(ifc_window *b) +{ + for (int i = 0;i < baseList.getNumItems();i++) + { + if (baseList.enumItem(i) == b) + { + Skin *s = skinList.enumItem(i); + baseList.delByPos(i); + skinList.delByPos(i); + if (baseList.getNumItems() == 0) + baseList.removeAll(); + if (skinList.getNumItems() == 0) + skinList.removeAll(); + return s; + } + } + return NULL; +} + +Skin *Skin::baseToSkin(ifc_window *b) +{ + if (b == NULL) return NULL; + for (int i = 0;i < baseList.getNumItems();i++) + if (baseList.enumItem(i) == b) + return skinList.enumItem(i); + return NULL; +} + +void Skin::renderBaseTexture(ifc_window *base, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha) +{ + renderBaseTexture(base, baseToSkin(base), c, r, dest, alpha); +} + +void Skin::renderBaseTexture(ifc_window *base, Skin *s, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha) +{ + ASSERT(tha != NULL); + if (!s) + { + DebugStringW(L"Warning, base texture from main wnd?!\n"); + s = tha; + } + + s->_renderBaseTexture(base, c, r, dest, alpha); +} + +void Skin::validateBaseTextureRect(RECT *r) +{ + /* if (!base) { + ASSERT(!(tha && this == tha)); + if (origbase) + base = new SkinBitmap(origbase, origbase->getWidth(), origbase->getHeight()); + else + base = new SkinBitmap(tha->base, tha->base->getWidth(), tha->base->getHeight()); + if (!base) return; + } + + // make a region with the rect we have to draw + api_region *newregion = new api_region(r); + + // check if newregion is enclosed in validRgn, put whatever is outside back into newregion + if (newregion->enclosed(validRgn, newregion)) { + delete newregion; + return; + } + // compute projected coordinates + RECT destRect, srcRect; + newregion->getRgnBox(&destRect); + srcRect.left = (int)(((float)destRect.left / scale_x) * base->getWidth()); + srcRect.right = (int)(((float)destRect.right / scale_x) * base->getWidth()); + srcRect.top = (int)(((float)destRect.top / scale_y) * base->getHeight()); + srcRect.bottom = (int)(((float)destRect.bottom / scale_y) * base->getHeight()); + + // stretch the relevant portion of the image + base->stretchRectToRect(scaled, &srcRect, &destRect); + + #if 0 //FG> debug purpose + HDC dc = GetDC(NULL); + BitBlt(dc, 0, 0, scale_x, scale_y, scaled->getHDC(), 0, 0, SRCCOPY); + ReleaseDC(NULL, dc); + #endif + + // add this region to the valid region + validRgn->add(newregion); + delete newregion;*/ +} + +#define SAFEROUND(d) ((float)(int)d == d) ? (int)d : (d - (float)(int)d > 0) ? ((int)d)+1 : ((int)d)-1 + +// FG> Please change this only if you REALLY know what you are doing. this needs to account for basewnd +// coordinates (start from 0,0), as well as virtualwnd (relative to parent), at any depth (group holding +// texture as 2nd group of the tree, and rendering the base texture in a basewnd in a virtual in the group), +// and should handle resized textures and scaled windows. ooch + +void Skin::_renderBaseTexture(ifc_window *wndbase, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha) +{ + // pick our basetexture + AutoSkinBitmap *b = base ? base : tha->base; + + if (!b) return ; + + // srcRect is the source rectangle in the basetexture + RECT srcRect; + // destProjectedRect is the basetexture rectangle projected to dest coordinates + RECT destProjectedRect; + + ifc_window *p = dest; + POINT pt; + int sx = 0, sy = 0; + while (p && p != wndbase) + { + if (!p->isVirtual()) + { + p->getPosition(&pt); + sx += pt.x; + sy += pt.y; + } + p = p->getParent(); + } + ASSERT(p); + + wndbase->getNonClientRect(&destProjectedRect); + destProjectedRect.left -= sx; + destProjectedRect.top -= sy; + destProjectedRect.right -= sx; + destProjectedRect.bottom -= sy; + + srcRect.left = 0; + srcRect.top = 0; + srcRect.right = b->getBitmap()->getWidth(); + srcRect.bottom = b->getBitmap()->getHeight(); + +#if 0//CUT + // NONPORTABLE + HDC hdc = c->getHDC(); + HRGN oldRgn = CreateRectRgn(0, 0, 0, 0); + HRGN newRgn = CreateRectRgnIndirect(&r); + + int cs = GetClipRgn(hdc, oldRgn); + + ExtSelectClipRgn(hdc, newRgn, (cs != 1) ? RGN_COPY : RGN_AND); + + b->getBitmap()->stretchToRectAlpha(c, &srcRect, &destProjectedRect, alpha); + + SelectClipRgn(hdc, cs ? oldRgn : NULL); + + DeleteObject(oldRgn); + DeleteObject(newRgn); +#endif + BaseCloneCanvas clone(c); + RegionI oldRgn, newRgn(&r); +#ifdef _WIN32 + int cs = clone.getClipRgn(&oldRgn); + if (cs) newRgn.andRegion(&oldRgn); + clone.selectClipRgn(&newRgn); + b->getBitmap()->stretchToRectAlpha(&clone, &srcRect, &destProjectedRect, alpha); + clone.selectClipRgn(cs ? &oldRgn : NULL); +#else +#warning port me + b->getBitmap()->stretchToRectAlpha(&clone, &srcRect, &destProjectedRect, alpha); +#endif +} + +wchar_t *Skin::enumLoadableSkins(int refresh) +{ + static size_t loadSkinListSize = 1024; + + if (loadSkinList) + { + if (!refresh) + return loadSkinList; + FREE(loadSkinList); + } + + loadSkinList = WMALLOC(loadSkinListSize); + loadSkinList[0] = 0; + + int first = 1; + ReadDir skins(L"skins"); + + while (skins.next()) + { + const wchar_t *filename = skins.getFilename(); + + wchar_t *ext = const_cast<wchar_t *>(Wasabi::Std::extension(filename)); + + if (skins.isDir() || !WCSICMP(ext, L"wal") || + !WCSICMP(ext, L"wsz") || !WCSICMP(ext, L"zip")) + { + if (!skins.isDotDir() && !skins.isDotDotDir()) + { + if (!skins.isDir() ) + { + if (ext && *ext) *(ext - 1) = 0; + } + + // check loadSkinList size + if ((wcslen(loadSkinList) + wcslen(filename) + 2) > loadSkinListSize) + { + loadSkinListSize *= 2; + loadSkinList = (wchar_t *)REALLOC(loadSkinList, sizeof(wchar_t) * loadSkinListSize); + } + + if (!first) + wcscat(loadSkinList, L"/"); + wcscat(loadSkinList, filename); + first = 0; + } + } + } + + return loadSkinList; +} + +int Skin::loadSkinPart(const wchar_t *xmlfile) +{ +#ifdef WASABI_COMPILE_COMPONENTS + WasabiKernelController *wkc = Main::getKernelController(); + if (wkc && !wkc->testSkinFile(xmlfile)) return -1; +#endif + + int id = WASABI_API_PALETTE->newSkinPart(); + SkinElementsMgr::onBeforeLoadingScriptElements(xmlfile, id); + SkinParser::loadScriptXml(xmlfile, id); + SkinElementsMgr::onAfterLoadingScriptElements(); +#ifdef WASABI_COMPILE_WNDMGR + SkinParser::startupContainers(id); +#endif + return id; +} + +void Skin::unloadSkinPart(int skinpartid) +{ + SkinElementsMgr::unloadScriptElements(skinpartid); + SkinParser::cleanupScript(skinpartid); +} + +int Skin::checkSkin(const wchar_t *skinname) +{ + OSFILETYPE fh = WFOPEN(StringPathCombine(WASABI_API_SKIN->getSkinPath(), L"skin.xml"), WF_READONLY_BINARY); + if (fh != OPEN_FAILED) + { + FCLOSE(fh); + // ok it's a wa3 skin, now check the skin version number in the xml file + SkinVersionXmlReader r(skinname); + if (!r.getWalVersion()) return CHKSKIN_ISWA3OLD; + #ifndef LC_NUMERIC + #define LC_NUMERIC 4 + #endif + float v = (float)(WTOF(r.getWalVersion()) * 100); // Since wa5.51 we will do a check for x.yz style + if (v < (SKIN_LEGACY_VERSION-0.5f)) return CHKSKIN_ISWA3OLD; + if (v > (SKIN_VERSION+0.5f)) return CHKSKIN_ISWA3FUTURE; + return CHKSKIN_ISWA3; + } + fh = WFOPEN(StringPathCombine(WASABI_API_SKIN->getSkinPath(), L"Main.bmp"), WF_READONLY_BINARY); + if (fh != OPEN_FAILED) + { + FCLOSE(fh); + return CHKSKIN_ISWA2; + } + return CHKSKIN_UNKNOWN; +} + +void Skin::toggleSkin(const wchar_t *skin_name, const wchar_t *skin_path, int deferred) +{ + StringW skinName = skin_name; + + if (sendAbortCallback(skinName)) return ; + + enable_group_reload = 0; + + StringW oldSkinPath = skinPath; + char title[32] = {0}; + setSkinName(skinName, skin_path); + int skinType = checkSkin(skinName); + skinPath = oldSkinPath; + +#ifdef WASABI_COMPILE_COMPONENTS + WasabiKernelController *wkc = Main::getKernelController(); + if (wkc && !wkc->testSkin(skinName)) skinType = CHKSKIN_DISALLOWED; +#endif + + switch (skinType) + { + case CHKSKIN_ISWA3OLD: + { +#ifdef WIN32 + WASABI_API_WND->appdeactivation_setbypass(1); + int ret = MessageBoxA(GetActiveWindow(), WASABI_API_LNGSTRING(IDS_SKIN_LOAD_FORMAT_OLD), + WASABI_API_LNGSTRING_BUF(IDS_SKIN_LOAD_WARNING,title,32), + MB_ICONWARNING | MB_YESNO); + WASABI_API_WND->appdeactivation_setbypass(0); + if (ret == IDNO) return ; +#else + DebugString( "The skin you are trying to load is meant for an older Winamp3 version.\n" ); +#endif + break; + } + case CHKSKIN_ISWA3FUTURE: + { +#ifdef WIN32 + WASABI_API_WND->appdeactivation_setbypass(1); + int ret = MessageBoxA(GetActiveWindow(), WASABI_API_LNGSTRING(IDS_SKIN_LOAD_FORMAT_TOO_RECENT), + WASABI_API_LNGSTRING_BUF(IDS_SKIN_LOAD_WARNING,title,32), + MB_ICONWARNING | MB_YESNO); + WASABI_API_WND->appdeactivation_setbypass(0); + if (ret == IDNO) return ; +#else + DebugString( "The skin you are trying to load is meant for an older Winamp3 version.\n" ); +#endif + break; + } + case CHKSKIN_UNKNOWN: +#ifdef WIN32 + WASABI_API_WND->appdeactivation_setbypass(1); + MessageBoxA(GetActiveWindow(), WASABI_API_LNGSTRING(IDS_SKIN_LOAD_NOT_SUPPORTED), + WASABI_API_LNGSTRING_BUF(IDS_ERROR,title,32), MB_ICONERROR); + WASABI_API_WND->appdeactivation_setbypass(0); +#else + DebugString( "The skin you are trying to load is meant for an older Winamp3 version.\n" ); +#endif + return ; + + case CHKSKIN_DISALLOWED: + + // kernel controller should output its own error message + + return ; + + case CHKSKIN_ISWA2: break; + } + + WASABI_API_COLORTHEMES->StartTransaction(); + if (skin_loaded) + { + sendUnloadingCallback(); + } + + loading = 1; + + if (skin_loaded) + { + //ComponentManager::detachAllTemporary(); + //ComponentManager::destroyAllCompContainer(); + +#ifdef WASABI_COMPILE_WNDMGR + #ifdef WASABI_COMPILE_CONFIG + #ifndef WASABI_WNDMGR_NORESPAWN + skinEmbedder->saveState(); +#endif + #endif + #endif + + // unload current skin + SkinParser::cleanUp(); + + delete(tha); + tha = NULL; + //delete(VCPU::scriptManager); + + unloadResources(); + + // TODO: benski> unload WAC files inside skin. + // we should have saved a list of WacComponent * when loading + // add a new method ComponentManager::unload(WacComponent *); + + Skin::sendResetCallback(); + + // VCPU::scriptManager = new ScriptObjectManager(); + Skin *n = new Skin; + tha = n; + } + + setSkinName(skinName, skin_path); + + if (skin_loaded) + { + SkinElementsMgr::resetSkinElements(); + //SkinElementsMgr::loadSkinElements(skinName); // only loads element definitions, not actual bitmaps + + sendReloadCallback(); + + reloadResources(); + } + + // TODO: benski> load WAC files inside skin. save list of WacComponent * to a list to unload later + // make ComponentManager::load() return the WacComponent to allow this + +#ifdef WASABI_COMPILE_WNDMGR + int ncont = SkinParser::loadContainers(skinName); //sends guiloaded cb +#endif + + GammaMgr::loadDefault(); + +#ifdef WASABI_COMPILE_WNDMGR + SkinParser::startupContainers(); +#ifdef WASABI_COMPILE_CONFIG +#ifndef WASABI_WNDMGR_NORESPAWN + skinEmbedder->restoreSavedState(); +#endif +#endif +#endif + + enable_group_reload = 1; + + sendLoadedCallback(); + +#ifdef WASABI_COMPILE_WNDMGR + SkinParser::centerSkin(); +#endif + + loading = 0; + +#ifdef WASABI_COMPILE_WNDMGR +#ifdef WA3COMPATIBILITY + if (ncont == 0) + SkinParser::emmergencyReloadDefaultSkin(); +#endif +#endif + skin_loaded = 1; + WASABI_API_COLORTHEMES->EndTransaction(); +} + +void Skin::unloadSkin() +{ + if (!skin_loaded) return ; + + sendUnloadingCallback(); + + loading = -1; + +#ifdef WASABI_COMPILE_WNDMGR + #ifdef WASABI_COMPILE_CONFIG + #ifndef WASABI_WNDMGR_NORESPAWN + skinEmbedder->saveState(); +#endif + #endif + #endif + + // unload current skin + SkinParser::cleanUp(); + + delete(tha); + tha = NULL; + //delete(VCPU::scriptManager); + + unloadResources(); + + Skin::sendResetCallback(); + + // VCPU::scriptManager = new ScriptObjectManager(); + Skin *n = new Skin; + tha = n; + + setSkinName(WASABI_API_LNGSTRINGW_BUF(IDS_NO_SKIN_LOADED_,skName,64)); + + SkinElementsMgr::resetSkinElements(); + //SkinElementsMgr::loadSkinElements(skinName); // only loads element definitions, not actual bitmaps + + sendReloadCallback(); + + reloadResources(); + loading = 0; + skin_loaded = 0; +} + +void Skin::sendUnloadingCallback() +{ +#if defined(WASABI_COMPILE_COMPONENTS) | defined(GEN_FF) // MULTIAPI-FIXME!! + ComponentManager::broadcastNotify(WAC_NOTIFY_SKINUNLOADING, WASABI_API_PALETTE->getSkinPartIterator()); +#endif + WASABI_API_SYSCB->syscb_issueCallback(SysCallback::SKINCB, SkinCallback::UNLOADING); +} + +int Skin::sendAbortCallback(const wchar_t *skinname) +{ + int a = 0; + WASABI_API_SYSCB->syscb_issueCallback(SysCallback::SKINCB, SkinCallback::CHECKPREVENTSWITCH, (intptr_t)skinname, (intptr_t)&a); + return a; +} + +void Skin::sendResetCallback() +{ + WASABI_API_SYSCB->syscb_issueCallback(SysCallback::SKINCB, SkinCallback::RESET); +} + +void Skin::sendReloadCallback() +{ +#if defined(WASABI_COMPILE_COMPONENTS) | defined(GEN_FF) // MULTIAPI-FIXME!! + ComponentManager::broadcastNotify(WAC_NOTIFY_SWITCHINGSKIN, WASABI_API_PALETTE->getSkinPartIterator()); // this msg primilarily here to insert stuff between unloading of the old skin and reloading of the new one +#endif + WASABI_API_SYSCB->syscb_issueCallback(SysCallback::SKINCB, SkinCallback::RELOAD); +} + +void Skin::sendBeforeLoadingElementsCallback() +{ +#if defined(WASABI_COMPILE_COMPONENTS) | defined(GEN_FF) // MULTIAPI-FIXME!! + ComponentManager::broadcastNotify(WAC_NOTIFY_BEFORELOADINGSKINELEMENTS, WASABI_API_PALETTE->getSkinPartIterator()); // this msg primilarily here to insert stuff between unloading of the old skin and reloading of the new one +#endif + WASABI_API_SYSCB->syscb_issueCallback(SysCallback::SKINCB, SkinCallback::BEFORELOADINGELEMENTS); +} + +void Skin::sendGuiLoadedCallback() +{ + WASABI_API_SYSCB->syscb_issueCallback(SysCallback::SKINCB, SkinCallback::GUILOADED); +} + +void Skin::sendLoadedCallback() +{ +#if defined(WASABI_COMPILE_COMPONENTS) | defined(GEN_FF) // MULTIAPI-FIXME!! + ComponentManager::broadcastNotify(WAC_NOTIFY_SKINLOADED, WASABI_API_PALETTE->getSkinPartIterator()); +#endif + WASABI_API_SYSCB->syscb_issueCallback(SysCallback::SKINCB, SkinCallback::LOADED); +} + +void Skin::setSkinReady(int i) +{ + loading = !i; +} + +void Skin::main_notifySkinLoaded() +{ + skin_loaded = 1; +} + +int Skin::isSkinReady() +{ + return !loading; +} + +int Skin::unloadResources() +{ + if (windowTracker) + { + for (int i = 0;i < windowTracker->getNumAllWindows();i++) + { + ifc_window *w = windowTracker->enumAllWindows(i); +#ifdef _WIN32 + if (w) w->wndProc(w->gethWnd(), WM_WA_RELOAD, 0, 0); +#else +#warning port me +#endif + } + Skin::unloadAllBaseTextures(); +#ifdef WASABI_COMPILE_PAINTSETS + paintset_reset(); +#endif + + } + + sendResetCallback(); + + return 1; +} + +int Skin::reloadResources() +{ + if (windowTracker) + { + for (int i = 0;i < windowTracker->getNumAllWindows();i++) + { + ifc_window *w = windowTracker->enumAllWindows(i); +#ifdef _WIN32 + if (w) w->wndProc(w->gethWnd(), WM_WA_RELOAD, 1, 0); +#else +#warning port me +#endif + } + Skin::reloadAllBaseTextures(); + } + + sendReloadCallback(); + + return 1; +} + +bool Skin::isLoaded() +{ + return !!skin_loaded; +} + +PtrList<Skin> Skin::skinList; +PtrList<ifc_window> Skin::baseList; +StringW Skin::skinName; +StringW Skin::skinPath; +int Skin::isDefaultSkin = 0; +int Skin::loading = 0; +int Skin::highest_id = 0; +int Skin::reloadingskin = 0; +int Skin::enable_group_reload = 0; +StringW Skin::defSkinPath; +SkinTimer *Skin::deferedskinset = NULL; +int Skin::skin_loaded = 0;
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/skin.h b/Src/Wasabi/api/skin/skin.h new file mode 100644 index 00000000..0f9da315 --- /dev/null +++ b/Src/Wasabi/api/skin/skin.h @@ -0,0 +1,150 @@ +#ifndef _SKIN_H +#define _SKIN_H + +#include <api/skin/api_skin.h> + +#include <bfc/platform/platform.h> +#include <api/wnd/basewnd.h> +#include <bfc/ptrlist.h> +#include <tataki/region/region.h> +#include <tataki/bitmap/autobitmap.h> +#include <bfc/string/bfcstring.h> +#include <api/wndmgr/container.h> +#include <api/xml/xmlreader.h> +#include <bfc/string/StringW.h> + +class SkinBitmap; +#include "SkinVersion.h" + +#define CB_SETSKINDEFERRED 0x5492 + +class SkinTimer; + +class Skin +{ +public: + enum { + CHKSKIN_UNKNOWN = -1, + CHKSKIN_ISWA3 = 1, + CHKSKIN_ISWA3OLD = 2, + CHKSKIN_ISWA3FUTURE = 3, + CHKSKIN_ISWA2 = 4, + CHKSKIN_DISALLOWED = 5, + }; + + Skin(); + virtual ~Skin(); + + static const wchar_t *getSkinName(); + static void setSkinName(const wchar_t *newskinname, const wchar_t *skinpath = NULL); + static const wchar_t *getSkinPath(); + static const wchar_t *getDefaultSkinPath(); + static Skin *getCurSkin(); + + void setBaseTexture(const wchar_t *b); + + //CUT static int registerCallback(SkinCallback *cb); + //CUT static int deregisterCallback(SkinCallback *cb); + + static void renderBaseTexture(ifc_window *base, Skin *s, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha = 255); + static void renderBaseTexture(ifc_window *s, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha = 255); + + static void invalidateBaseTexture(Skin *s); + static void invalidateAllBaseTextures(); + static Skin *baseToSkin(ifc_window *b); + static void registerBaseSkin(Skin *s, ifc_window *b); + static Skin *unregisterBaseSkin(ifc_window *b); + + + static void unloadAllBaseTextures(); + static void reloadAllBaseTextures(); + void _unloadBaseTexture(); + void _reloadBaseTexture(); + + static wchar_t *enumLoadableSkins(int refresh = FALSE); + + static int checkSkin(const wchar_t *name); + static void toggleSkin(const wchar_t *name, const wchar_t *skin_path = NULL, int deferred = 0); + static void unloadSkin(); + static void parseSkinFilename(const wchar_t *filename, const wchar_t *incpath); + static int isDefaultSkin; + static void sendUnloadingCallback(); + static int sendAbortCallback(const wchar_t *skinname); + static void sendResetCallback(); + static void sendReloadCallback(); + static void sendBeforeLoadingElementsCallback(); + static void sendGuiLoadedCallback(); + static void sendLoadedCallback(); + static int isSkinReady(); + static void setSkinReady(int i); + static int isDynamicGroupReloadEnabled() { return enable_group_reload; } + static void unloadSkinPart(int id); + static int loadSkinPart(const wchar_t *xmlfile); + static void main_notifySkinLoaded(); + static int isLoading() { return loading; } + + static int unloadResources(); + static int reloadResources(); + static bool isLoaded(); +private: + void rescaleBaseTexture(int w, int h); + void _renderBaseTexture(ifc_window *base, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha); + void _invalidateBaseTexture(void); + void validateBaseTextureRect(RECT *r); + + AutoSkinBitmap *base; + BltCanvas *scaled; + int scale_x, scale_y; + bool forceinvalid; + int m_x, m_y; + int lastw, lasth, maxw, maxh; + bool resizing; + RegionI *validRgn; + static int loading; + static int enable_group_reload; + + static PtrList<Skin> skinList; + static PtrList<ifc_window> baseList; + + static StringW skinName; + static StringW skinPath; + static StringW defSkinPath; + static int highest_id; + static int reloadingskin; + static int skin_loaded; + + static SkinTimer *deferedskinset; +}; + +class SkinTimer : public TimerClientDI +{ +public : + SkinTimer() {} + virtual ~SkinTimer() {} + + void setSkinDeferred(const wchar_t *skinname) + { + skin = skinname; + timerclient_postDeferredCallback(CB_SETSKINDEFERRED, 0); + } + + virtual int timerclient_onDeferredCallback(intptr_t p1, intptr_t p2) + { + if (p1 == CB_SETSKINDEFERRED) + { + Skin::toggleSkin(skin); + skin.trunc(0); + } + else + return TimerClientDI::timerclient_onDeferredCallback(p1, p2); + return 1; + } + +private: + StringW skin; +}; + + +extern Skin *tha; + +#endif diff --git a/Src/Wasabi/api/skin/skinapi.cpp b/Src/Wasabi/api/skin/skinapi.cpp new file mode 100644 index 00000000..f68a0614 --- /dev/null +++ b/Src/Wasabi/api/skin/skinapi.cpp @@ -0,0 +1,347 @@ +#include <precomp.h> +#include <api.h> +#include "skinapi.h" +#include <api/skin/skin.h> +#include <api/wndmgr/skinembed.h> +#include <api/skin/skinelem.h> +#include <api/imgldr/imgldr.h> +#include <api/skin/gammamgr.h> +#include <api/skin/groupmgr.h> +#include <api/skin/cursormgr.h> +#include <api/skin/guitree.h> +#include <api/skin/groupwndcreate.h> +#include <api/wndmgr/autopopup.h> +#include <tataki/canvas/bltcanvas.h> + +api_skin *skinApi; +static waServiceTSingle<svc_windowCreate, GroupWndCreateSvc> groupWndCreate; + +SkinApi::SkinApi() +{ + lockui = 0; + tha = new Skin(); + SkinParser::initialize(); + + WASABI_API_SVC->service_register(&groupWndCreate); + + SkinElementsMgr::init(); + GammaMgr::init(); + + // fixed this for 5.58+ so it'll use the correct skins directory + // and not the winamp.exe folder + "skins" - fixes @SKINSPATH@ + // when the skins directory has been altered - from Bento notifier.xml + skinspath = WASABI_API_APP->path_getSkinSettingsPath(); +} + +SkinApi::~SkinApi() +{ + delete tha; tha = NULL; +#ifdef WASABI_COMPILE_WNDMGR + AutoPopup::reset(); +#endif + SkinElementsMgr::deinit(); + GammaMgr::deinit(); + WASABI_API_SVC->service_deregister(&groupWndCreate); + SkinParser::shutdown(); +} + +void SkinApi::preShutdown() +{ + Skin::unloadSkin(); + SkinElementsMgr::resetSkinElements(); +} + +ARGB32 SkinApi::skin_getColorElement(const wchar_t *type, const wchar_t **color_group) +{ + return WASABI_API_PALETTE->getColorElement(type, color_group); +} + +const ARGB32 *SkinApi::skin_getColorElementRef(const wchar_t *type, const wchar_t **color_group) +{ + return WASABI_API_PALETTE->getColorElementRef(type, color_group); +} + +const int *SkinApi::skin_getIterator() +{ + return WASABI_API_PALETTE->getSkinPartIteratorPtr(); +} + +void SkinApi::skin_switchSkin(const wchar_t *skin_name, const wchar_t *skin_path) +{ + if (skin_name && *skin_name) Skin::toggleSkin(skin_name, skin_path, 1); +} + +void SkinApi::skin_unloadSkin() +{ + Skin::unloadSkin(); +} + +const wchar_t *SkinApi::getSkinName() +{ + return Skin::getSkinName(); +} + +const wchar_t *SkinApi::getSkinPath() +{ + return Skin::getSkinPath(); +} + +const wchar_t *SkinApi::getSkinsPath() +{ + return skinspath; +} + +const wchar_t *SkinApi::getDefaultSkinPath() +{ + return Skin::getDefaultSkinPath(); +} + +ARGB32 *SkinApi::imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached) +{ + if (file == NULL) + { + DebugStringW(L"illegal param : file == NULL\n"); + return NULL; + } + return imageLoader::requestSkinBitmap(file, has_alpha, x, y, subw, subh, w, h, cached); +} + +void SkinApi::imgldr_releaseSkinBitmap(ARGB32 *bmpbits) +{ + if (bmpbits == NULL) + { + DebugStringW(L"illegal param : bmpbits == NULL\n"); + return ; + } + imageLoader::releaseSkinBitmap(bmpbits); +} + +ARGB32 SkinApi::filterSkinColor(ARGB32 color, const wchar_t *elementid, const wchar_t *groupname) +{ + return imageLoader::filterSkinColor(color, elementid, groupname); +} + +void SkinApi::reapplySkinFilters() +{ + imageLoader::applySkinFilters(); +} + +/* ---------------------------------------- */ +int SkinApi::colortheme_getNumColorSets() +{ + return WASABI_API_COLORTHEMES->getNumGammaSets(); +} + +const wchar_t *SkinApi::colortheme_enumColorSet(int n) +{ + return WASABI_API_COLORTHEMES->enumGammaSet(n); +} + +int SkinApi::colortheme_getNumColorGroups(const wchar_t *colorset) +{ + return WASABI_API_COLORTHEMES->getNumGammaGroups(colorset); +} + +const wchar_t *SkinApi::colortheme_enumColorGroupName(const wchar_t *colorset, int n) +{ + return WASABI_API_COLORTHEMES->enumGammaGroup(colorset, n); +} + +ColorThemeGroup *SkinApi::colortheme_enumColorGroup(int colorset, int colorgroup) +{ + return WASABI_API_COLORTHEMES->enumColorThemeGroup(colorset, colorgroup); +} + +ColorThemeGroup *SkinApi::colortheme_getColorGroup(const wchar_t *colorset, const wchar_t *colorgroup) +{ + return WASABI_API_COLORTHEMES->getColorThemeGroup(colorset, colorgroup); +} + +void SkinApi::colortheme_setColorSet(const wchar_t *colorset) +{ + WASABI_API_COLORTHEMES->setGammaSet(colorset); + // TODO: benski> move this to a syscallback: SysCallback::SKINCB, SkinCallback::COLORTHEMECHANGED + WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"Color Themes/%s", getSkinName()), colorset); +} + +const wchar_t *SkinApi::colortheme_getColorSet() +{ + return WASABI_API_COLORTHEMES->getGammaSet(); +} + +void SkinApi::colortheme_newColorSet(const wchar_t *set) +{ + WASABI_API_COLORTHEMES->newGammaSet(set); +} + +void SkinApi::colortheme_updateColorSet(const wchar_t *set) +{ + WASABI_API_COLORTHEMES->updateGammaSet(set); +} + +void SkinApi::colortheme_renameColorSet(const wchar_t *set, const wchar_t *newname) +{ + WASABI_API_COLORTHEMES->renameGammaSet(set, newname); +} + +void SkinApi::colortheme_deleteColorSet(const wchar_t *set) +{ + WASABI_API_COLORTHEMES->deleteGammaSet(set); +} + + /* -------------------------------------------- */ + +int SkinApi::loadSkinFile(const wchar_t *xmlfile) +{ + return Skin::loadSkinPart(xmlfile); +} + +void SkinApi::unloadSkinPart(int skinpartid) +{ + Skin::unloadSkinPart(skinpartid); +} + +ifc_window *SkinApi::group_create(const wchar_t *groupid, int scripts_enabled) +{ + return GroupMgr::instantiate(groupid, GROUP_GROUP, NULL, scripts_enabled); +} + +int SkinApi::group_destroy(ifc_window *group) +{ + return GroupMgr::destroy(static_cast<Group*>(group)); +} + +int SkinApi::group_exists(const wchar_t *groupid) +{ + return GroupMgr::exists(groupid); +} + +#ifdef WASABI_COMPILE_CONFIG +ifc_window *SkinApi::group_create_cfg(const wchar_t *groupid, CfgItem *cfgitem, const wchar_t *attributename, int scripts_enabled) +{ + return GroupMgr::instantiate(groupid, cfgitem, attributename, scripts_enabled); +} +#endif // WASABI_COMPILE_CONFIG + +#ifdef WASABI_COMPILE_WNDMGR +ifc_window *SkinApi::group_create_layout(const wchar_t *groupid, int scripts_enabled) +{ + return GroupMgr::instantiate(groupid, GROUP_LAYOUTGROUP, NULL, scripts_enabled); +} +#endif //WASABI_COMPILE_WNDMGR + +OSCURSOR SkinApi::cursor_request(const wchar_t *id) +{ + return CursorMgr::requestCursor(id); +} + +int SkinApi::parse(const wchar_t *str, const wchar_t *how) +{ + return SkinParser::parse(str, how); +} + +GuiObject *SkinApi::xui_new(const wchar_t *classname) +{ + return SkinParser::xui_new(classname); +} + +void SkinApi::xui_delete(GuiObject *o) +{ + SkinParser::xui_delete(o); +} + +int SkinApi::getNumGroupDefs() +{ + return guiTree->getNumGroupDefs(); +} + +SkinItem *SkinApi::enumGroupDef(int n) +{ + return guiTree->enumGroupDef(n); +} + +ifc_window *SkinApi::group_createBySkinItem(SkinItem *item, int scripts_enabled) +{ + return GroupMgr::instantiate(NULL, GROUP_GROUP, item, scripts_enabled); +} + +SkinItem *SkinApi::getGroupDefAncestor(SkinItem *item) +{ + return guiTree->getGroupDefAncestor(item); +} + +int SkinApi::groupdef_getNumObjects(SkinItem *_item) +{ + GuiTreeItem *item = static_cast<GuiTreeItem *>(_item); + int idx = item->getIdx(); + idx++; + int n = 0; + while (1) + { + GuiTreeItem *it = guiTree->getList()->enumItem(idx); + if (it->getType() == XML_TAG_GROUPDEF && it->getParams() == NULL) break; + idx++; n++; + } + return n; +} + +SkinItem *SkinApi::groupdef_enumObject(SkinItem *_item, int n) +{ + GuiTreeItem *item = static_cast<GuiTreeItem *>(_item); + int idx = item->getIdx(); + idx++; + int _n = 0; + GuiTreeItem *it = NULL; + while (1) + { + it = guiTree->getList()->enumItem(idx); + if (it->getType() == XML_TAG_GROUPDEF && it->getParams() == NULL) break; + if (n == _n) break; + idx++; _n++; + } + return it; +} + +int SkinApi::loadGroupDefData(const wchar_t *groupdef, SkinItem **lastgroupdef) +{ + StringW s; + s = L"buf:"; + + s += L"<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\"?>" + L"<WinampAbstractionLayer version=\"0.8\">"; + + s += groupdef; + + s += L"</WinampAbstractionLayer>"; + + int r = Skin::loadSkinPart(s); + if (lastgroupdef != NULL) + *lastgroupdef = guiTree->getLastDefinedGroup(); + return r; +} + +double SkinApi::skin_getVersion() +{ + return SkinParser::getSkinVersion(); +} +#ifdef WASABI_COMPILE_IMGLDR +ARGB32 SkinApi::skin_getBitmapColor(const wchar_t *id) +{ + SkinBitmap bitmap(id); + BltCanvas c(bitmap.getWidth() + 1, bitmap.getHeight() + 1, 0); // TODO: this won't work on the mac i don't think + bitmap.blit(&c, 0, 0); + int x = bitmap.getWidth() / 2; + int y = bitmap.getHeight() / 2; + int *bits = (int *)c.getBits(); + if (bits != NULL) + { + return bits[x + y*bitmap.getWidth() + 1]; + } + return 0xFFFF00FF; +} +#endif + +bool SkinApi::skin_isLoaded() +{ + return Skin::isLoaded(); +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/skinapi.h b/Src/Wasabi/api/skin/skinapi.h new file mode 100644 index 00000000..b4cedc99 --- /dev/null +++ b/Src/Wasabi/api/skin/skinapi.h @@ -0,0 +1,79 @@ +#ifndef __SKINAPI_H +#define __SKINAPI_H + +#include <api/skin/api_skin.h> +#include <bfc/string/StringW.h> +#include <api/skin/widgets.h> +#include <api/xml/xmlparams.h> + +class SkinApi : public api_skinI +{ + public: + + SkinApi(); + virtual ~SkinApi(); + virtual void preShutdown(); + + virtual ARGB32 skin_getColorElement(const wchar_t *type, const wchar_t **color_group = NULL); + virtual const ARGB32 *skin_getColorElementRef(const wchar_t *type, const wchar_t **color_group = NULL); + virtual const int *skin_getIterator(); + virtual void skin_switchSkin(const wchar_t *skin_name, const wchar_t *skin_path); + virtual void skin_unloadSkin(); + virtual const wchar_t *getSkinName(); + virtual const wchar_t *getSkinPath(); + virtual const wchar_t *getSkinsPath(); + virtual const wchar_t *getDefaultSkinPath(); + virtual ARGB32 *imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached); + virtual void imgldr_releaseSkinBitmap(ARGB32 *bmpbits); + virtual ARGB32 filterSkinColor(ARGB32 color, const wchar_t *elementid, const wchar_t *groupname); + virtual void reapplySkinFilters(); + virtual int colortheme_getNumColorSets(); + virtual const wchar_t *colortheme_enumColorSet(int n); + virtual int colortheme_getNumColorGroups(const wchar_t *colorset); + virtual const wchar_t *colortheme_enumColorGroupName(const wchar_t *colorset, int n); + virtual ColorThemeGroup *colortheme_enumColorGroup(int colorset, int n); + virtual ColorThemeGroup *colortheme_getColorGroup(const wchar_t *colorset, const wchar_t *group); + virtual void colortheme_setColorSet(const wchar_t *colorset); + virtual const wchar_t *colortheme_getColorSet(); + virtual void colortheme_newColorSet(const wchar_t *set); + virtual void colortheme_updateColorSet(const wchar_t *set); + virtual void colortheme_renameColorSet(const wchar_t *set, const wchar_t *newname); + virtual void colortheme_deleteColorSet(const wchar_t *set); + virtual int loadSkinFile(const wchar_t *xmlfile); + virtual int loadGroupDefData(const wchar_t *groupdef, SkinItem **lastgroupitem); + virtual void unloadSkinPart(int skinpartid); + virtual ifc_window *group_create(const wchar_t *groupid, int scripts_enabled=1); + virtual int group_exists(const wchar_t *groupid); +#ifdef WASABI_COMPILE_CONFIG + virtual ifc_window *group_create_cfg(const wchar_t *groupid, CfgItem *cfgitem, const wchar_t *attributename, int scripts_enabled=1); +#endif // WASABI_COMPILE_CONFIG +#ifdef WASABI_COMPILE_WNDMGR + virtual ifc_window *group_create_layout(const wchar_t *groupid, int scripts_enabled=1); +#endif //WASABI_COMPILE_WNDMGR + virtual int group_destroy(ifc_window *group); + virtual int parse(const wchar_t *str, const wchar_t *how); + virtual GuiObject *xui_new(const wchar_t *classname); + virtual void xui_delete(GuiObject *o); + virtual OSCURSOR cursor_request(const wchar_t *id); + + virtual int getNumGroupDefs(); + virtual SkinItem *enumGroupDef(int n); + virtual ifc_window *group_createBySkinItem(SkinItem *item, int scripts_enabled=1); + virtual SkinItem *getGroupDefAncestor(SkinItem *item); + virtual int groupdef_getNumObjects(SkinItem *item); + virtual SkinItem *groupdef_enumObject(SkinItem *groupitem, int n); + virtual void skin_setLockUI(int l) { if (l) lockui++; else if (lockui) lockui--; } + virtual int skin_getLockUI() { return lockui; } + virtual double skin_getVersion(); +#ifdef WASABI_COMPILE_IMGLDR + virtual ARGB32 skin_getBitmapColor(const wchar_t *id); +#endif + bool skin_isLoaded(); + + private: + + StringW skinspath; + int lockui; +}; + +#endif diff --git a/Src/Wasabi/api/skin/skinbmps.h b/Src/Wasabi/api/skin/skinbmps.h new file mode 100644 index 00000000..dab8568c --- /dev/null +++ b/Src/Wasabi/api/skin/skinbmps.h @@ -0,0 +1,122 @@ +#ifndef _SKINBMPS_H +#define _SKINBMPS_H +/* +typedef enum { + SKIN_BITMAP_UNKNOWN, + + // Base texture + SKIN_BITMAP_BASE_TEXTURE, + + // Framewnd + SKIN_BITMAP_FRAME_VERTICAL_DIVIDER, + SKIN_BITMAP_FRAME_HORIZONTAL_DIVIDER, + + // Listwnd/Treewnd + SKIN_BITMAP_LIST_BACKGROUND, + SKIN_BITMAP_TREE_BACKGROUND, + + // Appctrl + SKIN_BITMAP_APPCTRL_LEFTARROW_NONPRESSED, + SKIN_BITMAP_APPCTRL_LEFTARROW_PRESSED, + SKIN_BITMAP_APPCTRL_RIGHTARROW_NONPRESSED, + SKIN_BITMAP_APPCTRL_RIGHTARROW_PRESSED, + SKIN_BITMAP_APPCTRL_WINDOWSIZER, + SKIN_BITMAP_APPCTRL_PLAYERMODE_NONPRESSED, + SKIN_BITMAP_APPCTRL_PLAYERMODE_PRESSED, + SKIN_BITMAP_APPCTRL_MINIMIZE_NONPRESSED, + SKIN_BITMAP_APPCTRL_MINIMIZE_PRESSED, + SKIN_BITMAP_APPCTRL_MAXIMIZE_NONPRESSED, + SKIN_BITMAP_APPCTRL_MAXIMIZE_PRESSED, + SKIN_BITMAP_APPCTRL_CLOSE_NONPRESSED, + SKIN_BITMAP_APPCTRL_CLOSE_PRESSED, + SKIN_BITMAP_APPCTRL_SYSTEMICON, + SKIN_BITMAP_APPCTRL_PLACEHOLDER_LEFT, + SKIN_BITMAP_APPCTRL_PLACEHOLDER_MIDDLE, + SKIN_BITMAP_APPCTRL_PLACEHOLDER_RIGHT, + SKIN_BITMAP_APPCTRL_TITLEBAR, + + // Controls + SKIN_BITMAP_PLAYBACKCONTROLS_PREVIOUS_NONPRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_PREVIOUS_PRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_PLAY_NONPRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_PLAY_PRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_PAUSE_NONPRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_PAUSE_PRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_STOP_NONPRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_STOP_PRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_NEXT_NONPRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_NEXT_PRESSED, + + // Paintset + SKIN_BITMAP_LABEL_UPPERLEFT, + SKIN_BITMAP_LABEL_TOP, + SKIN_BITMAP_LABEL_UPPERRIGHT, + SKIN_BITMAP_LABEL_LEFT, + SKIN_BITMAP_LABEL_MIDDLE, + SKIN_BITMAP_LABEL_RIGHT, + SKIN_BITMAP_LABEL_LOWERLEF, + SKIN_BITMAP_LABEL_BOTTOM, + SKIN_BITMAP_LABEL_LOWERRIGHT, + SKIN_BITMAP_APPBORDER_UPPERLEFT, + SKIN_BITMAP_APPBORDER_TOP, + SKIN_BITMAP_APPBORDER_UPPERRIGHT, + SKIN_BITMAP_APPBORDER_LEFT, + SKIN_BITMAP_APPBORDER_RIGHT, + SKIN_BITMAP_APPBORDER_LOWERLEFT, + SKIN_BITMAP_APPBORDER_BOTTOM, + SKIN_BITMAP_APPBORDER_LOWERRIGHT, + + // Seeker + SKIN_BITMAP_SEEKBAR_LEFT, + SKIN_BITMAP_SEEKBAR_MIDDLE, + SKIN_BITMAP_SEEKBAR_RIGHT, + SKIN_BITMAP_SEEKBAR_BUTTON_NONPRESSED, + SKIN_BITMAP_BUTTON_PRESSED, + + // Status + SKIN_BITMAP_STATUSBAR_LEFT, + SKIN_BITMAP_STATUSBAR_MIDDLE, + SKIN_BITMAP_STATUSBAR_RIGHT, + + // Volbar + SKIN_BITMAP_VOLBAR_LEFT, + SKIN_BITMAP_VOLBAR_MIDDLE, + SKIN_BITMAP_VOLBAR_RIGHT, + SKIN_BITMAP_VOLBAR_BUTTON_NONPRESSED, + SKIN_BITMAP_VOLBAR_BUTTON_PRESSED, + + // Titlewnd + SKIN_BITMAP_COMPONENT_PROP_TOP, + SKIN_BITMAP_COMPONENT_PROP, + SKIN_BITMAP_COMPONENT_PROP_MIDDLE, + SKIN_BITMAP_COMPONENT_PROP_BOTTOM, + + // Videownd + SKIN_BITMAP_MOVIE_BACKGROUND, + + // Seditwnd + SKIN_BITMAP_AVS_SCRIPT_MARKER, + SKIN_BITMAP_AVS_SCRIPT_PLAY_NONPRESSED, + SKIN_BITMAP_AVS_SCRIPT_PLAY_PRESSED, + SKIN_BITMAP_AVS_SCRIPT_PAUSE_NONPRESSED, + SKIN_BITMAP_AVS_SCRIPT_PAUSE_PRESSED, + SKIN_BITMAP_AVS_SCRIPT_STOP_NONPRESSED, + SKIN_BITMAP_AVS_SCRIPT_STOP_PRESSED, + SKIN_BITMAP_AVS_SCRIPT_TIMEARROW, + SKIN_BITMAP_AVS_SCRIPT_BACKGROUND, + SKIN_BITMAP_AVS_SCRIPT_ZOOMER_TOP, + SKIN_BITMAP_AVS_SCRIPT_ZOOMER_MIDDLE, + SKIN_BITMAP_AVS_SCRIPT_ZOOMER_BOTTOM, + SKIN_BITMAP_AVS_SCRIPT_ZOOMER_BUTTON_NONPRESSED, + SKIN_BITMAP_AVS_SCRIPT_ZOOMER_BUTTON_PRESSED, + +// ComponentAPI1 ends here + NUM_SKIN_BITMAP_ELEMENT_IDS +} SkinBitmapElementId; + +typedef struct { + SkinBitmapElementId id; + char *fn; + } SkinBitmapTableElement; +*/ +#endif diff --git a/Src/Wasabi/api/skin/skinelem.cpp b/Src/Wasabi/api/skin/skinelem.cpp new file mode 100644 index 00000000..45d1a39f --- /dev/null +++ b/Src/Wasabi/api/skin/skinelem.cpp @@ -0,0 +1,316 @@ +#include <precomp.h> +#include <api.h> +#include "skinelem.h" +#include <api/skin/skin.h> +#include <api/skin/skinparse.h> +#include <api/wac/compon.h> +#include <api/wac/wac.h> +#include <api/font/font.h> +#include <bfc/parse/pathparse.h> +#include <api/service/svcs/svc_collection.h> +#include <tataki/canvas/bltcanvas.h> + +xml_elementtag elementtaglist[] = + { + {L"bitmap", XML_ELEMENTTAG_BITMAP, 0}, + {L"bitmapfont", XML_ELEMENTTAG_BITMAPFONT, 0}, + {L"color", XML_ELEMENTTAG_COLOR, 0}, + {L"cursor", XML_ELEMENTTAG_CURSOR, 0}, + {L"elements", XML_ELEMENTTAG_ELEMENTS, 1}, + {L"elementalias", XML_ELEMENTTAG_ELEMENTALIAS, 0}, + {L"truetypefont", XML_ELEMENTTAG_TRUETYPEFONT, 0}, + }; + +//------------------------- + + + + + + + +//------------------------- + +void SkinElementsMgr::init() +{ + if (!quickxmltaglist.getNumItems()) + { + for (int i = 0;i < sizeof(elementtaglist) / sizeof(xml_elementtag);i++) + quickxmltaglist.addItem(&elementtaglist[i]); + } + skinXML.registerCallback(L"WinampAbstractionLayer\felements\f*", &xmlreader); //back compat + skinXML.registerCallback(L"WasabiXML\felements\f*", &xmlreader); +} + +void SkinElementsMgr::deinit() +{ + resetSkinElements(); + skinXML.unregisterCallback(&xmlreader); +} + +void SkinElementsMgr::onBeforeLoadingSkinElements(const wchar_t *_rootpath) +{ + Skin::sendBeforeLoadingElementsCallback(); + elementScriptId = WASABI_API_PALETTE->newSkinPart(); + + WASABI_API_PALETTE->StartTransaction(); + + rootpath = _rootpath; + original_rootpath = rootpath; + last_includepath = L""; +} + +void SkinElementsMgr::onAfterLoadingSkinElements() +{ + WASABI_API_PALETTE->EndTransaction(); + +#ifdef WASABI_COMPILE_COMPONENTS + ComponentManager::broadcastNotify(WAC_NOTIFY_SKINELEMENTSLOADED, Skin::getSkinPartIterator()); +#endif +} + +void SkinElementsXmlReader::xmlReaderOnEndElementCallback(const wchar_t *xmltag) +{ + SkinElementsMgr::xmlReaderOnEndElementCallback(xmltag); +} + +void SkinElementsMgr::xmlReaderOnEndElementCallback(const wchar_t *xmltag) +{ + xml_elementtag *i = quickxmltaglist.findItem(xmltag); + if (!i) return ; + if (i->id == XML_ELEMENTTAG_ELEMENTS) + { + if (inelements) + inelements = 0; + } +} + +void SkinElementsXmlReader::xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params) +{ + SkinElementsMgr::xmlReaderOnStartElementCallback(xmltag, params); +} + +void SkinElementsMgr::xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params) +{ + xml_elementtag *i = quickxmltaglist.findItem(xmltag); + if (i) + _xmlReaderOnStartElementCallback( i->id, xmltag, params); + else + _xmlReaderOnStartElementCallback( XML_ELEMENTTAG_UNKNOWN, xmltag, params); +} + +void SkinElementsMgr::_xmlReaderOnStartElementCallback(int tagid, const wchar_t *xmltag, skin_xmlreaderparams *params) +{ + const wchar_t *ic = skinXML.getIncludePath(); + if (WCSICMP(ic, last_includepath)) + { + last_includepath = skinXML.getIncludePath(); + rootpath = getSkinRootpathFromIncludePath(last_includepath, original_rootpath); + } + // If we're loading from a buffer, there should be no rootpath prefix. + if (!WCSNICMP(rootpath, L"buf:", 4)) + { + rootpath = NULL; + } + if (tagid == XML_ELEMENTTAG_ELEMENTALIAS) + { + WASABI_API_PALETTE->AddAlias(params->getItemValue(L"id"), params->getItemValue(L"target")); + } + else if (tagid == XML_ELEMENTTAG_BITMAP) + { + StringW id; + const wchar_t *fn; + id = params->getItemValue(L"id"); + fn = params->getItemValue(L"file"); + int x = params->getItemValueInt(L"x", -1); + int y = params->getItemValueInt(L"y", -1); + int w = params->getItemValueInt(L"w", -1); + int h = params->getItemValueInt(L"h", -1); + + const wchar_t *aliastarget = WASABI_API_PALETTE->getElementAlias(id); + if (aliastarget) + id = aliastarget; + + const wchar_t *colorgroup = params->getItemValue(L"colorgroup"); + if (!colorgroup || !*colorgroup) + colorgroup = params->getItemValue(L"gammagroup"); + + WASABI_API_PALETTE->AddBitmap(id, fn, rootpath, x, y, w, h, params, colorgroup); + + } + else if (tagid == XML_ELEMENTTAG_COLOR) + { + const wchar_t *colorstr = params->getItemValue(L"value"); + StringW id = params->getItemValue(L"id"); + const wchar_t *aliastarget = WASABI_API_PALETTE->getElementAlias(id); + if (aliastarget) + id = aliastarget; + const wchar_t *colorgroup = params->getItemValue(L"colorgroup"); + if (!colorgroup || !*colorgroup) + colorgroup = params->getItemValue(L"gammagroup"); + if (!wcschr(colorstr, ',')) + { + ARGB32 c = WASABI_API_PALETTE->getColorElement((colorstr)); + WASABI_API_PALETTE->AddColor(id, c, colorgroup, rootpath, params); + } + else + { + WASABI_API_PALETTE->AddColor((id), SkinParser::parseColor(colorstr), colorgroup, rootpath, params); + } + } + else if (tagid == XML_ELEMENTTAG_BITMAPFONT) + { + Font::installBitmapFont(params->getItemValue(L"file"), rootpath, params->getItemValue(L"id"), params->getItemValueInt(L"charwidth", 0), params->getItemValueInt(L"charheight", 0), params->getItemValueInt(L"hspacing", 0), params->getItemValueInt(L"vspacing", 0), elementScriptId, params->getItemValueInt(L"allowmapping", 1)); + } + else if (tagid == XML_ELEMENTTAG_TRUETYPEFONT) + { + Font::installTrueTypeFont(params->getItemValue(L"file"), rootpath, params->getItemValue(L"id"), elementScriptId, params->getItemValueInt(L"allowmapping", 1), 0); + } + else if (tagid == XML_ELEMENTTAG_CURSOR) + { + const wchar_t *bitmap = params->getItemValue(L"bitmap"); + StringW id = params->getItemValue(L"id"); + const wchar_t *aliastarget = WASABI_API_PALETTE->getElementAlias(id); + int x = params->getItemValueInt(L"hotspot_x", 0); + int y = params->getItemValueInt(L"hotspot_y", 0); + if (aliastarget) + id = aliastarget; + WASABI_API_PALETTE->AddCursor(id, bitmap, x, y, rootpath, params); + } + else if (tagid == XML_ELEMENTTAG_UNKNOWN) + { + CollectionSvcEnum cse(xmltag); + svc_collection *svc; + if (svc = cse.getFirst()) + { // got one! + svc->addElement(params->getItemValue(L"id"), rootpath, elementScriptId, params); + WASABI_API_SVC->service_release(svc); + } + } + else + { + DebugStringW(L"SkinElementsMgr: tag %s was recognized but not handled!\n", xmltag); + } +} + +void SkinElementsMgr::resetSkinElements() +{ + WASABI_API_PALETTE->Reset(); + + Font::uninstallAll(); + // remove any element inserted into a hierarchical collection + for (int i = 0;i < (int)WASABI_API_SVC->service_getNumServices(WaSvc::COLLECTION);i++) + { + waServiceFactory *f = WASABI_API_SVC->service_enumService(WaSvc::COLLECTION, i); + if (f != NULL) + { + svc_collection *svc = static_cast<svc_collection*>(f->getInterface(FALSE)); + svc->removeAllElements(); + f->releaseInterface(svc); + } + } +} + +void SkinElementsMgr::onBeforeLoadingScriptElements(const wchar_t *name, int script_id) +{ + SkinElementsMgr::rootpathstack.addItem(new StringW(rootpath)); + oldid = elementScriptId; + oldinel = inelements; + + WASABI_API_PALETTE->StartTransaction(); + wchar_t buf[WA_MAX_PATH] = {0}; + WCSCPYN(buf, name, WA_MAX_PATH); + + wchar_t *ptr = const_cast<wchar_t *>(Wasabi::Std::filename(buf)); + if (ptr != NULL) *ptr = '\0'; + rootpath = buf; + rootpath.AddBackslash(); + + original_rootpath = rootpath; + + last_includepath = L""; + + inelements = 0; + elementScriptId = script_id; +} + +void SkinElementsMgr::onAfterLoadingScriptElements() +{ + WASABI_API_PALETTE->EndTransaction(); + elementScriptId = oldid; + inelements = oldinel; + rootpath = SkinElementsMgr::rootpathstack.getLast(); + delete SkinElementsMgr::rootpathstack.getLast(); + SkinElementsMgr::rootpathstack.removeLastItem(); +} + +void SkinElementsMgr::unloadScriptElements(int scriptid) +{ + int i; + + + WASABI_API_PALETTE->UnloadElements(scriptid); + + Font::uninstallByScriptId(scriptid); + // remove any element inserted into a hierarchical collection + for (i = 0;i < (int)WASABI_API_SVC->service_getNumServices(WaSvc::COLLECTION);i++) + { + waServiceFactory *f = WASABI_API_SVC->service_enumService(WaSvc::COLLECTION, i); + if (f != NULL) + { + svc_collection *svc = static_cast<svc_collection*>(f->getInterface(FALSE)); + svc->removeElement(scriptid); + f->releaseInterface(svc); + } + } +} + +int SkinElementsMgr::elementEqual(const wchar_t *file1, const wchar_t *rootpath1, + const wchar_t *file2, const wchar_t *rootpath2) +{ + + StringPathCombine a(rootpath1, file1); + StringPathCombine b(rootpath2, file2); + + return PATHEQL(a, b); +} + +const wchar_t *SkinElementsMgr::getSkinRootpathFromIncludePath(const wchar_t *includepath, const wchar_t *def) +{ + if (!wcsstr(includepath, L"..")) return def; + + PathParserW pp(includepath); + if (pp.getNumStrings() < 2 || !WCSCASEEQLSAFE(pp.enumString(0), L"skins")) // UNSAFE if the skinpath isn't "skins" + return def; + + StringW baseskin = pp.enumString(1); + + if (wcsstr(includepath, L"..")) + { + int x = 0; + for (int i = 0;i < pp.getNumStrings();i++) + { + const wchar_t *p = pp.enumString(i); + if (WCSICMP(p, L"..")) + { + if (x == 1) + baseskin = pp.enumString(i); + x++; + } + else + x--; + } + } + + t_rootpath = pp.enumString(0); + t_rootpath.AppendFolder(baseskin); + return t_rootpath; +} + +SkinElementsXmlReader SkinElementsMgr::xmlreader; +int SkinElementsMgr::inelements = 0; +int SkinElementsMgr::elementScriptId = -1; +int SkinElementsMgr::oldid, SkinElementsMgr::oldinel; +StringW SkinElementsMgr::rootpath, SkinElementsMgr::original_rootpath, SkinElementsMgr::t_rootpath, SkinElementsMgr::last_includepath; +PtrList<StringW> SkinElementsMgr::rootpathstack; +PtrListQuickSorted<xml_elementtag, XmlElementTagComp> SkinElementsMgr::quickxmltaglist; diff --git a/Src/Wasabi/api/skin/skinelem.h b/Src/Wasabi/api/skin/skinelem.h new file mode 100644 index 00000000..bc4f8185 --- /dev/null +++ b/Src/Wasabi/api/skin/skinelem.h @@ -0,0 +1,106 @@ +#ifndef _SKINELEM_H +#define _SKINELEM_H + +#include <api/xml/xmlreader.h> +#include <tataki/region/region.h> + +#include <api/skin/skinitem.h> +#include <api/xml/xmlparamsi.h> + +typedef struct +{ + const wchar_t *tagname; + int id; + int needclosetag; +} +xml_elementtag; + +class XmlElementTagComp +{ +public: + static int compareItem(void *p1, void *p2) + { + return WCSICMP(((xml_elementtag *)p1)->tagname, ((xml_elementtag *)p2)->tagname); + } + static int compareAttrib(const wchar_t *attrib, void *item) + { + return WCSICMP(attrib, ((xml_elementtag *)item)->tagname); + } +}; + +enum { + XML_ELEMENTTAG_UNKNOWN = 0, + XML_ELEMENTTAG_ELEMENTS, + XML_ELEMENTTAG_ELEMENTALIAS, + XML_ELEMENTTAG_BITMAP, + XML_ELEMENTTAG_COLOR, + XML_ELEMENTTAG_BITMAPFONT, + XML_ELEMENTTAG_TRUETYPEFONT, + XML_ELEMENTTAG_CURSOR, + +}; + + +class ElementRegionServer; + +/*typedef enum { + SKIN_BITMAP_ELEMENT, + SKIN_FONT_ELEMENT, + SKIN_CURSOR_ELEMENT, + SKIN_COLOR_ELEMENT +} SkinElementType;*/ + + + + +class SkinElementsXmlReader : public XmlReaderCallbackI +{ +public: + void xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params); + void xmlReaderOnEndElementCallback(const wchar_t *xmltag); +}; + +class SkinElementsMgr +{ +public: + static void init(); + static void deinit(); + + static void onBeforeLoadingSkinElements(const wchar_t *rootpath); + static void onAfterLoadingSkinElements(); + + static void onBeforeLoadingScriptElements(const wchar_t *name, int script_id); + static void onAfterLoadingScriptElements(); + + static void resetSkinElements(); + static void unloadScriptElements(int scriptid); + + static void xmlReaderOnStartElementCallback( const wchar_t *xmltag, skin_xmlreaderparams *params); + static void _xmlReaderOnStartElementCallback( int tagid, const wchar_t *xmltag, skin_xmlreaderparams *params); + static void xmlReaderOnEndElementCallback( const wchar_t *xmltag); + + static const wchar_t *getSkinRootpathFromIncludePath(const wchar_t *includepath, const wchar_t *def); + static int elementEqual(const wchar_t *file1, const wchar_t *rootpath1, + const wchar_t *file2, const wchar_t *rootpath2); + + + +private: + static SkinElementsXmlReader xmlreader; + + static int inelements; + static int elementScriptId; + + static int oldid, oldinel; + static StringW rootpath; + static StringW original_rootpath; + static StringW t_rootpath; + static StringW last_includepath; + static PtrList<StringW> rootpathstack; + + static PtrListQuickSorted<xml_elementtag, XmlElementTagComp> quickxmltaglist; +}; + + + +#endif diff --git a/Src/Wasabi/api/skin/skinfilter.cpp b/Src/Wasabi/api/skin/skinfilter.cpp new file mode 100644 index 00000000..03dca473 --- /dev/null +++ b/Src/Wasabi/api/skin/skinfilter.cpp @@ -0,0 +1,18 @@ +#include <precomp.h> +#include "skinfilter.h" +#include <api/service/svcs/svc_skinfilter.h> + +void ApplySkinFilters::apply(const wchar_t *elementid, const wchar_t *forced_gammagroup, ARGB32 *bits, int w, int h, int bpp) +{ + if ((elementid == NULL && forced_gammagroup == NULL) || bits == NULL || w <= 0 || h <= 0) + return; + SkinFilterEnum sfe; + + while (1) + { + svc_skinFilter *obj = sfe.getNext(FALSE); + if (!obj) break; + obj->filterBitmap((uint8_t *)bits, w, h, bpp, elementid, forced_gammagroup); + sfe.getLastFactory()->releaseInterface(obj); + } +} diff --git a/Src/Wasabi/api/skin/skinfilter.h b/Src/Wasabi/api/skin/skinfilter.h new file mode 100644 index 00000000..7fa0aaa8 --- /dev/null +++ b/Src/Wasabi/api/skin/skinfilter.h @@ -0,0 +1,12 @@ +#ifndef _SKINFILTER_H +#define _SKINFILTER_H + +#include <bfc/wasabi_std.h> + +class ApplySkinFilters +{ +public: + static void apply(const wchar_t *element_id, const wchar_t *forced_gammagroup, ARGB32 *bits, int w, int h, int bpp=32); +}; + +#endif diff --git a/Src/Wasabi/api/skin/skinfont.cpp b/Src/Wasabi/api/skin/skinfont.cpp new file mode 100644 index 00000000..1c370e3f --- /dev/null +++ b/Src/Wasabi/api/skin/skinfont.cpp @@ -0,0 +1,48 @@ +#include <precomp.h> + +#include "skinfont.h" + +#include <bfc/wasabi_std.h> + +SkinFont::SkinFont() +{} + +SkinFont::~SkinFont() +{ + if (!tempFn.isempty()) + { +#ifdef WIN32 + RemoveFontResourceW(tempFn); +#else + DebugString( "portme -- SkinFont::~SkinFont\n" ); +#endif + UNLINK(tempFn); + } +} + +int SkinFont::setXmlOption(const wchar_t *paramname, const wchar_t *strvalue) +{ + return 0; +} + +void SkinFont::installFont(const wchar_t *filename, const wchar_t *path) +{ + OSFILETYPE in, out; + StringPathCombine temp(path, filename); + in = WFOPEN(temp, WF_READONLY_BINARY); + if (in == OPEN_FAILED) return ; + int len = (int)FGETSIZE(in); + MemBlock<char> m(len); + FREAD(m.getMemory(), len, 1, in); + tempFn = TMPNAM(NULL); + out = WFOPEN(tempFn, WF_WRITE_BINARY); + ASSERT(out != OPEN_FAILED); + FWRITE(m.getMemory(), len, 1, out); + FCLOSE(out); + FCLOSE(in); +#ifdef WIN32 + AddFontResourceW(tempFn); +#else + DebugString( "portme -- SkinFont::installFont\n" ); +#endif +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/skinfont.h b/Src/Wasabi/api/skin/skinfont.h new file mode 100644 index 00000000..b70895e0 --- /dev/null +++ b/Src/Wasabi/api/skin/skinfont.h @@ -0,0 +1,17 @@ +#ifndef _SKINFONT_H +#define _SKINFONT_H + +#include <api/skin/xmlobject.h> + +class SkinFont : public XmlObjectI +{ +public: + SkinFont(); + ~SkinFont(); + void installFont(const wchar_t *filename, const wchar_t *path); + virtual int setXmlOption(const wchar_t *name, const wchar_t *val); +private: + StringW tempFn; +}; + +#endif diff --git a/Src/Wasabi/api/skin/skinitem.cpp b/Src/Wasabi/api/skin/skinitem.cpp new file mode 100644 index 00000000..d4f0f1b3 --- /dev/null +++ b/Src/Wasabi/api/skin/skinitem.cpp @@ -0,0 +1,14 @@ +#include <precomp.h> +#include "skinitem.h" + +#ifdef CBCLASS +#undef CBCLASS +#endif +#define CBCLASS SkinItemI +START_DISPATCH; + CB(SKINITEM_GETXMLROOTPATH, getXmlRootPath); + CB(SKINITEM_GETNAME, getName); + CB(SKINITEM_GETPARAMS, getParams); + CB(SKINITEM_GETSKINPARTID, getSkinPartId); + CB(SKINITEM_GETANCESTOR, getAncestor); +END_DISPATCH; diff --git a/Src/Wasabi/api/skin/skinitem.h b/Src/Wasabi/api/skin/skinitem.h new file mode 100644 index 00000000..88d82c13 --- /dev/null +++ b/Src/Wasabi/api/skin/skinitem.h @@ -0,0 +1,66 @@ +#ifndef __SKINITEM_H +#define __SKINITEM_H + +#include <bfc/dispatch.h> +#include "../xml/ifc_xmlreaderparams.h" + +class skin_xmlreaderparams; + +class SkinItem : public Dispatchable +{ + public: + const wchar_t *getXmlRootPath(); + const wchar_t *getName(); + ifc_xmlreaderparams *getParams(); + int getSkinPartId(); + SkinItem *getAncestor(); + + enum + { + SKINITEM_GETXMLROOTPATH = 0, + SKINITEM_GETNAME = 10, + SKINITEM_GETPARAMS = 20, + SKINITEM_GETSKINPARTID = 30, + SKINITEM_GETANCESTOR = 40, + }; +}; + +inline const wchar_t *SkinItem::getXmlRootPath() +{ + return _call(SKINITEM_GETXMLROOTPATH, (const wchar_t *)0); +} + +inline const wchar_t *SkinItem::getName() +{ + return _call(SKINITEM_GETNAME, (const wchar_t *)0); +} + +inline ifc_xmlreaderparams *SkinItem::getParams() +{ + return _call(SKINITEM_GETPARAMS, (ifc_xmlreaderparams *)NULL); +} + +inline int SkinItem::getSkinPartId() +{ + return _call(SKINITEM_GETSKINPARTID, (int)0); +} + +inline SkinItem *SkinItem::getAncestor() +{ + return _call(SKINITEM_GETANCESTOR, (SkinItem *)NULL); +} + +class SkinItemI : public SkinItem +{ + public: + virtual const wchar_t *getXmlRootPath()=0; + virtual const wchar_t *getName()=0; + virtual ifc_xmlreaderparams *getParams()=0; + virtual int getSkinPartId()=0; + virtual SkinItem *getAncestor()=0; + + protected: + RECVS_DISPATCH; +}; + +#endif diff --git a/Src/Wasabi/api/skin/skinparse.cpp b/Src/Wasabi/api/skin/skinparse.cpp new file mode 100644 index 00000000..7df77e81 --- /dev/null +++ b/Src/Wasabi/api/skin/skinparse.cpp @@ -0,0 +1,1822 @@ +#include <precomp.h> +#include <api.h> +#include <api/skin/widgets/mb/scriptbrowser.h> +#include <api/skin/skinparse.h> +#include <api/script/scriptmgr.h> +//#include <api/wac/main.h>//CUT!! +#include <api/skin/skinfont.h> +#include <api/skin/skin.h> +#include <api/skin/skinelem.h> +#include <api/font/font.h> +#include <api/wndmgr/snappnt.h> +#include <bfc/parse/pathparse.h> +#include <api/skin/guitree.h> +#ifdef WASABI_COMPILE_COMPONENTS +#include <api/wac/compon.h> +#endif +#include <api/service/svc_enum.h> +#include <api/script/objects/guiobject.h> +#ifdef WASABI_COMPILE_WNDMGR +#include <api/wndmgr/autopopup.h> +#endif +#include <bfc/parse/paramparser.h> +#include <api/skin/gammamgr.h> +#include <bfc/util/profiler.h> +#ifdef WASABI_COMPILE_LOCALES +#include <api/locales/xlatstr.h> +#include <api/locales/localesmgr.h> +#else +#define _ +#endif +#include <bfc/string/stringdict.h> +#include <api/skin/widgets.h> + +#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<svc_xuiObject>; +} + +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<Layout *>(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<ifc_xmlreaderparams> 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<XmlObject *>(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<ifc_xmlreaderparams> *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<XmlObject *>(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<XmlObject *>(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<XmlObject *>(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<svc_xuiObject>(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<XmlObject *>(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<GuiObjectWnd *>(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;i<n;i++) { + Layout *l = c->enumLayout(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;i<n;i++) { + Layout *l = c->enumLayout(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<parser_status> SkinParser::statusstack; +int SkinParser::instantiatinggroup = 0; +int SkinParser::allowscripts = 0; +skin_xmlreaderparams *SkinParser::groupparams = NULL; +PtrListQuickSorted<xml_tag, XmlTagComp> 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<Container> SkinParser::script_containers; +PtrList<Container> SkinParser::containers; +int SkinParser::centerskin; +int SkinParser::transcientcontainer; +SvcCacheT<svc_xuiObject> *SkinParser::xuiCache; +int SkinParser::loading_main_skinfile = 0; +StringW SkinParser::includepath; +#endif diff --git a/Src/Wasabi/api/skin/skinparse.h b/Src/Wasabi/api/skin/skinparse.h new file mode 100644 index 00000000..b232e92d --- /dev/null +++ b/Src/Wasabi/api/skin/skinparse.h @@ -0,0 +1,337 @@ +#ifndef __SKINPARSER_H +#define __SKINPARSER_H + +#include <bfc/wasabi_std.h> +#include <api/wnd/basewnd.h> +#include <api/service/svccache.h> + +#ifdef WASABI_COMPILE_WNDMGR +#include <api/wndmgr/layout.h> +#include <api/wndmgr/container.h> +#else +class Container; +class Layout; +#endif + +#ifdef WASABI_COMPILE_FONTS +#include <api/font/skinfont.h> +#endif + +#ifdef WASABI_COMPILE_XMLPARSER +#include <api/xml/xmlreader.h> +#else +class skin_xmlreaderparams; +#endif + +#ifdef WASABI_COMPILE_SKIN +#include <api/skin/group.h> +#else +class Group; +class SkinItem; +#endif + +class XmlObject; + +enum { + PARSETYPE_RESIZE=0, + PARSETYPE_COLOR, + PARSETYPE_COLORALPHA, + PARSETYPE_REGIONOP, + PARSETYPE_INTERNALACTION, + PARSETYPE_GROUPINHERITANCE, +} ; + +enum { + XML_TAG_CONTAINER, + XML_TAG_GROUP, + XML_TAG_CFGGROUP, + XML_TAG_GROUPDEF, + XML_TAG_LAYOUT, + XML_TAG_ACCELERATORS, + XML_TAG_ACCELERATOR, + XML_TAG_ELEMENTS, + XML_TAG_STRINGTABLE, + XML_TAG_STRINGENTRY, + XML_TAG_SCRIPTS, + XML_TAG_SNAPPOINT, + XML_TAG_TRUETYPEFONT, + XML_TAG_BITMAPFONT, + XML_TAG_SCRIPT, + XML_TAG_UNKNOWN, +}; + +#define GROUP_INHERIT_NOTHING 0 +#define GROUP_INHERIT_XUIOBJECTS 1 +#define GROUP_INHERIT_SCRIPTS 2 +#define GROUP_INHERIT_PARAMS 4 +#define GROUP_INHERIT_ALL GROUP_INHERIT_XUIOBJECTS | GROUP_INHERIT_SCRIPTS | GROUP_INHERIT_PARAMS +#define GROUP_INHERIT_ALLCONTENT GROUP_INHERIT_XUIOBJECTS | GROUP_INHERIT_SCRIPTS + +#define GROUP_GROUP 0 +#define GROUP_CFGGROUP 1 + +#ifdef WASABI_COMPILE_WNDMGR +#define GROUP_LAYOUTGROUP 2 +#endif + +enum { + ACTION_NONE, + ACTION_UNIMPLEMENTED=0x1000, + ACTION_MINIMIZE, + ACTION_MAXIMIZE, + ACTION_CLOSE, + ACTION_ABOUT, + ACTION_SWITCH, + ACTION_TOGGLE, + ACTION_SYSMENU, + ACTION_CONTROLMENU, + ACTION_REPORT_BUGS, + ACTION_MB_BACK, //FG + ACTION_MB_FORWARD, //FG + ACTION_MB_URL, //FG + ACTION_MB_STOP, //FG + ACTION_MB_REFRESH, //FG + ACTION_MB_HOME, //FG + ACTION_CB_NEXT, //FG + ACTION_CB_PREV, //FG + ACTION_CB_NEXTPAGE, + ACTION_CB_PREVPAGE, + ACTION_SCALE_50, //FG + ACTION_SCALE_75, //FG + ACTION_SCALE_100, //FG + ACTION_SCALE_125, //FG + ACTION_SCALE_150, //FG + ACTION_SCALE_200, //FG + ACTION_SCALE_400, //BU :) + ACTION_RELOAD_SKIN, + ACTION_TEXT_LARGER, + ACTION_TEXT_SMALLER, + ACTION_PREFERENCES, + ACTION_REGISTRY, + ACTION_ALPHA_10, //FG + ACTION_ALPHA_20, //FG + ACTION_ALPHA_30, //FG + ACTION_ALPHA_40, //FG + ACTION_ALPHA_50, //FG + ACTION_ALPHA_60, //FG + ACTION_ALPHA_70, //FG + ACTION_ALPHA_80, //FG + ACTION_ALPHA_90, //FG + ACTION_ALPHA_100, //FG + ACTION_AOT, //BU always-on-top for this window only + ACTION_TOGGLE_ALWAYS_ON_TOP, + ACTION_MENU, + ACTION_VIEW_FILE_INFO, + ACTION_ADD_BOOKMARK, + ACTION_EDIT_BOOKMARKS, + ACTION_ENDMODAL, + ACTION_ENFORCEMINMAX, + ACTION_DOUBLESIZE, + ACTION_CLOSE_WINDOW, + ACTION_WINDOWMENU, + ACTION_EQ_TOGGLE, + ACTION_AUTOOPACIFY, +}; + +enum { + DISPLAY_NONE, + DISPLAY_SONGNAME, + DISPLAY_SONGINFO, + DISPLAY_SONGTITLE, //BU + DISPLAY_SONGARTIST, + DISPLAY_SONGALBUM, + DISPLAY_SONGLENGTH, + DISPLAY_TIME, + DISPLAY_CB, //FG + DISPLAY_SONGBITRATE, + DISPLAY_SONGSAMPLERATE, + DISPLAY_SERVICE, + DISPLAY_SONGINFO_TRANSLATED, +}; + +enum { + ORIENTATION_HORIZONTAL, + ORIENTATION_VERTICAL +}; + +enum { + ALIGN_TOP, + ALIGN_BOTTOM, +}; + +typedef struct +{ + const wchar_t *tagname; + int id; + int needclosetag; +} xml_tag; + +class XmlTagComp +{ +public: + static int compareItem(void *p1, void *p2) + { + return WCSICMP(((xml_tag *)p1)->tagname, ((xml_tag *)p2)->tagname); + } + static int compareAttrib(const wchar_t *attrib, void *item) + { + return WCSICMP(attrib, ((xml_tag *)item)->tagname); + } +}; + +typedef struct { + int staticloading; + int recording_container; + int recording_groupdef; + Group *curGroup; + int inElements; + int inAccelerators; + int inStringTable; + int inGroupDef; + int inGroup; + StringW includepath; + skin_xmlreaderparams *groupparams; + int instantiatinggroup; + int scriptid; + int allowscripts; +#ifdef WASABI_COMPILE_WNDMGR + Container *curContainer; + Layout *curLayout; + int inContainer; + int inLayout; + int transcientcontainer; +#endif +} parser_status; + +class SkinParser { + +public: + static void initialize(); + static void shutdown(); + + static void setInitialFocus(); + + static GuiObject *newDynamicGroup(const wchar_t *groupid, int grouptype=GROUP_GROUP, SkinItem *item=NULL, int specific_scriptid=-1, int scripts_enabled=1); + static void parseGroup(SkinItem *groupitem, PtrList<ifc_xmlreaderparams> *ancestor_param_list, int params_only=0, int content_flags=GROUP_INHERIT_ALL); + static void loadScriptXml(const wchar_t *filename, int scriptid); + + static void xmlReaderCallback(int start, const wchar_t *xmltag, skin_xmlreaderparams *params); + static void onXmlStartElement(const wchar_t *name, skin_xmlreaderparams *params); + static void onXmlEndElement(const wchar_t *name); + + static void _onXmlStartElement(int object_type, const wchar_t *object_name, ifc_xmlreaderparams *params); + static void _onXmlEndElement(int object_type, const wchar_t *object_name); + +#ifdef WASABI_COMPILE_WNDMGR + static GUID *getComponentGuid(const wchar_t *id); + static int getComponentGuid(GUID *g, const wchar_t *p); +#endif + +#ifdef WASABI_COMPILE_WNDMGR + static int loadContainers(const wchar_t *skin); // todo: change name + static void startupContainers(int scriptid=-1); // todo: change name + static Container *loadContainerForWindowHolder(const wchar_t *groupid=NULL, GUID g=INVALID_GUID, int initit=1, int transcient=0, const wchar_t *containerid=NULL/*any*/, int container_flag=0/*dontcare*/); + static Container *newDynamicContainer(const wchar_t *containerid, int transcient=0); + static Container *getContainer(const wchar_t *name); + static Layout *getLayout(const wchar_t *container_layout_pair); + static Container *script_getContainer(const wchar_t *name); + static Container *instantiateDynamicContainer(SkinItem *containeritem, int initit=1); + static void componentToggled(GUID *g, int visible); + static void sendNotifyToAllContainers(int notifymsg, int param1=0, int param2=0); + static void toggleContainer(const wchar_t *); + static void toggleContainer(int); + static void showContainer(int num, int show); + static void showContainer(const wchar_t *, int show); + static PtrList<Container> containers; + //static PtrList<Container> script_containers; + static int getNumContainers(); + static Container *enumContainer(int n); + static int script_getNumContainers(); + static Container *script_enumContainer(int id); + static int isContainer(Container *c); + static int verifyContainer(Container *); + static void unloadAllContainers(); + static const wchar_t *getCurrentContainerId(); +#endif + + static void cleanupScript(int scriptid); + static void cleanUp(); +#ifdef WA3COMPATIBILITY + static void emmergencyReloadDefaultSkin(); +#endif + static void initGuiObject(GuiObject *o, Group *pgroup); + static void initXmlObject(XmlObject *x, ifc_xmlreaderparams *params, int no_id=0); + static void initLayout(Layout *l, Container *c); + + static int getAction(const wchar_t *action, const wchar_t **name=NULL); + static int getDisplay(const wchar_t *display); + static int getAlign(const wchar_t *align); + static int getOrientation(const wchar_t *orient); + static int parse(const wchar_t *str, const wchar_t *how); + static int parseResize(const wchar_t *r); + static int parseRegionOp(const wchar_t *r); + static int parseGroupInheritance(const wchar_t *str); + static ARGB32 parseColor(const wchar_t *color, int *error=NULL); // 1 for bitmap colors please + static ARGB32 parseColorAlpha(const wchar_t *color); // 1 for bitmap colors please + static const wchar_t *getXmlRootPath(); + static void pushParserState(); + static void popParserState(); + +#ifdef WASABI_COMPILE_WNDMGR + static void noCenterSkin() { centerskin=0; } +#endif + static const wchar_t *getCurrentGroupId(); + static void destroyGuiObject(GuiObject *o); + static void fillGroup(Group *group, const wchar_t *groupid, SkinItem *specific_item=NULL, int params_only=0, int no_params=0, int scripts_enabled=1); + + static int getSkinRect(RECT *r, ifc_window *exclude=NULL); + static void centerSkin(); + static void focusFirst(); + + static GuiObject *xui_new(const wchar_t *classname); + static void xui_delete(GuiObject *o); + + static double getSkinVersion(); + + static void setAllLayoutsRatio(double ra); + static void setAllLayoutsTransparency(int v); +// static void setAllLayoutsAutoOpacify(int v, int force=0); +// static void setAllLayoutsOverrideAlpha(int oa); + static Layout *getMainLayout(); + +private: + static GuiObject *createExternalGuiObject(const wchar_t *object_name, XmlObject **x, ifc_xmlreaderparams *params); + + static int getHex(const wchar_t *p,int size=-1); + + // xml parser handlers + static Group *curGroup, *lastCreatedGroup; + static int inScripts; + static int inElements, inAccelerators, inStringTable; + static int inGroupDef, inGroup; + static StringW includepath; + static int recording_container; + static int recording_groupdef; + static int staticloading; + static PtrList<parser_status> statusstack; + static int instantiatinggroup; + static int scriptId; + static int allowscripts; + static skin_xmlreaderparams *groupparams; + +#ifdef WASABI_COMPILE_WNDMGR + static Container *curContainer, *lastCreatedContainer; + static Layout *curLayout; + static int centerskin; + static int transcientcontainer; + static int inContainer; + static int inLayout; +#endif + static double skinversion; + static int loading_main_skinfile; + + static PtrListQuickSorted<xml_tag,XmlTagComp> quickxmltaglist; + static SvcCacheT<svc_xuiObject> *xuiCache; +}; + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets.cpp b/Src/Wasabi/api/skin/widgets.cpp new file mode 100644 index 00000000..86fe0f05 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets.cpp @@ -0,0 +1,451 @@ +#include <precomp.h> +#include <api/skin/widgets.h> + +#include <api/skin/widgets/group.h> + +#ifdef WASABI_WIDGETS_LAYER +#include <api/skin/widgets/layer.h> +#endif + +#ifdef WASABI_WIDGETS_ANIMLAYER +#include <api/skin/widgets/animlayer.h> +#endif + +#ifdef WASABI_WIDGETS_BUTTON +#include <api/skin/widgets/button.h> +#endif + +#ifdef WASABI_WIDGETS_TGBUTTON +#include <api/skin/widgets/tgbutton.h> +#endif + +#ifdef WASABI_WIDGETS_GUIOBJECT +#include <api/script/objects/guiobj.h> +#endif + +#ifdef WASABI_WIDGETS_GROUPLIST +#include <api/skin/widgets/grouplist.h> +#endif + +#ifdef WASABI_WIDGETS_MOUSEREDIR +#include <api/skin/widgets/mouseredir.h> +#endif + +#ifdef WASABI_WIDGETS_SLIDER +#include <api/skin/widgets/pslider.h> +#endif + +#ifdef WASABI_WIDGETS_MEDIASLIDERS +#include <api/skin/widgets/seqband.h> +#include <api/skin/widgets/seqpreamp.h> +#include <api/skin/widgets/svolbar.h> +#include <api/skin/widgets/sseeker.h> +#include <api/skin/widgets/spanbar.h> +#endif + +#ifdef WASABI_WIDGETS_MEDIAVIS +#include <api/skin/widgets/sa.h> +#endif + +#ifdef WASABI_WIDGETS_MEDIAEQCURVE +#include <api/skin/widgets/seqvis.h> +#endif + +#ifdef WASABI_WIDGETS_MEDIASTATUS +#include <api/skin/widgets/sstatus.h> +#endif + +#ifdef _WIN32 +#include <api/skin/widgets/wa2/xuiwa2slider.h> +#endif + +#ifdef WASABI_WIDGETS_SVCWND +#include <api/skin/widgets/script/svcwnd.h> +#endif + +#ifdef WASABI_WIDGETS_TEXT +#include <api/skin/widgets/text.h> +#endif + +#ifdef WASABI_WIDGETS_EDIT +#include <api/skin/widgets/edit.h> +#endif + +#ifdef WASABI_WIDGETS_TITLEBAR +#include <api/skin/widgets/title.h> +#endif + +#ifdef WASABI_WIDGETS_COMPBUCK +#include <api/skin/widgets/compbuck2.h> +#endif + +#ifdef WASABI_WIDGETS_BROWSER +#include <api/skin/widgets/mb/xuibrowser.h> +#ifdef WASABI_WIDGETS_BROWSERSVC +#include <api/skin/widgets/mb/iebrowser.h> +#include <api/skin/widgets/mb/mbsvc.h> +#endif +#endif + +#ifdef WASABI_WIDGETS_FRAME +#include <api/skin/widgets/xuiframe.h> +#endif + +#ifdef WASABI_WIDGETS_GRID +#include <api/skin/widgets/xuigrid.h> +#endif + +#ifdef WASABI_WIDGETS_QUERYDRAG +#include <api/skin/widgets/xuiquerydrag.h> +#endif + +#ifdef WASABI_WIDGETS_QUERYLIST +#include <api/skin/widgets/db/xuiquerylist.h> +#endif + +#ifdef WASABI_WIDGETS_FILTERLIST +#include <api/skin/widgets/db/xuifilterlist.h> +#endif + +#ifdef WASABI_WIDGETS_QUERYLINE +#include <api/skin/widgets/db/xuiqueryline.h> +#endif + +#ifdef WASABI_WIDGETS_WNDHOLDER +#include <api/skin/widgets/xuiwndholder.h> +#endif + +#ifdef WASABI_COMPILE_WNDMGR + +#ifdef WASABI_WIDGETS_LAYOUTSTATUS +#include <api/skin/widgets/xuistatus.h> +#endif + +#endif // wndmgr + +#ifdef WASABI_WIDGETS_TABSHEET +#include <api/skin/widgets/xuitabsheet.h> +#endif + +#ifdef WASABI_WIDGETS_CHECKBOX +#include <api/skin/widgets/xuicheckbox.h> +#endif + +#ifdef WASABI_WIDGETS_TITLEBOX +#include <api/skin/widgets/xuititlebox.h> +#endif + +#ifdef WASABI_WIDGETS_CUSTOMOBJECT +#include <api/skin/widgets/xuicustomobject.h> +#endif + +#ifdef WASABI_WIDGETS_OSWNDHOST +#include <api/skin/widgets/xuioswndhost.h> +#endif + +#ifdef WASABI_WIDGETS_RADIOGROUP +#include <api/skin/widgets/xuiradiogroup.h> +#endif + +#ifdef WASABI_TOOLOBJECT_HIDEOBJECT +#include <api/skin/widgets/xuihideobject.h> +#endif + +#ifdef WASABI_TOOLOBJECT_SENDPARAMS +#include <api/skin/widgets/xuisendparams.h> +#endif + +#ifdef WASABI_TOOLOBJECT_ADDPARAMS +#include <api/skin/widgets/xuiaddparams.h> +#endif + +#ifdef WASABI_WIDGETS_LIST +#include <api/skin/widgets/xuilist.h> +#endif + +#ifdef WASABI_WIDGETS_TREE +#include <api/skin/widgets/xuitree.h> +#endif + +#ifdef WASABI_WIDGETS_DROPDOWNLIST +#include <api/skin/widgets/xuidropdownlist.h> +#endif + +#ifdef WASABI_WIDGETS_COMBOBOX +#include <api/skin/widgets/xuicombobox.h> +#endif + +#ifdef WASABI_WIDGETS_HISTORYEDITBOX +#include <api/skin/widgets/xuihistoryedit.h> +#endif + +#ifdef WASABI_WIDGETS_OBJECTDIRECTORY +#include <api/skin/widgets/xuiobjdirwnd.h> +#endif + +#ifdef WASABI_WIDGETS_RECTANGLE +#include <api/skin/widgets/xuirect.h> +#endif + +#ifdef WASABI_WIDGETS_PATHPICKER +#include <api/skin/widgets/xuipathpicker.h> +#endif + +#ifdef WASABI_WIDGETS_GRADIENT +#include <api/skin/widgets/xuigradientwnd.h> +#endif + +#ifdef WASABI_WIDGETS_MENU +#include <api/skin/widgets/xuimenu.h> +#endif + +#include <api/skin/widgets/xuidownloadslist.h> + +#ifdef WASABI_COMPILE_STATSWND +#include <api/skin/widgets/stats/xuistats.h> +#include <api/skin/widgets/stats/statswnd.h> +#endif + +extern StringW g_resourcepath; + +Widgets::Widgets() { + count = 0; + + registerService(new XuiObjectCreator<GuiObjectXuiSvc>); + + #ifdef WASABI_WIDGETS_LAYER + registerService(new XuiObjectCreator<LayerXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_ANIMLAYER + registerService(new XuiObjectCreator<AnimLayerXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_BUTTON + registerService(new XuiObjectCreator<ButtonXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_TGBUTTON + registerService(new XuiObjectCreator<ToggleButtonXuiSvc>); + registerService(new XuiObjectCreator<nStatesTgButtonXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_GROUPLIST + registerService(new XuiObjectCreator<GroupListXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_MOUSEREDIR + registerService(new XuiObjectCreator<MouseRedirXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_SLIDER + registerService(new XuiObjectCreator<SliderXuiSvc>); + #endif +#ifdef _WIN32 + registerService(new XuiObjectCreator<Wa2SliderXuiSvc>); +#endif + #ifdef WASABI_WIDGETS_MEDIASLIDERS + registerService(new XuiObjectCreator<EqBandXuiSvc>); + registerService(new XuiObjectCreator<EqPreAmpXuiSvc>); + registerService(new XuiObjectCreator<VolBarXuiSvc>); + registerService(new XuiObjectCreator<SeekBarXuiSvc>); + registerService(new XuiObjectCreator<PanBarXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_MEDIAVIS + registerService(new XuiObjectCreator<VisXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_MEDIAEQCURVE + registerService(new XuiObjectCreator<EqVisXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_MEDIASTATUS + registerService(new XuiObjectCreator<StatusXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_SVCWND + registerService(new XuiObjectCreator<SvcWndXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_TEXT + registerService(new XuiObjectCreator<TextXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_EDIT + registerService(new XuiObjectCreator<EditXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_TITLEBAR + registerService(new XuiObjectCreator<TitleBarXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_COMPBUCK + registerService(new XuiObjectCreator<ComponentBucketXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_BROWSER + registerService(new XuiObjectCreator<BrowserXuiSvc>); + #ifdef WASABI_WIDGETS_BROWSERSVC + registerService(new waServiceFactoryT<svc_miniBrowser, MbSvc>); + #endif + #endif + #ifdef WASABI_WIDGETS_FRAME + registerService(new XuiObjectCreator<FrameXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_GRID + registerService(new XuiObjectCreator<GridXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_QUERYDRAG + registerService(new XuiObjectCreator<QueryDragXuiSvc>); + #endif + #ifdef WASABI_COMPILE_METADB + #ifdef WASABI_WIDGETS_QUERYLIST + registerService(new XuiObjectCreator<QueryListXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_FILTERLIST + registerService(new XuiObjectCreator<FilterListXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_QUERYLINE + registerService(new XuiObjectCreator<QueryLineXuiSvc>); + #endif + #endif // metadb + #ifdef WASABI_WIDGETS_WNDHOLDER + registerService(new XuiObjectCreator<WindowHolderXuiSvc>); + registerService(new XuiObjectCreator<WindowHolderXuiSvc2>); + #endif // components + #ifdef WASABI_COMPILE_WNDMGR + #ifdef WASABI_WIDGETS_LAYOUTSTATUS + registerService(new XuiObjectCreator<LayoutStatusXuiSvc>); + #endif + #endif // wndmgr + #ifdef WASABI_WIDGETS_TABSHEET + registerService(new XuiObjectCreator<ScriptTabSheetXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_CHECKBOX + registerService(new XuiObjectCreator<ScriptCheckBoxXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_TITLEBOX + registerService(new XuiObjectCreator<ScriptTitleBoxXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_CUSTOMOBJECT + registerService(new XuiObjectCreator<CustomObjectXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_OSWNDHOST + registerService(new XuiObjectCreator<OSWndHostXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_RADIOGROUP + registerService(new XuiObjectCreator<ScriptRadioGroupXuiSvc>); + #endif + #ifdef WASABI_TOOLOBJECT_HIDEOBJECT + registerService(new XuiObjectCreator<HideObjectXuiSvc>); + #endif + #ifdef WASABI_TOOLOBJECT_SENDPARAMS + registerService(new XuiObjectCreator<SendParamsXuiSvc>); + #endif + #ifdef WASABI_TOOLOBJECT_ADDPARAMS + registerService(new XuiObjectCreator<AddParamsXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_LIST + registerService(new XuiObjectCreator<ScriptListXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_TREE + registerService(new XuiObjectCreator<ScriptTreeXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_DROPDOWNLIST + registerService(new XuiObjectCreator<DropDownListXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_COMBOBOX + registerService(new XuiObjectCreator<ComboBoxXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_HISTORYEDITBOX + registerService(new XuiObjectCreator<HistoryEditXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_OBJECTDIRECTORY + registerService(new XuiObjectCreator<ScriptObjDirWndXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_RECTANGLE + registerService(new XuiObjectCreator<ScriptRectXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_PATHPICKER + registerService(new XuiObjectCreator<PathPickerXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_GRADIENT + registerService(new XuiObjectCreator<GradientWndXuiSvc>); + #endif + #ifdef WASABI_WIDGETS_MENU + registerService(new XuiObjectCreator<MenuXuiSvc>); + #endif + + //registerService(new XuiObjectCreator<DownloadsListXuiSvc>); + + #ifdef WASABI_COMPILE_WNDMGR + //registerSkinFile("xml/msgbox/msgbox.xml"); + #endif + + #ifdef WASABI_WIDGETS_TOOLTIPS + //registerSkinFile("xml/tooltips/tooltips.xml"); + #endif + + #ifdef WASABI_COMPILE_STATSWND + registerService(new XuiObjectCreator<XuiStatsXuiSvc>); + statswnd = new StatsWnd(); + #endif + + //loadResources(); + WASABI_API_SYSCB->syscb_registerCallback(static_cast<SysCallbackI *>(this)); +} + +Widgets::~Widgets() { +#ifdef WASABI_COMPILE_STATSWND + delete statswnd; +#endif + WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SysCallbackI *>(this)); + if (WASABI_API_SVC != NULL) + { + int i=factories.getNumItems(); + while (i--) + WASABI_API_SVC->service_deregister(factories[i]); + } + factories.deleteAll(); +} + + +void Widgets::registerService(waServiceFactoryI *f) +{ + WASABI_API_SVC->service_register(f); + factories.addItem(f); +} + +int Widgets::skincb_onBeforeLoadingElements() { + if (count++ > 0) // if 0, we're already loaded so that the lib is usable without 'a skin' + loadResources(); + return 1; +} + +void Widgets::loadResources() +{ + // TODO: benski> want to put this into gen_ff somewhere, instead. + WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\winamp\\cover\\cover.xml")); + WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\winamp\\thinger\\thinger.xml")); + + #ifndef WA3COMPATIBILITY // ifNdef + WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\wasabi\\wasabi.xml")); + #endif + #ifdef WASABI_WIDGETS_PATHPICKER + WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\pathpicker\\pathpicker.xml")); + #endif + #ifdef WASABI_WIDGETS_LAYOUTSTATUS + WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\statusbar\\statusbar.xml")); + #endif + #ifdef WASABI_WIDGETS_TABSHEET + WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\tabsheet\\tabsheet.xml")); + #endif + #ifdef WASABI_WIDGETS_CHECKBOX + WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\checkbox\\checkbox.xml")); + #endif + #ifdef WASABI_WIDGETS_TITLEBOX + WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\titlebox\\titlebox.xml")); + #endif + #ifdef WASABI_WIDGETS_DROPDOWNLIST + WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\dropdownlist\\dropdownlist.xml")); + #endif + #ifdef WASABI_WIDGETS_COMBOBOX + WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\combobox\\combobox.xml")); + #endif + #ifdef WASABI_WIDGETS_HISTORYEDITBOX + WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\historyeditbox\\historyeditbox.xml")); + #endif + #ifdef WASABI_WIDGETS_TOOLTIPS + WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\tooltips\\tooltips.xml")); + #endif + #ifdef WASABI_COMPILE_WNDMGR + //WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,"xml\\msgbox\\msgbox.xml")); + #endif + WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\about\\about.xml")); +} diff --git a/Src/Wasabi/api/skin/widgets.h b/Src/Wasabi/api/skin/widgets.h new file mode 100644 index 00000000..0089dfd2 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets.h @@ -0,0 +1,35 @@ +#ifndef __WIDGETS_H +#define __WIDGETS_H + +#include <wasabicfg.h> +#include <bfc/ptrlist.h> +#include <api/syscb/callbacks/skincb.h> + +class waServiceFactoryI; + +#ifdef WASABI_COMPILE_STATSWND +class StatsWnd; +#endif + +class Widgets : public SkinCallbackI { + public: + Widgets(); + virtual ~Widgets(); + + void registerService(waServiceFactoryI *f); + int skincb_onBeforeLoadingElements(); + + void loadResources(); + private: + + + PtrList<waServiceFactoryI> factories; + int count; +#ifdef WASABI_COMPILE_STATSWND + StatsWnd *statswnd; +#endif +}; + + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/animlayer.cpp b/Src/Wasabi/api/skin/widgets/animlayer.cpp new file mode 100644 index 00000000..10c7da1a --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/animlayer.cpp @@ -0,0 +1,880 @@ +#include "precomp.h" +#include <api/script/scriptmgr.h> +#include <api/script/script.h> +#include <api/skin/widgets/animlayer.h> +#include <tataki/canvas/canvas.h> + +const wchar_t animLayerXuiObjectStr[] = L"AnimatedLayer"; // This is the xml tag +char animLayerXuiSvcName[] = "Animated Layer xui object"; // this is the name of the xuiservice + +AnimLayerScriptController _animlayerController; +AnimLayerScriptController *animlayerController = &_animlayerController; + +// -- Functions table ------------------------------------- +function_descriptor_struct AnimLayerScriptController::exportedFunction[] = { + {L"setSpeed", 1, (void*)AnimatedLayer::script_vcpu_setSpeed }, + {L"gotoFrame", 1, (void*)AnimatedLayer::script_vcpu_gotoFrame }, + {L"setStartFrame", 1, (void*)AnimatedLayer::script_vcpu_setStartFrame }, + {L"setEndFrame", 1, (void*)AnimatedLayer::script_vcpu_setEndFrame }, + {L"setAutoReplay", 1, (void*)AnimatedLayer::script_vcpu_setAutoReplay }, + {L"play", 0, (void*)AnimatedLayer::script_vcpu_play }, + {L"togglePause", 0, (void*)AnimatedLayer::script_vcpu_pause }, + {L"stop", 0, (void*)AnimatedLayer::script_vcpu_stop }, + {L"pause", 0, (void*)AnimatedLayer::script_vcpu_pause }, + {L"isPlaying", 0, (void*)AnimatedLayer::script_vcpu_isPlaying }, + {L"isPaused", 0, (void*)AnimatedLayer::script_vcpu_isPaused }, + {L"isStopped", 0, (void*)AnimatedLayer::script_vcpu_isStopped }, + {L"getStartFrame", 0, (void*)AnimatedLayer::script_vcpu_getStartFrame }, + {L"getEndFrame", 0, (void*)AnimatedLayer::script_vcpu_getEndFrame }, + {L"getLength", 0, (void*)AnimatedLayer::script_vcpu_getLength }, + {L"getDirection", 0, (void*)AnimatedLayer::script_vcpu_getDirection }, + {L"getAutoReplay", 0, (void*)AnimatedLayer::script_vcpu_getAutoReplay }, + {L"getCurFrame", 0, (void*)AnimatedLayer::script_vcpu_getCurFrame }, + {L"onPlay", 0, (void*)AnimatedLayer::script_vcpu_onPlay }, + {L"onPause", 0, (void*)AnimatedLayer::script_vcpu_onPause }, + {L"onResume", 0, (void*)AnimatedLayer::script_vcpu_onResume }, + {L"onStop", 0, (void*)AnimatedLayer::script_vcpu_onStop }, + {L"onFrame", 1, (void*)AnimatedLayer::script_vcpu_onFrame }, + {L"setRealtime", 1, (void*)AnimatedLayer::script_vcpu_setRealtime }, + }; +// -------------------------------------------------------- + +const wchar_t *AnimLayerScriptController::getClassName() +{ + return L"AnimatedLayer"; +} + +const wchar_t *AnimLayerScriptController::getAncestorClassName() +{ + return L"Layer"; +} + +ScriptObject *AnimLayerScriptController::instantiate() +{ + AnimatedLayer *a = new AnimatedLayer; + ASSERT(a != NULL); + return a->getScriptObject(); +} + +void AnimLayerScriptController::destroy(ScriptObject *o) +{ + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + ASSERT(a != NULL); + delete a; +} + +void *AnimLayerScriptController::encapsulate(ScriptObject *o) +{ + return NULL; // no encapsulation for animatedlayer yet +} + +void AnimLayerScriptController::deencapsulate(void *o) +{} + +int AnimLayerScriptController::getNumFunctions() +{ + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *AnimLayerScriptController::getExportedFunctions() +{ + return exportedFunction; +} + +GUID AnimLayerScriptController::getClassGuid() +{ + return animLayerGuid; +} +XMLParamPair AnimatedLayer::params[] = + { + {ANIMLAYER_AUTOPLAY, L"AUTOPLAY"}, + {ANIMLAYER_AUTOREPLAY, L"AUTOREPLAY"}, + {ANIMLAYER_DEBUG, L"DEBUG"}, + {ANIMLAYER_ELEMENTFRAMES, L"ELEMENTFRAMES"}, + {ANIMLAYER_END, L"END"}, + {ANIMLAYER_FRAMEHEIGHT, L"FRAMEHEIGHT"}, + {ANIMLAYER_FRAMEWIDTH, L"FRAMEWIDTH"}, + {ANIMLAYER_REALTIME, L"REALTIME"}, + {ANIMLAYER_SPEED, L"SPEED"}, + {ANIMLAYER_START, L"START"}, + }; + +AnimatedLayer::AnimatedLayer() +{ + getScriptObject()->vcpu_setInterface(animLayerGuid, (void *)static_cast<AnimatedLayer *>(this)); + getScriptObject()->vcpu_setClassName(L"AnimatedLayer"); + getScriptObject()->vcpu_setController(animlayerController); + autoplay = 0; + startframe = -1; + endframe = -1; + curframe = 0; + autoreplay = 1; + speed = 200; + timerset = 0; + status = ANIM_STOPPED; + realtime = 0; + debug = 0; + style = ANIM_UNKNOWN; + oldstyle = ANIM_UNKNOWN; + frameHeight = AUTOWH; + frameWidth = AUTOWH; + multiple_elements_frames = 0; + + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); +} + +void AnimatedLayer::CreateXMLParameters(int master_handle) +{ + //ANIMLAYER_PARENT::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); +} + +AnimatedLayer::~AnimatedLayer() +{ + bitmap_elements.deleteAll(); + regionlist.deleteAll(); +} + +int AnimatedLayer::onInit() +{ + ANIMLAYER_PARENT::onInit(); + + int w, h; + getGuiObject()->guiobject_getGuiPosition(NULL, NULL, &w, &h, NULL, NULL, NULL, NULL); + if (frameWidth == AUTOWH && w != AUTOWH) setWidth(w, 1); + if (frameHeight == AUTOWH && h != AUTOWH) setHeight(h, 1); + if (style == 0) + { + SkinBitmap *bm = getBitmap(); + if (bm) + { + if (bm->getWidth() != w) style = ANIM_HORZ; + else if (bm->getHeight() != h) style = ANIM_VERT; + } + } + + if (getRegionOp()) + makeRegion(); + reloadMultipleElements(); + + if (autoplay) + { + if (startframe == -1) + setStartFrame(0); + if (endframe == -1) + setEndFrame(getLength() - 1); + play(); + } + return 1; +} + +int AnimatedLayer::setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *strvalue) +{ + if (xuihandle == _xuihandle) + { + switch (xmlattributeid) + { + case ANIMLAYER_AUTOREPLAY: setAutoReplay(WTOI(strvalue)); return 1; + case ANIMLAYER_AUTOPLAY: setAutoPlay(WTOI(strvalue)); return 1; + case ANIMLAYER_SPEED: setSpeed(WTOI(strvalue)); return 1; + case ANIMLAYER_FRAMEHEIGHT: setHeight(WTOI(strvalue)); return 1; + case ANIMLAYER_FRAMEWIDTH: setWidth(WTOI(strvalue)); return 1; + case ANIMLAYER_REALTIME: setRealtime(WTOI(strvalue)); return 1; + case ANIMLAYER_ELEMENTFRAMES: setElementFrames(WTOI(strvalue)); return 1; + case ANIMLAYER_START: setStartFrame(WTOI(strvalue)); return 1; + case ANIMLAYER_END: setEndFrame(WTOI(strvalue)); return 1; + case ANIMLAYER_DEBUG: debug = WTOI(strvalue); return 1; + } + } + return ANIMLAYER_PARENT::setXuiParam(_xuihandle, xmlattributeid, xmlattributename, strvalue); +} + +void AnimatedLayer::_invalidate() +{ + if (realtime) + { + if (isVisible() && !isMinimized()) cascadeRepaint(); + } + else + invalidate(); +} + +void AnimatedLayer::setElementFrames(int n) +{ + if (multiple_elements_frames == n) return ; + multiple_elements_frames = n; + if (n > 0) + { + if (style != ANIM_MULTI) + oldstyle = style; + style = ANIM_MULTI; + } + else + { + style = oldstyle; + oldstyle = ANIM_UNKNOWN; + } + invalidateRegionCache(); +} + +void AnimatedLayer::setHeight(int h, int selfset) +{ + ASSERTPR(selfset || style == ANIM_UNKNOWN, "can't set frameHeight if frameWidth has already been set"); + frameHeight = h; + if (!selfset) style = ANIM_VERT; +} + +int AnimatedLayer::getHeight() +{ + if (style == ANIM_MULTI) + { + SkinBitmap *bm0 = getElementBitmap(0); + if (bm0 == NULL) return AUTOWH; + return bm0->getHeight(); + } + if (style == ANIM_HORZ) + return ANIMLAYER_PARENT::getHeight(); + return frameHeight; +} + +void AnimatedLayer::setWidth(int w, int selfset) +{ + ASSERTPR(selfset || style == ANIM_UNKNOWN, "can't set frameWidth if frameHeight has already been set"); + frameWidth = w; + if (!selfset) style = ANIM_HORZ; +} + +int AnimatedLayer::getWidth() +{ + if (style == ANIM_MULTI) + { + SkinBitmap *bm0 = getElementBitmap(0); + if (bm0 == NULL) return AUTOWH; + return bm0->getWidth(); + } + if (style == ANIM_VERT) + return ANIMLAYER_PARENT::getWidth(); + return frameWidth; +} + +void AnimatedLayer::setRealtime(int r) +{ + realtime = r; +} + +int AnimatedLayer::getLength() +{ + if (style == ANIM_VERT && frameHeight < 0) return 0; + if (style == ANIM_HORZ && frameWidth < 0) return 0; + ASSERT(getBitmap() != NULL); + if (style == ANIM_VERT) + return ANIMLAYER_PARENT::getHeight() / frameHeight; + else if (style == ANIM_HORZ) + return ANIMLAYER_PARENT::getWidth() / frameWidth; + else if (style == ANIM_MULTI) + return multiple_elements_frames; + return 0; +} + +void AnimatedLayer::timerCallback(int id) +{ + switch (id) + { + case TIMER_ANIM: + { + int oldframe = curframe; + for (int i = 0;i < timerclient_getSkipped() + 1;i++) + { + if (curframe == getEndFrame()) + { + if (!autoreplay) + { + stop(); + break; + } + else + curframe = getStartFrame(); + } + else + { + curframe += getDirection(); + if (curframe != oldframe) + script_onFrame(curframe); + } + } + if (curframe != oldframe) + _invalidate(); + break; + } + default: + ANIMLAYER_PARENT::timerCallback(id); + break; + } +} + +int AnimatedLayer::getSourceOffsetY() +{ + if (style == ANIM_MULTI) return 0; + if (style == ANIM_HORZ) return 0; + if (curframe > getLength() - 1) return 0; + return curframe * getHeight(); +} + +int AnimatedLayer::getSourceOffsetX() +{ + if (style == ANIM_MULTI) return 0; + if (style == ANIM_VERT) return 0; + if (curframe > getLength() - 1) return 0; + return curframe * getWidth(); +} + +void AnimatedLayer::setSpeed(int s) +{ + speed = s; + if (status == ANIM_PLAYING) + { + stopTimer(); + startTimer(); + } +} + +void AnimatedLayer::stopTimer() +{ + if (timerset) + { + killTimer(TIMER_ANIM); + timerset = 0; + } +} + +void AnimatedLayer::startTimer() +{ + if (!timerset) + { + setTimer(TIMER_ANIM, speed); + timerset = 1; + } +} + +void AnimatedLayer::play() +{ + gotoFrame(startframe); + startTimer(); + status = ANIM_PLAYING; + script_onPlay(); +} + +void AnimatedLayer::stop() +{ + stopTimer(); + status = ANIM_STOPPED; + script_onStop(); +} + +void AnimatedLayer::pause() +{ + if (status == ANIM_PAUSED) + { + startTimer(); + status = ANIM_PLAYING; + script_onResume(); + } + else + if (status == ANIM_PLAYING) + { + stopTimer(); + status = ANIM_PAUSED; + script_onPause(); + } +} + +int AnimatedLayer::getCurFrame() +{ + return curframe; +} + +void AnimatedLayer::setStartFrame(int s) +{ + if (s < 0) return ; + startframe = s; +} + +void AnimatedLayer::setEndFrame(int e) +{ + if (e < 0) return ; + endframe = e; +} + +void AnimatedLayer::setAutoReplay(int r) +{ + autoreplay = r; +} + +void AnimatedLayer::setAutoPlay(int r) +{ + autoplay = r; + // no need to trigger an event here, we can't be in a script if we + // need to autoplay at xml loading +} + +int AnimatedLayer::getStartFrame() +{ + return startframe == -1 ? 0 : startframe; +} + +int AnimatedLayer::getEndFrame() +{ + return endframe == -1 ? getLength() - 1 : endframe; +} + +int AnimatedLayer::getSpeed() +{ + return speed; +} + +int AnimatedLayer::isPlaying() +{ + return status == ANIM_PLAYING; +} + +int AnimatedLayer::isStopped() +{ + return status == ANIM_STOPPED; +} + +int AnimatedLayer::isPaused() +{ + return status == ANIM_PAUSED; +} + +int AnimatedLayer::getAutoReplay() +{ + return autoreplay; +} + +int AnimatedLayer::getDirection() +{ + return getStartFrame() < getEndFrame() ? 1 : -1; +} + +void AnimatedLayer::gotoFrame(int n) +{ + if (n != curframe) + { + curframe = n; + _invalidate(); + script_onFrame(n); + } +} + +api_region *AnimatedLayer::getBitmapRegion() +{ + if (curframe > getLength() - 1) return NULL; + return regionlist.enumItem(getCurFrame()); +} + +void AnimatedLayer::makeRegion() +{ + if (!isInited()) return ; + regionlist.deleteAll(); + for (int i = 0;i < getLength();i++) + { + RegionI *rg; + if (style == ANIM_VERT) + { + RECT g = {0, i * getHeight(), getWidth(), i * getHeight() + getHeight()}; + rg = new RegionI(getBitmap(), &g, 0, -i * getHeight(), FALSE); + } + else if (style == ANIM_HORZ) + { + RECT g = {i * getWidth(), 0, i * getWidth() + getWidth(), getHeight()}; + rg = new RegionI(getBitmap(), &g, -i * getWidth(), 0, FALSE); + } + else if (style == ANIM_MULTI) + { + RECT g = {0, 0, getWidth(), getHeight()}; + rg = new RegionI(getElementBitmap(i), &g, 0, 0, FALSE); + } + else + return; + regionlist.addItem(rg); + } +} + +void AnimatedLayer::deleteRegion() +{ + regionlist.deleteAll(); +} + +SkinBitmap *AnimatedLayer::getBitmap() +{ + if (style != ANIM_MULTI) + return layer_getBitmap(); + return getElementBitmap(getCurFrame()); +} + +SkinBitmap *AnimatedLayer::getElementBitmap(int n) +{ + return bitmap_elements.enumItem(n); +} + +void AnimatedLayer::reloadMultipleElements() +{ + bitmap_elements.deleteAll(); + if (style != ANIM_MULTI) return ; + // basically blah$$$$.png becomes blah0000.png, blah0001.png etc + for (int i = 0;i < multiple_elements_frames;i++) + { + StringW elementname(layer_getBitmapName()); + elementname.replaceNumericField(i); + bitmap_elements.addItem(new SkinBitmap(elementname)); + } +} + +void AnimatedLayer::setBitmap(const wchar_t *name) +{ + ANIMLAYER_PARENT::setBitmap(name); + reloadMultipleElements(); +} + +// Script virtuals + +int AnimatedLayer::script_getStartFrame() +{ + return getStartFrame(); +} + +int AnimatedLayer::script_getEndFrame() +{ + return getEndFrame(); +} + +int AnimatedLayer::script_getSpeed() +{ + return getSpeed(); +} + +int AnimatedLayer::script_getCurFrame() +{ + return getCurFrame(); +} + +int AnimatedLayer::script_getDirection() +{ + return getDirection(); +} + +int AnimatedLayer::script_getAutoReplay() +{ + return getAutoReplay(); +} + +int AnimatedLayer::script_getLength() +{ + return getLength(); +} + +int AnimatedLayer::script_isPlaying() +{ + return isPlaying(); +} + +int AnimatedLayer::script_isStopped() +{ + return isStopped(); +} + +int AnimatedLayer::script_isPaused() +{ + return isPaused(); +} + +void AnimatedLayer::script_play() +{ + play(); +} + +void AnimatedLayer::script_pause() +{ + pause(); +} + +void AnimatedLayer::script_stop() +{ + stop(); +} + +void AnimatedLayer::script_setStartFrame(int s) +{ + setStartFrame(s); +} + +void AnimatedLayer::script_setEndFrame(int e) +{ + setEndFrame(e); +} + +void AnimatedLayer::script_setRealtime(int r) +{ + setRealtime(r); +} + +void AnimatedLayer::script_setAutoReplay(int r) +{ + setAutoReplay(r); +} +/* +void AnimatedLayer::script_gotoFrame(int n) { + gotoFrame(n); +}*/ + +void AnimatedLayer::script_setSpeed(int n) +{ + setSpeed(n); +} + +void AnimatedLayer::script_onPause() +{ + script_vcpu_onPause(SCRIPT_CALL, getScriptObject()); +} + +void AnimatedLayer::script_onResume() +{ + script_vcpu_onResume(SCRIPT_CALL, getScriptObject()); +} + +void AnimatedLayer::script_onStop() +{ + script_vcpu_onStop(SCRIPT_CALL, getScriptObject()); +} + +void AnimatedLayer::script_onPlay() +{ + script_vcpu_onPlay(SCRIPT_CALL, getScriptObject()); +} + +void AnimatedLayer::script_onFrame(int n) +{ + if (getRegionOp()) { invalidateRegionCache(); getParent()->invalidateWindowRegion(); } + scriptVar _n = SOM::makeVar(SCRIPT_INT); + SOM::assign(&_n, n); + script_vcpu_onFrame(SCRIPT_CALL, getScriptObject(), _n); +} + +// end virtuals + +// VCPU + +scriptVar AnimatedLayer::script_vcpu_gotoFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar f) +{ + SCRIPT_FUNCTION_INIT; + ASSERT(SOM::isNumeric(&f)); + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) a-> /*script_*/gotoFrame(SOM::makeInt(&f)); + RETURN_SCRIPT_VOID; +} + +scriptVar AnimatedLayer::script_vcpu_getLength(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) return MAKE_SCRIPT_INT(a->script_getLength()); + RETURN_SCRIPT_ZERO; +} + +scriptVar AnimatedLayer::script_vcpu_setStartFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s) +{ + SCRIPT_FUNCTION_INIT; + ASSERT(SOM::isNumeric(&s)); + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) a->script_setStartFrame(SOM::makeInt(&s)); + RETURN_SCRIPT_VOID; +} + +scriptVar AnimatedLayer::script_vcpu_setEndFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar e) +{ + SCRIPT_FUNCTION_INIT; + ASSERT(SOM::isNumeric(&e)); + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) a->script_setEndFrame(SOM::makeInt(&e)); + RETURN_SCRIPT_VOID; +} + +scriptVar AnimatedLayer::script_vcpu_setAutoReplay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar rp) +{ + SCRIPT_FUNCTION_INIT; + ASSERT(SOM::isNumeric(&rp)); + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) a->script_setAutoReplay(SOM::makeBoolean(&rp)); + RETURN_SCRIPT_VOID; +} + +scriptVar AnimatedLayer::script_vcpu_play(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) a->script_play(); + RETURN_SCRIPT_VOID; +} + +scriptVar AnimatedLayer::script_vcpu_pause(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) a->script_pause(); + RETURN_SCRIPT_VOID; +} + +scriptVar AnimatedLayer::script_vcpu_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) a->script_stop(); + RETURN_SCRIPT_VOID; +} + +scriptVar AnimatedLayer::script_vcpu_onPlay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS0(o, animlayerController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +scriptVar AnimatedLayer::script_vcpu_onStop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS0(o, animlayerController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +scriptVar AnimatedLayer::script_vcpu_onPause(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS0(o, animlayerController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +scriptVar AnimatedLayer::script_vcpu_onResume(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS0(o, animlayerController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +scriptVar AnimatedLayer::script_vcpu_onFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar f) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS1(o, animlayerController, f); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, f); +} + +scriptVar AnimatedLayer::script_vcpu_getAutoReplay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) return MAKE_SCRIPT_INT(a->script_getAutoReplay()); + RETURN_SCRIPT_ZERO; +} + +scriptVar AnimatedLayer::script_vcpu_getDirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) return MAKE_SCRIPT_INT(a->script_getDirection()); + RETURN_SCRIPT_ZERO; +} + +scriptVar AnimatedLayer::script_vcpu_getStartFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) return MAKE_SCRIPT_INT(a->script_getStartFrame()); + RETURN_SCRIPT_ZERO; +} + +scriptVar AnimatedLayer::script_vcpu_getEndFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) return MAKE_SCRIPT_INT(a->script_getEndFrame()); + RETURN_SCRIPT_ZERO; +} + +scriptVar AnimatedLayer::script_vcpu_isPlaying(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) return MAKE_SCRIPT_BOOLEAN(a->script_isPlaying()); + RETURN_SCRIPT_ZERO; +} + +scriptVar AnimatedLayer::script_vcpu_isPaused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) return MAKE_SCRIPT_BOOLEAN(a->script_isPaused()); + RETURN_SCRIPT_ZERO; +} + +scriptVar AnimatedLayer::script_vcpu_isStopped(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) return MAKE_SCRIPT_BOOLEAN(a->script_isStopped()); + RETURN_SCRIPT_ZERO; +} + +scriptVar AnimatedLayer::script_vcpu_getSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) return MAKE_SCRIPT_INT(a->script_getSpeed()); + RETURN_SCRIPT_ZERO; +} + +scriptVar AnimatedLayer::script_vcpu_getCurFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) return MAKE_SCRIPT_INT(a->script_getCurFrame()); + RETURN_SCRIPT_ZERO; +} + +scriptVar AnimatedLayer::script_vcpu_setSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s) +{ + SCRIPT_FUNCTION_INIT; + ASSERT(SOM::isNumeric(&s)); + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) a->script_setSpeed(SOM::makeInt(&s)); + RETURN_SCRIPT_VOID; +} + +scriptVar AnimatedLayer::script_vcpu_setRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r) +{ + SCRIPT_FUNCTION_INIT; + AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid)); + if (a) a->script_setRealtime(SOM::makeInt(&r)); + RETURN_SCRIPT_VOID; +} + + +int AnimatedLayer::onPaint(Canvas *canvas) +{ + int r = ANIMLAYER_PARENT::onPaint(canvas); + if (debug && canvas != NULL) + { + Wasabi::FontInfo fontInfo; + fontInfo.pointSize = 14; + canvas->textOut(0, 0, StringPrintfW(L"%d", curframe), &fontInfo); + } + return r; +} diff --git a/Src/Wasabi/api/skin/widgets/animlayer.h b/Src/Wasabi/api/skin/widgets/animlayer.h new file mode 100644 index 00000000..94c45606 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/animlayer.h @@ -0,0 +1,214 @@ +#ifndef _ANIMLAYER_H +#define _ANIMLAYER_H + +#include "layer.h" + +// {6B64CD27-5A26-4c4b-8C59-E6A70CF6493A} +static const GUID animLayerGuid = +{ 0x6b64cd27, 0x5a26, 0x4c4b, { 0x8c, 0x59, 0xe6, 0xa7, 0xc, 0xf6, 0x49, 0x3a } }; + +#define ANIMLAYER_SCRIPTPARENT Layer + +class AnimLayerScriptController : public LayerScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return layerController; } + 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); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern AnimLayerScriptController *animlayerController; + + +#ifndef _NOSTUDIO + +#define TIMER_ANIM 872 + +#define ANIM_STOPPED 0 +#define ANIM_PLAYING 1 +#define ANIM_PAUSED 2 + +#define ANIMLAYER_PARENT Layer + +#define ANIM_UNKNOWN 0 +#define ANIM_VERT 1 +#define ANIM_HORZ 2 +#define ANIM_MULTI 3 + +class AnimatedLayer : public ANIMLAYER_SCRIPTPARENT { +public: + AnimatedLayer(); + virtual ~AnimatedLayer(); + + virtual int onInit(); + virtual int getHeight(); + virtual int getWidth(); + virtual void timerCallback(int id); + virtual int getSourceOffsetY(); + virtual int getSourceOffsetX(); + virtual void setAutoPlay(int p); + virtual int setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + virtual void setHeight(int h, int selfset=0); + virtual void setWidth(int w, int selfset=0); + virtual SkinBitmap *getBitmap(); + + void play(); + void pause(); + void stop(); + int getLength(); + void setStartFrame(int s); + void setEndFrame(int e); + void setAutoReplay(int r); + int getStartFrame(); + int getEndFrame(); + int isPlaying(); + int isPaused(); + int isStopped(); + int getSpeed(); + int getDirection(); + void gotoFrame(int n); + void setSpeed(int s); + int getAutoReplay(); + int getCurFrame(); + void setRealtime(int r); + + virtual api_region *getBitmapRegion(); + SkinBitmap *getElementBitmap(int n); + virtual void makeRegion(); + virtual void deleteRegion(); + void reloadMultipleElements(); + virtual void setElementFrames(int n); + virtual void setBitmap(const wchar_t *name); + + virtual int onPaint(Canvas *canvas); + +protected: + /*static */void CreateXMLParameters(int master_handle); + enum { + ANIMLAYER_AUTOREPLAY=0, + ANIMLAYER_AUTOPLAY, + ANIMLAYER_SPEED, + ANIMLAYER_FRAMEHEIGHT, + ANIMLAYER_FRAMEWIDTH, + ANIMLAYER_REALTIME, + ANIMLAYER_ELEMENTFRAMES, + ANIMLAYER_START, + ANIMLAYER_END, + ANIMLAYER_DEBUG, + }; + +private: + int frameHeight, frameWidth; + int startframe; + int endframe; + int status; + int curframe; + int autoreplay; + int speed; + int timerset; + int realtime; + int style; + int autoplay; + PtrList<SkinBitmap> bitmap_elements; + int multiple_elements_frames; + int debug; + int xuihandle; + + void _invalidate(); + + void stopTimer(); + void startTimer(); + + PtrList<RegionI> regionlist; + int oldstyle; + static XMLParamPair params[]; + +// FG> +// -- SCRIPT ----------------------------------------------------- + +public: + + // virtuals + + virtual void script_play(); + virtual void script_pause(); + virtual void script_stop(); + virtual int script_getLength(); + virtual void script_setStartFrame(int s); + virtual void script_setEndFrame(int e); + virtual void script_setAutoReplay(int r); + virtual void script_setSpeed(int a); + virtual int script_getStartFrame(); + virtual int script_getEndFrame(); + virtual int script_getSpeed(); + virtual int script_getDirection(); + virtual int script_getAutoReplay(); + virtual int script_isPlaying(); + virtual int script_isStopped(); + virtual int script_isPaused(); + //virtual void script_gotoFrame(int f); + virtual void script_onFrame(int n); + virtual void script_onStop(); + virtual void script_onPlay(); + virtual void script_onPause(); + virtual void script_onResume(); + virtual int script_getCurFrame(); + virtual void script_setRealtime(int r); + + static scriptVar script_vcpu_setSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s); + static scriptVar script_vcpu_gotoFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar f); + static scriptVar script_vcpu_setStartFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s); + static scriptVar script_vcpu_setEndFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar e); + static scriptVar script_vcpu_setAutoReplay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar ar); + static scriptVar script_vcpu_play(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_pause(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + + static scriptVar script_vcpu_isPlaying(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_isPaused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_isStopped(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_getStartFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_getEndFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_getLength(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_getDirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_getAutoReplay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_getSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_getCurFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_setRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r); + static scriptVar script_vcpu_onPlay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_onStop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_onPause(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_onResume(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_onFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar f); + + +#else +class AnimatedLayer : public ANIMLAYER_SCRIPTPARENT { + +public: + +#endif + +// INSERT_SCRIPT_OBJECT_CONTROL + +}; + +extern const wchar_t animLayerXuiObjectStr[]; +extern char animLayerXuiSvcName[]; +class AnimLayerXuiSvc : public XuiObjectSvc<AnimatedLayer, animLayerXuiObjectStr, animLayerXuiSvcName> {}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/button.cpp b/Src/Wasabi/api/skin/widgets/button.cpp new file mode 100644 index 00000000..639443bc --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/button.cpp @@ -0,0 +1,508 @@ +#include <precomp.h> +#include <wasabicfg.h> +#include "button.h" +#include <api/skin/skinparse.h> + +#include <api/script/scriptmgr.h> + +#ifdef WASABI_WIDGETS_COMPBUCK +#include <api/skin/widgets/compbuck2.h> +#endif + +#ifdef WASABI_COMPILE_MEDIACORE +#include <api/core/api_core.h> +#endif + +#include <api/service/svcs/svc_action.h> + +const wchar_t buttonXuiObjectStr[] = L"Button"; // This is the xml tag +char buttonXuiSvcName[] = "Button xui object"; // this is the name of the xuiservice + + +ButtonScriptController _buttonController; +ButtonScriptController *buttonController = &_buttonController; + +// -- Functions table ------------------------------------- +function_descriptor_struct ButtonScriptController::exportedFunction[] = { +{L"onActivate", 1, (void*)Wasabi::Button::script_vcpu_onActivate }, + {L"setActivated", 1, (void*)Wasabi::Button::script_vcpu_setActivated }, + {L"getActivated", 0, (void*)Wasabi::Button::script_vcpu_getActivated }, + {L"onLeftClick", 0, (void*)Wasabi::Button::script_vcpu_onLeftClick }, + {L"onRightClick", 0, (void*)Wasabi::Button::script_vcpu_onRightClick }, + {L"leftClick", 0, (void*)Wasabi::Button::script_vcpu_leftClick }, + {L"rightClick", 0, (void*)Wasabi::Button::script_vcpu_rightClick }, + {L"setActivatedNoCallback", 1, (void*)Wasabi::Button::script_vcpu_setActivatedNoCallback }, + +}; +// -------------------------------------------------------- + +const wchar_t *ButtonScriptController::getClassName() { + return L"Button"; +} + +const wchar_t *ButtonScriptController::getAncestorClassName() { + return L"GuiObject"; +} + +ScriptObject *ButtonScriptController::instantiate() { + Wasabi::Button *b = new Wasabi::Button; + ASSERT(b != NULL); + return b->getScriptObject(); +} + +void ButtonScriptController::destroy(ScriptObject *o) { + Wasabi::Button *b = static_cast<Wasabi::Button *>(o->vcpu_getInterface(buttonGuid)); + ASSERT(b != NULL); + delete b; +} + +void *ButtonScriptController::encapsulate(ScriptObject *o) { + return NULL; // no encapsulation for buttojn yet +} + +void ButtonScriptController::deencapsulate(void *o) { +} + +int ButtonScriptController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *ButtonScriptController::getExportedFunctions() { + return exportedFunction; +} + +GUID ButtonScriptController::getClassGuid() { + return buttonGuid; +} + +XMLParamPair Wasabi::Button::params[] = +{ + {BUTTON_ACTION, L"ACTION"}, + {BUTTON_ACTIONTARGET, L"ACTION_TARGET"}, + {BUTTON_ACTIVEIMAGE, L"ACTIVEIMAGE"}, + {BUTTON_BORDERS, L"BORDERS"}, + #ifdef WASABI_WIDGETS_COMPBUCK + {BUTTON_CBTARGET, L"CBTARGET"}, +#endif + {BUTTON_CENTER_IMAGE, L"CENTER_IMAGE"}, + {BUTTON_DOWNIMAGE, L"DOWNIMAGE"}, + {BUTTON_HOVERIMAGE, L"HOVERIMAGE"}, + {BUTTON_IMAGE, L"IMAGE"}, + {BUTTON_PARAM, L"PARAM"}, + // {BUTTON_RECTRGN, "RECTRGN"}, + {BUTTON_RETCODE, L"RETCODE"}, + {BUTTON_BORDERSTYLE, L"STYLE"}, + {BUTTON_TEXT, L"TEXT"}, + {BUTTON_TEXTCOLOR, L"TEXTCOLOR"}, + {BUTTON_TEXTHOVERCOLOR, L"TEXTDIMMEDCOLOR"}, + {BUTTON_TEXTHOVERCOLOR, L"TEXTHOVERCOLOR"}, +}; +// ----------------------------------------------------------------------- + +Wasabi::Button::Button() { + disablenextcontextmenu = 0; +#ifdef WASABI_COMPILE_MEDIACORE + WASABI_API_MEDIACORE->core_addCallback(0, this); +#endif + getScriptObject()->vcpu_setInterface(buttonGuid, (void *)static_cast<Button*>(this)); + getScriptObject()->vcpu_setClassName(L"Button"); + getScriptObject()->vcpu_setController(buttonController); + cbtarget = NULL; + setBorders(FALSE); + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); +} + +void Wasabi::Button::CreateXMLParameters(int master_handle) +{ + //BUTTON_PARENT::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); +} + +Wasabi::Button::~Button() { + //int c=getNotifyId(); +#ifdef WASABI_COMPILE_MEDIACORE + WASABI_API_MEDIACORE->core_delCallback(0, this); +#endif + WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<WndCallbackI*>(this)); +} + +int Wasabi::Button::onInit() +{ + BUTTON_PARENT::onInit(); + if (!action.isempty()) + setAction(action); + //FG> this is retarded, and yes, i'm the one who coded it in + //if (s_normal.isempty() && s_down.isempty() && s_hover.isempty() && s_active.isempty()) + // setRectRgn(1); + setupBitmaps(); + //int c=getNotifyId(); + setHandleRightClick(TRUE); +#ifdef WASABI_COMPILE_MEDIACORE + if (WCSCASEEQLSAFE(actionstr, L"eq_toggle") + || WCSCASEEQLSAFE(actionstr, L"eq_auto")) + { + if (WCSCASEEQLSAFE(actionstr, L"eq_toggle")) + corecb_onEQStatusChange(WASABI_API_MEDIACORE->core_getEqStatus(0)); + else corecb_onEQAutoChange(WASABI_API_MEDIACORE->core_getEqAuto(0)); + } +#endif + WASABI_API_SYSCB->syscb_registerCallback(static_cast<WndCallbackI*>(this)); + return 1; +} + +void Wasabi::Button::setupBitmaps() +{ + setBitmaps(s_normal, s_down, s_hover, s_active); +} + +void Wasabi::Button::setParam(const wchar_t *p) +{ + param=p; +} + +void Wasabi::Button::setAction(const wchar_t *_action) +{ + actionstr = _action; + const wchar_t *name; + int id = SkinParser::getAction(_action, &name); + actionname = name; + if (id == ACTION_NONE || !action_target.isempty()) + action = _action; + else { + setNotifyId(id); + action = L""; + } +} + +int Wasabi::Button::setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *paramname, const wchar_t *strvalue) { + if (xuihandle == _xuihandle) { + switch (xmlattributeid) { + case BUTTON_TEXT: setButtonText(strvalue); return 1; + case BUTTON_ACTION: action = strvalue; if (isInited()) { setAction(action); } return 1; + case BUTTON_IMAGE: s_normal = strvalue; if (isInited()) { setBitmaps(s_normal, s_down, s_hover, s_active); } return 1; + case BUTTON_DOWNIMAGE: s_down = strvalue; if (isInited()) { setBitmaps(s_normal, s_down, s_hover, s_active); } return 1; + case BUTTON_HOVERIMAGE: s_hover = strvalue; if (isInited()) { setBitmaps(s_normal, s_down, s_hover, s_active); } return 1; + case BUTTON_ACTIVEIMAGE: s_active = strvalue; if (isInited()) { setBitmaps(s_normal, s_down, s_hover, s_active); }return 1; + case BUTTON_PARAM: setParam(strvalue); return 1; + //case BUTTON_RECTRGN: setRectRgn(WTOI(strvalue)); return 1; +#ifdef WASABI_WIDGETS_COMPBUCK + case BUTTON_CBTARGET: setCBTarget(strvalue); return 1; +#endif + case BUTTON_BORDERS: setBorders(WTOI(strvalue)); return 1; + case BUTTON_BORDERSTYLE: setBorderStyle(strvalue); return 1; + case BUTTON_RETCODE: setModalRetCode(WTOI(strvalue)); return 1; + case BUTTON_ACTIONTARGET: { + action_target = strvalue; + if (!actionstr.isempty()) { + action = actionstr; + setAction(action); + } + return 1; + } + case BUTTON_CENTER_IMAGE: setBitmapCenter(WTOI(strvalue)); return 1; + case BUTTON_TEXTCOLOR: setTextColor(strvalue); return 1; + case BUTTON_TEXTHOVERCOLOR: setTextHoverColor(strvalue); return 1; + case BUTTON_TEXTDIMMEDCOLOR: setTextDimmedColor(strvalue); return 1; + } + } + return BUTTON_PARENT::setXuiParam(_xuihandle, xmlattributeid, paramname, strvalue); +} + +#ifdef WASABI_WIDGETS_COMPBUCK +void Wasabi::Button::setCBTarget(const wchar_t *t) { + cbtarget = ComponentBucket2::getComponentBucket(t); +} +#endif + +const wchar_t *Wasabi::Button::getParam() +{ + return param; +} + +int Wasabi::Button::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2) { +#ifdef WASABI_COMPILE_WNDMGR + switch(msg) + { +#ifdef _WIN32 + case WM_WA_CONTAINER_TOGGLED: + if(!param) break; + if(!WCSICMP((const wchar_t *)param1,param)) setActivatedButton(param2); + break; +#else +#warning port me +#endif +#ifdef WASABI_COMPILE_COMPONENTS + case WM_WA_COMPONENT_TOGGLED: + if(!param) break; + GUID *g; + if(g=SkinParser::getComponentGuid(param)) { + if(!MEMCMP((GUID *)param1,g,sizeof(GUID))) setActivatedButton(param2); + } + break; +#endif + } +#endif + return BUTTON_PARENT::childNotify(child, msg, param1, param2); +} + +#ifdef WASABI_COMPILE_MEDIACORE +int Wasabi::Button::corecb_onEQStatusChange(int newval) { + if(WCSCASEEQLSAFE(actionstr, L"eq_toggle")) setActivatedButton(newval); + return 0; +} + +int Wasabi::Button::corecb_onEQAutoChange(int newval) { + if(WCSCASEEQLSAFE(actionstr,L"eq_auto")) setActivatedButton(newval); + return 0; +} +#endif + +int Wasabi::Button::onLeftButtonUp(int x, int y) { + BUTTON_PARENT::onLeftButtonUp(x, y); + if (!WASABI_API_MAKI->vcpu_getComplete()) { +#ifdef WASABI_WIDGETS_COMPBUCK + if (getNotifyId() == ACTION_CB_NEXT) { + if (cbtarget) + cbtarget->ComponentBucket2::next_up(); + else + ComponentBucket2::next_up(getGuiObject()->guiobject_getParentGroup()); + } else if (getNotifyId() == ACTION_CB_PREV) { + if (cbtarget) + cbtarget->ComponentBucket2::prev_up(); + else + ComponentBucket2::prev_up(getGuiObject()->guiobject_getParentGroup()); + } else if (getNotifyId() == ACTION_CB_NEXTPAGE) { + if (cbtarget) + cbtarget->ComponentBucket2::next_page(); + else + ComponentBucket2::next_page(getGuiObject()->guiobject_getParentGroup()); + } else if (getNotifyId() == ACTION_CB_PREVPAGE) { + if (cbtarget) + cbtarget->ComponentBucket2::prev_page(); + else + ComponentBucket2::prev_page(getGuiObject()->guiobject_getParentGroup()); + } +#endif + } + return 1; +} + +int Wasabi::Button::onLeftButtonDown(int x, int y) { + BUTTON_PARENT::onLeftButtonDown(x, y); + if (!WASABI_API_MAKI->vcpu_getComplete()) { +#ifdef WASABI_WIDGETS_COMPBUCK + if (getNotifyId() == ACTION_CB_NEXT) { + if (cbtarget) + cbtarget->ComponentBucket2::next_down(); + else + ComponentBucket2::next_down(getGuiObject()->guiobject_getParentGroup()); + } else if (getNotifyId() == ACTION_CB_PREV) { + if (cbtarget) + cbtarget->ComponentBucket2::prev_down(); + else + ComponentBucket2::prev_down(getGuiObject()->guiobject_getParentGroup()); + } +#endif + } + return 1; +} + +void Wasabi::Button::onLeftPush(int x, int y) { + BUTTON_PARENT::onLeftPush(x, y); + script_vcpu_onLeftClick(SCRIPT_CALL, getScriptObject()); + if (!WASABI_API_MAKI->vcpu_getComplete()) { + if (!action.isempty()) { + if (!action_target.isempty()) + { + GuiObject *go = getGuiObject()->guiobject_findObject(action_target); + if (!go) + { + ScriptObject *so = WASABI_API_MAKI->maki_findObject(action_target); + if (so != NULL) + go = static_cast<GuiObject *>(so->vcpu_getInterface(guiObjectGuid)); + } + if (go) { + ifc_window *w = go->guiobject_getRootWnd(); + if (w) { + int _x = x; + int _y = y; + clientToScreen(&_x, &_y); + sendAction(w, actionstr, getParam(), _x, _y); + } + } + } else { + svc_action *act = ActionEnum(actionstr).getNext(); + if (act) { + int _x = x; + int _y = y; + clientToScreen(&_x, &_y); + act->onAction(actionstr, getParam(), _x, _y, NULL, 0, this); + SvcEnum::release(act); + } + } + } + } +} + +int Wasabi::Button::wantAutoContextMenu() { + int a = disablenextcontextmenu; + disablenextcontextmenu = 0; + return !a; +} + +void Wasabi::Button::onRightPush(int x, int y) { + BUTTON_PARENT::onRightPush(x, y); + script_vcpu_onRightClick(SCRIPT_CALL, getScriptObject()); + if (!WASABI_API_MAKI->vcpu_getComplete()) { + if (!action.isempty()) { + if (!action_target.isempty()) + { + GuiObject *go = getGuiObject()->guiobject_findObject(action_target); + if (!go) { + ScriptObject *so = WASABI_API_MAKI->maki_findObject(action_target); + if (so != NULL) + go = static_cast<GuiObject *>(so->vcpu_getInterface(guiObjectGuid)); + } + if (go) { + ifc_window *w = go->guiobject_getRootWnd(); + if (w) { + int _x = x; + int _y = y; + clientToScreen(&_x, &_y); + sendAction(w, actionstr, getParam(), _x, _y); + disablenextcontextmenu = 1; + } + } + } else { + svc_action *act = ActionEnum(actionstr).getNext(); + if (act) { + const wchar_t *par = getParam(); + if (par == NULL || *par == 0) par = L"1"; + int _x = x; + int _y = y; + clientToScreen(&_x, &_y); + disablenextcontextmenu = act->onAction(actionstr, par, _x, _y, NULL, 0, this); + SvcEnum::release(act); + } + } + } + } +} + +int Wasabi::Button::onActivateButton(int is) { + BUTTON_PARENT::onActivateButton(is); + scriptVar _is = SOM::makeVar(SCRIPT_INT); + SOM::assign(&_is, is); + script_vcpu_onActivate(SCRIPT_CALL, getScriptObject(), _is); + return 1; +} + +int Wasabi::Button::getPreferences(int what) { + if (what == SUGGESTED_W) return getWidth(); + if (what == SUGGESTED_H) return getHeight(); + return BUTTON_PARENT::getPreferences(what); +} + +int Wasabi::Button::onShowWindow(Container *c, GUID guid, const wchar_t *groupid) +{ + if(!param) return 1; + if (groupid != NULL && !WCSICMP(groupid, param)) + { + setActivatedButton(1); + return 1; + } +#ifdef WASABI_COMPILE_WNDMGR + GUID *g; + if (g=SkinParser::getComponentGuid(param)) + { + if(*g != INVALID_GUID && guid == *g) setActivatedButton(1); + } +#endif + return 1; +} + +int Wasabi::Button::onHideWindow(Container *c, GUID guid, const wchar_t *groupid) { + if(!param) return 1; + if (groupid != NULL && !WCSICMP(groupid, param)) { + setActivatedButton(0); + return 1; + } +#ifdef WASABI_COMPILE_WNDMGR + GUID *g; + if (g=SkinParser::getComponentGuid(param)) { + if(guid == *g) setActivatedButton(0); + } +#endif + return 1; +} + +scriptVar Wasabi::Button::script_vcpu_setActivatedNoCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) { + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&v)); + Button *b = static_cast<Button *>(o->vcpu_getInterface(buttonGuid)); + if (b) b->setActivatedNoCallback(SOM::makeBoolean(&v)); + RETURN_SCRIPT_VOID; +} + +scriptVar Wasabi::Button::script_vcpu_onLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS0(o, buttonController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +scriptVar Wasabi::Button::script_vcpu_onRightClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS0(o, buttonController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +scriptVar Wasabi::Button::script_vcpu_leftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT; + RECT r; + Wasabi::Button *b = static_cast<Button *>(o->vcpu_getInterface(buttonGuid)); + if (b) { + b->getClientRect(&r); + b->onLeftPush(r.left, r.top); + } + RETURN_SCRIPT_VOID; +} + +scriptVar Wasabi::Button::script_vcpu_rightClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT; + RECT r; + Wasabi::Button *b = static_cast<Button *>(o->vcpu_getInterface(buttonGuid)); + if (b) { + b->getClientRect(&r); + b->onRightPush(r.left, r.top); + } + RETURN_SCRIPT_VOID; +} + +scriptVar Wasabi::Button::script_vcpu_setActivated(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) { + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&v)); + Wasabi::Button *b = static_cast<Button *>(o->vcpu_getInterface(buttonGuid)); + if (b) b->setActivatedButton(SOM::makeBoolean(&v)); + RETURN_SCRIPT_VOID; +} + +scriptVar Wasabi::Button::script_vcpu_getActivated(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + Wasabi::Button *b = static_cast<Button *>(o->vcpu_getInterface(buttonGuid)); + if (b) return MAKE_SCRIPT_BOOLEAN(b->getActivatedButton()); + RETURN_SCRIPT_ZERO; +} + +scriptVar Wasabi::Button::script_vcpu_onActivate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) { + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS1(o, buttonController, v); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, v); +} + diff --git a/Src/Wasabi/api/skin/widgets/button.h b/Src/Wasabi/api/skin/widgets/button.h new file mode 100644 index 00000000..383c9b75 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/button.h @@ -0,0 +1,134 @@ +#ifndef _BUTTON_H +#define _BUTTON_H + +#include <bfc/string/bfcstring.h> +#include <api/script/script.h> +#include <api/wnd/wndclass/buttwnd.h> +#include <api/script/objects/guiobj.h> +#include <api/syscb/callbacks/corecbi.h> +#include <api/wndmgr/layout.h> +#include <api/wnd/wndclass/guiobjwnd.h> +#include <api/service/svcs/svc_xuiobject.h> + +#define BUTTON_PARENT ButtonWnd + +class ComponentBucket2; + +class ScriptObject; + +class ButtonScriptController: public GuiObjectScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + 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); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern ButtonScriptController *buttonController; + +namespace Wasabi // Apple defines "Button" so we're pretty much forced to namespace this... annoying +{ +#ifdef WASABI_COMPILE_MEDIACORE +class Button : public BUTTON_PARENT, public CoreCallbackI { +#else +class Button : public BUTTON_PARENT { +#endif + +public: + Button(); + virtual ~Button(); + + virtual int onInit(); + virtual int setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *paramname, const wchar_t *strvalue); + virtual void setParam(const wchar_t *p); + virtual int getPreferences(int what); + virtual const wchar_t *getParam(); + virtual int onLeftButtonUp(int x, int y); + virtual int onLeftButtonDown(int x, int y); + virtual void onLeftPush(int x, int y); + virtual void onRightPush(int x, int y); + virtual int onActivateButton(int is); + + virtual int childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2); + + virtual int wantAutoContextMenu(); +#ifdef WASABI_WIDGETS_COMPBUCK + virtual void setCBTarget(const wchar_t *t); +#endif + virtual void setAction(const wchar_t *action); + + virtual int onShowWindow(Container *c, GUID guid, const wchar_t *groupid); + virtual int onHideWindow(Container *c, GUID guid, const wchar_t *groupid); + +protected: + /*static */void CreateXMLParameters(int master_handle); +#ifdef WASABI_COMPILE_MEDIACORE + virtual int corecb_onEQStatusChange(int newval); + virtual int corecb_onEQAutoChange(int newval); +#endif + StringW s_normal, s_down, s_hover, s_active; + int btn_getXuiHandle() { return xuihandle; } + int retcode; + virtual void setupBitmaps(); + + enum { + BUTTON_TEXT = 0, + BUTTON_ACTION, + BUTTON_IMAGE, + BUTTON_DOWNIMAGE, + BUTTON_HOVERIMAGE, + BUTTON_ACTIVEIMAGE, + BUTTON_PARAM, + BUTTON_RECTRGN, + BUTTON_CBTARGET, + BUTTON_BORDERS, + BUTTON_BORDERSTYLE, + BUTTON_RETCODE, + BUTTON_ACTIONTARGET, + BUTTON_CENTER_IMAGE, + BUTTON_TEXTCOLOR, + BUTTON_TEXTHOVERCOLOR, + BUTTON_TEXTDIMMEDCOLOR, + BUTTON_NUMPARAMS, + }; + +private: + StringW param; + StringW action, actionstr, actionname; + StringW action_target; + ComponentBucket2 *cbtarget; + int borders; + int disablenextcontextmenu; + int xuihandle; + static XMLParamPair params[]; + +public: + static scriptVar script_vcpu_setActivatedNoCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v); + static scriptVar script_vcpu_onLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_onRightClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_leftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_rightClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_setActivated(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v); + static scriptVar script_vcpu_getActivated(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_onActivate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v); +}; +} + +extern const wchar_t buttonXuiObjectStr[]; +extern char buttonXuiSvcName[]; +class ButtonXuiSvc : public XuiObjectSvc<Wasabi::Button, buttonXuiObjectStr, buttonXuiSvcName> {}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/checkbox.cpp b/Src/Wasabi/api/skin/widgets/checkbox.cpp new file mode 100644 index 00000000..505687b2 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/checkbox.cpp @@ -0,0 +1,262 @@ +#include <precomp.h> +#include "checkbox.h" +#include <api/service/svcs/svc_action.h> +#include <api/script/objects/c_script/c_text.h> +#include <api/script/objects/c_script/c_button.h> +#include <api/script/objects/guiobject.h> +#include <api/script/scriptguid.h> +#include <api/script/api_maki.h> + +// ----------------------------------------------------------------------- +CheckBox::CheckBox(const wchar_t *_text, const wchar_t *_radioid) : + textclicks(NULL), toggleclicks(NULL), text(_text), radioid(_radioid), + buttonGuiObj(NULL), use_radioval(0), + CHECKBOX_PARENT() { } + +CheckBox::~CheckBox() { + delete textclicks; + delete toggleclicks; +} + +int CheckBox::onInit() { + int r = CHECKBOX_PARENT::onInit(); + if (radioid.len()) { + abstract_setContent(L"wasabi.radiobutton.group"); + // After we set the content for radio, we should register ourselves + // as a radio button under the radio group we are assigned. + GuiObject *radioGuiObj = abstract_findObject(radioid); // this will actually go down a level + if (radioGuiObj != NULL) { + ifc_window *radioRootWnd = *radioGuiObj; // explicit cast operator :) + // Now, once we have the rootwnd, we can send our radio group object a message, it will turn off other items as we turn on specific ones + if (radioRootWnd != NULL) { + sendAction(radioRootWnd, L"REGISTER", NULL, -1, -1, 0, 0, (void *)getGuiObject(), 4); + } + } + } else { + abstract_setContent(L"wasabi.checkbox.group"); + } + return r; +} + +void CheckBox::onNewContent() { + // remove all previous hooks because our content changed + delete toggleclicks; + toggleclicks = NULL; + + delete textclicks; + textclicks = NULL; + + // Capture the clicks on the button + buttonGuiObj = abstract_findObject(L"checkbox.toggle"); + if (buttonGuiObj != NULL) { + toggleclicks = new ToggleClicks(*buttonGuiObj, this); + } + + // Capture the clicks on the text + GuiObject *textGuiObj = abstract_findObject(L"checkbox.text"); + if (textGuiObj != NULL) { + textclicks = new TextClicks(*textGuiObj, this); + } + + // Set the text object to display the requested text. + updateText(); +} + +int CheckBox::getPreferences(int what) { + ifc_window *w = abstract_getContentRootWnd(); + if (w != NULL) + return w->getPreferences(what); + return CHECKBOX_PARENT::getPreferences(what); +} + +void CheckBox::setActivated(int activated, int writetocfg) { + // this is usually called as a response to onReloadConfig, but could also be called + // directly by a 3rd party, so if we can, we read the current value and do nothing if + // it hasn't changed. + GuiObject *toggleGuiObj = abstract_findObject(L"checkbox.toggle"); + if (toggleGuiObj != NULL) { + C_Button buttonObj(*toggleGuiObj); + int act = buttonObj.getActivated(); + if (!!act == !!activated) return; + buttonObj.setActivatedNoCallback(!!activated); + } + if (writetocfg) { + if (use_radioval) { + if (activated) { +#ifdef WASABI_COMPILE_CONFIG + getGuiObject()->guiobject_setCfgString(radioval); +#endif + if (radioval != 0) doAction(); + } + } else { +#ifdef WASABI_COMPILE_CONFIG + getGuiObject()->guiobject_setCfgInt(activated); +#endif + if (activated) doAction(); + } + } +} + +// This is called by the click catchers +void CheckBox::toggle(int self_switch) { + + if (!buttonGuiObj) return; + + int activated = !!isActivated(); + if (self_switch) activated = !activated; + +/* int no_setactive = self_switch; + + if (radioid.len() > 0 && activated) { // but if we're a radiobox, do not toggle if we're already activated + no_setactive = 1; + } + + if (self_switch) activated = !!!activated; +*/ + + if (!(activated && !radioid.isempty())) + activated = !activated; + + if (!use_radioval || activated) { + C_Button b(*buttonGuiObj); + b.setActivatedNoCallback(activated); + } + + if (activated) { + if (use_radioval) { +#ifdef WASABI_COMPILE_CONFIG + getGuiObject()->guiobject_setCfgString(radioval); +#endif + if (radioval != 0) doAction(); + } else { +#ifdef WASABI_COMPILE_CONFIG + getGuiObject()->guiobject_setCfgInt(activated); +#endif + if (activated) doAction(); + } + } else +#ifdef WASABI_COMPILE_CONFIG + if (radioid.len() == 0) getGuiObject()->guiobject_setCfgInt(0); // if we're a radioid being turned off, we shouldn't write our value, as we'll prolly be sharing the same cfgattr with other radioboxes, todo: make that optional +#endif + + if (radioid.len() > 0 && activated) { + GuiObject *radioGuiObj = abstract_findObject(radioid); + ifc_window *radioRootWnd = *radioGuiObj; + if (radioRootWnd != NULL) + sendAction(radioRootWnd, L"TOGGLE", NULL, -1, -1, 0, 0, (void *)getGuiObject(), 4); + } + + onToggle(); +} + +void CheckBox::onToggle() { +} + +void CheckBox::setText(const wchar_t *_text) +{ + text = _text; + setName(text); + if (isInited()) { + updateText(); + } +} + +const wchar_t *CheckBox::getText() { + return text; +} + +void CheckBox::setRadioid(const wchar_t *_radioid) +{ + radioid = _radioid; +} + +void CheckBox::setRadioVal(const wchar_t *val, int _use_radioval) +{ + radioval = val; + use_radioval = _use_radioval; +} + +#ifdef WASABI_COMPILE_CONFIG +int CheckBox::onReloadConfig() +{ + StringW newVal = getGuiObject()->guiobject_getCfgString(); + int checkit = use_radioval ? (newVal == radioval) : WTOI(newVal); + setActivated(checkit, 0); + return CHECKBOX_PARENT::onReloadConfig(); +} +#endif + +void CheckBox::updateText() { + GuiObject *textGuiObj = abstract_findObject(L"checkbox.text"); + if (textGuiObj != NULL) { + textGuiObj->guiobject_setXmlParam(L"text", text); + } +} +int CheckBox::isActivated() { + if (!buttonGuiObj) return 0; + C_Button b(*buttonGuiObj); + return b.getActivated(); +} + +int CheckBox::onChar(unsigned int c) { + switch (c) { +#ifdef _WIN32 + case VK_SPACE: + toggle(0); + break; +#else +#warning port me +#endif + default: + return CHECKBOX_PARENT::onChar(c); + } + return 1; +} + +void CheckBox::setAction(const wchar_t *str) +{ + action = str; +} + +void CheckBox::setActionTarget(const wchar_t *target) { + action_target = target; +} + +void CheckBox::setActionParam(const wchar_t *param) { + action_param = param; +} + +const wchar_t *CheckBox::getActionParam() +{ + return action_param; +} + +void CheckBox::doAction() +{ + if (!action_target.isempty()) + { + GuiObject *go = getGuiObject()->guiobject_findObject(action_target); + if (!go) { + ScriptObject *so = WASABI_API_MAKI->maki_findObject(action_target); + if (so != NULL) + go = static_cast<GuiObject *>(so->vcpu_getInterface(guiObjectGuid)); + } + if (go) { + ifc_window *w = go->guiobject_getRootWnd(); + if (w) { + RECT cr; + getClientRect(&cr); + int _x = cr.left; + int _y = cr.top; + clientToScreen(&_x, &_y); + sendAction(w, action, action_target, _x, _y); + } + } + } else { + svc_action *act = ActionEnum(action).getNext(); + if (act) { + act->onAction(action, getActionParam()); + SvcEnum::release(act); + } + } +} diff --git a/Src/Wasabi/api/skin/widgets/checkbox.h b/Src/Wasabi/api/skin/widgets/checkbox.h new file mode 100644 index 00000000..213d25a0 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/checkbox.h @@ -0,0 +1,246 @@ +#ifndef __CHECKBOX_H +#define __CHECKBOX_H + +#include <api/wnd/wndclass/guiobjwnd.h> +#include <api/script/objects/c_script/h_guiobject.h> +#include <api/script/objects/c_script/h_button.h> + +#define CHECKBOX_PARENT GuiObjectWnd + +class TextClicks; +class ToggleClicks; + + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class CheckBox : public CHECKBOX_PARENT { + + public: + + CheckBox(const wchar_t *_text = L"ERROR", const wchar_t *_radioid = NULL); + virtual ~CheckBox(); + + + /** + Method + + @see + @ret + @param + */ + virtual int onInit(); + + + /** + Method + + @see + @ret + @param + */ + virtual int getPreferences(int what); + + + /** + Method + + @see + @ret + @param + */ + void toggle(int self_switch); // this is called by the click catchers. + + /** + Method + + @see + @ret + @param + */ + void setActivated(int activated, int writetocfg=1); + + /** + Method + + @see + @ret + @param + */ + int isActivated(); + + + /** + Method + + @see + @ret + @param + */ + void setText(const wchar_t *_text); + const wchar_t *getText(); + void setRadioid(const wchar_t *_radioid); + const wchar_t *getRadioid() { return radioid; } + void setRadioVal(const wchar_t *val, int use_radioval=TRUE); + const wchar_t *getRadioVal() { return radioval; } + + +#ifdef WASABI_COMPILE_CONFIG + /** + Method + + @see + @ret + @param + */ + virtual int onReloadConfig(); +#endif + + /** + Method + + @see + @ret + @param + */ + virtual void onNewContent(); + + virtual int wantFocus() { return 1; } + virtual int onChar(unsigned int c); + + virtual void setAction(const wchar_t *str); + virtual void setActionTarget(const wchar_t *target); + virtual void setActionParam(const wchar_t *param); + virtual const wchar_t *getActionParam(); + + protected: + virtual void onToggle(); //override to catch toggles + + private: + + void doAction(); + + /** + Method + + @see + @ret + @param + */ + void updateText(); + + TextClicks *textclicks; + ToggleClicks *toggleclicks; + StringW text; + StringW radioid; + GuiObject *buttonGuiObj; + StringW radioval; + int use_radioval; + StringW action, action_target, action_param; +}; + + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class TextClicks : public H_GuiObject { + public: + + /** + Method + + @see + @ret + @param + */ + TextClicks(ScriptObject *textobj, CheckBox *_callback) : + + /** + Method + + @see + @ret + @param + */ + callback(_callback), H_GuiObject(textobj) { + } + + + /** + Method + + @see + @ret + @param + */ + virtual void hook_onLeftButtonDown(int x, int y) { + callback->toggle(0); + } + private: + CheckBox *callback; +}; + + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class ToggleClicks : public H_Button { + public: + + /** + Method + + @see + @ret + @param + */ + ToggleClicks(ScriptObject *button, CheckBox *_callback) : + + /** + Method + + @see + @ret + @param + */ + callback(_callback), H_Button(button) { + inhere=0; + } + + + /** + Method + + @see + @ret + @param + */ + virtual void hook_onActivate(int activate) { + if (inhere) return; + inhere=1; + callback->toggle(1); + inhere=0; + } + + private: + CheckBox *callback; + int inhere; +}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/combobox.cpp b/Src/Wasabi/api/skin/widgets/combobox.cpp new file mode 100644 index 00000000..9096e7be --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/combobox.cpp @@ -0,0 +1,270 @@ +#include <precomp.h> +#include "combobox.h" +#include <api/script/objects/c_script/c_edit.h> +#include <api/skin/xmlobject.h> + +ComboBox::ComboBox() { + keys_edit = NULL; + lastlist = NULL; + disable_getselection = 0; + savedidle = 0; + savedautoenter = 0; +} + +ComboBox::~ComboBox() { + delete keys_edit; +} + +void ComboBox::abstract_onNewContent() { + COMBOBOX_PARENT::abstract_onNewContent(); + trapControls(); +} + +void ComboBox::trapControls() { + delete keys_edit; + + keys_edit = NULL; + + if (wantTrapEdit()) { + GuiObject *editGuiObj = getGuiObject()->guiobject_findObject(combobox_getEditId()); + if (editGuiObj) keys_edit = new HEBKeysCallback(*editGuiObj, this); + } +} + +void ComboBox::updateTextInControl(const wchar_t *txt) +{ + if (txt == NULL) return; + if (WCSCASEEQLSAFE(getText(), txt)) return; + GuiObject *content = getContent(); + if (content != NULL) { + if (wantTrapEdit()) { + GuiObject *text = content->guiobject_findObject(combobox_getEditId()); + if (text != NULL) { + C_Edit t(*text); + t.setText(txt); + curtxt = txt; + } + } + } +} + +void ComboBox::dropdownlist_onCloseList() { + COMBOBOX_PARENT::dropdownlist_onCloseList(); + if (wantTrapEdit()) { + GuiObject *o = embeddedxui_getEmbeddedObject(); + if (o != NULL) { + o->guiobject_getRootWnd()->setFocus(); + GuiObject *edit = o->guiobject_findObjectByInterface(editGuid); + if (edit != NULL) { + C_Edit e(*edit); + e.setAutoEnter(savedautoenter); + e.setIdleEnabled(savedidle); + } + } + } + if (wantEnterOnSelect()) + enter(); + disable_getselection = 0; +} + +void ComboBox::dropdownlist_onOpenList() { + COMBOBOX_PARENT::dropdownlist_onOpenList(); + if (wantTrapEdit()) { + GuiObject *o = embeddedxui_getEmbeddedObject(); + if (o != NULL) { + o->guiobject_getRootWnd()->setFocus(); + GuiObject *edit = o->guiobject_findObjectByInterface(editGuid); + if (edit != NULL) { + C_Edit e(*edit); + savedidle = e.getIdleEnabled(); + savedautoenter = e.getAutoEnter(); + e.setIdleEnabled(0); + e.setAutoEnter(0); + } + } + } +} + +void ComboBox::setText(const wchar_t *text, int hover) { + updateTextInControl(text); + selectItem(-1, hover); + selectEditor(); +} + +const wchar_t *ComboBox::getText(int fromcontrol) +{ + + if (!fromcontrol) + return curtxt; + + const wchar_t *c = NULL; + GuiObject *content = getContent(); + if (content != NULL) { + if (wantTrapEdit()) { + GuiObject *text = content->guiobject_findObject(combobox_getEditId()); + if (text != NULL) { + C_Edit t(*text); + c = t.getText(); + } + } + } + curtxt = c; + return c; +} + +void ComboBox::dropdownlist_onConfigureList(GuiObject *o) { + COMBOBOX_PARENT::dropdownlist_onConfigureList(o); + ifc_window *w = o->guiobject_getRootWnd()->findWindowByInterface(listGuid); + sendAction(w, L"register_tempselectnotify"); + //w->getGuiObject()->guiobject_setXmlParam("select", getCustomText()); + lastlist = w->getGuiObject(); +} + +void ComboBox::onSelect(int id, int hover) { + COMBOBOX_PARENT::onSelect(id, hover); + if (!hover) { + selectEditor(); + if (wantEnterOnSelect()) + enter(); + } +} + +void ComboBox::enter() { + GuiObject *content = getContent(); + if (content != NULL) { + if (wantTrapEdit()) { + GuiObject *text = content->guiobject_findObject(combobox_getEditId()); + if (text != NULL) { + C_Edit t(*text); + t.enter(); + } + } + } +} + +void ComboBox::selectEditor() { + GuiObject *content = getContent(); + if (content != NULL) { + if (wantTrapEdit()) { + GuiObject *text = content->guiobject_findObject(combobox_getEditId()); + if (text != NULL) { + C_Edit t(*text); + t.selectAll(); + } + } + } +} + +int ComboBox::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) { + int r = COMBOBOX_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source); + if (WCSCASEEQLSAFE(action, L"tempselectnotify")) { + if (!disable_getselection) + setText(param, 1); + } + return r; +} + +void ComboBox::onEditKeyDown(int vk) { + if (Std::keyDown(VK_CONTROL)) return; + if (vk == VK_DOWN) { + if (wantDownOpenList()) { + if (!isListOpen()) + openList(); + else { + if (wantTransferDownToList()) + listDown(); + } + } + } else if (vk == VK_UP) { + if (wantTransferUpToList()) + listUp(); + } else if (vk == VK_HOME) { + if (wantTransferHomeToList()) + listHome(); + } else if (vk == VK_END) { + if (wantTransferEndToList()) + listEnd(); + } else if (vk == VK_PRIOR) { + if (wantTransferPgUpToList()) + listPageUp(); + } else if (vk == VK_NEXT) { + if (wantTransferPgDnToList()) + listPageDown(); + } else if (vk == VK_ESCAPE) { + if (isListOpen()) + closeList(); + } else if (vk == VK_BACK || vk == VK_DELETE || vk == VK_LEFT || vk == VK_RIGHT) { + if (wantCloseListOnChar()) { + if (isListOpen()) + closeList(); + } + } +} + +void ComboBox::onEditKeyUp(int vk) +{ + curtxt = getText(1); +} + +void ComboBox::onEditEnter(const wchar_t *txt) +{ + if (isListOpen()) { + if (wantTransferEnterToList()) + listSelect(); + } +} + +void ComboBox::onEditChar(int c) { + if (wantCloseListOnChar()) { + if (isListOpen()) + closeList(); + } +} + + +void ComboBox::listUp() { + if (lastlist != NULL && isListOpen()) { + sendAction(lastlist->guiobject_getRootWnd(), L"up"); + } +} + +void ComboBox::listDown() { + if (lastlist != NULL && isListOpen()) { + sendAction(lastlist->guiobject_getRootWnd(), L"down"); + } +} + +void ComboBox::listHome() { + if (lastlist != NULL && isListOpen()) { + sendAction(lastlist->guiobject_getRootWnd(), L"home"); + } +} + +void ComboBox::listEnd() { + if (lastlist != NULL && isListOpen()) { + sendAction(lastlist->guiobject_getRootWnd(), L"end"); + } +} + +void ComboBox::listPageUp() { + if (lastlist != NULL && isListOpen()) { + sendAction(lastlist->guiobject_getRootWnd(), L"pageup"); + } +} + +void ComboBox::listPageDown() { + if (lastlist != NULL && isListOpen()) { + sendAction(lastlist->guiobject_getRootWnd(), L"pagedown"); + } +} + +void ComboBox::listSelect() { + if (lastlist != NULL && isListOpen()) { + sendAction(lastlist->guiobject_getRootWnd(), L"select_current"); + } +} + +void ComboBox::onPreCloseList() { + disable_getselection = 1; +} + diff --git a/Src/Wasabi/api/skin/widgets/combobox.h b/Src/Wasabi/api/skin/widgets/combobox.h new file mode 100644 index 00000000..08ec11bf --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/combobox.h @@ -0,0 +1,121 @@ +#ifndef __COMBOBOX_H +#define __COMBOBOX_H + +#include <api/skin/widgets/dropdownlist.h> +#include <api/script/objects/c_script/h_edit.h> +#include <api/script/objects/c_script/c_edit.h> + +#define COMBOBOX_PARENT DropDownList + +class XmlObject; +class HEBKeysCallback; + +class ComboBox : public COMBOBOX_PARENT { + + public: + + ComboBox(); + virtual ~ComboBox(); + + virtual int wantTrapButton() { return 1; } + virtual int wantTrapText() { return 0; } + virtual int wantTrapEdit() { return 1; } + + virtual void abstract_onNewContent(); + virtual void trapControls(); + + virtual const wchar_t *dropdownlist_getMainGroupId() { return L"wasabi.combobox.main.group"; } + virtual const wchar_t *dropdownlist_getListGroupId() { return L"wasabi.combobox.list.group"; } + virtual const wchar_t *dropdownlist_getButtonId() { return L"combobox.button"; } + virtual const wchar_t *dropdownlist_getListId() { return L"combobox.list"; } + + virtual const wchar_t *combobox_getEditId() { return L"combobox.edit"; } + + virtual const wchar_t *embeddedxui_getEmbeddedObjectId() { return combobox_getEditId(); } + + virtual void dropdownlist_onCloseList(); + virtual void dropdownlist_onOpenList(); + + virtual void setText(const wchar_t *text, int hover=0); // use this to set the content of the edit box + virtual const wchar_t *getText(int fromcontrol=0); // use this one to ask for the currently displayed entry + + virtual const wchar_t *getCustomText() { return NULL; } + + virtual void dropdownlist_onConfigureList(GuiObject *o); + virtual void onSelect(int id, int hover); + virtual void enter(); + + void selectEditor(); + virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, ifc_window *source=NULL); + + virtual void onEditKeyDown(int vk); + virtual void onEditKeyUp(int vk); + virtual void onEditEnter(const wchar_t *txt); + virtual void onEditChar(int c); + + virtual int wantTransferDownToList() { return 1; } + virtual int wantTransferUpToList() { return 1; } + virtual int wantTransferHomeToList() { return 1; } + virtual int wantTransferEndToList() { return 1; } + virtual int wantTransferPgUpToList() { return 1; } + virtual int wantTransferPgDnToList() { return 1; } + virtual int wantTransferEnterToList() { return 1; } + virtual int wantDownOpenList() { return 1; } + virtual int wantCloseListOnChar() { return 1; } + virtual int wantEnterOnSelect() { return 1; } + + virtual void listDown(); + virtual void listUp(); + virtual void listHome(); + virtual void listEnd(); + virtual void listPageDown(); + virtual void listPageUp(); + virtual void listSelect(); + + virtual void onPreCloseList(); + + private: + + virtual void updateTextInControl(const wchar_t *text); + + HEBKeysCallback *keys_edit; + GuiObject *lastlist; + StringW curtxt; + + int savedidle, savedautoenter; + int disable_getselection; +}; + +class HEBKeysCallback : public H_Edit { + public: + + HEBKeysCallback(ScriptObject *trap, ComboBox *_callback) : + callback(_callback), H_Edit(trap), o(trap) { + } + + virtual void hook_onKeyDown(int vk) { + callback->onEditKeyDown(vk); + } + + virtual void hook_onKeyUp(int vk) { + callback->onEditKeyUp(vk); + } + + virtual void hook_onEnter() + { + C_Edit e(o); + callback->onEditEnter(e.getText()); + } + + + virtual void hook_onChar(wchar_t c) { + callback->onEditChar(c); + } + + private: + ComboBox *callback; + ScriptObject *o; +}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/compbuck2.cpp b/Src/Wasabi/api/skin/widgets/compbuck2.cpp new file mode 100644 index 00000000..68b147b2 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/compbuck2.cpp @@ -0,0 +1,611 @@ +#include "precomp.h" +#include <bfc/std_math.h> +#include "compbuck2.h" +#include <api/wac/wac.h> +#include <tataki/bitmap/bitmap.h> +#include <api/wndmgr/layout.h> +#include <api/wnd/notifmsg.h> +#include <api/service/service.h> +#include <api/service/services.h> +#include <api/wnd/wndclass/svcwndhold.h> + +#define TIMER_SCROLL (0x400+8879) +#define TIMER_SCROLLPAGE (0x400+8880) + +#define TIMER_SPEED 10 +#define SCROLL_STEPS 10 +#define SCROLL_SPEED 20 + +#define SCROLL_LEFT -2 +#define SCROLL_RIGHT +2 + +#ifndef PI +#define PI 3.1415926536 +#endif + +const wchar_t componentBucketXuiObjectStr[] = L"ComponentBucket"; // This is the xml tag +char componentBucketXuiSvcName[] = "ComponentBucket xui object"; // this is the name of the xuiservice + +XMLParamPair ComponentBucket2::params[] = +{ + {COMPBUCK_LEFTMARGIN, L"LEFTMARGIN"}, + {COMPBUCK_RIGHTMARGIN, L"RIGHTMARGIN"}, + {COMPBUCK_SPACING, L"SPACING"}, + {COMPBUCK_VERTICAL, L"VERTICAL"}, + {COMPBUCK_WNDTYPE, L"WNDTYPE"}, +}; + +ComponentBucket2::ComponentBucket2() { + getScriptObject()->vcpu_setInterface(cbucketGuid, (void *)static_cast<ComponentBucket2 *>(this)); + getScriptObject()->vcpu_setClassName(L"ComponentBucket"); + getScriptObject()->vcpu_setController(cbucketController); + lastticcount=0; + wndtype = BUCKETITEM; + timeron = 0; + lmargin = 2; + rmargin = 2; + spacing = 2; + direction = 0; + xscroll = 0; + timerset = 0; + cblist.addItem(this); + vertical = 0; + scrollpage_timerset = 0; + scrollpage_starttime = 0; + scrollpage_start = 0; + scrollpage_target = 0; + scrollpage_speed = 250; + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); +} + +void ComponentBucket2::CreateXMLParameters(int master_handle) +{ + //COMPONENTBUCKET2_PARENT::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); +} + +ComponentBucket2::~ComponentBucket2() { + if (scrollpage_timerset) killTimer(TIMER_SCROLLPAGE); + myclients.deleteAll(); + cblist.removeItem(this); + if (cblist.getNumItems() == 0) cblist.removeAll(); +} + +int ComponentBucket2::onInit() { + COMPONENTBUCKET2_PARENT::onInit(); + load(); + return 1; +} + +int ComponentBucket2::setXuiParam(int _xuihandle, int id, const wchar_t *name, const wchar_t *strval) { + if (xuihandle == _xuihandle) { + switch (id) { + case COMPBUCK_LEFTMARGIN: setLMargin(WTOI(strval)); return 1; + case COMPBUCK_RIGHTMARGIN: setRMargin(WTOI(strval)); return 1; + case COMPBUCK_SPACING: setSpacing(WTOI(strval)); return 1; + case COMPBUCK_VERTICAL: setVertical(WTOI(strval)); return 1; + case COMPBUCK_WNDTYPE: wndtype = strval; return 1; + } + } + return COMPONENTBUCKET2_PARENT::setXuiParam(_xuihandle, id, name, strval); +} + +void ComponentBucket2::setScroll(int v) { + xscroll = v; + if (isInited()) + onResize(); + invalidate(); +} + +int ComponentBucket2::getScroll() { + return xscroll; +} + +void ComponentBucket2::timerCallback(int id) { + switch (id) { + case TIMER_SCROLL: { + RECT r; + getClientRect(&r); + do { + xscroll += direction; + lastticcount += TIMER_SPEED; + } while (lastticcount < Wasabi::Std::getTickCount() - TIMER_SPEED); + if (!vertical) + xscroll = MIN((int)(getMaxWidth()-(r.right-r.left)), xscroll); + else + xscroll = MIN((int)(getMaxHeight()-(r.bottom-r.top)), xscroll); + xscroll = MAX(0, xscroll); + if (isInited()) + onResize(); + invalidate(); + return; + } + case TIMER_SCROLLPAGE: { + int n = MulDiv(Wasabi::Std::getTickCount()-scrollpage_starttime,256,scrollpage_speed); + if (n > 255) n = 255; if (n < 0) n = 0; + float sintrans = (float)(sin(((float)n/255)*PI-PI/2)/2+0.5); + xscroll = (int)(((float)(scrollpage_target - scrollpage_start) * sintrans) + scrollpage_start); + if (n == 255) { + killTimer(TIMER_SCROLLPAGE); + scrollpage_timerset = 0; + } + if (isInited()) + onResize(); + invalidate(); + return; + } + default: + COMPONENTBUCKET2_PARENT::timerCallback(id); + return; + } +} + +int ComponentBucket2::childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2) { + switch (msg) { + case ChildNotify::COMPONENTBUCKET_SETTEXT: + setText((const wchar_t *)p1); + return 1; + } + return COMPONENTBUCKET2_PARENT::childNotify(child, msg, p1, p2); +} + +void ComponentBucket2::prev_down(Group *l) { + if (!l) return; + for (int i=0;i<cblist.getNumItems();i++) { + if (cblist[i]->getGuiObject()->guiobject_getParentGroup()->getParentContainer() == l->getParentContainer()) + cblist[i]->prev_down(); + } +} + +void ComponentBucket2::next_down(Group *l) { + if (!l) return; + for (int i=0;i<cblist.getNumItems();i++) { + if (cblist[i]->getGuiObject()->guiobject_getParentGroup()->getParentContainer() == l->getParentContainer()) + cblist[i]->next_down(); + } +} + +void ComponentBucket2::prev_up(Group *l) { + if (!l) return; + for (int i=0;i<cblist.getNumItems();i++) { + if (cblist[i]->getGuiObject()->guiobject_getParentGroup()->getParentContainer() == l->getParentContainer()) + cblist[i]->prev_up(); + } +} + +void ComponentBucket2::next_up(Group *l) { + if (!l) return; + for (int i=0;i<cblist.getNumItems();i++) { + if (cblist[i]->getGuiObject()->guiobject_getParentGroup()->getParentContainer() == l->getParentContainer()) + cblist[i]->next_up(); + } +} + +void ComponentBucket2::prev_page(Group *l) { + if (!l) return; + for (int i=0;i<cblist.getNumItems();i++) { + if (cblist[i]->getGuiObject()->guiobject_getParentGroup()->getParentContainer() == l->getParentContainer()) + cblist[i]->prev_page(); + } +} + +void ComponentBucket2::next_page(Group *l) { + if (!l) return; + for (int i=0;i<cblist.getNumItems();i++) { + if (cblist[i]->getGuiObject()->guiobject_getParentGroup()->getParentContainer() == l->getParentContainer()) + cblist[i]->next_page(); + } +} + +void ComponentBucket2::prev_down() { + direction = SCROLL_LEFT; + startScrollTimer(); +} + +void ComponentBucket2::prev_up() { + stopScrollTimer(); +} + +void ComponentBucket2::next_down() { + direction = SCROLL_RIGHT; + startScrollTimer(); +} + +void ComponentBucket2::next_up() { + stopScrollTimer(); +} + +void ComponentBucket2::prev_page() { + scrollpage_starttime = Wasabi::Std::getTickCount(); + scrollpage_start = xscroll; + RECT r; + getClientRect(&r); + int nx = 0; + if (vertical) + nx = r.bottom - r.top; + else + nx = r.right - r.left; + nx = xscroll - nx; + if (nx < 0) nx = 0; + scrollpage_target = nx; + if (!scrollpage_timerset) { + setTimer(TIMER_SCROLLPAGE, 20); + scrollpage_timerset = 1; + } +} + +void ComponentBucket2::next_page() { + scrollpage_starttime = Wasabi::Std::getTickCount(); + scrollpage_start = xscroll; + RECT r; + getClientRect(&r); + int nx = 0; + if (vertical) + nx = r.bottom - r.top; + else + nx = r.right - r.left; + nx += xscroll; + if (!vertical) + nx = MIN((int)(getMaxWidth()-(r.right-r.left)), nx); + else + nx = MIN((int)(getMaxHeight()-(r.bottom-r.top)), nx); + scrollpage_target = nx; + if (!scrollpage_timerset) { + setTimer(TIMER_SCROLLPAGE, 20); + scrollpage_timerset = 1; + } +} + +void ComponentBucket2::startScrollTimer() { + if (timerset) return; + timerset=1; + lastticcount = Wasabi::Std::getTickCount(); + setTimer(TIMER_SCROLL, TIMER_SPEED); +} + +void ComponentBucket2::stopScrollTimer() { + if (!timerset) return; + killTimer(TIMER_SCROLL); + timerset=0; +} + +void ComponentBucket2::setText(const wchar_t *t) +{ + for (int i=0;i<txtlist.getNumItems();i++) { + if (txtlist.enumItem(i)->getRootParent() == getRootParent()) { + txtlist.enumItem(i)->setName(t); + txtlist.enumItem(i)->invalidate(); + } + } +} + +void ComponentBucket2::setText(ifc_window *cb , const wchar_t *txt) { + for (int i=0;i<cblist.getNumItems();i++) { + if (static_cast<ifc_window *>(cblist.enumItem(i)) == cb) + cblist.enumItem(i)->setText(txt); + } +} + +void ComponentBucket2::registerText(Text *t, const wchar_t *id) +{ + ComponentBucket2 *cb = getComponentBucket(id); + if (cb) { + cb->doRegisterText(t); + return; + } + ifc_window *p = t->getDesktopParent(); + for (int i=0;i<cblist.getNumItems();i++) { + if (cblist.enumItem(i)->getDesktopParent() == p) + cblist.enumItem(i)->doRegisterText(t); + } +} + +void ComponentBucket2::unRegisterText(Text *t, const wchar_t *id) { + ComponentBucket2 *cb = getComponentBucket(id); + if (cb) { + cb->doUnregisterText(t); + return; + } + ifc_window *p = t->getDesktopParent(); + for (int i=0;i<cblist.getNumItems();i++) { + if (cblist.enumItem(i)->getDesktopParent() == p) + cblist.enumItem(i)->doUnregisterText(t); + } +} + +ComponentBucket2 *ComponentBucket2::getComponentBucket(const wchar_t *cb) { + if (!cb) return NULL; + for (int i=0;i<cblist.getNumItems();i++) { + if (cblist.enumItem(i)->getGuiObject()->guiobject_getId() + && !WCSICMP(cblist.enumItem(i)->getGuiObject()->guiobject_getId(), cb)) + return cblist.enumItem(i); + } + return NULL; +} + +void ComponentBucket2::setLMargin(int i) { + lmargin = i; + invalidate(); +} + +void ComponentBucket2::setRMargin(int i) { + rmargin = i; + invalidate(); +} + +void ComponentBucket2::setSpacing(int i) { + spacing = i; + invalidate(); +} + +int ComponentBucket2::getLMargin(void) { + return lmargin; +} + +int ComponentBucket2::getRMargin(void) { + return rmargin; +} + +int ComponentBucket2::getSpacing(void) { + return spacing; +} + +void ComponentBucket2::load() { + WindowCreateByTypeEnum wce(wndtype); + svc_windowCreate *obj; + while ((obj = wce.getNext()) != NULL) { + addItems(obj); + } + if (isPostOnInit()) + onResize(); +} + +void ComponentBucket2::doRegisterText(Text *t) { + txtlist.addItem(t); +} + +void ComponentBucket2::doUnregisterText(Text *t) { + txtlist.delItem(t); +} + + +void ComponentBucket2::addItems(svc_windowCreate *svc) { + + for (int i = 0; ; i++) { + ASSERTPR(i < 1336, "someone is lame-o"); + ServiceWndHolder *svcwnd = new ServiceWndHolder; + ifc_window *wnd = svc->createWindowOfType(wndtype, svcwnd, i); + if (wnd == NULL) { + delete svcwnd; + if (i==0) SvcEnum::release(svc); + break; + } + svcwnd->setChild(wnd, svc); + myclients.addItem(svcwnd); + svcwnd->setStartHidden(1); + svcwnd->init(this); + } +} + +int ComponentBucket2::getMaxWidth() { + if (!vertical) { + int p = getLMargin(); + + for (int j=0;j<myclients.getNumItems();j++) { + //CUT for (int i=0;i<myclients.enumItem(j)->wnds.getNumItems();i++) { + RECT r; + myclients[j]->getClientRect(&r); + p+=(r.right-r.left)+getSpacing(); + //CUT } + } + + return p+getRMargin(); + } + RECT r; + getClientRect(&r); + return r.right-r.left; +} + +int ComponentBucket2::getMaxHeight() { + if (vertical) { + int p = getLMargin(); + + for (int j=0;j<myclients.getNumItems();j++) { + //CUT for (int i=0;i<myclients.enumItem(j)->wnds.getNumItems();i++) { + RECT r; + myclients[j]->getClientRect(&r); + p+=(r.bottom-r.top)+getSpacing(); + //CUT } + } + + return p+getLMargin(); + } + RECT r; + getClientRect(&r); + return r.right-r.left; +} + +int ComponentBucket2::onResize() { + COMPONENTBUCKET2_PARENT::onResize(); + + RECT r; + getClientRect(&r); + + int sh; + int myh; + if (!vertical) { + sh = r.bottom - r.top; + } else { + sh = r.right - r.left; + } + myh = sh; + + + int p = getLMargin() - xscroll; + + for (int j=0;j<myclients.getNumItems();j++) { +//CUT for (int i=0;i<myclients.enumItem(j)->wnds.getNumItems();i++) { +//CUT api_window *c = myclients.enumItem(j)->wnds.enumItem(i); +ifc_window *c = myclients[j]; + int w = c->getPreferences(SUGGESTED_W); + int h = c->getPreferences(SUGGESTED_H); + + if (!vertical) { + float rt = (float)myh / (float)h; + if (ABS(rt-1.0f) > 0.1) { + w = (int)((float)w*rt); + h = (int)((float)h*rt); + } + } else { + float rt = (float)myh / (float)w; + if (ABS(rt-1.0f) > 0.1) { + w = (int)((float)w*rt); + h = (int)((float)h*rt); + } + } + + if (!vertical) + c->resize(p+r.left, r.top+(sh - h) / 2, w, h); + else + c->resize(r.left+(sh - w) / 2, p+r.top, w, h); + + if (!vertical) + p+=w+getSpacing(); + else + p+=h+getSpacing(); + + if (!c->isVisible()) c->setVisible(1); +//CUT } + } + + return 1; +} + +void ComponentBucket2::setVertical(int v) { + if (v == vertical) return; + vertical = v; + if (isInited()) invalidate(); +} + +int ComponentBucket2::getNumChildren() { + return myclients.getNumItems(); +} + +GuiObject *ComponentBucket2::enumChildren(int i) { + ServiceWndHolder *w = myclients.enumItem(i); + if (!w) return NULL; + ifc_window *_w = w->rootwndholder_getRootWnd(); + if (!_w) return NULL; + return _w->getGuiObject(); +} + +PtrList<ComponentBucket2> ComponentBucket2::cblist; + +CompBucketScriptController _cbucketController; +CompBucketScriptController *cbucketController = &_cbucketController; + + +// -- Functions table ------------------------------------- +function_descriptor_struct CompBucketScriptController ::exportedFunction[] = { + {L"getMaxWidth", 0, (void*)ComponentBucket2::script_vcpu_getMaxWidth}, + {L"getMaxHeight", 0, (void*)ComponentBucket2::script_vcpu_getMaxHeight}, + {L"getScroll", 0, (void*)ComponentBucket2::script_vcpu_getScroll}, + {L"setScroll", 1, (void*)ComponentBucket2::script_vcpu_setScroll}, + {L"getNumChildren", 0, (void*)ComponentBucket2::script_vcpu_getNumChildren}, + {L"enumChildren", 1, (void*)ComponentBucket2::script_vcpu_enumChildren}, + {L"fake", 0, (void*)ComponentBucket2::script_vcpu_fake }, +}; + +const wchar_t *CompBucketScriptController ::getClassName() { + return L"ComponentBucket"; +} + +const wchar_t *CompBucketScriptController ::getAncestorClassName() { + return L"GuiObject"; +} + +ScriptObject *CompBucketScriptController::instantiate() { + ComponentBucket2 *cb = new ComponentBucket2; + ASSERT(cb != NULL); + return cb->getScriptObject(); +} + +void CompBucketScriptController::destroy(ScriptObject *o) { + ComponentBucket2 *cb = static_cast<ComponentBucket2 *>(o->vcpu_getInterface(cbucketGuid)); + ASSERT(cb != NULL); + delete cb; +} + +void *CompBucketScriptController::encapsulate(ScriptObject *o) { + return NULL; // no encapsulation for componentbucket yet +} + +void CompBucketScriptController::deencapsulate(void *o) { +} + +int CompBucketScriptController ::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *CompBucketScriptController ::getExportedFunctions() { + return exportedFunction; +} + +GUID CompBucketScriptController ::getClassGuid() { + return cbucketGuid; +} + +scriptVar ComponentBucket2::script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + RETURN_SCRIPT_VOID; +} + +scriptVar ComponentBucket2::script_vcpu_getMaxWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ComponentBucket2 *cb = static_cast<ComponentBucket2*>(o->vcpu_getInterface(cbucketGuid)); + if (cb) return MAKE_SCRIPT_INT(cb->getMaxWidth()); + RETURN_SCRIPT_ZERO; +} + +scriptVar ComponentBucket2::script_vcpu_getMaxHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ComponentBucket2 *cb = static_cast<ComponentBucket2*>(o->vcpu_getInterface(cbucketGuid)); + if (cb) return MAKE_SCRIPT_INT(cb->getMaxHeight()); + RETURN_SCRIPT_ZERO; +} + +scriptVar ComponentBucket2::script_vcpu_getScroll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ComponentBucket2 *cb = static_cast<ComponentBucket2*>(o->vcpu_getInterface(cbucketGuid)); + if (cb) return MAKE_SCRIPT_INT(cb->getScroll()); + RETURN_SCRIPT_ZERO; +} + +scriptVar ComponentBucket2::script_vcpu_setScroll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) { + SCRIPT_FUNCTION_INIT + ComponentBucket2 *cb = static_cast<ComponentBucket2*>(o->vcpu_getInterface(cbucketGuid)); + if (cb) cb->setScroll(GET_SCRIPT_INT(v)); + RETURN_SCRIPT_VOID; +} + +scriptVar ComponentBucket2::script_vcpu_getNumChildren(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ComponentBucket2 *cb = static_cast<ComponentBucket2*>(o->vcpu_getInterface(cbucketGuid)); + if (cb) return MAKE_SCRIPT_INT(cb->getNumChildren()); + RETURN_SCRIPT_VOID; +} + +scriptVar ComponentBucket2::script_vcpu_enumChildren(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) { + SCRIPT_FUNCTION_INIT + ComponentBucket2 *cb = static_cast<ComponentBucket2*>(o->vcpu_getInterface(cbucketGuid)); + if (cb) { + GuiObject *o = cb->enumChildren(GET_SCRIPT_INT(v)); + if (o) return MAKE_SCRIPT_OBJECT(o->guiobject_getScriptObject()); + } + RETURN_SCRIPT_ZERO; +} + diff --git a/Src/Wasabi/api/skin/widgets/compbuck2.h b/Src/Wasabi/api/skin/widgets/compbuck2.h new file mode 100644 index 00000000..e08c8aa0 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/compbuck2.h @@ -0,0 +1,156 @@ +//PORTABLE +#ifndef _COMPBUCK_H +#define _COMPBUCK_H + +#include <api/wnd/wndclass/clickwnd.h> +#include <api/skin/widgets/text.h> +#include <api/wnd/wndclass/guiobjwnd.h> +#include <api/service/svc_enum.h> +#include <api/script/objects/guiobj.h> +#include <api/service/svcs/svc_wndcreate.h> + +// {97AA3E4D-F4D0-4fa8-817B-0AF22A454983} +static const GUID cbucketGuid = +{ 0x97aa3e4d, 0xf4d0, 0x4fa8, { 0x81, 0x7b, 0xa, 0xf2, 0x2a, 0x45, 0x49, 0x83 } }; + +#define COMPONENTBUCKET2_PARENT GuiObjectWnd +#define COMPONENTBUCKET2_XMLPARENT GuiObjectWnd + +class CompBucketScriptController: public GuiObjectScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + 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); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern CompBucketScriptController *cbucketController; + +class Layout; + +class ServiceWndHolder; + +class ComponentBucket2 : public COMPONENTBUCKET2_PARENT { +public: + ComponentBucket2(); + virtual ~ComponentBucket2(); + + virtual int onInit(); + virtual int setXuiParam(int _xuihandle, int id, const wchar_t *name, const wchar_t *strval); + +/* virtual int getAutoHeight(); + virtual int getAutoWidth();*/ + + virtual void timerCallback(int id); + virtual int childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2); + + virtual int onResize(); + virtual void setLMargin(int i); + virtual void setRMargin(int i); + virtual void setSpacing(int i); + virtual int getLMargin(void); + virtual int getRMargin(void); + virtual int getSpacing(void); + + void next_page(); + void prev_page(); + void next_down(); + void next_up(); + void prev_down(); + void prev_up(); + static void next_down(Group *l); // next_down on all compbucks in this group + static void next_up(Group *l); // next_up on all compbucks in this group + static void prev_down(Group *l); // prev_down on all compbucks in this group + static void prev_up(Group *l); // prev_up on all compbucks in this group + static void prev_page(Group *l); // prev_down on all compbucks in this group + static void next_page(Group *l); // prev_up on all compbucks in this group + + void setText(const wchar_t *txt); + static void setText(ifc_window *cb , const wchar_t *txt); // set this text for this compbuck's rootwnd + + static void registerText(Text *t, const wchar_t *id=NULL); // id=NULL => register for all compbucks in this group + static void unRegisterText(Text *t, const wchar_t *id=NULL); // id=NULL => unregister for all compbucks in this group + + static ComponentBucket2 *getComponentBucket(const wchar_t *cb); + + int getMaxWidth(); + int getMaxHeight(); + void setVertical(int v); + void setScroll(int v); + int getScroll(); + int getNumChildren(); + GuiObject *enumChildren(int i); + +protected: +/*static */void CreateXMLParameters(int master_handle); + enum { + COMPBUCK_LEFTMARGIN=0, + COMPBUCK_RIGHTMARGIN, + COMPBUCK_SPACING, + COMPBUCK_VERTICAL, + COMPBUCK_WNDTYPE, + }; + +private: + + void load(); + void addItems(svc_windowCreate *wc); + void doRegisterText(Text *t); + void doUnregisterText(Text *t); + + int timeron; + static PtrList<ComponentBucket2> cblist; + PtrList<Text> txtlist; + StringW id; + PtrList<ServiceWndHolder> myclients; + int lmargin; + int rmargin; + int spacing; + + int xscroll; + int direction; + int timerset; + + void startScrollTimer(); + void stopScrollTimer(); + uint32_t lastticcount; + int vertical; + int xuihandle; + static XMLParamPair params[]; + StringW wndtype; + + uint32_t scrollpage_starttime; + int scrollpage_timerset; + int scrollpage_start; + int scrollpage_target; + int scrollpage_speed; + +public: + + static scriptVar script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_getMaxWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_getMaxHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_getScroll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_setScroll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v); + static scriptVar script_vcpu_getNumChildren(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_enumChildren(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v); +}; + +extern const wchar_t componentBucketXuiObjectStr[]; +extern char componentBucketXuiSvcName[]; +class ComponentBucketXuiSvc : public XuiObjectSvc<ComponentBucket2, componentBucketXuiObjectStr, componentBucketXuiSvcName> {}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/customobject.cpp b/Src/Wasabi/api/skin/widgets/customobject.cpp new file mode 100644 index 00000000..bfe0066f --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/customobject.cpp @@ -0,0 +1,8 @@ +#include <precomp.h> +#include "customobject.h" + +#define CBCLASS CustomObjectI +START_DISPATCH; + VCB(CUSTOMOBJECT_SETROOTWND, customobject_setRootWnd); +END_DISPATCH; + diff --git a/Src/Wasabi/api/skin/widgets/customobject.h b/Src/Wasabi/api/skin/widgets/customobject.h new file mode 100644 index 00000000..5cd6a3f3 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/customobject.h @@ -0,0 +1,78 @@ +#ifndef __CUSTOMOBJECT_H +#define __CUSTOMOBJECT_H + +#include <bfc/dispatch.h> +#include <bfc/common.h> + +class ifc_window; + +// {F5527A4F-C910-48c2-A80B-98A60D317F35} +const GUID customObjectGuid = +{ 0xf5527a4f, 0xc910, 0x48c2, { 0xa8, 0xb, 0x98, 0xa6, 0xd, 0x31, 0x7f, 0x35 } }; + + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class CustomObject : public Dispatchable { +public: + + /** + Method + + @see + @ret + @param + */ + void customobject_setRootWnd(ifc_window *w); + + enum { + CUSTOMOBJECT_SETROOTWND=10, + CUSTOMOBJECT_GETROOTWND=20, + }; +}; + +inline void CustomObject::customobject_setRootWnd(ifc_window *w) { + + /** + Method + + @see + @ret + @param + */ + _voidcall(CUSTOMOBJECT_SETROOTWND, w); +} + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class CustomObjectI : public CustomObject { +public: + + + /** + Method + + @see + @ret + @param + */ + virtual void customobject_setRootWnd(ifc_window *w)=0; + +protected: + RECVS_DISPATCH; +}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/db/autofilterlist.cpp b/Src/Wasabi/api/skin/widgets/db/autofilterlist.cpp new file mode 100644 index 00000000..513d8c44 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/db/autofilterlist.cpp @@ -0,0 +1,406 @@ +#include <precomp.h> +#include "autofilterlist.h" +#include <api/db/subqueryserver.h> +#include <api/script/objects/c_script/c_text.h> +#include <api/script/objects/c_script/h_button.h> +#include <api/wnd/popup.h> +#include <bfc/file/filename.h> + +#define TIMER_SCANNERDEL 0x6891 + +class ButtHooker : public H_Button { +public: + ButtHooker(AutoFilterList *hangout, ScriptObject *butt) : afl(hangout), H_Button(butt) { } + void hook_onLeftClick() { + afl->doFieldPopup(); + } + +private: + AutoFilterList *afl; +}; + +FilterListItem::FilterListItem(void *_data, int _datalen, int _datatype) { + data_len = _datalen; + data_type = _datatype; + data.setSize(data_len+1); + MEMCPY(data.getMemory(), _data, data_len); +} + +AutoFilterList::AutoFilterList() { + showColumnsHeaders = FALSE; + local_scanner = NULL; + order = -1; + viscount = 0; + grab_playstrings = 0; + linked = 1; + hooker = NULL; + needrestart = 0; + querydirection = SetQuery::FORWARD; + last_populate_flag = -1; + setContent("wasabi.buttonbar.stack"); + fn = NULL; + data_type = NULL; +} + +AutoFilterList::~AutoFilterList() { + delete local_scanner; + delete hooker; +} + +int AutoFilterList::onInit() { + AUTOFILTERLIST_PARENT::onInit(); + //scannerserver_newScanner(); + + return 1; +} + +void AutoFilterList::scannerserver_onNewScanner(SharedDbScannerI *scanner) { + AUTOFILTERLIST_DBPARENTSRV::scannerserver_onNewScanner(scanner); + delete local_scanner; + local_scanner = new dbScanner(scannerserver_getTable()); + local_scanner->setQuery(sqs_getQuery()); +} + +void AutoFilterList::mqc_onNewMultiQuery(SubQueryServer *modifier, int flag) { + AUTOFILTERLIST_DBPARENTCLIENT::mqc_onNewMultiQuery(modifier); + if (!isInited()) return; + if (modifier == this && !needrestart) return; + if (local_scanner == NULL) return; + int id = sqs_getCooperativeId(); + int need_reset = (modifier == NULL || needrestart); + if (!need_reset) switch (flag) {//glag! + default: + case SetQuery::FORWARD: + need_reset = (id >= modifier->sqs_getCooperativeId()); + break; + case SetQuery::REVERSE: + need_reset = (id <= modifier->sqs_getCooperativeId()); + break; + case SetQuery::GLOBAL: + need_reset = (id != modifier->sqs_getCooperativeId()); + break; + } + + if (need_reset) { + needrestart = 0; + + last_populate_flag = flag; + + int optimized = sqs_getMultiQueryServer() && sqs_getMultiQueryServer()->mqs_isQueryEmpty(); + + uniques.deleteAll(); + deleteAllItems(); + + const char *allstr = getAllString(); + FilterListItem *fli = new FilterListItem((void *)allstr, STRLEN(allstr)+1, MDT_STRINGZ); + insertItem(0, NULL, reinterpret_cast<LPARAM>(fli)); + setSelected(0, 1); + + SharedDbScannerI *shs = scannerserver_getScanner(); + if (shs != NULL) { + dbSvcScanner *sc = shs->getScanner(); + if (sc != NULL) sc->cancelQuery(); + } + dbSvcScanner *lc= local_scanner->getScanner(); + if (lc != NULL) lc->cancelQuery(); + + if (optimized) { + grab_playstrings = 0; + setRedraw(0); + dbScanner *unique_scanner = new dbScanner(sqs_getTable(), field); + while (!unique_scanner->eof()) { + char data[4096]=""; + unique_scanner->getData("Value", data, 4095, MDT_STRINGZ); + data[4095]=0; + insertData(data, STRLEN(data)+1, MDT_STRINGZ); + unique_scanner->next(); + } + setRedraw(1); + delete unique_scanner; + } else { + grab_playstrings = 1; + lc->cancelQuery(); + } + + return; + } +} + +void AutoFilterList::mqc_onCompleteMultiQuery() { + grab_playstrings = 0; +} + +void AutoFilterList::mqc_onAddPlaystring(const char *playstring, int nitems, int thispos) { + AUTOFILTERLIST_DBPARENTCLIENT::mqc_onAddPlaystring(playstring, nitems, thispos); + if (grab_playstrings) + filterEntry(playstring, local_scanner, field); +} + +void AutoFilterList::setMetadataField(const char *_field) { + if (!field.isempty() && STRCASEEQL(field, _field)) return; + field = _field; + delColumnByPos(0); + addColumn(field, 100); + data_type = api->metadb_getMetaDataType(field); + sqs_setTable(api->metadb_getMetaDataTable(field)); + if (isPostOnInit()) + setLabelName(); + sqs_setQuery(""); + needrestart = 1; + scannerserver_newScanner(); +} + +int AutoFilterList::onResize() { + AUTOFILTERLIST_PARENT::onResize(); + RECT r = clientRect(); + ListColumn *c = enumListColumn(0); + if (!c) return 1; + c->setWidth(r.right-r.left-4); + recalcHeaders(); + + return 1; +} + +void AutoFilterList::getClientRect(RECT *r) { + AUTOFILTERLIST_PARENT::getClientRect(r); + api_window *rw = getContentRootWnd(); + if (rw) r->top += rw->getPreferences(SUGGESTED_H); +// else r->top += 16; +} + +void AutoFilterList::rootwndholder_getRect(RECT *r) { + getClientRect(r); + r->bottom = r->top; + api_window *rw = getContentRootWnd(); + if (rw) r->top -= rw->getPreferences(SUGGESTED_H); +// else r->top += 16; +} + +void AutoFilterList::onNewContent() { + setLabelName(); + // hook the clicks + delete hooker; + ScriptObject *mousetrap = findScriptObject("mousetrap"); + hooker = new ButtHooker(this, mousetrap); +} + +int AutoFilterList::ownerDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int isselected, int isfocused) { + COLORREF bgcolor = isfocused ? getFocusColor(lParam) : getSelBgColor(lParam); + COLORREF fgcolor = getTextColor(lParam); + + RECT box; + canvas->getClipBox(&box); + + if (!getBgBitmap()) { + RECT r2 = *r; + r2.left = box.left; + new RegionI reg(&r2); + canvas->selectClipRgn(®); + canvas->fillRect(r, getBgColor()); + } + + canvas->setTextColor(fgcolor); + + if (isselected) { + RECT mr = *r; + canvas->fillRect(&mr, bgcolor); + } + + if (isfocused) + canvas->drawRect(r, 0, getFocusColor(lParam)); + + canvas->pushTextSize(getFontSize()); + + int x = 1+r->left; + for (int i = 0; i < getNumColumns(); i++) { + RECT ir; + ir.left = x; + ir.right = x + getColumnWidth(i); + ir.top = r->top; + ir.bottom = r->bottom; + if (ir.right >= box.left && ir.bottom >= box.top && ir.left <= box.right && ir.top <= box.bottom) { + FilterListItem *fli = reinterpret_cast<FilterListItem *>(lParam); + api->metadb_renderData(canvas, ir, (void *)fli->getData(), fli->getDatatype(), 0); + } + x = ir.right; + } + canvas->popTextSize(); + return 1; +} + +void AutoFilterList::filterEntry(const char *playstring, dbScanner *scanner, const char *field) { + dbSvcScanner *sp = scanner->getScanner(); + if (sp != NULL) sp->push(); + scanner->setIndexName(MT_PLAYSTRING); + scanner->setIndexValue(playstring); + scanner->first(); + + if (scanner->eof()) return; + + char data[4096]=""; + scanner->getData((char *)field, data, 4095, data_type); + data[4095]=0; + + sp->pop(); + + switch (data_type) { + case MDT_INT: + case MDT_TIME: + case MDT_BOOLEAN: + case MDT_TIMESTAMP: + filterInt(*(int *)data); + break; + case MDT_STRINGZ: + filterString((const char *)data); + break; + } +} + +void AutoFilterList::filterInt(int data) { + int pos=0; + if (uniques.findItem((const char *)&data, &pos)) return; + insertData(&data, 4, data_type); +} + +void AutoFilterList::insertData(void *data, int len, int type) { + int pos=0; + FilterListItem *fli = new FilterListItem(data, len, type); + uniques.addItem(fli); + pos = uniques.searchItem(fli); + insertItem(pos+1/*+1 for item ALL at the top*/, NULL, reinterpret_cast<LPARAM>(fli)); +} + +void AutoFilterList::filterString(const char *data) { + if (!data || !*data) return; + int pos=0; + if (uniques.findItem(data, &pos)) return; + insertData((void *)data, STRLEN(data)+1, data_type); +} + +void AutoFilterList::onLeftClick(int itemnum) { + + if (itemnum == 0 && last_populate_flag != lastflag) { + needrestart = 1; + } + String query; + if (itemnum > 0) { + for (int i=0;i<getNumItems();i++) { + if (getItemSelected(i)) { + if (!query.isempty()) + query += " || "; + query += field; + query += " == "; + FilterListItem *fli = reinterpret_cast<FilterListItem *>(getItemData(i)); + switch (fli->getDatatype()) { + case MDT_INT: + case MDT_TIME: + case MDT_BOOLEAN: + case MDT_TIMESTAMP: + query += StringPrintf("%d", *(int *)fli->getData()); + break; + case MDT_STRINGZ: + query += "\""; + query += fli->getData(); + query += "\""; + break; + } + } + } + } + sqs_setQuery(query, querydirection); + if (local_scanner != NULL) local_scanner->setQuery(query); +} + +void AutoFilterList::onDoubleClick(int itemnum) { + int sav = querydirection; + querydirection = SetQuery::GLOBAL; + onLeftClick(itemnum); + querydirection = sav; +} + +void AutoFilterList::sqs_onAttachServer(MultiQueryServer *s) { + s->mqs_registerClient(this); +} + +void AutoFilterList::sqs_onDetachServer(MultiQueryServer *s) { + s->mqs_unregisterClient(this); +} + +void AutoFilterList::sqs_reset() { + postDeferredCallback(7873, 3245); +} + +int AutoFilterList::onDeferredCallback(intptr_t p1, intptr_t p2) { + if (p1 == 7873 && p2 == 3245) { + deselectAll(); + setItemFocused(0); + setSelected(0, TRUE); + needrestart=1; last_populate_flag = -1; + onLeftClick(0); + ensureItemVisible(0); + return 1; + } + return AUTOFILTERLIST_PARENT::onDeferredCallback(p1, p2); +} + +void AutoFilterList::setLabelName() { + ScriptObject *tx = findScriptObject("buttonbar.text"); + if (tx == NULL) return; + C_Text(tx).setText(field); +} + +void AutoFilterList::setQueryDirection(int glag) { + querydirection = glag; +} + +void AutoFilterList::doFieldPopup() { + PopupMenu popup; + dbSvcScanner *scanner = api->metadb_newScanner(sqs_getTable()); + if (scanner == NULL) return; + int n = scanner->getNumCols(); + PtrListQuickSorted<String, StringComparator> fields; + for (int i = 0; i < n; i++) { + dbSvcColInfo *info = scanner->enumCol(i); + if (!info->uniques_indexed) continue; + fields.addItem(new String(info->name)); + } + fields.sort(); + foreach(fields) + const char *name = fields.getfor()->getValue(); + int checked = STRCASEEQLSAFE(name, field); + popup.addCommand(name, foreach_index, checked); + endfor + RECT cr = clientRect(); + clientToScreen((int *)&cr.left, (int *)&cr.top); + int r = popup.popAtXY(cr.left, cr.top); + if (r >= 0) { + const char *col = fields.enumItem(r)->getValue(); + dbSvcColInfo *info = scanner->getColByName(col); + setMetadataField(info->name); + } + fields.deleteAll(); + api->metadb_deleteScanner(scanner); +} + +void AutoFilterList::onVScrollToggle(BOOL set) { + AUTOFILTERLIST_PARENT::onVScrollToggle(set); + if (getContentRootWnd() && isPostOnInit()) + onResize(); +} + +int AutoFilterList::onBeginDrag(int iItem) { + String query; + FilterListItem *fli = reinterpret_cast<FilterListItem *>(getItemData(iItem)); + if (fli == NULL) return 0; // BU added in response to talkback data we'll see if it helps + String val = (fli->getDatatype() == MDT_STRINGZ) ? fli->getData() : StringPrintf(*(int *)fli->getData()).getValue(); + fn = new FilenameI(StringPrintf("query://%s;\"%s\" == \"%s\"", StringPrintf(scannerserver_getTable()).getValue(), field.getValue(), val.getValue())); + addDragItem(Filename::dragitem_getDatatype(), static_cast<Filename*>(fn)); + handleDrag(); + return 1; +} + +int AutoFilterList::dragComplete(int success) { + delete fn; fn = NULL; + return 1; +} + diff --git a/Src/Wasabi/api/skin/widgets/db/autofilterlist.h b/Src/Wasabi/api/skin/widgets/db/autofilterlist.h new file mode 100644 index 00000000..df998465 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/db/autofilterlist.h @@ -0,0 +1,447 @@ +#ifndef __AUTOFILTERLIST_H +#define __AUTOFILTERLIST_H + +#include "../std.h" +#include "listwnd.h" +#include "../db/scanner.h" +#include "../timeslicer.h" +#include "../db/subqueryserver.h" +#include "../db/multiqueryclient.h" +#include "autoquerylist.h" + +/** + A filter list item is a data item of any type or + size to put on a FilterList. The type and size are accessible + for memory management purposes. + + @short Items for FilterLists + @author Nullsoft + @ver 1.0 + @see FilterListItemSort, MultiQueryServer +*/ +class FilterListItem { + public: + + /** + Allocates memory for copying a data + object, and then copies the object into newly allocated memory. + + @see MemBlock + @see VoidMemblock + @param _data Pointer to a data object + @param _datalen Length of data object + @param _datatype Type of data object + */ + FilterListItem(void *_data, int _datalen, int _datatype); + + /** + Does nothing. + */ + virtual ~FilterListItem() { } + + /** + Get the data associated with the filter + list item. + + @see getDatatype() + @see getDataLen() + @ret A pointer to the data. + */ + const char *getData() { return data.getMemory(); } + + /** + Get the type of the data associated with the + filter list item. + + @see getData() + @see getDataLen() + @see metatags.h + @ret Data type of item. + */ + int getDatatype() { return data_type; } + + /** + Get the length of the data (in bytes). + + @see getDatatype() + @see getData() + @ret Length of data (in bytes). + */ + int getDataLen() { return data_len; } + + private: + + MemBlock<char> data; + int data_type; + int data_len; +}; + +/** + Provides methods for sorting a FilterList. + + @short FilterList sorting. + @author Nullsoft + @ver 1.0 + @see FilterListItem +*/ +class FilterListItemSort { + public: + /** + Determines the data types of two objects and + calls an appropriate comparison function to compare them. + + @assert The two objects to be compared have the same data type. + @see compareAttrib() + @ret -1, _p1 < _p2; 0, _p1 = _p2; 1, _p1 > _p2 + @param _p1 Object to compare + @param _p2 Object to compare + */ + static int compareItem(void *_p1, void *_p2) { + FilterListItem *p1 = ((FilterListItem *)_p1); + FilterListItem *p2 = ((FilterListItem *)_p2); + ASSERT(p1->getDatatype() == p2->getDatatype()); + switch (p1->getDatatype()) { + case MDT_INT: + case MDT_TIME: + case MDT_BOOLEAN: + case MDT_TIMESTAMP: { + int a = *(int *)p1->getData(); + int b = *(int *)p2->getData(); + if (a < b) return -1; + if (a > b) return 1; + return 0; } + case MDT_STRINGZ: + return STRICMP(p1->getData(), p2->getData()); + } + return 0; + } + + /** + Compares the value of an item to an attribute string, + or to the value of the attribute string cast to an + appropriate data type. + + @see compareItem() + @ret -1, _p1 < _p2; 0, _p1 = _p2; 1, _p1 > _p2 + @param attrib + @param _item + */ + static int compareAttrib(const wchar_t *attrib, void *_item) { + FilterListItem *item = ((FilterListItem *)_item); + switch (item->getDatatype()) { + case MDT_INT: + case MDT_TIME: + case MDT_BOOLEAN: + case MDT_TIMESTAMP: { + int a = *(int *)attrib; + int b = *(int *)item->getData(); + if (a < b) return -1; + if (a > b) return 1; + return 0; } + case MDT_STRINGZ: + return STRICMP(attrib, item->getData()); + } + return 0; + } +}; + +class ButtHooker; +class FilenameI; + +#define AUTOFILTERLIST_PARENT ListWnd +#define AUTOFILTERLIST_DBPARENTSRV SubQueryServerI +#define AUTOFILTERLIST_DBPARENTCLIENT MultiQueryClientI + +/** + A list of items to filter on. + + @short A list of items to filter on. + @author Nullsoft + @ver 1.0 + @see FilterListItemSort + @see FilterListItem +*/ +class AutoFilterList : public AUTOFILTERLIST_PARENT, + public AUTOFILTERLIST_DBPARENTSRV, + public AUTOFILTERLIST_DBPARENTCLIENT { + public: + + /** + Creates an empty filter list with a NULL local scanner. + + @see ~AutoFilterList() + */ + AutoFilterList(); + + /** + Deletes the local scanner. + + @see AutoFilterList() + */ + virtual ~AutoFilterList(); + + /** + Sets the field name and sets the scanner to NULL. + + @param field The name of the field. + */ + void setMetadataField(const char *field); + + /** + Creates and populates the list. + + @ret 1 + */ + virtual int onInit(); + + /** + Prepares a window for repainting in a new size. + + @ret 1 + */ + virtual int onResize(); + + virtual void getClientRect(RECT *); + virtual void rootwndholder_getRect(RECT *r); + virtual void onNewContent(); + + /** + Displays a window in a specified position and state. + + @ret 1 + @param canvas + @param pos + @param r + @param lParam + @param isselected + @param isfocused + */ + virtual int ownerDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int isselected, int isfocused); + + /** + Event is triggered when the user clicks (with the left mouse + button) on an item in the auto filter list. + + @param itemnum The number of the item that was clicked. + */ + virtual void onLeftClick(int itemnum); + + /** + Event is triggered when the user double-clicks (with the left mouse + button) on an item in the auto filter list. + + @param itemnum The number of the item that was double-clicked. + */ + virtual void onDoubleClick(int itemnum); // double-click on an item + + /** + Gets the dependency pointer. + + @ret The dependency pointer. + */ + virtual api_dependent *timeslicer_getDependencyPtr() { return rootwnd_getDependencyPtr(); } + + /** + Returns the proper query string for "all items" + present in the list. + + @ret Query string for "all items". + */ + virtual const char *getAllString() { return "All"; } + + + /** + Deletes the current scanner and sets up a new one. + + @param A shared database scanner + */ + virtual void scannerserver_onNewScanner(SharedDbScannerI *scanner); + + /** + Makes the necessary preparations for running a new query. + + @see SetQuery + @see MultiQueryServer, SubQueryServer + @param modifier refers to a SubQueryServer, which implements a simple filter. + @param flag The type of query that will be performed. + */ + virtual void mqc_onNewMultiQuery(SubQueryServer *modifier, int flag); + + /** + Gets the dependency pointer. + + @see api_dependent + @ret Dependency Dependency pointer + */ + virtual api_dependent *mqc_getDependencyPtr() { return rootwnd_getDependencyPtr(); } + + /** + Sets the order of the result list. + <b>Not currently implemented!</b> + + @param order order desired for the result list. + */ + void setOrder(int n) { order = n; } + + /** + Gets the order number. + + @see setOrder() + @ret Order number if linked, otherwise -1 + @param None + */ + virtual int sqs_getCooperativeId() { return linked ? order : -1; } + + /** + Event is triggered when a multi query has completed. + Has no external effect. + */ + virtual void mqc_onCompleteMultiQuery(); + + /** + Tests whether to enter a playstring in a filter entry, and does it if + necessary. + + @param playstring The playstring being added. + @param nitems HELP + @param thispos HELP + */ + virtual void mqc_onAddPlaystring(const char *playstring, int nitems, int thispos); + + + /** + Registers a client with a query server. + + @see sqs_onDetachServer() + @param s The server we will register to. + */ + virtual void sqs_onAttachServer(MultiQueryServer *s); + + /** + Unregisters a client with a query server. + + @see sqs_onAttachServer() + @param s The server we will unregister from. + */ + virtual void sqs_onDetachServer(MultiQueryServer *s); + + /** + Resets the query. + */ + virtual void sqs_reset(); + + /** + Generic deferred callback interface. + */ + virtual int onDeferredCallback(intptr_t p1, intptr_t p2); + + /** + Sets the linking status according to the value v. + + @param v linking status to set + */ + virtual void setLinked(int v) { linked = v; } + + /** + Set the direction of the query. + + @see SetQuery + @param glag The direction of the query. + */ + void setQueryDirection(int glag); + + /** + HELP + */ + void doFieldPopup(); + + /** + HELP + */ + virtual void onVScrollToggle(BOOL set); + + /** + HELP + */ + virtual int wantRenderBaseTexture() { return 1; } + + /** + Event is triggered when an item is + being dragged. + + @param iItem The item being dragged. + @ret 0, Drag not handled; 1, Drag handled; + */ + virtual int onBeginDrag(int iItem); + + /** + Gets called when the API thinks the drag and drop + was successful. + + @param success Drag and Drop succeeded? (According to API). + @ret 0, Drag and Drop not sucessful; 1, Drop and Drop completed successfully; + */ + virtual int dragComplete(int success); + + private: + /** + HELP + */ + void populate(); + + /** + Finds a specific entry in the database. + + @param playstring The playstring for the item. + @param scanner The db scanner to use. + @param field The field to be read. + */ + void filterEntry(const char *playstring, dbScanner *scanner, const char *field); + + /** + Filters and formats integer type data + and inserts it into the list to be displayed. + */ + void filterInt(int data); + + /** + Filters and formats string type data + and inserts it into the list to be displayed. + */ + void filterString(const char *data); + + /** + Inserts data into the list so that it may be + displayed. + + @see metatags.h + @param data The data to insert. + @param len The length of the data to insert. + @param type The type of the data to insert. + */ + void insertData(void *data, int len, int type); + + /** + Sets the filter label to the meta data field we are + currently sorting on. + + @see filterEntry() + */ + void setLabelName(); + + String field; + dbScanner *local_scanner; + PtrListInsertSorted<FilterListItem, FilterListItemSort> uniques; + int data_type; + int order; + int grab_playstrings; + int viscount; + int linked; + int needrestart; + int querydirection; + int last_populate_flag; + ButtHooker *hooker; + FilenameI *fn; +}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/db/autoquerylist.cpp b/Src/Wasabi/api/skin/widgets/db/autoquerylist.cpp new file mode 100644 index 00000000..5513cb34 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/db/autoquerylist.cpp @@ -0,0 +1,111 @@ +#include <precomp.h> +#include "autoquerylist.h" +#include <api/db/subqueryserver.h> +#include <api/db/multiqueryclient.h> +#include <api/db/sharedscanner.h> +#include <bfc/string/playstring.h> +#include <api/db/metatags.h> +#include <api/wnd/fakedrag.h> +#include <bfc/util/profiler.h> +#include <bfc/file/filename.h> +#include <api/api.h> +#include <api/service/svcs/svc_droptarget.h> +#include <api/service/svc_enum.h> + +#include "../../pledit/svc_pldir.h" +#include "../../pledit/playlist.h" +#include "../../pledit/editor.h" + +#define TIMER_SCANNERDEL 0x6879 +#define DC_REFRESH 0x6880 + +AutoQueryList::AutoQueryList() : + playlist(NULL) +{ + lastpc = -1; + last_status_update = 0; + pldir = NULL; + nFound = 0; +} + +AutoQueryList::~AutoQueryList() { + getGuiObject()->guiobject_removeAppCmds(this); + SvcEnum::release(pldir); +} + +int AutoQueryList::onInit() { + AUTOQUERYLIST_PARENT::onInit(); + + pldir = SvcEnumByGuid<svc_plDir>(); + if (pldir != NULL) { + PlaylistHandle hand = pldir->insertPlaylist(NULL, "Media library query results", NULL, TRUE); + pldir->setAutoSave(hand, FALSE); + playlist = pldir->getPlaylist(hand); + playlist->lock(TRUE); + } + + appcmds_addCmd("Reset", 0, AppCmds::SIDE_RIGHT); + getGuiObject()->guiobject_addAppCmds(this); + + postDeferredCallback(DC_REFRESH, 0); + + return 1; +} + +int AutoQueryList::onDeferredCallback(intptr_t p1, intptr_t p2) { + if (p1 == DC_REFRESH) { + mqs_refresh(); + return 0; + } + return AUTOQUERYLIST_PARENT::onDeferredCallback(p1, p2); +} + +void AutoQueryList::mqs_onAddPlaystring(const char *playstring, int nitems, int thispos) { + nfound++; + stdtimevalms now = Std::getTimeStampMS(); +// if (n > lastpc) { + if (now - last_status_update > 0.100) { + int n = (int)(thispos / (float)nitems * 100.0f); + getGuiObject()->guiobject_setCompleted(n); + getGuiObject()->guiobject_setStatusText(StringPrintf("%d%c, %d item%s found", n, '%', nfound, (nfound > 1) ? "s" : ""), TRUE); +// lastpc = n; +// } + last_status_update = now; + } + if (playlist != NULL) + playlist->addPlaylistItem(playstring, Playlist::APPEND, FALSE); +} + +void AutoQueryList::mqs_onCompleteMultiQuery() { + getGuiObject()->guiobject_setStatusText(StringPrintf("100%c, %d item%s found", '%', nfound, (nfound > 1) ? "s" : ""), TRUE); + lastpc = -1; + getGuiObject()->guiobject_popCompleted(); +} + +void AutoQueryList::mqs_onNewMultiQuery() { + nfound = 0; + getGuiObject()->guiobject_setStatusText("0%", TRUE); + getGuiObject()->guiobject_pushCompleted(); + if (playlist != NULL) { + playlist->deleteAll(); + + GuiObject *ed = getGuiObject()->guiobject_findObjectByInterface(Editor::getInterfaceGuid()); + if (ed != NULL) { + Editor *e = static_cast<Editor*>(ed->guiobject_getRootWnd()->getInterface(Editor::getInterfaceGuid())); + e->setPlaylistByHandle(playlist->getHandle()); + } + } +} + +void AutoQueryList::appcmds_onCommand(int id, const RECT *buttonRect, int which_btn) { + switch (id) { + case 0: + resetSubQueries(); + break; + } +} + +void AutoQueryList::onSetVisible(int v) { + AUTOQUERYLIST_PARENT::onSetVisible(v); + if (!v) mqs_abort(); +} diff --git a/Src/Wasabi/api/skin/widgets/db/autoquerylist.h b/Src/Wasabi/api/skin/widgets/db/autoquerylist.h new file mode 100644 index 00000000..2ed7cd55 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/db/autoquerylist.h @@ -0,0 +1,109 @@ +#ifndef __AUTOQUERYLIST_H +#define __AUTOQUERYLIST_H + +#include "itemlistwnd.h" +#include "../db/multiqueryserver.h" +#include "../ptrlist.h" +#include "../string.h" +#include "../timeslicer.h" +#include "../appcmds.h" +#include "../../pledit/plhand.h" +#include "../nakedobject.h" + +class svc_plDir; +class Playlist; + +#define AUTOQUERYLIST_PARENT NakedObject +#define AUTOQUERYLIST_DBPARENTSRV MultiQueryServerI + +/** + Automates the display of the result set of + a query. + + Simply create an AutoQueryList instance, + set it's query with setQuery(). + + Can send results to the playlist directory + for automatic playlist creation based on + the result of the query. + + @short Automated query result display window. + @author Nullsoft + @ver 1.0 + @see AutoFilterList +*/ +class AutoQueryList : public AUTOQUERYLIST_PARENT, + public AUTOQUERYLIST_DBPARENTSRV, AppCmdsI { + + public: + /** + Initializes member data. + */ + AutoQueryList(); + + /** + Releases playlist directory service and removes + the AppCmd button. + */ + virtual ~AutoQueryList(); + + /** + Initializes the auto query list. + + ret 1 + */ + virtual int onInit(); + + /** + Event is triggered when a playstring is added to the result list. + + Updates the progress bar at the bottom of the window (from 0 to 100%). + + @param playstring The playstring to being added to the result list. + @param nitems The number of items (total) in the result list. + @param thispos The current position in the list of items. + */ + virtual void mqs_onAddPlaystring(const char *playstring, int nitems, int thispos); + + /** + Event is triggered when a new query is set. + + Updates the progress bar to 0%, resets the playlist associated + with this auto query list and resets the number of items found + for the query to zero. + */ + virtual void mqs_onNewMultiQuery(); + + /** + Event is triggered when a query completes. + + Updates the progress bar to 100% and resets the last + known progress count. + */ + virtual void mqs_onCompleteMultiQuery(); + virtual int onDeferredCallback(intptr_t p1, intptr_t p2); + +protected: + /** + Event is triggered when an AppCmd button (which belongs to this + auto query list) is pushed. + + Only one command is handled by the auto query list which causes the query + to be reset. The id of the command is 0. + + @param id The id of the command associated with the button that was pressed. + @param rect The RECT of the button that was pushed. + */ + virtual void appcmds_onCommand(int id, const RECT *buttonRect, int which_btn); + virtual void onSetVisible(int v); + +private: + + int lastpc; + int nfound; + Playlist *playlist; + svc_plDir *pldir; + stdtimevalms last_status_update; +}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/db/queryline.cpp b/Src/Wasabi/api/skin/widgets/db/queryline.cpp new file mode 100644 index 00000000..4f844508 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/db/queryline.cpp @@ -0,0 +1,32 @@ +#include <precomp.h> + +#include "queryline.h" + +#include <api/api.h> +#include <api/db/metatags.h> +#include <bfc/string/string.h> +#include <bfc/parse/pathparse.h> + +QueryLine::QueryLine(const char *query) : autoquery(FALSE), querytext(query), autofield(MT_NAME) { +} + +void QueryLine::setQuery(const char *query) { + querytext = query; + String sp = querytext; + if (autoquery && !querytext.isempty()) { + sp = ""; + PathParser pp(querytext, " "); + if (pp.getNumStrings() <= 0) return; + for (int i = 0; i < pp.getNumStrings(); i++) { + if (i != 0) sp += " and "; + sp += StringPrintf("(\"%s\" has \"%s\")", autofield.getValue(), pp.enumString(i)); + } + } + sqs_setQuery(sp); +} + +int QueryLine::setAuto(int bv) { + autoquery = !!bv; + setQuery(querytext); + return 1; +} diff --git a/Src/Wasabi/api/skin/widgets/db/queryline.h b/Src/Wasabi/api/skin/widgets/db/queryline.h new file mode 100644 index 00000000..4743e731 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/db/queryline.h @@ -0,0 +1,64 @@ +#ifndef _QUERYLINE_H +#define _QUERYLINE_H + +#include <api/skin/nakedobject.h> +#include <api/db/subqueryserver.h> + +#define QUERYLINE_PARENT NakedObject + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class QueryLine : public QUERYLINE_PARENT, public SubQueryServerI { +public: + + /** + Method + + @see + @ret + @param + */ + QueryLine(const char *query=NULL); + + /** + Method + + @see + @ret + @param + */ + virtual ~QueryLine() { } + + + /** + Method + + @see + @ret + @param + */ + virtual void setQuery(const char *query); + + /** + Method + + @see + @ret + @param + */ + int setAuto(int bv); + +protected: + int autoquery; + +private: + String querytext, autofield; +}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/db/xuiquerydrag.cpp b/Src/Wasabi/api/skin/widgets/db/xuiquerydrag.cpp new file mode 100644 index 00000000..c1981774 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/db/xuiquerydrag.cpp @@ -0,0 +1,103 @@ +#include <precomp.h> +#include "xuiquerydrag.h" +#include <tataki/canvas/ifc_canvas.h> +#include <api/db/multiqueryserver.h> +#include <bfc/file/filename.h> + +char QueryDragXuiObjectStr[] = "QueryDrag"; // This is the xml tag +char QueryDragXuiSvcName[] = "QueryDrag xui object"; // and this is the name of the service + +XMLParamPair QueryDrag::params[] = { + {QUERYDRAG_SETIMAGE, "image"}, + {QUERYDRAG_SETSOURCE, "source"}, + }; +QueryDrag::QueryDrag() { + setVirtual(0); // fucko + myxuihandle = newXuiHandle(); + + + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); + fn = NULL; +} + +QueryDrag::~QueryDrag() { +} + +int QueryDrag::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return QUERYDRAG_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) { + case QUERYDRAG_SETIMAGE: + setImage(value); + break; + case QUERYDRAG_SETSOURCE: + setSource(value); + break; + default: + return 0; + } + return 1; +} + +int QueryDrag::onPaint(Canvas *canvas) { + QUERYDRAG_PARENT::onPaint(canvas); + + RECT r; + getClientRect(&r); + + RenderBaseTexture(canvas, r, 255); + + if (image.getBitmap()) + image.getBitmap()->stretchToRectAlpha(canvas, &r, getPaintingAlpha()); + + return 1; +} + +void QueryDrag::setImage(const char *elementname) { + image = elementname; + if (isInited()) invalidate(); +} + +void QueryDrag::setSource(const char *elementname) { + source = elementname; +} + +int QueryDrag::getPreferences(int what) { + switch (what) { + case SUGGESTED_W: + if (image.getBitmap()) return image.getBitmap()->getWidth(); + case SUGGESTED_H: + if (image.getBitmap()) return image.getBitmap()->getHeight(); + } + return QUERYDRAG_PARENT::getPreferences(what); +} + +int QueryDrag::onMouseMove(int x, int y) { + QUERYDRAG_PARENT::onMouseMove(x,y); + if (isInClick()) + onBeginDrag(); + return 1; +} + +void QueryDrag::onBeginDrag() { + api_window *mqsw = NULL; + if (source.isempty()) mqsw = findWindowByInterface(multiQueryServerGuid); + else mqsw = findWindow(source); + if (!mqsw) return; + MultiQueryServer *mqs = static_cast<MultiQueryServer *>(mqsw->getInterface(multiQueryServerGuid)); + + // multiquery is now available in mqs->mqs_getMultiQuery(); using format "table guid;query;table guid;query;etc..." + fn = new FilenameI(StringPrintf("query://%s.nsq", mqs->mqs_getMultiQuery())); + addDragItem(Filename::dragitem_getDatatype(), static_cast<Filename*>(fn)); + handleDrag(); +} + +int QueryDrag::dragComplete(int success) { + ASSERT(fn != NULL); + delete fn; fn = NULL; + return 1; +} diff --git a/Src/Wasabi/api/skin/widgets/db/xuiquerydrag.h b/Src/Wasabi/api/skin/widgets/db/xuiquerydrag.h new file mode 100644 index 00000000..6dad07ae --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/db/xuiquerydrag.h @@ -0,0 +1,53 @@ +#ifndef __QUERYDRAG_H +#define __QUERYDRAG_H + +#include <api/wnd/wndclass/guiobjwnd.h> +#include <tataki/bitmap/autobitmap.h> + +class FilenameI; + +#define QUERYDRAG_PARENT GuiObjectWnd + +// ----------------------------------------------------------------------- +// Your wnd object class + +class QueryDrag : public QUERYDRAG_PARENT { + + public: + + QueryDrag(); + virtual ~QueryDrag(); + + virtual int onPaint(Canvas *c); + virtual int getPreferences(int what); + virtual int onMouseMove(int x, int y); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + void setImage(const char *elementname); + void setSource(const char *elementname); + void onBeginDrag(); + virtual int dragComplete(int success); + + private: + + AutoSkinBitmap image; + String source; + + FilenameI *fn; + + enum { + QUERYDRAG_SETIMAGE = 0, + QUERYDRAG_SETSOURCE, + }; + static XMLParamPair params[]; + int myxuihandle; +}; + + +// ----------------------------------------------------------------------- +extern char QueryDragXuiObjectStr[]; +extern char QueryDragXuiSvcName[]; +class QueryDragXuiSvc : public XuiObjectSvc<QueryDrag, QueryDragXuiObjectStr, QueryDragXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/db/xuiqueryline.cpp b/Src/Wasabi/api/skin/widgets/db/xuiqueryline.cpp new file mode 100644 index 00000000..2de3c918 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/db/xuiqueryline.cpp @@ -0,0 +1,73 @@ +#include <precomp.h> + +#include "xuiqueryline.h" +#include <api/skin/widgets/db/xuiquerylist.h> + +#define CB_SETQUERYLIST 0x1978 + +char QueryLineXuiObjectStr[] = "QueryLine"; // This is the xml tag +char QueryLineXuiSvcName[] = "QueryLine xui object"; + +ScriptQueryLine::ScriptQueryLine() { + myxuihandle = newXuiHandle(); + addParam(myxuihandle, "querylist", QUERYLINE_SETQUERYLIST, XUI_ATTRIBUTE_IMPLIED); + addParam(myxuihandle, "query", QUERYLINE_SETQUERY, XUI_ATTRIBUTE_IMPLIED); + addParam(myxuihandle, "auto", QUERYLINE_SETAUTO, XUI_ATTRIBUTE_IMPLIED); +} + +ScriptQueryLine::~ScriptQueryLine() { } + +/*int ScriptQueryLine::onInit() { + SCRIPTQUERYLINE_PARENT::onInit(); + if (!querylist_id.isempty()) + postDeferredCallback(CB_SETQUERYLIST, 0, 500); + return 1; +}*/ + +int ScriptQueryLine::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return SCRIPTQUERYLINE_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) { + case QUERYLINE_SETQUERYLIST: + setXuiQueryList(value); + break; + case QUERYLINE_SETQUERY: + ql_setQuery(value); + break; + case QUERYLINE_SETAUTO: + setAuto(WTOI(value)); + break; + default: + return 0; + } + return 1; +} + +void ScriptQueryLine::ql_setQuery(const char *q) { + ensureConnected(); + setQuery(q); +} + +void ScriptQueryLine::ensureConnected() { + api_window *o = findWindow(querylist_id); + if (!o) return; + ScriptQueryList *querylist = static_cast<ScriptQueryList *>(o->getInterface(queryListGuid)); + if (!querylist) return; + sqs_setMultiQueryServer(querylist); +} + +void ScriptQueryLine::setXuiQueryList(const char *v) { + querylist_id = v; +} + +/*int ScriptQueryLine::onDeferredCallback(intptr_t p1, intptr_t p2) { + switch (p1) { + case CB_SETQUERYLIST: + break; + default: + return SCRIPTQUERYLINE_PARENT::onDeferredCallback(p1, p2); + } + return 1; +} +*/
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/db/xuiqueryline.h b/Src/Wasabi/api/skin/widgets/db/xuiqueryline.h new file mode 100644 index 00000000..a65554e6 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/db/xuiqueryline.h @@ -0,0 +1,35 @@ +#ifndef _XUIQUERYLINE_H +#define _XUIQUERYLINE_H + +#include <api/skin/widgets/db/queryline.h> + +#define SCRIPTQUERYLINE_PARENT QueryLine +class ScriptQueryLine : public SCRIPTQUERYLINE_PARENT { +public: + ScriptQueryLine(); + virtual ~ScriptQueryLine(); + + //virtual int onInit(); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + void setXuiQueryList(const char *v); + + //virtual int onDeferredCallback(intptr_t p1, intptr_t p2); + +private: + enum { + QUERYLINE_SETQUERYLIST=1, + QUERYLINE_SETQUERY, + QUERYLINE_SETAUTO, + }; + void ql_setQuery(const char *); + void ensureConnected(); + int myxuihandle; + String querylist_id; +}; + +extern char QueryLineXuiObjectStr[]; +extern char QueryLineXuiSvcName[]; +class QueryLineXuiSvc : public XuiObjectSvc<ScriptQueryLine, QueryLineXuiObjectStr, QueryLineXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/db/xuiquerylist.cpp b/Src/Wasabi/api/skin/widgets/db/xuiquerylist.cpp new file mode 100644 index 00000000..b5ff10bd --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/db/xuiquerylist.cpp @@ -0,0 +1,119 @@ +#include <precomp.h> +#include "xuiquerylist.h" +#include <tataki/canvas/ifc_canvas.h> + +#include <api/service/svcs/svc_objectdir.h> + +// ----------------------------------------------------------------------- +char QueryListXuiObjectStr[] = "QueryResults"; // This is the xml tag +char QueryListXuiSvcName[] = "ScriptQueryResults xui object"; +XMLParamPair ScriptQueryList::params[] = { +{QUERYLIST_SETTITLE, "TITLE"}, +}; +// ----------------------------------------------------------------------- +ScriptQueryList::ScriptQueryList() { + getScriptObject()->vcpu_setInterface(queryListGuid, (void *)static_cast<ScriptQueryList *>(this)); +#ifdef WASABI_COMPILE_METADB + getScriptObject()->vcpu_setInterface(multiQueryServerGuid, (void *)static_cast<MultiQueryServer *>(this)); +#endif + getScriptObject()->vcpu_setClassName("QueryList"); // this is the script class name + getScriptObject()->vcpu_setController(queryListController); + + myxuihandle = newXuiHandle(); + + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +ScriptQueryList::~ScriptQueryList() { +} + +// ----------------------------------------------------------------------- +int ScriptQueryList::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return QUERYLIST_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) { + case QUERYLIST_SETTITLE: setTitle(value); break; + default: return 0; + } + return 1; +} + +// ----------------------------------------------------------------------- +void ScriptQueryList::setTitle(const char *name) { + setName(name); +//CUT if (!name || !*name) showLabel(0); else showLabel(1); +} + +#ifdef WASABI_COMPILE_METADB +// ----------------------------------------------------------------------- +void ScriptQueryList::onResetSubqueries() { + QUERYLIST_PARENT::onResetSubqueries(); + QueryListScriptController::querylist_onResetQuery(SCRIPT_CALL, getScriptObject()); +} +#endif + +#ifdef WASABI_COMPILE_METADB +int ScriptQueryList::onAction(const char *action, const char *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, api_window *source) { + if (STRCASEEQLSAFE(action, "SAVEQUERY")) { + String q = mqs_getMultiQuery(); + if (!q.isempty()) { + svc_objectDir *qd = ObjectDirEnum("querydir").getNext(); + if (qd != NULL) { + qd->insertObject(q, "gay", "user is gay"); + } + } + return 1; + } + return QUERYLIST_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source); +} +#endif + +// ----------------------------------------------------------------------- +// Script Object + +QueryListScriptController _queryListController; +QueryListScriptController *queryListController = &_queryListController; + +// -- Functions table ------------------------------------- +function_descriptor_struct QueryListScriptController::exportedFunction[] = { + {"onResetQuery", 0, (void*)QueryListScriptController::querylist_onResetQuery}, +}; + +ScriptObject *QueryListScriptController::instantiate() { + ScriptQueryList *sql = new ScriptQueryList; + ASSERT(sql != NULL); + return sql->getScriptObject(); +} + +void QueryListScriptController::destroy(ScriptObject *o) { + ScriptQueryList *sql = static_cast<ScriptQueryList *>(o->vcpu_getInterface(queryListGuid)); + ASSERT(sql != NULL); + delete sql; +} + +void *QueryListScriptController::encapsulate(ScriptObject *o) { + return NULL; // no encapsulation for querylist yet +} + +void QueryListScriptController::deencapsulate(void *o) { +} + +int QueryListScriptController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *QueryListScriptController::getExportedFunctions() { + return exportedFunction; +} + + +scriptVar QueryListScriptController::querylist_onResetQuery(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS0(o, queryListController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} diff --git a/Src/Wasabi/api/skin/widgets/db/xuiquerylist.h b/Src/Wasabi/api/skin/widgets/db/xuiquerylist.h new file mode 100644 index 00000000..a278afcb --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/db/xuiquerylist.h @@ -0,0 +1,72 @@ +#ifndef __QUERYLIST_H +#define __QUERYLIST_H + +#include <api/wnd/wndclass/guiobjwnd.h> +#ifdef WASABI_COMPILE_METADB +#include <api/skin/widgets/db/autoquerylist.h> +#endif +#include <api/script/objcontroller.h> + +#ifdef WASABI_COMPILE_METADB +#define QUERYLIST_PARENT AutoQueryList +#else +#define QUERYLIST_PARENT GuiObjectWnd +#endif + +// ----------------------------------------------------------------------- +class ScriptQueryList : public QUERYLIST_PARENT { + + public: + + ScriptQueryList(); + virtual ~ScriptQueryList(); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + void setTitle(const char *name); + +#ifdef WASABI_COMPILE_METADB + void onResetSubqueries(); + virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, api_window *source=NULL); +#endif + + private: + + enum { + QUERYLIST_SETTITLE = 0, + }; + static XMLParamPair params[]; + int myxuihandle; +}; + +// ----------------------------------------------------------------------- +class QueryListScriptController: public ScriptObjectControllerI { + public: + + virtual const wchar_t *getClassName() { return L"QueryList"; } + virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; } + virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); } + virtual int getNumFunctions(); + virtual const function_descriptor_struct *getExportedFunctions(); + virtual GUID getClassGuid() { return queryListGuid; } + virtual ScriptObject *instantiate(); + virtual void destroy(ScriptObject *o); + virtual void *encapsulate(ScriptObject *o); + virtual void deencapsulate(void *o); + + static scriptVar querylist_onResetQuery(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern QueryListScriptController *queryListController; + +// ----------------------------------------------------------------------- +extern char QueryListXuiObjectStr[]; +extern char QueryListXuiSvcName[]; +class QueryListXuiSvc : public XuiObjectSvc<ScriptQueryList, QueryListXuiObjectStr, QueryListXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/dropdownlist.cpp b/Src/Wasabi/api/skin/widgets/dropdownlist.cpp new file mode 100644 index 00000000..2a399550 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/dropdownlist.cpp @@ -0,0 +1,747 @@ +#include <precomp.h> +#include "dropdownlist.h" +#include <api/wnd/wndclass/listwnd.h> +#include <api/script/objects/guiobject.h> +#include <api/script/scriptguid.h> +#include <api/script/objects/c_script/c_text.h> +#include <api/wnd/popexitcb.h> +#include <api/wnd/notifmsg.h> +#include <api/service/svc_enum.h> +#include <bfc/parse/paramparser.h> +#include <api/service/svcs/svc_textfeed.h> + +#define DDL_CLOSELISTCB 0x0721 + +XMLParamPair DropDownList::params[] = +{ + {DROPDOWNLIST_SETFEED, L"FEED"}, + {DROPDOWNLIST_SETITEMS, L"ITEMS"}, + {DROPDOWNLIST_LISTHEIGHT, L"LISTHEIGHT"}, + {DROPDOWNLIST_MAXITEMS, L"MAXITEMS"}, + {DROPDOWNLIST_SELECT, L"SELECT"}, + {DROPDOWNLIST_SETLISTANTIALIAS, L"ANTIALIAS"}, +}; +// ----------------------------------------------------------------------- +DropDownList::DropDownList() { + selected = -1; + //abstract_setAllowDeferredContent(1); + clicks_button = NULL; + clicks_text = NULL; + list_key = NULL; + height = 128; + maxitems = 0; + noitemtext = L""; + list_group = NULL; + trap_click = 0; + disable_cfg_event = 0; + + GuiObjectWnd::getScriptObject()->vcpu_setInterface(dropDownListGuid, (void *)static_cast<DropDownList *>(this)); + GuiObjectWnd::getScriptObject()->vcpu_setClassName(L"DropDownList"); // this is the script class name + GuiObjectWnd::getScriptObject()->vcpu_setController(dropDownListController); + + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); + + registerAcceleratorSection(L"popup", 1); +} + +void DropDownList::CreateXMLParameters(int master_handle) +{ + //DROPDOWNLIST_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} +// ----------------------------------------------------------------------- +DropDownList::~DropDownList() { + doCloseList(0); + delete clicks_text; + delete clicks_button; + delete list_key; +} + +// ----------------------------------------------------------------------- +int DropDownList::onAcceleratorEvent(const wchar_t *name) { + int r = DROPDOWNLIST_PARENT::onAcceleratorEvent(name); + if (WCSCASEEQLSAFE(name, L"exit")) { + escapeCallback(); + return 1; + } + return r; +} + +// ----------------------------------------------------------------------- +int DropDownList::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return DROPDOWNLIST_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) { + case DROPDOWNLIST_SETITEMS: + setItems(value); + break; + case DROPDOWNLIST_SETFEED: + setFeed(value); + break; + case DROPDOWNLIST_SELECT: + selectItem(findItem(value)); + break; + case DROPDOWNLIST_LISTHEIGHT: + setListHeight(WTOI(value)); + break; + case DROPDOWNLIST_MAXITEMS: + setMaxItems(WTOI(value)); + break; + case DROPDOWNLIST_SETLISTANTIALIAS: + listAntialias = WTOI(value); + break; + default: + return 0; + } + return 1; +} + +// ----------------------------------------------------------------------- +int DropDownList::onInit() +{ + int rt = DROPDOWNLIST_PARENT::onInit(); + abstract_setContent(dropdownlist_getMainGroupId()); + return rt; +} + +// ----------------------------------------------------------------------- +void DropDownList::abstract_onNewContent() { + DROPDOWNLIST_PARENT::abstract_onNewContent(); + trapControls(); + updateTextInControl(getSelectedText()); +} + +#ifdef WASABI_COMPILE_CONFIG +// ----------------------------------------------------------------------- +int DropDownList::onReloadConfig() { + int r = DROPDOWNLIST_PARENT::onReloadConfig(); + disable_cfg_event = 1; + updateTextFromConfig(); // triggers onSelect + disable_cfg_event = 0; + return r; +} + +// ----------------------------------------------------------------------- +void DropDownList::updateTextFromConfig() { + const wchar_t *val = getGuiObject()->guiobject_getCfgString(); + const wchar_t *old = getSelectedText(); + if (old && val && !_wcsicmp(val, old)) return; + + if (val != NULL) { + int id = findItem(val); + if (id != -1) + selectItem(id); + } +} +#endif + +// ----------------------------------------------------------------------- +void DropDownList::trapControls() { + delete clicks_button; + delete clicks_text; + + clicks_button = NULL; + clicks_text = NULL; + + if (wantTrapText()) { + GuiObject *textGuiObj = getGuiObject()->guiobject_findObject(dropdownlist_getTextId()); + if (textGuiObj) clicks_text = new DDLClicksCallback(*textGuiObj, this); + } + + if (wantTrapButton()) { + GuiObject *butGuiObj = getGuiObject()->guiobject_findObject(dropdownlist_getButtonId()); + if (butGuiObj) clicks_button = new DDLClicksCallback(*butGuiObj, this); + } +} + + +// ----------------------------------------------------------------------- +void DropDownList::clickCallback() { + if (list_group != NULL) + closeList(); + else + openList(); +} + +// ----------------------------------------------------------------------- +void DropDownList::escapeCallback() { + if (isListOpen()) + closeList(); +} + +// ----------------------------------------------------------------------- +void DropDownList::openList() { + onPreOpenList(); + WASABI_API_WND->appdeactivation_push_disallow(this); +#ifdef WASABI_COMPILE_WNDMGR + list_group = WASABI_API_SKIN->group_create_layout(dropdownlist_getListGroupId()); +#else + list_group = WASABI_API_SKIN->group_create(dropdownlist_getListGroupId()); +#endif + group_dep = list_group->getDependencyPtr(); + viewer_addViewItem(group_dep); + if (list_group == NULL) return; + list_group->setStartHidden(1); + list_group->setParent(WASABI_API_WND->main_getRootWnd()); + trap_click = 0; + list_group->init(this, TRUE); + setListParams(); + + // At this point, the list should be good. Calc for max-items size + int calc_height = 0; + if (maxitems) { + ifc_window *listroot = list_group->findWindowByInterface(listGuid); + ListWnd *listwnd = static_cast<ListWnd *>(listroot->getInterface(guilistGuid)); + GuiObject *listobj = listroot->getGuiObject(); + if (listwnd) { + int numitems = 0; + if (maxitems == -1) { + numitems = listwnd->getNumItems(); + } else { + numitems = MIN(maxitems, listwnd->getNumItems()); + } + int offset_h = 0; + if (listobj) { + const wchar_t *y_param = listobj->guiobject_getXmlParam(L"y"); + const wchar_t *h_param = listobj->guiobject_getXmlParam(L"h"); + const wchar_t *ry_param = listobj->guiobject_getXmlParam(L"relaty"); + const wchar_t *rh_param = listobj->guiobject_getXmlParam(L"relath"); + int h_val = (h_param)?WTOI(h_param):0; + int y_val = (y_param)?WTOI(y_param):0; + if (ry_param && (wcscmp(ry_param, L"1") == 0)) { + if (y_val < 0) y_val = -y_val; + else y_val = 0; + } + if (rh_param && (wcscmp(rh_param, L"1") == 0)) { + if (h_val < 0) h_val = -h_val; + } + offset_h = h_val + y_val; + } + calc_height = (numitems * listwnd->getItemHeight()) + offset_h; + } + } else { + calc_height = height; + } + + RECT r; + getWindowRect(&r); + r.top = r.bottom; + r.bottom = r.top + calc_height; + divRatio(&r); + list_group->resize(r.left, r.top, r.right-r.left, r.bottom-r.top); + list_group->setVisible(1); + WASABI_API_WND->popupexit_register(this, list_group); // this will call us back whenever someone clicks outside us + trap_click = 1; + listif = list_group->findWindowByInterface(listGuid); + if (listif != NULL) + list_key = new DDLKeyCallback(listif->getGuiObject()->guiobject_getScriptObject(), this); + dropdownlist_onOpenList(); +} + +// ----------------------------------------------------------------------- +void DropDownList::dropdownlist_onOpenList() +{ +#ifdef _WIN32 + SetCapture(NULL); // NONPORTABLE, the goal is to cancel any capture some of our content guiobject might have so as to let the click down + slide in list transfer mouse capture +#else +#warning port me? +#endif + setFocus(); +} + +// ----------------------------------------------------------------------- +void DropDownList::dropdownlist_onCloseList() { +} + +// ----------------------------------------------------------------------- +void DropDownList::closeList() { + if (list_group != NULL) { + onPreCloseList(); + postDeferredCallback(DDL_CLOSELISTCB, 0); + } +} + +// ----------------------------------------------------------------------- +void DropDownList::doCloseList(int cb) { + if (cb) dropdownlist_onCloseList(); + if (list_group) { + trap_click = 0; + WASABI_API_WND->popupexit_deregister(this); + WASABI_API_SKIN->group_destroy(list_group); + list_group = NULL; + group_dep = NULL; + action_list = NULL; + delete list_key; + list_key = NULL; + WASABI_API_WND->appdeactivation_pop_disallow(this); + } +} + +// ----------------------------------------------------------------------- +void DropDownList::setListParams() { + ASSERT(list_group != NULL); + GuiObject *go = static_cast<GuiObject *>(list_group->getInterface(guiObjectGuid)); + if (go != NULL) { + dropdownlist_onConfigureList(go); + } +} + +// ----------------------------------------------------------------------- +void DropDownList::dropdownlist_onConfigureList(GuiObject *go) { + XmlObject *o = NULL; + if (go != NULL) { + GuiObject *list = go->guiobject_findObject(dropdownlist_getListId()); + if (list != NULL) { + action_list = list->guiobject_getRootWnd(); + o = static_cast<XmlObject *>(list->guiobject_getScriptObject()->vcpu_getInterface(xmlObjectGuid)); + } + } + StringW s; + foreach(items) + if (foreach_index > 0) + s += L";"; + s += items.getfor()->getText(); + endfor; + o->setXmlParam(L"multiselect", L"0"); + o->setXmlParam(L"hoverselect", L"1"); + o->setXmlParam(L"selectonupdown", L"0"); + o->setXmlParam(L"sort", StringPrintfW(L"%d", wantAutoSort())); + o->setXmlParam(L"items", s); + o->setXmlParam(L"antialias", listAntialias ? L"1" : L"0"); + if (selected != -1) + o->setXmlParam(L"select", getSelectedText()); +} + +// ----------------------------------------------------------------------- +int DropDownList::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) { + if (WCSCASEEQLSAFE(action, L"set_selection")) { + int p = findItem(param); + selectItem(p); + return p; + } + if (WCSCASEEQLSAFE(action, L"get_selection")) { + if (source) + sendAction(source, L"set_selection", getSelectedText()); + } + return DROPDOWNLIST_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source); +} + +// ----------------------------------------------------------------------- +int DropDownList::addItem(const wchar_t *text) { + DDLEntry *e = new DDLEntry(text); + items.setSorted(wantAutoSort()); + items.addItem(e); + return e->getId(); +} + +// ----------------------------------------------------------------------- +void DropDownList::selectDefault() { +#ifdef WASABI_COMPILE_CONFIG + onReloadConfig(); +#endif +} + +// ----------------------------------------------------------------------- +void DropDownList::delItem(int id) { + foreach(items) + if (items.getfor()->getId() == id) { + delete items.getfor(); + items.removeByPos(foreach_index); + break; + } + endfor; + if (list_group != NULL) + setListParams(); +} + +// ----------------------------------------------------------------------- +void DropDownList::selectItem(int id, int hover) { + //FG> DO NOT PUT THIS TEST BACK: if (selected == id) return; + selected = id; + onSelect(selected, hover); +} + +// ----------------------------------------------------------------------- +void DropDownList::onSelect(int id, int hover) { + updateTextInControl(getSelectedText()); + if (!disable_cfg_event && !hover) { +#ifdef WASABI_COMPILE_CONFIG + if (selected == -1) + getGuiObject()->guiobject_setCfgString(L""); + else + getGuiObject()->guiobject_setCfgString(getSelectedText()); +#endif + } + + // Let the script have the callback, too. + DropDownListScriptController::DropDownList_onSelect(SCRIPT_CALL, GuiObjectWnd::getScriptObject(), MAKE_SCRIPT_INT(id), MAKE_SCRIPT_INT(hover)); + +} + +// ----------------------------------------------------------------------- +const wchar_t *DropDownList::getItemText(int id) { + foreach(items) + if (items.getfor()->getId() == id) + return items.getfor()->getText(); + endfor; + return NULL; +} + +// ----------------------------------------------------------------------- +int DropDownList::findItem(const wchar_t *text) { + int pos=-1; + items.findItem(text, &pos); + if (pos < 0) return -1; + return items[pos]->getId(); +} + +// ----------------------------------------------------------------------- +void DropDownList::updateTextInControl(const wchar_t *txt) +{ + GuiObject *content = getContent(); + if (content != NULL) { + if (wantTrapText()) { + GuiObject *text = content->guiobject_findObject(dropdownlist_getTextId()); + if (text != NULL) { + C_Text t(*text); + t.setText(txt); + } + } + } +} + +// ----------------------------------------------------------------------- +void DropDownList::setNoItemText(const wchar_t *txt) +{ + noitemtext = txt; + if (selected == -1) + updateTextInControl(getSelectedText()); +} + +// ----------------------------------------------------------------------- +int DropDownList::popupexitcb_onExitPopup() { + closeList(); + return 1; +} + +// ----------------------------------------------------------------------- +int DropDownList::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2) { + if (msg == ChildNotify::LISTWND_ITEMSELCHANGED && param2 && trap_click) { + sendAction(action_list, L"get_selection"); + closeList(); + } + return DROPDOWNLIST_PARENT::childNotify(child, msg, param1, param2); +} + +// ----------------------------------------------------------------------- +int DropDownList::onDeferredCallback(intptr_t p1, intptr_t p2) { + if (p1 == DDL_CLOSELISTCB) + doCloseList(); + return DROPDOWNLIST_PARENT::onDeferredCallback(p1, p2); +} + +// ----------------------------------------------------------------------- +int DropDownList::viewer_onItemDeleted(ifc_dependent *item) { + if (item == group_dep) { + WASABI_API_WND->popupexit_deregister(this); + trap_click = 0; + list_group = NULL; + group_dep = NULL; + action_list = NULL; + } + return 1; +} + +// ----------------------------------------------------------------------- + +void DropDownList::feedwatcher_onSetFeed(svc_textFeed *svc) +{ + StringW a = getRootWndName(); + if (a.isempty()) + setName(svc->getFeedDescription(getFeedId())); +} + +void DropDownList::feedwatcher_onFeedChange(const wchar_t *data) +{ + setItems(data); +} + +// ----------------------------------------------------------------------- +void DropDownList::deleteAllItems() { + items.deleteAll(); + selected = -1; +} + +// ----------------------------------------------------------------------- +int DropDownList::onKeyDown(int keyCode) { +#ifdef _WIN32 + if (isListOpen()) { + switch (keyCode) { + case VK_ESCAPE: + closeList(); + break; + } + if (listif != NULL) { + listif->onKeyDown(keyCode); + } + } else { + switch (keyCode) { + case VK_SPACE: + case VK_RETURN: + openList(); + break; + } + } +#else +#warning port me +#endif + return DROPDOWNLIST_PARENT::onKeyDown(keyCode); +} + +// ----------------------------------------------------------------------- +int DropDownList::onKeyUp(int keyCode) { + if (isListOpen()) { + if (listif != NULL) { + listif->onKeyUp(keyCode); + return 1; + } + } + return DROPDOWNLIST_PARENT::onKeyDown(keyCode); +} + +// ----------------------------------------------------------------------- +void DropDownList::setItems(const wchar_t *value) { + deleteAllItems(); + ParamParser pp(value); + for (int i=0;i<pp.getNumItems();i++) { + addItem(pp.enumItem(i)); + } + selectDefault(); +} + +// ----------------------------------------------------------------------- + +int DDLEntry::id_gen=0; + + +// ----------------------------------------------------------------------- +// Script Object + +DropDownListScriptController _dropDownListController; +DropDownListScriptController *dropDownListController = &_dropDownListController; + +// -- Functions table ------------------------------------- +function_descriptor_struct DropDownListScriptController::exportedFunction[] = { + {L"getItemSelected", 0, (void*)DropDownListScriptController::DropDownList_getItemSelected}, + {L"onSelect", 2, (void*)DropDownListScriptController::DropDownList_onSelect}, + + {L"setListHeight", 1, (void*)DropDownListScriptController::DropDownList_setListHeight}, + {L"openList", 0, (void*)DropDownListScriptController::DropDownList_openList}, + {L"closeList", 0, (void*)DropDownListScriptController::DropDownList_closeList}, + {L"setItems", 1, (void*)DropDownListScriptController::DropDownList_setItems}, + {L"addItem", 1, (void*)DropDownListScriptController::DropDownList_addItem}, + {L"delItem", 1, (void*)DropDownListScriptController::DropDownList_delItem}, + {L"findItem", 1, (void*)DropDownListScriptController::DropDownList_findItem}, + {L"getNumItems", 0, (void*)DropDownListScriptController::DropDownList_getNumItems}, + {L"selectItem", 2, (void*)DropDownListScriptController::DropDownList_selectItem}, + {L"getItemText", 1, (void*)DropDownListScriptController::DropDownList_getItemText}, + {L"getSelected", 0, (void*)DropDownListScriptController::DropDownList_getSelected}, + {L"getSelectedText", 0, (void*)DropDownListScriptController::DropDownList_getSelectedText}, + {L"getCustomText", 0, (void*)DropDownListScriptController::DropDownList_getCustomText}, + {L"deleteAllItems", 0, (void*)DropDownListScriptController::DropDownList_deleteAllItems}, + {L"setNoItemText", 1, (void*)DropDownListScriptController::DropDownList_setNoItemText}, +}; + +ScriptObject *DropDownListScriptController::instantiate() { + DropDownList *ddl = new DropDownList; + ASSERT(ddl != NULL); + return ddl->GuiObjectWnd::getScriptObject(); +} + +void DropDownListScriptController::destroy(ScriptObject *o) { + DropDownList *ddl= static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + ASSERT(ddl != NULL); + delete ddl; +} + +void *DropDownListScriptController::encapsulate(ScriptObject *o) { + return NULL; // no encapsulation for DropDownlist yet +} + +void DropDownListScriptController::deencapsulate(void *o) { +} + +int DropDownListScriptController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *DropDownListScriptController::getExportedFunctions() { + return exportedFunction; +} + + +scriptVar DropDownListScriptController::DropDownList_getItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList*>(o->vcpu_getInterface(dropDownListGuid)); + const wchar_t *p=L""; + if (ddl) p = ddl->getSelectedText(); + + + return MAKE_SCRIPT_STRING(p); +} + +scriptVar DropDownListScriptController::DropDownList_onSelect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar id, scriptVar hover) { + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS2(o, dropDownListController, id, hover); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT2(o, id, hover); +} + +/*void*/ scriptVar DropDownListScriptController::DropDownList_setListHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar h) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + if (ddl) { + ddl->setListHeight(GET_SCRIPT_INT(h)); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar DropDownListScriptController::DropDownList_openList(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + if (ddl) { + ddl->openList(); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar DropDownListScriptController::DropDownList_closeList(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + if (ddl) { + ddl->closeList(); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar DropDownListScriptController::DropDownList_setItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar lotsofitems) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + if (ddl) { + ddl->setItems(GET_SCRIPT_STRING(lotsofitems)); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar DropDownListScriptController::DropDownList_addItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar text) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + int retval = 0; + if (ddl) + { + retval = ddl->addItem(GET_SCRIPT_STRING(text)); + } + return MAKE_SCRIPT_INT(retval); +} + +/*void*/ scriptVar DropDownListScriptController::DropDownList_delItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar id) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + if (ddl) { + ddl->delItem(GET_SCRIPT_INT(id)); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar DropDownListScriptController::DropDownList_findItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar text) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + int retval = 0; + if (ddl) { + retval = ddl->findItem(GET_SCRIPT_STRING(text)); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar DropDownListScriptController::DropDownList_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + int retval = 0; + if (ddl) { + retval = ddl->getNumItems(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*void*/ scriptVar DropDownListScriptController::DropDownList_selectItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar id, /*int*/ scriptVar hover) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + if (ddl) { + ddl->selectItem(GET_SCRIPT_INT(id), GET_SCRIPT_INT(hover)); + } + RETURN_SCRIPT_VOID; +} + +/*String*/ scriptVar DropDownListScriptController::DropDownList_getItemText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar id) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + const wchar_t *retval = L""; + if (ddl) { + retval = ddl->getItemText(GET_SCRIPT_INT(id)); + } + return MAKE_SCRIPT_STRING(retval); +} + +/*int*/ scriptVar DropDownListScriptController::DropDownList_getSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + int retval = 0; + if (ddl) { + retval = ddl->getSelected(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*String*/ scriptVar DropDownListScriptController::DropDownList_getSelectedText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + const wchar_t *retval = L""; + if (ddl) { + retval = ddl->getSelectedText(); + } + return MAKE_SCRIPT_STRING(retval); +} + +/*String*/ scriptVar DropDownListScriptController::DropDownList_getCustomText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + const wchar_t *retval=L""; + if (ddl) { + retval = ddl->getCustomText(); + } + return MAKE_SCRIPT_STRING(retval); +} + +/*void*/ scriptVar DropDownListScriptController::DropDownList_deleteAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + if (ddl) { + ddl->deleteAllItems(); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar DropDownListScriptController::DropDownList_setNoItemText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar txt) { + SCRIPT_FUNCTION_INIT + DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid)); + if (ddl) { + ddl->setNoItemText(GET_SCRIPT_STRING(txt)); + } + RETURN_SCRIPT_VOID; +} + diff --git a/Src/Wasabi/api/skin/widgets/dropdownlist.h b/Src/Wasabi/api/skin/widgets/dropdownlist.h new file mode 100644 index 00000000..0b3ef247 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/dropdownlist.h @@ -0,0 +1,531 @@ +#ifndef __DROPDOWNLIST_H +#define __DROPDOWNLIST_H + +#include <api/wnd/popexitcb.h> +#include <api/wnd/wndclass/embeddedxui.h> +#include <api/script/objects/c_script/h_guiobject.h> +#include <api/script/objects/c_script/h_button.h> +#include <api/skin/feeds/feedwatch.h> +#include <api/script/objcontroller.h> + +#define DROPDOWNLIST_PARENT EmbeddedXuiObject + +class DDLClicksCallback; +class DDLKeyCallback; +class svc_textFeed; + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class DDLEntry { + public: + + + /** + Method + + @see + @ret + @param + */ + DDLEntry(const wchar_t *txt) : text(txt), id(id_gen++) { } + const wchar_t *getText() { return text; } + + /** + Method + + @see + @ret + @param + */ + int getId() { return id; } + + private: + StringW text; + int id; + static int id_gen; +}; + + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class SortDDLEntries{ +public: + + static int compareItem(DDLEntry *p1, DDLEntry *p2) { + + return WCSICMP(p1->getText(), p2->getText()); + } + + static int compareAttrib(const wchar_t *attrib, DDLEntry *item) + { + return WCSICMP(attrib, item->getText()); + } +}; + + + + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class DropDownList : public DROPDOWNLIST_PARENT, public PopupExitCallbackI, public FeedWatcher, public DependentViewerI { + + public: + + + /** + Method + + @see + @ret + @param + */ + DropDownList(); + + /** + Method + + @see + @ret + @param + */ + virtual ~DropDownList(); + + + /** + Method + + @see + @ret + @param + */ + virtual int onInit(); + + + /** + Method + + @see + @ret + @param + */ + void clickCallback(); + void escapeCallback(); + + + /** + Method + + @see + @ret + @param + */ +#ifdef WASABI_COMPILE_CONFIG + virtual int onReloadConfig(); +#endif + + /** + Method + + @see + @ret + @param + */ + virtual void abstract_onNewContent(); + + /** + Method + + @see + @ret + @param + */ + virtual void setListHeight(int h) { height = h; } + + + /** + Method + + @see + @ret + @param + */ + virtual int popupexitcb_onExitPopup(); + virtual api_dependent *popupexit_getDependencyPtr() { return rootwnd_getDependencyPtr(); } + + /** + Method + + @see + @ret + @param + */ + void openList(); + + /** + Method + + @see + @ret + @param + */ + void closeList(); + + + void setItems(const wchar_t *lotsofitems); + + int addItem(const wchar_t *text); + + /** + Method + + @see + @ret + @param + */ + void delItem(int id); + + + int findItem(const wchar_t *text); + + int getNumItems() { return items.getNumItems(); } + DDLEntry *enumItem(int i) { return items.enumItem(i); } + + /** + Method + + @see + @ret + @param + */ + void selectItem(int id, int hover=0); + const wchar_t *getItemText(int id); + + int getSelected() { return selected; } + const wchar_t *getSelectedText() { int a = getSelected(); if (a == -1) return getCustomText(); return getItemText(a); } + virtual const wchar_t *getCustomText() { return noitemtext; } + + /** + Method + + @see + @ret + @param + */ + virtual void deleteAllItems(); + + + /** + Method + + @see + @ret + @param + */ + virtual void onSelect(int id, int hover=0); + + virtual void setNoItemText(const wchar_t *txt); + + + /** + Method + + @see + @ret + @param + */ + virtual int childNotify(ifc_window *child, int msg, intptr_t param1=0, intptr_t param2=0); + + /** + Method + + @see + @ret + @param + */ + virtual int onDeferredCallback(intptr_t p1, intptr_t p2); + + + /** + Method + + @see + @ret + @param + */ + virtual int viewer_onItemDeleted(api_dependent *item); + + virtual void feedwatcher_onSetFeed(svc_textFeed *svc); + virtual void feedwatcher_onFeedChange(const wchar_t *data); + + virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, ifc_window *source=NULL); + + + /** + Method + + @see + @ret + @param + */ + virtual void selectDefault(); + + virtual void setMaxItems(int _maxitems) { maxitems = _maxitems; } + virtual int getMaxItems() { return maxitems; } + + virtual int wantTrapButton() { return 1; } + virtual int wantTrapText() { return 1; } + virtual int wantFocus() { return 1; } + + virtual const wchar_t *dropdownlist_getMainGroupId() { return L"wasabi.dropdownlist.main.group"; } + virtual const wchar_t *dropdownlist_getListGroupId() { return L"wasabi.dropdownlist.list.group"; } + virtual const wchar_t *dropdownlist_getTextId() { return L"dropdownlist.text"; } + virtual const wchar_t *dropdownlist_getButtonId() { return L"dropdownlist.button"; } + virtual const wchar_t *dropdownlist_getListId() { return L"dropdownlist.list"; } + + virtual void updateTextInControl(const wchar_t *txt); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + virtual const wchar_t *embeddedxui_getContentId() { return dropdownlist_getMainGroupId(); } + virtual const wchar_t *embeddedxui_getEmbeddedObjectId() { return dropdownlist_getTextId(); } + + int isListOpen() { return list_group != NULL; }; + virtual int wantAutoSort() { return 1; } + + virtual void dropdownlist_onCloseList(); + virtual void dropdownlist_onOpenList(); + + virtual void dropdownlist_onConfigureList(GuiObject *o); + virtual int onKeyDown(int keyCode); + virtual int onKeyUp(int keyCode); + virtual int onAcceleratorEvent(const wchar_t *name); + + virtual void onPreCloseList() {} + virtual void onPreOpenList() {} +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + + enum { + DROPDOWNLIST_SETITEMS = 0, + DROPDOWNLIST_SETFEED, + DROPDOWNLIST_SELECT, + DROPDOWNLIST_LISTHEIGHT, + DROPDOWNLIST_MAXITEMS, + DROPDOWNLIST_SETLISTANTIALIAS, + }; + int myxuihandle; + static XMLParamPair params[]; + + private: + +#ifdef WASABI_COMPILE_CONFIG + void updateTextFromConfig(); +#endif + + /** + Method + + @see + @ret + @param + */ + void trapControls(); + + /** + Method + + @see + @ret + @param + */ + void setListParams(); + + /** + Method + + @see + @ret + @param + */ + void doCloseList(int cb=1); + + DDLClicksCallback *clicks_button; + DDLClicksCallback *clicks_text; + DDLKeyCallback *list_key; + ifc_window *list_group; + PtrListInsertSorted<DDLEntry, SortDDLEntries> items; + int selected; + + int height; + int maxitems; + StringW noitemtext; + int trap_click; + api_dependent *group_dep; + ifc_window *action_list; + int disable_cfg_event; + ifc_window *listif; + int listAntialias; +}; + + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class DDLClicksCallback : public H_GuiObject { + public: + + /** + Method + + @see + @ret + @param + */ + DDLClicksCallback(ScriptObject *trap, DropDownList *_callback) : + + /** + Method + + @see + @ret + @param + */ + callback(_callback), H_GuiObject(trap) { + } + + + /** + Method + + @see + @ret + @param + */ + virtual void hook_onLeftButtonDown(int x, int y) { + callback->clickCallback(); + } + virtual void hook_onChar(wchar_t c) + { +#ifdef _WIN32 + if (c == VK_SPACE || c == VK_RETURN) + callback->clickCallback(); +#else +#warning port me +#endif + } + private: + DropDownList *callback; +}; + +class DDLKeyCallback : public H_GuiObject { + public: + + /** + Method + + @see + @ret + @param + */ + DDLKeyCallback(ScriptObject *trap, DropDownList *_callback) : + + /** + Method + + @see + @ret + @param + */ + callback(_callback), H_GuiObject(trap) { + } + + + /** + Method + + @see + @ret + @param + */ + + virtual void hook_onChar(wchar_t c) + { +#ifdef _WIN32 + if (c == VK_ESCAPE) + callback->escapeCallback(); +#else +#warning port me +#endif + } + private: + DropDownList *callback; +}; + +// ----------------------------------------------------------------------- +class DropDownListScriptController: public ScriptObjectControllerI { +public: + virtual const wchar_t *getClassName() { return L"DropDownList"; } + virtual const wchar_t *getAncestorClassName() { return L"ObjectEmbedder"; } + virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(embeddedXuiGuid); } + virtual int getNumFunctions(); + virtual const function_descriptor_struct *getExportedFunctions(); + virtual GUID getClassGuid() { return dropDownListGuid; } + virtual ScriptObject *instantiate(); + virtual void destroy(ScriptObject *o); + virtual void *encapsulate(ScriptObject *o); + virtual void deencapsulate(void *o); + + // public cause it's called by the xui object. + static scriptVar DropDownList_onSelect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar id, scriptVar hover); + +private: + + static function_descriptor_struct exportedFunction[]; + static scriptVar DropDownList_getItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + + static /*void*/ scriptVar DropDownList_setListHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar h); + static /*void*/ scriptVar DropDownList_openList(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar DropDownList_closeList(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar DropDownList_setItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar lotsofitems); + static /*int*/ scriptVar DropDownList_addItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar text); + static /*void*/ scriptVar DropDownList_delItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar id); + static /*int*/ scriptVar DropDownList_findItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar text); + static /*int*/ scriptVar DropDownList_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar DropDownList_selectItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar id, /*int*/ scriptVar hover); + static /*String*/ scriptVar DropDownList_getItemText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar id); + static /*int*/ scriptVar DropDownList_getSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*String*/ scriptVar DropDownList_getSelectedText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*String*/ scriptVar DropDownList_getCustomText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar DropDownList_deleteAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar DropDownList_setNoItemText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar txt); + + +}; + +extern COMEXP DropDownListScriptController *dropDownListController; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/edit.cpp b/Src/Wasabi/api/skin/widgets/edit.cpp new file mode 100644 index 00000000..b7b9fe7c --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/edit.cpp @@ -0,0 +1,312 @@ +#include <precomp.h> +#include <bfc/wasabi_std.h> +#include <api/skin/skinparse.h> +#include "edit.h" +#include <api/script/scriptmgr.h> +#include <api/skin/widgets/mb/xuibrowser.h> +#include <api/skin/widgets/mb/mainminibrowser.h> + +#define BUFSIZE 0x7ffe + +const wchar_t editXuiObjectStr[] = L"Edit"; // This is the xml tag +char editXuiSvcName[] = "Edit xui object"; // this is the name of the xuiservice + + +EditScriptController _editController; +EditScriptController *editController = &_editController; + +// -- Functions table ------------------------------------- +function_descriptor_struct EditScriptController::exportedFunction[] = { + {L"setText", 1, (void*)Edit::script_vcpu_setText }, + {L"setAutoEnter", 1, (void*)Edit::script_vcpu_setAutoEnter }, + {L"getAutoEnter", 0, (void*)Edit::script_vcpu_getAutoEnter }, + {L"getText", 0, (void*)Edit::script_vcpu_getText }, + {L"onEnter", 0, (void*)Edit::script_vcpu_onEnter }, + {L"onAbort", 0, (void*)Edit::script_vcpu_onAbort }, + {L"onIdleEditUpdate", 0, (void*)Edit::script_vcpu_onIdleEditUpdate }, + {L"onEditUpdate", 0, (void*)Edit::script_vcpu_onEditUpdate }, + {L"selectAll", 0, (void*)Edit::script_vcpu_selectAll }, + {L"enter", 0, (void*)Edit::script_vcpu_enter }, + {L"setIdleEnabled", 1, (void*)Edit::script_vcpu_setIdleEnabled}, + {L"getIdleEnabled", 0, (void*)Edit::script_vcpu_getIdleEnabled}, + }; +// -------------------------------------------------------- + +const wchar_t *EditScriptController::getClassName() +{ + return L"Edit"; +} + +const wchar_t *EditScriptController::getAncestorClassName() +{ + return L"GuiObject"; +} + +ScriptObject *EditScriptController::instantiate() +{ + Edit *e = new Edit; + ASSERT(e != NULL); + return e->getScriptObject(); +} + +void EditScriptController::destroy(ScriptObject *o) +{ + Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid)); + ASSERT(e != NULL); + delete e; +} + +void *EditScriptController::encapsulate(ScriptObject *o) +{ + return NULL; // no encapsulation for edit yet +} + +void EditScriptController::deencapsulate(void *o) +{} + +int EditScriptController::getNumFunctions() +{ + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *EditScriptController::getExportedFunctions() +{ + return exportedFunction; +} + +GUID EditScriptController::getClassGuid() +{ + return editGuid; +} + +// ----------------------------------------------------------------------------- + +XMLParamPair Edit::params[] = { + {EDIT_ACTION, L"ACTION"}, + {EDIT_AUTOENTER, L"AUTOENTER"}, + {EDIT_AUTOHSCROLL, L"AUTOHSCROLL"}, + {EDIT_AUTOSELECT, L"AUTOSELECT"}, + {EDIT_MULTILINE, L"MULTILINE"}, + {EDIT_PASSWORD, L"PASSWORD"}, + {EDIT_TEXT, L"TEXT"}, + {EDIT_VSCROLL, L"VSCROLL"}, + }; +Edit::Edit() +{ + getScriptObject()->vcpu_setInterface(editGuid, (void *)static_cast<Edit *>(this)); + getScriptObject()->vcpu_setClassName(L"Edit"); + getScriptObject()->vcpu_setController(editController); + my_buffer = WMALLOC(BUFSIZE); + *my_buffer = 0; + autourl = 0; + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); +} + +void Edit::CreateXMLParameters(int master_handle) +{ + //EDIT_PARENT::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); +} + +Edit::~Edit() +{ + FREE(my_buffer); +} + +int Edit::setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value) +{ + if (xuihandle == _xuihandle) + { + switch (xmlattrid) + { + case EDIT_TEXT: setText(value); return 1; + case EDIT_ACTION: if (SkinParser::getAction(value) == ACTION_MB_URL) setAutoUrl(1); return 1; + case EDIT_MULTILINE: setMultiline(WTOI(value)); return 1; + case EDIT_VSCROLL: setVScroll(WTOI(value)); return 1; + case EDIT_AUTOHSCROLL: setAutoHScroll(WTOI(value)); return 1; + case EDIT_AUTOENTER: setAutoEnter(WTOI(value)); return 1; + case EDIT_PASSWORD: setPassword(WTOI(value)); return 1; + case EDIT_AUTOSELECT: setAutoSelect(WTOI(value)); return 1; + } + } + return EDIT_PARENT::setXuiParam(_xuihandle, xmlattrid, name, value); +} + +int Edit::onInit() +{ + int r = EDIT_PARENT::onInit(); + setBuffer(my_buffer, BUFSIZE - 1); + my_buffer[BUFSIZE - 1] = 0; + return r; +} + +void Edit::onEditUpdate() +{ + EDIT_PARENT::onEditUpdate(); + script_vcpu_onEditUpdate(SCRIPT_CALL, getScriptObject()); +} + +void Edit::onIdleEditUpdate() +{ + EDIT_PARENT::onIdleEditUpdate(); + script_vcpu_onIdleEditUpdate(SCRIPT_CALL, getScriptObject()); +} + +int Edit::onEnter() +{ + if (autourl) + { + MainMiniBrowser::navigateUrl(my_buffer); + } +#ifdef WASABI_COMPILE_CONFIG + getGuiObject()->guiobject_setCfgString(my_buffer); +#endif + int r = EDIT_PARENT::onEnter(); +#ifdef WASABI_COMPILE_CONFIG + script_vcpu_onEnter(SCRIPT_CALL, getScriptObject()); +#endif + return r; +} + +#ifdef WASABI_COMPILE_CONFIG +int Edit::onReloadConfig() +{ + EDIT_PARENT::onReloadConfig(); + setText(getGuiObject()->guiobject_getCfgString()); + return 1; +} +#endif + +int Edit::onAbort() +{ + if (autourl) + { + ScriptObject *so = MainMiniBrowser::getScriptObject(); + if (so) + { + ScriptBrowserWnd *sbw = static_cast<ScriptBrowserWnd *>(so->vcpu_getInterface(browserGuid)); + if (sbw) + setText(sbw->getCurrentUrl()); + } + } + int r = EDIT_PARENT::onAbort(); + script_vcpu_onAbort(SCRIPT_CALL, getScriptObject()); + return r; +} + +void Edit::setText(const wchar_t *t) +{ + wcsncpy(my_buffer, t, BUFSIZE - 1); + setBuffer(my_buffer, BUFSIZE - 1); + my_buffer[BUFSIZE - 1] = 0; +} + +void Edit::setAutoUrl(int a) +{ + autourl = a; +} + +// ----------------------------------------------------------------------------- + +scriptVar Edit::script_vcpu_setText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t) +{ + SCRIPT_FUNCTION_INIT + ASSERT(t.type == SCRIPT_STRING); + Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid)); + if (e) e->setText(t.data.sdata); + RETURN_SCRIPT_VOID; +} + +scriptVar Edit::script_vcpu_setAutoEnter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t) +{ + SCRIPT_FUNCTION_INIT + Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid)); + if (e) e->setAutoEnter(t.data.idata); + RETURN_SCRIPT_VOID; +} + +scriptVar Edit::script_vcpu_getAutoEnter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + int a = 0; + Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid)); + if (e) a = e->getAutoEnter(); + return MAKE_SCRIPT_INT(a); +} + +scriptVar Edit::script_vcpu_setIdleEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t) +{ + SCRIPT_FUNCTION_INIT + Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid)); + if (e) e->setIdleEnabled(t.data.idata); + RETURN_SCRIPT_VOID; +} + +scriptVar Edit::script_vcpu_getIdleEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + int a = 0; + Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid)); + if (e) a = e->getIdleEnabled(); + return MAKE_SCRIPT_INT(a); +} + +scriptVar Edit::script_vcpu_getText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid)); + if (e) return MAKE_SCRIPT_STRING(e->getBufferPtr()); + return MAKE_SCRIPT_STRING(L""); +} + +scriptVar Edit::script_vcpu_selectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid)); + if (e) e->selectAll(); + RETURN_SCRIPT_VOID; +} + +scriptVar Edit::script_vcpu_enter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid)); + if (e) e->enter(); + RETURN_SCRIPT_VOID; +} + +scriptVar Edit::script_vcpu_onEnter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS0(o, editController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +scriptVar Edit::script_vcpu_onIdleEditUpdate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS0(o, editController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +scriptVar Edit::script_vcpu_onEditUpdate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS0(o, editController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +scriptVar Edit::script_vcpu_onAbort(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS0(o, editController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/edit.h b/Src/Wasabi/api/skin/widgets/edit.h new file mode 100644 index 00000000..82b81776 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/edit.h @@ -0,0 +1,100 @@ +#ifndef __EDIT_H +#define __EDIT_H + +#include <api/script/script.h> +#include <api/script/objects/guiobj.h> + +#define EDIT_PARENT EditWnd + +class EditScriptController : public GuiObjectScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + 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); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern EditScriptController *editController; + +#ifndef _NOSTUDIO + +#include <api/wnd/wndclass/editwnd.h> + +class Edit : public EDIT_PARENT { +public: + Edit(); + ~Edit(); + + virtual void onEditUpdate(); + virtual void onIdleEditUpdate(); + virtual int onEnter(); // user hit enter.. return 1 to close window + virtual int onAbort(); // user hit escape.. return 1 to close window + virtual int onInit(); +#ifdef WASABI_COMPILE_CONFIG + virtual int onReloadConfig(); +#endif + + virtual int setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value); + + void setText(const wchar_t *t); + void setAutoUrl(int a); + +protected: + /*static */void CreateXMLParameters(int master_handle); +private: + wchar_t *my_buffer; + int autourl; + int xuihandle; + +#else +class Edit : public EDIT_SCRIPTPARENT { +#endif + +public: + + static scriptVar script_vcpu_setText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t); + static scriptVar script_vcpu_setAutoEnter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t); + static scriptVar script_vcpu_getAutoEnter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_setIdleEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t); + static scriptVar script_vcpu_getIdleEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_getText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_onEnter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_onAbort(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_onEditUpdate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_onIdleEditUpdate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_selectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_enter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + +protected: + enum { + EDIT_TEXT=0, + EDIT_ACTION, + EDIT_MULTILINE, + EDIT_VSCROLL, + EDIT_AUTOHSCROLL, + EDIT_AUTOENTER, + EDIT_PASSWORD, + EDIT_AUTOSELECT, +}; +private: + static XMLParamPair params[]; +}; + +extern const wchar_t editXuiObjectStr[]; +extern char editXuiSvcName[]; +class EditXuiSvc : public XuiObjectSvc<Edit, editXuiObjectStr, editXuiSvcName> {}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/fx.h b/Src/Wasabi/api/skin/widgets/fx.h new file mode 100644 index 00000000..7c8d318e --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/fx.h @@ -0,0 +1,12 @@ +#ifndef __FX_H +#define __FX_H + +class Layer; + +class Fx { + public: + virtual int render(Layer *l, int _w, int _h, int *input, int tw, int th, int twpitch)=0; +}; + + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/fx_dmove.cpp b/Src/Wasabi/api/skin/widgets/fx_dmove.cpp new file mode 100644 index 00000000..cb492260 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/fx_dmove.cpp @@ -0,0 +1,409 @@ +#include <precomp.h> + +#include <tataki/blending/blending.h> +#include "fx_dmove.h" + +#include <api/skin/widgets/layer.h> +#include <math.h> + +#define M_PI 3.14159265358979323846 + + +FxDynamicMove::FxDynamicMove() +: fx_canvas(4,4) +{ + need_flush=false; + cache_w=cache_h=4; + m_wmul=0; + m_tab=0; + last_m_tab=0; + m_lastxres=m_lastyres=m_lastpitch=0; + m_xres=16; + m_yres=16; + last_w=last_h=-1; + inited=0; + subpixel=1; + rectcoords=0; + blend=0; + wrap=0; + need_alpha = 1; + alpha_table = (double *)MALLOC((m_xres+1)*(m_yres+1)*sizeof(double)); + alpha_once= 0; + can_cache = 1; + m_lastw = 0; + m_lasth = 0; + m_tab_size = 0; +} + +FxDynamicMove::~FxDynamicMove() +{ + FREE(m_wmul); + FREE(m_tab); + FREE(last_m_tab); + FREE(alpha_table); +} + +int FxDynamicMove::render(Layer *l, int _w, int _h, int *input, int tw, int th, int twpitch) +{ + double var_x; + double var_y; + double var_d; + double var_r; + + +/*if (fx_canvas) { + HDC dc; + dc = GetDC(NULL); + BitBlt(dc, 0, 0, w, h, fx_canvas->getHDC(),0, 0, SRCCOPY); + ReleaseDC(NULL, dc); + }*/ + + prepareCanvas(_w, _h); + + int w_adj=(tw-2)<<16; + int h_adj=(th-2)<<16; + int dowrap=wrap; + int XRES=m_xres+1; + int YRES=m_yres+1; + int ignore_last_compare=0; + + if (XRES > _w) XRES=_w; + if (YRES > _h) YRES=_h; + if (XRES < 2) XRES=2; + if (XRES > 256) XRES=256; + if (YRES < 2) YRES=2; + if (YRES > 256) YRES=256; + if (need_flush || m_lasth != th || m_lastpitch != twpitch || m_lastw != tw || !m_tab || !m_wmul || m_lastxres != XRES || m_lastyres != YRES) + { + int y; + m_lastxres = XRES; + m_lastyres = YRES; + m_lastw=tw; + m_lasth=th; + m_lastpitch=twpitch; + FREE(m_wmul); + m_wmul=(int*)MALLOC(sizeof(int)*th); + for (y = 0; y < th; y ++) m_wmul[y]=y*twpitch; + FREE(m_tab); + FREE(last_m_tab); + m_tab_size = (XRES*YRES*3 + XRES*6 + 6)*sizeof(int); + m_tab=(int*)MALLOC(m_tab_size); + last_m_tab=(int*)MALLOC(m_tab_size); + ignore_last_compare=1; + } + need_flush=false; + int isblend=blend; + + int issub=subpixel; + if (!issub) + { + w_adj=(tw-1)<<16; + h_adj=(th-1)<<16; + } + if (w_adj<0) w_adj=0; + if (h_adj<0) h_adj=0; + + { + int x; + int y; + int *tabptr=m_tab; + + double xsc=2.0/tw,ysc=2.0/th; + double dw2=((double)tw*32768.0); + double dh2=((double)th*32768.0); + double max_screen_d=sqrt((double)(tw*tw+th*th))*0.5; + + double divmax_d=1.0/max_screen_d; + + max_screen_d *= 65536.0; + + double _var_alpha = 0.50; + int yc_pos, yc_dpos, xc_pos, xc_dpos; + yc_pos=0; + xc_dpos = (tw<<16)/(XRES-1); + yc_dpos = (th<<16)/(YRES-1); + for (y = 0; y < YRES; y ++) + { + xc_pos=0; + for (x = 0; x < XRES; x ++) + { + double xd,yd; + + xd=((double)xc_pos-dw2)*(1.0/65536.0); + yd=((double)yc_pos-dh2)*(1.0/65536.0); + + xc_pos+=xc_dpos; + + var_x=xd*xsc; + var_y=yd*ysc; + var_d=sqrt(xd*xd+yd*yd)*divmax_d; + var_r=atan2(yd,xd) + M_PI*0.5; + + double _var_r=var_r, _var_d=var_d; + if (isblend && need_alpha) { + _var_alpha = l->fx_onGetPixelA(var_r, var_d, var_x, var_y); + alpha_table[y*YRES+x] = _var_alpha; + } else if (isblend && !need_alpha) { + _var_alpha = alpha_table[y*YRES+x]; + } + if (!rectcoords) { + double t_var_r = l->fx_onGetPixelR(var_r, var_d, var_x, var_y); + _var_d = l->fx_onGetPixelD(var_r, var_d, var_x, var_y); + _var_r = t_var_r; + } + double _var_x=var_x, _var_y=var_y; + if (rectcoords) { + double t_var_x = l->fx_onGetPixelX(var_r, var_d, var_x, var_y); + _var_y = l->fx_onGetPixelY(var_r, var_d, var_x, var_y); + _var_x = t_var_x; + } + + int tmp1,tmp2,tmp3; + if (!rectcoords) + { + _var_d *= max_screen_d; + _var_r -= M_PI*0.5; + tmp1=(int) (dw2 + cos(_var_r) * _var_d); + tmp2=(int) (dh2 + sin(_var_r) * _var_d); + } + else + { + tmp1=(int) ((_var_x+1.0)*dw2); + tmp2=(int) ((_var_y+1.0)*dh2); + } + if (!dowrap) + { + if (tmp1 < 0) tmp1=0; + if (tmp1 > w_adj) tmp1=w_adj; + if (tmp2 < 0) tmp2=0; + if (tmp2 > h_adj) tmp2=h_adj; + } + *tabptr++ = tmp1; + *tabptr++ = tmp2; + tmp3 = (int)(_var_alpha*65536.0*256.0); + if (tmp3 < 0) tmp3=0; + if (tmp3 > 0xff0000) tmp3=0xff0000; + *tabptr++=tmp3; + } + yc_pos+=yc_dpos; + } + if (alpha_once) + need_alpha=0; + } + + if (can_cache && !ignore_last_compare && !MEMCMP(m_tab, last_m_tab, m_tab_size)) { + // cached, do nothing + // DebugString("cache hit!\n"); + } else { + MEMCPY(last_m_tab, m_tab, m_tab_size); + + // yay, the table is generated. now we do a fixed point + // interpolation of the whole thing and pray. + { + int *interptab=m_tab+XRES*YRES*3; + int *rdtab=m_tab; + unsigned int *in=(unsigned int *)input; + unsigned int *blendin=(unsigned int *)input; + unsigned int *out=(unsigned int *)fx_canvas.getBits(); + int yseek=1; + int xc_dpos, yc_pos=0, yc_dpos; + xc_dpos=(tw<<16)/(XRES-1); + yc_dpos=(th<<16)/(YRES-1); + int lypos=0; + int yl=_h; + while (yl>0) + { + yc_pos+=yc_dpos; + yseek=(yc_pos>>16)-lypos; + if (!yseek) return 0; + lypos=yc_pos>>16; + int l=XRES; + int *stab=interptab; + int xr3=XRES*3; + while (l--) + { + int tmp1, tmp2,tmp3; + tmp1=rdtab[0]; + tmp2=rdtab[1]; + tmp3=rdtab[2]; + stab[0]=tmp1; + stab[1]=tmp2; + stab[2]=(rdtab[xr3]-tmp1)/yseek; + stab[3]=(rdtab[xr3+1]-tmp2)/yseek; + stab[4]=tmp3; + stab[5]=(rdtab[xr3+2]-tmp3)/yseek; + rdtab+=3; + stab+=6; + } + + if (yseek > yl) yseek=yl; + yl-=yseek; + + if (yseek > 0) while (yseek--) + { + int d_x; + int d_y; + int d_a; + int ap; + int seek; + int *seektab=interptab; + int xp,yp; + int l=_w; + int lpos=0; + int xc_pos=0; + while (l>0) + { + xc_pos+=xc_dpos; + seek=(xc_pos>>16)-lpos; + if (!seek) + { + #ifndef NO_MMX + Blenders::BLEND_MMX_END(); + #endif + return 0; + } + lpos=xc_pos>>16; + xp=seektab[0]; + yp=seektab[1]; + ap=seektab[4]; + d_a=(seektab[10]-ap)/(seek); + d_x=(seektab[6]-xp)/(seek); + d_y=(seektab[7]-yp)/(seek); + seektab[0] += seektab[2]; + seektab[1] += seektab[3]; + seektab[4] += seektab[5]; + seektab+=6; + + if (seek>l) seek=l; + l-=seek; + if (seek>0) + { + // normal loop + #define NORMAL_LOOP(Z) while (seek--) { Z; xp+=d_x; yp+=d_y; } + + // wrapping loop + #define WRAPPING_LOOPS(Z) \ + if (d_x <= 0 && d_y <= 0) NORMAL_LOOP(if (xp < 0) xp += w_adj; if (yp < 0) yp += h_adj; Z) \ + else if (d_x <= 0) NORMAL_LOOP(if (xp < 0) xp += w_adj; if (yp >= h_adj) yp-=h_adj; Z) \ + else if (d_y <= 0) NORMAL_LOOP(if (xp >= w_adj) xp-=w_adj; if (yp < 0) yp += h_adj; Z) \ + else NORMAL_LOOP(if (xp >= w_adj) xp-=w_adj; if (yp >= h_adj) yp-=h_adj; Z) + + + // this is uber gay. J1, D4, L or J1_MMX, D4_MMX, L_MMX + #define LOOPS(DO,J1,D4,L) \ + if ((isblend&2) && issub) DO(*out++=Blenders::BLEND_AD##J1(Blenders::BLEN##D4(in+(xp>>16)+m_wmul[yp>>16],twpitch,xp,yp),*blendin++,ap>>16); ap+=d_a) \ + else if (isblend&2) DO(*out++=Blenders::BLEND_AD##J1(in[(xp>>16)+m_wmul[yp>>16]],*blendin++,ap>>16); ap+=d_a) \ + else if (isblend && issub) DO(*out++=Blenders::BLEND_MU##L(Blenders::BLEN##D4(in+(xp>>16)+m_wmul[yp>>16],twpitch,xp,yp),ap>>16); ap+=d_a) \ + else if (isblend) DO(*out++=Blenders::BLEND_MU##L(in[(xp>>16)+m_wmul[yp>>16]],ap>>16); ap+=d_a) \ + else if (issub) DO(*out++=Blenders::BLEN##D4(in+(xp>>16)+m_wmul[yp>>16],twpitch,xp,yp)) \ + else DO(*out++=in[(xp>>16)+m_wmul[yp>>16]]) + + if (!dowrap) + { + #ifndef NO_MMX + if (Blenders::MMX_AVAILABLE()) + { + LOOPS(NORMAL_LOOP,J1_MMX,D4_MMX,L_MMX) + } + else + #endif + { + LOOPS(NORMAL_LOOP,J1,D4,L) + } + } + else // dowrap + { + xp %= w_adj+1; yp %= h_adj+1; + if (xp < 0) xp+=w_adj; if (yp < 0) yp+=h_adj; + + if (d_x < -w_adj || d_x > w_adj) d_x=0; if (d_y < -h_adj || d_y > h_adj) d_y=0; + + #ifndef NO_MMX + if (Blenders::MMX_AVAILABLE()) + { + LOOPS(WRAPPING_LOOPS,J1_MMX,D4_MMX,L_MMX) + } + else + #endif + { + LOOPS(WRAPPING_LOOPS,J1,D4,L) + } + } + } + } + blendin+=twpitch-_w; + + // adjust final (rightmost elem) part of seektab + seektab[0] += seektab[2]; + seektab[1] += seektab[3]; + seektab[4] += seektab[5]; + } + } + } + } + +/*HDC dc = GetDC(NULL); +BitBlt(dc, 0, 0, w, h, fx_canvas->getHDC(),0, 0, SRCCOPY); +ReleaseDC(NULL, dc);*/ + + #ifndef NO_MMX + Blenders::BLEND_MMX_END(); + #endif + return 0; +}; + +void FxDynamicMove::setWrap(int i) { + wrap = i; +} + +void FxDynamicMove::setRect(int i) { + rectcoords = i; + +} +void FxDynamicMove::setBilinear(int i) { + subpixel = i; +} + +void FxDynamicMove::setAlphaMode(int i) { + blend = i; +} + +void FxDynamicMove::setAlphaOnce(int i) { + alpha_once = i; +} + +void FxDynamicMove::setGridSize(int x, int y) { + m_xres = x; + m_yres = y; + FREE(alpha_table); + alpha_table = (double *)MALLOC((x+1)*(y+1)*sizeof(double)); + need_alpha = 1; +} + +BltCanvas *FxDynamicMove::getBltCanvas() +{ + return &fx_canvas; +} + +void FxDynamicMove::prepareCanvas(int w, int h) { + if (w != last_w || h != last_h) + { + if (cache_w < w || cache_h < h) + { + cache_w = max(cache_w, w); + cache_h = max(cache_h, h); + fx_canvas.DestructiveResize(cache_w, cache_h, 32); + } + last_w = w; + last_h = h; + } +} + +void FxDynamicMove::setCanCache(int i) { + can_cache = i; +} + +void FxDynamicMove::flushCache() +{ + need_flush=true; +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/fx_dmove.h b/Src/Wasabi/api/skin/widgets/fx_dmove.h new file mode 100644 index 00000000..dc6356f5 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/fx_dmove.h @@ -0,0 +1,48 @@ +#ifndef __FX_DMOVE_H +#define __FX_DMOVE_H + +#include "fx.h" +#include <tataki/canvas/bltcanvas.h> + +class Layer; + +class FxDynamicMove : public Fx { + public: + + FxDynamicMove(); + ~FxDynamicMove(); + + virtual int render(Layer *l, int _w, int _h, int *input, int tw, int th, int twpitch); + virtual void setWrap(int i); + virtual void setRect(int i); + virtual void setBilinear(int i); + virtual void setAlphaMode(int i); + virtual void setAlphaOnce(int i); + virtual void setCanCache(int i); + virtual void setGridSize(int x, int y); + virtual BltCanvas *getBltCanvas(); + virtual void prepareCanvas(int w, int h); + virtual void flushCache(); + private: + + BltCanvas fx_canvas; + int last_w, last_h; + int cache_w, cache_h; + + int m_lastw,m_lasth; + int m_lastxres, m_lastyres, m_xres, m_yres, m_lastpitch; + int *m_wmul; + int *m_tab; + int *last_m_tab; + int m_tab_size; + int subpixel,rectcoords,blend,wrap; + int inited; + int need_alpha; + int alpha_once; + int can_cache; + bool need_flush; + double *alpha_table; + +}; + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/group.cpp b/Src/Wasabi/api/skin/widgets/group.cpp new file mode 100644 index 00000000..d0827ef5 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/group.cpp @@ -0,0 +1,1753 @@ +#include <precomp.h> +#include <tataki/bitmap/bitmap.h> +#include <api/wnd/popup.h> +#include <api/wndmgr/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/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/items/attribute.h> +#include <api/wndmgr/layout.h> +#include <api/script/script.h> +#include <api/script/scriptmgr.h> +#include <bfc/util/profiler.h> +#include <api/wndmgr/resize.h> +#include <bfc/wasabi_std_wnd.h> +#include <api/wnd/PaintCanvas.h> + +#ifndef WM_MOUSEWHEEL +#define WM_MOUSEWHEEL 0x20A +#endif + +const wchar_t groupXuiObjectStr[] = L"Group"; // This is the xml tag +char groupXuiSvcName[] = "Group xui object"; // this is the name of the xuiservice + +#ifdef WASABI_COMPILE_CONFIG +const wchar_t cfgGroupXuiObjectStr[] = L"CfgGroup"; // This is the xml tag +char cfgGroupXuiSvcName[] = "CfgGroup xui object"; // this is the name of the xuiservice +#endif + +XMLParamPair Group::groupParams[] = + { + {XUIGROUP_AUTOHEIGHTSOURCE, L"AUTOHEIGHTSOURCE"}, + {XUIGROUP_AUTOWIDTHSOURCE, L"AUTOWIDTHSOURCE"}, + {XUIGROUP_BACKGROUND, L"BACKGROUND"}, + {XUIGROUP_DRAWBACKGROUND, L"DRAWBACKGROUND"}, + {XUIGROUP_DEFAULT_W, L"DEFAULT_W"}, + {XUIGROUP_DEFAULT_H, L"DEFAULT_H"}, + {XUIGROUP_DESIGN_H, L"DESIGN_H"}, + {XUIGROUP_DESIGN_W, L"DESIGN_W"}, + {XUIGROUP_EMBED_XUI, L"EMBED_XUI"}, + {XUIGROUP_INHERIT_CONTENT, L"INHERIT_CONTENT"}, + {XUIGROUP_INHERIT_GROUP, L"INHERIT_GROUP"}, + {XUIGROUP_INSTANCEID, L"INSTANCEID"}, + {XUIGROUP_LOCKMINMAX, L"LOCKMINMAX"}, + {XUIGROUP_MAXIMUM_H, L"MAXIMUM_H"}, + {XUIGROUP_MAXIMUM_W, L"MAXIMUM_W"}, + {XUIGROUP_MINIMUM_H, L"MINIMUM_H"}, + {XUIGROUP_MINIMUM_W, L"MINIMUM_W"}, + {XUIGROUP_NAME, L"NAME"}, + {XUIGROUP_PROPAGATESIZE, L"PROPAGATESIZE"}, + {XUIGROUP_XUITAG, L"XUITAG"}, + }; + +Group::Group() +{ + scripts_enabled = 1; + getScriptObject()->vcpu_setInterface(groupGuid, (void *)static_cast<Group *>(this)); + getScriptObject()->vcpu_setClassName(L"Group"); + getScriptObject()->vcpu_setController(groupController); + background = NULL; + skinpart = 0; + captured = 0; resizing = 0; + x = 0; y = 0; + size_w = 0; size_h = 0; + lockminmax = 0; + propagatesize = 0; + reg = NULL; + default_h = AUTOWH; + default_w = AUTOWH; + // allreg = NULL; + // subregionlayers = new PtrList<api_window>; + // subregiongroups = new PtrList<api_window>; + deleting = 0; + moving = 0; + drawbackground = 0; + groupmaxheight = AUTOWH; + groupmaxwidth = AUTOWH; + groupminheight = AUTOWH; + groupminwidth = AUTOWH; + // regionop = 0; + // allsubreg = NULL; + groups.addItem(this); + scaledreg = NULL; + scaledregionvalid = 0; + autoregionop = 1; + setRectRgn(0); + disable_update_pos = 0; + no_init_on_addchild = 0; + lastheightsource = lastwidthsource = NULL; + lastgetwidthbasedon = lastgetheightbasedon = AUTOWH; + content_item = NULL; + + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); + + design_w = AUTOWH; + design_h = AUTOWH; +} + +void Group::CreateXMLParameters(int master_handle) +{ + //GROUP_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(groupParams) / sizeof(groupParams[0]); + hintNumberOfParams(xuihandle, numParams); + for (int i = 0;i < numParams;i++) + { + addParam(xuihandle, groupParams[i], XUI_ATTRIBUTE_IMPLIED); + } +} + +Group::~Group() +{ + deleteScripts(); + deleting = 1; + WASABI_API_WND->skin_unregisterBaseTextureWindow(this); + while (gui_objects.getNumItems() > 0) + { + SkinParser::destroyGuiObject(gui_objects.enumItem(0)); + gui_objects.removeByPos(0); + } + delete background; + delete reg; + delete scaledreg; + xuiparams.deleteAll(); + /* subregionlayers->removeAll(); + delete subregionlayers; + subregiongroups->removeAll(); + delete subregiongroups;*/ + groups.removeItem(this); + WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<WndCallbackI*>(this)); +} + +int Group::isGroup(Group *o) +{ + return groups.haveItem(o); +} + +int Group::setXmlParam(const wchar_t *paramname, const wchar_t *strvalue) +{ + if (!WCSICMP(paramname, L"id") && !instanceid.isempty()) + return GROUP_PARENT::setXmlParam(paramname, instanceid); + return GROUP_PARENT::setXmlParam(paramname, strvalue); +} + +int Group::setXuiParam(int _xuihandle, int xuiid, const wchar_t *paramname, const wchar_t *strvalue) +{ + if (xuihandle == _xuihandle) + { + switch (xuiid) + { + case XUIGROUP_INSTANCEID: + instanceid = strvalue; + getGuiObject()->guiobject_setId(instanceid); + return 1; + case XUIGROUP_BACKGROUND: + setBaseTexture(strvalue); + setDrawBackground(1); + return 1; + case XUIGROUP_DRAWBACKGROUND: + setDrawBackground(WTOI(strvalue)); + return 1; + case XUIGROUP_DEFAULT_W: + { + int w = WTOI(strvalue); + //getGuiObject()->guiobject_setGuiPosition(NULL, NULL, &w, NULL, NULL, NULL, NULL, NULL); + default_w = w; + return 1; + } + case XUIGROUP_DEFAULT_H: + { + int h = WTOI(strvalue); + //getGuiObject()->guiobject_setGuiPosition(NULL, NULL, NULL, &h, NULL, NULL, NULL, NULL); + default_h = h; + return 1; + } + + case XUIGROUP_MAXIMUM_H: + groupmaxheight = WTOI(strvalue); + return 1; + case XUIGROUP_MAXIMUM_W: + groupmaxwidth = WTOI(strvalue); + return 1; + case XUIGROUP_MINIMUM_H: + groupminheight = WTOI(strvalue); + return 1; + case XUIGROUP_MINIMUM_W: + groupminwidth = WTOI(strvalue); + return 1; + case XUIGROUP_PROPAGATESIZE: + propagatesize = WTOI(strvalue); + return 1; + case XUIGROUP_LOCKMINMAX: + lockminmax = WTOI(strvalue); + return 1; + case XUIGROUP_NAME: + setName(strvalue); + return 1; + case XUIGROUP_AUTOWIDTHSOURCE: + setAutoWidthSource(strvalue); + return 1; + case XUIGROUP_AUTOHEIGHTSOURCE: + setAutoHeightSource(strvalue); + return 1; + case XUIGROUP_EMBED_XUI: + xui_embedded_id = strvalue; + return 1; + case XUIGROUP_XUITAG: + return 1; + case XUIGROUP_INHERIT_GROUP: + return 1; + case XUIGROUP_INHERIT_CONTENT: + return 1; + case XUIGROUP_DESIGN_W: + setDesignWidth(WTOI(strvalue)); + return 1; + case XUIGROUP_DESIGN_H: + setDesignHeight(WTOI(strvalue)); + return 1; + } + } + return GROUP_PARENT::setXuiParam(_xuihandle, xuiid, paramname, strvalue); +} + +void Group::setDesignWidth(int w) +{ + design_w = w; + if (isPostOnInit()) + onResize(); +} + +void Group::setDesignHeight(int h) +{ + design_h = h; + if (isPostOnInit()) + onResize(); +} + +int Group::getDesignWidth() +{ + return design_w; +} + +int Group::getDesignHeight() +{ + return design_h; +} + +int Group::onPostedMove() +{ + return GROUP_PARENT::onPostedMove(); +} + +#ifdef WASABI_COMPILE_WNDMGR +void Group::beginMove() +{ + if (getGuiObject()->guiobject_getParentGroup()) + getGuiObject()->guiobject_getParentGroup()->beginMove(); +} + +void Group::beginScale() +{ + if (getGuiObject()->guiobject_getParentGroup()) + getGuiObject()->guiobject_getParentGroup()->beginScale(); +} + +void Group::beginResize() +{ + if (getGuiObject()->guiobject_getParentGroup()) + getGuiObject()->guiobject_getParentGroup()->beginResize(); +} + +void Group::endMove() +{ + if (getGuiObject()->guiobject_getParentGroup()) + getGuiObject()->guiobject_getParentGroup()->endMove(); +} + +void Group::endScale() +{ + if (getGuiObject()->guiobject_getParentGroup()) + getGuiObject()->guiobject_getParentGroup()->endScale(); +} + +void Group::endResize() +{ + if (getGuiObject()->guiobject_getParentGroup()) + getGuiObject()->guiobject_getParentGroup()->endResize(); +} +#endif + +void Group::onMinMaxEnforcerChanged() +{ + if (!isPostOnInit()) return ; + int min_x = getPreferences(MINIMUM_W); + int min_y = getPreferences(MINIMUM_H); + int max_x = getPreferences(MAXIMUM_W); + int max_y = getPreferences(MAXIMUM_H); + int sug_x = getPreferences(SUGGESTED_W); + int sug_y = getPreferences(SUGGESTED_H); + min_x = MAX(RESIZE_MINW, min_x); + min_y = MAX(RESIZE_MINH, min_y); + + RECT r; + POINT pt; + getClientRect(&r); + int w = r.right - r.left; + int h = r.bottom - r.top; + getPosition(&pt); + if ((w < min_x || h < min_y || w > max_x || h > max_y) && (w != sug_x || h != sug_y)) + { + //DebugString("reapplying minmax constraints\n"); + resize(pt.x, pt.y, sug_x, sug_y); + } +} + +#ifdef WASABI_COMPILE_WNDMGR +void Group::mouseResize(int x, int y, int resizeway) +{ // screen coords! + + int min_x = getPreferences(MINIMUM_W); + int min_y = getPreferences(MINIMUM_H); + int max_x = getPreferences(MAXIMUM_W); + int max_y = getPreferences(MAXIMUM_H); + int sug_x = getPreferences(SUGGESTED_W); + int sug_y = getPreferences(SUGGESTED_H); + + if (max_x != AUTOWH && min_x != AUTOWH && max_x < min_x) max_x = min_x; + if (max_y != AUTOWH && min_y != AUTOWH && max_y < min_y) max_y = min_y; + if (min_x != AUTOWH && max_x != AUTOWH && min_x > max_x) min_x = max_x; + if (min_y != AUTOWH && max_y != AUTOWH && min_y > max_y) min_y = max_y; + if (sug_x != AUTOWH && min_x != AUTOWH && sug_x < min_x) sug_x = min_x; + if (sug_y != AUTOWH && min_y != AUTOWH && sug_y < min_y) sug_y = min_y; + if (sug_x != AUTOWH && max_x != AUTOWH && sug_x > max_x) sug_x = max_x; + if (sug_y != AUTOWH && max_y != AUTOWH && sug_y > max_y) sug_y = max_y; + + beginResize(); + + int mask = 0; + if (resizeway & RESIZE_BOTTOM) + { + mask |= BOTTOM; + } + if (resizeway & RESIZE_RIGHT) + { + mask |= RIGHT; + } + if (resizeway & RESIZE_TOP) + { + mask |= TOP; + } + if (resizeway & RESIZE_LEFT) + { + mask |= LEFT; + } + + min_x = MAX(RESIZE_MINW, min_x); + min_y = MAX(RESIZE_MINH, min_y); + + if (renderRatioActive()) + { + if (min_x != AUTOWH) multRatio(&min_x); + if (min_y != AUTOWH) multRatio(NULL, &min_y); + if (max_x != AUTOWH) multRatio(&max_x); + if (max_y != AUTOWH) multRatio(NULL, &max_y); + if (sug_x != AUTOWH) multRatio(&sug_x); + if (sug_y != AUTOWH) multRatio(NULL, &sug_y); + } + + if (min_x == AUTOWH) min_x = -1; + if (max_x == AUTOWH) max_x = -1; + if (min_y == AUTOWH) min_y = -1; + if (max_y == AUTOWH) max_y = -1; + if (sug_x == AUTOWH) sug_x = -1; + if (sug_y == AUTOWH) sug_y = -1; + + resizeClass rsize(this, min_x, min_y, max_x, max_y, sug_x, sug_y); + if (rsize.resizeWindow(this, mask | NOINTERSECT)) + { + RECT r = rsize.getRect(); + + if (renderRatioActive()) + { + r.right = (int)(((double)(r.right - r.left) / getRenderRatio()) + r.left + 0.5f); + r.bottom = (int)(((double)(r.bottom - r.top) / getRenderRatio()) + r.top + 0.5f); + } + + int _min_x = getPreferences(MINIMUM_W); + int _min_y = getPreferences(MINIMUM_H); + int _max_x = getPreferences(MAXIMUM_W); + int _max_y = getPreferences(MAXIMUM_H); + + if (_max_x != AUTOWH && _min_x != AUTOWH && _max_x < _min_x) _max_x = _min_x; + if (_max_y != AUTOWH && _min_y != AUTOWH && _max_y < _min_y) _max_y = _min_y; + if (_min_x != AUTOWH && _max_x != AUTOWH && _min_x > _max_x) _min_x = _max_x; + if (_min_y != AUTOWH && _max_y != AUTOWH && _min_y > _max_y) _min_y = _max_y; + + if (r.right - r.left < _min_x) r.right = r.left + _min_x; + if (r.bottom - r.top < _min_y) r.bottom = r.top + _min_y; + if (r.right - r.left > _max_x) r.right = r.left + _max_x; + if (r.bottom - r.top > _max_y) r.bottom = r.top + _max_y; + + resizeToRect(&r); + invalidate(); + endResize(); + } +} +#endif + +void Group::setAutoWidthSource(const wchar_t *obj) +{ + autowidthsource = obj; +} + +void Group::setAutoHeightSource(const wchar_t *obj) +{ + autoheightsource = obj; +} + +int Group::getAutoWidth() +{ + return default_w == AUTOWH ? GROUP_PARENT::getPreferences(SUGGESTED_W) : default_w; +} + +int Group::getAutoHeight() +{ + return default_h == AUTOWH ? GROUP_PARENT::getPreferences(SUGGESTED_H) : default_h; +} + +int Group::getWidthBasedOn(GuiObject *o) +{ + if (o == NULL) + { + if (lastwidthsource == NULL) + { + if (!autowidthsource.isempty()) + { + lastwidthsource = getObject(autowidthsource); + } + } + o = lastwidthsource; + } + if (o == NULL) return AUTOWH; + if (lastgetwidthbasedon != AUTOWH) return lastgetwidthbasedon; + int x, rx, w, rw; + o->guiobject_getGuiPosition(&x, NULL, &w, NULL, &rx, NULL, &rw, NULL); + int p = o->guiobject_getAutoWidth(); +if (w == AUTOWH) { w = p; rw = 0; } + if (rx == 0 && rw == 1) + lastgetwidthbasedon = p - w; + else if (rx == 0 && rw == 0) + lastgetwidthbasedon = p + x; + else + lastgetwidthbasedon = AUTOWH; + + return lastgetwidthbasedon; +} + +int Group::getHeightBasedOn(GuiObject *o) +{ + if (o == NULL) + { + if (lastheightsource == NULL) + { + if (!autoheightsource.isempty()) + { + lastheightsource = getObject(autoheightsource); + } + } + o = lastheightsource; + } + if (o == NULL) return AUTOWH; + if (lastgetheightbasedon != AUTOWH) return lastgetheightbasedon; + int y, ry, h, rh; + o->guiobject_getGuiPosition(NULL, &y, NULL, &h, NULL, &ry, NULL, &rh); + int p = o->guiobject_getAutoHeight(); +if (h == AUTOWH) { h = p; rh = 0; } + if (ry == 0 && rh == 1) + lastgetheightbasedon = p - h; + else if (ry == 0 && rh == 0) + lastgetheightbasedon = h + y; + else + lastgetheightbasedon = AUTOWH; + + return lastgetheightbasedon; +} + +int Group::getPreferences(int what) +{ + int _what = what; + if (lockminmax) + { + if (_what == MAXIMUM_W || _what == MINIMUM_W) + _what = SUGGESTED_W; + if (_what == MAXIMUM_H || _what == MINIMUM_H) + _what = SUGGESTED_H; + } + switch (_what) + { + case SUGGESTED_W: + { + int w, rw; + getGuiObject()->guiobject_getGuiPosition(NULL, NULL, &w, NULL, NULL, NULL, &rw, NULL); + + if (w == AUTOWH) + w = getWidthBasedOn(); + + if (w == AUTOWH || rw == 1) + w = getAutoWidth(); + + if (w == AUTOWH && getBaseTexture()) + w = getBaseTexture()->getWidth(); + + if (groupmaxwidth != AUTOWH) + { + if (groupminwidth != AUTOWH) + { + return MIN(groupmaxwidth, MAX(groupminwidth, w)); + } + else + { + return MIN(groupmaxwidth, w); + } + } + else if (groupminwidth != AUTOWH) + { + return MAX(groupminwidth, w); + } + return w; + } + case SUGGESTED_H: + { + int h, rh; + getGuiObject()->guiobject_getGuiPosition(NULL, NULL, NULL, &h, NULL, NULL, NULL, &rh); + + if (h == AUTOWH) + h = getHeightBasedOn(); + + if (h == AUTOWH || rh == 1) + h = getAutoHeight(); + + if (h == AUTOWH && getBaseTexture()) + h = getBaseTexture()->getHeight(); + + if (groupmaxheight != AUTOWH) + { + if (groupminheight != AUTOWH) + { + return MIN(groupmaxheight, MAX(groupminheight, h)); + } + else + { + return MIN(groupmaxheight, h); + } + } + else if (groupminheight != AUTOWH) + { + return MAX(groupminheight, h); + } + return h; + } + case MAXIMUM_H: + { + int h = GROUP_PARENT::getPreferences(what); + + if (h != AUTOWH) + return MIN(h, groupmaxheight); + + return groupmaxheight; + } + case MAXIMUM_W: + { + int w = GROUP_PARENT::getPreferences(what); + + if (w != AUTOWH) + return MIN(w, groupmaxwidth); + + return groupmaxwidth; + } + case MINIMUM_H: + { + int h = GROUP_PARENT::getPreferences(what); + + if (h != AUTOWH) + return MAX(h, groupminheight); + + return groupminheight; + } + case MINIMUM_W: + { + int w = GROUP_PARENT::getPreferences(what); + + if (w != AUTOWH) + return MAX(w, groupminwidth); + + return groupminwidth; + } + } + return GROUP_PARENT::getPreferences(what); +} + +void Group::updatePos(GuiObject *o, RECT *r2) +{ + + if (disable_update_pos) return ; + + RECT r; + if (r2 == NULL) + { + getClientRect(&r); + r2 = &r; + } + + + double d = getRenderRatio(); + int w, h; + int ox, oy, ow, oh, orx, ory, orw, orh; + int ox1, ox2, oy1, oy2, oanchor; + + if (o->guiobject_getAnchoragePosition(&ox1, &oy1, &ox2, &oy2, &oanchor)) + { + // anchorage values have not been translated into native values yet, do it now + int x, y, w, h, rx, ry, rw, rh; + x = y = w = h = rx = ry = rw = rh = AUTOWH; + int lw = ox2 - ox1; + int lh = oy2 - oy1; + int iw = getDesignWidth(); + int ih = getDesignHeight(); + if (iw == AUTOWH || ih == AUTOWH) + { + Wasabi::Std::messageBox(L"anchor coordinate system used without design size for the parent group.\nYour parent group needs the design_w/design_h parameters if you are using x1/y1/x2/y2/anchor parameters on one of its children\nDefaulting to 320x200", L"XML Error", 0); + iw = 320; + ih = 200; + } + int right_m = iw - ox2; + int bottom_m = ih - oy2; + + if ((oanchor & ANCHOR_LEFT) == 0 && (oanchor & ANCHOR_RIGHT) == 0) oanchor |= ANCHOR_LEFT; + if ((oanchor & ANCHOR_TOP) == 0 && (oanchor & ANCHOR_BOTTOM) == 0) oanchor |= ANCHOR_TOP; + + if (oanchor & ANCHOR_LEFT) + { + x = ox1; + rx = 0; + if (oanchor & ANCHOR_RIGHT) + { + w = -((iw - ox2) + ox1); + rw = 1; + } + else + { + w = lw; + rw = 0; + } + } + else + { + if (oanchor & ANCHOR_RIGHT) + { + x = -(right_m + lw); + rx = 1; + w = lw; + rw = 0; + } + } + if (oanchor & ANCHOR_TOP) + { + y = oy1; + ry = 0; + if (oanchor & ANCHOR_BOTTOM) + { + h = -((ih - oy2) + oy1); + rh = 1; + } + else + { + h = lh; + rh = 0; + } + } + else + { + if (oanchor & ANCHOR_BOTTOM) + { + y = -(bottom_m + lh); + ry = 1; + h = lh; + rh = 0; + } + } + disable_update_pos = 1; + o->guiobject_setGuiPosition(&x, &y, &w, &h, &rx, &ry, &rw, &rh); + o->guiobject_validateAnchorage(); + disable_update_pos = 0; + } + + o->guiobject_getGuiPosition(&ox, &oy, &ow, &oh, &orx, &ory, &orw, &orh); + if (ow == AUTOWH) { ow = o->guiobject_getAutoWidth(); orw = 0; } + if (oh == AUTOWH) { oh = o->guiobject_getAutoHeight(); orh = 0; } + + TextInfoCanvas fontInfoCanvas(this); + double fontScale = fontInfoCanvas.getSystemFontScale(); + if (o->guiobject_getAutoSysMetricsX()) + ox = (int)((float)ox * fontScale); + + if (o->guiobject_getAutoSysMetricsY()) + oy = (int)((float)oy * fontScale); + + if (o->guiobject_getAutoSysMetricsW()) + ow = (int)((float)ow * fontScale); + + if (o->guiobject_getAutoSysMetricsH()) + oh = (int)((float)oh * fontScale); + + if (!o->guiobject_getRootWnd()->handleRatio()) + { + if (orw == 1) + w = (int)((float)(r2->right - r2->left + ow) * d); + else if (orw == 2) + w = (int)(((float)(r2->right - r2->left) * ((float)ow / 100.0f)) * d); + else + w = (int)((float)(ow) * d); + if (orh == 1) + h = (int)((float)(r2->bottom - r2->top + oh) * d); + else if (orh == 2) + h = (int)(((float)(r2->bottom - r2->top) * ((float)oh / 100.0f)) * d); + else + h = (int)((float)(oh) * d); + if (orx == 1) + x = (int)((float)(r2->right - r2->left + ox) * d); + else if (orx == 2) + x = (int)(((float)(r2->right - r2->left) * ((float)ox / 100.0f)) * d); + else + x = (int)((float)(ox) * d); + if (ory == 1) + y = (int)((float)(r2->bottom - r2->top + oy) * d); + else if (ory == 2) + y = (int)(((float)(r2->bottom - r2->top) * ((float)oy / 100.0f)) * d); + else + y = (int)((float)(oy) * d); + x += (int)((float)(r2->left) * d); + y += (int)((float)(r2->top) * d); + } + else + { + if (orw == 1) + w = r2->right - r2->left + ow; + else if (orw == 2) + w = (int)((float)(r2->right - r2->left) * ((float)ow / 100.0f)); + else + w = ow; + if (orh == 1) + h = r2->bottom - r2->top + oh; + else if (orh == 2) + h = (int)((float)(r2->bottom - r2->top) * ((float)oh / 100.0f)); + else + h = oh; + if (orx == 1) + x = r2->right - r2->left + ox; + else if (orx == 2) + x = (int)((float)(r2->right - r2->left) * ((float)ox / 100.0f)); + else + x = ox; + if (ory == 1) + y = r2->bottom - r2->top + oy; + else if (ory == 2) + y = (int)((float)(r2->bottom - r2->top) * ((float)oy / 100.0f)); + else + y = oy; + x += r2->left; + y += r2->top; + } + + o->guiobject_getRootWnd()->resize(x, y, w, h); +} + + +int Group::onResize() +{ + GROUP_PARENT::onResize(); + if (!isInited()) return 1; + + RECT wr; + getWindowRect(&wr); + RECT r2; + getClientRect(&r2); + size_w = r2.right - r2.left; size_h = r2.bottom - r2.top; + for (int i = 0;i < gui_objects.getNumItems();i++) + { + GuiObject *o = gui_objects.enumItem(i); + updatePos(o, &r2); + } + invalidateScaledReg(); + return 1; +} + +void Group::invalidateScaledReg() +{ + scaledregionvalid = 0; + invalidateWindowRegion(); +} + +int Group::onInit() +{ + GROUP_PARENT::onInit(); + + WASABI_API_SYSCB->syscb_registerCallback(static_cast<WndCallbackI*>(this)); + + disable_update_pos = 1; + no_init_on_addchild = 1; + + const wchar_t *id = getGroupContentId(); + SkinItem *item = getGroupContentSkinItem(); + if ((id && *id) || item != NULL) + { + SkinParser::fillGroup(this, id, item, 0, 1, scripts_enabled); + } + + disable_update_pos = 0; + no_init_on_addchild = 0; + + onFillGroup(); + + return 1; +} + +void Group::onFillGroup() +{ + reloadDefaults(); + if (xui_embedded_id.len() > 0) + embeddedxui_onNewEmbeddedContent(); +} + +int Group::onGroupChange(const wchar_t *id) +{ + GROUP_PARENT::onGroupChange(id); + + if (!isInited()) return 1; + const wchar_t *cid = getGroupContentId(); + SkinItem *item = getGroupContentSkinItem(); + if (!(cid && *cid) || item != NULL) return 1; + + if (!WCSICMP(id, cid)) return 1; + + deleteScripts(); + + WASABI_API_WND->skin_unregisterBaseTextureWindow(this); + while (gui_objects.getNumItems() > 0) + { + SkinParser::destroyGuiObject(gui_objects.enumItem(0)); + } + + delete background; background = NULL; + delete reg; reg = NULL; + delete scaledreg; scaledreg = NULL; + + disable_update_pos = 1; + no_init_on_addchild = 1; + + SkinParser::fillGroup(this, cid, item, 0, 1, scripts_enabled); + + disable_update_pos = 0; + no_init_on_addchild = 0; + + onFillGroup(); + if (isInited()) + onResize(); + + getGuiObject()->guiobject_onStartup(); + + return 1; +} + +void Group::reloadDefaults() +{ + getGuiObject()->guiobject_getGuiPosition(NULL, NULL, &size_w, &size_h, NULL, NULL, NULL, NULL); + if (size_w == AUTOWH && size_h == AUTOWH) + { + /* if (!background) { + size_w = 250; + size_h = 100; + } else { + size_w = background->getWidth(); + size_h = background->getHeight(); + }*/ + if (background) + { + setPreferences(SUGGESTED_W, background->getWidth()); + setPreferences(SUGGESTED_H, background->getHeight()); + } + size_w = GROUP_PARENT::getPreferences(SUGGESTED_W); + size_h = GROUP_PARENT::getPreferences(SUGGESTED_H); + } + //setName(getGuiObject()->guiobject_getId()); + + if (propagatesize) + { + Layout *l = getGuiObject()->guiobject_getParentLayout(); + if (l) l->addMinMaxEnforcer(this); + } + + int i; + for (i = 0;i < gui_objects.getNumItems();i++) + { + + GuiObject *o = gui_objects.enumItem(i); + + if (o->guiobject_getParentGroup()) + { + o->guiobject_getRootWnd()->setParent(o->guiobject_getParentGroup()); + if (!o->guiobject_getRootWnd()->isInited()) + { + o->guiobject_getRootWnd()->init(o->guiobject_getParentGroup()); + o->guiobject_getParentGroup()->onCreateObject(getGuiObject()); + } + } + } + + /* if (getGuiObject()->guiobject_getParentGroup() && regionop) + getGuiObject()->guiobject_getParentGroup()->addSubRegionGroup(this);*/ + + invalidateWindowRegion(); + + startScripts(); + + for (i = 0;i < gui_objects.getNumItems();i++) + { + GuiObject *o = gui_objects.enumItem(i); + o->guiobject_onStartup(); + } + + autoResize(); + + const wchar_t *name = getName(); + if (name != NULL) + onSetName(); +} + +void Group::startScripts() +{ + for (int i = 0;i < getNumScripts();i++) + { + int vcpuid = enumScript(i); + SystemObject *o = SOM::getSystemObjectByScriptId(vcpuid); + if (o != NULL) + { + o->onLoad(); + foreach(xuiparams) + XuiParam *p = xuiparams.getfor(); + o->onSetXuiParam(p->param, p->value); + endfor; + } + } +} + +int Group::onPaint(Canvas *canvas) +{ + PaintCanvas paintcanvas; + if (canvas == NULL) + { + if (!paintcanvas.beginPaint(this)) return 0; + canvas = &paintcanvas; + } + GROUP_PARENT::onPaint(canvas); + RECT r; + if (!canvas->getClipBox(&r)) + getClientRect(&r); + + + if (getDrawBackground()) RenderBaseTexture(canvas, r); + return 1; +} + +ifc_window *Group::getBaseTextureWindow() +{ + if (reg && !reg->isEmpty()) return this; + if (getParent()) return getParent()->getBaseTextureWindow(); + return this; +} + +void Group::autoResize() +{ + int w = getWidthBasedOn(); + int h = getHeightBasedOn(); + if (h == AUTOWH && w == AUTOWH) return ; + resize(NOCHANGE, NOCHANGE, w == AUTOWH ? NOCHANGE : w, h == AUTOWH ? NOCHANGE : h); +} + +int Group::childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2) +{ + if (msg == ChildNotify::AUTOWHCHANGED) + { + if (lastwidthsource && child == lastwidthsource->guiobject_getRootWnd() || + lastheightsource && child == lastheightsource->guiobject_getRootWnd()) + { + lastgetwidthbasedon = AUTOWH; + lastgetheightbasedon = AUTOWH; + autoResize(); + } + } + if (!getParent()) + return 0; + return getParent()->childNotify(child, msg, p1, p2); +} + + +void Group::sendNotifyToAllChildren(int notifymsg, intptr_t param1, intptr_t param2) +{ + for (int i = 0;i < gui_objects.getNumItems();i++) + gui_objects.enumItem(i)->guiobject_getRootWnd()->childNotify(this, notifymsg, param1, param2); +} + +void Group::addScript(int scriptid) +{ + scripts.addItem(scriptid); +} + +int Group::getNumScripts() +{ + return scripts.getNumItems(); +} + +int Group::enumScript(int n) +{ + return scripts.enumItem(n); +} + +void Group::deleteScripts() +{ + for (int i = 0;i < scripts.getNumItems();i++) + Script::unloadScript(scripts.enumItem(i)); + scripts.removeAll(); +} + +SkinBitmap *Group::getBaseTexture() +{ + if (!background) return NULL; + return background->getBitmap(); +} + +void Group::setBaseTexture(const wchar_t *b, int regis) +{ + backgroundstr = b; + if (regis) WASABI_API_WND->skin_unregisterBaseTextureWindow(this); + delete background; + background = NULL; + if (b != NULL && *b) + { + background = new AutoSkinBitmap(); + background->setBitmap(b); +#ifdef _WIN32 + RegionI r(background->getBitmap()); + setRegion(&r); +#else +#warning port me! +#endif + + if (regis) WASABI_API_WND->skin_registerBaseTextureWindow(this, b); + } + else + { + delete reg; + reg = NULL; + delete scaledreg; + scaledreg = NULL; + invalidateWindowRegion(); + } + +} + +const wchar_t *Group::getBackgroundStr() +{ + return backgroundstr; +} + +int Group::onUnknownXuiParam(const wchar_t *xmlattributename, const wchar_t *value) +{ + int r = GROUP_PARENT::onUnknownXuiParam(xmlattributename, value); + if (r == 0) + { + if (!isInited()) + { + xuiparams.addItem(new XuiParam(xmlattributename, value)); + } + else + { + for (int i = 0;i < getNumScripts();i++) + { + int vcpuid = enumScript(i); + SystemObject *o = SOM::getSystemObjectByScriptId(vcpuid); + if (o != NULL) o->onSetXuiParam(xmlattributename, value); + } + } + } + return r; +} + +api_region *Group::getRegion() +{ + ensureScaledRegValid(); + return scaledreg; +} + +void Group::ensureScaledRegValid() +{ + if (!scaledregionvalid) + { + scaledregionvalid = 1; + if (!reg) return ; + if (!scaledreg) scaledreg = new RegionI; + scaledreg->empty(); + scaledreg->addRegion(reg); + RECT rr; + getNonClientRect(&rr); + if (background) + { + float w = (float)(rr.right - rr.left) / (float)background->getWidth(); + float h = (float)(rr.bottom - rr.top) / (float)background->getHeight(); + if (w && h && (ABS(w - 1.0f) > 0.01f || ABS(h - 1.0f) > 0.01f)) + scaledreg->scale(w, h, 1); + else if (w == 0 || h == 0) + { + RECT r = {0, 0, 0, 0}; + scaledreg->setRect(&r); + } + } + } +} + +void Group::setRegion(api_region *r) +{ + ASSERT(r != NULL); + if (!reg) reg = new RegionI; + + reg->empty(); + reg->addRegion(r); // background + + invalidateWindowRegion(); + invalidateScaledReg(); +} + +Container *Group::getParentContainer() +{ + if (!getGuiObject()->guiobject_getParentGroup()) + { + ifc_window *r = getDesktopParent(); + if (r != NULL) + { + //ASSERT(r != NULL); + Layout *l = static_cast<Layout *>(r->getInterface(layoutGuid)); + if (!l) return NULL; + return l->getParentContainer(); + } + } + Group *g = getGuiObject()->guiobject_getParentGroup(); + if (g) return g->getParentContainer(); + return NULL; +} + +ifc_window *Group::enumObjects(int i) +{ + if (i >= gui_objects.getNumItems()) return NULL; + return gui_objects.enumItem(i)->guiobject_getRootWnd(); +} + +int Group::getNumObjects() +{ + return gui_objects.getNumItems(); +} + +void Group::addChild(GuiObject *g) +{ + gui_objects.addItem(g); + script_objects.addItem((ScriptObject *)g); + g->guiobject_setParentGroup(this); + g->guiobject_getRootWnd()->setParent(this); + if (!no_init_on_addchild && isInited() + && !g->guiobject_getRootWnd()->isInited()) + g->guiobject_getRootWnd()->init(this); +} + +void Group::removeChild(GuiObject *g) +{ + if (!deleting) + gui_objects.removeItem(g); + script_objects.removeItem((ScriptObject *)g); +} + +void Group::onCreateObject(GuiObject *o) +{ + script_vcpu_onCreateObject(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(o->guiobject_getScriptObject())); +} + +int Group::getDrawBackground() +{ + return drawbackground; +} + +void Group::setDrawBackground(int t) +{ + drawbackground = t; +} + +int Group::isLayout() +{ + return 0; +} + +int Group::isDesktopAlphaSafe() +{ + if (!Wasabi::Std::Wnd::isDesktopAlphaAvailable()) return 0; + for (int i = 0;i < getNumObjects();i++) + { + ifc_window *w = enumObjects(i); + Group *cg = static_cast<Group *>(w); + if (Group::isGroup(cg)) + if (!cg->isDesktopAlphaSafe()) return 0; + if (!w->handleDesktopAlpha()) return 0; + } + return 1; +} + +int Group::isTransparencySafe(int excludeme) +{ + if (!Wasabi::Std::Wnd::isTransparencyAvailable()) return 0; + if (!excludeme && isTransparencyForcedOff()) return 0; + for (int i = 0;i < getNumObjects();i++) + { + ifc_window *w = enumObjects(i); + Group *cg = static_cast<Group *>(w); + if (Group::isGroup(cg)) + if (!cg->isTransparencySafe()) return 0; + if (!w->handleTransparency()) return 0; + } + return 1; +} + +GuiObject *Group::getObject(const wchar_t *id) +{ + for (int i = 0;i < script_objects.getNumItems();i++) + { + if (!WCSICMP(id, gui_objects.enumItem(i)->guiobject_getId())) + { + return gui_objects.enumItem(i); + } + } + return NULL; +} + +void Group::setGroupContent(const wchar_t *id, SkinItem *item, int allowscripts) +{ + content_id = id; + content_item = item; + scripts_enabled = allowscripts; +} + +const wchar_t *Group::getGroupContentId() +{ + return content_id; +} + +SkinItem *Group::getGroupContentSkinItem() +{ + return content_item; +} + +ScriptObject *Group::script_cast(GUID g) +{ + GuiObject *o = embeddedxui_getEmbeddedObject(); + if (o != NULL) + { + void *r = o->guiobject_getScriptObject()->vcpu_getInterface(g); + if (r != NULL) + { + return o->guiobject_getScriptObject(); + } + } + return NULL; +} + +// ----------------------------------------------------------------------- + +GroupScriptController _groupController; +GroupScriptController *groupController = &_groupController; + +// -- Functions table ------------------------------------- +function_descriptor_struct GroupScriptController::exportedFunction[] = { + {L"getObject", 1, (void*)Group::script_vcpu_getObject }, + {L"enumObject", 1, (void*)Group::script_vcpu_enumObject }, + {L"getNumObjects", 0, (void*)Group::script_vcpu_getNumObjects }, + {L"onCreateObject", 1, (void*)Group::script_vcpu_onCreateObject }, + {L"getMousePosX", 0, (void*)Group::script_vcpu_getMousePosX }, + {L"getMousePosY", 0, (void*)Group::script_vcpu_getMousePosY }, + {L"isLayout", 0, (void*)Group::script_vcpu_isLayout }, + {L"autoResize", 0, (void*)Group::script_vcpu_autoResize}, + }; +// -------------------------------------------------------- + +ScriptObject *GroupScriptController::cast(ScriptObject *o, GUID g) +{ + Group *grp = static_cast<Group *>(o->vcpu_getInterface(groupGuid)); + if (grp != NULL) + return grp->script_cast(g); + return NULL; +} + +const wchar_t *GroupScriptController::getClassName() +{ + return L"Group"; +} + +const wchar_t *GroupScriptController::getAncestorClassName() +{ + return L"GuiObject"; +} + +int GroupScriptController::getInstantiable() +{ + return 1; +} + +ScriptObject *GroupScriptController::instantiate() +{ + return NULL; +} + +void GroupScriptController::destroy(ScriptObject *o) +{} + +void *GroupScriptController::encapsulate(ScriptObject *o) +{ + return NULL; +} + +void GroupScriptController::deencapsulate(void *o) +{} + +int GroupScriptController::getNumFunctions() +{ + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *GroupScriptController::getExportedFunctions() +{ + return exportedFunction; +} + +GUID GroupScriptController::getClassGuid() +{ + return groupGuid; +} + + +const wchar_t *Group::vcpu_getClassName() +{ + return L"Group"; +} + + +void Group::addObject(GuiObject *o) +{ + addChild(o); +} + +void Group::removeObject(GuiObject *o) +{ + removeChild(o); +} + +void Group::setRegionOp(int o) +{ + GROUP_PARENT::setRegionOp(o); + autoregionop = 0; +} + +void Group::invalidateWindowRegion() +{ + GROUP_PARENT::invalidateWindowRegion(); + if (!isInited() || isLayout()) return ; + if (autoregionop) + { + int yes = 0; + for (int i = 0;i < gui_objects.getNumItems();i++) + { + if (gui_objects.enumItem(i)->guiobject_getRegionOp() != REGIONOP_NONE) + { + yes = 1; + break; + } + } + if (yes) + GROUP_PARENT::setRegionOp(REGIONOP_OR); + else + GROUP_PARENT::setRegionOp(REGIONOP_NONE); + } +} + +// VCPU + +scriptVar Group::script_vcpu_onCreateObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar ob) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS1(o, groupController, ob); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, ob); +} + +// Get an object from its ID +scriptVar Group::script_vcpu_getObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj) +{ + SCRIPT_FUNCTION_INIT + ASSERT(obj.type == SCRIPT_STRING); // compiler discarded + Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid)); + GuiObject *ob = NULL; + if (g) + ob = g->getObject(GET_SCRIPT_STRING(obj)); + return MAKE_SCRIPT_OBJECT(ob ? ob->guiobject_getScriptObject() : NULL); +} + +scriptVar Group::script_vcpu_getMousePosX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid)); + if (g) + { + POINT pt; + Wasabi::Std::getMousePos(&pt); + g->screenToClient(&pt); + return MAKE_SCRIPT_INT(pt.x); + } + RETURN_SCRIPT_ZERO; +} + +scriptVar Group::script_vcpu_getMousePosY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid)); + if (g) + { + POINT pt; + Wasabi::Std::getMousePos(&pt); + g->screenToClient(&pt); + return MAKE_SCRIPT_INT(pt.y); + } + RETURN_SCRIPT_ZERO; +} + +scriptVar Group::script_vcpu_getNumObjects(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid)); + if (g) return MAKE_SCRIPT_INT(g->getNumObjects()); + RETURN_SCRIPT_ZERO; +} + +scriptVar Group::script_vcpu_enumObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i) +{ + SCRIPT_FUNCTION_INIT + Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid)); + GuiObject *obj = NULL; + if (g) + obj = g->gui_objects.enumItem(GET_SCRIPT_INT(i)); + return MAKE_SCRIPT_OBJECT(obj ? obj->guiobject_getScriptObject() : NULL); +} + +scriptVar Group::script_vcpu_isLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid)); + return MAKE_SCRIPT_BOOLEAN(g ? g->isLayout() : NULL); +} + +scriptVar Group::script_vcpu_autoResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid)); + if (g != NULL) g->autoResize(); + RETURN_SCRIPT_VOID +} + +#ifdef WASABI_COMPILE_CONFIG + +int Group::isCfgGroup(Group *ptr) +{ + CfgGroup *g = static_cast<CfgGroup *>(ptr); + return cfggrouplist.haveItem(g); +} + +#endif + +PtrList<CfgGroup> Group::cfggrouplist; +PtrList<Group> Group::groups; + +// --------------------------------------------------------------- +// Config Groups + + +#ifdef WASABI_COMPILE_CONFIG + +CfgGroup::CfgGroup() +{ + getScriptObject()->vcpu_setInterface(cfgGroupGuid, (void *)static_cast<CfgGroup *>(this)); + getScriptObject()->vcpu_setClassName(L"CfgGroup"); + getScriptObject()->vcpu_setController(cfgGroupController); + cfgitem = NULL; + cfggrouplist.addItem(this); +} + +CfgGroup::~CfgGroup() +{ + if (cfgitem) viewer_delViewItem(cfgitem); + cfggrouplist.removeItem(this); +} + +const wchar_t *CfgGroup::vcpu_getClassName() +{ + return L"CfgGroup"; +} + +void CfgGroup::setAttr(CfgItem *item, const wchar_t *name) +{ + if (cfgitem) viewer_delViewItem(cfgitem); + cfgitem = item; + attrname = name; + if (cfgitem != NULL) + { + wchar_t t[256] = L""; + nsGUID::toCharW(cfgitem->getGuid(), t); + cfgguid = t; + } + if (cfgitem) viewer_addViewItem(cfgitem); + dataChanged(); +} + +int CfgGroup::viewer_onEvent(CfgItem *item, int event, intptr_t param, void *ptr, size_t ptrlen) +{ + dataChanged(); + return 1; +} + +int CfgGroup::onInit() +{ + int r = Group::onInit(); + dataChanged(); + return r; +} + +void CfgGroup::dataChanged() +{ + script_vcpu_onCfgChanged(SCRIPT_CALL, getScriptObject()); +} + +CfgItem *CfgGroup::getCfgItem() +{ + return cfgitem; +} + +const wchar_t *CfgGroup::getAttributeName() +{ + return attrname; +} + +scriptVar CfgGroup::script_vcpu_cfgGetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid)); + if (cg) + { + CfgItem *i = cg->getCfgItem(); + const wchar_t *attrname = cg->getAttributeName(); + if (o != NULL && attrname != NULL) + return MAKE_SCRIPT_INT(i->getDataAsInt(attrname, 0)); + } + return MAKE_SCRIPT_INT(0); +} + +scriptVar CfgGroup::script_vcpu_cfgSetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) +{ + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&v)); + CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid)); + if (cg) + { + CfgItem *i = cg->getCfgItem(); + const wchar_t *attrname = cg->getAttributeName(); + if (o != NULL && attrname != NULL) + { + i->setDataAsInt(attrname, GET_SCRIPT_INT(v)); + } + } + RETURN_SCRIPT_VOID; +} + +scriptVar CfgGroup::script_vcpu_cfgGetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid)); + if (cg) + { + CfgItem *i = cg->getCfgItem(); + const wchar_t *a = cg->getAttributeName(); + *txt = 0; + if (!i || !a) + return MAKE_SCRIPT_STRING(txt); + if (o != NULL && a != NULL) + { + i->getData(a, txt, 512); + } + return MAKE_SCRIPT_STRING(txt); + } + return MAKE_SCRIPT_STRING(L""); +} + +scriptVar CfgGroup::script_vcpu_cfgSetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) +{ + SCRIPT_FUNCTION_INIT + ASSERT(!SOM::isNumeric(&v)); + CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid)); + if (cg) + { + CfgItem *i = cg->getCfgItem(); + const wchar_t *a = cg->getAttributeName(); + if (!i || !a) RETURN_SCRIPT_VOID; + if (o != NULL && a != NULL) + { + i->setData(a, GET_SCRIPT_STRING(v)); + } + } + RETURN_SCRIPT_VOID; +} + +scriptVar CfgGroup::script_vcpu_cfgGetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid)); + if (cg) + { + CfgItem *i = cg->getCfgItem(); + const wchar_t *attrname = cg->getAttributeName(); + if (o != NULL && attrname != NULL) + return MAKE_SCRIPT_FLOAT((float)i->getDataAsFloat(attrname, 0)); + } + return MAKE_SCRIPT_FLOAT(0); +} + +scriptVar CfgGroup::script_vcpu_cfgSetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) +{ + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&v)); + CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid)); + if (cg) + { + CfgItem *i = cg->getCfgItem(); + const wchar_t *attrname = cg->getAttributeName(); + if (o != NULL && attrname != NULL) + { + i->setDataAsFloat(attrname, GET_SCRIPT_FLOAT(v)); + } + } + RETURN_SCRIPT_VOID; +} + +scriptVar CfgGroup::script_vcpu_cfgGetName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid)); + + if (cg) + { + return MAKE_SCRIPT_STRING(cg->getAttributeName()); + } + return MAKE_SCRIPT_STRING(L""); +} + +scriptVar CfgGroup::script_vcpu_cfgGetGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid)); + if (cg) + return MAKE_SCRIPT_STRING(cg->getCfgGuid()); + return MAKE_SCRIPT_STRING(L""); +} + + +scriptVar CfgGroup::script_vcpu_onCfgChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS0(o, cfgGroupController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +CfgGroupScriptController _cfgGroupController; +CfgGroupScriptController *cfgGroupController = &_cfgGroupController; + +// -- Functions table ------------------------------------- +function_descriptor_struct CfgGroupScriptController::exportedFunction[] = { + {L"cfgGetInt", 0, (void*)CfgGroup::script_vcpu_cfgGetInt }, + {L"cfgSetInt", 1, (void*)CfgGroup::script_vcpu_cfgSetInt }, + {L"cfgGetFloat", 0, (void*)CfgGroup::script_vcpu_cfgGetFloat }, + {L"cfgSetFloat", 1, (void*)CfgGroup::script_vcpu_cfgSetFloat }, + {L"cfgGetString", 0, (void*)CfgGroup::script_vcpu_cfgGetString }, + {L"cfgSetString", 1, (void*)CfgGroup::script_vcpu_cfgSetString }, + {L"onCfgChanged", 0, (void*)CfgGroup::script_vcpu_onCfgChanged }, + {L"cfgGetName", 0, (void*)CfgGroup::script_vcpu_cfgGetName }, + {L"cfgGetGuid", 0, (void*)CfgGroup::script_vcpu_cfgGetGuid}, + }; + +/*SET_HIERARCHY(Group, SCRIPT_LAYOUT); +SET_HIERARCHY2(Group, SCRIPT_LAYOUT, LAYOUT_SCRIPTPARENT);*/ + +const wchar_t *CfgGroupScriptController::getClassName() +{ + return L"CfgGroup"; +} + +const wchar_t *CfgGroupScriptController::getAncestorClassName() +{ + return L"Group"; +} + +int CfgGroupScriptController::getInstantiable() +{ + return 1; +} + +ScriptObject *CfgGroupScriptController::instantiate() +{ + return NULL; +} + +int CfgGroupScriptController::getNumFunctions() +{ + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *CfgGroupScriptController::getExportedFunctions() +{ + return exportedFunction; +} + +GUID CfgGroupScriptController::getClassGuid() +{ + return cfgGroupGuid; +} + +wchar_t CfgGroup::txt[512] = L""; + +#endif // config diff --git a/Src/Wasabi/api/skin/widgets/group.h b/Src/Wasabi/api/skin/widgets/group.h new file mode 100644 index 00000000..186541f6 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/group.h @@ -0,0 +1,365 @@ +#ifndef __GROUP_H +#define __GROUP_H + +#ifndef _NOSTUDIO + +class Group; +class Container; +class Layout; +class CfgItem; +class CfgGroup; +class SRegion; + +#include <bfc/tlist.h> +#include <bfc/depview.h> +#include <api/wnd/wndclass/embeddedxui.h> +#include <api/wnd/wndclass/clickwnd.h> +#include <api/wnd/wndclass/buttwnd.h> +#include <tataki/bitmap/bitmap.h> +#include <tataki/region/region.h> +#ifdef WASABI_COMPILE_CONFIG +#include <api/config/items/cfgitem.h> +#endif // wasabi_compile_config + +#include <api/wndmgr/container.h> + +#endif // _nostudio + +#include <api/script/script.h> +#include <api/script/scriptobj.h> +#include <api/script/objects/guiobj.h> + +// {80F0F8BD-1BA5-42a6-A093-3236A00C8D4A} +static const GUID cfgGroupGuid = +{ 0x80f0f8bd, 0x1ba5, 0x42a6, { 0xa0, 0x93, 0x32, 0x36, 0xa0, 0xc, 0x8d, 0x4a } }; + +#define RESIZE_MINW 96 +#define RESIZE_MINH 24 + +class XmlObject; + +class GroupScriptController : public GuiObjectScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + 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(); + virtual ScriptObject *cast(ScriptObject *, GUID g); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern GroupScriptController *groupController; + +class XuiParam +{ + public: + XuiParam(const wchar_t *_param, const wchar_t *_value) : param(_param), value(_value) {} + virtual ~XuiParam() {} + StringW param; + StringW value; +}; + +#define GROUP_PARENT EmbeddedXuiObject + +class Group : public GROUP_PARENT +{ +public: + Group(); + virtual ~Group(); + + int onPaint(Canvas *canvas); + + virtual int onResize(); + virtual int onPostedMove(); + virtual int onInit(); + virtual Container *getParentContainer(); + virtual int childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2); + + virtual void setBaseTexture(const wchar_t *b, int regis=1); + virtual SkinBitmap *getBaseTexture(); + virtual ifc_window *getBaseTextureWindow(); + + virtual int setXmlParam(const wchar_t *paramname, const wchar_t *strvalue); + virtual int setXuiParam(int _xuihandle, int xuiid, const wchar_t *paramname, const wchar_t *strvalue); + virtual api_region *getRegion(); + virtual void setRegion(api_region *r); + void reloadDefaults(); + virtual int onGroupChange(const wchar_t *id); + virtual void autoResize(); + virtual void startScripts(); + + void onCreateObject(GuiObject *o); + GuiObject *getObject(const wchar_t *id); + + void sendNotifyToAllChildren(int notifymsg, intptr_t param1, intptr_t param2); + + int isDeleting() { return deleting; } + + void updatePos(GuiObject *o, RECT *r=NULL); + + AutoSkinBitmap *background; + int x, y; +#ifdef _WIN32 + LPARAM wndHolder_getParentParam(int i=0); +#endif + + virtual void setDesignWidth(int w); + virtual void setDesignHeight(int h); + virtual int getDesignWidth(); + virtual int getDesignHeight(); + + virtual void invalidateWindowRegion(); + virtual void setRegionOp(int o); + virtual void setGroupContent(const wchar_t *id, SkinItem *specific_item, int scripts_enabled); + virtual const wchar_t *getGroupContentId(); + virtual SkinItem *getGroupContentSkinItem(); + virtual void setAutoWidthSource(const wchar_t *obj); + virtual void setAutoHeightSource(const wchar_t *obj); + + virtual void cancelCapture() {}; + virtual int getPreferences(int what); + + virtual const wchar_t *vcpu_getClassName(); + virtual ScriptObjectController *vcpu_getController() { return groupController; } + + int getNumObjects(); + ifc_window *enumObjects(int i); + + void addChild(GuiObject *g); + void removeChild(GuiObject *g); + +#ifdef WASABI_COMPILE_WNDMGR + virtual void mouseResize(int x, int y, int resizeway);// screen coords! + virtual void beginMove(); + virtual void beginScale(); + virtual void beginResize(); + virtual void endMove(); + virtual void endScale(); + virtual void endResize(); +#endif + + virtual int getAutoWidth(void); + virtual int getAutoHeight(void); + + virtual int isLayout(); + + void setDrawBackground(int t); + int getDrawBackground(void); + +#ifdef WASABI_COMPILE_CONFIG + static int isCfgGroup(Group *ptr); +#endif + + void addScript(int scriptid); + void deleteScripts(); + int enumScript(int n); + int getNumScripts(); + virtual int isDesktopAlphaSafe(); + virtual int isTransparencySafe(int excludeme=0); + + static int isGroup(Group *o); + const wchar_t *getBackgroundStr(); + int getWidthBasedOn(GuiObject *o=NULL); + int getHeightBasedOn(GuiObject *o=NULL); + + void fixPosition(); + + const wchar_t *embeddedxui_getEmbeddedObjectId() { return xui_embedded_id; } + virtual void onFillGroup(); + virtual int onUnknownXuiParam(const wchar_t *xmlattributename, const wchar_t *value); + + virtual ScriptObject *script_cast(GUID g); + + virtual void onMinMaxEnforcerChanged(); + virtual int isTransparencyForcedOff() { return 0; } + +protected: + /*static */void CreateXMLParameters(int master_handle); + static PtrList<CfgGroup> cfggrouplist; + +private: + StringW basetextureStr; + StringW xui_embedded_id; + + void invalidateScaledReg(); + void ensureScaledRegValid(); + + int resizing; + int size_w,size_h; + int cX,cY; + int captured; + POINT mousepos; + int propagatesize; + + PtrList<XuiParam> xuiparams; + + int moving; + int mover; + int drawbackground; + RECT oldRect; + int groupmaxheight; + int groupmaxwidth; + int groupminheight; + int groupminwidth; + int lockminmax; +// int regionop; + TList<int> scripts; + RegionI *subtractedreg; + static PtrList<Group> groups; + StringW backgroundstr; + StringW instanceid; + RegionI *reg; + RegionI *scaledreg; + int scaledregionvalid; + int autoregionop; + StringW content_id; + SkinItem *content_item; + int no_init_on_addchild; + StringW autoheightsource; + StringW autowidthsource; + GuiObject *lastheightsource; + GuiObject *lastwidthsource; + int lastgetwidthbasedon, lastgetheightbasedon; + + int default_w, default_h; + int design_w, design_h; + int scripts_enabled; + int xuihandle; + static XMLParamPair groupParams[]; +protected: + enum { + XUIGROUP_INSTANCEID=0, + XUIGROUP_BACKGROUND, + XUIGROUP_DRAWBACKGROUND, + XUIGROUP_DEFAULT_W, + XUIGROUP_DEFAULT_H, + XUIGROUP_MAXIMUM_H, + XUIGROUP_MAXIMUM_W, + XUIGROUP_MINIMUM_H, + XUIGROUP_MINIMUM_W, + XUIGROUP_PROPAGATESIZE, + XUIGROUP_LOCKMINMAX, + XUIGROUP_NAME, + XUIGROUP_AUTOWIDTHSOURCE, + XUIGROUP_AUTOHEIGHTSOURCE, + XUIGROUP_EMBED_XUI, + XUIGROUP_XUITAG, + XUIGROUP_INHERIT_GROUP, + XUIGROUP_INHERIT_CONTENT, + XUIGROUP_DESIGN_W, + XUIGROUP_DESIGN_H, + XUIGROUP_NUMPARAMS, + }; + +// FG> +// -- SCRIPT ----------------------------------------------------- +private: + PtrList<ScriptObject> script_objects; + PtrList<GuiObject> gui_objects; + int deleting; + int skinpart; + int alpha; + int disable_update_pos; + +public: + void addObject(GuiObject *o); + void removeObject(GuiObject *o); + void setSkinPartId(int i) { skinpart = i; } + int getSkinPartId() { return skinpart; } + + static scriptVar script_vcpu_getObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj); + static scriptVar script_vcpu_getNumObjects(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_enumObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i); + static scriptVar script_vcpu_onCreateObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar ob); + static scriptVar script_vcpu_getMousePosX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_getMousePosY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_subtractRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg); + static scriptVar script_vcpu_isLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_autoResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + + static void instantiate(Layout *l); + +}; + +extern const wchar_t groupXuiObjectStr[]; +extern char groupXuiSvcName[]; +class GroupXuiSvc : public XuiObjectSvc<Group, groupXuiObjectStr, groupXuiSvcName> {}; + + +#ifdef WASABI_COMPILE_CONFIG + +class CfgGroupScriptController : 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(); + + private: + + static function_descriptor_struct exportedFunction[]; +}; + +extern CfgGroupScriptController *cfgGroupController; + +class CfgGroup : public Group, public DependentViewerTPtr<CfgItem> { + public: + + CfgGroup(); + virtual ~CfgGroup(); + + void setAttr(CfgItem *item, const wchar_t *name); + const wchar_t *vcpu_getClassName(); + virtual ScriptObjectController *vcpu_getController() { return cfgGroupController; } + + virtual int viewer_onEvent(CfgItem *item, int event, intptr_t param, void *ptr, size_t ptrlen); + virtual void dataChanged(); + + CfgItem *getCfgItem(); + const wchar_t *getAttributeName(); + const wchar_t *getCfgGuid() { return cfgguid; } + virtual int onInit(); + + static scriptVar script_vcpu_cfgGetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_cfgSetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v); + static scriptVar script_vcpu_cfgGetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_cfgSetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v); + static scriptVar script_vcpu_cfgGetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_cfgSetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v); + static scriptVar script_vcpu_cfgGetName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_cfgGetGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_onCfgChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + + private: + + CfgItem *cfgitem; + StringW attrname; + StringW cfgguid; + static wchar_t txt[512]; +}; + +extern const wchar_t cfgGroupXuiObjectStr[]; +extern char cfgGroupXuiSvcName[]; +class CfgGroupXuiSvc : public XuiObjectSvc<CfgGroup, cfgGroupXuiObjectStr, cfgGroupXuiSvcName> {}; + +#endif // wasabi_compile_config + + +#endif // group.h diff --git a/Src/Wasabi/api/skin/widgets/groupclickwnd.cpp b/Src/Wasabi/api/skin/widgets/groupclickwnd.cpp new file mode 100644 index 00000000..119885bb --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/groupclickwnd.cpp @@ -0,0 +1,84 @@ +#include <precomp.h> +#include "groupclickwnd.h" +#include <api/script/objects//guiobject.h> +#include <api/wnd/notifmsg.h> + +GroupClickWnd::GroupClickWnd() { + trap = NULL; + inarea = 0; +} + +GroupClickWnd::~GroupClickWnd() { + delete trap; +} + +void GroupClickWnd::abstract_onNewContent() { + delete trap; + trap = NULL; + + if (!abstract_getContent()) return; + + GuiObject *mousetrap = abstract_getContent()->guiobject_findObject(L"mousetrap"); + + if (mousetrap != NULL) + trap = new MouseTrap(this, mousetrap->guiobject_getScriptObject()); +} + +void GroupClickWnd::groupclick_onLeftPush() { + notifyParent(ChildNotify::BUTTON_LEFTPUSH); +} + +void GroupClickWnd::groupclick_onRightPush() { + notifyParent(ChildNotify::BUTTON_RIGHTPUSH); +} + +void GroupClickWnd::content_onLeftButtonDown() { + notifyParent(ChildNotify::CLICKWND_LEFTDOWN); +} + +void GroupClickWnd::content_onLeftButtonUp() { + notifyParent(ChildNotify::CLICKWND_LEFTUP); + if (inarea) groupclick_onLeftPush(); +} + +void GroupClickWnd::content_onRightButtonDown() { + notifyParent(ChildNotify::CLICKWND_RIGHTDOWN); +} + +void GroupClickWnd::content_onRightButtonUp() { + notifyParent(ChildNotify::CLICKWND_RIGHTUP); + if (inarea) groupclick_onRightPush(); +} + +void GroupClickWnd::content_onEnterArea() { + inarea = 1; +} + +void GroupClickWnd::content_onLeaveArea() { + inarea = 0; +} + + +void MouseTrap::hook_onLeftButtonDown(int x, int y) { + window->content_onLeftButtonDown(); +} + +void MouseTrap::hook_onLeftButtonUp(int x, int y) { + window->content_onLeftButtonUp(); +} + +void MouseTrap::hook_onRightButtonDown(int x, int y) { + window->content_onRightButtonDown(); +} + +void MouseTrap::hook_onRightButtonUp(int x, int y) { + window->content_onRightButtonUp(); +} + +void MouseTrap::hook_onEnterArea() { + window->content_onEnterArea(); +} + +void MouseTrap::hook_onLeaveArea() { + window->content_onLeaveArea(); +} diff --git a/Src/Wasabi/api/skin/widgets/groupclickwnd.h b/Src/Wasabi/api/skin/widgets/groupclickwnd.h new file mode 100644 index 00000000..591f0c7c --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/groupclickwnd.h @@ -0,0 +1,226 @@ +/* This class simulates a very basic button thru the use of a group. the group needs to have a guiobject (ie: a transparent layer) + with id "mousetrap" on top of the rest of its content. */ + +#ifndef __GROUPCLICKWND_H +#define __GROUPCLICKWND_H + +#include <api/wnd/wndclass/guiobjwnd.h> +#include <api/script/objects/c_script/h_guiobject.h> + +class MouseTrap; + + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class GroupClickWnd : public GuiObjectWnd { + + public: + + + /** + Method + + @see + @ret + @param + */ + GroupClickWnd(); + + /** + Method + + @see + @ret + @param + */ + virtual ~GroupClickWnd(); + + + /** + Method + + @see + @ret + @param + */ + virtual void content_onLeftButtonDown(); + + /** + Method + + @see + @ret + @param + */ + virtual void content_onLeftButtonUp(); + + /** + Method + + @see + @ret + @param + */ + virtual void content_onRightButtonDown(); + + /** + Method + + @see + @ret + @param + */ + virtual void content_onRightButtonUp(); + + /** + Method + + @see + @ret + @param + */ + virtual void content_onEnterArea(); + + /** + Method + + @see + @ret + @param + */ + virtual void content_onLeaveArea(); + + + /** + Method + + @see + @ret + @param + */ + virtual void groupclick_onLeftPush(); + + /** + Method + + @see + @ret + @param + */ + virtual void groupclick_onRightPush(); + + + /** + Method + + @see + @ret + @param + */ + virtual void abstract_onNewContent(); + + private: + + int inarea; + MouseTrap *trap; +}; + + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class MouseTrap : public H_GuiObject { + public: + + + /** + Method + + @see + @ret + @param + */ + MouseTrap(GroupClickWnd *w, ScriptObject *obj) : H_GuiObject(obj), window(w) { } + + /** + Method + + @see + @ret + @param + */ + virtual ~MouseTrap() {} + + + /** + Method + + @see + @ret + @param + */ + virtual void hook_onLeftButtonDown(int x, int y); + + /** + Method + + @see + @ret + @param + */ + virtual void hook_onLeftButtonUp(int x, int y); + + /** + Method + + @see + @ret + @param + */ + virtual void hook_onRightButtonDown(int x, int y); + + /** + Method + + @see + @ret + @param + */ + virtual void hook_onRightButtonUp(int x, int y); + + /** + Method + + @see + @ret + @param + */ + virtual void hook_onEnterArea(); + + /** + Method + + @see + @ret + @param + */ + virtual void hook_onLeaveArea(); + + private: + + GroupClickWnd *window; +}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/grouplist.cpp b/Src/Wasabi/api/skin/widgets/grouplist.cpp new file mode 100644 index 00000000..c082abc5 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/grouplist.cpp @@ -0,0 +1,228 @@ +#include <precomp.h> +#include <api/skin/widgets/group.h> +#include <api/skin/groupmgr.h> +#include "grouplist.h" +#include <api/config/items/cfgitem.h> +#include <api/wnd/notifmsg.h> +const wchar_t groupListXuiObjectStr[] = L"GroupList"; // This is the xml tag +char groupListXuiSvcName[] = "GroupList xui object"; // this is the name of the xuiservice + +GroupList::GroupList() { + getScriptObject()->vcpu_setInterface(grouplistGuid, (void *)static_cast<GroupList *>(this)); + getScriptObject()->vcpu_setClassName(L"GroupList"); + getScriptObject()->vcpu_setController(grouplistController); + scrollY = 0; + maxheight = 0; + maxwidth = 0; + redraw=1; +} + +GroupList::~GroupList() { + // todo: unload group scripts + for (int i=0;i<groups.getNumItems();i++) + GroupMgr::destroy(groups.enumItem(i)); + groups.removeAll(); +} + +Group *GroupList::instantiate(const wchar_t *id, int n) { + Group *last=NULL; + RECT r; + getClientRect(&r); + + for (int i=0;i<n;i++) { + + last = GroupMgr::instantiate(id); + last->setParent(this); + last->init(this); + + groups.addItem(last); + } + + reposChildren(); + notifyParent(ChildNotify::AUTOWHCHANGED); + invalidate(); + + return last; +} + +int GroupList::onResize() { + int r = GROUPLIST_PARENT::onResize(); + reposChildren(); + return r; +} + +Group *GroupList::enumItem(int n) { + return groups.enumItem(n); +} + +void GroupList::removeAll() { + for (int i=0;i<groups.getNumItems();i++) + GroupMgr::destroy(groups.enumItem(i)); + groups.removeAll(); + notifyParent(ChildNotify::AUTOWHCHANGED); + if (!redraw) return; + invalidate(); +} + +int GroupList::getNumItems() { + return groups.getNumItems(); +} + +void GroupList::scrollToPercent(int p) { + RECT r; + getClientRect(&r); + int height = r.bottom - r.top; + if (height > maxheight) return; + scrollTo((int)((float)(maxheight - height) * (float)p / 100.0f)); +} + +void GroupList::scrollTo(int y) { + scrollY = y; + if (!redraw) return; + invalidate(); +} + +void GroupList::reposChildren() { + if (!redraw) return; + + RECT r; + getClientRect(&r); + + int ch = -scrollY+r.top; + maxheight = 0; + + for (int i=0;i<getNumItems();i++) { + + Group *g = enumItem(i); + + int h = g->getPreferences(SUGGESTED_H); + int w = g->getPreferences(SUGGESTED_W); + + RECT cr; + getClientRect(&cr); + cr.top = ch; + cr.bottom = cr.top + h; + + g->resize(&cr); + maxheight += h; + if (maxwidth < w) maxwidth = w; + ch += h; + } + +} + +void GroupList::setRedraw(int i) { + if (redraw == i) return; + redraw=i; + if (redraw) { + notifyParent(ChildNotify::AUTOWHCHANGED); + reposChildren(); + invalidate(); + } +} + +int GroupList::getPreferences(int what) { + if (what == SUGGESTED_H) { reposChildren(); return maxheight; } + if (what == SUGGESTED_W) { reposChildren(); return maxwidth; } + return GROUPLIST_PARENT::getPreferences(what); +} + + +GroupListScriptController _grouplistController; +GroupListScriptController *grouplistController = &_grouplistController; + + +// -- Functions table ------------------------------------- +function_descriptor_struct GroupListScriptController ::exportedFunction[] = { + {L"instantiate", 2, (void*)GroupList::script_vcpu_instantiate }, + {L"getNumItems", 0, (void*)GroupList::script_vcpu_getNumItems }, + {L"enumItem", 1, (void*)GroupList::script_vcpu_enumItem }, + {L"removeAll", 0, (void*)GroupList::script_vcpu_removeAll }, + {L"scrollToPercent", 1, (void*)GroupList::script_vcpu_scrollToPercent }, + {L"setRedraw", 1, (void*)GroupList::script_vcpu_setRedraw}, +}; + +const wchar_t *GroupListScriptController ::getClassName() { + return L"GroupList"; +} + +const wchar_t *GroupListScriptController ::getAncestorClassName() { + return L"GuiObject"; +} + +ScriptObject *GroupListScriptController::instantiate() { + GroupList *gl = new GroupList; + ASSERT(gl != NULL); + return gl->getScriptObject(); +} + +void GroupListScriptController::destroy(ScriptObject *o) { + GroupList *gl = static_cast<GroupList *>(o->vcpu_getInterface(grouplistGuid)); + ASSERT(gl != NULL); + delete gl; +} + +void *GroupListScriptController::encapsulate(ScriptObject *o) { + return NULL; // no encapsulation for grouplist yet +} + +void GroupListScriptController::deencapsulate(void *o) { +} + + +int GroupListScriptController ::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *GroupListScriptController ::getExportedFunctions() { + return exportedFunction; +} + +GUID GroupListScriptController ::getClassGuid() { + return grouplistGuid; +} + +scriptVar GroupList::script_vcpu_instantiate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar id, scriptVar n) { + SCRIPT_FUNCTION_INIT + GroupList *gl = static_cast<GroupList *>(o->vcpu_getInterface(grouplistGuid)); + Group *g = NULL; + if (gl) g = gl->instantiate(GET_SCRIPT_STRING(id), GET_SCRIPT_INT(n)); + return MAKE_SCRIPT_OBJECT(g ? g->getScriptObject() : NULL); +} + +scriptVar GroupList::script_vcpu_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + GroupList *gl = static_cast<GroupList *>(o->vcpu_getInterface(grouplistGuid)); + if (gl) return MAKE_SCRIPT_INT(gl->getNumItems()); + RETURN_SCRIPT_ZERO; +} + +scriptVar GroupList::script_vcpu_enumItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n) { + SCRIPT_FUNCTION_INIT + GroupList *gl = static_cast<GroupList *>(o->vcpu_getInterface(grouplistGuid)); + Group *g = NULL; + if (gl) g = gl->enumItem(GET_SCRIPT_INT(n)); + return MAKE_SCRIPT_OBJECT(g ? g->getScriptObject() : NULL); +} + +scriptVar GroupList::script_vcpu_removeAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + GroupList *gl = static_cast<GroupList *>(o->vcpu_getInterface(grouplistGuid)); + if (gl) gl->removeAll(); + RETURN_SCRIPT_VOID; +} + +scriptVar GroupList::script_vcpu_scrollToPercent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n) { + SCRIPT_FUNCTION_INIT + GroupList *gl = static_cast<GroupList *>(o->vcpu_getInterface(grouplistGuid)); + if (gl) gl->scrollToPercent(GET_SCRIPT_INT(n)); + RETURN_SCRIPT_VOID; +} + +scriptVar GroupList::script_vcpu_setRedraw(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n) { + SCRIPT_FUNCTION_INIT + GroupList *gl = static_cast<GroupList *>(o->vcpu_getInterface(grouplistGuid)); + if (gl) gl->setRedraw(GET_SCRIPT_INT(n)); + RETURN_SCRIPT_VOID; +} + diff --git a/Src/Wasabi/api/skin/widgets/grouplist.h b/Src/Wasabi/api/skin/widgets/grouplist.h new file mode 100644 index 00000000..9eebf6d4 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/grouplist.h @@ -0,0 +1,79 @@ +//PORTABLE +#ifndef _GROUPLIST_H +#define _GROUPLIST_H + +#include <api/script/objects/guiobj.h> +#include <api/wnd/wndclass/guiobjwnd.h> +#include <bfc/ptrlist.h> + +// {01E28CE1-B059-11d5-979F-E4DE6F51760A} +static const GUID grouplistGuid = +{ 0x1e28ce1, 0xb059, 0x11d5, { 0x97, 0x9f, 0xe4, 0xde, 0x6f, 0x51, 0x76, 0xa } }; + +#define GROUPLIST_PARENT GuiObjectWnd + +class GroupListScriptController: public GuiObjectScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + 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); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern GroupListScriptController *grouplistController; + +class GroupList : public GROUPLIST_PARENT { +public: + GroupList(); + virtual ~GroupList(); + + Group *instantiate(const wchar_t *id, int n); + void removeAll(); + Group *enumItem(int n); + int getNumItems(); + void scrollToPercent(int p); + void scrollTo(int y); + void setRedraw(int i); + void reposChildren(); + virtual int onResize(); + + virtual int getPreferences(int what); + +private: + + void insert(const wchar_t *id, int where); + +public: + + static scriptVar script_vcpu_instantiate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar id, scriptVar n); + static scriptVar script_vcpu_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_enumItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n); + static scriptVar script_vcpu_removeAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_scrollToPercent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n); + static scriptVar script_vcpu_setRedraw(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n); + + PtrList<Group> groups; + int scrollY; + int maxheight; + int maxwidth; + int redraw; +}; + +extern const wchar_t groupListXuiObjectStr[]; +extern char groupListXuiSvcName[]; +class GroupListXuiSvc : public XuiObjectSvc<GroupList, groupListXuiObjectStr, groupListXuiSvcName> {}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/grouptgbutton.cpp b/Src/Wasabi/api/skin/widgets/grouptgbutton.cpp new file mode 100644 index 00000000..b0f22430 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/grouptgbutton.cpp @@ -0,0 +1,109 @@ +#include <precomp.h> +#include "grouptgbutton.h" +#include <api/script/objects/guiobject.h> +#include <api/wnd/notifmsg.h> + +GroupToggleButton::GroupToggleButton() { + status = STATUS_OFF; +} + +GroupToggleButton::~GroupToggleButton() { +} + +void GroupToggleButton::setGroups(const wchar_t *_on, const wchar_t *_off) { + on_id = _on; + on.setContent(on_id); + off_id = _off; + off.setContent(off_id); +} + +int GroupToggleButton::onInit() { + int rt = GROUPTOGGLEBUTTON_PARENT::onInit(); + initGroups(); + return rt; +} + +void GroupToggleButton::initGroups() { + on.setStartHidden(status == STATUS_ON ? 0 : 1); off.setStartHidden(status == STATUS_ON ? 1 : 0); + on.setContent(on_id); + off.setContent(off_id); + on.setParent(this); off.setParent(this); + on.init(this); off.init(this); + rootwndholder_setRootWnd(status == STATUS_ON ? &on : &off); +} + +int GroupToggleButton::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2) { + if (child == &on || child == &off) { + switch (msg) { + case ChildNotify::BUTTON_LEFTPUSH: { + if (wantFullClick()) grouptoggle_onLeftPush(); + return 1; + } + case ChildNotify::BUTTON_RIGHTPUSH: { + if (wantFullClick()) grouptoggle_onRightPush(); + return 1; + } + case ChildNotify::CLICKWND_LEFTDOWN: { + if (!wantFullClick()) grouptoggle_onLeftPush(); + return 1; + } + case ChildNotify::CLICKWND_RIGHTDOWN: { + if (!wantFullClick()) grouptoggle_onRightPush(); + return 1; + } + } + } + return GROUPTOGGLEBUTTON_PARENT::childNotify(child, msg, param1, param2); +} + +void GroupToggleButton::toggle() { + if (status == STATUS_OFF) { + if (isInited()) { + off.setVisible(0); + on.setVisible(1); + rootwndholder_setRootWnd(&on); + } + status = STATUS_ON; + } else { + if (isInited()) { + on.setVisible(0); + off.setVisible(1); + rootwndholder_setRootWnd(&off); + } + status = STATUS_OFF; + } + notifyParent(ChildNotify::GROUPCLICKTGBUTTON_TOGGLE, status); +} + +void GroupToggleButton::setStatus(int s) { + if (s != status) + toggle(); +} + +int GroupToggleButton::wantFullClick() { + return 0; +} + +void GroupToggleButton::grouptoggle_onLeftPush() { + notifyParent(ChildNotify::GROUPCLICKTGBUTTON_CLICKED); + if (!wantAutoToggle()) return; + if (status == STATUS_ON && !off_id.isempty() || status == STATUS_OFF && !on_id.isempty()) + toggle(); +} + +void GroupToggleButton::grouptoggle_onRightPush() { +} + +GroupClickWnd *GroupToggleButton::enumGroups(int n) { + if (n == 0) return &on; + if (n == 1) return &off; + return NULL; +} + +int GroupToggleButton::getNumGroups() { + int i=0; + i++; + i++; + return i; +} + diff --git a/Src/Wasabi/api/skin/widgets/grouptgbutton.h b/Src/Wasabi/api/skin/widgets/grouptgbutton.h new file mode 100644 index 00000000..c9fc8757 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/grouptgbutton.h @@ -0,0 +1,101 @@ +#ifndef __GROUPTGBUTTON_H +#define __GROUPTGBUTTON_H + +#include <api/skin/widgets/groupclickwnd.h> +#include <api/wnd/wndclass/guiobjwnd.h> + +#define GROUPTOGGLEBUTTON_PARENT GuiObjectWnd + +#define STATUS_OFF 0 +#define STATUS_ON 1 + + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class GroupToggleButton : public GROUPTOGGLEBUTTON_PARENT { + + public: + + + /** + Method + + @see + @ret + @param + */ + GroupToggleButton(); + + /** + Method + + @see + @ret + @param + */ + virtual ~GroupToggleButton(); + + + /** + Method + + @see + @ret + @param + */ + virtual int onInit(); + + /** + Method + + @see + @ret + @param + */ + virtual int childNotify(ifc_window *child, int msg, intptr_t param1=0, intptr_t param2=0); + + + virtual void setGroups(const wchar_t *on, const wchar_t *off); + + + virtual void toggle(); + + virtual int wantFullClick(); + + + virtual void grouptoggle_onLeftPush(); + + virtual void grouptoggle_onRightPush(); + + + virtual void setStatus(int s); + + virtual int getStatus() { return status; } + + virtual int wantAutoToggle() { return 1; } + + virtual GroupClickWnd *enumGroups(int n); + + + virtual int getNumGroups(); + + private: + + + void initGroups(); + + GroupClickWnd on; + GroupClickWnd off; + + StringW on_id, off_id; + + int status; +}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/grouptips.cpp b/Src/Wasabi/api/skin/widgets/grouptips.cpp new file mode 100644 index 00000000..c066dca0 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/grouptips.cpp @@ -0,0 +1,92 @@ +#include "precomp.h" +#include <bfc/wasabi_std.h> +#include "grouptips.h" +#include <api/wnd/api_window.h> +#include <api/script/objects/c_script/c_group.h> +#include <api/script/objects/c_script/c_text.h> +#include <api/script/scriptguid.h> +#include <api/script/objects/guiobject.h> +#ifndef _WASABIRUNTIME + +BEGIN_SERVICES(GroupTips_Svc); +DECLARE_SERVICETMULTI(svc_toolTipsRenderer, GroupTips); +END_SERVICES(GroupTips_Svc, _GroupTips_Svc); + +#ifdef _X86_ +extern "C" { int _link_GroupTipsSvc; } +#else +extern "C" { int __link_GroupTipsSvc; } +#endif + +#endif + +GroupTips::GroupTips() +{ + tipwnd = NULL; +} + +GroupTips::~GroupTips() +{ + if (tipwnd) + WASABI_API_SKIN->group_destroy(tipwnd); +} + +int GroupTips::spawnTooltip(const wchar_t *text) +{ + int x, y; + Wasabi::Std::getMousePos(&x, &y); + + ifc_window *wnd = WASABI_API_SKIN->group_create_layout(L"wasabi.tooltip.group"); + + if (wnd) + { + wnd->setStartHidden(1); + wnd->setParent(WASABI_API_WND->main_getRootWnd()); + wnd->init(WASABI_API_WND->main_getRootWnd(), TRUE); + wnd->getGuiObject()->guiobject_onStartup(); + + RECT r; + wnd->getClientRect(&r); + int w = r.right - r.left; + int h = r.bottom - r.top; + + y -= h; // move tip above mouse by default + + POINT pt = {x, y}; + RECT vpr; + + Wasabi::Std::getViewport(&vpr, &pt, NULL, NULL); + + if (x + w > vpr.right) x -= vpr.right - w; + if (x < vpr.left) x = vpr.left; + if (x + w > vpr.right) + { + w = vpr.right - vpr.left; + x = 0; + } + if (y + h > vpr.bottom) y -= vpr.bottom - w; + if (y < vpr.top) y = vpr.top; + if (y + h > vpr.bottom) + { + h = vpr.bottom - vpr.top; + y = 0; + } + + wnd->resize(x, y, w, h); + + ScriptObject *group = static_cast<ScriptObject *>(wnd->getInterface(scriptObjectGuid)); + if (group) + { + ScriptObject *txt = C_Group(group).getObject(L"tooltip.text"); + if (txt) + C_Text(txt).setText(text); + } + + // tooltips should always be on top otherwise they're pointless <dro> + Wasabi::Std::Wnd::setTopmost(wnd->getOsWindowHandle(), TRUE); + wnd->setVisible(1); + + tipwnd = wnd; + } + return 1; +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/grouptips.h b/Src/Wasabi/api/skin/widgets/grouptips.h new file mode 100644 index 00000000..0676b1e7 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/grouptips.h @@ -0,0 +1,23 @@ +#ifndef __GROUPTIPS_H +#define __GROUPTIPS_H + +#include <api/service/svcs/svc_tooltips.h> +#include <bfc/ptrlist.h> +#include <api/timer/timerclient.h> + +class ifc_window; + +int groupTipsTimerProc(int id, void *data1, void *data2); + +class GroupTips : public svc_toolTipsRendererI/*, public TimerClientI*/ { +public: + GroupTips(); + virtual ~GroupTips(); + static const char *getServiceName() { return "Group tooltip renderer"; } + + virtual int spawnTooltip(const wchar_t *text); +private: + ifc_window *tipwnd; +}; + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/guiradiogroup.cpp b/Src/Wasabi/api/skin/widgets/guiradiogroup.cpp new file mode 100644 index 00000000..a2fc3d68 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/guiradiogroup.cpp @@ -0,0 +1,36 @@ +#include <precomp.h> +#include "guiradiogroup.h" +#include <api/script/objects/c_script/c_button.h> +#include <api/script/objects/guiobject.h> +#include <api/script/scriptguid.h> + +void GuiRadioGroup::toggleChild(GuiObject *who) { + int i, num = children.getNumItems(); + for (i = 0; i < num; i++) { + GuiObject *childGuiObj = children.enumItem(i); + if (childGuiObj != NULL) { + GuiObject *toggleGuiObj = childGuiObj->guiobject_findObject(L"checkbox.toggle"); + if (toggleGuiObj != NULL) { + C_Button buttonObj(*toggleGuiObj); + if (childGuiObj != who) { + buttonObj.setActivated(0); + } + } + } + } +} + +void GuiRadioGroup::registerChild(GuiObject *who) { + children.addItem(who); +} + +int GuiRadioGroup::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) { + if (!_wcsicmp(action, L"REGISTER") && source != NULL) { + registerChild(static_cast<GuiObject *>(source->getInterface(guiObjectGuid))); + } else if (!_wcsicmp(action, L"TOGGLE")) { + toggleChild(static_cast<GuiObject *>(source->getInterface(guiObjectGuid))); + return 1; + } + return GUIRADIOGROUP_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source); +} + diff --git a/Src/Wasabi/api/skin/widgets/guiradiogroup.h b/Src/Wasabi/api/skin/widgets/guiradiogroup.h new file mode 100644 index 00000000..d1810593 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/guiradiogroup.h @@ -0,0 +1,53 @@ +#ifndef __GUIRADIOGROUP_H +#define __GUIRADIOGROUP_H + +#include <api/skin/nakedobject.h> +#include <bfc/ptrlist.h> +#include <bfc/string/StringW.h> + +#define GUIRADIOGROUP_PARENT NakedObject + + + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class GuiRadioGroup : public GUIRADIOGROUP_PARENT { + + public: + + + /** + Method + + @see + @ret + @param + */ + void toggleChild(GuiObject *who); + + /** + Method + + @see + @ret + @param + */ + void registerChild(GuiObject *who); + + // From BaseWnd + + + virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source); + + private: + + PtrList<GuiObject> children; +}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/historyeditbox.cpp b/Src/Wasabi/api/skin/widgets/historyeditbox.cpp new file mode 100644 index 00000000..bec191fc --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/historyeditbox.cpp @@ -0,0 +1,152 @@ +#include <precomp.h> +#include "historyeditbox.h" + +XMLParamPair HistoryEditBox::params[] = { + {HISTORYEDITBOX_SETNAVBUTTONS, L"NAVBUTTONS"}, // param is implemented by script +}; +HistoryEditBox::HistoryEditBox() { + history_pos = 0; + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); + + setXmlParam(L"navbuttons", L"1"); // so we need to set a default value in the xml param list +} + +void HistoryEditBox::CreateXMLParameters(int master_handle) +{ + //HISTORYEDITBOX_PARENT::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); +} + +HistoryEditBox::~HistoryEditBox() { + history.deleteAll(); +} + +void HistoryEditBox::history_forward() { + if (history_pos > 0 && !isListOpen()) { + history_pos--; + if (history_pos > 0) + setText(history.enumItem(history.getNumItems()-history_pos)->getValue(), 1); + } +} + +void HistoryEditBox::history_back() { + if (!isListOpen() && history_pos < history.getNumItems()) { + history_pos++; + setText(history.enumItem(history.getNumItems()-history_pos)->getValue(), 1); + } +} + +void HistoryEditBox::onEditKeyDown(int vk) { + HISTORYEDITBOX_PARENT::onEditKeyDown(vk); + if (Std::keyDown(VK_CONTROL)) return; + if (vk == VK_DOWN) { + history_forward(); + } else if (vk == VK_UP) { + history_back(); + } +} + +int HistoryEditBox::onInit() { + int r = HISTORYEDITBOX_PARENT::onInit(); +#ifdef WASABI_COMPILE_CONFIG + loadHistory(); +#endif + return r; +} + +void HistoryEditBox::dropdownlist_onCloseList() { + HISTORYEDITBOX_PARENT::dropdownlist_onCloseList(); + history_pos = 0; +} + +void HistoryEditBox::onPreOpenList() +{ + HISTORYEDITBOX_PARENT::onPreOpenList(); + addHistory(getText()); +} + +void HistoryEditBox::onEditEnter(const wchar_t *txt) +{ + HISTORYEDITBOX_PARENT::onEditEnter(txt); + if (Std::keyDown(VK_CONTROL)) return; + addHistory(txt); +} + +void HistoryEditBox::addHistory(const wchar_t *txt) +{ + HISTORYEDITBOX_PARENT::onEditEnter(txt); + history_pos = 0; + + if (!txt || !*txt) return; + + // yay multi-instances on unique history +#ifdef WASABI_COMPILE_CONFIG + loadHistory(0); +#endif + + foreach(history) + StringW *s = history.getfor(); + if (!_wcsicmp(s->getValue(), txt)) { + delete s; + history.removeByPos(foreach_index); + break; + } + endfor; + + history.addItem(new StringW(txt)); + + while (history.getNumItems() > 64) + { + StringW *s = history.enumItem(0); + delete s; + history.removeByPos(1); + } +#ifdef WASABI_COMPILE_CONFIG + saveHistory(); + loadHistory(1); +#endif +} + +#ifdef WASABI_COMPILE_CONFIG +void HistoryEditBox::loadHistory(int refill) { + history.deleteAll(); + wchar_t d[256] = {0}; + wchar_t c[WA_MAX_PATH] = {0}; + int i; + for (i=0;;i++) { + StringCbPrintfW(d,sizeof(d), L"%s_history_%d", getId(), i); + WASABI_API_CONFIG->getStringPrivate(d, c, WA_MAX_PATH, L""); + if (!*c) + break; + history.addItem(new StringW(c)); + } + if (refill) { + deleteAllItems(); + for (i=history.getNumItems()-1;i>=0;i--) { + addItem(history.enumItem(i)->getValue()); + } + } +} + +void HistoryEditBox::saveHistory() { + wchar_t d[256] = {0}; + int i; + for (i=0;i<history.getNumItems();i++) { + StringCbPrintfW(d, sizeof(d), L"%s_history_%d", getId(), i); + WASABI_API_CONFIG->setStringPrivate(d, history.enumItem(i)->getValue()); + } + StringCbPrintfW(d, sizeof(d), L"%s_history_%d", getId(), i); + WASABI_API_CONFIG->setStringPrivate(d, L""); +} +#endif + +int HistoryEditBox::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) { + int r = HISTORYEDITBOX_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source); + if (WCSCASEEQLSAFE(action, L"back")) history_back(); + if (WCSCASEEQLSAFE(action, L"forward")) history_forward(); + return r; +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/historyeditbox.h b/Src/Wasabi/api/skin/widgets/historyeditbox.h new file mode 100644 index 00000000..2a015738 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/historyeditbox.h @@ -0,0 +1,58 @@ +#ifndef __HISTORYEDITBOX_H +#define __HISTORYEDITBOX_H + +#include <api/skin/widgets/combobox.h> +#include <bfc/ptrlist.h> +#include <bfc/string/StringW.h> + +#define HISTORYEDITBOX_PARENT ComboBox + +class HistoryEditBox : public HISTORYEDITBOX_PARENT { + + public: + + HistoryEditBox(); + virtual ~HistoryEditBox(); + + virtual const wchar_t *dropdownlist_getMainGroupId() { return L"wasabi.historyeditbox.main.group"; } + virtual const wchar_t *dropdownlist_getListGroupId() { return L"wasabi.historyeditbox.list.group"; } + virtual const wchar_t *dropdownlist_getButtonId() { return L"historyeditbox.button"; } + virtual const wchar_t *dropdownlist_getListId() { return L"historyeditbox.list"; } + + virtual const wchar_t *combobox_getEditId() { return L"historyeditbox.edit"; } + + void onEditKeyDown(int vk); + void onEditEnter(const wchar_t *txt); + + virtual int wantAutoSort() { return 0; } + + virtual int wantDownOpenList() { return history_pos == 0; } + virtual void dropdownlist_onCloseList(); + virtual void onPreOpenList(); + virtual int onInit(); + virtual void addHistory(const wchar_t *txt); + + virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, ifc_window *source=NULL); + + void history_back(); + void history_forward(); + + enum { + HISTORYEDITBOX_SETNAVBUTTONS=0, + }; + +protected: + /*static */void CreateXMLParameters(int master_handle); + private: +static XMLParamPair params[]; +#ifdef WASABI_COMPILE_CONFIG + void saveHistory(); + void loadHistory(int refill=1); +#endif + + PtrList<StringW> history; + int history_pos; + int xuihandle; +}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/layer.cpp b/Src/Wasabi/api/skin/widgets/layer.cpp new file mode 100644 index 00000000..1a119563 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/layer.cpp @@ -0,0 +1,1727 @@ +#include <precomp.h> +#include "layer.h" +#include <api/wndmgr/resize.h> +#include <api/wnd/cwndtrack.h> +#ifdef WASABI_COMPILE_WNDMGR +#include <api/wndmgr/layout.h> +#include <api/wac/compon.h> +#endif +#ifdef WASABI_COMPILE_COMPONENTS +#include <api/script/objects/compoobj.h> +#endif +#include <api/skin/skinparse.h> +#if defined(WA3COMPATIBILITY) || defined(GEN_FF) +#include <api/skin/widgets/fx_dmove.h> +#endif +#include <api/script/objects/sregion.h> + +#include <api/script/script.h> +#include <api/script/scriptmgr.h> +#include <api/service/svcs/svc_action.h> +#include <api/script/vcpu.h> +#include <api/wnd/notifmsg.h> +#include <tataki/canvas/bltcanvas.h> +#include <api/wnd/PaintCanvas.h> + +#define SNAP_X 1 +#define SNAP_Y 1 +#define FX_TIMER 0x0A1C + +const wchar_t layerXuiObjectStr[] = L"Layer"; // This is the xml tag +char layerXuiSvcName[] = "Layer xui object"; // this is the name of the xuiservice + +XMLParamPair Layer::params[] = + { + {LAYER_SETMYCURSOR, L"CURSOR"}, + {LAYER_SETDBLCLICKACTION, L"DBLCLICKACTION"}, + {LAYER_DBLCLICKPARAM, L"DBLCLICKPARAM"}, + {LAYER_SETIMAGE, L"IMAGE"}, + {LAYER_SETINACTIVEIMAGE, L"INACTIVEIMAGE"}, + {LAYER_SETQUALITY, L"QUALITY"}, + {LAYER_SETREGION, L"REGION"}, + {LAYER_SETRESIZE, L"RESIZE"}, + {LAYER_SETSCALE, L"SCALE"}, + {LAYER_SETTILE, L"TILE"}, + + }; + +Layer::Layer() + : resizer(0), resizeway(0), scaler(0), scalerway(0), scaling(0), + rgn(NULL), secrgn(NULL), rgnclone(NULL), fx_wrap(0), fx_rect(0), + fx_dmove(NULL) +{ + getScriptObject()->vcpu_setInterface(layerGuid, (void *)static_cast<Layer *>(this)); + getScriptObject()->vcpu_setClassName(L"Layer"); + getScriptObject()->vcpu_setController(layerController); + resizerect = 1; + tiling = 0; + l_customcursor = false; + hasInactiveImage = 0; + fx_on = 0; + fx_bgfx = 0; + fx_grid_x = 16; + fx_grid_y = 16; + fx_bilinear = 1; + fx_alphamode = 0; + fx_delay = 35; + fx_timeron = 0; + fx_clear = 1; + fx_local = 1; + fx_realtime = 0; + last_w = last_h = -1; + getGuiObject()->guiobject_setMover(1); + setRectRgn(1); + xuihandle = newXuiHandle(); +CreateXMLParameters(xuihandle); + +} + +void Layer::CreateXMLParameters(int master_handle) +{ + //LAYER_PARENT::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); +} + +Layer::~Layer() +{ + WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SkinCallbackI*>(this)); + delete rgnclone; + delete rgn; + delete secrgn; + delete fx_dmove; +} + +int Layer::onInit() +{ + LAYER_PARENT::onInit(); + WASABI_API_SYSCB->syscb_registerCallback(static_cast<SkinCallbackI*>(this)); + return 1; +} + + +int Layer::onPaint(Canvas *canvas) +{ + PaintCanvas paintcanvas; + if (canvas == NULL) + { + if (!paintcanvas.beginPaint(this)) return 0; + canvas = &paintcanvas; + } + LAYER_PARENT::onPaint(canvas); + + if (!getBitmap()) return 0; + + int talpha = getPaintingAlpha(); + + RegionI *orig = NULL; + + if (secrgn) + { + orig = new RegionI(canvas); + api_region *clone = orig->clone(); + api_region *secclone = secrgn->clone(); + RECT dr; + getClientRect(&dr); + secclone->offset(dr.left, dr.top); + clone->andRegion(secclone); + canvas->selectClipRgn(clone); + orig->disposeClone(clone); + secrgn->disposeClone(secclone); + } + + RECT r, srcR, cb, cr; + getClientRect(&srcR); + r = cr = srcR; + + if (canvas->getClipBox(&cb)) + { + r.left = MAX(r.left, cb.left); + r.top = MAX(r.top, cb.top); + r.right = MIN(r.right, cb.right); + r.bottom = MIN(r.bottom, cb.bottom); + srcR = r; + } + + layer_adjustDest(&cr); + layer_adjustDest(&r); + + +#if defined(WA3COMPATIBILITY) || defined(GEN_FF) + int bmw = getBitmap()->getWidth(); + int bmh = getBitmap()->getHeight(); + int bmpitch = getBitmap()->getFullWidth(); + int *bmbits = (int*)getBitmap()->getBits(); + + if (bmbits) bmbits += getBitmap()->getX() + getBitmap()->getY() * bmpitch; +#endif + + if (getWidth() == (cr.right - cr.left) && getHeight() == (cr.bottom - cr.top)) + { + int w = r.right - r.left, h = r.bottom - r.top; + srcR.top = r.top - cr.top; + srcR.left = r.left - cr.left; + srcR.top += getSourceOffsetY(); + srcR.left += getSourceOffsetX(); + srcR.bottom = srcR.top + h; + srcR.right = srcR.left + w; + // FG> NOT READY FOR OPTIMIZATION YET +#if defined(WA3COMPATIBILITY) || defined(GEN_FF) + if (fx_on && fx_dmove && bmbits) + { + + if (fx_bgfx) + { + if (!fx_dmove->getBltCanvas() || !fx_dmove->getBltCanvas()->getBits()) + fx_dmove->render(this, getWidth(), getHeight(), bmbits, bmw, bmh, bmpitch); + + int w, h, p, *bits = (int*)canvas->getBits(); + if (bits && !canvas->getDim(&w, &h, &p) && + cr.left + getWidth() < w && cr.top + getHeight() < h && cr.left >= 0 && cr.top >= 0) + { + fx_dmove->render(this, getWidth(), getHeight(), bits + cr.left + cr.top*w, getWidth(), getHeight(), w); + } + else + { + BltCanvas c(getWidth(), getHeight()); + canvas->blit(cr.left, cr.top, &c, 0, 0, getWidth(), getHeight()); + fx_dmove->render(this, getWidth(), getHeight(), (int *)c.getBits(), + getWidth(), getHeight(), getWidth()); + } + if (fx_dmove->getBltCanvas()) + fx_dmove->getBltCanvas()->blit(0, 0, canvas, cr.left, cr.top, getWidth(), getHeight()); + + } + else + { // no bgfx + if (fx_getClear() && fx_dmove->getBltCanvas() && fx_dmove->getBltCanvas()->getBits()) + fx_dmove->getBltCanvas()->fillBits(0); + fx_dmove->render(this, getWidth(), getHeight(), bmbits, bmw, bmh, bmpitch); + //SkinBitmap *b = NULL; + if (fx_dmove->getBltCanvas()) + { + fx_dmove->getBltCanvas()->stretchToRectAlpha(canvas, &srcR, &r, talpha); +// b = fx_dmove->getBltCanvas()->getSkinBitmap(); +// if (b) +// b->stretchToRectAlpha(canvas, &srcR, &r, talpha); + } + } + } + else +#endif + getBitmap()->stretchToRectAlpha(canvas, &srcR, &r, talpha); + } + else + { + if (r.right == r.left || r.bottom == r.top) + { + if (orig) + { + canvas->selectClipRgn(orig); + delete orig; orig = 0; + } + return 0; + } + + srcR.top = getSourceOffsetY(); + srcR.left = getSourceOffsetX(); + srcR.bottom = srcR.top + getHeight(); + srcR.right = srcR.left + getWidth(); + + if (!tiling) + { + +#if defined(WA3COMPATIBILITY) || defined(GEN_FF) + if (fx_on && fx_dmove && bmbits) + { + if (fx_bgfx) + { + if (!fx_dmove->getBltCanvas() || !fx_dmove->getBltCanvas()->getBits()) + fx_dmove->render(this, cr.right - cr.left, cr.bottom - cr.top, bmbits, bmw, bmh, bmpitch); + + int w, h, p; + if (canvas->getBits() && !canvas->getDim(&w, &h, &p) && + cr.right < w && cr.bottom < h && cr.left >= 0 && cr.top >= 0) + { + fx_dmove->render(this, cr.right - cr.left, cr.bottom - cr.top, (int *)canvas->getBits() + cr.left + cr.top*w, + cr.right - cr.left, cr.bottom - cr.top, w); + } + else + { + BltCanvas c(cr.right - cr.left, cr.bottom - cr.top); + canvas->blit(cr.left, cr.top, &c, 0, 0, cr.right - cr.left, cr.bottom - cr.top); + fx_dmove->render(this, cr.right - cr.left, cr.bottom - cr.top, (int *)c.getBits(), + cr.right - cr.left, cr.bottom - cr.top, cr.right - cr.left); + + } + + if (fx_dmove->getBltCanvas()) + fx_dmove->getBltCanvas()->blit(0, 0, canvas, cr.left, cr.top, cr.right - cr.left, cr.bottom - cr.top); + } + else + { + if (fx_getClear() && fx_dmove->getBltCanvas() && fx_dmove->getBltCanvas()->getBits()) + fx_dmove->getBltCanvas()->fillBits(0); + fx_dmove->render(this, getWidth(), getHeight(), bmbits, bmw, bmh, bmpitch); + //SkinBitmap *b = NULL; + if (fx_dmove->getBltCanvas()) + { + fx_dmove->getBltCanvas()->stretchToRectAlpha(canvas, &srcR, &cr, talpha); +// b = fx_dmove->getBltCanvas()->getSkinBitmap(); +// if (b) +// b->stretchToRectAlpha(canvas, &srcR, &cr, talpha); + + } + } + } + else +#endif + { + getBitmap()->stretchToRectAlpha(canvas, &srcR, &cr, talpha); + } + + } + else + { + getBitmap()->blitRectToTile(canvas, &cr, &srcR, 0, 0, talpha); + } + } + + if (orig) + { + canvas->selectClipRgn(orig); + delete orig; orig = 0; + } + return 1; +} + +int Layer::onResize() +{ + LAYER_PARENT::onResize(); + RECT r; + getClientRect(&r); + int w = r.right - r.left; + int h = r.bottom - r.top; + if (w != last_w || h != last_h) + invalidateRegionCache(); + return 1; +} + +#pragma warning (disable : 4065) +void Layer::timerCallback(int id) +{ + switch (id) + { +#if defined(WA3COMPATIBILITY) || defined(GEN_FF) + case FX_TIMER: + fx_onFrame(); + invalidate(); + break; +#endif + + default: + LAYER_PARENT::timerCallback(id); + break; + } +} +#pragma warning (default: 4065) + +void Layer::invalidateRegionCache() +{ + delete rgnclone; + rgnclone = NULL; + invalidateWindowRegion(); +} + +int Layer::setXuiParam(int _xuihandle, int attribid, const wchar_t *paramname, const wchar_t *strvalue) +{ + if (xuihandle != _xuihandle) return LAYER_PARENT::setXuiParam(_xuihandle, attribid, paramname, strvalue); + switch (attribid) + { + case LAYER_SETIMAGE: + setBitmap(strvalue); + break; + case LAYER_SETRESIZE: + setResize(SkinParser::parseResize(strvalue)); + if (resizer) getGuiObject()->guiobject_setMover(0); + break; + case LAYER_SETSCALE: + setScaler(SkinParser::parseResize(strvalue)); + if (scaler) getGuiObject()->guiobject_setMover(0); + break; + case LAYER_SETREGION: + setRegionFromBitmap(strvalue); + break; + case LAYER_SETTILE: + setTiling(WTOI(strvalue)); + break; + case LAYER_SETDBLCLICKACTION: + dblClickAction = strvalue; + break; + case LAYER_DBLCLICKPARAM: + setDblClickParam(strvalue); + break; + case LAYER_SETINACTIVEIMAGE: + setInactiveBitmap(strvalue); + break; + case LAYER_SETMYCURSOR: + l_customcursor = true; + getGuiObject()->guiobject_setCursor(strvalue); + break; + case LAYER_SETQUALITY: + bitmap.setResamplingMode(WTOI(strvalue)); + break; + default: + return 0; + + } + return 1; +} + +int Layer::getPreferences(int what) +{ + if (what == SUGGESTED_W) + return getWidth(); + if (what == SUGGESTED_H) + return getHeight(); + return LAYER_PARENT::getPreferences(what); +} + +int Layer::getSourceOffsetX() +{ + return 0; +} + +int Layer::getSourceOffsetY() +{ + return 0; +} + +void Layer::setBitmap(const wchar_t *name) +{ + bitmapname = name; + bitmap = name; + deleteRegion(); + makeRegion(); + notifyParent(ChildNotify::AUTOWHCHANGED); + if (isInited()) invalidate(); +} + +void Layer::setInactiveBitmap(const wchar_t *name) +{ + inactiveImageName = name; + inactiveBitmap = name; + hasInactiveImage = 1; +} + +void Layer::setDblClickParam(const wchar_t *p) +{ + dblclickparam=p; +} + +const wchar_t *Layer::getDblClickParam() +{ + return dblclickparam; +} + +int Layer::getWidth() +{ + if (getBitmap()) return getBitmap()->getWidth(); + return 0; +} + +int Layer::getHeight() +{ + if (getBitmap()) return getBitmap()->getHeight(); + return 0; +} + +int Layer::onLeftButtonDown(int x, int y) +{ + LAYER_PARENT::onLeftButtonDown(x, y); + ifc_window *d = getDesktopParent(); + +#ifdef WASABI_COMPILE_WNDMGR + Layout *_l = NULL; + if (d != NULL) + { + _l = static_cast<Layout *>(d->getInterface(layoutGuid)); + if (_l && _l->isLocked()) return 1; + } + + int need_resize = 0, need_scale = 0, need_move = 0; + + int dock = APPBAR_NOTDOCKED; + int rw = applyResizeRestrictions(resizeway, &dock); + int sw = (dock == APPBAR_NOTDOCKED) ? scalerway : RESIZE_NONE; + + if (resizer && rw != RESIZE_NONE && (!_l || _l->getResizable())) + { + if (scaler && sw != RESIZE_NONE && Std::keyModifier(STDKEY_ALT) && (!_l || _l->getScalable())) + need_scale = 1; + else + need_resize = 1; + } + else if (scaler && sw != RESIZE_NONE && (!_l || _l->getScalable())) + { + need_scale = 1; + } + else if (getGuiObject()->guiobject_getMover()) + { + need_move = 1; + } + + Group *l = static_cast<Group *>(_l); + + if (need_move) + { + // do nothin' + } + else if (need_scale) + { + if (l) + { + l->beginScale(); + scaling = 1; + } + return 1; + } + else if (need_resize) + { + resizerect = 1; + if (l) + { + clientToScreen(&x, &y); + l->mouseResize(x, y, resizeway); + } + } +#endif + return 1; +} + +int Layer::onLeftButtonUp(int x, int y) +{ + LAYER_PARENT::onLeftButtonUp(x, y); +#ifdef WASABI_COMPILE_WNDMGR + if (scaling) + { + getGuiObject()->guiobject_getParentGroup()->endScale(); + scaling = 0; + } +#endif + return 1; +} + +void Layer::onCancelCapture() +{ + LAYER_PARENT::onCancelCapture(); + scaling = 0; +} + +int Layer::onMouseMove(int x, int y) +{ + LAYER_PARENT::onMouseMove(x, y); + POINT pos = {x, y}; + clientToScreen(&pos); + +#ifdef WASABI_COMPILE_WNDMGR + if (scaling && getCapture()) + { // todo: resizing w/no rect + if (!Std::keyDown(MK_LBUTTON)) + scaling = 0; + else + { + RECT oldRect; + RECT newRect; + ifc_window *b = getRootParent(); + b->getWindowRect(&oldRect); + newRect = oldRect; + clientToScreen(&x, &y); + int mask = 0; + if (scalerway & RESIZE_BOTTOM) + { + newRect.bottom = y - y % SNAP_Y; + mask |= BOTTOM; + } + if (scalerway & RESIZE_RIGHT) + { + newRect.right = x - x % SNAP_X; + mask |= RIGHT; + } + if (scalerway & RESIZE_TOP) + { + newRect.top = y - y % SNAP_Y; + mask |= TOP; + } + if (scalerway & RESIZE_LEFT) + { + newRect.left = x - x % SNAP_X; + mask |= LEFT; + } + + RECT dr = newRect; + WASABI_API_WNDMGR->wndTrackDock(b, &dr, &newRect, mask | NOINTERSECT); + if (dr.right - dr.left < 32) dr.right = dr.left + 32; + if (dr.bottom - dr.top < 32) dr.bottom = dr.top + 32; + if (MEMCMP(&dr, &oldRect, sizeof(RECT))) + { + RECT origRect; + b->getClientRect(&origRect); + double rx = (double)(dr.right - dr.left) / (double)(origRect.right - origRect.left); + double ry = (double)(dr.bottom - dr.top) / (double)(origRect.bottom - origRect.top); + double r = MAX(rx, ry); + if (r != 0) b->setRenderRatio(r); + } + } + } +#endif + + return 1; +} + +SkinBitmap *Layer::getBitmap() +{ + return layer_getBitmap(); +} + +SkinBitmap *Layer::layer_getBitmap() +{ + if (hasInactiveImage) + if (!isActive()) + return inactiveBitmap.getBitmap(); + return bitmap.getBitmap(); +} + +const wchar_t *Layer::layer_getBitmapName() +{ + return bitmapname; +} + +int Layer::applyResizeRestrictions(int way, int *side) +{ + ifc_window *rw = getDesktopParent(); + int dock = APPBAR_NOTDOCKED; + if (side) *side = dock; + if (rw) + { + Layout *l = (Layout *)rw->getInterface(layoutGuid); + if (l) dock = l->appbar_getSide(); + } + if (dock == APPBAR_NOTDOCKED) return way; + /* + switch (way) { + case RESIZE_TOPLEFT: + if (dock == APPBAR_TOP || dock == APPBAR_LEFT) return RESIZE_NONE; + break; + case RESIZE_BOTTOMRIGHT: + if (dock == APPBAR_RIGHT || dock == APPBAR_BOTTOM) return RESIZE_NONE; + break; + case RESIZE_TOPRIGHT: + if (dock == APPBAR_TOP || dock == APPBAR_RIGHT) return RESIZE_NONE; + break; + case RESIZE_BOTTOMLEFT: + if (dock == APPBAR_BOTTOM || dock == APPBAR_LEFT) return RESIZE_NONE; + break; + case RESIZE_TOP: + if (dock == APPBAR_TOP) return RESIZE_NONE; + break; + case RESIZE_BOTTOM: + if (dock == APPBAR_BOTTOM) return RESIZE_NONE; + break; + case RESIZE_LEFT: + if (dock == APPBAR_LEFT) return RESIZE_NONE; + break; + case RESIZE_RIGHT: + if (dock == APPBAR_RIGHT) return RESIZE_NONE; + break; + } + return way;*/ + if (dock != APPBAR_NOTDOCKED) return RESIZE_NONE; + return way; +} + +int Layer::getCursorType(int x, int y) +{ + // Return our user cursor if we have one (even when we are resizable!) + if (l_customcursor) + { + return BASEWND_CURSOR_USERSET; + } + // Then check if our layer is used to resize or scale the wnd + ifc_window *d = getDesktopParent(); + int scalable = 1; + int resizable = 1; + Layout *_l = NULL; + if (d != NULL) + { + _l = static_cast<Layout *>(d->getInterface(layoutGuid)); + if (_l) + { + scalable = _l->getScalable(); + resizable = _l->getResizable(); + } + } + + if (!_l || (!_l->isLocked() && (resizer || scaler))) + { + int dock = APPBAR_NOTDOCKED; + + int r = 0; + if (resizer && resizable) + { + if (scaler && scalable) + { + if (Std::keyModifier(STDKEY_ALT)) + { + r = applyResizeRestrictions(scalerway, &dock); + if (dock != APPBAR_NOTDOCKED) r = RESIZE_NONE; + } + else + { + r = applyResizeRestrictions(resizeway); + } + } + else + { + r = applyResizeRestrictions(resizeway); + } + } + if (scaler && scalable) + { + r = applyResizeRestrictions(scalerway, &dock); + if (dock != APPBAR_NOTDOCKED) r = RESIZE_NONE; + } + + switch (r) + { + case RESIZE_TOPLEFT: + case RESIZE_BOTTOMRIGHT: + return BASEWND_CURSOR_NORTHWEST_SOUTHEAST; + case RESIZE_TOPRIGHT: + case RESIZE_BOTTOMLEFT: + return BASEWND_CURSOR_NORTHEAST_SOUTHWEST; + break; + case RESIZE_TOP: + case RESIZE_BOTTOM: + return BASEWND_CURSOR_NORTHSOUTH; + break; + case RESIZE_LEFT: + case RESIZE_RIGHT: + return BASEWND_CURSOR_EASTWEST; + break; + } + } + // At leat we want to have a cursor so spit our the normal pointer + return BASEWND_CURSOR_POINTER; +} + +void Layer::setScaler(int r) +{ + if (r != 0) + { + scaler = 1; + scalerway = r; + } + else + { + resizer = 0; + scalerway = 0; + } +} + +void Layer::setResize(int r) +{ + if (r != 0) + { + resizer = 1; + resizeway = r; + } + else + { + resizer = 0; + resizeway = 0; + } +} + +api_region *Layer::getBitmapRegion() +{ + return rgn; +} + +api_region *Layer::getRegion() +{ + api_region *_rgn = getBitmapRegion(); + if (!_rgn) return NULL; + if (!rgnclone) + { + rgnclone = new RegionI(); + rgnclone->addRegion(_rgn); + } + else + return rgnclone; + float w, h; + RECT r; + getClientRect(&r); + if (r.right - r.left == 0 || r.bottom - r.top == 0) return NULL; + last_w = r.right - r.left; + last_h = r.bottom - r.top; + if (getWidth() == 0 || getHeight() == 0) return NULL; + w = (float)(last_w) / (float)getWidth(); + h = (float)(last_h) / (float)getHeight(); + if (!w || !h) return NULL; + if (!tiling) + { + if (w != 1.0 || h != 1.0) + { + rgnclone->scale(w, h, TRUE); + } + } + else + { + for (int j = 0;j < h;j++) + { + for (int i = 0;i < w;i++) + { + api_region *t = _rgn->clone(); + t->offset(i*getWidth(), j*getHeight()); + rgnclone->addRegion(t); + _rgn->disposeClone(t); + } + } + } + RegionI _r(&r); + _r.offset(-r.left, -r.top); + rgnclone->andRegion(&_r); + + return rgnclone; +} + +void Layer::setRegionOp(int i) +{ + int old = getRegionOp(); + LAYER_PARENT::setRegionOp(i); + if (!old && i) setRectRgn(0); +} + +void Layer::makeRegion() +{ + if (!bitmap.getBitmap()) + return; + delete rgn; + rgn = new RegionI(bitmap); + invalidateRegionCache(); +} + +void Layer::deleteRegion() +{ + if (!rgn) return; + invalidateRegionCache(); + delete rgn; + rgn = NULL; +} + +int Layer::onLeftButtonDblClk(int x, int y) +{ + // Martin> copied and adopted from textbase.cpp + //if (!dblClickAction.isempty() && !VCPU::getComplete()) + if (dblClickAction) + { +#ifdef WASABI_COMPILE_WNDMGR + const wchar_t *toCheck = L"SWITCH;"; + if (!_wcsnicmp(dblClickAction, toCheck, 7)) + { + onLeftButtonUp(x, y); + getGuiObject()->guiobject_getParentGroup()->getParentContainer()->switchToLayout(dblClickAction.getValue() + 7); + return 0; + } + else + { +#endif + svc_action *act = ActionEnum(dblClickAction).getNext(); + if (act) + { + int _x = x; + int _y = y; + clientToScreen(&_x, &_y); + act->onAction(dblClickAction, getDblClickParam(), _x, _y, NULL, 0, this); + //WASABI_API_WNDMGR->messageBox(L"on action; passed", L"debug", 0, NULL, NULL); + SvcEnum::release(act); + } +#ifdef WASABI_COMPILE_WNDMGR + + } +#endif + + } + int r = LAYER_PARENT::onLeftButtonDblClk(x, y); + return r; +} + + +void Layer::setRegionFromMap(SMap *map, int byte, int inversed) +{ + if (secrgn) + { + invalidate(); + delete secrgn; + secrgn = NULL; + } + //RECT r = {map->getBitmap()->getX(), map->getBitmap()->getY(), map->getBitmap()->getWidth(), map->getBitmap()->getHeight()}; + secrgn = new RegionI(map->getBitmap(), NULL, 0, 0, FALSE, 1, (unsigned char)byte, inversed); + if (secrgn) + invalidate(); +} + +void Layer::setRegion(SRegion *reg) +{ + invalidate(); + delete secrgn; + if (!reg) + { + secrgn = NULL; invalidate(); return; + } + secrgn = new RegionI(); + secrgn->addRegion(reg->getRegion()); + invalidate(); +} + +int Layer::wantSiblingInvalidations() +{ + return fx_on; +} + +int Layer::onSiblingInvalidateRgn(api_region *r, ifc_window *who, int who_idx, int my_idx) +{ + if (!fx_on || !fx_bgfx || who_idx >= my_idx) return 0; + RECT rr; + getClientRect(&rr); + if (rgn) + { + api_region *_r = rgn->clone(); + _r->offset(rr.left, rr.top); + if (fx_local && !_r->doesIntersectRgn(r)) + { + rgn->disposeClone(_r); + return 0; + } + if (secrgn) + { + api_region *_rs = secrgn->clone(); + _rs->offset(rr.left, rr.top); + _r->andRegion(_rs); + secrgn->disposeClone(_rs); + } + r->addRegion(_r); + rgn->disposeClone(_r); + } + else + { + RegionI _r(&rr); + if (secrgn) + { + api_region *_rs = secrgn->clone(); + _rs->offset(rr.left, rr.top); + _r.andRegion(_rs); + secrgn->disposeClone(_rs); + } + if (fx_local && !_r.doesIntersectRgn(r)) + { + return 0; + } + r->addRegion(&_r); + } + return 1; +} + +void Layer::onSetVisible(int show) +{ + LAYER_PARENT::onSetVisible(show); + getGuiObject()->guiobject_onSetVisible(show); +} + +int Layer::onActivate() +{ + invalidate(); + return 0; +} + +int Layer::onDeactivate() +{ + invalidate(); + return 0; +} + +void Layer::setTiling(int t) +{ + if (tiling == t) return; + tiling = t; + invalidate(); +} + +int Layer::getTiling() +{ + return tiling; +} + + +void Layer::onBeginResize(RECT r) +{ + scriptVar l = SOM::makeVar(SCRIPT_INT); + SOM::assign(&l, r.left); + scriptVar t = SOM::makeVar(SCRIPT_INT); + SOM::assign(&t, r.top); + scriptVar w = SOM::makeVar(SCRIPT_INT); + SOM::assign(&w, r.right - r.left); + scriptVar h = SOM::makeVar(SCRIPT_INT); + SOM::assign(&h, r.bottom - r.top); + script_vcpu_onBeginResize(SCRIPT_CALL, getScriptObject(), l, t, w, h); +} + +void Layer::onEndResize(RECT r) +{ + scriptVar l = SOM::makeVar(SCRIPT_INT); + SOM::assign(&l, r.left); + scriptVar t = SOM::makeVar(SCRIPT_INT); + SOM::assign(&t, r.top); + scriptVar w = SOM::makeVar(SCRIPT_INT); + SOM::assign(&w, r.right - r.left); + scriptVar h = SOM::makeVar(SCRIPT_INT); + SOM::assign(&h, r.bottom - r.top); + script_vcpu_onEndResize(SCRIPT_CALL, getScriptObject(), l, t, w, h); +} + +#if defined(WA3COMPATIBILITY) || defined(GEN_FF) +void Layer::fx_setEnabled(int i) +{ + static int inited = 0; + if (fx_getEnabled() == !!i) return; + fx_on = !!i; + if (fx_on) + { + if (!inited) + fx_onInit(); + fx_dmove = new FxDynamicMove; + fx_dmove->setBilinear(fx_getBilinear()); + if (fx_getAlphaMode()) + fx_dmove->setAlphaMode(1 | (fx_getBgFx() ? 2 : 0)); + else fx_setAlphaMode(0); + fx_dmove->setAlphaOnce(fx_alphaonce); + fx_dmove->setRect(fx_getRect()); + fx_dmove->setWrap(fx_getWrap()); + fx_dmove->setGridSize(fx_grid_x, fx_grid_y); + if (fx_realtime) + { + setTimer(FX_TIMER, fx_delay); + fx_timeron = 1; + } + } + else + { + if (fx_timeron) + { + killTimer(FX_TIMER); + fx_timeron = 0; + } + delete fx_dmove; + fx_dmove = NULL; + } + invalidate(); +} + +int Layer::fx_getEnabled(void) +{ + return fx_on; +} + +void Layer::fx_setWrap(int i) +{ + if (fx_getWrap() == !!i) return; + fx_wrap = !!i; + if (fx_dmove) fx_dmove->setWrap(fx_wrap); + invalidate(); +} + +int Layer::fx_getWrap(void) +{ + return fx_wrap; +} + +void Layer::fx_setRect(int i) +{ + if (fx_getRect() == !!i) return; + fx_rect = !!i; + if (fx_dmove) fx_dmove->setRect(fx_rect); + invalidate(); +} + +int Layer::fx_getRect(void) +{ + return fx_rect; +} + +int Layer::fx_getAlphaMode() +{ + if (!fx_alphamode) return 0; + if (fx_alphaonce) return 2; + return 1; +} + +void Layer::fx_setAlphaMode(int i) +{ + + if (i == 2) + { + i = 1; + fx_alphaonce = 1; + if (fx_dmove) fx_dmove->setAlphaOnce(1); + } + else + { + fx_alphaonce = 0; + if (fx_dmove) fx_dmove->setAlphaOnce(0); + } + + if (fx_getAlphaMode() == !!i) return; + fx_alphamode = !!i; + if (fx_dmove) + { + if (fx_getAlphaMode()) + fx_dmove->setAlphaMode(1 | (fx_getBgFx() ? 2 : 0)); + else + fx_dmove->setAlphaMode(0); + } + invalidate(); +} + + +int Layer::fx_getBilinear() +{ + return fx_bilinear; +} + +void Layer::fx_setBilinear(int i) +{ + if (fx_getBilinear() == !!i) return; + fx_bilinear = !!i; + if (fx_dmove) fx_dmove->setBilinear(fx_bilinear); + invalidate(); +} + +int Layer::fx_getBgFx() +{ + return fx_bgfx; +} + +void Layer::fx_setBgFx(int i) +{ + if (fx_getBgFx() == !!i) return; + fx_bgfx = !!i; + if (fx_dmove) fx_dmove->setCanCache(!i); + if (fx_dmove && fx_getAlphaMode()) + { + fx_dmove->setAlphaMode(1 | (fx_getBgFx() ? 2 : 0)); + } + invalidate(); +} + +int Layer::fx_getSpeed() +{ + return fx_delay; +} + +void Layer::fx_setSpeed(int s) +{ + if (fx_getSpeed() == s) return; + fx_delay = s; + if (fx_timeron) + { + killTimer(FX_TIMER); + fx_timeron = 0; + } + if (fx_on && fx_realtime) + { + setTimer(FX_TIMER, fx_delay); + fx_timeron = 1; + } +} + +int Layer::fx_getClear() +{ + return fx_clear; +} + +void Layer::fx_setClear(int i) +{ + if (fx_getClear() == !!i) return; + fx_clear = !!i; +} + +int Layer::fx_getRealtime() +{ + return fx_realtime; +} + +void Layer::fx_setRealtime(int i) +{ + if (fx_getRealtime() == !!i) return; + fx_realtime = !!i; +} + +int Layer::fx_getLocalized() +{ + return fx_local; +} + +void Layer::fx_setLocalized(int i) +{ + if (fx_getLocalized() == !!i) return; + fx_local = !!i; +} + +void Layer::fx_setGridSize(int x, int y) +{ + fx_grid_x = x; + fx_grid_y = y; + if (!fx_dmove) return; + fx_dmove->setGridSize(x, y); +} + +void Layer::fx_update(void) +{ + RECT r; + getClientRect(&r); + if (fx_realtime && !isMinimized()) + cascadeRepaintRect(&r); + else + invalidateRect(&r); +} + +void Layer::fx_restart(void) +{ + fx_onInit(); + if (fx_dmove && fx_dmove->getBltCanvas() && fx_dmove->getBltCanvas()->getBits()) + fx_dmove->getBltCanvas()->fillBits(0); + // todo: reset need_alpha in fx_dmove +} + +void Layer::fx_onInit(void) +{ + script_vcpu_fx_onInit(SCRIPT_CALL, getScriptObject()); +} + +void Layer::fx_onFrame(void) +{ + script_vcpu_fx_onFrame(SCRIPT_CALL, getScriptObject()); +} + +double Layer::fx_onGetPixelA(double r, double d, double x, double y) +{ + scriptVar _x = SOM::makeVar(SCRIPT_DOUBLE); + scriptVar _y = SOM::makeVar(SCRIPT_DOUBLE); + scriptVar _r = SOM::makeVar(SCRIPT_DOUBLE); + scriptVar _d = SOM::makeVar(SCRIPT_DOUBLE); + SOM::assign(&_x, x); + SOM::assign(&_y, y); + SOM::assign(&_r, r); + SOM::assign(&_d, d); + scriptVar v = script_vcpu_fx_onGetPixelA(SCRIPT_CALL, getScriptObject(), _r, _d, _x, _y); + return (v.type == 0) ? 0.5 : v.data.ddata; +} + + +double Layer::fx_onGetPixelX(double r, double d, double x, double y) +{ + scriptVar _x = SOM::makeVar(SCRIPT_DOUBLE); + scriptVar _y = SOM::makeVar(SCRIPT_DOUBLE); + scriptVar _r = SOM::makeVar(SCRIPT_DOUBLE); + scriptVar _d = SOM::makeVar(SCRIPT_DOUBLE); + SOM::assign(&_x, x); + SOM::assign(&_y, y); + SOM::assign(&_r, r); + SOM::assign(&_d, d); + scriptVar v = script_vcpu_fx_onGetPixelX(SCRIPT_CALL, getScriptObject(), _r, _d, _x, _y); + return (v.type == 0) ? x : v.data.ddata; +} + +double Layer::fx_onGetPixelY(double r, double d, double x, double y) +{ + scriptVar _x = SOM::makeVar(SCRIPT_DOUBLE); + scriptVar _y = SOM::makeVar(SCRIPT_DOUBLE); + scriptVar _r = SOM::makeVar(SCRIPT_DOUBLE); + scriptVar _d = SOM::makeVar(SCRIPT_DOUBLE); + SOM::assign(&_x, x); + SOM::assign(&_y, y); + SOM::assign(&_r, r); + SOM::assign(&_d, d); + scriptVar v = script_vcpu_fx_onGetPixelY(SCRIPT_CALL, getScriptObject(), _r, _d, _x, _y); + return (v.type == 0) ? y : v.data.ddata; +} + +double Layer::fx_onGetPixelR(double r, double d, double x, double y) +{ + scriptVar _x = SOM::makeVar(SCRIPT_DOUBLE); + scriptVar _y = SOM::makeVar(SCRIPT_DOUBLE); + scriptVar _r = SOM::makeVar(SCRIPT_DOUBLE); + scriptVar _d = SOM::makeVar(SCRIPT_DOUBLE); + SOM::assign(&_x, x); + SOM::assign(&_y, y); + SOM::assign(&_r, r); + SOM::assign(&_d, d); + scriptVar v = script_vcpu_fx_onGetPixelR(SCRIPT_CALL, getScriptObject(), _r, _d, _x, _y); + return (v.type == 0) ? r : v.data.ddata; +} + +double Layer::fx_onGetPixelD(double r, double d, double x, double y) +{ + scriptVar _x = SOM::makeVar(SCRIPT_DOUBLE); + scriptVar _y = SOM::makeVar(SCRIPT_DOUBLE); + scriptVar _r = SOM::makeVar(SCRIPT_DOUBLE); + scriptVar _d = SOM::makeVar(SCRIPT_DOUBLE); + SOM::assign(&_x, x); + SOM::assign(&_y, y); + SOM::assign(&_r, r); + SOM::assign(&_d, d); + scriptVar v = script_vcpu_fx_onGetPixelD(SCRIPT_CALL, getScriptObject(), _r, _d, _x, _y); + return (v.type == 0) ? d : v.data.ddata; +} +#endif + +int Layer::skincb_onColorThemeChanged(const wchar_t *newcolortheme) +{ + #if defined(WA3COMPATIBILITY) || defined(GEN_FF) + if (fx_getEnabled()) + { + fx_dmove->flushCache(); + fx_update(); + } +#endif + return 0; +} + +void Layer::setRegionFromBitmap(const wchar_t *bmpid) +{ + delete secrgn; + secrgn = NULL; + if (bmpid == NULL || *bmpid == '\0') + return; + bool invert = (*bmpid == '!'); + if (invert) bmpid++; + SkinBitmap b(bmpid); + secrgn = new RegionI(&b, NULL, 0, 0, invert); +} + +LayerScriptController _layerController; +LayerScriptController *layerController = &_layerController; + +// -- Functions table ------------------------------------- +function_descriptor_struct LayerScriptController::exportedFunction[] = { + {L"setRegionFromMap", 3, (void*)Layer::script_vcpu_setRegionFromMap }, + {L"setRegion", 1, (void*)Layer::script_vcpu_setRegion }, + {L"isInvalid", 0, (void*)Layer::script_vcpu_isInvalid }, +#ifdef WASABI_COMPILE_WNDMGR + {L"onBeginResize", 4, (void*)Layer::script_vcpu_onBeginResize }, + {L"onEndResize", 4, (void*)Layer::script_vcpu_onEndResize }, +#endif +#if defined(WA3COMPATIBILITY) || defined(GEN_FF) + { + L"fx_setEnabled", 1, (void*)Layer::script_vcpu_fx_setEnabled + }, + {L"fx_getEnabled", 0, (void*)Layer::script_vcpu_fx_getEnabled }, + {L"fx_onInit", 0, (void*)Layer::script_vcpu_fx_onInit }, + {L"fx_onFrame", 0, (void*)Layer::script_vcpu_fx_onFrame }, + {L"fx_onGetPixelR", 4, (void*)Layer::script_vcpu_fx_onGetPixelR }, + {L"fx_onGetPixelD", 4, (void*)Layer::script_vcpu_fx_onGetPixelD }, + {L"fx_onGetPixelX", 4, (void*)Layer::script_vcpu_fx_onGetPixelX }, + {L"fx_onGetPixelY", 4, (void*)Layer::script_vcpu_fx_onGetPixelY }, + {L"fx_onGetPixelA", 4, (void*)Layer::script_vcpu_fx_onGetPixelA }, + {L"fx_setWrap", 1, (void*)Layer::script_vcpu_fx_setWrap }, + {L"fx_getWrap", 0, (void*)Layer::script_vcpu_fx_getWrap }, + {L"fx_setRect", 1, (void*)Layer::script_vcpu_fx_setRect }, + {L"fx_getRect", 0, (void*)Layer::script_vcpu_fx_getRect }, + {L"fx_setBgFx", 1, (void*)Layer::script_vcpu_fx_setBgFx }, + {L"fx_getBgFx", 0, (void*)Layer::script_vcpu_fx_getBgFx }, + {L"fx_setClear", 1, (void*)Layer::script_vcpu_fx_setClear }, + {L"fx_getClear", 0, (void*)Layer::script_vcpu_fx_getClear }, + {L"fx_setSpeed", 1, (void*)Layer::script_vcpu_fx_setSpeed }, + {L"fx_getSpeed", 0, (void*)Layer::script_vcpu_fx_getSpeed }, + {L"fx_setRealtime", 1, (void*)Layer::script_vcpu_fx_setRealtime }, + {L"fx_getRealtime", 0, (void*)Layer::script_vcpu_fx_getRealtime }, + {L"fx_setLocalized", 1, (void*)Layer::script_vcpu_fx_setLocalized }, + {L"fx_getLocalized", 0, (void*)Layer::script_vcpu_fx_getLocalized }, + {L"fx_setBilinear", 1, (void*)Layer::script_vcpu_fx_setBilinear }, + {L"fx_getBilinear", 0, (void*)Layer::script_vcpu_fx_getBilinear }, + {L"fx_setAlphaMode", 1, (void*)Layer::script_vcpu_fx_setAlphaMode }, + {L"fx_getAlphaMode", 0, (void*)Layer::script_vcpu_fx_getAlphaMode }, + {L"fx_setGridSize", 2, (void*)Layer::script_vcpu_fx_setGridSize }, + {L"fx_update", 0, (void*)Layer::script_vcpu_fx_update }, + {L"fx_restart", 0, (void*)Layer::script_vcpu_fx_restart }, +#endif + }; +// -------------------------------------------------------- + +const wchar_t *LayerScriptController::getClassName() +{ + return L"Layer"; +} + +const wchar_t *LayerScriptController::getAncestorClassName() +{ + return L"GuiObject"; +} + +ScriptObject *LayerScriptController::instantiate() +{ + Layer *l = new Layer; + ASSERT(l != NULL); + return l->getScriptObject(); +} + +void LayerScriptController::destroy(ScriptObject *o) +{ + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + ASSERT(l != NULL); + delete l; +} + +void *LayerScriptController::encapsulate(ScriptObject *o) +{ + return NULL; // no encapsulation for layer yet +} + +void LayerScriptController::deencapsulate(void *o) +{} + +int LayerScriptController::getNumFunctions() +{ + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *LayerScriptController::getExportedFunctions() +{ + return exportedFunction; +} + +GUID LayerScriptController::getClassGuid() +{ + return layerGuid; +} + + +//------------------------------------------------------------------------ + +scriptVar Layer::script_vcpu_onBeginResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar left, scriptVar top, scriptVar width, scriptVar height) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS4(o, layerController, left, top, width, height); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT4(o, left, top, width, height); +} + +scriptVar Layer::script_vcpu_onEndResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar left, scriptVar top, scriptVar width, scriptVar height) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS4(o, layerController, left, top, width, height); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT4(o, left, top, width, height); +} + +scriptVar Layer::script_vcpu_setRegionFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inv) +{ + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&byte)); + ASSERT(SOM::isNumeric(&inv)); + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + SMap *m = static_cast<SMap *>(GET_SCRIPT_OBJECT_AS(map, mapGuid)); + if (l) l->setRegionFromMap(m, GET_SCRIPT_INT(byte), GET_SCRIPT_INT(inv)); + RETURN_SCRIPT_VOID; +} + +scriptVar Layer::script_vcpu_setRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg) +{ + SCRIPT_FUNCTION_INIT + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + SRegion *r = static_cast<SRegion *>(GET_SCRIPT_OBJECT_AS(reg, regionGuid)); + if (l) l->setRegion(r); + RETURN_SCRIPT_VOID; +} + +bool Layer::layer_isInvalid() +{ + SkinBitmap *b = layer_getBitmap(); + if (b) + return !!b->isInvalid(); + else + return true; +} + +scriptVar Layer::script_vcpu_isInvalid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) + { + return MAKE_SCRIPT_INT(l->layer_isInvalid()?1:0); + } + return MAKE_SCRIPT_INT(1); +} + + +#if defined(WA3COMPATIBILITY) || defined(GEN_FF) +scriptVar Layer::script_vcpu_fx_setEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a) +{ + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&a)); + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) l->fx_setEnabled(GET_SCRIPT_INT(a)); + RETURN_SCRIPT_VOID; +} + +scriptVar Layer::script_vcpu_fx_getEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) return MAKE_SCRIPT_INT(l->fx_getEnabled()); + RETURN_SCRIPT_ZERO; +} + +scriptVar Layer::script_vcpu_fx_setWrap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a) +{ + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&a)); + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) l->fx_setWrap(SOM::makeInt(&a)); + RETURN_SCRIPT_VOID; +} + +scriptVar Layer::script_vcpu_fx_getWrap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) return MAKE_SCRIPT_INT(l->fx_getWrap()); + RETURN_SCRIPT_ZERO; +} + +scriptVar Layer::script_vcpu_fx_setRect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a) +{ + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&a)); + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) l->fx_setRect(SOM::makeInt(&a)); + RETURN_SCRIPT_VOID; +} + +scriptVar Layer::script_vcpu_fx_getRect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) return MAKE_SCRIPT_INT(l->fx_getRect()); + RETURN_SCRIPT_ZERO; +} + +scriptVar Layer::script_vcpu_fx_setAlphaMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a) +{ + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&a)); + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) l->fx_setAlphaMode(SOM::makeInt(&a)); + RETURN_SCRIPT_VOID; +} + +scriptVar Layer::script_vcpu_fx_getAlphaMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) return MAKE_SCRIPT_INT(l->fx_getAlphaMode()); + RETURN_SCRIPT_ZERO; +} + +scriptVar Layer::script_vcpu_fx_setBilinear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a) +{ + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&a)); + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) l->fx_setBilinear(SOM::makeInt(&a)); + RETURN_SCRIPT_VOID; +} + +scriptVar Layer::script_vcpu_fx_getBilinear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) return MAKE_SCRIPT_INT(l->fx_getBilinear()); + RETURN_SCRIPT_ZERO; +} + +scriptVar Layer::script_vcpu_fx_setBgFx(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a) +{ + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&a)); + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) l->fx_setBgFx(SOM::makeInt(&a)); + RETURN_SCRIPT_VOID; +} + +scriptVar Layer::script_vcpu_fx_getBgFx(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) return MAKE_SCRIPT_INT(((Layer *)o)->fx_getBgFx()); + RETURN_SCRIPT_ZERO; +} + +scriptVar Layer::script_vcpu_fx_setSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s) +{ + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&s)); + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) l->fx_setSpeed(SOM::makeInt(&s)); + RETURN_SCRIPT_VOID; +} + +scriptVar Layer::script_vcpu_fx_getSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) return MAKE_SCRIPT_INT(((Layer *)o)->fx_getSpeed()); + RETURN_SCRIPT_ZERO; +} + +scriptVar Layer::script_vcpu_fx_setRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s) +{ + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&s)); + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) l->fx_setRealtime(SOM::makeInt(&s)); + RETURN_SCRIPT_VOID; +} + +scriptVar Layer::script_vcpu_fx_getRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) return MAKE_SCRIPT_INT(((Layer *)o)->fx_getRealtime()); + RETURN_SCRIPT_ZERO; +} + +scriptVar Layer::script_vcpu_fx_setClear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s) +{ + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&s)); + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) l->fx_setClear(SOM::makeInt(&s)); + RETURN_SCRIPT_VOID; +} + +scriptVar Layer::script_vcpu_fx_getClear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) return MAKE_SCRIPT_INT(l->fx_getClear()); + RETURN_SCRIPT_ZERO; +} + +scriptVar Layer::script_vcpu_fx_setLocalized(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s) +{ + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&s)); + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) l->fx_setLocalized(SOM::makeInt(&s)); + RETURN_SCRIPT_VOID; +} + +scriptVar Layer::script_vcpu_fx_getLocalized(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) return MAKE_SCRIPT_INT(l->fx_getLocalized()); + RETURN_SCRIPT_ZERO; +} + +scriptVar Layer::script_vcpu_fx_setGridSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) +{ + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&x)); + ASSERT(SOM::isNumeric(&y)); + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) l->fx_setGridSize(SOM::makeInt(&x), SOM::makeInt(&y)); + RETURN_SCRIPT_VOID; +} + +scriptVar Layer::script_vcpu_fx_update(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) l->fx_update(); + RETURN_SCRIPT_VOID; +} + +scriptVar Layer::script_vcpu_fx_restart(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid)); + if (l) l->fx_restart(); + RETURN_SCRIPT_VOID; +} + +scriptVar Layer::script_vcpu_fx_onInit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS0(o, layerController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +scriptVar Layer::script_vcpu_fx_onFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS0(o, layerController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +scriptVar Layer::script_vcpu_fx_onGetPixelA(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS4(o, layerController, r, d, x, y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT4(o, r, d, x, y); +} + + +scriptVar Layer::script_vcpu_fx_onGetPixelX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS4(o, layerController, r, d, x, y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT4(o, r, d, x, y); +} + +scriptVar Layer::script_vcpu_fx_onGetPixelY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS4(o, layerController, r, d, x, y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT4(o, r, d, x, y); +} + +scriptVar Layer::script_vcpu_fx_onGetPixelR(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS4(o, layerController, r, d, x, y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT4(o, r, d, x, y); +} + +scriptVar Layer::script_vcpu_fx_onGetPixelD(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS4(o, layerController, r, d, x, y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT4(o, r, d, x, y); +} + +#endif //WA3COMPATIBILITY || GEN_FF + + diff --git a/Src/Wasabi/api/skin/widgets/layer.h b/Src/Wasabi/api/skin/widgets/layer.h new file mode 100644 index 00000000..efc607d2 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/layer.h @@ -0,0 +1,287 @@ +//PORTABLE +#ifndef _LAYER_H +#define _LAYER_H + +#ifndef _NOSTUDIO + +#include <api/script/objects/smap.h> +#ifdef WASABI_WIDGETS_GUIOBJECT +#include <api/script/objects/guiobj.h> +#endif +#include <api/wnd/basewnd.h> +#include <tataki/bitmap/bitmap.h> +#include <api/wnd/virtualwnd.h> +#include <tataki/region/region.h> +#include <tataki/bitmap/autobitmap.h> +#include <api/wnd/wndclass/qpaintwnd.h> + +#endif + +#include <api/script/script.h> +#ifdef WASABI_WIDGETS_GUIOBJECT +#include <api/script/objects/guiobj.h> +#endif + +// {5AB9FA15-9A7D-4557-ABC8-6557A6C67CA9} +static const GUID layerGuid = +{ 0x5ab9fa15, 0x9a7d, 0x4557, { 0xab, 0xc8, 0x65, 0x57, 0xa6, 0xc6, 0x7c, 0xa9 } }; + +#define LAYER_PARENT GuiObjectWnd +#ifdef WASABI_WIDGETS_GUIOBJECT +class LayerScriptController : public GuiObjectScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + 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); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern LayerScriptController *layerController; +#endif +#ifndef _NOSTUDIO + +#define RESIZE_NONE 0 +#define RESIZE_TOP 1 +#define RESIZE_BOTTOM 2 +#define RESIZE_LEFT 4 +#define RESIZE_RIGHT 8 +#define RESIZE_TOPLEFT RESIZE_TOP | RESIZE_LEFT +#define RESIZE_TOPRIGHT RESIZE_TOP | RESIZE_RIGHT +#define RESIZE_BOTTOMLEFT RESIZE_BOTTOM | RESIZE_LEFT +#define RESIZE_BOTTOMRIGHT RESIZE_BOTTOM | RESIZE_RIGHT + +class FxDynamicMove; + +class Layer : public LAYER_PARENT, public SkinCallbackI +{ +public: + Layer(); + virtual ~Layer(); + + virtual int onInit(); + virtual int onPaint(Canvas *canvas); + virtual int onLeftButtonDown(int x, int y); + virtual int onLeftButtonUp(int x, int y); + virtual int onMouseMove(int x, int y); + virtual int onLeftButtonDblClk(int x, int y); + virtual int getCursorType(int x, int y); + virtual int onResize(); + virtual int onActivate(); + virtual int onDeactivate(); + virtual int getPreferences(int what); + + virtual void setDblClickParam(const wchar_t *p); + virtual const wchar_t *getDblClickParam(); + + virtual void timerCallback(int id); + + virtual void setRegionFromBitmap(const wchar_t *bmpid); + + virtual void setRegionFromMap(SMap *map, int byte, int inversed); + virtual void setRegion(SRegion *reg); + virtual int onSiblingInvalidateRgn(api_region *r, ifc_window *who, int who_idx, int my_idx); + + virtual int wantSiblingInvalidations(); + + virtual int getSourceOffsetX(); + virtual int getSourceOffsetY(); + + virtual void layer_adjustDest(RECT *r) {} + + virtual void onBeginResize(RECT r); + virtual void onEndResize(RECT r); + virtual SkinBitmap *getBitmap(); + + virtual void onSetVisible(int show); + + void setResize(int r); + void setScaler(int m); + virtual void invalidateRegionCache(); + + virtual api_region *getRegion(); // stretched and tiled as needed + virtual api_region *getBitmapRegion(); // not stretched or tiled + virtual void makeRegion(); + virtual void deleteRegion(); + + virtual void setTiling(int t); + virtual int getTiling(); + + virtual void setBitmap(const wchar_t *name); + virtual int getWidth(); + virtual int getHeight(); + + virtual int setXuiParam(int _xuihandle, int id, const wchar_t *paramname, const wchar_t *strvalue); + + virtual void setRegionOp(int i); + + virtual void setInactiveBitmap(const wchar_t *name); + virtual void onCancelCapture(); + + virtual int applyResizeRestrictions(int way, int *side=NULL); + + virtual bool layer_isInvalid(); + //FG> fx + +#if defined(WA3COMPATIBILITY) || defined(GEN_FF) + virtual void fx_setEnabled(int i); + virtual int fx_getEnabled(void); + virtual void fx_setWrap(int i); + virtual int fx_getWrap(void); + virtual void fx_setRect(int i); + virtual int fx_getRect(void); + virtual void fx_setBilinear(int i); + virtual int fx_getBilinear(void); + virtual void fx_setAlphaMode(int i); + virtual int fx_getAlphaMode(void); + virtual void fx_setBgFx(int i); + virtual int fx_getBgFx(void); + virtual void fx_setClear(int i); + virtual int fx_getClear(void); + virtual void fx_setLocalized(int i); + virtual int fx_getLocalized(void); + virtual void fx_setGridSize(int x, int y); + virtual void fx_update(void); + virtual void fx_restart(void); + virtual void fx_onInit(void); + virtual void fx_onFrame(void); + virtual void fx_setSpeed(int d); + virtual int fx_getSpeed(void); + virtual void fx_setRealtime(int r); + virtual int fx_getRealtime(void); + virtual double fx_onGetPixelA(double r, double d, double x, double y); + virtual double fx_onGetPixelX(double r, double d, double x, double y); + virtual double fx_onGetPixelY(double r, double d, double x, double y); + virtual double fx_onGetPixelR(double r, double d, double x, double y); + virtual double fx_onGetPixelD(double r, double d, double x, double y); +#endif + + virtual int skincb_onColorThemeChanged(const wchar_t *newcolortheme); + + enum { + LAYER_SETIMAGE=0, + LAYER_SETRESIZE, + LAYER_SETSCALE, + LAYER_SETREGION, + LAYER_SETTILE, + LAYER_SETDBLCLICKACTION, + LAYER_DBLCLICKPARAM, + LAYER_SETINACTIVEIMAGE, + LAYER_SETMYCURSOR, + LAYER_SETQUALITY, + // LAYER_NUMPARAMS, // martin> there is no reference for this elsewhere in gen_ff, so CUT + + }; + + int l_customcursor; + +protected: +/*static */void CreateXMLParameters(int master_handle); + const wchar_t *layer_getBitmapName(); + SkinBitmap *layer_getBitmap(); + +private: +static XMLParamPair params[]; + AutoSkinBitmap bitmap; + int resizer, resizeway, resizing, resizerect; + int cap, scaler, scalerway, scaling; + POINT anchor; + int clickthrough; + RegionI *rgn, *secrgn, *rgnclone; + int tiling; + StringW bitmapname; + int hasInactiveImage; + StringW inactiveImageName; + AutoSkinBitmap inactiveBitmap; + int xuihandle; + StringW dblclickparam; + + int fx_on; + int fx_wrap; + int fx_rect; + int fx_grid_x; + int fx_grid_y; + int fx_bilinear; + int fx_alphamode; + int fx_alphaonce; + int fx_bgfx; + int fx_clear; + int fx_delay; + int fx_timeron; + int fx_local; + int fx_realtime; + int last_w, last_h; + FxDynamicMove *fx_dmove; + + StringW dblClickAction; + StringW statustext; + +// FG> +// -- SCRIPT ----------------------------------------------------- + +public: + static scriptVar script_vcpu_onBeginResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l, scriptVar t, scriptVar w, scriptVar h); + static scriptVar script_vcpu_onEndResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l, scriptVar t, scriptVar w, scriptVar h); + static scriptVar script_vcpu_setRegionFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inversed); + static scriptVar script_vcpu_setRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg); + + static scriptVar script_vcpu_isInvalid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + + static scriptVar script_vcpu_fx_setEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a); + static scriptVar script_vcpu_fx_getEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_fx_setWrap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a); + static scriptVar script_vcpu_fx_getWrap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_fx_setRect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a); + static scriptVar script_vcpu_fx_getRect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_fx_setBgFx(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a); + static scriptVar script_vcpu_fx_getBgFx(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_fx_setClear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a); + static scriptVar script_vcpu_fx_getClear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_fx_setRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a); + static scriptVar script_vcpu_fx_getRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_fx_setLocalized(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a); + static scriptVar script_vcpu_fx_getLocalized(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_fx_setBilinear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a); + static scriptVar script_vcpu_fx_getBilinear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_fx_setAlphaMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a); + static scriptVar script_vcpu_fx_getAlphaMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_fx_setGridSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y); + static scriptVar script_vcpu_fx_update(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_fx_restart(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_fx_onInit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_fx_onFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_fx_setSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s); + static scriptVar script_vcpu_fx_getSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_fx_onGetPixelA(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y); + static scriptVar script_vcpu_fx_onGetPixelX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y); + static scriptVar script_vcpu_fx_onGetPixelY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y); + static scriptVar script_vcpu_fx_onGetPixelR(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y); + static scriptVar script_vcpu_fx_onGetPixelD(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y); + +#else +class Layer : public LAYER_SCRIPTPARENT { + +#endif + +public: + +// INSERT_SCRIPT_OBJECT_CONTROL + +}; +#ifdef WASABI_WIDGETS_GUIOBJECT +extern const wchar_t layerXuiObjectStr[]; +extern char layerXuiSvcName[]; +class LayerXuiSvc : public XuiObjectSvc<Layer, layerXuiObjectStr, layerXuiSvcName> {}; +#endif +#endif diff --git a/Src/Wasabi/api/skin/widgets/mb/iebrowser.cpp b/Src/Wasabi/api/skin/widgets/mb/iebrowser.cpp new file mode 100644 index 00000000..5be43319 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/iebrowser.cpp @@ -0,0 +1,637 @@ +#include <precomp.h> +#include "iebrowser.h" +#include "mbsvc.h" +#include "main.h" +#include "../nu/ns_wc.h" +#include "../Winamp/buildtype.h" +#include <api/config/items/cfgitem.h> +#include <wa2frontend.h> +#include <windows.h> +#include <Mshtml.h> +#include "minibrowserCOM.h" + +class BrowserMsgProc: public ifc_messageprocessor +{ +public: + BrowserMsgProc(BrowserWnd *pBrowser) : pTarget(pBrowser) {} + ~BrowserMsgProc(void) {} + +public: + bool ProcessMessage(MSG *pMsg) + { + if (WM_KEYFIRST <= pMsg->message && WM_KEYLAST >= pMsg->message) + { + HWND hwndHost; + hwndHost = pTarget->gethWnd(); + if ((hwndHost == pMsg->hwnd || IsChild(hwndHost, pMsg->hwnd)) && IsWindowVisible(pMsg->hwnd)) + { + if (!(GetAsyncKeyState(VK_CONTROL)&0x8000) && !(GetAsyncKeyState(VK_MENU)&0x8000)) + { + if (pTarget->TranslateKey(pMsg)) return true; + } + switch(pMsg->message) + { + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + switch(pMsg->wParam) + { + case VK_F1: + if (!(GetAsyncKeyState(VK_SHIFT)&0x8000)) pMsg->hwnd = plugin.hwndParent; + break; + + case VK_F4: + if ((pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN) && (GetAsyncKeyState(VK_MENU)&0x8000)) + SendMessageW(plugin.hwndParent, WM_CLOSE, 0, 0); + pMsg->message = WM_NULL; + break; + case 'P': + case 'K': + case 'H': + case VK_TAB: + if ((GetAsyncKeyState(VK_CONTROL)&0x8000) && !(GetAsyncKeyState(VK_MENU)&0x8000)) pMsg->hwnd = plugin.hwndParent; + break; + case '3': + case VK_UP: + case VK_DOWN: + break; + default: + if ((GetAsyncKeyState(VK_MENU)&0x8000) && !(GetAsyncKeyState(VK_CONTROL)&0x8000)) pMsg->hwnd = plugin.hwndParent; + break; + } + break; + } + + } + + } + return /*(IsDialogMessageW(pTarget->gethWnd(), pMsg)) ? true :*/ false; + } + +protected: + BrowserWnd *pTarget; + RECVS_DISPATCH; + +}; + +extern HINSTANCE hInstance; +STDAPI WriteBSTR(BSTR *pstrDest, LPCWSTR szSrc) +{ + *pstrDest = SysAllocString( szSrc ); + if ( !(*pstrDest) ) return E_OUTOFMEMORY; + return NOERROR; +} + +STDAPI FreeBSTR(BSTR* pstr) +{ + if ( *pstr == NULL ) return S_FALSE; + SysFreeString( *pstr ); + return NOERROR; +} + +HRESULT writeBString(BSTR* psz, const char *str) +{ + WCHAR WideStr[WA_MAX_PATH] = {0}; + String s = str; + if (s.isempty()) s = ""; + MultiByteToWideCharSZ(CP_ACP, 0, s, -1, WideStr, WA_MAX_PATH); + return WriteBSTR(psz, WideStr); +} + +BrowserWnd::BrowserWnd() : HTMLContainer2(NULL, NULL), processor(NULL) +{ + setVirtual(0); + + oleOk = FALSE; + homepage = L"about:blank"; + timerset1 = 0; + timerset2 = 0; + cancelIEErrorPage = false; + scrollbarsflag = BROWSER_SCROLLBARS_DEFAULT; +} + +BrowserWnd::~BrowserWnd() +{ + if (processor) + { + if (WASABI_API_APP) WASABI_API_APP->app_removeMessageProcessor(processor); + free(processor); + processor = NULL; + } + if (timerset1) + { + killTimer(MB_TIMERID1); + timerset1 = 0; + } + if (timerset2) + { + killTimer(MB_TIMERID2); + timerset2 = 0; + } + + freeBrowserStuff(); +} + +bool BrowserWnd::InitializeLibrary() +{ + return (FALSE != HTMLContainer2_Initialize()); +} + +void BrowserWnd::UninitializeLibrary() +{ + HTMLContainer2_Uninitialize(); +} + +int BrowserWnd::onInit() +{ + BROWSER_PARENT::onInit(); + if (isVisible()) + onSetVisible(1); + updateScrollbars(); + return 1; +} + +void BrowserWnd::onSetVisible(int show) +{ + if (show) initBrowserStuff(); +} + +int BrowserWnd::initBrowserStuff() +{ + if (pUnk) return 1; + + if (SUCCEEDED(OleInitialize(NULL))) oleOk = TRUE; + if (!oleOk) return 1; + + // {280876CF-48C0-40bc-8E86-73CE6BB462E5} + const GUID options_guid = + { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } }; + hParent = gethWnd(); + + int usemozilla = 0; + +#ifdef WASABI_COMPILE_CONFIG + usemozilla = _intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid), L"Use Mozilla instead of IE for minibrowser"); +#endif + + if (SUCCEEDED(Initialize())) + { + HRESULT hr; + IWebBrowser2 *pWeb2; + + hr = GetIWebBrowser2(&pWeb2); + if (SUCCEEDED(hr)) + { + pWeb2->put_RegisterAsBrowser(VARIANT_TRUE); + + if (deferednavigate.isempty()) + { + if (!homepage.isempty()) + minibrowser_navigateUrl(homepage); + else + minibrowser_navigateUrl(L"about:blank"); + } + else minibrowser_navigateUrl(deferednavigate); + } + } + if (!processor && WASABI_API_APP) + { + processor = new BrowserMsgProc(this); + WASABI_API_APP->app_addMessageProcessor(processor); + + } + + ShowWindow(hParent, SW_SHOWNA); + + return 1; +} + +void BrowserWnd::freeBrowserStuff() +{ + if (oleOk) + { + Finish(); + OleUninitialize(); + oleOk = FALSE; +#ifndef WASABINOMAINAPI + api->hint_garbageCollect(); +#endif + + } +} + +int BrowserWnd::minibrowser_navigateUrl(const wchar_t *url) +{ + HRESULT hr; + + curpage = url; + + hr = NavigateToName(url, 0); + if (FAILED(hr)) + { + deferednavigate = url; + return 0; + } + return 1; +} + +int BrowserWnd::minibrowser_back() +{ + HRESULT hr; + IWebBrowser2 *pWeb2; + hr = GetIWebBrowser2(&pWeb2); + if (SUCCEEDED(hr)) + { + pWeb2->GoBack(); + pWeb2->Release(); + } + return 1; +} + +int BrowserWnd::minibrowser_forward() +{ + HRESULT hr; + IWebBrowser2 *pWeb2; + hr = GetIWebBrowser2(&pWeb2); + if (SUCCEEDED(hr)) + { + pWeb2->GoForward(); + pWeb2->Release(); + } + return 1; +} + +int BrowserWnd::minibrowser_refresh() +{ + HRESULT hr; + IWebBrowser2 *pWeb2; + hr = GetIWebBrowser2(&pWeb2); + if (SUCCEEDED(hr)) + { + pWeb2->Refresh(); + pWeb2->Release(); + } + return 1; +} + +int BrowserWnd::minibrowser_home() +{ + minibrowser_navigateUrl(homepage); + return 1; +} + +int BrowserWnd::minibrowser_stop() +{ + HRESULT hr; + IWebBrowser2 *pWeb2; + hr = GetIWebBrowser2(&pWeb2); + if (SUCCEEDED(hr)) + { + pWeb2->Stop(); + pWeb2->Release(); + } + return 1; +} + +HWND BrowserWnd::getOSHandle() +{ + return ::GetWindow(gethWnd(), GW_CHILD); // assumes setVirtual(0) in constructor +} + +void BrowserWnd::onTargetNameTimer() +{ + updateTargetName(); +} + +void BrowserWnd::onScrollbarsFlagTimer() +{ + updateScrollbars(); +} + +void BrowserWnd::timerCallback(int id) +{ + switch (id) + { + case MB_TIMERID1: + onTargetNameTimer(); + return ; + case MB_TIMERID2: + onScrollbarsFlagTimer(); + return ; + } + BROWSER_PARENT::timerCallback(id); +} + +void BrowserWnd::minibrowser_setTargetName(const wchar_t *name) +{ + targetname = name; + updateTargetName(); +} + +void BrowserWnd::updateTargetName() +{ + if (!doSetTargetName(targetname)) + { + if (!timerset1) { setTimer(MB_TIMERID1, 100); timerset1 = 1; } + return ; + } + else + { + if (timerset1) { killTimer(MB_TIMERID1); timerset1 = 0; } + } +} + +int BrowserWnd::doSetTargetName(const wchar_t *name) +{ + HRESULT hr; + IWebBrowser2 *pWeb2; + IDispatch *id; + + hr = GetIWebBrowser2(&pWeb2); + + if (FAILED(hr)) return FALSE; + + if (SUCCEEDED(pWeb2->get_Document(&id)) && id) + { + IHTMLDocument2 *doc; + if (SUCCEEDED(id->QueryInterface(IID_IHTMLDocument2, (void **)&doc)) && doc) + { + IHTMLWindow2 *w; + if (SUCCEEDED(doc->get_parentWindow(&w)) && w) + { + w->put_name(SysAllocString(targetname.getValue())); + w->Release(); + doc->Release(); + id->Release(); + pWeb2->Release(); + return 1; + } + doc->Release(); + } + id->Release(); + } + pWeb2->Release(); + return 0; +} + +const wchar_t *BrowserWnd::minibrowser_getTargetName() +{ + return targetname; +} + +void BrowserWnd::OnBeforeNavigate(IDispatch *pDispatch, VARIANT *URL, VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers, VARIANT_BOOL *Cancel) +{ + int i = 0; + foreach(callbacks) + int r = callbacks.getfor()->minibrowsercb_onBeforeNavigate(URL->bstrVal, Flags->intVal, TargetFrameName->bstrVal); + if (i++ == 0) *Cancel = (r) ? VARIANT_TRUE : VARIANT_FALSE; + endfor; + updateScrollbars(); + +} + +void BrowserWnd::minibrowser_setScrollbarsFlag(int a) +{ + scrollbarsflag = a; + updateScrollbars(); +} + +void BrowserWnd::updateScrollbars() +{ + if (!doSetScrollbars()) + { + if (!timerset2) { setTimer(MB_TIMERID2, 100); timerset2 = 1; } + return ; + } + else + { + if (timerset2) { killTimer(MB_TIMERID2); timerset2 = 0; } + } +} + +void BrowserWnd::OnDocumentComplete(IDispatch *pDispatch, VARIANT *URL) +{ + if (!targetname.isempty()) + minibrowser_setTargetName(targetname); + foreach(callbacks) + callbacks.getfor()->minibrowsercb_onDocumentComplete(URL->bstrVal); + endfor; + updateScrollbars(); +} + +void BrowserWnd::OnDocumentReady(IDispatch *pDispatch, VARIANT *URL) +{ + if (!targetname.isempty()) + minibrowser_setTargetName(targetname); + foreach(callbacks) + callbacks.getfor()->minibrowsercb_onDocumentReady(URL->bstrVal); + endfor; + updateScrollbars(); +} + +void BrowserWnd::OnNavigateError(IDispatch *pDispatch, VARIANT *URL, VARIANT *TargetFrameName, VARIANT *StatusCode, VARIANT_BOOL *Cancel) +{ + if (TargetFrameName->bstrVal != NULL) + return; //TODO: send targetframe via api to script + foreach(callbacks) + callbacks.getfor()->minibrowsercb_onNavigateError(URL->bstrVal, StatusCode->intVal); + endfor; + if (cancelIEErrorPage) *Cancel = -1; +} + +const wchar_t* BrowserWnd::messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3) +{ + const wchar_t* ret = 0; + foreach(callbacks) + ret = callbacks.getfor()->minibrowsercb_messageToMaki(str1, str2, i1, i2, i3); + if (ret) break; + endfor; + return ret; +} + +const wchar_t* BrowserWnd::minibrowser_messageToJS(const wchar_t* str1, const wchar_t* str2, int i1, int i2, int i3) +{ + // TODO feed JS w/ this info + return 0; +} + +void BrowserWnd::minibrowser_scrape() +{ + IWebBrowser2 *browser=0; + GetIWebBrowser2(&browser); + IDispatch *docDisp=0; + IHTMLDocument2 *document = 0; + if (browser) + { + browser->get_Document(&docDisp); + if (docDisp) + { + docDisp->QueryInterface(&document); + docDisp->Release(); + } + browser->Release(); + } + + if (document) + { + IHTMLElementCollection *links=0; + document->get_all(&links); + + if (links) + { + IDispatch *anchorDisp=0; + VARIANT index; + + VariantInit(&index); + index.vt = VT_I4; + index.intVal = 0; + + links->item(index, index, &anchorDisp); + while (anchorDisp) + { + IHTMLAnchorElement *anchor=0; + anchorDisp->QueryInterface(&anchor); + if (anchor) + { + BSTR href=0; + anchor->get_href(&href); + if (href && (wa2.CanPlay(href) || wa2.IsPlaylist(href))) + { + foreach(callbacks) + callbacks.getfor()->minibrowsercb_onMediaLink(href); + endfor; + } + SysFreeString(href); + anchor->Release(); + } + + index.intVal++; + anchorDisp->Release(); + links->item(index, index, &anchorDisp); + } + + links->Release(); + } + document->Release(); + } + +} + +void BrowserWnd::minibrowser_getDocumentTitle(wchar_t *str, size_t len) +{ + IWebBrowser2 *browser=0; + GetIWebBrowser2(&browser); + IDispatch *docDisp=0; + IHTMLDocument2 *document = 0; + if (browser) + { + browser->get_Document(&docDisp); + if (docDisp) + { + docDisp->QueryInterface(&document); + docDisp->Release(); + } + browser->Release(); + } + + if (document) + { + BSTR title_bstr; + document->get_title(&title_bstr); + document->Release(); + + WCSCPYN(str, title_bstr, len); + // the COM object SysAllocString'd this for us, so we need to free it via COM also + SysFreeString(title_bstr); + } + else + str[0]=0; +} + +void BrowserWnd::minibrowser_setCancelIEErrorPage (bool cancel) +{ + cancelIEErrorPage = cancel; +} + +int BrowserWnd::doSetScrollbars() +{ + HRESULT hr; + IWebBrowser2 *pWeb2; + IDispatch *id; + + hr = GetIWebBrowser2(&pWeb2); + + if (FAILED(hr)) return 0; + + if (scrollbarsflag == BROWSER_SCROLLBARS_DEFAULT) return 1; + + if (SUCCEEDED(pWeb2->get_Document(&id)) && id) + { + IHTMLDocument2 *doc; + if (SUCCEEDED(id->QueryInterface(IID_IHTMLDocument2, (void **)&doc)) && doc) + { + IHTMLElement *e; + if (SUCCEEDED(doc->get_body(&e))) + { + IHTMLStyle *s; + if (SUCCEEDED(e->get_style(&s))) + { + BSTR a; + switch (scrollbarsflag) + { + case BROWSER_SCROLLBARS_ALWAYS: + writeBString(&a, "scroll"); + break; + case BROWSER_SCROLLBARS_AUTO: + writeBString(&a, "auto"); + break; + case BROWSER_SCROLLBARS_NEVER: + writeBString(&a, "hidden"); + break; + default: + a = NULL; + break; + } + if (a) s->put_overflow(a); + FreeBSTR(&a); + s->Release(); + pWeb2->Release(); + return 1; + } + e->Release(); + } + doc->Release(); + } + id->Release(); + } + pWeb2->Release(); + return 0; +} + +const wchar_t *BrowserWnd::minibrowser_getCurrentUrl() +{ + return curpage; +} + +STDMETHODIMP BrowserWnd::GetExternal(IDispatch __RPC_FAR *__RPC_FAR *ppDispatch) +{ + *ppDispatch = (IDispatch*) new MinibrowserCOM(this); //TODO we might need to delete this as well! + return S_OK; +} + +DWORD BrowserWnd::OnGetDownlodFlags(void) +{ + return DLCTL_DLIMAGES | DLCTL_VIDEOS | DLCTL_PRAGMA_NO_CACHE +#ifdef WINAMP_FINAL_BUILD + |DLCTL_SILENT +#endif + ; +} + + +#define CBCLASS BrowserMsgProc +START_DISPATCH; +CB(IFC_MESSAGEPROCESSOR_PROCESS_MESSAGE, ProcessMessage) +END_DISPATCH; +#undef CBCLASS diff --git a/Src/Wasabi/api/skin/widgets/mb/iebrowser.h b/Src/Wasabi/api/skin/widgets/mb/iebrowser.h new file mode 100644 index 00000000..e0e61e35 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/iebrowser.h @@ -0,0 +1,102 @@ +#ifndef __BROWSER_H +#define __BROWSER_H + +class BrowserWnd; + +#define BROWSER_PARENT OSWnd +#define IDC_SINKOBJ 0x9871 // arbitrary unique id +#define MB_TIMERID1 0x1927 +#define MB_TIMERID2 0x1928 + +class String; + +#include <nu/HTMLContainer2.h> +#include <api/wnd/wndclass/oswnd.h> +#include <api/wnd/minibrowser.h> + +class BrowserWnd : public BROWSER_PARENT, public HTMLContainer2, public MiniBrowserI { +public: + BrowserWnd(); + virtual ~BrowserWnd(); + +public: + static bool InitializeLibrary(); + static void UninitializeLibrary(); + +public: + // ifc_window + virtual int onInit(); + virtual void onSetVisible(int show); + virtual int handleDesktopAlpha() { return 0; } + DWORD OnGetDownlodFlags(void); + + virtual int onMouseWheelUp(int click, int lines){return 1;} + virtual int onMouseWheelDown(int click, int lines){return 1;} + + // OSWnd + virtual HWND getOSHandle(); + + // MiniBrowser + virtual int minibrowser_navigateUrl(const wchar_t *url); + virtual void minibrowser_setHome(const wchar_t *url) { homepage = url; } + virtual int minibrowser_back(); + virtual int minibrowser_forward(); + virtual int minibrowser_home(); + virtual int minibrowser_refresh(); + virtual int minibrowser_stop(); + virtual void minibrowser_setTargetName(const wchar_t *name); + const wchar_t *minibrowser_getTargetName(); + const wchar_t *minibrowser_getCurrentUrl(); + virtual void minibrowser_addCB(MiniBrowserCallback *cb) { callbacks.addItem(cb); } + virtual ifc_window *minibrowser_getRootWnd() { return this; } + + virtual void minibrowser_setScrollbarsFlag(int a); //BROWSER_SCROLLBARS_ALWAYS, BROWSER_SCROLLBARS_AUTO, BROWSER_SCROLLBARS_NEVER + virtual void minibrowser_scrape(); + virtual void minibrowser_setCancelIEErrorPage(bool cancel); + void minibrowser_getDocumentTitle(wchar_t *str, size_t len); + virtual const wchar_t* minibrowser_messageToJS(const wchar_t* str1, const wchar_t* str2, int i1, int i2, int i3); + // + virtual void timerCallback(int id); + void onTargetNameTimer(); + + bool ProcessMessage(MSG *msg); // return true to 'eat' the message + + bool cancelIEErrorPage; + const wchar_t* messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3); + +protected: + virtual void OnBeforeNavigate(IDispatch *pDispatch, VARIANT *URL, VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers, VARIANT_BOOL *Cancel); + virtual void OnDocumentComplete(IDispatch *pDispatch, VARIANT *URL); + virtual void OnDocumentReady(IDispatch *pDispatch, VARIANT *URL); // So we can get rid of all iFrame completes + virtual void OnNavigateError(IDispatch *pDispatch, VARIANT *URL, VARIANT *TargetFrameName, VARIANT *StatusCode, VARIANT_BOOL *Cancel); + virtual STDMETHODIMP GetExternal(IDispatch __RPC_FAR *__RPC_FAR *ppDispatch); + virtual int initBrowserStuff(); + virtual void freeBrowserStuff(); + virtual void onScrollbarsFlagTimer(); + virtual int wantFocus() { return 1; } + + +private: + virtual int doSetTargetName(const wchar_t *name); + virtual int doSetScrollbars(); + + virtual void updateTargetName(); + virtual void updateScrollbars(); + + + + + BOOL oleOk; + StringW homepage; + StringW deferednavigate; + StringW targetname; + StringW curpage; + int timerset1; + int timerset2; + PtrList<MiniBrowserCallback> callbacks; + int scrollbarsflag; + ifc_messageprocessor *processor; +}; + +#endif + diff --git a/Src/Wasabi/api/skin/widgets/mb/mainminibrowser.cpp b/Src/Wasabi/api/skin/widgets/mb/mainminibrowser.cpp new file mode 100644 index 00000000..bdf22f41 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/mainminibrowser.cpp @@ -0,0 +1,70 @@ +#include <precomp.h> +#include "mainminibrowser.h" +#include <api/script/scriptguid.h> +#include <api/script/objects/guiobject.h> + +ScriptObject *MainMiniBrowser::getScriptObject() +{ + return WASABI_API_MAKI->maki_getObjectAtom(L"browser.main.object"); +} + +void MainMiniBrowser::back() { + ScriptObject *so = getScriptObject(); + if (so) { + C_Browser browser(so); + browser.back(); + } +} + +void MainMiniBrowser::forward(){ + ScriptObject *so = getScriptObject(); + if (so) { + C_Browser browser(so); + browser.forward(); + } +} + +void MainMiniBrowser::refresh(){ + ScriptObject *so = getScriptObject(); + if (so) { + C_Browser browser(so); + browser.refresh(); + } +} + +void MainMiniBrowser::stop(){ + ScriptObject *so = getScriptObject(); + if (so) { + C_Browser browser(so); + browser.stop(); + } +} + +void MainMiniBrowser::home(){ + ScriptObject *so = getScriptObject(); + if (so) { + C_Browser browser(so); + browser.home(); + } +} + +void MainMiniBrowser::navigateUrl(const wchar_t *url){ + ScriptObject *so = getScriptObject(); + if (so) { + C_Browser browser(so); + browser.navigateUrl(url); + } +} + +#ifdef WASABI_COMPILE_WNDMGR +void MainMiniBrowser::popMb(){ + ScriptObject *so = getScriptObject(); + if (so) { + GuiObject *go = static_cast<GuiObject*>(so->vcpu_getInterface(guiObjectGuid)); + if (go) { + go->guiobject_popParentLayout(); + } + } +} +#endif + diff --git a/Src/Wasabi/api/skin/widgets/mb/mainminibrowser.h b/Src/Wasabi/api/skin/widgets/mb/mainminibrowser.h new file mode 100644 index 00000000..10af16ad --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/mainminibrowser.h @@ -0,0 +1,24 @@ +#ifndef __MAINMINIBROWSER_H +#define __MAINMINIBROWSER_H + +#include <wasabicfg.h> +#include <api/script/objects/c_script/c_browser.h> +#include <api/script/objects/c_script/h_browser.h> + +class MainMiniBrowser { + + public: + + static ScriptObject *getScriptObject(); + static void back(); + static void forward(); + static void refresh(); + static void stop(); + static void home(); + static void navigateUrl(const wchar_t *url); +#ifdef WASABI_COMPILE_WNDMGR + static void popMb(); +#endif +}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/mb/mbsvc.cpp b/Src/Wasabi/api/skin/widgets/mb/mbsvc.cpp new file mode 100644 index 00000000..59dd1c34 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/mbsvc.cpp @@ -0,0 +1,48 @@ +#include "precomp.h" +#include <direct.h> +#include "mbsvc.h" + +#ifndef _WASABIRUNTIME + +BEGIN_SERVICES(MbSvc_Svc); +DECLARE_SERVICETSINGLE(svc_miniBrowser, MbSvc); +END_SERVICES(MbSvc_Svc, _MbSvc_Svc); + +#ifdef _X86_ +extern "C" { int _link_MbSvc; } +#else +extern "C" { int __link_MbSvc; } +#endif + +#endif + +MbSvc::MbSvc() +{ + BrowserWnd::InitializeLibrary(); +} + +MbSvc::~MbSvc() +{ + BrowserWnd::UninitializeLibrary(); +} + +int MbSvc::testGuid(GUID g) { + return (g == GUID_MINIBROWSER_ANY || g == GUID_MINIBROWSER_IEACTIVEX); +} + +MiniBrowser *MbSvc::createMiniBrowser() { + BrowserWnd *w = new BrowserWnd; + browsers.addItem(w); + return w; +} + +void MbSvc::destroyMiniBrowser(MiniBrowser *b) { + ASSERT(b != NULL); + BrowserWnd *bw = static_cast<BrowserWnd *>(b->minibrowser_getRootWnd()); + ASSERT(bw != NULL); + int i = browsers.searchItem(bw); + if (i < 0) return; + browsers.removeByPos(i); + delete bw; +} + diff --git a/Src/Wasabi/api/skin/widgets/mb/mbsvc.h b/Src/Wasabi/api/skin/widgets/mb/mbsvc.h new file mode 100644 index 00000000..c1c1b4b8 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/mbsvc.h @@ -0,0 +1,26 @@ +#ifndef _SVC_H +#define _SVC_H + +#include <api/service/svcs/svc_minibrowser.h> +#include <bfc/ptrlist.h> +#include <api/service/svc_enum.h> +#include "iebrowser.h" + +class MbSvc : public svc_miniBrowserI { +public: + MbSvc(); + ~MbSvc(); + + static const char *getServiceName() { return "Internet Explorer ActiveX MiniBrowser Service"; } + virtual int testQueryFormat(int queryformat) { return WaSvc::MINIBROWSER; } + + virtual int testGuid(GUID g); + virtual MiniBrowser *createMiniBrowser(); + virtual void destroyMiniBrowser(MiniBrowser *w); + +private: + + PtrList<BrowserWnd> browsers; +}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/mb/mbsvcwac.cpp b/Src/Wasabi/api/skin/widgets/mb/mbsvcwac.cpp new file mode 100644 index 00000000..1f68199b --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/mbsvcwac.cpp @@ -0,0 +1,26 @@ +#include "precomp.h" +#include "mbsvc.h" +#include "svc.h" +#include "../studio/genwnd.h" + +static WACNAME wac; +WAComponentClient *the = &wac; +WACNAME *wacmb = &wac; + +#include "../studio/services/servicei.h" + +// {181BE599-2249-4a1c-8283-4EE85FE8EC86} +static const GUID guid = +{ 0x181be599, 0x2249, 0x4a1c, { 0x82, 0x83, 0x4e, 0xe8, 0x5f, 0xe8, 0xec, 0x86 } }; + +WACNAME::WACNAME() { + registerService(new waServiceFactoryT<svc_miniBrowser, MbSvc>); +} + +WACNAME::~WACNAME() { +} + +GUID WACNAME::getGUID() { + return guid; +} + diff --git a/Src/Wasabi/api/skin/widgets/mb/mbsvcwac.h b/Src/Wasabi/api/skin/widgets/mb/mbsvcwac.h new file mode 100644 index 00000000..e7d94564 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/mbsvcwac.h @@ -0,0 +1,24 @@ +#ifndef _MB_H +#define _MB_H + +#include "../ns_database/nde.h" +#include "../studio/wac.h" + +#define WACNAME WACmb + +class GenWnd; + +class WACNAME : public WAComponentClient { + public: + WACNAME(); + virtual ~WACNAME(); + + virtual const char *getName() { return "Internet Explorer ActiveX MiniBrowser Service"; }; + virtual GUID getGUID(); + + private: +}; + +extern WACNAME *wacmb; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/mb/minibrowser.cpp b/Src/Wasabi/api/skin/widgets/mb/minibrowser.cpp new file mode 100644 index 00000000..f70c8609 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/minibrowser.cpp @@ -0,0 +1,36 @@ +#include <precomp.h> +#include "minibrowser.h" + +#define CBCLASS MiniBrowserCallbackI +START_DISPATCH; + CB(MINIBROWSER_ONBEFORENAVIGATE, minibrowsercb_onBeforeNavigate); + VCB(MINIBROWSER_ONDOCUMENTCOMPLETE, minibrowsercb_onDocumentComplete); + VCB(MINIBROWSER_ONDOCUMENTREADY, minibrowsercb_onDocumentReady); + VCB(MINIBROWSER_ONNAVIGATEERROR, minibrowsercb_onNavigateError); + VCB(MINIBROWSER_ONMEDIALINK, minibrowsercb_onMediaLink); + CB(MINIBROWSER_MESSAGETOMAKI, minibrowsercb_messageToMaki); +END_DISPATCH; +#undef CBCLASS + +#define CBCLASS MiniBrowserI +START_DISPATCH; + CB(MINIBROWSER_GETROOTWND, minibrowser_getRootWnd); + CB(MINIBROWSER_NAVIGATEURL, minibrowser_navigateUrl); + CB(MINIBROWSER_BACK, minibrowser_back); + CB(MINIBROWSER_FORWARD, minibrowser_forward); + CB(MINIBROWSER_HOME, minibrowser_home); + CB(MINIBROWSER_REFRESH, minibrowser_refresh); + CB(MINIBROWSER_STOP, minibrowser_stop); + VCB(MINIBROWSER_SETTARGETNAME, minibrowser_setTargetName); + CB(MINIBROWSER_GETTARGETNAME, minibrowser_getTargetName); + CB(MINIBROWSER_GETCURRENTURL, minibrowser_getCurrentUrl); + VCB(MINIBROWSER_ADDCB, minibrowser_addCB); + VCB(MINIBROWSER_SETHOME, minibrowser_setHome); + VCB(MINIBROWSER_SETSCROLLFLAG, minibrowser_setScrollbarsFlag); + VCB(MINIBROWSER_SCRAPE, minibrowser_scrape); + VCB(MINIBROWSER_SETCANCELIEERRORPAGE, minibrowser_setCancelIEErrorPage); + VCB(MINIBROWSER_GETDOCUMENTTITLE, minibrowser_getDocumentTitle); + CB(MINIBROWSER_MESSAGETOJS, minibrowser_messageToJS); +END_DISPATCH; +#undef CBCLASS + diff --git a/Src/Wasabi/api/skin/widgets/mb/minibrowser.h b/Src/Wasabi/api/skin/widgets/mb/minibrowser.h new file mode 100644 index 00000000..f08a5564 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/minibrowser.h @@ -0,0 +1,215 @@ +#ifndef __MINIBROWSER_H +#define __MINIBROWSER_H + +#include <bfc/dispatch.h> +#include <bfc/common.h> + +class ifc_window; + +class MiniBrowserCallback : public Dispatchable { + public: + int minibrowsercb_onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame); + void minibrowsercb_onDocumentComplete(const wchar_t *url); + void minibrowsercb_onDocumentReady(const wchar_t *url); + void minibrowsercb_onMediaLink(const wchar_t *url); + void minibrowsercb_onNavigateError(const wchar_t *url, int status); + const wchar_t* minibrowsercb_messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3); + + enum { + MINIBROWSER_ONBEFORENAVIGATE = 10, + MINIBROWSER_ONDOCUMENTCOMPLETE = 20, + MINIBROWSER_ONMEDIALINK = 30, + MINIBROWSER_ONNAVIGATEERROR = 40, + MINIBROWSER_ONDOCUMENTREADY = 50, + MINIBROWSER_MESSAGETOMAKI = 60, + }; +}; + +inline int MiniBrowserCallback ::minibrowsercb_onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame) { + return _call(MINIBROWSER_ONBEFORENAVIGATE, 0, url, flags, frame); +} + +inline void MiniBrowserCallback ::minibrowsercb_onDocumentComplete(const wchar_t *url) { + _voidcall(MINIBROWSER_ONDOCUMENTCOMPLETE, url); +} + +inline void MiniBrowserCallback ::minibrowsercb_onDocumentReady(const wchar_t *url) { + _voidcall(MINIBROWSER_ONDOCUMENTREADY, url); +} + +inline void MiniBrowserCallback ::minibrowsercb_onNavigateError(const wchar_t *url, int status) { + _voidcall(MINIBROWSER_ONNAVIGATEERROR, url, status); +} + +inline void MiniBrowserCallback ::minibrowsercb_onMediaLink(const wchar_t *url) { + _voidcall(MINIBROWSER_ONMEDIALINK, url); +} + +inline const wchar_t* MiniBrowserCallback ::minibrowsercb_messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3) { + return _call(MINIBROWSER_MESSAGETOMAKI, (const wchar_t*)0, str1, str2, i1, i2, i3); +} + +class MiniBrowserCallbackI : public MiniBrowserCallback { + public: + virtual int minibrowsercb_onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame)=0; + virtual void minibrowsercb_onDocumentComplete(const wchar_t *url)=0; + virtual void minibrowsercb_onDocumentReady(const wchar_t *url)=0; + virtual void minibrowsercb_onMediaLink(const wchar_t *url)=0; + virtual void minibrowsercb_onNavigateError(const wchar_t *url, int status)=0; + virtual const wchar_t* minibrowsercb_messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3)=0; + + protected: + RECVS_DISPATCH; +}; + +class MiniBrowser : public Dispatchable { + + public: + + ifc_window *minibrowser_getRootWnd(); + int minibrowser_navigateUrl(const wchar_t *url); + int minibrowser_back(); + int minibrowser_forward(); + int minibrowser_home(); + int minibrowser_refresh(); + int minibrowser_stop(); + void minibrowser_setTargetName(const wchar_t *name); + const wchar_t *minibrowser_getTargetName(); + const wchar_t *minibrowser_getCurrentUrl(); + void minibrowser_getDocumentTitle(wchar_t *str, size_t len); + void minibrowser_addCB(MiniBrowserCallback *cb); + void minibrowser_setHome(const wchar_t *url); + void minibrowser_setScrollbarsFlag(int a); // BROWSER_SCROLLBARS_ALWAYS, BROWSER_SCROLLBARS_AUTO, BROWSER_SCROLLBARS_NEVER + void minibrowser_scrape(); + virtual void minibrowser_setCancelIEErrorPage(bool cancel); + virtual const wchar_t* minibrowser_messageToJS(const wchar_t* str1, const wchar_t* str2, int i1, int i2, int i3); + + enum { + MINIBROWSER_GETROOTWND = 100, + MINIBROWSER_NAVIGATEURL = 200, + MINIBROWSER_BACK = 300, + MINIBROWSER_FORWARD = 400, + MINIBROWSER_HOME = 500, + MINIBROWSER_REFRESH = 600, + MINIBROWSER_STOP = 700, + MINIBROWSER_SETTARGETNAME = 800, + MINIBROWSER_GETTARGETNAME = 900, + MINIBROWSER_GETCURRENTURL = 1000, + MINIBROWSER_ADDCB = 1100, + MINIBROWSER_SETHOME = 1200, + MINIBROWSER_SETSCROLLFLAG = 1300, + MINIBROWSER_SCRAPE = 2000, + MINIBROWSER_GETDOCUMENTTITLE = 2100, + MINIBROWSER_SETCANCELIEERRORPAGE = 2200, + MINIBROWSER_MESSAGETOJS = 2300, + }; + + enum { + BROWSER_SCROLLBARS_DEFAULT = -1, + BROWSER_SCROLLBARS_ALWAYS = 0, + BROWSER_SCROLLBARS_AUTO = 1, + BROWSER_SCROLLBARS_NEVER = 2, + }; + +}; + +inline ifc_window *MiniBrowser::minibrowser_getRootWnd() { + return _call(MINIBROWSER_GETROOTWND, (ifc_window *)NULL); +} + +inline int MiniBrowser::minibrowser_navigateUrl(const wchar_t *url) { + return _call(MINIBROWSER_NAVIGATEURL, 0, url); +} + +inline int MiniBrowser::minibrowser_back() { + return _call(MINIBROWSER_BACK, 0); +} + +inline int MiniBrowser::minibrowser_forward() { + return _call(MINIBROWSER_FORWARD, 0); +} + +inline int MiniBrowser::minibrowser_home() { + return _call(MINIBROWSER_HOME, 0); +} + +inline int MiniBrowser::minibrowser_refresh() { + return _call(MINIBROWSER_REFRESH, 0); +} + +inline int MiniBrowser::minibrowser_stop() { + return _call(MINIBROWSER_STOP, 0); +} + +inline void MiniBrowser::minibrowser_setHome(const wchar_t *url) { + _voidcall(MINIBROWSER_SETHOME, url); +} + +inline void MiniBrowser::minibrowser_setTargetName(const wchar_t *name) { + _voidcall(MINIBROWSER_SETTARGETNAME, name); +} + +inline const wchar_t *MiniBrowser::minibrowser_getTargetName() { + return _call(MINIBROWSER_GETTARGETNAME, (const wchar_t *)NULL); +} + +inline void MiniBrowser::minibrowser_getDocumentTitle(wchar_t *str, size_t len) { + _voidcall(MINIBROWSER_GETDOCUMENTTITLE, str, len); +} + +inline const wchar_t *MiniBrowser::minibrowser_getCurrentUrl() { + return _call(MINIBROWSER_GETCURRENTURL, (const wchar_t *)NULL); +} + +inline void MiniBrowser::minibrowser_addCB(MiniBrowserCallback *cb) { + _voidcall(MINIBROWSER_ADDCB, cb); +} + +inline void MiniBrowser::minibrowser_setScrollbarsFlag(int a) { + _voidcall(MINIBROWSER_SETSCROLLFLAG, a); +} + +inline void MiniBrowser::minibrowser_scrape() +{ + _voidcall(MINIBROWSER_SCRAPE); +} + +inline void MiniBrowser::minibrowser_setCancelIEErrorPage(bool cancel) +{ + _voidcall(MINIBROWSER_SETCANCELIEERRORPAGE, cancel); +} + +inline const wchar_t* MiniBrowser::minibrowser_messageToJS(const wchar_t* str1, const wchar_t* str2, int i1, int i2, int i3) +{ + return _call(MINIBROWSER_MESSAGETOJS, (const wchar_t *)NULL, str1, str2, i1, i2, i3); +} + +class MiniBrowserI : public MiniBrowser { + + public: + + virtual ifc_window *minibrowser_getRootWnd()=0; + virtual int minibrowser_navigateUrl(const wchar_t *url)=0; + virtual int minibrowser_back()=0; + virtual int minibrowser_forward()=0; + virtual int minibrowser_home()=0; + virtual int minibrowser_refresh()=0; + virtual int minibrowser_stop()=0; + virtual void minibrowser_setTargetName(const wchar_t *name)=0; + virtual const wchar_t *minibrowser_getTargetName()=0; + virtual const wchar_t *minibrowser_getCurrentUrl()=0; + virtual void minibrowser_getDocumentTitle(wchar_t *str, size_t len)=0; + virtual void minibrowser_addCB(MiniBrowserCallback *cb)=0; + virtual void minibrowser_setHome(const wchar_t *url)=0; + virtual void minibrowser_setScrollbarsFlag(int a)=0; + virtual void minibrowser_scrape()=0; + virtual void minibrowser_setCancelIEErrorPage(bool cancel)=0; + virtual const wchar_t* minibrowser_messageToJS(const wchar_t* str1, const wchar_t* str2, int i1, int i2, int i3)=0; + + protected: + RECVS_DISPATCH; +}; + + +#endif + diff --git a/Src/Wasabi/api/skin/widgets/mb/minibrowserwnd.cpp b/Src/Wasabi/api/skin/widgets/mb/minibrowserwnd.cpp new file mode 100644 index 00000000..87cc8d30 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/minibrowserwnd.cpp @@ -0,0 +1,173 @@ +#include <precomp.h> +#include <api/skin/widgets/mb/minibrowserwnd.h> +#include <api/skin/widgets/mb/minibrowser.h> +#include <api/service/svcs/svc_minibrowser.h> +#include <api/service/svc_enum.h> + +MiniBrowserWnd::MiniBrowserWnd(GUID mb_provider) { + mb = NULL; + mbsvc = MiniBrowserSvcEnum(mb_provider).getFirst(); +} + +MiniBrowserWnd::~MiniBrowserWnd() { + if (mbsvc) { + if (mb) mbsvc->destroyMiniBrowser(mb); + WASABI_API_SVC->service_release(mbsvc); + } +} + +int MiniBrowserWnd::onInit() { + int r = MBWND_PARENT::onInit(); + if (mb) { + mb->minibrowser_getRootWnd()->setStartHidden(1); + mb->minibrowser_getRootWnd()->setParent(this); + r &= mb->minibrowser_getRootWnd()->init(this); + } + onSetVisible(1); + return r; +} + +void MiniBrowserWnd::onSetVisible(int i) { + MBWND_PARENT::onSetVisible(i); + if (i) { + if (!mb && mbsvc) { + mb = mbsvc->createMiniBrowser(); + if (mb) { + mb->minibrowser_addCB(this); + mb->minibrowser_getRootWnd()->setStartHidden(1); + mb->minibrowser_getRootWnd()->setParent(this); + mb->minibrowser_getRootWnd()->init(this); + if (isPostOnInit()) + onResize(); + } + } + } else { + if (mb) { + mbsvc->destroyMiniBrowser(mb); + mb = NULL; + } + } + if (mb && mb->minibrowser_getRootWnd()) { + mb->minibrowser_getRootWnd()->setVisible(i); + } +} + +int MiniBrowserWnd::onResize() { + int r = MBWND_PARENT::onResize(); + if (mb && mb->minibrowser_getRootWnd()) { + RECT r; + getClientRect(&r); + mb->minibrowser_getRootWnd()->resize(r.left, r.top, r.right-r.left, r.bottom-r.top); + } + return r; +} + + +int MiniBrowserWnd::handleDesktopAlpha() { + if (mb && mb->minibrowser_getRootWnd()) return mb->minibrowser_getRootWnd()->handleDesktopAlpha(); + return 0; +} + +int MiniBrowserWnd::handleRatio() { + if (mb && mb->minibrowser_getRootWnd()) return mb->minibrowser_getRootWnd()->handleRatio(); + return 0; +} + +int MiniBrowserWnd::navigateUrl(const wchar_t *url) { + if (mb) return mb->minibrowser_navigateUrl(url); + return 0; +} + +int MiniBrowserWnd::back() { + if (mb) return mb->minibrowser_back(); + return 0; +} + +int MiniBrowserWnd::forward() { + if (mb) return mb->minibrowser_forward(); + return 0; +} + +int MiniBrowserWnd::home() { + if (mb) return mb->minibrowser_home(); + return 0; +} + +int MiniBrowserWnd::refresh() { + if (mb) return mb->minibrowser_refresh(); + return 0; +} + +int MiniBrowserWnd::stop() { + if (mb) return mb->minibrowser_stop(); + return 0; +} + +void MiniBrowserWnd::setTargetName(const wchar_t *name) { + if (mb) mb->minibrowser_setTargetName(name); +} + +const wchar_t *MiniBrowserWnd::getTargetName() { + if (mb) return mb->minibrowser_getTargetName(); + return NULL; +} + +const wchar_t *MiniBrowserWnd::getCurrentUrl() { + if (mb) return mb->minibrowser_getCurrentUrl(); + return NULL; +} + +int MiniBrowserWnd::onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame) { + return 0; // return 1 to cancel navigation +} + +void MiniBrowserWnd::onDocumentComplete(const wchar_t *url) { +} + +void MiniBrowserWnd::onDocumentReady(const wchar_t *url) { +} + +void MiniBrowserWnd::onNavigateError(const wchar_t *url, int status) { +} + +void MiniBrowserWnd::onMediaLink(const wchar_t *url) { +} + +const wchar_t* MiniBrowserWnd::messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3) +{ + return 0; +} + +int MiniBrowserWnd::minibrowsercb_onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame) { + return onBeforeNavigate(url, flags, frame); +} + +void MiniBrowserWnd::minibrowsercb_onDocumentComplete(const wchar_t *url) { + onDocumentComplete(url); +} + +void MiniBrowserWnd::minibrowsercb_onDocumentReady(const wchar_t *url) { + onDocumentReady(url); +} + +void MiniBrowserWnd::minibrowsercb_onMediaLink(const wchar_t *url) { + onMediaLink(url); +} + +void MiniBrowserWnd::minibrowsercb_onNavigateError(const wchar_t *url, int status) { + onNavigateError(url, status); +} + +const wchar_t* MiniBrowserWnd::minibrowsercb_messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3) +{ + return messageToMaki(str1, str2, i1, i2, i3); +} + +void MiniBrowserWnd::setScrollbarsFlag(int a) { + if (mb) mb->minibrowser_setScrollbarsFlag(a); +} + +MiniBrowser *MiniBrowserWnd::getBrowser() { + return mb; +} + diff --git a/Src/Wasabi/api/skin/widgets/mb/minibrowserwnd.h b/Src/Wasabi/api/skin/widgets/mb/minibrowserwnd.h new file mode 100644 index 00000000..093e466e --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/minibrowserwnd.h @@ -0,0 +1,57 @@ +#ifndef __MINIBROWSERWND_H +#define __MINIBROWSERWND_H + +#include <api/wnd/wndclass/guiobjwnd.h> +#include <api/service/svcs/svc_minibrowser.h> +#include <api/skin/widgets/mb/minibrowser.h> + +#define MBWND_PARENT GuiObjectWnd + +class MiniBrowserWnd : public MBWND_PARENT, public MiniBrowserCallbackI { + + public: + + MiniBrowserWnd(GUID mb_provider=GUID_MINIBROWSER_ANY); + virtual ~MiniBrowserWnd(); + + virtual int handleDesktopAlpha(); + virtual int handleRatio(); + virtual void onSetVisible(int i); + virtual int onResize(); + virtual int onInit(); + + virtual int navigateUrl(const wchar_t *url); + virtual int back(); + virtual int forward(); + virtual int home(); + virtual int refresh(); + virtual int stop(); + virtual void setTargetName(const wchar_t *name); + virtual const wchar_t *getTargetName(); + virtual const wchar_t *getCurrentUrl(); + virtual int onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame); // return 1 to cancel navigation + virtual void onDocumentComplete(const wchar_t *url); + virtual void onDocumentReady(const wchar_t *url); + virtual void onNavigateError(const wchar_t *url, int status); + virtual void onMediaLink(const wchar_t *url); + virtual const wchar_t* messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3); + + virtual void setScrollbarsFlag(int a); // BROWSER_SCROLLBARS_ALWAYS, BROWSER_SCROLLBARS_AUTO, BROWSER_SCROLLBARS_NEVER + + virtual int minibrowsercb_onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame); + virtual void minibrowsercb_onDocumentComplete(const wchar_t *url); + virtual void minibrowsercb_onDocumentReady(const wchar_t *url); + virtual void minibrowsercb_onMediaLink(const wchar_t *url); + virtual void minibrowsercb_onNavigateError(const wchar_t *url, int status); + virtual const wchar_t* minibrowsercb_messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3); + + virtual MiniBrowser *getBrowser(); + + private: + + MiniBrowser *mb; + svc_miniBrowser *mbsvc; +}; + +#endif + diff --git a/Src/Wasabi/api/skin/widgets/mb/scriptbrowser.cpp b/Src/Wasabi/api/skin/widgets/mb/scriptbrowser.cpp new file mode 100644 index 00000000..bb86a227 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/scriptbrowser.cpp @@ -0,0 +1,180 @@ +#include "precomp.h" + +#include "scriptbrowser.h" + +#include "main.h" + +#include "script/script.h" +#include "script/scriptmgr.h" +#include "script/vcpu.h" + +#include "mbmgr.h" + +BrowserScriptController _browserController; +BrowserScriptController *browserController = &_browserController; + +// -- Functions table ------------------------------------- +function_descriptor_struct BrowserScriptController::exportedFunction[] = { + {"gotoUrl", 1, (void*)ScriptBrowserWnd::script_vcpu_gotoUrl }, + {"back", 0, (void*)ScriptBrowserWnd::script_vcpu_back }, + {"forward", 0, (void*)ScriptBrowserWnd::script_vcpu_forward }, + {"home", 0, (void*)ScriptBrowserWnd::script_vcpu_home}, + {"refresh", 0, (void*)ScriptBrowserWnd::script_vcpu_refresh}, + {"setTargetName", 1, (void*)ScriptBrowserWnd::script_vcpu_setTargetName}, + {"onBeforeNavigate", 3, (void*)ScriptBrowserWnd::script_vcpu_onBeforeNavigate}, + {"onDocumentComplete", 1, (void*)ScriptBrowserWnd::script_vcpu_onDocumentComplete}, + +}; +// -------------------------------------------------------- + +const wchar_t *BrowserScriptController::getClassName() { + return L"Browser"; +} + +const wchar_t *BrowserScriptController::getAncestorClassName() { + return L"GuiObject"; +} + +ScriptObject *BrowserScriptController::instantiate() { + ScriptBrowserWnd *sb = new ScriptBrowserWnd; + ASSERT(sb != NULL); + return sb->getScriptObject(); +} + +void BrowserScriptController::destroy(ScriptObject *o) { + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd *>(o->vcpu_getInterface(browserGuid)); + ASSERT(sb != NULL); + delete sb; +} + +void *BrowserScriptController::encapsulate(ScriptObject *o) { + return NULL; // no encapsulation for browsers yet +} + +void BrowserScriptController::deencapsulate(void *o) { +} + +int BrowserScriptController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *BrowserScriptController::getExportedFunctions() { + return exportedFunction; +} + +GUID BrowserScriptController::getClassGuid() { + return browserGuid; +} + +ScriptBrowserWnd::ScriptBrowserWnd() { + getScriptObject()->vcpu_setInterface(browserGuid, (void *)static_cast<ScriptBrowserWnd *>(this)); + getScriptObject()->vcpu_setClassName("Browser"); + getScriptObject()->vcpu_setController(browserController); +} + +ScriptBrowserWnd::~ScriptBrowserWnd() { +} + +int ScriptBrowserWnd::setXmlParam(const char *name, const char *value) { + if (SCRIPTBROWSERWND_PARENT::setParam(name, value)) return 1; + else if (STRCASEEQL(name,"url")) defurl = value; + else if (STRCASEEQL(name,"mainmb")) setMainMB(WTOI(value)); + else if (STRCASEEQL(name,"targetname")) setTargetName(value); + else return 0; + return 1; +} + +int ScriptBrowserWnd::onInit() { + SCRIPTBROWSERWND_PARENT::onInit(); + if (!defurl.isempty()) navigateUrl(defurl); + return 1; +} + +void ScriptBrowserWnd::setMainMB(int m) { + if (m) + MBManager::setMainMB(this); + else + if (MBManager::getMainMB() == this) + MBManager::setMainMB(NULL); +} + +int ScriptBrowserWnd::onBeforeNavigate(const char *url, int flags, const char *frame) { + if (SCRIPTBROWSERWND_PARENT::onBeforeNavigate(url, flags, frame)) return 1; + scriptVar v = script_vcpu_onBeforeNavigate(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(url), MAKE_SCRIPT_INT(flags), MAKE_SCRIPT_STRING(frame)); + if (SOM::isNumeric(&v)) return GET_SCRIPT_BOOLEAN(v); + return 0; +} + +void ScriptBrowserWnd::onDocumentComplete(const char *url) { + SCRIPTBROWSERWND_PARENT::onDocumentComplete(url); + script_vcpu_onDocumentComplete(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(url)); +} + + +// VCPU + +scriptVar ScriptBrowserWnd::script_vcpu_gotoUrl(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url) { + SCRIPT_FUNCTION_INIT + ASSERT(url.type == SCRIPT_STRING); + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) sb->navigateUrl(url.data.sdata); + RETURN_SCRIPT_VOID; +} + +scriptVar ScriptBrowserWnd::script_vcpu_back(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) sb->back(); + RETURN_SCRIPT_VOID; +} + +scriptVar ScriptBrowserWnd::script_vcpu_forward(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) sb->forward(); + RETURN_SCRIPT_VOID; +} + +scriptVar ScriptBrowserWnd::script_vcpu_home(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) sb->home(); + RETURN_SCRIPT_VOID; +} + +scriptVar ScriptBrowserWnd::script_vcpu_refresh(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) sb->refresh(); + RETURN_SCRIPT_VOID; +} + +scriptVar ScriptBrowserWnd::script_vcpu_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) sb->stop(); + RETURN_SCRIPT_VOID; +} + +scriptVar ScriptBrowserWnd::script_vcpu_setTargetName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name) { + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) sb->setTargetName(GET_SCRIPT_STRING(name)); + RETURN_SCRIPT_VOID; +} + +scriptVar ScriptBrowserWnd::script_vcpu_onBeforeNavigate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url, scriptVar flags, scriptVar framename) { + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS3(o, browserController, url, flags, framename); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT3(o, url, flags, framename); +} + +scriptVar ScriptBrowserWnd::script_vcpu_onDocumentComplete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url) { + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, browserController, url); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, url); +} + + diff --git a/Src/Wasabi/api/skin/widgets/mb/scriptbrowser.h b/Src/Wasabi/api/skin/widgets/mb/scriptbrowser.h new file mode 100644 index 00000000..3ff2b5d0 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/scriptbrowser.h @@ -0,0 +1,63 @@ +#ifndef _SCRIPTBROWSER_H +#define _SCRIPTBROWSER_H + +#include <api/skin/widgets/mb/minibrowserwnd.h> +#include <api/script/script.h> +#include <api/script/objects/guiobj.h> + +class BrowserScriptController : public GuiObjectScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + 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); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern BrowserScriptController *browserController; + + +#define SCRIPTBROWSERWND_PARENT MiniBrowserWnd +class ScriptBrowserWnd : public SCRIPTBROWSERWND_PARENT { +public: + + ScriptBrowserWnd(); + virtual ~ScriptBrowserWnd(); + + void setMainMB(int m); + virtual int setXmlParam(const wchar_t *name, const wchar_t *value); + virtual int onInit(); + + virtual int handleDesktopAlpha() { return 0; } // showing the browser will turn off desktop alpha on the parent layout + + virtual void onDocumentComplete(const char *url); + virtual int onBeforeNavigate(const char *url, int flags, const char *frame); + +public: + static scriptVar script_vcpu_gotoUrl(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url); + static scriptVar script_vcpu_back(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_forward(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_home(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_refresh(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_setTargetName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name); + static scriptVar script_vcpu_onDocumentComplete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url); + static scriptVar script_vcpu_onBeforeNavigate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url, scriptVar flags, scriptVar framename); + +private: + + String defurl; +}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/mb/sharedminibrowser.cpp b/Src/Wasabi/api/skin/widgets/mb/sharedminibrowser.cpp new file mode 100644 index 00000000..f22f3580 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/sharedminibrowser.cpp @@ -0,0 +1,39 @@ +#include "precomp.h" +#include "sharedminibrowser.h" +#include "wnds/skinwnd.h" +#include "../studio/api.h" +#include "../common/mainminibrowser.h" + +void SharedMiniBrowser::navigateUrl(const char *url) { + if (!m_monitor) { + m_monitor = new SkinMonitor(); + } + + if (!MainMiniBrowser::getScriptObject()) { + + if (!m_inserted) { + String xml = "buf:\n"; + xml += "<WinampAbstractionLayer>\n"; + xml += " <groupdef id=\"addon.shared.minibrowser\" name=\"MiniBrowser\">\n"; + xml += " <browser mainmb=\"1\" x=\"0\" y=\"0\" w=\"0\" h=\"0\" relatw=\"1\" relath=\"1\" />\n"; + xml += " </groupdef>\n"; + xml += "</WinampAbstractionLayer>\n"; + WASABI_API_SKIN->loadSkinFile(xml); + m_inserted = 1; + } + + SkinWnd("addon.shared.minibrowser", WASABISTDCONTAINER_RESIZABLE_NOSTATUS); + ASSERTPR(MainMiniBrowser::getScriptObject() != NULL, "Something is really wrong with wasabi"); + } + + MainMiniBrowser::navigateUrl(url); + MainMiniBrowser::popMb(); +} + +void SharedMiniBrowser::shutdown() { + if (m_monitor) delete m_monitor; + m_monitor = NULL; +} + +int SharedMiniBrowser::m_inserted = 0; +SkinMonitor *SharedMiniBrowser::m_monitor = NULL;
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/mb/sharedminibrowser.h b/Src/Wasabi/api/skin/widgets/mb/sharedminibrowser.h new file mode 100644 index 00000000..57dbf15c --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/sharedminibrowser.h @@ -0,0 +1,33 @@ +#ifndef _SHAREDMINIBROWSER_H +#define _SHAREDMINIBROWSER_H + +#include "../studio/skincb.h" + +class SkinMonitor; + +class SharedMiniBrowser { +public: + static void navigateUrl(const char *url); + static void shutdown(); + + static int m_inserted; + static SkinMonitor *m_monitor; + +}; + +class SkinMonitor : public SkinCallbackI { +public: + SkinMonitor() { + WASABI_API_SYSCB->syscb_registerCallback(this); + } + virtual ~SkinMonitor() { + WASABI_API_SYSCB->syscb_deregisterCallback(this); + } + virtual int skincb_onReset() { + SharedMiniBrowser::m_inserted = 0; + return 0; + } +}; + + +#endif // _SHAREDMINIBROWSER_H diff --git a/Src/Wasabi/api/skin/widgets/mb/xuibrowser.cpp b/Src/Wasabi/api/skin/widgets/mb/xuibrowser.cpp new file mode 100644 index 00000000..a8c82408 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/xuibrowser.cpp @@ -0,0 +1,385 @@ +#include <precomp.h> +#include "xuibrowser.h" + +const wchar_t browserXuiObjectStr[] = L"Browser"; // This is the xml tag +char browserXuiSvcName[] = "Browser xui object"; // this is the name of the xuiservice + +XMLParamPair ScriptBrowserWnd::params[] = { + {BROWSER_SETMAINMB, L"MAINMB"}, + {BROWSER_SETSCROLLBARS, L"SCROLLBARS"}, + {BROWSER_SETTARGETNAME, L"TARGETNAME"}, + {BROWSER_SETURL, L"URL"}, + }; + +ScriptBrowserWnd::ScriptBrowserWnd() +{ + getScriptObject()->vcpu_setInterface(browserGuid, (void *)static_cast<ScriptBrowserWnd *>(this)); + getScriptObject()->vcpu_setClassName(L"Browser"); // this is the script class name + getScriptObject()->vcpu_setController(browserController); + + myxuihandle = newXuiHandle(); +CreateXMLParameters(myxuihandle); +} + +void ScriptBrowserWnd::CreateXMLParameters(int master_handle) +{ + //SCRIPTBROWSERWND_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +ScriptBrowserWnd::~ScriptBrowserWnd() +{ + + if (WASABI_API_MAKI->maki_getObjectAtom(MAIN_BROWSER_ATOM_NAME) == getScriptObject()) + WASABI_API_MAKI->maki_setObjectAtom(MAIN_BROWSER_ATOM_NAME, NULL); +} + +int ScriptBrowserWnd::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) +{ + if (xuihandle != myxuihandle) + return SCRIPTBROWSERWND_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) + { + case BROWSER_SETURL: + setUrl(value); + break; + case BROWSER_SETMAINMB: + setMainMB(WTOI(value)); + break; + case BROWSER_SETTARGETNAME: + setTargetName(value); + break; + case BROWSER_SETSCROLLBARS: + setScrollbarsFlag(translateScrollbarFlag(value)); + break; + default: + return 0; + } + return 1; +} + +int ScriptBrowserWnd::translateScrollbarFlag(const wchar_t *scrollbarflag) +{ + if (WCSCASEEQLSAFE(scrollbarflag, L"auto")) return MiniBrowser::BROWSER_SCROLLBARS_AUTO; + if (WCSCASEEQLSAFE(scrollbarflag, L"never")) return MiniBrowser::BROWSER_SCROLLBARS_NEVER; + if (WCSCASEEQLSAFE(scrollbarflag, L"always")) return MiniBrowser::BROWSER_SCROLLBARS_ALWAYS; + if (WCSCASEEQLSAFE(scrollbarflag, L"default")) return MiniBrowser::BROWSER_SCROLLBARS_DEFAULT; // as specified by HTML content + return MiniBrowser::BROWSER_SCROLLBARS_AUTO; +} + +void ScriptBrowserWnd::onSetVisible(int v) +{ + SCRIPTBROWSERWND_PARENT::onSetVisible(v); + if (v && !defurl.isempty() && _wcsicmp(defurl, getCurrentUrl() ? getCurrentUrl() : L"")) + navigateUrl(defurl); +} + +void ScriptBrowserWnd::setMainMB(int m) +{ + if (m) + WASABI_API_MAKI->maki_setObjectAtom(MAIN_BROWSER_ATOM_NAME, getScriptObject()); + else + if (WASABI_API_MAKI->maki_getObjectAtom(MAIN_BROWSER_ATOM_NAME) == getScriptObject()) + WASABI_API_MAKI->maki_setObjectAtom(MAIN_BROWSER_ATOM_NAME, NULL); +} + +void ScriptBrowserWnd::setUrl(const wchar_t *url) +{ + defurl = url; + if (isVisible()) + { + if (!defurl.isempty()) + navigateUrl(defurl); + } +} + +void ScriptBrowserWnd::setCancelIEErrorPage(bool cancel) +{ + MiniBrowser *browser = getBrowser(); + if (browser) browser->minibrowser_setCancelIEErrorPage(cancel); +} + +void ScriptBrowserWnd::Scrape() +{ + MiniBrowser *browser = getBrowser(); + if (browser) browser->minibrowser_scrape(); +} + +void ScriptBrowserWnd::getDocumentTitle(wchar_t *str, size_t len) +{ + MiniBrowser *browser = getBrowser(); + if (browser) + browser->minibrowser_getDocumentTitle(str, len); + else + str[0]=0; +} + +int ScriptBrowserWnd::navigateUrl(const wchar_t *url) +{ + defurl = url; + return SCRIPTBROWSERWND_PARENT::navigateUrl(url); +} + +int ScriptBrowserWnd::onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame) +{ + if (SCRIPTBROWSERWND_PARENT::onBeforeNavigate(url, flags, frame)) return 1; + scriptVar v = BrowserScriptController::browser_onBeforeNavigate(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(url), MAKE_SCRIPT_INT(flags), MAKE_SCRIPT_STRING(frame)); + if (v.type != SCRIPT_VOID) + return GET_SCRIPT_BOOLEAN(v); + return 0; +} + +void ScriptBrowserWnd::onDocumentComplete(const wchar_t *url) +{ + SCRIPTBROWSERWND_PARENT::onDocumentComplete(url); + if (url) + BrowserScriptController::browser_onDocumentComplete(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(url)); +} + +void ScriptBrowserWnd::onDocumentReady(const wchar_t *url) +{ + SCRIPTBROWSERWND_PARENT::onDocumentComplete(url); + if (url) + BrowserScriptController::browser_onDocumentReady(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(url)); +} + +void ScriptBrowserWnd::onNavigateError(const wchar_t *url, int status) +{ + SCRIPTBROWSERWND_PARENT::onNavigateError(url, status); + BrowserScriptController::browser_onNavigateError(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(url), MAKE_SCRIPT_INT(status)); +} + +void ScriptBrowserWnd::onMediaLink(const wchar_t *url) +{ + SCRIPTBROWSERWND_PARENT::onMediaLink(url); + if (url) + BrowserScriptController::browser_onMediaLink(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(url)); +} + +const wchar_t * ScriptBrowserWnd::messageToMaki(wchar_t* str1, wchar_t* str2, int intval1, int intval2, int intval3) +{ + const wchar_t* ret = SCRIPTBROWSERWND_PARENT::messageToMaki(str1, str2, intval1, intval2, intval3); + if (ret) return ret; + + scriptVar v = BrowserScriptController::browser_messageToMaki(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(str1), MAKE_SCRIPT_STRING(str2), MAKE_SCRIPT_INT(intval1), MAKE_SCRIPT_INT(intval2), MAKE_SCRIPT_INT(intval3)); + if (v.type == SCRIPT_STRING) + return v.data.sdata; + return 0; +} + +const wchar_t * ScriptBrowserWnd::messageToJS(const wchar_t* str1, const wchar_t* str2, int i1, int i2, int i3) +{ + MiniBrowser *browser = getBrowser(); + if (browser) return browser->minibrowser_messageToJS(str1, str2, i1, i2, i3); + return 0; +} + +// ----------------------------------------------------------------------- +// Script Object + +BrowserScriptController _browserController; +BrowserScriptController *browserController = &_browserController; + +// -- Functions table ------------------------------------- +function_descriptor_struct BrowserScriptController::exportedFunction[] = { + {L"gotoUrl", 1, (void*)BrowserScriptController::browser_navigateUrl }, + {L"navigateUrl", 1, (void*)BrowserScriptController::browser_navigateUrl }, + {L"back", 0, (void*)BrowserScriptController::browser_back }, + {L"forward", 0, (void*)BrowserScriptController::browser_forward }, + {L"home", 0, (void*)BrowserScriptController::browser_home}, + {L"stop", 0, (void*)BrowserScriptController::browser_stop}, + {L"refresh", 0, (void*)BrowserScriptController::browser_refresh}, + {L"scrape", 0, (void*)BrowserScriptController::browser_scrape}, + {L"setTargetName", 1, (void*)BrowserScriptController::browser_setTargetName}, + {L"onBeforeNavigate", 3, (void*)BrowserScriptController::browser_onBeforeNavigate}, + {L"onDocumentComplete", 1, (void*)BrowserScriptController::browser_onDocumentComplete}, + {L"onDocumentReady", 1, (void*)BrowserScriptController::browser_onDocumentReady}, + {L"onNavigateError", 2, (void*)BrowserScriptController::browser_onNavigateError}, + {L"onMediaLink", 1, (void*)BrowserScriptController::browser_onMediaLink}, + {L"getDocumentTitle", 0, (void*)BrowserScriptController::browser_getDocumentTitle}, + {L"setCancelIEErrorPage",1, (void*)BrowserScriptController::browser_setCancelIEErrorPage}, + {L"messageToMaki", 5, (void*)BrowserScriptController::browser_messageToMaki}, + {L"messageToJS", 5, (void*)BrowserScriptController::browser_messageToJS}, + }; + +ScriptObject *BrowserScriptController::instantiate() +{ + ScriptBrowserWnd *sb = new ScriptBrowserWnd; + ASSERT(sb != NULL); + return sb->getScriptObject(); +} + +void BrowserScriptController::destroy(ScriptObject *o) +{ + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd *>(o->vcpu_getInterface(browserGuid)); + ASSERT(sb != NULL); + delete sb; +} + +void *BrowserScriptController::encapsulate(ScriptObject *o) +{ + return NULL; // no encapsulation for browsers yet +} + +void BrowserScriptController::deencapsulate(void *o) +{} + +int BrowserScriptController::getNumFunctions() +{ + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *BrowserScriptController::getExportedFunctions() +{ + return exportedFunction; +} + + +scriptVar BrowserScriptController::browser_navigateUrl(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url) +{ + SCRIPT_FUNCTION_INIT + ASSERT(url.type == SCRIPT_STRING); + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) sb->navigateUrl(url.data.sdata); + RETURN_SCRIPT_VOID; +} + +scriptVar BrowserScriptController::browser_back(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) sb->back(); + RETURN_SCRIPT_VOID; +} + +scriptVar BrowserScriptController::browser_forward(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) sb->forward(); + RETURN_SCRIPT_VOID; +} + +scriptVar BrowserScriptController::browser_home(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) sb->home(); + RETURN_SCRIPT_VOID; +} + +scriptVar BrowserScriptController::browser_refresh(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) sb->refresh(); + RETURN_SCRIPT_VOID; +} + +scriptVar BrowserScriptController::browser_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) sb->stop(); + RETURN_SCRIPT_VOID; +} + +scriptVar BrowserScriptController::browser_scrape(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) sb->Scrape(); + RETURN_SCRIPT_VOID; +} + +scriptVar BrowserScriptController::browser_setCancelIEErrorPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar cancel) +{ + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) sb->setCancelIEErrorPage(!!cancel.data.idata); + RETURN_SCRIPT_VOID; +} + +scriptVar BrowserScriptController::browser_setTargetName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name) +{ + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) + sb->setTargetName(GET_SCRIPT_STRING(name)); + RETURN_SCRIPT_VOID; +} + +scriptVar BrowserScriptController::browser_onBeforeNavigate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url, scriptVar flags, scriptVar framename) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS3(o, browserController, url, flags, framename); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT3(o, url, flags, framename); +} + +scriptVar BrowserScriptController::browser_messageToMaki(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str1, scriptVar str2, scriptVar i1, scriptVar i2, scriptVar i3) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS5(o, browserController, str1, str2, i1, i2, i3); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT5(o, str1, str2, i1, i2, i3); +} + +scriptVar BrowserScriptController::browser_messageToJS(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str1, scriptVar str2, scriptVar i1, scriptVar i2, scriptVar i3) +{ + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + if (sb) + { + const wchar_t * ret = sb->messageToJS(str1.data.sdata, str2.data.sdata, i1.data.idata, i2.data.idata, i3.data.idata); + if (ret) + return MAKE_SCRIPT_STRING(ret); + } + return MAKE_SCRIPT_STRING(L""); +} + +scriptVar BrowserScriptController::browser_onDocumentComplete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, browserController, url); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, url); +} + +scriptVar BrowserScriptController::browser_onDocumentReady(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, browserController, url); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, url); +} + +scriptVar BrowserScriptController::browser_onNavigateError(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url, scriptVar status) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS2(o, browserController, url, status); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT2(o, url, status); +} + +scriptVar BrowserScriptController::browser_onMediaLink(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, browserController, url); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, url); +} + +static wchar_t docTitle[1024]; + +/*string*/ scriptVar BrowserScriptController::browser_getDocumentTitle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid)); + docTitle[0]=0; + if (sb) sb->getDocumentTitle(docTitle, 1024); + return MAKE_SCRIPT_STRING(docTitle); +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/mb/xuibrowser.h b/Src/Wasabi/api/skin/widgets/mb/xuibrowser.h new file mode 100644 index 00000000..90989240 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mb/xuibrowser.h @@ -0,0 +1,106 @@ +#ifndef __XUIBROWSER_H +#define __XUIBROWSER_H + +#include <api/skin/widgets/mb/minibrowserwnd.h> +#include <api/script/objcontroller.h> + +#define MAIN_BROWSER_ATOM_NAME L"browser.main.object" +#define SCRIPTBROWSERWND_PARENT MiniBrowserWnd + +// ----------------------------------------------------------------------------------------------------- +class ScriptBrowserWnd : public SCRIPTBROWSERWND_PARENT { + + public: + + ScriptBrowserWnd(); + virtual ~ScriptBrowserWnd(); + + virtual void onSetVisible(int v); + + // XuiObject + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + // MiniBrowserWnd + int onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame); + void onDocumentComplete(const wchar_t *url); + void onDocumentReady(const wchar_t *url); + void onNavigateError(const wchar_t *url, int status); + void onMediaLink(const wchar_t *url); + void getDocumentTitle(wchar_t *str, size_t len); + + virtual int navigateUrl(const wchar_t *url); + const wchar_t* messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3); + const wchar_t* messageToJS(const wchar_t* str1, const wchar_t* str2, int i1, int i2, int i3); + + // -- + + void setUrl(const wchar_t *url); + void setMainMB(int tf); + void Scrape(); // benski> added Aug 17 2007 + + void setCancelIEErrorPage(bool cancel); + +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + + enum { + BROWSER_SETURL = 0, + BROWSER_SETMAINMB, + BROWSER_SETTARGETNAME, + BROWSER_SETSCROLLBARS, + BROWSER_CANCELIEERRORPAGE, + }; +static XMLParamPair params[]; + int translateScrollbarFlag(const wchar_t *scrollbarflag); + + StringW defurl; + int myxuihandle; +}; + +// ----------------------------------------------------------------------------------------------------- +class BrowserScriptController : public ScriptObjectControllerI { + public: + + virtual const wchar_t *getClassName() { return L"Browser"; } + virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; } + virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); } + virtual int getNumFunctions(); + virtual const function_descriptor_struct *getExportedFunctions(); + virtual GUID getClassGuid() { return browserGuid; } + virtual ScriptObject *instantiate(); + virtual void destroy(ScriptObject *o); + virtual void *encapsulate(ScriptObject *o); + virtual void deencapsulate(void *o); + + public: + static scriptVar browser_navigateUrl(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url); + static scriptVar browser_back(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar browser_forward(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar browser_home(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar browser_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar browser_refresh(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar browser_scrape(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar browser_setTargetName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name); + static scriptVar browser_onDocumentComplete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url); + static scriptVar browser_onDocumentReady(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url); + static scriptVar browser_onNavigateError(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url, scriptVar status); + static scriptVar browser_onBeforeNavigate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url, scriptVar flags, scriptVar framename); + static scriptVar browser_messageToMaki(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str1, scriptVar str2, scriptVar i1, scriptVar i2, scriptVar i3); + static scriptVar browser_messageToJS(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str1, scriptVar str2, scriptVar i1, scriptVar i2, scriptVar i3); + static scriptVar browser_onMediaLink(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url); + static /*string*/ scriptVar browser_getDocumentTitle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar browser_setCancelIEErrorPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar cancel); + private: + + static function_descriptor_struct exportedFunction[]; +}; + +extern BrowserScriptController *browserController; + +extern const wchar_t browserXuiObjectStr[]; +extern char browserXuiSvcName[]; +class BrowserXuiSvc : public XuiObjectSvc<ScriptBrowserWnd, browserXuiObjectStr, browserXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/mouseredir.cpp b/Src/Wasabi/api/skin/widgets/mouseredir.cpp new file mode 100644 index 00000000..5fe58c15 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mouseredir.cpp @@ -0,0 +1,221 @@ +#include <precomp.h> +#include "mouseredir.h" + +#include <api/skin/widgets/group.h> +#include <api/script/scriptmgr.h> +#include <api/script/objects/smap.h> +#include <api/script/objects/sregion.h> +const wchar_t mouseRedirXuiObjectStr[] = L"MouseRedir"; // This is the xml tag +char mouseRedirXuiSvcName[] = "MouseRedir xui object"; // this is the name of the xuiservice + +XMLParamPair MouseRedir::params[] = { + {MOUSEREDIR_TARGET, L"target"}, + }; +MouseRedir::MouseRedir() +{ + getScriptObject()->vcpu_setInterface(mouseredirGuid, (void *)static_cast<MouseRedir *>(this)); + getScriptObject()->vcpu_setClassName(L"MouseRedir"); + getScriptObject()->vcpu_setController(mouseredirController); + rgn = NULL; + redirobject = NULL; + getGuiObject()->guiobject_setClickThrough(0); + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); +} + +void MouseRedir::CreateXMLParameters(int master_handle) +{ + //MOUSEREDIR_PARENT::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_REQUIRED); +} + +MouseRedir::~MouseRedir() +{ + delete rgn; +} + +int MouseRedir::setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) +{ + if (_xuihandle == xuihandle) + { + switch (xmlattributeid) + { + case MOUSEREDIR_TARGET: + setTarget(value); + return 1; + } + } + return MOUSEREDIR_PARENT::setXuiParam(_xuihandle, xmlattributeid, xmlattributename, value); +} + +int MouseRedir::onInit() +{ + MOUSEREDIR_PARENT::onInit(); + if (!deferedredirobjectid.isempty()) + doSetTarget(deferedredirobjectid); + deferedredirobjectid = L""; + return 1; +} + +int MouseRedir::mouseInRegion(int x, int y) +{ + if (!rgn) return 1; + RECT cr; + getClientRect(&cr); + POINT pt = {x - cr.left, y - cr.top}; + return rgn->ptInRegion(&pt); +} + +void MouseRedir::setRedirection(GuiObject *o) +{ + redirobject = o; +} + +GuiObject *MouseRedir::getRedirection() +{ + return redirobject; +} + +void MouseRedir::setTarget(const wchar_t *id) +{ + if (!isInited()) + deferedredirobjectid = id; + else + doSetTarget(id); +} + +void MouseRedir::doSetTarget(const wchar_t *id) +{ + Group *g = getGuiObject()->guiobject_getParentGroup(); + if (!g) return ; + GuiObject *o = g->getObject(id); + if (!o) return ; + redirobject = o; +} + +MouseRedirScriptController _mouseredirController; +MouseRedirScriptController *mouseredirController = &_mouseredirController; + +// -- Functions table ------------------------------------- +function_descriptor_struct MouseRedirScriptController::exportedFunction[] = { + {L"setRegionFromMap", 1, (void*)MouseRedir::script_vcpu_setRegionFromMap}, + {L"setRegion", 1, (void*)MouseRedir::script_vcpu_setRegion }, + {L"setRedirection", 1, (void*)MouseRedir::script_vcpu_setRedirection}, + {L"getRedirection", 0, (void*)MouseRedir::script_vcpu_getRedirection}, + }; +// -------------------------------------------------------- + + +const wchar_t *MouseRedirScriptController::getClassName() +{ + return L"MouseRedir"; +} + +const wchar_t *MouseRedirScriptController::getAncestorClassName() +{ + return L"GuiObject"; +} + +ScriptObject *MouseRedirScriptController::instantiate() +{ + MouseRedir *m = new MouseRedir; + if (!m) return NULL; + return m->getScriptObject(); +} + +void MouseRedirScriptController::destroy(ScriptObject *o) +{ + MouseRedir *obj = static_cast<MouseRedir*>(o->vcpu_getInterface(mouseredirGuid)); + ASSERT(obj != NULL); + delete obj; +} + +void *MouseRedirScriptController::encapsulate(ScriptObject *o) +{ + return NULL; // no encapsulation for mouseredir yet +} + +void MouseRedirScriptController::deencapsulate(void *) +{} + + +int MouseRedirScriptController::getNumFunctions() +{ + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *MouseRedirScriptController::getExportedFunctions() +{ + return exportedFunction; +} + +GUID MouseRedirScriptController::getClassGuid() +{ + return mouseredirGuid; +} + +//--------------------------------------------------------------------------- + + +void MouseRedir::setRegionFromMap(SMap *map, int byte, int inversed) +{ + if (rgn) + { + delete rgn; + rgn = NULL; + } + rgn = new RegionI(map->getBitmap(), NULL, 0, 0, FALSE, 1, (unsigned char)byte, inversed); +} + +void MouseRedir::setRegion(SRegion *reg) +{ + if (rgn) { delete rgn; rgn = NULL; } + if (!reg) { invalidate(); return ; } + rgn = new RegionI(); + rgn->addRegion(reg->getRegion()); +} + +ifc_window *MouseRedir::getForwardWnd() +{ + if (redirobject) return redirobject->guiobject_getRootWnd(); + return this; +} + +scriptVar MouseRedir::script_vcpu_setRedirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj) +{ + SCRIPT_FUNCTION_INIT; + MouseRedir *mr = static_cast<MouseRedir *>(o->vcpu_getInterface(mouseredirGuid)); + if (mr) mr->setRedirection(static_cast<GuiObject *>(GET_SCRIPT_OBJECT_AS(obj, guiObjectGuid))); + RETURN_SCRIPT_VOID; +} + +scriptVar MouseRedir::script_vcpu_getRedirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT; + MouseRedir *mr = static_cast<MouseRedir *>(o->vcpu_getInterface(mouseredirGuid)); + return MAKE_SCRIPT_OBJECT(mr ? mr ->getRedirection()->guiobject_getScriptObject() : NULL); +} + +scriptVar MouseRedir::script_vcpu_setRegionFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inv) +{ + SCRIPT_FUNCTION_INIT; + ASSERT(SOM::isNumeric(&byte)); + ASSERT(SOM::isNumeric(&inv)); + MouseRedir *mr = static_cast<MouseRedir *>(o->vcpu_getInterface(mouseredirGuid)); + SMap *sm = static_cast<SMap*>(GET_SCRIPT_OBJECT_AS(map, mapGuid)); + if (mr) mr->setRegionFromMap(sm, SOM::makeInt(&byte), SOM::makeInt(&inv)); + RETURN_SCRIPT_VOID; +} + +scriptVar MouseRedir::script_vcpu_setRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg) +{ + SCRIPT_FUNCTION_INIT; + MouseRedir *mr = static_cast<MouseRedir *>(o->vcpu_getInterface(mouseredirGuid)); + SRegion *r = static_cast<SRegion *>(GET_SCRIPT_OBJECT_AS(reg, regionGuid)); + if (mr) mr->setRegion(r); + RETURN_SCRIPT_VOID; +} + diff --git a/Src/Wasabi/api/skin/widgets/mouseredir.h b/Src/Wasabi/api/skin/widgets/mouseredir.h new file mode 100644 index 00000000..c852c34e --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/mouseredir.h @@ -0,0 +1,88 @@ +//PORTABLE +#ifndef _MOUSEREDIR_H +#define _MOUSEREDIR_H + +#include <api/script/script.h> +#include <api/script/objects/guiobj.h> +#include <bfc/string/StringW.h> +#include <api/wnd/wndclass/guiobjwnd.h> + +#define MOUSEREDIR_PARENT GuiObjectWnd + +// {9B2E341B-6C98-40fa-8B85-0C1B6EE89405} +static const GUID mouseredirGuid = +{ 0x9b2e341b, 0x6c98, 0x40fa, { 0x8b, 0x85, 0xc, 0x1b, 0x6e, 0xe8, 0x94, 0x5 } }; + + +class SMap; +class SRegion; + +class MouseRedirScriptController : public GuiObjectScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + virtual int getNumFunctions(); + virtual const function_descriptor_struct *getExportedFunctions(); + virtual GUID getClassGuid(); + virtual ScriptObject *instantiate(); + virtual void *encapsulate(ScriptObject *o); + virtual void destroy(ScriptObject *o); + virtual void deencapsulate(void *o); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern MouseRedirScriptController *mouseredirController; + +class MouseRedir : public MOUSEREDIR_PARENT { +public: + MouseRedir(); + virtual ~MouseRedir(); + + virtual int onInit(); + + void setTarget(const wchar_t *id); + + void setRedirection(GuiObject *o); + GuiObject *getRedirection(); + void setRegionFromMap(SMap *map, int byte, int inversed); + void setRegion(SRegion *reg); + virtual int mouseInRegion(int x, int y); + + virtual ifc_window *getForwardWnd(); + virtual int setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + +protected: +/*static */void CreateXMLParameters(int master_handle); + enum { + MOUSEREDIR_TARGET=0, + }; + + +private: + GuiObject *redirobject; + StringW deferedredirobjectid; + int xuihandle; + static XMLParamPair params[]; + + void doSetTarget(const wchar_t *id); + RegionI *rgn; + +public: + static scriptVar script_vcpu_setRedirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj); + static scriptVar script_vcpu_getRedirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_setRegionFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inv); + static scriptVar script_vcpu_setRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg); +}; + +extern const wchar_t mouseRedirXuiObjectStr[]; +extern char mouseRedirXuiSvcName[]; +class MouseRedirXuiSvc : public XuiObjectSvc<MouseRedir, mouseRedirXuiObjectStr, mouseRedirXuiSvcName> {}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/objdirwnd.cpp b/Src/Wasabi/api/skin/widgets/objdirwnd.cpp new file mode 100644 index 00000000..d49515a6 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/objdirwnd.cpp @@ -0,0 +1,227 @@ +#include <precomp.h> + +#include "objdirwnd.h" + +#include <api/wnd/contextmenu.h> +#include <api/wnd/dragitemi.h> +#include <api/skin/widgets/customobject.h> +#include <bfc/parse/pathparse.h> + +ObjDirWnd::ObjDirWnd() : + objdir(NULL), displaygroup(NULL) { } + +ObjDirWnd::~ObjDirWnd() { + WASABI_API_SVC->service_release(objdir); + if (displaygroup != NULL) WASABI_API_SKIN->group_destroy(displaygroup); +} + +void ObjDirWnd::setTargetDirName(const wchar_t *dirname) { + objectDirName = dirname; +//FUCKO: reset here +} + +void ObjDirWnd::setActionTarget(const wchar_t *targetname) { + objectDirTarget = targetname; +} + +void ObjDirWnd::setDisplayTarget(const wchar_t *name) { + displayTarget = name; +} + +void ObjDirWnd::setDefaultDisplay(const wchar_t *display) { + defaultDisplay = display; +} + +int ObjDirWnd::onInit() { + OBJDIRWND_PARENT::onInit(); + + setSorted(TRUE); + + ASSERT(!objectDirName.isempty()); + objdir = ObjectDirEnum(objectDirName).getNext(); + + if (objdir != NULL) { + setHilitedColor(L"pledit.currentOutline");//FUCKO from service + viewer_addViewItem(objdir); + + int nobj = objdir->getNumObjects(); + for (int i = 0; i < nobj; i++) { + ObjectHandle hand = objdir->enumObject(i); + folderify(createObjItem(hand)); + } + } + + return 1; +} + +int ObjDirWnd::onContextMenu(int x, int y) { + if (objdir != NULL) { + DragItemT<svc_objectDir> di(objdir); + ContextMenu(this, &di); + } + return 1; +} + +int ObjDirWnd::onPreItemContextMenu(TreeItem *item, int x, int y) { + BaseObjItem *boi = static_cast<BaseObjItem*>(item); + if (boi->getParam() == OBJTYPE_OBJ) { + ObjItem *oi = static_cast<ObjItem*>(item); + int r = objdir->contextMenu(this, x, y, oi->getObjectHandle()); + if (r == -1) { + editItemLabel(item); + } + } else { + // handle other item types here + } + return 1; +} + +int ObjDirWnd::compareItem(TreeItem *p1, TreeItem *p2) { + BaseObjItem *b1 = static_cast<BaseObjItem*>(p1); + BaseObjItem *b2 = static_cast<BaseObjItem*>(p2); + int r = CMP3(b1->sortorder, b2->sortorder); + if (r == 0) return OBJDIRWND_PARENT::compareItem(p1, p2); + return r; +} + +int ObjDirWnd::viewer_onEvent(svc_objectDir *item, int event, intptr_t param2, void *ptr, size_t ptrlen) { + switch (event) { + case svc_objectDir::Event_OBJECT_ADDED: { + int sel_after = (enumAllItems(0) == NULL); + ObjItem *oi = createObjItem(param2); + folderify(oi); + if (sel_after) selectItemDeferred(oi); + } + break; + case svc_objectDir::Event_OBJECT_REMOVED: { + ObjItem *pli = getObjItemForHandle(param2); + delItemDeferred(pli); + } + break; + case svc_objectDir::Event_OBJECT_LABELCHANGE: { + ObjItem *pli = getObjItemForHandle(param2); + const wchar_t *name = objdir->getObjectLabel(pli->getObjectHandle()); + pli->setLabel(name); + } + break; + case svc_objectDir::Event_OBJECT_PATHCHANGE: { + ObjItem *pli = getObjItemForHandle(param2); + folderify(pli); + } + break; + case svc_objectDir::Event_OBJECT_SORTORDERCHANGE: { + ObjItem *pli = getObjItemForHandle(param2); + ASSERT(pli != NULL); + pli->sortorder = objdir->getObjectSortOrder(param2); + sortTreeItems(); + } + break; + } + return 1; +} + +ObjItem *ObjDirWnd::createObjItem(ObjectHandle handle) { + ObjItem *ret = new ObjItem(handle, objdir->getObjectLabel(handle)); + const wchar_t *nn = objdir->getObjectIcon(handle); + if (nn && *nn) { + SkinBitmap *ic = new SkinBitmap(nn); + ret->setIcon(ic); + } + ret->hittable = objdir->getObjectSelectable(handle); + ret->sortorder = objdir->getObjectSortOrder(handle); + return ret; +} + +ObjItem *ObjDirWnd::getObjItemForHandle(ObjectHandle handle) { + for (int i = 0; ; i++) { + TreeItem *it = enumAllItems(i); + if (it == NULL) break; + BaseObjItem *boi = static_cast<BaseObjItem*>(it); + if (boi->getParam() != OBJTYPE_OBJ) continue; + ObjItem *plit = static_cast<ObjItem *>(it); + if (plit->getObjectHandle() == handle) return plit; + } + return NULL; +} + +void ObjDirWnd::folderify(ObjItem *item) { + if (item->getTree() != NULL) + removeTreeItem(item); + + PathParserW pp(objdir->getObjectPath(item->getObjectHandle())); + TreeItem *prevpar = NULL; + + for (int i = 0; i < pp.getNumStrings(); i++) { + TreeItem *newpar = NULL; + // check for already-existing folder + for (int j = 0; ; j++) { + if (prevpar == NULL) { // search top level + newpar = enumRootItem(j); + } else { // search prevpar children + newpar = prevpar->getNthChild(j); + } + + if (newpar == NULL) break; // out of thingies + BaseObjItem *boi = static_cast<BaseObjItem*>(newpar); + if (boi->getParam() != OBJTYPE_FOLDER) continue; + ObjDirFolderItem *fi = static_cast<ObjDirFolderItem*>(newpar); + if (fi->dying) continue; + + if (!wcscmp(boi->getLabel(), pp.enumString(i))) { + break; + } + } + if (newpar == NULL) { + newpar = new ObjDirFolderItem(pp.enumString(i)); + addTreeItem(newpar, prevpar, FALSE, TRUE); + expandItemDeferred(newpar); + } + prevpar = newpar; + } + + // now attach it + addTreeItem(item, prevpar); +} + +void ObjDirWnd::onItemSelected(TreeItem *item) { + BaseObjItem *boi = static_cast<BaseObjItem*>(item); + if (boi->getParam() == OBJTYPE_OBJ) { + ObjItem *objitem = static_cast<ObjItem *>(item); + ObjectHandle handle = objitem->getObjectHandle(); + StringW display(objdir->getObjectDisplayGroup(handle)); + if (display.isempty()) display = defaultDisplay; + if (!display.isempty()) + { + GuiObject *go = findObject(displayTarget); + if (go != NULL) + { + CustomObject *co = static_cast<CustomObject *>(go->guiobject_getScriptObject()->vcpu_getInterface(customObjectGuid)); + if (co != NULL) { + if (displaygroupname != display) { + co->customobject_setRootWnd(NULL); + ifc_window *prev = displaygroup; + if (prev != NULL) WASABI_API_SKIN->group_destroy(prev); + displaygroup = WASABI_API_SKIN->group_create(display); + co->customobject_setRootWnd(displaygroup); + displaygroupname = display; + } + } + } + } + // tell the objdir + objdir->onAction(svc_objectDir::ODACTION_SELECTED, this, objectDirTarget, handle); + } else { + // handle other item types here + } +} + +void ObjDirWnd::onItemDeselected(TreeItem *item) { + BaseObjItem *boi = static_cast<BaseObjItem*>(item); + if (boi->getParam() == OBJTYPE_OBJ) { + ObjItem *objitem = static_cast<ObjItem *>(item); + ObjectHandle handle = objitem->getObjectHandle(); + objdir->onAction(svc_objectDir::ODACTION_DESELECTED, this, objectDirTarget, handle); + } else { + // handle other item types here + } +} diff --git a/Src/Wasabi/api/skin/widgets/objdirwnd.h b/Src/Wasabi/api/skin/widgets/objdirwnd.h new file mode 100644 index 00000000..fc6ce78f --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/objdirwnd.h @@ -0,0 +1,90 @@ +#ifndef _OBJDIRWND_H +#define _OBJDIRWND_H + +#include <api/wnd/wndclass/treewnd.h> +#include <api/service/svcs/svc_objectdir.h> +#include <bfc/depview.h> + +enum OBJ_type { OBJTYPE_OBJ, OBJTYPE_FOLDER }; +class BaseObjItem : public TreeItemParam<OBJ_type> { +protected: + BaseObjItem(OBJ_type type, const wchar_t *label) : TreeItemParam<OBJ_type>(type, label), sortorder(0) { } +public: + int sortorder; +}; + +class ObjItem : public BaseObjItem { +public: + ObjItem(ObjectHandle _handle, const wchar_t *label=NULL) : hittable(TRUE), handle(_handle), BaseObjItem(OBJTYPE_OBJ, label) {} + + ObjectHandle getObjectHandle() const { return handle; } + + virtual int onBeginLabelEdit() { return 0; } // allow editing + virtual int isHitTestable() { return hittable; } + + int hittable; + +private: + ObjectHandle handle; +}; + +class ObjDirFolderItem : public BaseObjItem { +public: + ObjDirFolderItem(const wchar_t *label) : BaseObjItem(OBJTYPE_FOLDER, label), dying(0) { + setIcon(new SkinBitmap(L"player.button.thinger")); + } + virtual void onChildItemRemove(TreeItem *item) { + if (getNumChildren() == 0) { + dying = 1; + getTree()->delItemDeferred(this); + } + } + + int dying; +}; + +#define OBJDIRWND_PARENT TreeWnd +class ObjDirWnd : public OBJDIRWND_PARENT, DependentViewerTPtr<svc_objectDir> { +public: + ObjDirWnd(); + virtual ~ObjDirWnd(); + + void setTargetDirName(const wchar_t *dirname); + + void setActionTarget(const wchar_t *targetname); + + void setDisplayTarget(const wchar_t *name); + + void setDefaultDisplay(const wchar_t *display); + + virtual int onInit(); + + virtual int onContextMenu(int x, int y); + virtual int onPreItemContextMenu(TreeItem *item, int x, int y); + virtual int compareItem(TreeItem *p1, TreeItem *p2); + + virtual int viewer_onEvent(svc_objectDir *item, int event, intptr_t param2, void *ptr, size_t ptrlen); + +protected: + ObjItem *createObjItem(ObjectHandle handle); + ObjItem *getObjItemForHandle(ObjectHandle handle); + + void folderify(ObjItem *item); + +private: + virtual void onItemSelected(TreeItem *item); + virtual void onItemDeselected(TreeItem *item); + + svc_objectDir *objdir; + StringW objectDirName, objectDirTarget, displayTarget, defaultDisplay; + ifc_window *displaygroup; + StringW displaygroupname; +}; + +template <class TREEITEMCLASS> +class ObjDirWndT : public ObjDirWnd { +public: + virtual ObjItem *createObjItem(ObjectHandle handle) { return new TREEITEMCLASS(handle); } +}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/pathpicker.cpp b/Src/Wasabi/api/skin/widgets/pathpicker.cpp new file mode 100644 index 00000000..baa0c443 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/pathpicker.cpp @@ -0,0 +1,111 @@ +#include <precomp.h> +#include "pathpicker.h" +#include <api/script/objects/guiobject.h> +#include <api/script/scriptguid.h> +#include <api/script/objects/c_script/c_text.h> +#include <api/util/selectfile.h> + +#define PATHPICKER_MAIN_GROUP L"wasabi.pathpicker.main.group" +#define PATHPICKER_BUTTON L"pathpicker.button" +#define PATHPICKER_TEXT L"pathpicker.text" + +// ----------------------------------------------------------------------- +PathPicker::PathPicker() +{ + abstract_setAllowDeferredContent(1); + abstract_setContent(PATHPICKER_MAIN_GROUP); + clicks_button = NULL; + disable_cfg_event = 0; +} + +PathPicker::~PathPicker() { +} + +int PathPicker::onInit() { + int rt = PATHPICKER_PARENT::onInit(); + return rt; +} + +void PathPicker::abstract_onNewContent() { + PATHPICKER_PARENT::abstract_onNewContent(); + trapControls(); + updatePathInControl(); +} + +#ifdef WASABI_COMPILE_CONFIG +int PathPicker::onReloadConfig() { + int r = PATHPICKER_PARENT::onReloadConfig(); + disable_cfg_event = 1; + updatePathFromConfig(); // triggers onSelect + disable_cfg_event = 0; + return r; +} + +void PathPicker::updatePathFromConfig() { + + const wchar_t *val = getGuiObject()->guiobject_getCfgString(); + const wchar_t *old = getPath(); + if (old && val && !_wcsicmp(val, old)) return; + + setPath(val); +} +#endif + +void PathPicker::trapControls() { + delete clicks_button; + clicks_button = NULL; + + GuiObject *butGuiObj = getGuiObject()->guiobject_findObject(PATHPICKER_BUTTON); + if (butGuiObj) clicks_button = new PPClicksCallback(*butGuiObj, this); +} + +void PathPicker::clickCallback() { + SelectFile sf(this,0,0); + sf.setDefaultDir(getPath()); + if (sf.runSelector(L"directory",0,0)) { + StringW p = sf.getDirectory(); + if (p[wcslen(p-1)] != '/' && p[wcslen(p-1)] != '\\') + p += L"\\"; + setPath(p); + } +} + +void PathPicker::setDefault() { +#ifdef WASABI_COMPILE_CONFIG + onReloadConfig(); +#endif +} + +void PathPicker::setPath(const wchar_t *path) +{ + if (WCSCASEEQLSAFE(curpath, path)) return; + curpath = path; + onPathChanged(path); +} + +void PathPicker::onPathChanged(const wchar_t *newpath) { + updatePathInControl(); + if (!disable_cfg_event) { +#ifdef WASABI_COMPILE_CONFIG + if (newpath == NULL) + getGuiObject()->guiobject_setCfgString(L""); + else + getGuiObject()->guiobject_setCfgString(newpath); +#endif + } +} + +void PathPicker::updatePathInControl() { + GuiObject *content = getContent(); + if (content != NULL) { + GuiObject *text = content->guiobject_findObject(PATHPICKER_TEXT); + if (text != NULL) { + C_Text t(*text); + if (curpath.isempty()) + t.setText(L""); + else + t.setText(curpath); + } + } +} + diff --git a/Src/Wasabi/api/skin/widgets/pathpicker.h b/Src/Wasabi/api/skin/widgets/pathpicker.h new file mode 100644 index 00000000..37b9127b --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/pathpicker.h @@ -0,0 +1,183 @@ +#ifndef __PATHPICKER_H +#define __PATHPICKER_H + +#include <api/wnd/wndclass/guiobjwnd.h> +#include <api/script/objects/c_script/h_guiobject.h> +#include <api/script/objects/c_script/h_button.h> + +#define PATHPICKER_PARENT GuiObjectWnd + +class PPClicksCallback; +extern int __id; + + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class PathPicker : public PATHPICKER_PARENT { + + public: + + + /** + Method + + @see + @ret + @param + */ + PathPicker(); + + + virtual ~PathPicker(); + + + /** + Method + + @see + @ret + @param + */ + virtual int onInit(); + + + /** + Method + + @see + @ret + @param + */ + void clickCallback(); + + +#ifdef WASABI_COMPILE_CONFIG + /** + Method + + @see + @ret + @param + */ + virtual int onReloadConfig(); +#endif + + /** + Method + + @see + @ret + @param + */ + virtual void abstract_onNewContent(); + void setPath(const wchar_t *newpath); + const wchar_t *getPath() { return curpath; } + + + /** + Method + + @see + @ret + @param + */ + virtual void onPathChanged(const wchar_t *newpath); + + + /** + Method + + @see + @ret + @param + */ + virtual void setDefault(); + + private: + + /** + Method + + @see + @ret + @param + */ + void updatePathInControl(); + + /** + Method + + @see + @ret + @param + */ +#ifdef WASABI_COMPILE_CONFIG + void updatePathFromConfig(); +#endif + /** + Method + + @see + @ret + @param + */ + void trapControls(); + + PPClicksCallback *clicks_button; + StringW curpath; + int disable_cfg_event; +}; + + +/** + Class + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class PPClicksCallback : public H_GuiObject { + public: + + /** + Method + + @see + @ret + @param + */ + PPClicksCallback(ScriptObject *trap, PathPicker *_callback) : + + /** + Method + + @see + @ret + @param + */ + callback(_callback), H_GuiObject(trap) { + } + + + /** + Method + + @see + @ret + @param + */ + virtual void hook_onLeftButtonDown(int x, int y) { + callback->clickCallback(); + } + private: + PathPicker *callback; +}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/pslider.cpp b/Src/Wasabi/api/skin/widgets/pslider.cpp new file mode 100644 index 00000000..8d960f21 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/pslider.cpp @@ -0,0 +1,371 @@ +#include <precomp.h> +#include <wasabicfg.h> +#include "pslider.h" +#include <api/script/scriptmgr.h> +#include <api/script/vcpu.h> +#include <api/skin/skinparse.h> + +#ifdef WASABI_WIDGETS_MEDIASLIDERS +#include "seqband.h" +#include "seqpreamp.h" +#include "svolbar.h" +#include "sseeker.h" +#include "spanbar.h" +#endif + +char sliderObjectStr[] = "Slider"; // This is the xml tag +char sliderXuiSvcName[] = "Slider xui object"; // this is the name of the xuiservice +XMLParamPair PSliderWnd::params[] = +{ + {PSLIDER_SETBARLEFT, L"BARLEFT"}, + {PSLIDER_SETBARMIDDLE, L"BARMIDDLE"}, + {PSLIDER_SETBARRIGHT, L"BARRIGHT"}, + {PSLIDER_SETDOWNTHUMB, L"DOWNTHUMB"}, + {PSLIDER_SETHIGH, L"HIGH"}, + {PSLIDER_SETHOTPOS, L"HOTPOS"}, + {PSLIDER_SETHOTRANGE, L"HOTRANGE"}, + {PSLIDER_SETHOVERTHUMB, L"HOVERTHUMB"}, + {PSLIDER_SETLOW, L"LOW"}, + {PSLIDER_SETORIENTATION, L"ORIENTATION"}, + {PSLIDER_SETTHUMB, L"THUMB"}, + {PSLIDER_SETSTRETCHTHUMB, L"STRETCHTHUMB"}, + }; + +PSliderWnd::PSliderWnd() +{ + setLimits(0, 255); + getScriptObject()->vcpu_setInterface(sliderGuid, (void *)static_cast<PSliderWnd *>(this)); + getScriptObject()->vcpu_setClassName(L"Slider"); + getScriptObject()->vcpu_setController(sliderController); + + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); +} + +void PSliderWnd::CreateXMLParameters(int master_handle) +{ + //PSLIDER_PARENT::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); +} + +PSliderWnd::~PSliderWnd() +{} + +int PSliderWnd::setXuiParam(int _xuihandle, int attrid, const wchar_t *paramname, const wchar_t *strvalue) +{ + if (xuihandle != _xuihandle) return PSLIDER_PARENT::setXuiParam(_xuihandle, attrid, paramname, strvalue); + switch (attrid) + { + case PSLIDER_SETBARLEFT: + setLeftBmp(strvalue); + break; + case PSLIDER_SETBARMIDDLE: + setMiddleBmp(strvalue); + break; + case PSLIDER_SETBARRIGHT: + setRightBmp(strvalue); + break; + case PSLIDER_SETTHUMB: + setThumbBmp(strvalue); + break; + case PSLIDER_SETDOWNTHUMB: + setThumbDownBmp(strvalue); + break; + case PSLIDER_SETHOVERTHUMB: + setThumbHiliteBmp(strvalue); + break; + case PSLIDER_SETSTRETCHTHUMB: + setThumbStretched(_wtoi(strvalue)); + break; + case PSLIDER_SETORIENTATION: + setOrientation(SkinParser::getOrientation(strvalue)); + break; + case PSLIDER_SETLOW: + { + int mx = getMaxLimit(); + setLimits(WTOI(strvalue), mx); +#ifdef WASABI_COMPILE_CONFIG + reloadConfig(); +#endif + break; + } + case PSLIDER_SETHIGH: + { + int mn = getMinLimit(); + setLimits(mn, WTOI(strvalue)); +#ifdef WASABI_COMPILE_CONFIG + reloadConfig(); +#endif + break; + } + case PSLIDER_SETHOTPOS: + { + int a = WTOI(strvalue); + setHotPosition(a); + break; + } + case PSLIDER_SETHOTRANGE: + { + int a = WTOI(strvalue); + setHotPosRange(a); + break; + } + default: + return 0; + } + return 1; +} + +int PSliderWnd::onInit() +{ + setNoDefaultBackground(1); + PSLIDER_PARENT::onInit(); + return 1; +} + +#ifdef WASABI_COMPILE_CONFIG +void PSliderWnd::reloadConfig() +{ + if (getGuiObject()->guiobject_hasCfgAttrib()) + onReloadConfig(); +} +#endif + +#ifdef WASABI_COMPILE_CONFIG +int PSliderWnd::onReloadConfig() +{ + int newVal = getGuiObject()->guiobject_getCfgInt(); + setPosition(newVal, 0); + + return PSLIDER_PARENT::onReloadConfig(); +} +#endif + +int PSliderWnd::onSetPosition() +{ + int r = PSLIDER_PARENT::onSetPosition(); + scriptVar p = SOM::makeVar(SCRIPT_INT); + int intVal = getSliderPosition(); +#ifdef WASABI_COMPILE_CONFIG + getGuiObject()->guiobject_setCfgInt(intVal); +#endif + SOM::assign(&p, intVal / scriptDivisor()); + script_onSetPosition(SCRIPT_CALL, getScriptObject(), p); + return r; +} + +int PSliderWnd::onPostedPosition(int pp) +{ + scriptVar p = SOM::makeVar(SCRIPT_INT); + int intVal = getSliderPosition(); +#ifdef WASABI_COMPILE_CONFIG + getGuiObject()->guiobject_setCfgInt(intVal); +#endif + SOM::assign(&p, intVal / scriptDivisor()); + script_onPostedPosition(SCRIPT_CALL, getScriptObject(), p); + return 1; +} + +int PSliderWnd::onSetFinalPosition() +{ + int r = PSLIDER_PARENT::onSetPosition(); + scriptVar p = SOM::makeVar(SCRIPT_INT); + int intVal = getSliderPosition(); +#ifdef WASABI_COMPILE_CONFIG + getGuiObject()->guiobject_setCfgInt(intVal); +#endif + SOM::assign(&p, intVal / scriptDivisor()); + script_onSetFinalPosition(SCRIPT_CALL, getScriptObject(), p); + return r; +} + +SliderScriptController _sliderController; +SliderScriptController *sliderController = &_sliderController; + +// -- Functions table ------------------------------------- +function_descriptor_struct SliderScriptController::exportedFunction[] = { + {L"setPosition", 1, (void*)PSliderWnd::script_setPosition }, + {L"getPosition", 0, (void*)PSliderWnd::script_getPosition }, + {L"onSetPosition", 1, (void*)PSliderWnd::script_onSetPosition }, + {L"onPostedPosition", 1, (void*)PSliderWnd::script_onPostedPosition }, + {L"onSetFinalPosition", 1, (void*)PSliderWnd::script_onSetFinalPosition }, + {L"lock", 0, (void*)PSliderWnd::script_lock}, + {L"unlock", 0, (void*)PSliderWnd::script_unlock}, + }; +// -------------------------------------------------------- + +const wchar_t *SliderScriptController::getClassName() +{ + return L"Slider"; +} + +const wchar_t *SliderScriptController::getAncestorClassName() +{ + return L"GuiObject"; +} + +ScriptObject *SliderScriptController::instantiate() +{ + PSliderWnd *s = new PSliderWnd; + ASSERT(s != NULL); + return s->getScriptObject(); +} + +void SliderScriptController::destroy(ScriptObject *o) +{ + PSliderWnd *s = static_cast<PSliderWnd *>(o->vcpu_getInterface(sliderGuid)); + ASSERT(s != NULL); + delete s; +} + +void *SliderScriptController::encapsulate(ScriptObject *o) +{ + return NULL; // no encapsulation for sliders yet +} + +void SliderScriptController::deencapsulate(void *o) +{} + +int SliderScriptController::getNumFunctions() +{ + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *SliderScriptController::getExportedFunctions() +{ + return exportedFunction; +} + +GUID SliderScriptController::getClassGuid() +{ + return sliderGuid; +} + + +const wchar_t *PSliderWnd::vcpu_getClassName() +{ + return L"Slider"; +} + +void PSliderWnd::lock () +{} + +void PSliderWnd::unlock() +{} + +//------------------------------------------------------------------------ + +scriptVar PSliderWnd::script_onSetPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS1(o, sliderController, p); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, p); +} + +scriptVar PSliderWnd::script_onPostedPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS1(o, sliderController, p); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, p); +} + +scriptVar PSliderWnd::script_onSetFinalPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS1(o, sliderController, p); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, p); +} + +scriptVar PSliderWnd::script_setPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) +{ + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&v)); + PSliderWnd *s = static_cast<PSliderWnd *>(o->vcpu_getInterface(sliderGuid)); + if (s) s->setPosition(GET_SCRIPT_INT(v) * s->scriptDivisor()); + RETURN_SCRIPT_VOID; +} + +scriptVar PSliderWnd::script_getPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PSliderWnd *s = static_cast<PSliderWnd *>(o->vcpu_getInterface(sliderGuid)); + if (s) return MAKE_SCRIPT_INT(s->getSliderPosition() / s->scriptDivisor()); + return MAKE_SCRIPT_FLOAT(0); +} + +scriptVar PSliderWnd::script_lock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PSliderWnd *s = static_cast<PSliderWnd *>(o->vcpu_getInterface(sliderGuid)); + if (s) s->lock (); + RETURN_SCRIPT_VOID; +} + +scriptVar PSliderWnd::script_unlock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PSliderWnd *s = static_cast<PSliderWnd *>(o->vcpu_getInterface(sliderGuid)); + if (s) s->unlock(); + RETURN_SCRIPT_VOID; +} + +GuiObject *SliderXuiSvc::instantiate(const wchar_t *xmltag, ifc_xmlreaderparams *params) +{ +#ifdef WASABI_WIDGETS_MEDIASLIDERS + if (!params) + { + PSliderWnd *r = new PSliderWnd; + return r->getGuiObject(); + } + const wchar_t *action = params->getItemValue(L"action"); + const wchar_t *param = params->getItemValue(L"param"); + if (!action) + action=L""; + PSliderWnd *r = NULL; +#ifdef WASABI_WIDGETS_MEDIASLIDERS + if (!_wcsicmp(action, L"seek")) + r = new SSeeker; + else if (!_wcsicmp(action, L"volume")) + r = new SVolBar; + else if (!_wcsicmp(action, L"pan")) + r = new SPanBar; + else if (!_wcsicmp(action, L"eq_band")) + { + if (!_wcsicmp(param, L"preamp")) + r = new SEQPreamp; + else + r = new SEQBand; + } + else if (!_wcsicmp(action, L"eq_preamp")) + { + r = new SEQPreamp; + } + else + { +#endif + + r = new PSliderWnd; + +#ifdef WASABI_WIDGETS_MEDIASLIDERS + + } +#endif + + return r->getGuiObject(); +#else + PSliderWnd *r = new PSliderWnd; + return r->getGuiObject(); +#endif +} + +void SliderXuiSvc::destroy(GuiObject *g) +{ + PSliderWnd *obj = static_cast<PSliderWnd *>(g->guiobject_getRootWnd()); + delete obj; +} diff --git a/Src/Wasabi/api/skin/widgets/pslider.h b/Src/Wasabi/api/skin/widgets/pslider.h new file mode 100644 index 00000000..6ef52870 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/pslider.h @@ -0,0 +1,110 @@ +#ifndef _PSLIDER_H +#define _PSLIDER_H + +#include <api/wnd/wndclass/slider.h> +#include <api/script/objects/guiobj.h> +#include <api/skin/widgets.h> + +#define PSLIDER_PARENT SliderWnd + +class SliderScriptController : public GuiObjectScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + 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); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern SliderScriptController *sliderController; + + + +class PSliderWnd : public PSLIDER_PARENT { + +public: + + PSliderWnd(); + virtual ~PSliderWnd(); + + virtual int onSetPosition(); + virtual int onSetFinalPosition(); + virtual int onPostedPosition(int p); + virtual void lock(); + virtual void unlock(); + + virtual int setXuiParam(int _xuihandle, int attribid, const wchar_t *paramname, const wchar_t *strvalue); + virtual const wchar_t *vcpu_getClassName(); + virtual ScriptObjectController *vcpu_getController() { return sliderController; } + +/* virtual int getAutoHeight(); + virtual int getAutoWidth();*/ + + virtual int onInit(); + +#ifdef WASABI_COMPILE_CONFIG + virtual int onReloadConfig(); + void reloadConfig(); +#endif + + virtual int scriptDivisor() { return 1; } + + enum { + PSLIDER_SETBARLEFT=0, + PSLIDER_SETBARMIDDLE, + PSLIDER_SETBARRIGHT, + PSLIDER_SETTHUMB, + PSLIDER_SETDOWNTHUMB, + PSLIDER_SETHOVERTHUMB, + PSLIDER_SETORIENTATION, + PSLIDER_SETLOW, + PSLIDER_SETHIGH, + PSLIDER_SETHOTPOS, + PSLIDER_SETHOTRANGE, + PSLIDER_SETSTRETCHTHUMB, + PSLIDER_NUMPARAMS, + }; +protected: + /*static */void CreateXMLParameters(int master_handle); + +public: + static scriptVar script_setPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v); + static scriptVar script_getPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_onSetPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p); + static scriptVar script_onPostedPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p); + static scriptVar script_onSetFinalPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p); + static scriptVar script_lock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_unlock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + + +private: + int xuihandle; + static XMLParamPair params[]; +}; + +class SliderXuiSvc : public svc_xuiObjectI { + +public: + SliderXuiSvc() {}; + virtual ~SliderXuiSvc() {}; + + static const char *getServiceName() { return "Slider xui object"; } + static const wchar_t *xuisvc_getXmlTag() { return L"Slider"; } + virtual int testTag(const wchar_t *xmltag) { return !WCSICMP(xmltag, L"Slider"); } + virtual GuiObject *instantiate(const wchar_t *xmltag, ifc_xmlreaderparams *params=NULL); + virtual void destroy(GuiObject *g); +}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/sa.cpp b/Src/Wasabi/api/skin/widgets/sa.cpp new file mode 100644 index 00000000..ff2c72fc --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/sa.cpp @@ -0,0 +1,735 @@ +#include <precomp.h> +#include <api/wnd/popup.h> +#include <api/script/script.h> +#include <api/script/scriptmgr.h> +#include <math.h> +#include <api/skin/skinparse.h> +#include "sa.h" +#include <api/core/api_core.h> +#include <tataki/canvas/bltcanvas.h> +#include "resource.h" +#include "../Agave/Language/api_language.h" + +const wchar_t visXuiStr[] = L"Vis"; // This is the xml tag +char visXuiSvcName[] = "Vis xui object"; // this is the name of the xuiservice + + +// {9149C445-3C30-4e04-8433-5A518ED0FDDE} +const GUID uioptions_guid = + { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } }; + +unsigned char ppal[] = { +#ifdef CLASSIC + 0,0,0, // color 0 = black + 75,72,80, // color 1 = grey for dots + 255,55,16, // color 2 = top of spec + 255,55,16, // 3 + 255,80,0, // 4 + 255,80,0, // 5 + 239,112,0, // 6 + 239,112,0, // 7 + 255,168,32, // 8 + 255,168,32, // 9 + 176,255,47, // 10 + 176,255,47, // 11 + 47,239,0, // 12 + 47,239,0, // 13 + 48,160,0, // 14 + 48,160,0, // 15 + 32,128,0, // 16 + 32,128,0, // 17 = bottom of spec + 255,255,255, // 18 = osc 1 + 214,214,222, // 19 = osc 2 (slightly dimmer) + 181,189,189, // 20 = osc 3 + 160,170,175, // 21 = osc 4 + 148,156,165, // 22 = osc 4 + 150, 150, 150, // 23 = analyzer peak dots +#else + 0,0,0, // color 0 = black + 24,33,41, // color 1 = grey for dots + 239,49,16, // color 2 = top of spec + 206,41,16, // 3 + 214,90,0, // 4 + 214,102,0, // 5 + 214,115,0, // 6 + 198,123,8, // 7 + 222,165,24, // 8 + 214,181,33, // 9 + 189,222,41, // 10 + 148,222,33, // 11 + 41,206,16, // 12 + 50,190,16, // 13 + 57,181,16, // 14 + 49,156,8, // 15 + 41,148,0, // 16 + 24,132,8, // 17 + 255,255,255, // 18 = osc 1 + 214,214,222, // 19 = osc 2 (slightly dimmer) + 181,189,189, // 20 = osc 3 + 160,170,175, // 21 = osc 4 + 148,156,165, // 22 = osc 4 + 150, 150, 150, // 23 = analyzer peak +#endif +}; + +#define CHANNEL_LEFT 1 +#define CHANNEL_RIGHT 2 + +XMLParamPair SAWnd::params[] = { + {SA_SETCOLORALLBANDS, L"COLORALLBANDS"}, + {SA_SETCOLORBAND1, L"COLORBAND1"}, + {SA_SETCOLORBAND2, L"COLORBAND2"}, + {SA_SETCOLORBAND3, L"COLORBAND3"}, + {SA_SETCOLORBAND4, L"COLORBAND4"}, + {SA_SETCOLORBAND5, L"COLORBAND5"}, + {SA_SETCOLORBAND6, L"COLORBAND6"}, + {SA_SETCOLORBAND7, L"COLORBAND7"}, + {SA_SETCOLORBAND8, L"COLORBAND8"}, + {SA_SETCOLORBAND9, L"COLORBAND9"}, + {SA_SETCOLORBAND10, L"COLORBAND10"}, + {SA_SETCOLORBAND11, L"COLORBAND11"}, + {SA_SETCOLORBAND12, L"COLORBAND12"}, + {SA_SETCOLORBAND13, L"COLORBAND13"}, + {SA_SETCOLORBAND14, L"COLORBAND14"}, + {SA_SETCOLORBAND15, L"COLORBAND15"}, + {SA_SETCOLORBAND16, L"COLORBAND16"}, + {SA_SETCOLORBANDPEAK, L"COLORBANDPEAK"}, + {SA_SETCOLORALLOSC, L"COLORALLOSC"}, + {SA_SETCOLOROSC1, L"COLOROSC1"}, + {SA_SETCOLOROSC2, L"COLOROSC2"}, + {SA_SETCOLOROSC3, L"COLOROSC3"}, + {SA_SETCOLOROSC4, L"COLOROSC4"}, + {SA_SETCOLOROSC5, L"COLOROSC5"}, + {SA_SETCHANNEL, L"CHANNEL"}, + {SA_SETFLIPH, L"FLIPH"}, + {SA_SETFLIPV, L"FLIPV"}, + {SA_SETMODE, L"MODE"}, + {SA_SETGAMMA, L"GAMMAGROUP"}, + {SA_SETFALLOFF, L"FALLOFF"}, + {SA_SETPEAKFALLOFF, L"PEAKFALLOFF"}, + {SA_SETBANDWIDTH, L"BANDWIDTH"}, + {SA_FPS, L"FPS"}, + {SA_COLORING, L"COLORING"}, + {SA_PEAKS, L"PEAKS"}, + {SA_OSCDRAWSTYLE, L"OSCSTYLE"}, +}; + +SAWnd::SAWnd() +{ + filtergroup = SA_PARENT::getFiltersGroup(); + + getScriptObject()->vcpu_setInterface(visGuid, (void *)static_cast<SAWnd *>(this)); + getScriptObject()->vcpu_setClassName(L"Vis"); + getScriptObject()->vcpu_setController(visController); + + char *p = (char *)&ppal; + for (int i=0;i<72;i++) { + palette[i] = ((*p)<<16) + ((*(p+1))<<8) + *(p+2); + p += 3; + } + + setRealtime(1); + startQuickPaint(); + + config_sa=-1; // default value +#ifdef WASABI_COMPILE_CONFIG + { + CfgItem *ci=WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid); + if(ci) { + config_sa=ci->getDataAsInt(L"Spectrum analyzer mode"); + viewer_addViewItem(ci->getDependencyPtr()); + } + } + saveconfsa=0; +#endif + + flip_v = 0; + flip_h = 0; + channel = CHANNEL_LEFT | CHANNEL_RIGHT; + off = 0; + + config_safalloff=2; + config_sa_peak_falloff=1; + config_safire=4; + config_sa_peaks=1; + + memset(bx, 0, sizeof(bx)); + memset(t_bx, 0, sizeof(t_bx)); + memset(t_vx, 0, sizeof(t_vx)); + + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); +} + +void SAWnd::CreateXMLParameters(int master_handle) +{ + //SA_PARENT::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); +} + +int SAWnd::onInit() { + SA_PARENT::onInit(); +#ifdef WASABI_COMPILE_CONFIG + if(config_sa==-1) { + Layout *pl=getGuiObject()->guiobject_getParentLayout(); + if (pl->getParentContainer()) { + confsaname.printf(L"%s/%s/%s/config_sa",WASABI_API_SKIN->getSkinName(),pl->getParentContainer()->getName(),pl->getName()); + config_sa=WASABI_API_CONFIG->getIntPrivate(confsaname,1); + saveconfsa=1; + } + } +#endif + return 1; +} + +SAWnd::~SAWnd() +{ +#ifdef WASABI_COMPILE_CONFIG + if(saveconfsa) + WASABI_API_CONFIG->setIntPrivate(confsaname,config_sa); +#endif +} + +int SAWnd::setXuiParam(int _xuihandle, int attrid, const wchar_t *pname, const wchar_t *str) { + if (_xuihandle != xuihandle) return SA_PARENT::setXuiParam(_xuihandle, attrid, pname, str); + switch (attrid) { + case SA_SETCOLORALLBANDS: + setBandColor(-1, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND1: + setBandColor(15, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND2: + setBandColor(14, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND3: + setBandColor(13, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND4: + setBandColor(12, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND5: + setBandColor(11, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND6: + setBandColor(10, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND7: + setBandColor(9, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND8: + setBandColor(8, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND9: + setBandColor(7, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND10: + setBandColor(6, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND11: + setBandColor(5, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND12: + setBandColor(4, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND13: + setBandColor(3, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND14: + setBandColor(2, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND15: + setBandColor(1, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBAND16: + setBandColor(0, SkinParser::parseColor(str)); + break; + case SA_SETCOLORBANDPEAK: + setPeakColor(SkinParser::parseColor(str)); + break; + case SA_SETCOLORALLOSC: + setOscColor(-1, SkinParser::parseColor(str)); + break; + case SA_SETCOLOROSC1: + setOscColor(0, SkinParser::parseColor(str)); + break; + case SA_SETCOLOROSC2: + setOscColor(1, SkinParser::parseColor(str)); + break; + case SA_SETCOLOROSC3: + setOscColor(2, SkinParser::parseColor(str)); + break; + case SA_SETCOLOROSC4: + setOscColor(3, SkinParser::parseColor(str)); + break; + case SA_SETCOLOROSC5: + setOscColor(4, SkinParser::parseColor(str)); + break; + case SA_SETCHANNEL: + setChannel(WTOI(str)); + break; + case SA_SETFLIPH: + setFlipH(WTOI(str)); + break; + case SA_SETFLIPV: + setFlipV(WTOI(str)); + break; + case SA_SETMODE: + setMode(WTOI(str)); + break; + case SA_SETGAMMA: + filtergroup = str; + break; + case SA_SETFALLOFF: + config_safalloff = WTOI(str); + break; + case SA_SETPEAKFALLOFF: + config_sa_peak_falloff=WTOI(str); + break; + case SA_SETBANDWIDTH: + if (WCSCASEEQLSAFE(str, L"wide")) + config_safire &= (~32); + else if (WCSCASEEQLSAFE(str, L"thin")) + config_safire |= 32; + break; + case SA_FPS: + { + int fps = WTOI(str); + if (fps) + setSpeed(1000/fps); + } + break; + case SA_COLORING: + if (WCSCASEEQLSAFE(str, L"fire")) + config_safire = (config_safire&~3) | 1; + else if (WCSCASEEQLSAFE(str, L"normal")) + config_safire = (config_safire&~3) | 0; + else if (WCSCASEEQLSAFE(str, L"line")) + config_safire = (config_safire&~3) | 2; + break; + case SA_PEAKS: + if (str && WTOI(str)) + config_sa_peaks=1; + else + config_sa_peaks=0; + break; + case SA_OSCDRAWSTYLE: + if (WCSCASEEQLSAFE(str, L"dots")) + config_safire = (config_safire & ~(3<<2)) | 0; + else if (WCSCASEEQLSAFE(str, L"solid")) + config_safire = (config_safire & ~(3<<2)) | 4; + else if (WCSCASEEQLSAFE(str, L"lines")) + config_safire = (config_safire & ~(3<<2)) | 8; + break; + default: + return 0; + } + return 1; +} + +void SAWnd::setChannel(int c) { + channel = c; +} + +void SAWnd::setFlipH(int v) { + if (v == flip_h) return; + flip_h = v; + invalidate(); +} + +void SAWnd::setFlipV(int v) { + if (v == flip_v) return; + flip_v = v; + invalidate(); +} + +void SAWnd::setBandColor(int band, ARGB32 col) { + if (band == -1) { + for (int i=0;i<16;i++) + palette[i+2] = RGBTOBGR(col); + } else + palette[band+2] = RGBTOBGR(col); +} + +void SAWnd::setOscColor(int n, ARGB32 col) { + if (n == -1) { + for (int i=0;i<4;i++) + palette[i+18] = RGBTOBGR(col); + } else + palette[n+18] = RGBTOBGR(col); +} + +void SAWnd::setPeakColor(ARGB32 col) { + palette[23] = RGBTOBGR(col); +} + +#define SA_BLEND(c) (palette[c] | 0xFF000000) //(alpha << 24)) + +int SAWnd::onQuickPaint(BltCanvas *bc, int w, int h, int newone) { + if(!isVisible()) return 0; + +#ifdef WASABI_COMPILE_MEDIACORE + int x; + int fo[5] = {3, 6, 12, 16, 32 }; + float pfo[5]={1.05f,1.1f,1.2f,1.4f,1.6f}; + + specData=(int *)bc->getBits(); + if (newone || !config_sa) + MEMSET(specData,0,76*16*4*4); + + if(!config_sa) { + if (!off) { + off = 1; + return 1; + } + return 0; + } + + off = 0; + + char visdata[576*2*2] = {0}; + unsigned char *values=(unsigned char *)visdata; + int ret=WASABI_API_MEDIACORE->core_getVisData(0,visdata,sizeof(visdata)); + if (!ret) { + MEMSET(visdata,0,sizeof(visdata)); + } else if (ret == 75*2) { + if (config_sa==2) values+=75; + } else { + if(config_sa==1) { + register int v; + for(int x=0;x<75;x++) { + v=values[x]+values[576+x]; + v>>=4; + values[x]=v; + } + } + if (config_sa==2) { + values+=576*2; + register int v; + register char *blah=(char *)values; + for(int x=0;x<75;x++) { + v=blah[x*4]+blah[576+(x*4)]; + v>>=4; + blah[x]=v; + } + } + } + +// int ws=(config_windowshade&&config_mw_open); +// int s = (config_dsize&&config_mw_open)?1:0; + + int dbx = fo[max(min(config_safalloff,4),0)]; + float spfo=pfo[max(min(config_sa_peak_falloff,4),0)]; + + MEMSET(specData,0,76*16*4*4); + + { + { + if (config_sa == 2) + { + int *gmem = specData; + { + int lv=-1; + if (((config_safire>>2)&3)==0) for (x = 0; x < 75; x ++) + { + register int v; register char c; + v = (((int) ((signed char *)values)[x])) + 8; + if (v < 0) v = 0 ; if (v > 15) v = 15; c = v/2-4; if (c < 0) c = -c; c += 18; + gmem[v*76*2] = SA_BLEND(c); + gmem++; + } + else if (((config_safire>>2)&3)==1) for (x = 0; x < 75; x ++) + { + register int v,t; register char c; + v = (((int) ((signed char *)values)[x])) + 8; + if (v < 0) v = 0 ; if (v > 15) v = 15; c = v/2-4; if (c < 0) c = -c; c += 18; + if (lv == -1) lv=v; + t=lv; + lv=v; + if (v >= t) while (v >= t) gmem[v--*76*2] = SA_BLEND(c); + else while (v < t) gmem[v++*76*2] = SA_BLEND(c); + gmem++; + } + else if (((config_safire>>2)&3)==2) for (x = 0; x < 75; x ++) // solid + { + register int v; register char c; + v = (((int) ((signed char *)values)[x])) + 8; + if (v < 0) v = 0 ; if (v > 15) v = 15; c = v/2-4; if (c < 0) c = -c; c += 18; + if (v > 7) while (v > 7) gmem[v--*76*2] = SA_BLEND(c); + else while (v <= 7) gmem[v++*76*2] = SA_BLEND(c); + gmem++; + } + } + } + else + { + for (x = 0; x < 75; x ++) + { + register int y,v,t; +#ifndef CLASSIC + t=x&~3; +#else + t=x-(x%6); +#endif + if (!(config_safire&32)) + { + int a=values[t],b=values[t+1],c=values[t+2],d=values[t+3]; +#ifndef CLASSIC + v = a+b+c+d;//-min(a,min(b,min(c,d))); + v/=4; +#else + v = a+b+c+d+(int)values[t+4]+(int)values[t+5];//-min(a,min(b,min(c,d))); + v/=6; +#endif + } + else v = (((int)values[x])); + if (v > 15) v = 15; + if ((v<<4) < bx[x]) v = (bx[x]-=dbx)>>4; + else bx[x] = v<<4; + if (bx[x] < 0) bx[x] = 0; + if (v < 0) v = 0; + int *gmem = specData + 76*2*15 + x; + if ((config_safire&3)==1) t = v+2; + else if ((config_safire&3)==2) t=17-(v); + else t = 17; + + if (t_bx[x] <= v*256) { + t_bx[x]=v*256; + t_vx[x]=3.0f; + } +#ifndef CLASSIC + if ((config_safire&32 || (x&3)!=3)) + { + if ((config_safire&3)!=2) for (y = 0; y < v; y ++) + { + *gmem = SA_BLEND(t-y); + gmem -= 76*2; + } + else for (y = 0; y < v; y ++) + { + *gmem = SA_BLEND(t); + gmem -= 76*2; + } +#else + if ((config_safire&32 || (!(x&1) && (x%6) < 4))) + { + if ((config_safire&3)!=2) for (y = 0; y < v/2; y ++) + { + *gmem = SA_BLEND(t-y*2); + gmem -= 76*2*2; + } + else for (y = 0; y < v/2; y ++) + { + *gmem = SA_BLEND(t); + gmem -= 76*2*2; + } +#endif +#ifndef CLASSIC + if (config_sa_peaks && t_bx[x]/256 >= 0 && t_bx[x]/256 <= 15) + { + specData[76*2*15 - (t_bx[x]/256)*76*2 + x]=SA_BLEND(23); + } +#endif + } + t_bx[x] -= (int)t_vx[x]; + t_vx[x] *= spfo; + if (t_bx[x] < 0) t_bx[x]=0; + } + } + } + } + + if (flip_v) + bc->vflip(2); + if (flip_h) + bc->hflip(2); + + invalidated = 1; // rerun filter + +#endif //mediacore + + return 1; +} + +int SAWnd::onLeftButtonDown(int x, int y) { + SA_PARENT::onLeftButtonDown(x, y); + if (!WASABI_API_MAKI->vcpu_getComplete()) { + nextMode(); +#ifdef WASABI_COMPILE_CONFIG + CfgItem *ci=WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid); + if(ci) ci->setDataAsInt(L"Spectrum analyzer mode",config_sa); +#endif + } + return 1; +} + +void SAWnd::nextMode() { + config_sa++; + if(config_sa>2) config_sa=0; +} + +void SAWnd::setMode(int mode) { + config_sa=mode; + if(config_sa>2) config_sa=0; +} + +int SAWnd::getMode() { + return config_sa; +} + +int SAWnd::onRightButtonUp(int x, int y) +{ + SA_PARENT::onRightButtonUp(x, y); + + PopupMenu menu (this); + menu.addCommand(WASABI_API_LNGSTRINGW(IDS_NO_VISUALISATION)/*"No visualization"*/, 0, config_sa==0, FALSE); + menu.addCommand(WASABI_API_LNGSTRINGW(IDS_SPECTRUM_ANALYZER)/*L"Spectrum analyzer"*/, 1, config_sa==1, FALSE); + menu.addCommand(WASABI_API_LNGSTRINGW(IDS_OSCILLOSCOPE)/*L"Oscilloscope"*/, 2, config_sa==2, FALSE); + + clientToScreen(&x, &y); + + int ret = menu.popAtXY(x,y); +#ifdef WASABI_COMPILE_CONFIG + if(ret>=0) + { + config_sa=ret; + CfgItem *ci=WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid); + if(ci) ci->setDataAsInt(L"Spectrum analyzer mode",config_sa); + } +#endif + + WASABI_API_MAKI->vcpu_setComplete(); + return 1; +} + +int SAWnd::getPreferences(int what) { + switch (what) { + case SUGGESTED_W: return 76; + case SUGGESTED_H: return 16; + } + return SA_PARENT::getPreferences(what); +} + +void SAWnd::getQuickPaintSize(int *w, int *h) { + if (w) *w = 76*2; + if (h) *h = 16*2; +} + +void SAWnd::getQuickPaintSource(RECT *r) { + ASSERT(r != NULL); + r->left = 0; + r->top = 0; + r->right = 72; + r->bottom = 16; +} + +int SAWnd::viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen) { +#ifdef WASABI_COMPILE_CONFIG + if(event==CfgItem::Event_ATTRIBUTE_CHANGED && ptr && STRCASEEQLSAFE((const char *)ptr, "Spectrum analyzer mode")) { + CfgItem *ci=WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid); + if(ci) config_sa=ci->getDataAsInt((const wchar_t *)ptr); + } +#endif + return 1; +} + +VisScriptController _visController; +VisScriptController *visController = &_visController; + +// -- Functions table ------------------------------------- +function_descriptor_struct VisScriptController::exportedFunction[] = { + {L"onFrame", 0, (void*)SAWnd::script_onFrame }, + {L"setRealtime", 1, (void*)SAWnd::script_setRealtime }, + {L"getRealtime", 0, (void*)SAWnd::script_getRealtime }, + {L"setMode", 1, (void*)SAWnd::script_vcpu_setMode}, + {L"getMode", 0, (void*)SAWnd::script_vcpu_getMode}, + {L"nextMode", 0, (void*)SAWnd::script_vcpu_nextMode}, +}; + +// -------------------------------------------------------- +const wchar_t *VisScriptController::getClassName() { + return L"Vis"; +} + +const wchar_t *VisScriptController::getAncestorClassName() { + return L"GuiObject"; +} + +ScriptObject *VisScriptController::instantiate() { + SAWnd *sa = new SAWnd; + ASSERT(sa != NULL); + return sa->getScriptObject(); +} + +void VisScriptController::destroy(ScriptObject *o) { + SAWnd *sa = static_cast<SAWnd *>(o->vcpu_getInterface(visGuid)); + ASSERT(sa != NULL); + delete sa; +} + +void *VisScriptController::encapsulate(ScriptObject *o) { + return NULL; // no encapsulation for vis yet +} + +void VisScriptController::deencapsulate(void *o) { +} + +int VisScriptController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *VisScriptController::getExportedFunctions() { + return exportedFunction; +} + +GUID VisScriptController::getClassGuid() { + return visGuid; +} + +// ----------------------------------------------------------------------- +scriptVar SAWnd::script_onFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS0(o, visController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +scriptVar SAWnd::script_setRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s) { + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&s)); + SAWnd *sa = static_cast<SAWnd*>(o->vcpu_getInterface(visGuid)); + if (sa) sa->setRealtime(SOM::makeInt(&s)); + RETURN_SCRIPT_VOID; +} + +scriptVar SAWnd::script_getRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + SAWnd *sa = static_cast<SAWnd*>(o->vcpu_getInterface(visGuid)); + if (sa) return MAKE_SCRIPT_INT(sa->getRealtime()); + return MAKE_SCRIPT_INT(0); +} + +scriptVar SAWnd::script_vcpu_setMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a) { + SCRIPT_FUNCTION_INIT + ASSERT(SOM::isNumeric(&a)); + SAWnd *sa = static_cast<SAWnd*>(o->vcpu_getInterface(visGuid)); + if (sa) sa->setMode(SOM::makeInt(&a)); + RETURN_SCRIPT_VOID; +} + +scriptVar SAWnd::script_vcpu_getMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + SAWnd *sa = static_cast<SAWnd*>(o->vcpu_getInterface(visGuid)); + if (sa) return MAKE_SCRIPT_INT(sa->getMode()); + return MAKE_SCRIPT_INT(0); +} + +scriptVar SAWnd::script_vcpu_nextMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + SAWnd *sa = static_cast<SAWnd*>(o->vcpu_getInterface(visGuid)); + if (sa) sa->nextMode(); + RETURN_SCRIPT_VOID; +} diff --git a/Src/Wasabi/api/skin/widgets/sa.h b/Src/Wasabi/api/skin/widgets/sa.h new file mode 100644 index 00000000..a421bb3b --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/sa.h @@ -0,0 +1,157 @@ +#ifndef _SA_H +#define _SA_H + +#include <api/wnd/wndclass/qpaintwnd.h> +#include <api/service/svc_enum.h> +#include <api/service/svcs/svc_skinfilter.h> + +#define SA_TIMER_UPDATE 1 +#define SA_PARENT QuickPaintWnd + +// {CE4F97BE-77B0-4e19-9956-D49833C96C27} +static const GUID visGuid = +{ 0xce4f97be, 0x77b0, 0x4e19, { 0x99, 0x56, 0xd4, 0x98, 0x33, 0xc9, 0x6c, 0x27 } }; + +#include <api/script/objects/guiobj.h> + +class VisScriptController : public GuiObjectScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + 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); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern VisScriptController *visController; + +class SAWnd : public SA_PARENT, public DependentViewerI { +public: + SAWnd(); + virtual ~SAWnd(); + + int onInit(); + int onRightButtonUp(int x, int y); + int onLeftButtonDown(int x, int y); + virtual int setXuiParam(int _xuihandle, int attrid, const wchar_t *p, const wchar_t *s); + virtual int getPreferences(int what); + + void setChannel(int c); + void setFlipH(int v); + void setFlipV(int v); + int wantAutoContextMenu() { return 0; } + + virtual int onQuickPaint(BltCanvas *c, int w, int h, int newone); + + virtual void setBandColor(int band, ARGB32 col); + virtual void setOscColor(int n, ARGB32 col); + virtual void setPeakColor(ARGB32 col); + + virtual void setMode(int mode); + virtual int getMode(); + virtual void nextMode(); + virtual void getQuickPaintSize(int *w, int *h); + virtual void getQuickPaintSource(RECT *r); + virtual int wantNegativeHeight() { return 1; } + virtual int wantFilters() { return 1; } + virtual const wchar_t *getFiltersGroup() { return filtergroup; } +protected: + /*static */void CreateXMLParameters(int master_handle); +private: + int *specData; + int palette[256]; + int realtime; + int xuihandle; + + enum { + SA_SETCOLORALLBANDS=0, + SA_SETCOLORBAND1, + SA_SETCOLORBAND2, + SA_SETCOLORBAND3, + SA_SETCOLORBAND4, + SA_SETCOLORBAND5, + SA_SETCOLORBAND6, + SA_SETCOLORBAND7, + SA_SETCOLORBAND8, + SA_SETCOLORBAND9, + SA_SETCOLORBAND10, + SA_SETCOLORBAND11, + SA_SETCOLORBAND12, + SA_SETCOLORBAND13, + SA_SETCOLORBAND14, + SA_SETCOLORBAND15, + SA_SETCOLORBAND16, + SA_SETCOLORBANDPEAK, + SA_SETCOLORALLOSC, + SA_SETCOLOROSC1, + SA_SETCOLOROSC2, + SA_SETCOLOROSC3, + SA_SETCOLOROSC4, + SA_SETCOLOROSC5, + SA_SETCHANNEL, + SA_SETFLIPH, + SA_SETFLIPV, + SA_SETMODE, + SA_SETGAMMA, + SA_SETFALLOFF, + SA_SETPEAKFALLOFF, + SA_SETBANDWIDTH, + SA_FPS, + SA_COLORING, + SA_PEAKS, + SA_OSCDRAWSTYLE, + }; + static XMLParamPair params[]; + + int config_safalloff; + int config_sa_peak_falloff; + int config_sa; + int config_safire; + int config_sa_peaks; + int flip_h, flip_v; + int channel; + StringW filtergroup; + + int bx[75]; +int t_bx[75]; +float t_vx[75]; + + PtrList<svc_skinFilter>filters; + SkinFilterEnum *sfe; + +#ifdef WASABI_COMPILE_CONFIG + int saveconfsa; + StringW confsaname; +#endif + int off; + + virtual int viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen); + +public: + + static scriptVar script_onFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_setRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r); + static scriptVar script_getRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_setMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a); + static scriptVar script_vcpu_getMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_nextMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + +}; + +extern const wchar_t visXuiStr[]; +extern char visXuiSvcName[]; +class VisXuiSvc : public XuiObjectSvc<SAWnd, visXuiStr, visXuiSvcName> {}; + + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/seeker.h b/Src/Wasabi/api/skin/widgets/seeker.h new file mode 100644 index 00000000..6b95e9df --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/seeker.h @@ -0,0 +1,22 @@ +#ifndef _SEEKER_H +#define _SEEKER_H + +#include "../common/slider.h" + +#define SEEKER_PARENT SliderWnd +class Seeker : public SliderWnd { +public: + Seeker(); + virtual ~Seeker(); + + virtual int onInit(); + virtual int onResize(); + +protected: + virtual int onSetFinalPosition(); + + // from BaseWnd + virtual void timerCallback(int id); +}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/seqband.cpp b/Src/Wasabi/api/skin/widgets/seqband.cpp new file mode 100644 index 00000000..2d813fd2 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/seqband.cpp @@ -0,0 +1,121 @@ +#include <precomp.h> +#include "seqband.h" +#include <api/core/api_core.h> + +#define NOTIFYMSG_EQ_HELLO 0x3003 + +const wchar_t eqBandXuiStr[] = L"EqBand"; // This is the xml tag +char eqBandXuiSvcName[] = "EqBand xui object"; // this is the name of the xuiservice + +XMLParamPair SEQBand::params[] = { + {SEQBAND_SETPARAM, L"BAND"}, + {SEQBAND_SETPARAM, L"PARAM"}, +}; + +SEQBand::SEQBand() { + band = 0; + setDrawOnBorders(TRUE); + setEnable(TRUE); + setHotPosition(0); + isactive=0; + discard_next_event = 0; + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); + + setLimits(-127,127); +} + +void SEQBand::CreateXMLParameters(int master_handle) +{ + //SEQBAND_PARENT::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); +} + +SEQBand::~SEQBand() { + WASABI_API_MEDIACORE->core_delCallback(0, this); +} + +int SEQBand::setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval) { + if (_xuihandle != xuihandle) return SEQBAND_PARENT::setXuiParam(_xuihandle, attrid, name, strval); + switch (attrid) { + case SEQBAND_SETPARAM: + case SEQBAND_SETBAND: + setBand(WTOI(strval)-1); + break; + default: + return 0; + } + return 1; +} + +void SEQBand::setBand(int b) { + band = b; +} + +int SEQBand::onInit() { + SEQBAND_PARENT::onInit(); + + corecb_onEQBandChange(band, WASABI_API_MEDIACORE->core_getEqBand(0, band)); + WASABI_API_MEDIACORE->core_addCallback(0, this); + + return 1; +} + +int SEQBand::onSetPosition() { + setHotPosition((Std::keyDown(VK_SHIFT) ? -1 : 0)); + SEQBAND_PARENT::onSetPosition(); + int pos = getSliderPosition(); // get slider pos + discard_next_event = 1; + WASABI_API_MEDIACORE->core_setEqBand(0,band,pos); + return 1; +} + +int SEQBand::onResize() { + SEQBAND_PARENT::onResize(); + invalidate(); + return 1; +} + +int SEQBand::corecb_onEQBandChange(int b, int newval) { + if(b!=band) return 0; + if (discard_next_event) { + discard_next_event = 0; + return 0; + } + setPosition(newval,0); + return 0; +} + +int SEQBand::onLeftButtonDown(int x, int y) { + isactive=1; + return SEQBAND_PARENT::onLeftButtonDown(x,y); +} + +int SEQBand::onMouseMove(int x, int y) { + if(isactive) { + ifc_window *parent=getParent(); + if(parent) { + ifc_window *wnd=parent->findRootWndChild(x,y); + if(wnd && wnd!=this) { + if(wnd->childNotify(this,NOTIFYMSG_EQ_HELLO,0,0)) { // will return 1 if it's another EQBand + onLeftButtonUp(x,y); + wnd->onLeftButtonDown(x,y); + } + } + } + } + return SEQBAND_PARENT::onMouseMove(x,y); +} + +int SEQBand::onLeftButtonUp(int x, int y) { + isactive=0; + return SEQBAND_PARENT::onLeftButtonUp(x,y); +} + +int SEQBand::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2) { + if(msg==NOTIFYMSG_EQ_HELLO) return 1; + return SEQBAND_PARENT::childNotify(child,msg,param1,param2); +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/seqband.h b/Src/Wasabi/api/skin/widgets/seqband.h new file mode 100644 index 00000000..26c211bb --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/seqband.h @@ -0,0 +1,47 @@ +#ifndef _SEQBAND_H +#define _SEQBAND_H + +#include "pslider.h" +#include <api/syscb/callbacks/corecbi.h> + +#define SEQBAND_PARENT PSliderWnd +#define SEQBAND_XMLPARENT PSliderWnd + +class SEQBand : public SEQBAND_PARENT, public CoreCallbackI { +public: + SEQBand(); // band=0-9 + virtual ~SEQBand(); + + virtual int onInit(); + virtual int onResize(); + virtual int setXuiParam(int xuihandle, int attrid, const wchar_t *name, const wchar_t *strval); + virtual void setBand(int b); + + virtual int onLeftButtonDown(int x, int y); + virtual int onMouseMove(int x, int y); // only called when mouse captured + virtual int onLeftButtonUp(int x, int y); + virtual int childNotify(ifc_window *child, int msg, intptr_t param1=0, intptr_t param2=0); + + enum { + SEQBAND_SETPARAM=0, + SEQBAND_SETBAND, + }; + +protected: + /*static */void CreateXMLParameters(int master_handle); + virtual int onSetPosition(); + + virtual int corecb_onEQBandChange(int band, int newval); + + int band, isactive; + int discard_next_event; +private: + static XMLParamPair params[]; + int xuihandle; +}; + +extern const wchar_t eqBandXuiStr[]; +extern char eqBandXuiSvcName[]; +class EqBandXuiSvc : public XuiObjectSvc<SEQBand, eqBandXuiStr, eqBandXuiSvcName> {}; + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/seqpreamp.cpp b/Src/Wasabi/api/skin/widgets/seqpreamp.cpp new file mode 100644 index 00000000..7b61d2cd --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/seqpreamp.cpp @@ -0,0 +1,44 @@ +#include <precomp.h> +#include "seqpreamp.h" + +#include <api/core/api_core.h> + +const wchar_t eqPreAmpXuiStr[] = L"EQPreAmp"; // This is the xml tag +char eqPreAmpXuiSvcName[] = "EQPreAmp xui object"; // this is the name of the xuiservice + +SEQPreamp::SEQPreamp() { + setDrawOnBorders(TRUE); + setEnable(TRUE); + setHotPosition(0); + setLimits(-127,127); + discard_next_event = 0; +} + +SEQPreamp::~SEQPreamp() { + WASABI_API_MEDIACORE->core_delCallback(0, this); +} + +int SEQPreamp::onInit() { + SEQPREAMP_PARENT::onInit(); + + corecb_onEQPreampChange(WASABI_API_MEDIACORE->core_getEqPreamp(0)); + WASABI_API_MEDIACORE->core_addCallback(0, this); + + return 1; +} + +int SEQPreamp::onSetPosition() { + setHotPosition((Std::keyDown(VK_SHIFT) ? -1 : 0)); + SEQPREAMP_PARENT::onSetPosition(); + int pos = getSliderPosition(); // get slider pos + discard_next_event = 1; + WASABI_API_MEDIACORE->core_setEqPreamp(0,pos); + discard_next_event = 0; + return 1; +} + +int SEQPreamp::corecb_onEQPreampChange(int newval) { + if (discard_next_event) return 0; + setPosition(newval,0); + return 0; +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/seqpreamp.h b/Src/Wasabi/api/skin/widgets/seqpreamp.h new file mode 100644 index 00000000..7d7c779f --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/seqpreamp.h @@ -0,0 +1,28 @@ +#ifndef _SEQPREAMP_H +#define _SEQPREAMP_H + +#include "pslider.h" +#include <api/syscb/callbacks/corecbi.h> + +#define SEQPREAMP_PARENT PSliderWnd +#define SEQPREAMP_XMLPARENT PSliderWnd + +class SEQPreamp : public SEQPREAMP_PARENT, public CoreCallbackI { +public: + SEQPreamp(); + virtual ~SEQPreamp(); + + virtual int onInit(); + +protected: + virtual int onSetPosition(); + + virtual int corecb_onEQPreampChange(int newval); + int discard_next_event; +}; + +extern const wchar_t eqPreAmpXuiStr[]; +extern char eqPreAmpXuiSvcName[]; +class EqPreAmpXuiSvc : public XuiObjectSvc<SEQPreamp, eqPreAmpXuiStr, eqPreAmpXuiSvcName> {}; + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/seqvis.cpp b/Src/Wasabi/api/skin/widgets/seqvis.cpp new file mode 100644 index 00000000..9850954d --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/seqvis.cpp @@ -0,0 +1,367 @@ +#include <precomp.h> + +#include <api/wnd/popup.h> +#include <math.h> +#include <api/skin/skinparse.h> +#include <api/service/svc_enum.h> +#include <api/service/svcs/svc_skinfilter.h> +#include <api/skin/widgets/seqvis.h> +#include <api/core/api_core.h> +#include <tataki/canvas/bltcanvas.h> +const wchar_t eqVisXuiStr[] = L"EQVis"; // This is the xml tag +char eqVisXuiSvcName[] = "EQVis xui object"; // this is the name of the xuiservice +XMLParamPair SEQVis::params[] = + { + { + SEQVIS_SETCOLORBOTTOM, L"COLORBOTTOM" + }, + {SEQVIS_SETCOLORMIDDLE, L"COLORMIDDLE"}, + {SEQVIS_SETCOLORPREAMP, L"COLORPREAMP"}, + {SEQVIS_SETCOLORTOP, L"COLORTOP"}, + {SEQVIS_SETALPHA, L"GAMMA"}, // BACKWARD COMPAT + }; +SEQVis::SEQVis() +{ + getScriptObject()->vcpu_setInterface(eqvisGuid, (void *)static_cast<SEQVis *>(this)); + getScriptObject()->vcpu_setClassName(L"EqVis"); + getScriptObject()->vcpu_setController(eqvisController); + colortop = colormid = colorbottom = 0xffffff; + colorpreamp = 0x888888; + shadedColors = NULL; + bc = NULL; + sfe = new SkinFilterEnum(); + + while (1) + { + svc_skinFilter *obj = sfe->getNext(); + if (!obj) break; + filters.addItem(obj); + } + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); + +} + +void SEQVis::CreateXMLParameters(int master_handle) +{ + //SEQVIS_PARENT::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); +} + +int SEQVis::onInit() +{ + SEQVIS_PARENT::onInit(); + WASABI_API_MEDIACORE->core_addCallback(0, this); + return 1; +} + +SEQVis::~SEQVis() +{ + foreach(filters) + sfe->release(filters.getfor()); + endfor; + delete sfe; + if (shadedColors) FREE(shadedColors); + delete(bc); + WASABI_API_MEDIACORE->core_delCallback(0, this); +} + +int SEQVis::setXuiParam(int _xuihandle, int attrid, const wchar_t *paramname, const wchar_t *strvalue) +{ + if (_xuihandle != xuihandle) return SEQVIS_PARENT::setXuiParam(_xuihandle, attrid, paramname, strvalue); + switch (attrid) + { + case SEQVIS_SETALPHA: + getGuiObject()->guiobject_setAlpha(WTOI(strvalue)); + break; + case SEQVIS_SETCOLORTOP: + colortop = RGBTOBGR(SkinParser::parseColor(strvalue)); + break; + case SEQVIS_SETCOLORMIDDLE: + colormid = RGBTOBGR(SkinParser::parseColor(strvalue)); + break; + case SEQVIS_SETCOLORBOTTOM: + colorbottom = RGBTOBGR(SkinParser::parseColor(strvalue)); + break; + case SEQVIS_SETCOLORPREAMP: + colorpreamp = RGBTOBGR(SkinParser::parseColor(strvalue)); + break; + default: + return 0; + } + return 1; +} + +void SEQVis::splineGetPoint(spline_struct *s, float frame, float *out) +{ + int i, i_1, i0, i1, i2; + float time1, time2, time3; + float t1, t2, t3, t4, u1, u2, u3, u4, v1, v2, v3; + float a, b, c, d; + + float *keys = s->keys; + + a = (1 - s->tens) * (1 + s->cont) * (1 + s->bias); + b = (1 - s->tens) * (1 - s->cont) * (1 - s->bias); + c = (1 - s->tens) * (1 - s->cont) * (1 + s->bias); + d = (1 - s->tens) * (1 + s->cont) * (1 - s->bias); + v1 = t1 = -a / 2.0f; u1 = a; + u2 = (-6 - 2 * a + 2 * b + c) / 2.0f; v2 = (a - b) / 2.0f; t2 = (4 + a - b - c) / 2.0f; + t3 = (-4 + b + c - d) / 2.0f; + u3 = (6 - 2 * b - c + d) / 2.0f; + v3 = b / 2.0f; + t4 = d / 2.0f; u4 = -t4; + + i0 = (int) frame; + i_1 = i0 - 1; + while (i_1 < 0) i_1 += s->numKeys; + i1 = i0 + 1; + while (i1 >= s->numKeys) i1 -= s->numKeys; + i2 = i0 + 2; + while (i2 >= s->numKeys) i2 -= s->numKeys; + time1 = frame - (float)((int) frame); + time2 = time1 * time1; + time3 = time2 * time1; + i0 *= s->keyWidth; + i1 *= s->keyWidth; + i2 *= s->keyWidth; + i_1 *= s->keyWidth; + for (i = 0; i < s->keyWidth; i ++) + { + a = t1 * keys[i + i_1] + t2 * keys[i + i0] + t3 * keys[i + i1] + t4 * keys[i + i2]; + b = u1 * keys[i + i_1] + u2 * keys[i + i0] + u3 * keys[i + i1] + u4 * keys[i + i2]; + c = v1 * keys[i + i_1] + v2 * keys[i + i0] + v3 * keys[i + i1]; + *out++ = a * time3 + b * time2 + c * time1 + keys[i + i0]; + } +} + +void SEQVis::DrawEQVis() +{ + + if (!shadedColors) return ; + + float keys[12] = {0}; + spline_struct spline = {keys, 1, 12, 0.0f, 0.0f, 0.1f}; + + MEMSET(specData, 0, cur_w*cur_h*4); + + int ph = (int)((127 + WASABI_API_MEDIACORE->core_getEqPreamp(0)) * ((float)cur_h) / 256.0f); + ph *= cur_w; + for (int j = 0;j < cur_w;j++) + specData[j + ph] = colorpreamp | 0xFF000000; // alpha :) + + { + int x; + int last_p = -1; + for (x = 0; x < 10; x ++) + keys[x + 1] = (127 - WASABI_API_MEDIACORE->core_getEqBand(0, x)) * ((float)cur_h) / 256.0f; + keys[0] = keys[1]; + keys[11] = keys[10]; + + for (x = 0; x < cur_w; x ++) + { + float p; + int this_p; + splineGetPoint(&spline, 1.0f + x / (cur_w*11.0f / 100.0f), &p); + this_p = (int)p; + if (this_p < 0) this_p = 0; + if (this_p >= cur_h) this_p = cur_h - 1; + if (last_p == -1 || this_p == last_p) + specData[x + this_p*cur_w] = shadedColors[this_p]; + else + { + if (this_p < last_p) + for (int j = 0;j < last_p - this_p + 1;j++) + specData[x + (this_p + j)*cur_w] = shadedColors[this_p + j]; + else if (this_p > last_p) + for (int j = 0;j < this_p - last_p + 1;j++) + specData[x + (last_p + j)*cur_w] = shadedColors[last_p + j]; + } + last_p = this_p; + } + } + invalidate(); + invalidated = 1; // rerun filter +} + +int SEQVis::onPaint(Canvas *canvas) +{ + PaintCanvas paintcanvas; + if (canvas == NULL) + { + if (!paintcanvas.beginPaint(this)) return 0; + canvas = &paintcanvas; + } + + SEQVIS_PARENT::onPaint(canvas); + + RECT s, r; + getClientRect(&r); + s.left = 0; + s.top = 0; + s.right = cur_w; + s.bottom = cur_h; + + if (invalidated) + { + SkinBitmap *b = bc->getSkinBitmap(); + foreach(filters) + filters.getfor()->filterBitmap((unsigned char *)bc->getBits(), b->getWidth(), b->getHeight(), 32, NULL, L"Vis/Eq"); + endfor; + invalidated = 0; + b->stretchToRectAlpha(canvas, &s, &r, getPaintingAlpha()); + } + else + { + bc->stretchToRectAlpha(canvas, &s, &r, getPaintingAlpha()); + //SkinBitmap *b = bc->getSkinBitmap(); + //b->stretchToRectAlpha(canvas, &s, &r, getPaintingAlpha()); + } + + + return 1; +} + +int SEQVis::corecb_onEQBandChange(int b, int newval) +{ + DrawEQVis(); + return 0; +} + +int SEQVis::corecb_onEQPreampChange(int newval) +{ + DrawEQVis(); + return 0; +} + +void SEQVis::reloadResources() +{ + SEQVIS_PARENT::reloadResources(); + DrawEQVis(); + invalidate(); +} + +int SEQVis::onResize() +{ + SEQVIS_PARENT::onResize(); + RECT r; + getClientRect(&r); + + cur_h = r.bottom - r.top; + if (cur_h <= 0) cur_h = 1; + cur_w = r.right - r.left; + if (cur_w <= 0) cur_w = 1; + + delete bc; + bc = new BltCanvas(cur_w, -cur_h); + specData = (int *)bc->getBits(); + MEMSET(specData, 0, cur_w*cur_h*4); + + if (shadedColors) FREE(shadedColors); + shadedColors = (int *)MALLOC(sizeof(int) * cur_h); + int r1 = colortop & 0xff0000; + int g1 = (colortop & 0x00ff00) << 8; + int b1 = (colortop & 0x0000ff) << 16; + int r2 = colormid & 0xff0000; + int g2 = (colormid & 0x00ff00) << 8; + int b2 = (colormid & 0x0000ff) << 16; + int r3 = colorbottom & 0xff0000; + int g3 = (colorbottom & 0x00ff00) << 8; + int b3 = (colorbottom & 0x0000ff) << 16; + int l = cur_h / 2; + if (!l) l = 1; + int i; + for (i = 0;i < l;i++) + { + int r = r1 + ((r2 - r1) * i / l); + int g = g1 + ((g2 - g1) * i / l); + int b = b1 + ((b2 - b1) * i / l); + shadedColors[i] = (r & 0xff0000); + shadedColors[i] += ((g & 0xff0000) >> 8); + shadedColors[i] += ((b & 0xff0000) >> 16); + shadedColors[i] += 0xff000000; // alpha? + } + for (i = l;i < cur_h;i++) + { + int r = r2 + ((r3 - r2) * (i - l) / l); + int g = g2 + ((g3 - g2) * (i - l) / l); + int b = b2 + ((b3 - b2) * (i - l) / l); + shadedColors[i] = (r & 0xff0000); + shadedColors[i] += ((g & 0xff0000) >> 8); + shadedColors[i] += ((b & 0xff0000) >> 16); + shadedColors[i] += 0xff000000; // alpha? + } + DrawEQVis(); + + return 1; +} + +EqVisScriptController _eqvisController; +EqVisScriptController *eqvisController = &_eqvisController; + +// -- Functions table ------------------------------------- +function_descriptor_struct EqVisScriptController::exportedFunction[] = { + {L"fake", 0, (void*)SEQVis::script_vcpu_fake }, + }; + +// -------------------------------------------------------- + +const wchar_t *EqVisScriptController::getClassName() +{ + return L"EqVis"; +} + +const wchar_t *EqVisScriptController::getAncestorClassName() +{ + return L"GuiObject"; +} + +ScriptObject *EqVisScriptController::instantiate() +{ + SEQVis *eqv = new SEQVis; + ASSERT(eqv != NULL); + return eqv->getScriptObject(); +} + +void EqVisScriptController::destroy(ScriptObject *o) +{ + SEQVis *eqv = static_cast<SEQVis *>(o->vcpu_getInterface(eqvisGuid)); + ASSERT(eqv != NULL); + delete eqv; +} + +void *EqVisScriptController::encapsulate(ScriptObject *o) +{ + return NULL; // no encapsulation for eqvis yet +} + +void EqVisScriptController::deencapsulate(void *o) +{} + +int EqVisScriptController::getNumFunctions() +{ + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *EqVisScriptController::getExportedFunctions() +{ + return exportedFunction; +} + +GUID EqVisScriptController::getClassGuid() +{ + return eqvisGuid; +} + +// ----------------------------------------------------------------------- + + +scriptVar SEQVis::script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + RETURN_SCRIPT_VOID; +} + diff --git a/Src/Wasabi/api/skin/widgets/seqvis.h b/Src/Wasabi/api/skin/widgets/seqvis.h new file mode 100644 index 00000000..0562c8a2 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/seqvis.h @@ -0,0 +1,104 @@ +#ifndef _SEQVIS_H +#define _SEQVIS_H + +#include <api/wnd/basewnd.h> +#include <api/wnd/virtualwnd.h> +#include <api/syscb/callbacks/corecbi.h> +#include <api/service/svc_enum.h> +#include <api/service/svcs/svc_skinfilter.h> +#include <api/script/objects/guiobj.h> + +// {8D1EBA38-489E-483e-B960-8D1F43C5C405} +static const GUID eqvisGuid = +{ 0x8d1eba38, 0x489e, 0x483e, { 0xb9, 0x60, 0x8d, 0x1f, 0x43, 0xc5, 0xc4, 0x5 } }; + +#define SEQVIS_PARENT GuiObjectWnd + +class EqVisScriptController : public GuiObjectScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + 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); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern EqVisScriptController *eqvisController; + +class SEQVis : public SEQVIS_PARENT, public CoreCallbackI { +public: + SEQVis(); + virtual ~SEQVis(); + + virtual int setXuiParam(int xiuhandle, int attrid, const wchar_t *paramname, const wchar_t *strvalue); + + int onInit(); + void DrawEQVis(); + int onPaint(Canvas *canvas); + + virtual int onResize(); + +protected: +/*static */void CreateXMLParameters(int master_handle); + typedef struct { + float *keys; /* Key data, keyWidth*numKeys */ + signed int keyWidth; /* Number of floats per key */ + signed int numKeys; /* Number of keys */ + float cont; /* Continuity. Should be -1.0 -> 1.0 */ + float bias; /* Bias. -1.0 -> 1.0 */ + float tens; /* Tension. -1.0 -> 1.0 */ + } spline_struct; + + void splineGetPoint(spline_struct *s, float frame, float *out); + + virtual int corecb_onEQPreampChange(int newval); + virtual int corecb_onEQBandChange(int band, int newval); + + virtual void reloadResources(); + + enum { + SEQVIS_SETALPHA=0, + SEQVIS_SETCOLORTOP, + SEQVIS_SETCOLORMIDDLE, + SEQVIS_SETCOLORBOTTOM, + SEQVIS_SETCOLORPREAMP, + }; + + +private: + static XMLParamPair params[]; + BltCanvas *bc; + int *specData; + int cur_w, cur_h; + int colortop, colormid, colorbottom; + int colorpreamp; + int *shadedColors; + int invalidated; + PtrList<svc_skinFilter>filters; + SkinFilterEnum *sfe; + int xuihandle; + +public: + + static scriptVar script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static void instantiate(SEQVis *s); + +}; + +extern const wchar_t eqVisXuiStr[]; +extern char eqVisXuiSvcName[]; +class EqVisXuiSvc : public XuiObjectSvc<SEQVis, eqVisXuiStr, eqVisXuiSvcName> {}; + + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/spanbar.cpp b/Src/Wasabi/api/skin/widgets/spanbar.cpp new file mode 100644 index 00000000..b377f88e --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/spanbar.cpp @@ -0,0 +1,58 @@ +#include <precomp.h> +#include "spanbar.h" +#include <api/core/api_core.h> + +const wchar_t panBarXuiStr[] = L"PanBar"; // This is the xml tag +char panBarXuiSvcName[] = "PanBar xui object"; // this is the name of the xuiservice + + +#define SPANBAR_NOTIFY_MSG NUM_NOTIFY_MESSAGES+0x1000 + +SPanBar::SPanBar() { + setDrawOnBorders(TRUE); + setEnable(TRUE); + setHotPosition(127); + locked = 0; +} + +SPanBar::~SPanBar() { + WASABI_API_MEDIACORE->core_delCallback(0, this); +} + +int SPanBar::onInit() { + SPANBAR_PARENT::onInit(); + + corecb_onPanChange(WASABI_API_MEDIACORE->core_getPan(0)); + WASABI_API_MEDIACORE->core_addCallback(0, this); + + return 1; +} + +int SPanBar::onSetPosition() { + setHotPosition((Std::keyDown(VK_SHIFT) ? -1 : 127)); + SPANBAR_PARENT::onSetPosition(); + int pos = getSliderPosition(); // get slider pos + int p=pos-127; + WASABI_API_MEDIACORE->core_setPan(0,p); + return 1; +} + +int SPanBar::corecb_onPanChange(int newpan) { + if (getSeekStatus()) return 0; + int pos = newpan+127; + setPosition(pos,0); + onPostedPosition(pos); + return 0; +} + +void SPanBar::lock() { + if (locked) return; + locked = 1; + WASABI_API_MEDIACORE->core_delCallback(0, this); +} + +void SPanBar::unlock() { + if (!locked) return; + locked = 0; + WASABI_API_MEDIACORE->core_addCallback(0, this); +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/spanbar.h b/Src/Wasabi/api/skin/widgets/spanbar.h new file mode 100644 index 00000000..63d40941 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/spanbar.h @@ -0,0 +1,31 @@ +#ifndef _SPANBAR_H +#define _SPANBAR_H + +#include "pslider.h" +#include <api/syscb/callbacks/corecbi.h> + +#define SPANBAR_PARENT PSliderWnd +#define SPANBAR_XMLPARENT PSliderWnd + +class SPanBar : public SPANBAR_PARENT, public CoreCallbackI { +public: + SPanBar(); + virtual ~SPanBar(); + + virtual int onInit(); + virtual void lock(); + virtual void unlock(); + +protected: + int locked; + virtual int onSetPosition(); + + virtual int corecb_onPanChange(int newpan); +}; + +extern const wchar_t panBarXuiStr[]; +extern char panBarXuiSvcName[]; +class PanBarXuiSvc : public XuiObjectSvc<SPanBar, panBarXuiStr, panBarXuiSvcName> {}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/sseeker.cpp b/Src/Wasabi/api/skin/widgets/sseeker.cpp new file mode 100644 index 00000000..fb2cbe5b --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/sseeker.cpp @@ -0,0 +1,128 @@ +#include <precomp.h> + +#include "sseeker.h" +#include <api/script/scriptmgr.h> +#include <api/core/api_core.h> + +#define SSeeker_TIMER_POS 1 +#define SSEEKER_INTERVAL 500 + +const wchar_t seekBarXuiStr[] = L"SeekBar"; // This is the xml tag +char seekBarXuiSvcName[] = "SeekBar xui object"; // this is the name of the xuiservice + +XMLParamPair SSeeker::params[] = { + {SSEEKER_SETINTERVAL, L"INTERVAL"}, +}; +SSeeker::SSeeker() { + setDrawOnBorders(TRUE); + status = STOP; + update_interval = SSEEKER_INTERVAL; + locked = 0; + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); + + setLimits(0, 65535); +} + +void SSeeker::CreateXMLParameters(int master_handle) +{ + //SSEEKER_PARENT::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); +} + +SSeeker::~SSeeker() { + killTimer(SSeeker_TIMER_POS); + WASABI_API_MEDIACORE->core_delCallback(0, this); +} + +int SSeeker::setXuiParam(int _xuihandle, int attribid, const wchar_t *name, const wchar_t *strval) { + if (xuihandle != _xuihandle) return SSEEKER_PARENT::setXuiParam(_xuihandle, attribid, name, strval); + switch (attribid) { + case SSEEKER_SETINTERVAL: + if ((update_interval = WTOI(strval)) <= 20) + update_interval = SSEEKER_INTERVAL; + break; + default: + return 0; + } + return 1; +} + +int SSeeker::onInit() { + SSEEKER_PARENT::onInit(); + + timerCallback(SSeeker_TIMER_POS); + setTimer(SSeeker_TIMER_POS, update_interval); + + WASABI_API_MEDIACORE->core_addCallback(0, this); + + return 1; +} + +int SSeeker::onSetFinalPosition() { + SSEEKER_PARENT::onSetFinalPosition(); + if (WASABI_API_MEDIACORE->core_getPosition(0) == -1) return 1; + int pos = getSliderPosition(); // get slider pos + int len = WASABI_API_MEDIACORE->core_getLength(0); + int corepos = (int)(((double)pos * (double)len) / 65535.f); + WASABI_API_MEDIACORE->core_setPosition(0,corepos); + return 1; +} + +void SSeeker::timerCallback(int id) { + switch (id) { + case SSeeker_TIMER_POS: { + if (getSeekStatus()) return; + + int playpos = WASABI_API_MEDIACORE->core_getPosition(0); + int len = WASABI_API_MEDIACORE->core_getLength(0); + if (playpos < 0 || len <= 0) { + setVisible(0); + status=STOP; + return; + } + int newpos = (int)(((double)playpos / (double)len) * 65535.f); + if (getSliderPosition() != newpos) { + setPosition(newpos, 0); + onPostedPosition(newpos / scriptDivisor()); + } + if (len > 0 && !isVisible()) { + status=PLAY; + setVisible(1); + } + } + break; + default: + SSEEKER_PARENT::timerCallback(id); + } +} + +int SSeeker::corecb_onStarted() { + timerCallback(SSeeker_TIMER_POS); + return 0; +} + +int SSeeker::corecb_onStopped() { + timerCallback(SSeeker_TIMER_POS); + return 0; +} + +int SSeeker::corecb_onSeeked(int newpos) { + timerCallback(SSeeker_TIMER_POS); + return 0; +} + +void SSeeker::lock() { + if (locked) return; + locked = 1; + WASABI_API_MEDIACORE->core_delCallback(0, this); +} + +void SSeeker::unlock() { + if (!locked) return; + locked = 0; + WASABI_API_MEDIACORE->core_addCallback(0, this); +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/sseeker.h b/Src/Wasabi/api/skin/widgets/sseeker.h new file mode 100644 index 00000000..ee948059 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/sseeker.h @@ -0,0 +1,56 @@ +#ifndef _SSEEKER_H +#define _SSEEKER_H + +#include "pslider.h" +#include <api/syscb/callbacks/corecbi.h> + +#define SSEEKER_PARENT PSliderWnd +#define SSEEKER_XMLPARENT PSliderWnd + +#define STOP 0 +#define PLAY 1 + +class SSeeker : public SSEEKER_PARENT, public CoreCallbackI { +public: + SSeeker(); + virtual ~SSeeker(); + + virtual int onInit(); + + virtual int setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *val); + virtual void lock(); + virtual void unlock(); + + virtual int scriptDivisor() { return 256; } + + enum { + SSEEKER_SETINTERVAL=0, + }; + +protected: + /*static */void CreateXMLParameters(int master_handle); + virtual int onSetFinalPosition(); + + // from BaseWnd + virtual void timerCallback(int id); + + // from CoreCallbackI + virtual int corecb_onSeeked(int newpos); + virtual int corecb_onStarted(); + virtual int corecb_onStopped(); + + int status; + +private: + static XMLParamPair params[]; + int update_interval; + int locked; + int xuihandle; +}; + +extern const wchar_t seekBarXuiStr[]; +extern char seekBarXuiSvcName[]; +class SeekBarXuiSvc : public XuiObjectSvc<SSeeker, seekBarXuiStr, seekBarXuiSvcName> {}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/sstatus.cpp b/Src/Wasabi/api/skin/widgets/sstatus.cpp new file mode 100644 index 00000000..e17d4da2 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/sstatus.cpp @@ -0,0 +1,172 @@ +#include <precomp.h> +#include <api/wndmgr/layout.h> +#include "sstatus.h" +#include <api/core/api_core.h> + +const wchar_t statusXuiStr[] = L"Status"; // This is the xml tag +char statusXuiSvcName[] = "Status xui object"; // this is the name of the xuiservice +XMLParamPair SStatus::params[] = { + {SSTATUS_SETPLAYBITMAP, L"PLAYBITMAP"}, + {SSTATUS_SETSTOPBITMAP, L"STOPBITMAP"}, + {SSTATUS_SETPAUSEBITMAP, L"PAUSEBITMAP"}, +}; + +SStatus::SStatus() { + getScriptObject()->vcpu_setInterface(statusGuid, (void *)static_cast<SStatus *>(this)); + getScriptObject()->vcpu_setClassName(L"Status"); + getScriptObject()->vcpu_setController(statusController); + currentStatus = -666; + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); + +} + +void SStatus::CreateXMLParameters(int master_handle) +{ + //SSTATUS_PARENT::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); +} + +SStatus::~SStatus() { + WASABI_API_MEDIACORE->core_delCallback(0, this); +} + +int SStatus::setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval) { + if (_xuihandle != xuihandle) return SSTATUS_PARENT::setXuiParam(_xuihandle, attrid, name, strval); + switch (attrid) { + case SSTATUS_SETPLAYBITMAP: + setPlayBitmap(strval); + break; + case SSTATUS_SETSTOPBITMAP: + setStopBitmap(strval); + break; + case SSTATUS_SETPAUSEBITMAP: + setPauseBitmap(strval); + break; + default: + return 0; + } + return 1; +} + +int SStatus::getPreferences(int what) { + if (what == SUGGESTED_W) return getWidth(); + if (what == SUGGESTED_H) return getHeight(); + return SSTATUS_PARENT::getPreferences(what); +} + +int SStatus::getWidth() { + if (!playBitmap.getBitmap()) return 16; + return playBitmap.getWidth(); +} + +int SStatus::getHeight() { + if (!playBitmap.getBitmap()) return 16; + return playBitmap.getHeight(); +} + +int SStatus::onInit() { + SSTATUS_PARENT::onInit(); + WASABI_API_MEDIACORE->core_addCallback(0, this); + currentStatus=WASABI_API_MEDIACORE->core_getStatus(0); + return 1; +} + +int SStatus::onPaint(Canvas *canvas) { + PaintBltCanvas paintcanvas; + if (canvas == NULL) { + if (!paintcanvas.beginPaint(this)) return 0; + canvas = &paintcanvas; + } + + SSTATUS_PARENT::onPaint(canvas); + + RECT r; + getClientRect(&r); + + AutoSkinBitmap *rb = NULL; + switch(currentStatus) { + case -1: rb = &pauseBitmap; break; + case 0: rb = &stopBitmap; break; + case 1: rb = &playBitmap; break; + } + if (rb != NULL && rb->getBitmap() != NULL) rb->stretchToRect(canvas, &r); + + return 1; +} + +int SStatus::corecb_onStarted() { currentStatus=1; invalidate(); return 0; } +int SStatus::corecb_onStopped() { currentStatus=0; invalidate(); return 0; } +int SStatus::corecb_onPaused() { currentStatus=-1; invalidate(); return 0; } +int SStatus::corecb_onUnpaused() { currentStatus=1; invalidate(); return 0; } + +void SStatus::setPlayBitmap(const wchar_t *name) +{ + playBitmap=name; +} + +void SStatus::setPauseBitmap(const wchar_t *name) { + pauseBitmap=name; +} + +void SStatus::setStopBitmap(const wchar_t *name) { + stopBitmap=name; +} + +StatusScriptController _statusController; +StatusScriptController *statusController=&_statusController; + +// -- Functions table ------------------------------------- +function_descriptor_struct StatusScriptController::exportedFunction[] = { + {L"fake", 0, (void*)SStatus::script_vcpu_fake }, +}; + +// -------------------------------------------------------- + +const wchar_t *StatusScriptController::getClassName() { + return L"Status"; +} + +const wchar_t *StatusScriptController::getAncestorClassName() { + return L"GuiObject"; +} + +ScriptObject *StatusScriptController::instantiate() { + SStatus *st = new SStatus; + ASSERT(st != NULL); + return st->getScriptObject(); +} + +void StatusScriptController::destroy(ScriptObject *o) { + SStatus *st = static_cast<SStatus*>(o->vcpu_getInterface(statusGuid)); + ASSERT(st != NULL); + delete st; +} + +void *StatusScriptController::encapsulate(ScriptObject *o) { + return NULL; // no encapsulation for status yet +} + +void StatusScriptController::deencapsulate(void *o) { +} + +int StatusScriptController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *StatusScriptController::getExportedFunctions() { + return exportedFunction; +} + +GUID StatusScriptController::getClassGuid() { + return statusGuid; +} + +scriptVar SStatus::script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + RETURN_SCRIPT_VOID; +} + diff --git a/Src/Wasabi/api/skin/widgets/sstatus.h b/Src/Wasabi/api/skin/widgets/sstatus.h new file mode 100644 index 00000000..eec7b38d --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/sstatus.h @@ -0,0 +1,100 @@ +//PORTABLE +#ifndef _SSTATUS_H +#define _SSTATUS_H + +#include <api/wnd/basewnd.h> +#include <tataki/bitmap/autobitmap.h> +#include <api/wnd/virtualwnd.h> +#include <api/syscb/callbacks/corecbi.h> +#include <api/wnd/wndclass/guiobjwnd.h> + +// {0F08C940-AF39-4b23-80F3-B8C48F7EBB59} +static const GUID statusGuid = +{ 0xf08c940, 0xaf39, 0x4b23, { 0x80, 0xf3, 0xb8, 0xc4, 0x8f, 0x7e, 0xbb, 0x59 } }; + +#define SSTATUS_PARENT GuiObjectWnd + +class StatusScriptController : public GuiObjectScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + 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); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern StatusScriptController *statusController; + + +#ifndef _NOSTUDIO +class SStatus : public SSTATUS_PARENT, public CoreCallbackI { +public: + SStatus(); + virtual ~SStatus(); + + virtual int onInit(); + virtual int onPaint(Canvas *canvas); + + void setPlayBitmap(const wchar_t *name); + void setPauseBitmap(const wchar_t *name); + void setStopBitmap(const wchar_t *name); + + virtual int getWidth(); + virtual int getHeight(); + + virtual int setXuiParam(int xuihandle, int attrid, const wchar_t *name, const wchar_t *strval); + virtual int getPreferences(int what); + + // core callbacks + virtual int corecb_onStarted(); + virtual int corecb_onStopped(); + virtual int corecb_onPaused(); + virtual int corecb_onUnpaused(); + + enum { + SSTATUS_SETPLAYBITMAP=0, + SSTATUS_SETSTOPBITMAP, + SSTATUS_SETPAUSEBITMAP, + }; + +protected: + /*static */void CreateXMLParameters(int master_handle); +/*protected: + virtual void timerCallback(int id);*/ + +private: + AutoSkinBitmap playBitmap,pauseBitmap,stopBitmap; + + int currentStatus; + int xuihandle; + static XMLParamPair params[]; + +#else + +class SStatus : public SSTATUS_SCRIPTPARENT { + +#endif + +public: + + static scriptVar script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + +}; + +extern const wchar_t statusXuiStr[]; +extern char statusXuiSvcName[]; +class StatusXuiSvc : public XuiObjectSvc<SStatus, statusXuiStr, statusXuiSvcName> {}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/stats/statswnd.cpp b/Src/Wasabi/api/skin/widgets/stats/statswnd.cpp new file mode 100644 index 00000000..116c6c95 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/stats/statswnd.cpp @@ -0,0 +1,38 @@ +#include <precomp.h> +#include "statswnd.h" +#include <bfc/string/StringW.h> + +StatsWnd::StatsWnd() +{ + registerXml(); + WASABI_API_WNDMGR->autopopup_registerGroupId(L"statswnd.group", L"Internal Statistics"); + WASABI_API_SYSCB->syscb_registerCallback(this); +} + +StatsWnd::~StatsWnd() +{ + WASABI_API_SYSCB->syscb_deregisterCallback(this); +} + +int StatsWnd::skincb_onBeforeLoadingElements() +{ + registerXml(); + return 1; +} + +void StatsWnd::registerXml() +{ + StringW xml; + + xml = L"buf:"; + + xml += L"<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\"?>\n"; + xml += L"<WasabiXml version=\"1.0\">\n"; + xml += L"<groupdef id=\"statswnd.group\" name=\"Internal Statistics\">\n"; + xml += L" <Wasabi:Stats fitparent=\"1\" />\n"; + xml += L"</groupdef>\n"; + xml += L"</WasabiXml>\n"; + + WASABI_API_SKIN->loadSkinFile(xml); +} + diff --git a/Src/Wasabi/api/skin/widgets/stats/statswnd.h b/Src/Wasabi/api/skin/widgets/stats/statswnd.h new file mode 100644 index 00000000..8b66ad14 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/stats/statswnd.h @@ -0,0 +1,18 @@ +#ifndef __STATSWND_H +#define __STATSWND_H + +#include <api/syscb/callbacks/skincb.h> + +class StatsWnd : public SkinCallbackI { + public: + StatsWnd(); + virtual ~StatsWnd(); + + virtual int skincb_onBeforeLoadingElements(); + + private: + void registerXml(); + +}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/stats/xuistats.cpp b/Src/Wasabi/api/skin/widgets/stats/xuistats.cpp new file mode 100644 index 00000000..dd4f2927 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/stats/xuistats.cpp @@ -0,0 +1,149 @@ +#include <precomp.h> +#include "xuistats.h" +#include <tataki/canvas/ifc_canvas.h> +#include <tataki/color/skinclr.h> +#include <api.h> + +#include <api/imgldr/imgldr.h> +#include <api/skin/skinparse.h> +#include <api/skin/gammamgr.h> +#include <api/skin/skinelem.h> +#include <api/skin/regioncache.h> +#include <api/wnd/wndtrack.h> +#include <api/font/font.h> +#include <api/wnd/wndapi.h> +#include <api/skin/guitree.h> +#include <api/xml/xmlreader.h> +#include <api/skin/groupwndcreate.h> +#include <api/skin/groupmgr.h> +#include <api/script/script.h> +#include "bfc/ptrlist.h" +#include "bfc/memblock.h" + +// ----------------------------------------------------------------------- +const wchar_t XuiStatsXuiObjectStr[] = L"Wasabi:Stats"; // This is the xml tag +char XuiStatsXuiSvcName[] = "Wasabi:Stats xui object"; + + +// ----------------------------------------------------------------------- +XuiStats::XuiStats() { + hastimer = 0; + line = 0; + col = 0; + curcanvas = NULL; +} + +// ----------------------------------------------------------------------- +XuiStats::~XuiStats() { + if (hastimer) + killTimer(0x10); +} + +// ----------------------------------------------------------------------- +int XuiStats::onInit() { + XUISTATS_PARENT::onInit(); + return 1; +} + +// ----------------------------------------------------------------------- +#define MARGIN 10 +#define FONTSIZE 15 +#define LINEMUL 15 +#define COLMUL 200 +void XuiStats::doTextOut(Canvas *canvas, const wchar_t *text, int line, int col, const Wasabi::FontInfo *fontInfo) +{ + RECT r; + getClientRect(&r); + if (!canvas || !text || !*text) return; + canvas->textOutEllipsed(r.left+MARGIN+col*COLMUL, r.top+MARGIN+line*LINEMUL, COLMUL-MARGIN/2, LINEMUL, text, fontInfo); +} + +// ----------------------------------------------------------------------- +void XuiStats::addLine(const wchar_t *txt, const Wasabi::FontInfo *fontInfo) +{ + if (!curcanvas) return; + RECT r; + getClientRect(&r); + if (line * LINEMUL + MARGIN + FONTSIZE + r.top > r.bottom) + { col++; line = 0; if (*txt == 0) return; } + doTextOut(curcanvas, txt, line++, col, fontInfo); +} + +// ----------------------------------------------------------------------- +int XuiStats::onPaint(Canvas *canvas) +{ + XUISTATS_PARENT::onPaint(canvas); + curcanvas = canvas; + line = 0; + col = 0; + + Wasabi::FontInfo fontInfo; + fontInfo.face = wasabi_default_fontnameW; + fontInfo.pointSize = FONTSIZE; + fontInfo.color = SkinColor(L"wasabi.list.text"); + + addLine(L"---------------------------- System ------", &fontInfo); + //addLine( StringPrintfW(L"entries in ptrlists : %d", ptrlist_totalnitems) ); +#ifdef _DEBUG + addLine( StringPrintfW(L"total memblocks size : %d", memblocks_totalsize) , &fontInfo); +#endif + + // TODO: add to api_timer - addLine( StringPrintfW(L"timers : %d/%d", mainmultiplex->getNumTimers(), mainmultiplex->getNumTimersLP()) , &fontInfo); + + addLine(L"", &fontInfo); + addLine(L"----------------------------- Wnds -------", &fontInfo); + addLine( StringPrintfW(L"rootwnds : %d", windowTracker->getNumAllWindows()) , &fontInfo); + addLine( StringPrintfW(L"desktop rootwnds : %d", windowTracker->getNumWindows()) , &fontInfo); + + addLine(L"", &fontInfo); + addLine(L"--------------------------- ImgLdr -------", &fontInfo); + addLine( StringPrintfW(L"bytes in imgldr : %d", imageLoader::getMemUsage()) , &fontInfo); + addLine( StringPrintfW(L"cached imgldr entries : %d", imageLoader::getNumCached()) , &fontInfo); + addLine( StringPrintfW(L"region caches : %d", RegionCache::getNumCaches()) , &fontInfo); + + addLine(L"", &fontInfo); + addLine(L"----------------------------- Skin -------", &fontInfo); + addLine( StringPrintfW(L"skin bitmap elements : %d", WASABI_API_PALETTE->getNumBitmapElement()) , &fontInfo); + addLine( StringPrintfW(L"skin color elements : %d", WASABI_API_PALETTE->getNumColorElements()) , &fontInfo); + addLine( StringPrintfW(L"containers loaded : %d", SkinParser::getNumContainers()) , &fontInfo); + addLine( StringPrintfW(L"gamma sets : %d", WASABI_API_COLORTHEMES->getNumGammaSets()) , &fontInfo); + addLine( StringPrintfW(L"fonts : %d", Font::getNumFonts()) , &fontInfo); + addLine( StringPrintfW(L"base textures : %d", WndApi::getNumBaseTextures()) , &fontInfo); + addLine( StringPrintfW(L"guitree entries : %d", guiTree->getNumObject()) , &fontInfo); + addLine( StringPrintfW(L"wndtype groups : %d", GroupWndCreateSvc::num_group_list) , &fontInfo); + addLine( StringPrintfW(L"hosted groups : %d", GroupMgr::getNumGroups()) , &fontInfo); + addLine( StringPrintfW(L"scripts : %d", Script::getNumScripts()) , &fontInfo); + + addLine(L"", &fontInfo); + addLine(L"----------------------------- Misc -------", &fontInfo); + addLine( StringPrintfW(L"registered cfgitems : %d", WASABI_API_CONFIG->config_getNumCfgItems()) , &fontInfo); + + if (WASABI_API_THREADPOOL) + { + addLine(L"", &fontInfo); + addLine(L"----------------------------- ThreadPool -------", &fontInfo); + addLine( StringPrintfW(L"active threads : %d", WASABI_API_THREADPOOL->GetNumberOfActiveThreads()) , &fontInfo); + addLine( StringPrintfW(L"threads in pool : %d", WASABI_API_THREADPOOL->GetNumberOfThreads()) , &fontInfo); + } + + curcanvas = NULL; + return 1; +} + +// ----------------------------------------------------------------------- +void XuiStats::onSetVisible(int show) { + XUISTATS_PARENT::onSetVisible(show); + if (show) { + setTimer(0x10, 250); + } else { + killTimer(0x10); + } + hastimer = show; +} + +// ----------------------------------------------------------------------- +void XuiStats::timerCallback(int p1) { + if (p1 == 0x10) invalidate(); + else XUISTATS_PARENT::timerCallback(p1); +} + diff --git a/Src/Wasabi/api/skin/widgets/stats/xuistats.h b/Src/Wasabi/api/skin/widgets/stats/xuistats.h new file mode 100644 index 00000000..c6b91a6a --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/stats/xuistats.h @@ -0,0 +1,43 @@ +#ifndef __XUISTATS_H +#define __XUISTATS_H + +#include <api/wnd/wndclass/guiobjwnd.h> + +#define XUISTATS_PARENT GuiObjectWnd + +// {12D9C377-A981-4b77-95E0-242AF7226960} +static const GUID COLOREDIT_PREVIEWRECT_GUID = +{ 0x12d9c377, 0xa981, 0x4b77, { 0x95, 0xe0, 0x24, 0x2a, 0xf7, 0x22, 0x69, 0x60 } }; + +class ColorEditorInstance; + +// ----------------------------------------------------------------------- +class XuiStats : public XUISTATS_PARENT { + + public: + + XuiStats(); + virtual ~XuiStats(); + + virtual int onInit(); + virtual int onPaint(Canvas *c); + virtual void onSetVisible(int show); + virtual void timerCallback(int p1); + + virtual void addLine(const wchar_t *txt, const Wasabi::FontInfo *fontInfo); + + private: + void doTextOut(Canvas *canvas, const wchar_t *text, int line, int col, const Wasabi::FontInfo *fontInfo); + int hastimer; + + int line ; + int col; + Canvas *curcanvas; +}; + +// ----------------------------------------------------------------------- +extern const wchar_t XuiStatsXuiObjectStr[]; +extern char XuiStatsXuiSvcName[]; +class XuiStatsXuiSvc : public XuiObjectSvc<XuiStats, XuiStatsXuiObjectStr, XuiStatsXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/svolbar.cpp b/Src/Wasabi/api/skin/widgets/svolbar.cpp new file mode 100644 index 00000000..5152224a --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/svolbar.cpp @@ -0,0 +1,55 @@ +#include <precomp.h> +#include "svolbar.h" +#include <api/core/api_core.h> + +const wchar_t volBarXuiStr[] = L"VolBar"; // This is the xml tag +char volBarXuiSvcName[] = "VolBar xui object"; // this is the name of the xuiservice + + +#define SVOLBAR_NOTIFY_MSG NUM_NOTIFY_MESSAGES+0x1000 + +SVolBar::SVolBar() { + setDrawOnBorders(TRUE); + setEnable(TRUE); + locked = 0; + setLimits(0,255); +} + +SVolBar::~SVolBar() { + WASABI_API_MEDIACORE->core_delCallback(0, this); +} + +int SVolBar::onInit() { + SVOLBAR_PARENT::onInit(); + + corecb_onVolumeChange(WASABI_API_MEDIACORE->core_getVolume(0)); + WASABI_API_MEDIACORE->core_addCallback(0, this); + + return 1; +} + +int SVolBar::onSetPosition() { + SVOLBAR_PARENT::onSetPosition(); + int pos = getSliderPosition(); // get slider pos + WASABI_API_MEDIACORE->core_setVolume(0,pos); + return 1; +} + +int SVolBar::corecb_onVolumeChange(int newvol) { + if (getSeekStatus()) return 0; + setPosition(newvol, 0); + onPostedPosition(newvol); + return 0; +} + +void SVolBar::lock() { + if (locked) return; + locked = 1; + WASABI_API_MEDIACORE->core_delCallback(0, this); +} + +void SVolBar::unlock() { + if (!locked) return; + locked = 0; + WASABI_API_MEDIACORE->core_addCallback(0, this); +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/svolbar.h b/Src/Wasabi/api/skin/widgets/svolbar.h new file mode 100644 index 00000000..30f2f18d --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/svolbar.h @@ -0,0 +1,30 @@ +#ifndef _SVOLBAR_H +#define _SVOLBAR_H + +#include "pslider.h" +#include <api/syscb/callbacks/corecbi.h> + +#define SVOLBAR_PARENT PSliderWnd +#define SVOLBAR_XMLPARENT PSliderWnd + +class SVolBar : public SVOLBAR_PARENT, public CoreCallbackI { +public: + SVolBar(); + virtual ~SVolBar(); + + virtual int onInit(); + virtual void lock(); + virtual void unlock(); + +protected: + int locked; + virtual int onSetPosition(); + + virtual int corecb_onVolumeChange(int newvol); +}; + +extern const wchar_t volBarXuiStr[]; +extern char volBarXuiSvcName[]; +class VolBarXuiSvc : public XuiObjectSvc<SVolBar, volBarXuiStr, volBarXuiSvcName> {}; + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/text.cpp b/Src/Wasabi/api/skin/widgets/text.cpp new file mode 100644 index 00000000..fd7a16f4 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/text.cpp @@ -0,0 +1,1767 @@ +#include <precomp.h> +#include "text.h" +#include <api.h> +#include <api/wndmgr/layout.h> +#ifdef WASABI_WIDGETS_COMPBUCK +#include <api/skin/widgets/compbuck2.h> +#endif +#include <api/skin/skinparse.h> +#if defined(WA3COMPATIBILITY) || defined(WASABI_STATICVARMGR) +#include <api/util/varmgr.h> +#endif +#include <api/core/sequence.h> +#include <api/script/vcpu.h> +#ifdef WA3COMPATIBILITY +#include <core/corehandle.h> +#endif +#include <api/wnd/notifmsg.h> +#include <api/locales/xlatstr.h> +#include <api/skin/feeds/TextFeedEnum.h> +#include <bfc/parse/pathparse.h> +#include <bfc/util/timefmt.h> +#ifdef WASABI_COMPILE_MEDIACORE +#include <api/core/api_core.h> +#endif +#include <api/service/svcs/svc_font.h> +#include <api/config/items/attribs.h> +#include <api/skin/skinelem.h> +#include <api/service/svcs/svc_action.h> +#include <tataki/blending/blending.h> +#include <tataki/canvas/bltcanvas.h> + + +const wchar_t textXuiObjectStr[] = L"Text"; // This is the xml tag +char textXuiSvcName[] = "Text xui object"; // this is the name of the xuiservice + +#define TTS_DELAY 4000 + +#define TICKER_TIMER_POS 1 +#define TICKER_RESET_ALTNAME 2 +#define TIMER_SKIPCFG 0x987 + +#define COLORMODE_RGB 0 +#define COLORMODE_SKINCOLOR 1 + +XMLParamPair Text::params[] = +{ + {TEXT_SETALTSHADOWCOLOR, L"ALTSHADOWCOLOR"}, + {TEXT_SETALTSHADOWX, L"ALTSHADOWX"}, + {TEXT_SETALTSHADOWY, L"ALTSHADOWY"}, + {TEXT_SETALTVALIGN, L"ALTVALIGN"}, + {TEXT_SETCBSOURCE, L"CBSOURCE"}, + {TEXT_SETTEXT, L"DEFAULT"}, + {TEXT_SETDISPLAY, L"DISPLAY"}, + {TEXT_SETFORCEFIXED, L"FORCEFIXED"}, + {TEXT_SETFORCELOCASE, L"FORCELOWERCASE"}, + {TEXT_SETFORCELOCASE, L"FORCELOCASE"}, + {TEXT_SETFORCEUPCASE, L"FORCEUPCASE"}, + {TEXT_SETFORCEUPCASE, L"FORCEUPPERCASE"}, + + {TEXT_SETNOGRAB, L"NOGRAB"}, + {TEXT_SETOFFSETX, L"OFFSETX"}, + {TEXT_SETOFFSETY, L"OFFSETY"}, + + {TEXT_SETSHADOWCOLOR, L"SHADOWCOLOR"}, + {TEXT_SETSHADOWX, L"SHADOWX"}, + {TEXT_SETSHADOWY, L"SHADOWY"}, + {TEXT_SETSHOWLEN, L"SHOWLEN"}, + {TEXT_SETTEXT, L"TEXT"}, + {TEXT_SETTICKER, L"TICKER"}, + {TEXT_SETTICKERSTEP, L"TICKERSTEP"}, + {TEXT_SETTIMECOLONWIDTH, L"TIMECOLONWIDTH"}, + {TEXT_SETTIMERHOURS, L"TIMERHOURS"}, + {TEXT_SETTIMEROFFSTYLE, L"TIMEROFFSTYLE"}, + {TEXT_SETVALIGN, L"VALIGN"}, + {TEXT_SETWRAPPED, L"WRAP"}, + {TEXT_SETTIMERHOURSROLLOVER, L"TIMERHOURSROLLOVER"}, +}; + +Text::Text() +{ + getScriptObject()->vcpu_setInterface(textGuid, (void *)static_cast<Text *>(this)); + getScriptObject()->vcpu_setClassName(L"Text"); + getScriptObject()->vcpu_setController(textController); + + //isbitmapfont = iswinfontrender = 0; + bufferinvalid = 1; + cachedsizew = 0; + size[0] = size[1] = 0; + textpos = 0; + time_tts = 20; + tts = time_tts; + sens = 0; + grab_x = 0; + cur_len = 0; + ticker = 0; + timerhours = 0; + timerhoursRollover = 0; + display = DISPLAY_NONE; + elapsed = 1; + fixedTimerStyle = 0; + + shadowcolor[0].setColorGroup(L"Text backgrounds"); + shadowcolor[0].setColor(RGB(0, 0, 0)); + shadowcolor[1].setColorGroup(L"Text backgrounds"); + shadowcolor[1].setColor(RGB(0, 0, 0)); + + shadowcolor_mode[0] = COLORMODE_RGB; + shadowcolor_mode[1] = COLORMODE_RGB; + shadowx[0] = shadowx[1] = shadowy[0] = shadowy[1] = 0; + timecolonw = -1; + + timeroffstyle = 0; + + nograb = 0; + showlen = 0; + forcefixed = 0; + + forceupcase = 0; + forcelocase = 0; + lastautowidth = 32; + textfeed = NULL; + wrapped = 0; + valign[0] = ALIGN_CENTER; + valign[1] = ALIGN_CENTER; + offsetx = 0; + offsety = 0; + tickerstep = 1; + const GUID uioptions_guid = + { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } }; + CfgItem *item = WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid); + if (item != NULL) + { + float f = (float)item->getDataAsFloat(L"Text Ticker Speed", 1.0f / 2.0f); + skipn = (int)((1.0f / f) - 1 + 0.5f); + } + skip = 0; + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); + registered_syscb = 0; +} + +void Text::CreateXMLParameters(int master_handle) +{ + //TEXT_PARENT::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); +} + +Text::~Text() +{ + killTimer(TICKER_TIMER_POS); + killTimer(TICKER_RESET_ALTNAME); + killTimer(TIMER_SKIPCFG); + + if (registered_syscb) WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SvcCallbackI*>(this)); + +#ifdef WASABI_WIDGETS_COMPBUCK + if (display == DISPLAY_CB) + if (mycbid.getNumItems() == 0) + ComponentBucket2::unRegisterText(this); + else + for (int i = 0;i < mycbid.getNumItems();i++) + ComponentBucket2::unRegisterText(this, mycbid.enumItem(i)->getValue()); +#endif + +#ifdef WASABI_COMPILE_MEDIACORE + WASABI_API_MEDIACORE->core_delCallback(0, this); +#endif + if (textfeed) + { + viewer_delViewItem(textfeed->getDependencyPtr()); + SvcEnum::release(textfeed); + textfeed = NULL; + } + mycbid.deleteAll(); +} + +int Text::setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval) +{ + if (xuihandle != _xuihandle) return TEXT_PARENT::setXuiParam(_xuihandle, attrid, name, strval); + switch (attrid) + { +#ifdef WASABI_COMPILE_MEDIACORE + case TEXT_SETDISPLAY: + displaystr = strval; + setDisplay(SkinParser::getDisplay(strval)); + if (!_wcsicmp(strval, L"TIMEREMAINING")) + { + fixedTimerStyle = 1; + elapsed = 0; + } + else if (!_wcsicmp(strval, L"TIMEELAPSED")) + { + fixedTimerStyle = 1; + elapsed = 1; + } + break; +#endif + case TEXT_SETTICKER: + setTickering(WTOI(strval)); + break; + + case TEXT_SETTEXT: + { + StringW old = getPrintedText(); + deftext = parseText(strval); + if (!WCSCASEEQLSAFE(old, getPrintedText())) + { + + if (WCSCASEEQLSAFE(L":componentname", deftext) || WCSCASEEQLSAFE(L"@COMPONENTNAME@", deftext)) + { + Container *container = getGuiObject()->guiobject_getParentGroup()->getParentContainer(); + viewer_addViewItem(container); + } + + StringW str = getPrintedText(); + onTextChanged(str); + } + break; + } + + case TEXT_SETSHADOWCOLOR: + if (WASABI_API_PALETTE->getColorElementRef(strval)) + { + shadowcolor_mode[0] = COLORMODE_SKINCOLOR; + sshadowcolor[0] = strval; + shadowcolor_mode[1] = COLORMODE_SKINCOLOR; + sshadowcolor[1] = strval; + } + else + setShadowColor(SkinParser::parseColor(strval), 0); + break; + + case TEXT_SETALTSHADOWCOLOR: + if (WASABI_API_PALETTE->getColorElementRef(strval)) + { + shadowcolor_mode[1] = COLORMODE_SKINCOLOR; + sshadowcolor[1] = strval; + } + else + setShadowColor(SkinParser::parseColor(strval), 1); + break; + + case TEXT_SETSHADOWX: + setShadowX(WTOI(strval)); + break; + + case TEXT_SETALTSHADOWX: + setShadowX(WTOI(strval), 1); + break; + + case TEXT_SETSHADOWY: + setShadowY(WTOI(strval)); + break; + + case TEXT_SETALTSHADOWY: + setShadowY(WTOI(strval), 0); + break; + + case TEXT_SETTIMEROFFSTYLE: + setTimerOffStyle(WTOI(strval)); + break; + + case TEXT_SETTIMERHOURS: + setTimerHours(WTOI(strval)); + break; + + case TEXT_SETTIMERHOURSROLLOVER: + setTimerHoursRollover(WTOI(strval)); + break; + + case TEXT_SETTIMECOLONWIDTH: + setTimeColonWidth(WTOI(strval)); + break; + + case TEXT_SETNOGRAB: + nograb = WTOI(strval); + break; + + case TEXT_SETSHOWLEN: + showlen = WTOI(strval); + break; + + case TEXT_SETFORCEFIXED: + forcefixed = WTOI(strval); + break; + + case TEXT_SETFORCEUPCASE: + forceupcase = WTOI(strval); + break; + + case TEXT_SETFORCELOCASE: + forcelocase = WTOI(strval); + break; + + case TEXT_SETCBSOURCE: + addCBSource(strval); + break; + + case TEXT_SETWRAPPED: + wrapped = WTOI(strval); + if (isPostOnInit()) + invalidateTextBuffer(); + break; + + case TEXT_SETVALIGN: + valign[0] = SkinParser::getAlign(strval); + valign[1] = valign[0]; + if (isPostOnInit()) + invalidateTextBuffer(); + break; + + case TEXT_SETALTVALIGN: + valign[1] = SkinParser::getAlign(strval); + if (isPostOnInit()) + invalidateTextBuffer(); + break; + + case TEXT_SETOFFSETX: + offsetx = WTOI(strval); + if (isPostOnInit()) + invalidateTextBuffer(); + break; + + case TEXT_SETTICKERSTEP: + tickerstep = WTOI(strval); + break; + + case TEXT_SETOFFSETY: + offsety = WTOI(strval); + if (isPostOnInit()) + invalidateTextBuffer(); + break; + + default: + return 0; + } + return 1; +} + +int Text::getPreferences(int what) +{ + StringW thaname = getPrintedText(); + if (thaname.isempty()) + { + return 32; + } + switch(wantTranslation()) + { + case 1: + thaname = _(thaname); + break; + case 2: + thaname = __(thaname); + break; + } + + int alt = 0; +#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 *item = WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid); + if (item != NULL) + { + alt = item->getDataAsInt(L"Alternate Fonts", 0); + if (alt < 0 || alt > 1) alt = 0; + } + if (alt) + { + if (item && item->getDataAsInt(L"No 7-bit TTF AltFonts", 1)) + { + const wchar_t *p = (const wchar_t *)thaname.getValue(); + while (p && *p) + { + if (*p > 127) break; + p++; + } + if (p && !*p) alt = 0; + } + } +#endif + switch (what) + { + case SUGGESTED_W: + { + int min_w = 0; + if (forceupcase) + thaname.toupper(); + if (forcelocase) + thaname.tolower(); + TextInfoCanvas canvas(this); + Wasabi::FontInfo fontInfo; + GetFontInfo(&fontInfo, alt); + + const wchar_t *p = wcschr(thaname, ':'); + if (display == DISPLAY_TIME && p) + { + wchar_t secs[256] = {0}; + wchar_t mins[256] = {0}; + WCSCPYN(mins, thaname, p - thaname); + + wcsncpy(secs, p + 1, 256); + int fixw = canvas.getTextWidth(L"0", &fontInfo); + int _ws = forcefixed ? fixw * wcslen(secs) : canvas.getTextWidth(secs, &fontInfo); + int _wm = forcefixed ? fixw * wcslen(mins) : canvas.getTextWidth(mins, &fontInfo); + int _wc = forcefixed ? fixw * wcslen(L":") : canvas.getTextWidth(L":", &fontInfo); + min_w = _ws + _wm + getTimeColonWidth(_wc); + } + else + { + PathParserW ppg(thaname, L"\n"); + for (int i = 0;i < ppg.getNumStrings();i++) + { + PathParserW pp(ppg.enumString(i), L"\t"); + int w = 0; + for (int j = 0; j < pp.getNumStrings(); j++) + { + w += canvas.getTextWidth(pp.enumString(j), &fontInfo) + 4; + } + min_w = MAX(min_w, w); + } + } + + return min_w + lpadding + rpadding; + } + case SUGGESTED_H: + PathParserW pp(thaname, L"\n"); + return fontsize[alt] * pp.getNumStrings(); + } + return TEXT_PARENT::getPreferences(what); +} + +// supermegafucko! corehandle should mirror bitrate/samplerate/channels functions instead of text having to know about gen_ff ! -- will do that real soon +#if defined(GEN_FF) & defined(WA5) +#include "../../../../Plugins/General/gen_ff/wa2frontend.h" +#endif + +int Text::onInit() +{ + TEXT_PARENT::onInit(); + registered_syscb++; + initDisplay(); + return 1; +} + +void Text::initDisplay() +{ +#ifdef WASABI_COMPILE_CONFIG + setTimer(TIMER_SKIPCFG, 1000); +#endif + switch (display) + { +#ifdef WASABI_COMPILE_MEDIACORE + case DISPLAY_SONGNAME: + setName(WASABI_API_APP->main_getVersionString()); + case DISPLAY_SONGARTIST: + case DISPLAY_SONGALBUM: + case DISPLAY_SONGLENGTH: + case DISPLAY_SONGTITLE: +#ifndef WASABI_COMPILE_METADB + case DISPLAY_SONGINFO: + case DISPLAY_SONGINFO_TRANSLATED: +#endif + setTimer(TICKER_TIMER_POS, 25); + setTimeTTS(TTS_DELAY / 25); + WASABI_API_MEDIACORE->core_addCallback(0, this); + timerCallback(TICKER_TIMER_POS); +#ifdef GEN_FF // supermegafucko! + if(WASABI_API_MEDIACORE->core_getStatus(0) != 0){ + if (display == DISPLAY_SONGINFO) + { + StringW txt; + GET_SONG_INFO_TEXT(txt); + corecb_onInfoChange(txt); + } + else if (display == DISPLAY_SONGINFO_TRANSLATED) + { + StringW txt; + GET_SONG_INFO_TEXT_TRANSLATED(txt); + corecb_onInfoChange(txt); + } + } +#endif + break; + + case DISPLAY_SONGBITRATE: + WASABI_API_MEDIACORE->core_addCallback(0, this); + corecb_onBitrateChange(wa2.getBitrate()); + break; + + case DISPLAY_SONGSAMPLERATE: + WASABI_API_MEDIACORE->core_addCallback(0, this); + corecb_onSampleRateChange(wa2.getSamplerate()); + break; + + case DISPLAY_TIME: +#ifdef WASABI_COMPILE_CONFIG + + if (getGuiObject()) + { + Layout *l = getGuiObject()->guiobject_getParentLayout(); + if (l && l->getId()) elapsed = WASABI_API_CONFIG->getIntPrivate(StringPrintfW(L"%s/timer_elapsed%s", l->getId(), (fixedTimerStyle ? StringPrintfW(L".%s", this->getId()) : L"")), elapsed); + else elapsed = WASABI_API_CONFIG->getIntPrivate(L"timer_elapsed", elapsed); + } + else elapsed = WASABI_API_CONFIG->getIntPrivate(L"timer_elapsed", elapsed); + +#endif + setTimer(TICKER_TIMER_POS, 250); + setTimeTTS(TTS_DELAY / 250); + WASABI_API_MEDIACORE->core_addCallback(0, this); + timerCallback(TICKER_TIMER_POS); + break; +#endif +#ifdef WASABI_WIDGETS_COMPBUCK + case DISPLAY_CB: + setTimer(TICKER_TIMER_POS, 50); + setTimeTTS(TTS_DELAY / 50); + postDeferredCallback(DISPLAY_CB, 0); + break; +#endif + case DISPLAY_SERVICE: + registerToTextFeedService(); + break; + break; + } +} + +int Text::onDeferredCallback(intptr_t p1, intptr_t p2) +{ +#ifdef WASABI_WIDGETS_COMPBUCK + switch (p1) + { + case DISPLAY_CB: + if (mycbid.getNumItems() == 0) + ComponentBucket2::registerText(this); + else + for (int i = 0;i < mycbid.getNumItems();i++) + ComponentBucket2::registerText(this, mycbid.enumItem(i)->getValue()); + return 0; + } +#endif + return TEXT_PARENT::onDeferredCallback(p1, p2); +} + +void Text::setShadowColor(COLORREF c, int alt) +{ + if (alt < 0 || alt > 1) alt = 0; + shadowcolor_mode[alt] = COLORMODE_RGB; + shadowcolor[alt].setColor(c); + invalidateTextBuffer(); + if (alt == 0) setShadowColor(c, 1); +} + +void Text::setShadowX(int x, int alt) +{ + if (alt < 0 || alt > 1) alt = 0; + shadowx[alt] = x; + invalidateTextBuffer(); + if (alt == 0) setShadowX(x, 1); +} + +void Text::setShadowY(int y, int alt) +{ + if (alt < 0 || alt > 1) alt = 0; + shadowy[alt] = y; + invalidateTextBuffer(); + if (alt == 0) setShadowY(y, 1); +} + +void Text::getBufferPaintSize(int *w, int *h) +{ + RECT r; + getClientRect(&r); + int _w = r.right - r.left; + int _h = r.bottom - r.top; + + if (bufferinvalid) + { + cachedsizew = getPreferences(SUGGESTED_W); + } + + if (w) *w = MAX(_w, cachedsizew); + if (h) *h = _h; +} + +void Text::getBufferPaintSource(RECT *r) +{ + if (r) + { + RECT cr; + getClientRect(&cr); + r->left = textpos; + r->right = cr.right - cr.left + textpos; + r->top = 0; + r->bottom = cr.bottom - cr.top; + } +} + +#include <bfc/util/profiler.h> + +// this is a temporary buffer, it should not be painted over with the painting alpha value, since it is going +// to be hanled in the actual blit by our ancestor +int Text::onBufferPaint(BltCanvas *canvas, int _w, int _h) +{ + int h, x, y=0; + + TEXT_PARENT::onBufferPaint(canvas, _w, _h); + + if (bufferinvalid) + { + cachedsizew = getPreferences(SUGGESTED_W); + + StringW thaname = getPrintedText(); + + if (thaname.isempty()) + { + RECT r = {0, 0, _w, _h}; + canvas->fillRect(&r, RGB(0, 0, 0)); + } + onTextChanged(thaname); // don't remove, skipped if unnecessary + + switch(wantTranslation()) + { + case 1: + thaname = _(thaname); + break; + case 2: + thaname = __(thaname); + break; + } + + int alt = 0; +#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 *item = WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid); + if (item != NULL) + { + alt = item->getDataAsInt(L"Alternate Fonts", 0); + if (alt < 0 || alt > 1) alt = 0; + } + if (alt) + { + if (item && item->getDataAsInt(L"No 7-bit TTF AltFonts", 1)) + { + const wchar_t *p = (const wchar_t *)thaname.getValue(); + while (p && *p) + { + if (*p > 127) break; + p++; + } + if (p && !*p) alt = 0; + } + } +#endif + + // canvas may have changed because of onTextChanged ! + canvas = render_canvas; + canvas->getDim(&_w, &_h, NULL); + + RECT r = {0, 0, _w, _h}; + + canvas->fillRect(&r, RGB(0, 0, 0)); + + if (forceupcase) + CharUpperW(thaname.getNonConstVal()); + if (forcelocase) + CharLowerW(thaname.getNonConstVal()); + + wchar_t secs[256] = {0}; + wchar_t mins[256] = {0}; + wchar_t hours[256] = {0}; + + Wasabi::FontInfo fontInfo; + GetFontInfo(&fontInfo, alt); + + const wchar_t *p = wcschr(thaname, L':'); + + if (display != DISPLAY_TIME || !p) + { + int wantpadding = 0; + int w = canvas->getTextWidth(thaname, &fontInfo); + if (w <= r.right - r.left - 2 - lpadding - rpadding) + { + // if text is wider than area, don't try to align it or it'll screw up the scroll + if (fontInfo.alignFlags != DT_CENTER) wantpadding = 1; + } + else + { + fontInfo.alignFlags = STDFONT_LEFT; + wantpadding = 1; + } + h = canvas->getTextHeight(thaname, &fontInfo); + x = r.left + 2 /*-textpos*/; + if (wantpadding) + x += lpadding; + switch (valign[alt]) + { + case ALIGN_CENTER: + y = r.top + ((r.bottom - r.top - h) / 2); + break; + case ALIGN_TOP: + y = r.top; + break; + } + x += offsetx; + y += offsety; + cur_len = 0; + PathParserW pp(thaname, L"\t"); + for (int i = 0; i < pp.getNumStrings(); i++) + { + if (i > 0) + fontInfo.alignFlags = ALIGN_RIGHT; + + if (shadowx[alt] != 0 || shadowy[alt] != 0) + { + fontInfo.color = getShadowColor(alt); + if (wrapped) + canvas->textOutWrapped(x + shadowx[alt], y + shadowy[alt], r.right - r.left - 2 /*+textpos*/, r.bottom - r.top, pp.enumString(i), &fontInfo); + else + canvas->textOut(x + shadowx[alt], y + shadowy[alt], r.right - r.left - 2 /*+textpos*/, r.bottom - r.top, pp.enumString(i), &fontInfo); + fontInfo.color = GetColor(alt); + } + if (wrapped) + canvas->textOutWrapped(x, y, r.right - r.left - 2 /*+textpos*/, r.bottom - r.top, pp.enumString(i), &fontInfo); + else + canvas->textOut(x, y, r.right - r.left - 2 /*+textpos*/, r.bottom - r.top, pp.enumString(i), &fontInfo); + cur_len = canvas->getTextWidth(pp.enumString(i), &fontInfo) + (wantpadding ? (lpadding + rpadding) : 0); + } + } + else + { + if(timerhours) + { + WCSCPYN(hours, thaname, (p - thaname)+1); + const wchar_t* p2 = wcschr(p + 1, L':'); + WCSCPYN(mins, p + 1, (p2 - p)); + if(p2 && *(p2 + 1)) + wcsncpy(secs, p2 + 1, 256); + else + { + wcsncpy(secs, mins, 256); + wcsncpy(mins, hours, 256); + hours[0] = 0; + } + } + else + { + WCSCPYN(mins, thaname, (p - thaname)+1); + wcsncpy(secs, p + 1, 256); + } + + h = canvas->getTextHeight(thaname, &fontInfo); + int fixw = canvas->getTextWidth(L"0", &fontInfo); + int _ws = forcefixed ? fixw * wcslen(secs) : canvas->getTextWidth(secs, &fontInfo); + int _wm = forcefixed ? fixw * wcslen(mins) : canvas->getTextWidth(mins, &fontInfo); + int _wh = forcefixed ? fixw * wcslen(hours) : canvas->getTextWidth(hours, &fontInfo); + int _wc = forcefixed ? fixw * wcslen(L":") : canvas->getTextWidth(L":", &fontInfo); + wchar_t widthchar = forcefixed ? '0' : 0; + if (fontInfo.alignFlags == ALIGN_RIGHT) + { + x = (r.right - 2) - shadowx[alt] - rpadding; + switch (valign[alt]) + { + case ALIGN_CENTER: + y = r.top + ((r.bottom - r.top - h) / 2); + break; + case ALIGN_TOP: + y = r.top; + break; + } + x += offsetx; + y += offsety; + if (shadowx[alt] != 0 || shadowy[alt] != 0) + { + fontInfo.color = getShadowColor(alt); + textOut(canvas, x - _ws, y, secs, widthchar, &fontInfo); + textOut(canvas, x - _ws - getTimeColonWidth(_wc), y, L":", widthchar, &fontInfo); + textOut(canvas, x - _ws - getTimeColonWidth(_wc) - _wm, y, mins, widthchar, &fontInfo); + if(timerhours && hours[0]) + { + textOut(canvas, x - _ws - getTimeColonWidth(_wc) - _wm - getTimeColonWidth(_wc), y, L":", widthchar, &fontInfo); + textOut(canvas, x - _ws - getTimeColonWidth(_wc) - _wm - getTimeColonWidth(_wc) - _wh, y, hours, widthchar, &fontInfo); + } + fontInfo.color = GetColor(alt); + } + + x += shadowx[alt]; y += shadowy[alt]; + textOut(canvas, x - _ws, y, secs, widthchar, &fontInfo); + textOut(canvas, x - _ws - getTimeColonWidth(_wc), y, L":", widthchar, &fontInfo); + textOut(canvas, x - _ws - getTimeColonWidth(_wc) - _wm, y, mins, widthchar, &fontInfo); + if(timerhours && hours[0]) + { + textOut(canvas, x - _ws - getTimeColonWidth(_wc) - _wm - getTimeColonWidth(_wc), y, L":", widthchar, &fontInfo); + textOut(canvas, x - _ws - getTimeColonWidth(_wc) - _wm - getTimeColonWidth(_wc) - _wh, y, hours, widthchar, &fontInfo); + } + } + else if (fontInfo.alignFlags == ALIGN_LEFT) + { + x = (r.left + 2) - shadowx[alt] + lpadding; + switch (valign[alt]) + { + case ALIGN_CENTER: + y = r.top + ((r.bottom - r.top - h) / 2); + break; + case ALIGN_TOP: + y = r.top; + break; + } + x += offsetx; + y += offsety; + if (shadowx != 0 || shadowy != 0) + { + fontInfo.color = getShadowColor(alt); + if(timerhours && hours[0]) + { + textOut(canvas, x, y, hours, widthchar, &fontInfo); + textOut(canvas, x + _wh, y, L":", widthchar, &fontInfo); + textOut(canvas, x + _wh + getTimeColonWidth(_wc), y, mins, widthchar, &fontInfo); + textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm, y, L":", widthchar, &fontInfo); + textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo); + } + else + { + textOut(canvas, x, y, mins, widthchar, &fontInfo); + textOut(canvas, x + _wm, y, L":", widthchar, &fontInfo); + textOut(canvas, x + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo); + } + fontInfo.color = GetColor(alt); + + } + x += shadowx[alt]; y += shadowy[alt]; + if(timerhours && hours[0]) + { + textOut(canvas, x, y, hours, widthchar, &fontInfo); + textOut(canvas, x + _wh, y, L":", widthchar, &fontInfo); + textOut(canvas, x + _wh + getTimeColonWidth(_wc), y, mins, widthchar, &fontInfo); + textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm, y, L":", widthchar, &fontInfo); + textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo); + } + else{ + textOut(canvas, x, y, mins, widthchar, &fontInfo); + textOut(canvas, x + _wm, y, L":", widthchar, &fontInfo); + textOut(canvas, x + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo); + } + } + else if (fontInfo.alignFlags == ALIGN_CENTER) + { + if(timerhours && hours[0]) + x = (r.left + ((r.right - r.left - _ws - _wm - _wh - getTimeColonWidth(_wc)) / 3)) - shadowx[alt]; + else + x = (r.left + ((r.right - r.left - _ws - _wm - getTimeColonWidth(_wc)) / 2)) - shadowx[alt]; + switch (valign[alt]) + { + case ALIGN_CENTER: + y = r.top + ((r.bottom - r.top - h) / 2); + break; + case ALIGN_TOP: + y = r.top; + break; + } + x += offsetx; + y += offsety; + if (shadowx[alt] != 0 || shadowy[alt] != 0) + { + fontInfo.color = getShadowColor(alt); + if(timerhours && hours[0]) + { + textOut(canvas, x, y, hours, widthchar, &fontInfo); + textOut(canvas, x + _wh, y, L":", widthchar, &fontInfo); + textOut(canvas, x + _wh + getTimeColonWidth(_wc), y, mins, widthchar, &fontInfo); + textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm, y, L":", widthchar, &fontInfo); + textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo); + } + else{ + textOut(canvas, x, y, mins, widthchar, &fontInfo); + textOut(canvas, x + _wm, y, L":", widthchar, &fontInfo); + textOut(canvas, x + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo); + } + fontInfo.color = GetColor(alt); + } + x += shadowx[alt]; y += shadowy[alt]; + if(timerhours && hours[0]) + { + textOut(canvas, x, y, hours, widthchar, &fontInfo); + textOut(canvas, x + _wh, y, L":", widthchar, &fontInfo); + textOut(canvas, x + _wh + getTimeColonWidth(_wc), y, mins, widthchar, &fontInfo); + textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm, y, L":", widthchar, &fontInfo); + textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo); + } + else{ + textOut(canvas, x, y, mins, widthchar, &fontInfo); + textOut(canvas, x + _wm, y, L":", widthchar, &fontInfo); + textOut(canvas, x + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo); + } + } + cur_len = _ws + _wm + getTimeColonWidth(_wc); + } + + bufferinvalid = 0; + } + + // alpha is taken care of in our bufferpaintwnd + return 1; +} + +void Text::timerCallback(int id) +{ + int upd = 0; + if (id == TIMER_SKIPCFG) + { +#ifdef WASABI_COMPILE_CONFIG + const GUID uioptions_guid = + { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } }; + CfgItem *item = WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid); + if (item != NULL) + { + float f = (float)item->getDataAsFloat(L"Text Ticker Speed", 1.0f / 2.0f); + skipn = (int)((1.0f / f) - 1 + 0.5f); + } +#endif + + } + if (id == TICKER_RESET_ALTNAME) + { + killTimer(id); + setAlternateName(NULL); + } + + if (getAlternateName() == NULL || !*getAlternateName()) + { + + if (id == TICKER_TIMER_POS) + { + +#ifdef WASABI_COMPILE_MEDIACORE + + wchar_t txt[4096] = {0}; + + // TODO: Change the way to get the current status text + switch (display) + { +#ifdef WASABI_COMPILE_METADB + case DISPLAY_SONGALBUM: + { + const char *cur = WASABI_API_CORE->core_getCurrent(0); + if (cur && (WASABI_API_METADB->metadb_getMetaData(cur, MT_ALBUM, txt, 4095, MDT_STRINGZ))) + { + if (!lastText.getValue() || STRCMP(txt, lastText.getValue())) + { + upd = 1; + setName(txt); + } + } + if (upd) + { + lastText = txt; + resetTicker(); + } + } + break; +#endif + case DISPLAY_SONGLENGTH: + { + int len = -1; +#ifdef WASABI_COMPILE_METADB + const char *cur = WASABI_API_CORE->core_getCurrent(0); + if (cur && (WASABI_API_METADB->metadb_getMetaData(cur, MT_LENGTH, (char *)&len, 4, MDT_TIME)) && len != -1) + { +#else + len = WASABI_API_MEDIACORE->core_getLength(0); + if (len != -1) + { +#endif + if (timerhours) + TimeFmt::printHourMinSec(len / 1000, txt, 4096, timerhoursRollover); + else + TimeFmt::printMinSec(len / 1000, txt, 4096); + + if (!lastText.getValue() || wcscmp(txt, lastText.getValue())) + { + upd = 1; + setName(txt); + } + } + if (upd) + { + lastText = txt; + resetTicker(); + } + } + break; +#ifdef WASABI_COMPILE_METADB + case DISPLAY_SONGARTIST: + { + const char *cur = WASABI_API_CORE->core_getCurrent(0); + if (cur && (WASABI_API_METADB->metadb_getMetaData(cur, MT_ARTIST, txt, 4095, MDT_STRINGZ))) + { + if (!lastText.getValue() || STRCMP(txt, lastText.getValue())) + { + upd = 1; + setName(txt); + } + } + if (upd) + { + lastText = txt; + resetTicker(); + } + } + break; +#endif + + + case DISPLAY_SONGNAME: + + case DISPLAY_SONGTITLE: + { + WCSCPYN(txt, WASABI_API_MEDIACORE->core_getTitle(0), 4096); + { + if (showlen) + { + int length = wa2.getLength(); + if (length != 0 && length != -1) + { + length /= 1000; + if (wcslen(txt) < 4095 - 25) + wcscat(txt, StringPrintfW(L" (%d:%02d)", length / 60, length % 60)); + } + } + + if (!lastText.getValue() || wcscmp(txt, lastText.getValue())) + { + upd = 1; + setName(txt); + } + } + if (upd) + { + lastText = txt; + resetTicker(); + } + } + break; + case DISPLAY_TIME: + { + int cp = WASABI_API_MEDIACORE->core_getPosition(0); + if (cp < 0) + { + switch (timeroffstyle) + { + case 0: + wcsncpy(txt, L" : ", 4096); + break; + case 1: + StringCbPrintfW(txt, sizeof(txt), L"%s00:00", elapsed ? L"" : L"-"); + break; + case 2: + *txt = 0; + break; + case 3: + StringCbPrintfW(txt, sizeof(txt), L"%s0:00:00", elapsed ? L"" : L"-"); + break; + case 4: + wcsncpy(txt, L" : : ", 4096); + break; + } + } + else + { + int p; + int len = WASABI_API_MEDIACORE->core_getLength(0); + int el = elapsed; + if (len == -1000 || el == -1) + el = 1; // no remaining time on http streams, etc... + if (el) + p = cp / 1000; + else + p = (len - cp) / 1000; + if (!el) p = -p; + if (timerhours) + TimeFmt::printHourMinSec(p, txt, 4096, timerhoursRollover); + else + TimeFmt::printMinSec(p, txt, 4096); + } + if (!lastText.getValue() || wcscmp(txt, lastText.getValue())) + { + setName(txt); + upd = 1; + lastText = txt; + } + } + break; + } + int u = 0; + advanceTicker(&u); + if (u) invalidateBuffer(); +#endif + + } + else + { + TEXT_PARENT::timerCallback(id); + } + } + + if (upd) + { + invalidateTextBuffer(); + } +} + +void Text::advanceTicker(int *upd) +{ + // update tts stuff + if (ticker && !grab && isVisible()) + { + int oldpos = textpos; + RECT re = clientRect(); + if (cur_len < (re.right - re.left - 2)) textpos = 0; + else if (tts > 0) tts -= (timerclient_getSkipped() + 1); + else + { + if (skip < skipn) skip++; + else + { + skip = 0; + if (!sens) textpos += tickerstep * (timerclient_getSkipped() + 1); else textpos -= tickerstep * (timerclient_getSkipped() + 1); + if (textpos < 0) textpos = 0; + if (textpos > cur_len - (re.right - re.left - 2)) textpos = cur_len - (re.right - re.left - 2); + if (cur_len <= (textpos + re.right - re.left - 2)) + { + sens = 1; + tts = time_tts; + } + if (textpos <= 0) + { + sens = 0; + textpos = 0; + tts = time_tts; + } + } + } + if (textpos != oldpos && upd != NULL) *upd = 1; + } +} + +void Text::setTimeDisplayMode(int remaining) +{ + if (fixedTimerStyle) + return; + + elapsed = !remaining; + Layout *l = getGuiObject()->guiobject_getParentLayout(); + if (l && l->getId()) + WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"%s/timer_elapsed", l->getId()), elapsed); + else + WASABI_API_CONFIG->setIntPrivate(L"timer_elapsed", elapsed); + invalidateTextBuffer(); +} + +int Text::onLeftButtonDown(int x, int y) +{ + if (!TEXT_PARENT::onLeftButtonDown(x, y)) + { + grab = 0; + return 0; + } + if (nograb || wrapped) return 0; + if (display == DISPLAY_TIME) + { + elapsed = !elapsed; +#ifdef WIN32 + // HACK! lone needs to make that a cfg attrib, but no time, a build needs to go out :D +#define WINAMP_OPTIONS_ELAPSED 40037 +#define WINAMP_OPTIONS_REMAINING 40038 + if (!fixedTimerStyle) SendMessageW(WASABI_API_WND->main_getRootWnd()->gethWnd(), WM_COMMAND, elapsed ? WINAMP_OPTIONS_ELAPSED : WINAMP_OPTIONS_REMAINING, 0); +#endif +#ifdef WASABI_COMPILE_WNDMGR +#ifdef WASABI_COMPILE_CONFIG + if (getGuiObject()) + { + Layout *l = getGuiObject()->guiobject_getParentLayout(); + if (l && l->getId()) WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"%s/timer_elapsed%s", l->getId(), (fixedTimerStyle ? StringPrintfW(L".%s", this->getId()) : L"")), elapsed); + else WASABI_API_CONFIG->setIntPrivate(L"timer_elapsed", elapsed); + } + else WASABI_API_CONFIG->setIntPrivate(L"timer_elapsed", elapsed); +#endif +#endif + timerCallback(TICKER_TIMER_POS); + return 1; + } + + grab = 1; + grab_x = x + textpos; + // onMouseMove(x,y); + return 1; +} + +int Text::onMouseMove(int x, int y) +{ + + if (!TEXT_PARENT::onMouseMove(x, y)) + { + grab = 0; + } + + //POINT pos = {x, y}; + //clientToScreen(&pos); + + if (!grab) return 1; + + textpos = grab_x - x; + + RECT re; + getClientRect(&re); + textpos = min(textpos, cur_len - ((re.right - re.left) - 2) - 1); + if (textpos < 0) textpos = 0; + invalidateBuffer(); + return 1; +} + +int Text::onLeftButtonUp(int x, int y) +{ + if (!TEXT_PARENT::onLeftButtonUp(x, y)) + { + grab = 0; + return 0; + } + if (nograb) return 0; + grab = 0; + tts = time_tts; + return 1; +} + + +#ifdef WASABI_COMPILE_MEDIACORE +int Text::corecb_onStatusMsg(const wchar_t *text) +{ + if (display == DISPLAY_SONGNAME) + setAlternateName(text); + return 0; +} + +int Text::corecb_onBitrateChange(int kbps) +{ + if (display == DISPLAY_SONGBITRATE) + { + if (kbps) + { + wchar_t bitrate[64] = {0}; + WCSNPRINTF(bitrate, 64, L"%d", kbps); + setName(bitrate); + } + else + setName(L""); + + } + return 0; +} + +int Text::corecb_onSampleRateChange(int hz) +{ + if (display == DISPLAY_SONGSAMPLERATE) + { + if (hz) + { + wchar_t sampleRate[64] = {0}; + WCSNPRINTF(sampleRate, 64, L"%d", hz); + setName(sampleRate); + } + else + setName(L""); + + } + return 0; +} + +int Text::corecb_onInfoChange(const wchar_t *text) +{ + switch (display) + { + case DISPLAY_SONGINFO: + case DISPLAY_SONGINFO_TRANSLATED: + setName(text); + break; + case DISPLAY_TIME: + timerCallback(TICKER_TIMER_POS); + break; + } + return 0; +} + +int Text::corecb_onStopped() +{ + switch (display) + { + case DISPLAY_SONGINFO: + case DISPLAY_SONGINFO_TRANSLATED: + case DISPLAY_SONGBITRATE: + case DISPLAY_SONGSAMPLERATE: + setName(L""); + break; + case DISPLAY_TIME: + timerCallback(TICKER_TIMER_POS); + break; + } + return 0; +} + +int Text::corecb_onStarted() +{ + /* if (display == DISPLAY_TIME) { + timerCallback(TICKER_TIMER_POS); + }*/ + return 0; +} + +int Text::corecb_onSeeked(int newpos) +{ + if (display == DISPLAY_TIME) + timerCallback(TICKER_TIMER_POS); + return 0; +} + +#endif //mediacore + +void Text::invalidateTextBuffer() +{ + bufferinvalid = 1; + invalidateBuffer(); +} + +int Text::setTextSize(int newsize, int alt) +{ + if (alt < 0 || alt > 1) alt = 0; + if (newsize < 1 || newsize > 72) return 0; + size[alt] = newsize; + invalidateTextBuffer(); + return 1; +} + +void Text::setTickering(int enable) +{ + ticker = enable; + if (!enable) textpos = 0; + invalidateTextBuffer(); +} + +void Text::setDisplay(int disp) +{ + if (disp == display) return ; + if (textfeed) + { + viewer_delViewItem(textfeed->getDependencyPtr()); + feed_id = L""; + SvcEnum::release(textfeed); + textfeed = NULL; + } + display = disp; + if (isPostOnInit()) initDisplay(); + if (disp == DISPLAY_SERVICE && isPostOnInit()) + registerToTextFeedService(); + invalidateTextBuffer(); +} + +void Text::setAlternateName(const wchar_t *s) +{ + if (((!s || !*s) && alternatename.isempty()) || WCSCASEEQLSAFE(alternatename, s)) return ; + killTimer(TICKER_RESET_ALTNAME); + alternatename = parseText(s); + onTextChanged(getPrintedText()); + resetTicker(); + invalidate(); + setTimer(TICKER_RESET_ALTNAME, 1000); +} + +void Text::setText(const wchar_t *t) +{ + deftext = parseText(t); + invalidate(); + onTextChanged(getPrintedText()); +} + +const wchar_t *Text::parseText(const wchar_t *s) +{ + static wchar_t t[4096]; + if (!s) return NULL; + WCSCPYN(t, s, 4096); + wchar_t *p = t; + while (p && *p && *(p + 1)) + { + if (*p == '\\' && *(p + 1) == 'n') + { + // TODO check + wcscpy(p, p + 1); + t[wcslen(t)] = 0; + *p = '\n'; + } + p++; + } + return t; +} + +void Text::onTextChanged(const wchar_t *txt) +{ + if (WCSCASEEQLSAFE(lasttxt, txt)) return ; + lasttxt = txt; + invalidate(); + int w = getTextWidth(); + if (w != lastautowidth) + notifyParent(ChildNotify::AUTOWHCHANGED); + lastautowidth = w; + script_vcpu_onTextChanged(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(lasttxt)); + invalidateTextBuffer(); +} + +const wchar_t *Text::getPrintedText() +{ + const wchar_t *name = getAlternateName(); + if (!name || !*name) + name = deftext.getValue(); + if (!name || !*name) + name = getName(); + if (name == NULL) + return L""; + +#if defined(WASABI_STATICVARMGR) || !defined(WASABINOMAINAPI) + + if (wantTranslation()) + { + StringW *s = PublicVarManager::translate(name, getGuiObject()); + if (s != NULL) + { + printedtxt.swap(s); + delete s; + return printedtxt.getValueSafe(); + } + } + + return name; +#else + return name; + +#endif +} + +void Text::onSetName() +{ + invalidateTextBuffer(); + onTextChanged(getPrintedText()); +} + +const wchar_t *Text::getAlternateName(void) +{ + if (alternatename.isempty()) return NULL; + return alternatename; +} + +void Text::setTimerOffStyle(int o) +{ + if (timeroffstyle == o) return ; + timeroffstyle = o; + invalidateTextBuffer(); +} + +void Text::setTimerHours(int o) +{ + if (timerhours == o) return ; + timerhours = o; + invalidateTextBuffer(); +} + +void Text::setTimerHoursRollover(int o) +{ + if (timerhoursRollover == o) return ; + timerhoursRollover = o; + invalidateTextBuffer(); +} + +void Text::setTimeTTS(int tts) +{ + time_tts = tts; + invalidateTextBuffer(); +} + +void Text::resetTicker() +{ + sens = 0; + textpos = 0; + tts = time_tts; + invalidateBuffer(); +} + +void Text::setTimeColonWidth(int w) +{ + timecolonw = w; + invalidateTextBuffer(); +} + +int Text::getTimeColonWidth(int def) +{ + return timecolonw == -1 ? def : timecolonw; +} + +void Text::textOut(Canvas *canvas, int x, int y, const wchar_t *txt, wchar_t widthchar, const Wasabi::FontInfo *fontInfo) +{ + if (widthchar == 0) + { + canvas->textOut(x, y, txt, fontInfo); + return ; + } + wchar_t wc[2] = { widthchar, 0 }; + int cwidth = canvas->getTextWidth(wc, fontInfo); + int slen = wcslen(txt); + + for (int i = 0; i < slen; i++) + { + wc[0] = txt[i]; + int dw = cwidth - canvas->getTextWidth(wc, fontInfo); // get difference + canvas->textOut(x + dw / 2, y, wc, fontInfo); + x += cwidth; + } +} + +void Text::addCBSource(const wchar_t *cbsource) +{ + StringW *s = new StringW(cbsource); + mycbid.addItem(s); +} + +int Text::getTextWidth() +{ + const wchar_t *txt = getAlternateName() ? getAlternateName() : isInited() ? getName() : NULL; + if (!txt) txt = deftext.getValue(); + if (!txt) return 0; +#ifdef WA3COMPATIBILITY + /* + String *translate = PublicVarManager::translate(thaname, getGuiObject()); + if (translate) + thanme = translate->getValueSafe(); + */ +#endif + //txt = _(txt); + int alt = 0; +#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 *item = WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid); + if (item != NULL) + { + alt = item->getDataAsInt(L"Alternate Fonts", 0); + if (alt < 0 || alt > 1) alt = 0; + } + if (alt) + { + if (item && item->getDataAsInt(L"No 7-bit TTF AltFonts", 1)) + { + const wchar_t *p = (const wchar_t *)txt; + while (p && *p) + { + if (*p > 127) break; + p++; + } + if (p && !*p) alt = 0; + } + } +#endif + TextInfoCanvas canvas(this); + Wasabi::FontInfo fontInfo; + GetFontInfo(&fontInfo, alt); + int w = canvas.getTextWidth(txt, &fontInfo) + 4; +// delete txt; + return w; +} + +void Text::registerToTextFeedService() +{ + if (!registered_syscb++) WASABI_API_SYSCB->syscb_registerCallback(static_cast<SvcCallbackI*>(this)); + + if (textfeed) + { + viewer_delViewItem(textfeed->getDependencyPtr()); + feed_id = L""; + SvcEnum::release(textfeed); + textfeed = NULL; + } + + if (!displaystr.isempty()) textfeed = TextFeedEnum(displaystr).getFirst(); + + if (textfeed != NULL) + { + feed_id = displaystr; + viewer_addViewItem(textfeed->getDependencyPtr()); + } +} + +void Text::svccb_onSvcRegister(FOURCC type, waServiceFactory *svc) +{ + if (type == WaSvc::TEXTFEED) + { + //CUTif (!displaystr.isempty()) { + //CUTDebugString("RERERERER %s", displaystr.v()); + //CUT} + registerToTextFeedService(); + } +} + +int Text::viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen) +{ + if (textfeed && item == textfeed->getDependencyPtr()) + { + if (event == svc_textFeed::Event_TEXTCHANGE && WCSCASEEQLSAFE((const wchar_t *)param, feed_id)) + { + //CUTDebugString("got feed '%s'", (const char *)ptr); + setName((const wchar_t *)ptr); + return 1; + } + } + + else if (classguid && *classguid == *Container::depend_getClassGuid()) + { + onSetName(); + return 1; + } + return 0; +} + +int Text::triggerEvent(int event, intptr_t p1, intptr_t p2) +{ + int r = TEXT_PARENT::triggerEvent(event, p1, p2); + if (event == TRIGGER_ONRESIZE) + notifyParent(ChildNotify::AUTOWHCHANGED); + if (event == TRIGGER_INVALIDATE) + invalidateTextBuffer(); + return r; +} + +COLORREF Text::getShadowColor(int alt) +{ + if (alt < 0 || alt > 1) alt = 0; + if (shadowcolor_mode[alt] == COLORMODE_SKINCOLOR) return sshadowcolor[alt]; + return shadowcolor[alt].getColor(); +} + +TextScriptController _textController; +TextScriptController *textController = &_textController; + +// -- Functions table ------------------------------------- +function_descriptor_struct TextScriptController::exportedFunction[] = +{ + {L"setText", 1, (void*)Text::script_vcpu_setText }, + {L"setAlternateText", 1, (void*)Text::script_vcpu_setAlternateText }, + {L"getText", 0, (void*)Text::script_vcpu_getText }, + {L"getTextWidth", 0, (void*)Text::script_vcpu_getTextWidth }, + {L"onTextChanged", 1, (void*)Text::script_vcpu_onTextChanged }, +}; +// -------------------------------------------------------- + +const wchar_t *TextScriptController::getClassName() +{ + return L"Text"; +} + +const wchar_t *TextScriptController::getAncestorClassName() +{ + return L"GuiObject"; +} + +ScriptObject *TextScriptController::instantiate() +{ + Text *t = new Text; + ASSERT(t != NULL); + return t->getScriptObject(); +} + +void TextScriptController::destroy(ScriptObject *o) +{ + Text *t = static_cast<Text *>(o->vcpu_getInterface(textGuid)); + ASSERT(t != NULL); + delete t; +} + +void *TextScriptController::encapsulate(ScriptObject *o) +{ + return NULL; // no encapsulation for text yet +} + +void TextScriptController::deencapsulate(void *o) +{} + +int TextScriptController::getNumFunctions() +{ + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *TextScriptController::getExportedFunctions() +{ + return exportedFunction; +} + +GUID TextScriptController::getClassGuid() +{ + return textGuid; +} + +const wchar_t *Text::vcpu_getClassName() +{ + return L"Text"; +} + +scriptVar Text::script_vcpu_setText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t) +{ + SCRIPT_FUNCTION_INIT + ASSERT(t.type == SCRIPT_STRING); + Text *tx = static_cast<Text *>(o->vcpu_getInterface(textGuid)); + if (tx) tx->setText(GET_SCRIPT_STRING(t)); + RETURN_SCRIPT_VOID; +} + +scriptVar Text::script_vcpu_setAlternateText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t) +{ + SCRIPT_FUNCTION_INIT + ASSERT(t.type == SCRIPT_STRING); + Text *tx = static_cast<Text *>(o->vcpu_getInterface(textGuid)); + if (tx) tx->setAlternateName(GET_SCRIPT_STRING(t)); + RETURN_SCRIPT_VOID; +} + +scriptVar Text::script_vcpu_getText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Text *t = static_cast<Text *>(o->vcpu_getInterface(textGuid)); + if (t) + { + const wchar_t *from = t->getPrintedText(); + // BU rewrote in response to talkback for 489 + if (from == NULL || *from == '\0') from = t->getLastText(); + if (from == NULL || *from == '\0') from = L""; + WCSCPYN(s_txt, from, 4096); + return MAKE_SCRIPT_STRING(s_txt); + } + return MAKE_SCRIPT_STRING(L""); +} + +scriptVar Text::script_vcpu_getTextWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + Text *t = static_cast<Text *>(o->vcpu_getInterface(textGuid)); + if (t) return MAKE_SCRIPT_INT(t->getTextWidth()); + return MAKE_SCRIPT_INT(0); +} + +scriptVar Text::script_vcpu_onTextChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newtxt) +{ + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS1(o, textController, newtxt); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, newtxt); +} + +wchar_t Text::s_txt[WA_MAX_PATH] = {0};
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/text.h b/Src/Wasabi/api/skin/widgets/text.h new file mode 100644 index 00000000..1435e8fa --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/text.h @@ -0,0 +1,240 @@ +//PORTABLE +#ifndef _TEXT_H +#define _TEXT_H + +#include <api/script/script.h> +#include <api/script/objects/guiobj.h> +#include <api/wnd/wndclass/guiobjwnd.h> +#include <bfc/string/StringW.h> +#include <bfc/depend.h> +#include "textbase.h" +#include <api/syscb/callbacks/svccbi.h> +#include <api/syscb/callbacks/skincb.h> + +#define TEXT_PARENT TextBase + +class svc_textFeed; + +class TextScriptController : public GuiObjectScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + 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); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern TextScriptController *textController; + +#include <api/wnd/wndclass/clickwnd.h> + +#ifdef WASABI_COMPILE_MEDIACORE +#include <api/syscb/callbacks/corecbi.h> +class Text : public TEXT_PARENT, public CoreCallbackI, public DependentViewerI, public SvcCallbackI{ +#else +class Text : public TEXT_PARENT, public DependentViewerI, public SvcCallbackI { +#endif +public: + Text(); + virtual ~Text(); + + virtual int onInit(); + virtual int onBufferPaint(BltCanvas *canvas, int w, int h); + + virtual int onLeftButtonDown(int x, int y); + virtual int onMouseMove(int x, int y); + virtual int onLeftButtonUp(int x, int y); + + virtual int getPreferences(int what); + + virtual int setXuiParam(int xuihandle, int attribid, const wchar_t *name, const wchar_t *strval); + virtual const wchar_t *vcpu_getClassName(); + virtual ScriptObjectController *vcpu_getController() { return textController; } + + virtual int getTextWidth(); + virtual int onDeferredCallback(intptr_t p1, intptr_t p2); + + + virtual void getBufferPaintSize(int *w, int *h); + virtual void getBufferPaintSource(RECT *r); + virtual void onNewBuffer(int w, int h) { BufferPaintWnd::onNewBuffer(w, h); invalidateTextBuffer(); } + + int setTextSize(int newsize, int alt=0); + void setTickering(int enable); + void setDisplay(int disp); + + + + void setShadowColor(ARGB32 c, int alt=0); + void setShadowX(int x, int alt=0); // relative offsets + void setShadowY(int y, int alt=0); + void setTimeTTS(int tts); + void resetTicker(); + void setTimeColonWidth(int w); + int getTimeColonWidth(int def); + void setTimerOffStyle(int o); + void setTimerHours(int o); + void setTimerHoursRollover(int o); + const wchar_t *getLastText() { return lasttxt; } + + void setAlternateName(const wchar_t *s); + const wchar_t *getAlternateName(void); + void setText(const wchar_t *t); + + void addCBSource(const wchar_t *cbsource); + + virtual void onTextChanged(const wchar_t *txt); + virtual void onSetName(); + virtual void advanceTicker(int *upd); + + virtual void setTimeDisplayMode(int remaining); // will only do so if text is displaying time in the first place + + ARGB32 getShadowColor(int alt=0); + +#ifdef WASABI_COMPILE_MEDIACORE + // core callbacks + virtual int corecb_onStatusMsg(const wchar_t *text); + virtual int corecb_onInfoChange(const wchar_t *text); + virtual int corecb_onStarted(); + virtual int corecb_onStopped(); + virtual int corecb_onSeeked(int newpos); + virtual int corecb_onBitrateChange(int kbps); + virtual int corecb_onSampleRateChange(int hz); +#endif + + static void textOut(Canvas *canvas, int x, int y, const wchar_t *txt, wchar_t widthchar, const Wasabi::FontInfo *fontInfo); + + virtual int viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen); + virtual int triggerEvent(int event, intptr_t p1, intptr_t p2); + + const wchar_t *getPrintedText(); + + virtual void svccb_onSvcRegister(FOURCC type, waServiceFactory *svc); + + + void initDisplay(); + void invalidateTextBuffer(); + + enum { + TEXT_SETDISPLAY=0, + TEXT_SETTICKER, + TEXT_SETTEXT, + TEXT_SETSHADOWCOLOR, + TEXT_SETALTSHADOWCOLOR, + TEXT_SETSHADOWX, + TEXT_SETSHADOWY, + TEXT_SETALTSHADOWX, + TEXT_SETALTSHADOWY, + TEXT_SETTIMEROFFSTYLE, + TEXT_SETTIMERHOURS, + TEXT_SETTIMECOLONWIDTH, + TEXT_SETNOGRAB, + TEXT_SETSHOWLEN, + TEXT_SETFORCEFIXED, + TEXT_SETFORCEUPCASE, + TEXT_SETFORCELOCASE, + TEXT_SETCBSOURCE, + TEXT_SETWRAPPED, + TEXT_SETVALIGN, + TEXT_SETALTVALIGN, + TEXT_SETDBLCLKACTION, + TEXT_SETRCLKACTION, + TEXT_SETOFFSETX, + TEXT_SETOFFSETY, + TEXT_SETTICKERSTEP, + TEXT_SETTIMERHOURSROLLOVER, + TEXT_NUMPARAMS, + }; + + +protected: + /*static */void CreateXMLParameters(int master_handle); + virtual void timerCallback(int id); + +private: + static XMLParamPair params[]; + + const wchar_t *parseText(const wchar_t *s); + void registerToTextFeedService(); + int size[2]; + int textpos,tts,sens; + int time_tts; + int grab_x; + int cur_len; + int ticker; + int display; + int elapsed; + int fixedTimerStyle; + + int nograb; + int showlen; + int forcefixed; + int timeroffstyle; + + StringW displaystr; + StringW alternatename; + StringW lastText; + + FilteredColor shadowcolor[2]; + + SkinColor sshadowcolor[2]; + int shadowcolor_mode[2]; + int shadowx[2], shadowy[2]; + int timecolonw; + StringW deftext; + + + + PtrList<StringW> mycbid; + StringW cbsource; + int forceupcase, forcelocase; + StringW lasttxt; + + + int lastautowidth; + + svc_textFeed *textfeed; + StringW feed_id; + int registered_syscb; + + int wrapped; + int valign[2]; + int xuihandle; + int offsetx, offsety; + + StringW printedtxt; + int tickerstep; + int skipn; + int skip; + int skipcfgcount; + + int timerhours; + int timerhoursRollover; + int bufferinvalid; + int cachedsizew; + +public: + static scriptVar script_vcpu_setText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t); + static scriptVar script_vcpu_setAlternateText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t); + static scriptVar script_vcpu_getText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_getTextWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_vcpu_onTextChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar text); + static wchar_t s_txt[WA_MAX_PATH]; +}; + +extern const wchar_t textXuiObjectStr[]; +extern char textXuiSvcName[]; +class TextXuiSvc : public XuiObjectSvc<Text, textXuiObjectStr, textXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/textbase.cpp b/Src/Wasabi/api/skin/widgets/textbase.cpp new file mode 100644 index 00000000..5fb32e7a --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/textbase.cpp @@ -0,0 +1,345 @@ +#include <precomp.h> +#include <api.h> +#include "textbase.h" +#include <api/skin/skinparse.h> +#include <api/skin/skinelem.h> +#include <api/service/svcs/svc_action.h> +#include <api/script/vcpu.h> + +#define COLORMODE_RGB 0 +#define COLORMODE_SKINCOLOR 1 + +XMLParamPair TextBase::params[] = +{ + {TEXTBASE_RCLICKPARAM, L"RCLICKPARAM"}, + {TEXTBASE_DBLCLICKPARAM, L"DBLCLICKPARAM"}, + {TEXTBASE_SETALIGN, L"ALIGN"}, + {TEXTBASE_SETALTANTIALIAS, L"ALTANTIALIAS"}, + {TEXTBASE_SETALTBOLD, L"ALTBOLD"}, + {TEXTBASE_SETALTCOLOR, L"ALTCOLOR"}, + {TEXTBASE_SETALTFONT, L"ALTFONT"}, + {TEXTBASE_SETALTFONTSIZE, L"ALTFONTSIZE"}, + {TEXTBASE_SETALTITALIC, L"ALTITALIC"}, + {TEXTBASE_SETANTIALIAS, L"ANTIALIAS"}, + {TEXTBASE_SETBOLD, L"BOLD"}, + {TEXTBASE_SETCOLOR, L"COLOR"}, + {TEXTBASE_SETDBLCLKACTION, L"DBLCLICKACTION"}, + {TEXTBASE_SETFONT, L"FONT"}, + {TEXTBASE_SETFONTSIZE, L"FONTSIZE"}, + {TEXTBASE_SETITALIC, L"ITALIC"}, + {TEXTBASE_SETLPADDING, L"LEFTPADDING"}, + {TEXTBASE_SETRCLKACTION, L"RIGHTCLICKACTION"}, + {TEXTBASE_SETRPADDING, L"RIGHTPADDING"}, +}; + +TextBase::TextBase() +{ + color[0].setColorGroup(L"Text"); + color[1].setColorGroup(L"Text"); + color[0].setColor(RGB(255, 255, 255)); + color[1].setColor(RGB(255, 255, 255)); + + color_mode[0] = COLORMODE_RGB; + color_mode[1] = COLORMODE_RGB; + + fontsize[0] = fontsize[1] = 14; + + font[0] = wasabi_default_fontnameW; + font[1] = wasabi_default_fontnameW; + + bold[0] = 0; + bold[1] = 0; + + italic[0] = 0; + italic[1] = 0; + + antialias[0] = 1; + antialias[1] = 1; + + align = ALIGN_LEFT; + + lpadding = rpadding = 0; + + grab = 0; + + /* register XML parameters */ + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); +} + +void TextBase::CreateXMLParameters(int master_handle) +{ + //TEXTBASE_PARENT::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); +} + +TextBase::~TextBase() +{ + WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SkinCallbackI*>(this)); +} + +int TextBase::onInit() +{ + TEXTBASE_PARENT::onInit(); + WASABI_API_SYSCB->syscb_registerCallback(static_cast<SkinCallbackI*>(this)); + return 1; +} + +int TextBase::skincb_onColorThemeChanged(const wchar_t *newcolortheme) +{ + invalidateTextBuffer(); + return 0; +} + + +ARGB32 TextBase::GetColor(int alt) +{ + if (alt < 0 || alt > 1) alt = 0; + if (color_mode[alt] == COLORMODE_SKINCOLOR) + return scolor[alt]; + return color[alt].getColor(); +} + +void TextBase::SetTextColor(ARGB32 c, int alt) +{ + if (alt < 0 || alt > 1) alt = 0; + color_mode[alt] = COLORMODE_RGB; + color[alt].setColor(c); + invalidateTextBuffer(); + if (alt == 0) SetTextColor(c, 1); +} + +void TextBase::SetFontSize(const wchar_t *strvalue, int alt) +{ + if (alt < 0 || alt > 1) alt = 0; + if (!strvalue || !*strvalue) return ; + if (*strvalue == '+') + fontsize[alt] += WTOI(strvalue + 1); + else if (*strvalue == '-') + fontsize[alt] -= WTOI(strvalue + 1); + else if (*strvalue == '*') + fontsize[alt] *= WTOI(strvalue + 1); + else if (*strvalue == '/') + fontsize[alt] /= WTOI(strvalue + 1); + else + fontsize[alt] = WTOI(strvalue); + invalidateTextBuffer(); + if (alt == 0) SetFontSize(strvalue, 1); +} + +void TextBase::GetFontInfo(Wasabi::FontInfo *_font, int alt) +{ + _font->opaque=false; + _font->color = GetColor(alt); + _font->pointSize = fontsize[alt]; + _font->face = font[alt]; + _font->bold = bold[alt]; + _font->italic = !!italic[alt]; + _font->antialias = antialias[alt]; + _font->alignFlags = align; +} + +void TextBase::SetFont(const wchar_t *name, int alt) +{ + if (alt < 0 || alt > 1) alt = 0; + font[alt] = name; + invalidateTextBuffer(); + if (alt == 0) SetFont(name, 1); +} + +void TextBase::SetAntialias(int a, int alt) +{ + antialias[alt] = a; + if (alt==0) + antialias[1] = antialias[0]; + invalidateTextBuffer(); +} + +void TextBase::SetFontAlign(int al) +{ + align = al; + invalidateTextBuffer(); + +} + +int TextBase::setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval) +{ + if (xuihandle != _xuihandle) return TEXTBASE_PARENT::setXuiParam(_xuihandle, attrid, name, strval); + switch (attrid) + { + case TEXTBASE_SETCOLOR: + if (WASABI_API_PALETTE->getColorElementRef(strval)) + { + color_mode[0] = COLORMODE_SKINCOLOR; + scolor[0] = strval; + color_mode[1] = COLORMODE_SKINCOLOR; + scolor[1] = strval; + } + else + SetTextColor(SkinParser::parseColor(strval), 0); + break; + + case TEXTBASE_SETALTCOLOR: + if (WASABI_API_PALETTE->getColorElementRef(strval)) + { + color_mode[1] = COLORMODE_SKINCOLOR; + scolor[1] = strval; + } + else + SetTextColor(SkinParser::parseColor(strval), 1); + break; + + case TEXTBASE_SETFONTSIZE: + SetFontSize(strval); + break; + + case TEXTBASE_SETFONT: + SetFont(strval); + break; + + case TEXTBASE_SETALTFONT: + SetFont(strval, 1); + break; + + case TEXTBASE_SETALTFONTSIZE: + SetFontSize(strval, 1); + break; + + case TEXTBASE_SETBOLD: + bold[0] = WTOI(strval); + bold[1] = bold[0]; + break; + + case TEXTBASE_SETALTBOLD: + bold[1] = WTOI(strval); + break; + + case TEXTBASE_SETITALIC: + italic[0] = WTOI(strval); + italic[1] = italic[0]; + break; + + case TEXTBASE_SETALTITALIC: + italic[1] = WTOI(strval); + break; + + case TEXTBASE_SETANTIALIAS: + SetAntialias(WTOI(strval)); + invalidateTextBuffer(); + break; + + case TEXTBASE_SETALTANTIALIAS: + SetAntialias(WTOI(strval), 1); + invalidateTextBuffer(); + break; + + case TEXTBASE_SETDBLCLKACTION: + dblClickAction = strval; + break; + + case TEXTBASE_DBLCLICKPARAM: + setDblClickParam(strval); + break; + + case TEXTBASE_RCLICKPARAM: + setRClickParam(strval); + break; + + case TEXTBASE_SETRCLKACTION: + rClickAction = strval; + break; + + case TEXTBASE_SETALIGN: + SetFontAlign(SkinParser::getAlign(strval)); + break; + + case TEXTBASE_SETLPADDING: + lpadding = WTOI(strval); + break; + case TEXTBASE_SETRPADDING: + rpadding = WTOI(strval); + break; + + + default: + return 0; + } + return 1; +} + +void TextBase::setDblClickParam(const wchar_t *p) +{ + dblclickparam=p; +} + +const wchar_t *TextBase::getDblClickParam() +{ + return dblclickparam; +} + +void TextBase::setRClickParam(const wchar_t *p) +{ + rclickparam=p; +} + +const wchar_t *TextBase::getRClickParam() +{ + return rclickparam; +} + +int TextBase::onLeftButtonDblClk(int x, int y) +{ + TEXTBASE_PARENT::onLeftButtonDblClk(x, y); + int r = 1; + grab = 0; + if (!dblClickAction.isempty() && !VCPU::getComplete()) + { +#ifdef WASABI_COMPILE_WNDMGR + const wchar_t *toCheck = L"SWITCH;"; + if (!_wcsnicmp(dblClickAction, toCheck, 7)) + { + onLeftButtonUp(x, y); + getGuiObject()->guiobject_getParentGroup()->getParentContainer()->switchToLayout(dblClickAction.getValue() + 7); + } + else + { +#endif + svc_action *act = ActionEnum(dblClickAction).getNext(); + if (act) + { + int _x = x; + int _y = y; + clientToScreen(&_x, &_y); + act->onAction(dblClickAction, getDblClickParam(), _x, _y, NULL, 0, this); + SvcEnum::release(act); + } +#ifdef WASABI_COMPILE_WNDMGR + + } +#endif + + } + return r; +} + + +int TextBase::onRightButtonDown(int x, int y) +{ + TEXTBASE_PARENT::onRightButtonDown(x, y); + if (!rClickAction.isempty()) + { + svc_action *act = ActionEnum(rClickAction).getNext(); + if (act) + { + int _x = x; + int _y = y; + clientToScreen(&_x, &_y); + act->onAction(rClickAction, getRClickParam(), _x, _y, NULL, 0, this); + SvcEnum::release(act); + } + } + return 1; +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/textbase.h b/Src/Wasabi/api/skin/widgets/textbase.h new file mode 100644 index 00000000..e143cf37 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/textbase.h @@ -0,0 +1,95 @@ +#ifndef NULLSOFT_WASABI_TEXTBASE_H +#define NULLSOFT_WASABI_TEXTBASE_H + +#include <api/wnd/wndclass/bufferpaintwnd.h> +#include <tataki/color/filteredcolor.h> +#include <tataki/color/skinclr.h> +#include <bfc/string/StringW.h> + +#define TEXTBASE_PARENT BufferPaintWnd + +class TextBase : public TEXTBASE_PARENT, public SkinCallbackI +{ +public: + TextBase(); + virtual ~TextBase(); + + ARGB32 GetColor(int alt=0); + void GetFontInfo(Wasabi::FontInfo *_font, int alt=0); + + void SetTextColor(ARGB32 c, int alt=0); + void SetFontSize(const wchar_t *strvalue, int alt=0); + void SetFont(const wchar_t *name, int alt=0); + void SetAntialias(int a, int alt=0); + void SetFontAlign(int al); + virtual void setDblClickParam(const wchar_t *p); + virtual const wchar_t *getDblClickParam(); + virtual void setRClickParam(const wchar_t *p); + virtual const wchar_t *getRClickParam(); +protected: + /* Virtual methods to override */ + virtual void invalidateTextBuffer()=0; + + +/*static */void CreateXMLParameters(int master_handle); +private: + StringW dblClickAction; + StringW rClickAction; + + /* Font Info */ + FilteredColor color[2]; + SkinColor scolor[2]; + int color_mode[2]; + StringW font[2]; + int bold[2]; + int italic[2]; + int antialias[2]; + int align; + +protected: + int fontsize[2]; + int lpadding, rpadding; + int grab; + +private: + /* XML Parameters */ + enum + { + TEXTBASE_SETCOLOR, + TEXTBASE_SETALTCOLOR, + TEXTBASE_SETFONTSIZE, + TEXTBASE_SETFONT, + TEXTBASE_SETALTFONT, + TEXTBASE_SETALTFONTSIZE, + TEXTBASE_SETBOLD, + TEXTBASE_SETITALIC, + TEXTBASE_SETALTBOLD, + TEXTBASE_SETALTITALIC, + TEXTBASE_SETANTIALIAS, + TEXTBASE_SETALTANTIALIAS, + TEXTBASE_SETDBLCLKACTION, + TEXTBASE_SETRCLKACTION, + TEXTBASE_SETALIGN, + TEXTBASE_SETLPADDING, + TEXTBASE_SETRPADDING, + TEXTBASE_RCLICKPARAM, + TEXTBASE_DBLCLICKPARAM, + + + }; + static XMLParamPair params[]; + int xuihandle; + StringW dblclickparam; + StringW rclickparam; +protected: + /* Methods that TextBase overrides */ + int setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval); + int onInit(); + int skincb_onColorThemeChanged(const wchar_t *newcolortheme); + int onLeftButtonDblClk(int x, int y); + int onRightButtonDown(int x, int y); + virtual int wantAutoContextMenu() { return rClickAction.isempty(); } + +}; + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/tgbutton.cpp b/Src/Wasabi/api/skin/widgets/tgbutton.cpp new file mode 100644 index 00000000..1e19d021 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/tgbutton.cpp @@ -0,0 +1,313 @@ +#include <precomp.h> +#include "tgbutton.h" +#include <api/script/scriptmgr.h> +#include <bfc/parse/paramparser.h> + +const wchar_t toggleButtonXuiObjectStr[] = L"ToggleButton"; // This is the xml tag +char toggleButtonXuiSvcName[] = "ToggleButton xui object"; // this is the name of the xuiservice + +XMLParamPair ToggleButton::params[] = { + {TOGGLEBUTTON_AUTOTOGGLE, L"AUTOTOGGLE"}, +#ifdef WASABI_COMPILE_CONFIG + {TOGGLEBUTTON_CFGVAL, L"CFGVAL"}, +#endif + }; + +ToggleButton::ToggleButton() { + param=0; +getScriptObject()->vcpu_setInterface(toggleButtonGuid, (void *)static_cast<ToggleButton *>(this)); + getScriptObject()->vcpu_setClassName(L"ToggleButton"); + getScriptObject()->vcpu_setController(tgbuttonController); + autotoggle = 1; +#ifdef WASABI_COMPILE_CONFIG + cfgVal = 1; +#endif + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); + +} + +void ToggleButton::CreateXMLParameters(int master_handle) +{ + //TOGGLEBUTTON_PARENT::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); +} + +ToggleButton::~ToggleButton() { +} + +void ToggleButton::onLeftPush(int x, int y) { + autoToggle(); + TOGGLEBUTTON_PARENT::onLeftPush(x, y); + onToggle(getActivatedButton()); +} + +void ToggleButton::autoToggle() { + if (autotoggle) { + if (!getActivatedButton()) + setActivatedButton(1); + else + setActivatedButton(0); + } +} + +void ToggleButton::onToggle(int i) { + scriptVar _y = SOM::makeVar(SCRIPT_INT); + SOM::assign(&_y, i ? 1 : 0); + script_onToggle(SCRIPT_CALL, getScriptObject(), _y); +#ifdef WASABI_COMPILE_CONFIG + getGuiObject()->guiobject_setCfgInt(i ? cfgVal : 0); +#endif +} + +int ToggleButton::setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *name, const wchar_t *value) { + if (xuihandle == _xuihandle) { + switch (xmlattributeid) { + case TOGGLEBUTTON_AUTOTOGGLE: autotoggle = WTOI(value); return 1; +#ifdef WASABI_COMPILE_CONFIG + case TOGGLEBUTTON_CFGVAL: + cfgVal = WTOI(value); return 1; +#endif + } + } + return TOGGLEBUTTON_PARENT::setXuiParam(_xuihandle, xmlattributeid, name, value); +} + +#ifdef WASABI_COMPILE_CONFIG +int ToggleButton::onReloadConfig() { + TOGGLEBUTTON_PARENT::onReloadConfig(); + setActivatedButton(getGuiObject()->guiobject_getCfgInt()); + return 1; +} +#endif + +int ToggleButton::getCurCfgVal() { + return cfgVal; +} + +TgButtonScriptController _tgbuttonController; +TgButtonScriptController *tgbuttonController=&_tgbuttonController; + + +// -- Functions table ------------------------------------- +function_descriptor_struct TgButtonScriptController::exportedFunction[] = { + {L"onToggle", 1, (void*)ToggleButton::script_onToggle }, + {L"getCurCfgVal", 0, (void*)ToggleButton::script_getCurCfgVal}, +}; +// -------------------------------------------------------- + +const wchar_t *TgButtonScriptController::getClassName() { + return L"ToggleButton"; +} + +const wchar_t *TgButtonScriptController::getAncestorClassName() { + return L"Button"; +} + +ScriptObject *TgButtonScriptController::instantiate() { + ToggleButton *tb = new ToggleButton; + ASSERT(tb != NULL); + return tb->getScriptObject(); +} + +void TgButtonScriptController::destroy(ScriptObject *o) { + ToggleButton *tb = static_cast<ToggleButton *>(o->vcpu_getInterface(toggleButtonGuid)); + ASSERT(tb != NULL); + delete tb; +} + +void *TgButtonScriptController::encapsulate(ScriptObject *o) { + return NULL; +} + +void TgButtonScriptController::deencapsulate(void *o) { +} + +int TgButtonScriptController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *TgButtonScriptController::getExportedFunctions() { + return exportedFunction; +} + +GUID TgButtonScriptController::getClassGuid() { + return toggleButtonGuid; +} + +const wchar_t *ToggleButton::vcpu_getClassName() { + return L"ToggleButton"; +} + +scriptVar ToggleButton::script_onToggle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar is) { + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS1(o, tgbuttonController, is); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, is); +} + +scriptVar ToggleButton::script_getCurCfgVal(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT; + ToggleButton *tg = static_cast<ToggleButton*>(o->vcpu_getInterface(toggleButtonGuid)); + return MAKE_SCRIPT_INT(tg->getCurCfgVal()); +} + +//--- + +const wchar_t nStatesTgButtonXuiObjectStr[] = L"NStatesButton"; // This is the xml tag +char nStatesTgButtonXuiSvcName[] = "NStatesButton xui object"; // this is the name of the xuiservice +XMLParamPair NStatesTgButton::params[] = { + {NSTATESTGBUTTON_NSTATES, L"NSTATES"}, + {NSTATESTGBUTTON_ONEVSTATE, L"AUTOELEMENTS"}, +#ifdef WASABI_COMPILE_CONFIG + {NSTATESTGBUTTON_CFGVALS, L"CFGVALS"}, +#endif +}; +NStatesTgButton::NStatesTgButton() { + getScriptObject()->vcpu_setInterface(NStatesTgButtonGuid, (void *)static_cast<NStatesTgButton*>(this)); + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); + onevstate = 0; +} + +void NStatesTgButton::CreateXMLParameters(int master_handle) +{ + //NSTATESTGBUTTON_PARENT::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); +} + +NStatesTgButton::~NStatesTgButton() { +} + +int NStatesTgButton::setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *paramname, const wchar_t *strvalue) { + if (_xuihandle == btn_getXuiHandle()) { + switch (xmlattributeid) { + case BUTTON_IMAGE: image = strvalue; break; + case BUTTON_HOVERIMAGE: hover = strvalue; break; + case BUTTON_DOWNIMAGE: down = strvalue; break; + case BUTTON_ACTIVEIMAGE: active = strvalue; break; + } + } + if (xuihandle == _xuihandle) { + switch (xmlattributeid) { + case NSTATESTGBUTTON_NSTATES: + setNStates(WTOI(strvalue)); + return 1; + case NSTATESTGBUTTON_ONEVSTATE: + setOneVisualState(!WTOI(strvalue)); + return 1; +#ifdef WASABI_COMPILE_CONFIG + case NSTATESTGBUTTON_CFGVALS: + cfgvals = strvalue; + return 1; +#endif + } + } + return NSTATESTGBUTTON_PARENT::setXuiParam(_xuihandle, xmlattributeid, paramname, strvalue); +} + +int NStatesTgButton::onInit() { + setState(0); + return NSTATESTGBUTTON_PARENT::onInit(); +} + +void NStatesTgButton::setOneVisualState(int v) { + if (!!onevstate == !!v) return; + onevstate = v; + if (isPostOnInit()) { + setupBitmaps(); + invalidate(); + } +} + +void NStatesTgButton::setState(int n) { + if (nstates <= 1) return; + state = n; + setupBitmaps(); +#ifdef WASABI_COMPILE_CONFIG + if (!cfgvals.isempty()) { + ParamParser pp(cfgvals); + const wchar_t *p = pp.enumItem(state); + if (p != NULL) + setXmlParam(L"cfgval", p); + } else { + // if the skinner doesn't ask for custom config values, + // simply use the current state number as the cfgval. + setXmlParam(L"cfgval", StringPrintfW(L"%d", state)); + } +#endif +} + +int NStatesTgButton::getActivatedButton() { + if (nstates <= 1) return NSTATESTGBUTTON_PARENT::getActivatedButton(); + return (getState() != 0); +} + +void NStatesTgButton::autoToggle() { + if (nstates <= 1) { + NSTATESTGBUTTON_PARENT::autoToggle(); + return; + } else { + int s = (state+1) % nstates; + setState(s); + } +} + +void NStatesTgButton::setupBitmaps() { + if (nstates <= 1 || onevstate) + setBitmaps(image, down, hover, active); + else + setBitmaps(StringPrintfW(L"%s%d", image.v(), state), + StringPrintfW(L"%s%d", down.v(), state), + StringPrintfW(L"%s%d", hover.v(), state) /*, StringPrintf("%s%d", image.v(), (state+1) % nstates)*/); +} + +void NStatesTgButton::setActivatedButton(int a) { + if (nstates <= 1) { + NSTATESTGBUTTON_PARENT::setActivatedButton(a); + return; + } + +#ifdef WASABI_COMPILE_CONFIG + if (!cfgvals.isempty()) { + ParamParser pp(cfgvals); + wchar_t t[64] = {0}; + wcsncpy(t, StringPrintfW(L"%d", a), 64); + for (int i=0;i<pp.getNumItems();i++) { + const wchar_t *p = pp.enumItem(i); + if (WCSCASEEQLSAFE(p, t)) { + setState(i); + return; + } + } + } else { + if (!a) + setState(0); + else + setState(a); + } +#endif +} + +int NStatesTgButton::getCurCfgVal() { +#ifdef WASABI_COMPILE_CONFIG + if (!cfgvals.isempty()) { + ParamParser pp(cfgvals); + const wchar_t *p = pp.enumItem(state); + if (p) return WTOI(p); + return 0; + } else { + // if the skinner doesn't ask for custom config values, + // simply use the current state number as the cfgval. + return state; + } +#else + return ToggleButton::getCurCfgVal(); +#endif +} diff --git a/Src/Wasabi/api/skin/widgets/tgbutton.h b/Src/Wasabi/api/skin/widgets/tgbutton.h new file mode 100644 index 00000000..704ce010 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/tgbutton.h @@ -0,0 +1,136 @@ +#ifndef _TOGGLEBUTTON_H +#define _TOGGLEBUTTON_H + +#include <api/script/script.h> +#include <api/script/scriptobj.h> +#include <api/skin/widgets/button.h> + +#define TOGGLEBUTTON_PARENT Wasabi::Button + +class TgButtonScriptController : public ButtonScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return buttonController; } + 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); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern TgButtonScriptController *tgbuttonController; + + +class ToggleButton : public TOGGLEBUTTON_PARENT { + +public: + + ToggleButton(); + virtual ~ToggleButton(); + + virtual void onLeftPush(int x, int y); + virtual void onToggle(int i); + + virtual int setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *name, const wchar_t *value); +#ifdef WASABI_COMPILE_CONFIG + virtual int onReloadConfig(); +#endif + virtual void autoToggle(); + + virtual const wchar_t *vcpu_getClassName(); + virtual ScriptObjectController *vcpu_getController() { return tgbuttonController; } + virtual int getCurCfgVal(); + +protected: +/*static */void CreateXMLParameters(int master_handle); + enum { + TOGGLEBUTTON_AUTOTOGGLE=0, +#ifdef WASABI_COMPILE_CONFIG + TOGGLEBUTTON_CFGVAL, +#endif + }; + + +private: + static XMLParamPair params[]; + wchar_t *param; + int autotoggle; +#ifdef WASABI_COMPILE_CONFIG + int cfgVal; +#endif + int xuihandle; + +public: + static scriptVar script_onToggle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar is); + static scriptVar script_getCurCfgVal(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); +}; + + +extern const wchar_t toggleButtonXuiObjectStr[]; +extern char toggleButtonXuiSvcName[]; +class ToggleButtonXuiSvc : public XuiObjectSvc<ToggleButton, toggleButtonXuiObjectStr, toggleButtonXuiSvcName> {}; + + +// {80F97426-9A10-472c-82E7-8309AA4789E7} +static const GUID NStatesTgButtonGuid = +{ 0x80f97426, 0x9a10, 0x472c, { 0x82, 0xe7, 0x83, 0x9, 0xaa, 0x47, 0x89, 0xe7 } }; + +#define NSTATESTGBUTTON_PARENT ToggleButton + +class NStatesTgButton : public NSTATESTGBUTTON_PARENT { + public: + NStatesTgButton(); + virtual ~NStatesTgButton(); + + virtual int setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *paramname, const wchar_t *strvalue); + void setNStates(int n) { nstates = n; } + virtual int onInit(); + + void setState(int n); + virtual int getActivatedButton(); + virtual void autoToggle(); + int getState() { return state; } + virtual void setActivatedButton(int a); + virtual int getCurCfgVal(); + void setOneVisualState(int v); + + protected: +/*static */void CreateXMLParameters(int master_handle); + virtual void setupBitmaps(); + + enum { + NSTATESTGBUTTON_NSTATES=0, +#ifdef WASABI_COMPILE_CONFIG + NSTATESTGBUTTON_CFGVALS, +#endif + NSTATESTGBUTTON_ONEVSTATE, + }; + + StringW image, hover, down, active; + int nstates; + int state; + + int onevstate; +#ifdef WASABI_COMPILE_CONFIG + StringW cfgvals; +#endif +private: + static XMLParamPair params[]; + int xuihandle; +}; + +extern const wchar_t nStatesTgButtonXuiObjectStr[]; +extern char nStatesTgButtonXuiSvcName[]; +class nStatesTgButtonXuiSvc : public XuiObjectSvc<NStatesTgButton, nStatesTgButtonXuiObjectStr, nStatesTgButtonXuiSvcName> {}; + + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/title.cpp b/Src/Wasabi/api/skin/widgets/title.cpp new file mode 100644 index 00000000..92acf4d7 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/title.cpp @@ -0,0 +1,261 @@ +#include <precomp.h> +#include "title.h" +#include <api/wndmgr/layout.h> +#include <api/wnd/paintset.h> +#include <api/skin/widgets/text.h> +#include <api/locales/xlatstr.h> +#include <api/wnd/cwndtrack.h> +#include <api/util/varmgr.h> +#include <api/wnd/PaintCanvas.h> + +#define DC_MAXIMIZE 0x9831 + +const wchar_t titleBarXuiObjectStr[] = L"TitleBar"; // This is the xml tag +char titleBarXuiSvcName[] = "TitleBar xui object"; // this is the name of the xuiservice +XMLParamPair Title::params[] = { + {TITLE_SETBORDER, L"BORDER"}, + {TITLE_SETDBLCLKACTION, L"DBLCLICKACTION"}, + {TITLE_SETMAXIMIZE, L"MAXIMIZE"}, + {TITLE_SETSTREAKS, L"STREAKS"}, + {TITLE_SETTITLE, L"TITLE"}, + }; +Title::Title() +{ + getScriptObject()->vcpu_setInterface(titleGuid, (void *)static_cast<Title *>(this)); + getScriptObject()->vcpu_setClassName(L"Title"); + getScriptObject()->vcpu_setController(titleController); + dostreaks = 1; + doborder = 1; + m_maximize = 0; + getGuiObject()->guiobject_setMover(1); + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); +} + +void Title::CreateXMLParameters(int master_handle) +{ + //TITLE_PARENT::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); +} + +Title::~Title() +{} + +int Title::setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval) +{ + if (xuihandle != _xuihandle) return TITLE_PARENT::setXuiParam(_xuihandle, attrid, name, strval); + switch (attrid) + { + case TITLE_SETTITLE: + setTitle(strval); + break; + case TITLE_SETSTREAKS: + setStreaks(WTOI(strval)); + break; + case TITLE_SETBORDER: + setBorder(WTOI(strval)); + break; + case TITLE_SETMAXIMIZE: + m_maximize = WTOI(strval); + break; + case TITLE_SETDBLCLKACTION: + dblClickAction = strval; + break; + default: + return 0; + } + return 1; +} + +void Title::setStreaks(int s) +{ + if (s == dostreaks) return ; + dostreaks = s; + invalidate(); +} + +void Title::setBorder(int b) +{ + if (b == doborder) return ; + doborder = b; + invalidate(); +} + +int Title::getPreferences(int what) +{ + if (what == SUGGESTED_W) return 128; + if (what == SUGGESTED_H) return 22; + return TITLE_PARENT::getPreferences(what); +} + +int Title::onPaint(Canvas *canvas) +{ + const wchar_t *tempname = title; + //StringW tempname(title); + PaintCanvas paintcanvas; + if (canvas == NULL) + { + if (!paintcanvas.beginPaint(this)) return 0; + canvas = &paintcanvas; + } + TITLE_PARENT::onPaint(canvas); + +#ifdef WA3COMPATIBILITY + //tempname = PublicVarManager::translate(title, getGuiObject()); +#else + tempname = title; +#endif + + +#ifdef WASABI_COMPILE_PAINTSETS + RECT pr(TITLE_PARENT::clientRect()); + const wchar_t *t = NULL; + switch(wantTranslation()) + { + case 0: + t = tempname; + break; + case 1: + t = _(tempname); + break; + case 2: + t = __(tempname); + break; + } + paintset_renderTitle(t, canvas, &pr, getPaintingAlpha(), dostreaks, doborder); +#endif + + + return 1; +} + +void Title::setTitle(const wchar_t *t) +{ + title = t; + title.toupper(); +} + +const wchar_t *Title::getTitle() +{ + return title; +} + +int Title::onLeftButtonDblClk(int x, int y) +{ + if (m_maximize) + postDeferredCallback(DC_MAXIMIZE, 0); + else + { +#ifdef WASABI_COMPILE_WNDMGR + if (dblClickAction) + { + const wchar_t *toCheck = L"SWITCH;"; + if (!WCSNICMP(dblClickAction, toCheck, 7)) + { + onLeftButtonUp(x, y); + getGuiObject()->guiobject_getParentGroup()->getParentContainer()->switchToLayout(dblClickAction.getValue() + 7); + } + } +#endif + + } + ifc_window *b = getParent(); + if (b) + return b->onLeftButtonDblClk(x, y); + return TITLE_PARENT::onLeftButtonDblClk(x, y); +} + +int Title::onDeferredCallback(intptr_t param1, intptr_t param2) +{ + switch (param1) + { +#ifdef WASABI_COMPILE_WNDMGR + case DC_MAXIMIZE: + Container *c = getGuiObject()->guiobject_getParentGroup()->getParentContainer(); + if (c) + { + Layout *l = c->getCurrentLayout(); + if (l) + { + if (l->isMaximized()) l->restore(); + else l->maximize(); + } + } + return 1; +#endif + + } + return TITLE_PARENT::onDeferredCallback(param1, param2); +} + +TitleScriptController _titleController; +TitleScriptController *titleController = &_titleController; + + +// -- Functions table ------------------------------------- +function_descriptor_struct TitleScriptController::exportedFunction[] = { + {L"fake", 0, (void*)Title::script_vcpu_fake }, + }; + +const wchar_t *TitleScriptController::getClassName() +{ + return L"Title"; +} + +const wchar_t *TitleScriptController::getAncestorClassName() +{ + return L"GuiObject"; +} + +ScriptObject *TitleScriptController::instantiate() +{ + Title *t = new Title; + ASSERT(t != NULL); + return t->getScriptObject(); +} + +void TitleScriptController::destroy(ScriptObject *o) +{ + Title *t = static_cast<Title *>(o->vcpu_getInterface(titleGuid)); + ASSERT(t != NULL); + delete t; +} + +void *TitleScriptController::encapsulate(ScriptObject *o) +{ + return NULL; // no encapsulation for title yet +} + +void TitleScriptController::deencapsulate(void *o) +{} + +int TitleScriptController::getNumFunctions() +{ + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *TitleScriptController::getExportedFunctions() +{ + return exportedFunction; +} + +GUID TitleScriptController::getClassGuid() +{ + return titleGuid; +} + + +const wchar_t *Title::vcpu_getClassName() +{ + return L"Title"; +} + +scriptVar Title::script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + RETURN_SCRIPT_VOID; +} + diff --git a/Src/Wasabi/api/skin/widgets/title.h b/Src/Wasabi/api/skin/widgets/title.h new file mode 100644 index 00000000..bbd9c448 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/title.h @@ -0,0 +1,87 @@ +//PORTABLE +#ifndef _TITLE_H +#define _TITLE_H + +#include <api/wnd/wndclass/guiobjwnd.h> +#include <api/script/objects/guiobj.h> + +// {7DFD3244-3751-4e7c-BF40-82AE5F3ADC33} +static const GUID titleGuid = +{ 0x7dfd3244, 0x3751, 0x4e7c, { 0xbf, 0x40, 0x82, 0xae, 0x5f, 0x3a, 0xdc, 0x33 } }; + +#define TITLE_PARENT GuiObjectWnd + +class TitleScriptController : public GuiObjectScriptController { + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + 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); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern TitleScriptController *titleController; + + +class Title : public TITLE_PARENT { +public: + + Title(); + virtual ~Title(); + + virtual int onPaint(Canvas *canvas); + virtual void setTitle(const wchar_t *title); + virtual const wchar_t *getTitle(); + virtual int onLeftButtonDblClk(int x, int y); + virtual int getPreferences(int what); + + virtual int setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval); + virtual const wchar_t *vcpu_getClassName(); + virtual ScriptObjectController *vcpu_getController() { return titleController; } + virtual int onDeferredCallback(intptr_t param1, intptr_t param2); + + void setBorder(int b); + void setStreaks(int s); + + enum { + TITLE_SETTITLE=0, + TITLE_SETSTREAKS, + TITLE_SETBORDER, + TITLE_SETMAXIMIZE, + TITLE_SETDBLCLKACTION, + }; + +protected: + /*static */void CreateXMLParameters(int master_handle); + +private: + static XMLParamPair params[]; + StringW title; + int dostreaks, doborder; + int m_maximize; + StringW dblClickAction; + int xuihandle; + +public: + + static scriptVar script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + +}; + +extern const wchar_t titleBarXuiObjectStr[]; +extern char titleBarXuiSvcName[]; +class TitleBarXuiSvc : public XuiObjectSvc<Title, titleBarXuiObjectStr, titleBarXuiSvcName> {}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/titlebox.cpp b/Src/Wasabi/api/skin/widgets/titlebox.cpp new file mode 100644 index 00000000..1c2c931d --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/titlebox.cpp @@ -0,0 +1,183 @@ +#include <precomp.h> +#include "titlebox.h" +#include <api/script/objects/guiobject.h> +#include <api/script/scriptobj.h> +#include <api/script/objects/c_script/c_text.h> +#include <api/skin/widgets/customobject.h> + +TitleBox::TitleBox() { + titleleft = NULL; + titleright = NULL; + titlecenter = NULL; + content = NULL; + centered = 0; +} + +TitleBox::~TitleBox() { + delete titleleft; + delete titleright; + delete titlecenter; + delete content; +} + +int TitleBox::onResize() { + int rt = TITLEBOX_PARENT::onResize(); + if (!isInited()) return 0; + + RECT r, d; + getClientRect(&r); + + int textwidth = titlecenter ? titlecenter->getPreferences(SUGGESTED_W) : 0; + + d = r; + + if (titleleft) { + if (!getCentered()) + d.right = d.left + titleleft->getPreferences(SUGGESTED_W); + else + d.right = d.left + ((r.right-r.left) - textwidth) / 2; + d.bottom = d.top + titleleft->getPreferences(SUGGESTED_H); + titleleft->resize(d.left, d.top, d.right-d.left, d.bottom-d.top); + } + + if (titlecenter) { + d.left = d.right; + d.right = d.left + titlecenter->getPreferences(SUGGESTED_W); + d.bottom = d.top + titlecenter->getPreferences(SUGGESTED_H); + titlecenter->resize(d.left, d.top, d.right-d.left, d.bottom-d.top); + } + + if (titleright) { + d.left = d.right; + d.right = r.right; + d.bottom = d.top + titleright->getPreferences(SUGGESTED_H); + titleright->resize(d.left, d.top, d.right-d.left, d.bottom-d.top); + } + + return rt; +} + +int TitleBox::onInit() { + int rt = TITLEBOX_PARENT::onInit(); + + titleleft = new GuiObjectWnd(); + titleleft->setContent(L"wasabi.titlebox.left.group"); + titlecenter = new GuiObjectWnd(); + titlecenter->setContent(L"wasabi.titlebox.center.group"); + titleright = new GuiObjectWnd(); + titleright->setContent(L"wasabi.titlebox.right.group"); + + titleleft->setParent(this); + titlecenter->setParent(this); + titleright->setParent(this); + + titleleft->init(this); + titlecenter->init(this); + titleright->init(this); + + setContent(L"wasabi.titlebox.main.group"); + return rt; +} + +void TitleBox::setSubContent(int setcontent) { + if (setcontent) { + delete content; + content = NULL; + } + + GuiObject *myself = getContent(); + + if (myself != NULL) + { + if (setcontent) + { + GuiObject *holder = findObject(L"titlebox.content"); // get the <CustomObject /> + if (holder != NULL) { + CustomObject *obj = static_cast<CustomObject*>(holder->guiobject_getScriptObject()->vcpu_getInterface(customObjectGuid)); + if (obj != NULL) { + content = new GuiObjectWnd(); + content->setContent(content_id); + obj->customobject_setRootWnd(content); // and give it our content, it'll init it as needed + } + } + } + GuiObject *text = titlecenter->getContent()->guiobject_findObject(L"titlebox.text"); + if (text != NULL) { + StringW name = getTitle(); + if (name.isempty()) { + ifc_window *cr = content->getContentRootWnd(); + if (cr != NULL) + name = cr->getRootWndName(); + } + if (name.isempty()) + name = myself->guiobject_getRootWnd()->getRootWndName(); + if (!name.isempty()) + { + name += suffix; + C_Text ctext(*text); + ctext.setText(name); + } + } + } + if (isPostOnInit()) + onResize(); +} + +void TitleBox::onNewContent() { + TITLEBOX_PARENT::onNewContent(); + setSubContent(); +} + +void TitleBox::setCentered(int _centered) { + centered = _centered; + if (isInited()) + onResize(); +} + +void TitleBox::setTitle(const wchar_t *t) { + title = t; + setName(title); + if (isInited()) + setSubContent(0); +} + +void TitleBox::setSuffix(const wchar_t *_suffix) { + if (!WCSICMPSAFE(suffix, _suffix)) return; + suffix = _suffix; + if (isInited()) + setSubContent(0); +} + +void TitleBox::setChildGroup(const wchar_t *grp) { + content_id = grp; + if (isInited()) + setSubContent(); +} + +int TitleBox::getPreferences(int what) { +/* GuiObject *contentGuiObj = findObject("titlebox.content"); + if (contentGuiObj != NULL) { + // FUCKO, this is a huge hack but I don't have time to make autowidth/heightsource be a GuiObject thing instead of a group thing right now + int x, y, rx, ry, w, rw, h, rh; + contentGuiObj->guiobject_getGuiPosition(&x, &y, &w, &h, &rx, &ry, &rw, &rh); + if (w == AUTOWH) { w = contentGuiObj->guiobject_getAutoWidth(); rw = 0; } + if (h == AUTOWH) { h = contentGuiObj->guiobject_getAutoHeight(); rh = 0; } + if (what == SUGGESTED_W) { + int p = contentGuiObj->guiobject_getRootWnd()->getPreferences(SUGGESTED_W); + if (rx == 0 && rw == 1) + return p - w; + else if (rx == 0 && rw == 0) + return p + x + w; + } else if (what == SUGGESTED_H) { + int p = contentGuiObj->guiobject_getRootWnd()->getPreferences(SUGGESTED_H); + if (ry == 0 && rh == 1) + return p + y + ((-h)-y); + else if (ry == 0 && rh == 0) + return p + y + h; + } + ifc_window *contentGuiRootWnd = contentGuiObj->guiobject_getRootWnd(); + return contentGuiRootWnd->getPreferences(what); + }*/ + return TITLEBOX_PARENT::getPreferences(what); +} + diff --git a/Src/Wasabi/api/skin/widgets/titlebox.h b/Src/Wasabi/api/skin/widgets/titlebox.h new file mode 100644 index 00000000..6631657a --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/titlebox.h @@ -0,0 +1,95 @@ +#ifndef __TITLEBOX_H +#define __TITLEBOX_H + +#include <api/wnd/wndclass/guiobjwnd.h> + +#define TITLEBOX_PARENT GuiObjectWnd + + +/** + Titlebox + + @short + @author Nullsoft + @ver 1.0 + @see +*/ +class TitleBox : public TITLEBOX_PARENT { + + public: + + + /** + Method + + @see + @ret + @param + */ + TitleBox(); + + /** + Method + + @see + @ret + @param + */ + virtual ~TitleBox(); + + + /** + Method + + @see + @ret + @param + */ + virtual int onInit(); + + virtual int onResize(); + virtual int getCentered() { return centered; } + virtual void setCentered(int _centered); + virtual void setTitle(const wchar_t *t); + virtual const wchar_t *getTitle() { return title; } + virtual void setSuffix(const wchar_t *suffix); + const wchar_t *getSuffix() { return suffix; } + + virtual void onNewContent(); + + + virtual void setChildGroup(const wchar_t *grp); + + /** + Method + + @see + @ret + @param + */ + virtual int getPreferences(int what); + + private: + + + /** + Method + + @see + @ret + @param + */ + void setSubContent(int insertcontent=1); + + GuiObjectWnd *titleleft; + GuiObjectWnd *titleright; + GuiObjectWnd *titlecenter; + GuiObjectWnd *content; + int centered; + StringW title; + StringW content_id; + StringW suffix; +}; + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/wa2/xuiwa2slider.cpp b/Src/Wasabi/api/skin/widgets/wa2/xuiwa2slider.cpp new file mode 100644 index 00000000..d4799a06 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/wa2/xuiwa2slider.cpp @@ -0,0 +1,186 @@ +#include <precomp.h> + +#include "xuiwa2slider.h" +#include <tataki/canvas/canvas.h> +#include <tataki/bitmap/bitmap.h> +#include <api/core/api_core.h> + +#define WA2SLIDER_SEEK_INTERVAL 500 + +const wchar_t Wa2SliderXuiObjectStr[] = L"images"; // This is the xml tag +char Wa2SliderXuiSvcName[] = "Images XuiObject Service"; + +XMLParamPair Wa2Slider::params[] = + { + {WA2SLIDER_IMAGES, L"IMAGES"}, + {WA2SLIDER_IMAGESSPACING, L"IMAGESSPACING"}, + {WA2SLIDER_SOURCE, L"SOURCE"}, + }; + +Wa2Slider::Wa2Slider() + : started(false) +{ + realpos = 0; + imagesBitmap = 0; + spacing = 0; + action = ACT_NONE; + + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); +} + +void Wa2Slider::CreateXMLParameters(int master_handle) +{ + //WA2SLIDER_PARENT::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); +} + +Wa2Slider::~Wa2Slider() +{ + killTimer(Wa2Slider_TIMER_POS); + WASABI_API_MEDIACORE->core_delCallback(0, this); + delete(imagesBitmap); +} + +int Wa2Slider::setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) +{ + if (xuihandle == _xuihandle) + { + switch (xmlattributeid) + { + case WA2SLIDER_IMAGES: images = value; return 1; + case WA2SLIDER_IMAGESSPACING: spacing = WTOI(value); return 1; + case WA2SLIDER_SOURCE: + if (!_wcsicmp(value, L"volume")) action = ACT_VOLUME; + if (!_wcsicmp(value, L"balance")) action = ACT_BALANCE; + if (!_wcsicmp(value, L"seek")) action = ACT_SEEK; + return 1; + } + } + return WA2SLIDER_PARENT::setXuiParam(_xuihandle, xmlattributeid, xmlattributename, value); +} + +int Wa2Slider::onInit() +{ + WA2SLIDER_PARENT::onInit(); + + imagesBitmap = new SkinBitmap(images); + + if (action == ACT_VOLUME) + corecb_onVolumeChange(WASABI_API_MEDIACORE->core_getVolume(0)); + if (action == ACT_BALANCE) + corecb_onPanChange(WASABI_API_MEDIACORE->core_getPan(0)); + if (action == ACT_SEEK) + { + corecb_onSeeked(WASABI_API_MEDIACORE->core_getPosition(0)); + started = (WASABI_API_MEDIACORE->core_getStatus(0) != 0); + setTimer(Wa2Slider_TIMER_POS, WA2SLIDER_SEEK_INTERVAL); + } + + WASABI_API_MEDIACORE->core_addCallback(0, this); + + return 0; +} + +int Wa2Slider::onPaint(Canvas *canvas) +{ + if (imagesBitmap->getHeight() && spacing) + { + RECT r, r2; + getClientRect(&r2); + int nb = (imagesBitmap->getHeight() / spacing) - 1; + int which = 0; + switch (action) + { + case ACT_BALANCE: + { + int p = realpos; + int f = 32768; //FULL/2; + if (p > f) + { + which = (realpos - f) * nb / f; + } + else if (p < f) + { + which = (f - realpos) * nb / f; + } + else which = 0; + } + break; + case ACT_SEEK: + if (!started) + which = 0; + else + which = realpos * nb / 65536; + break; + case ACT_VOLUME: + which = realpos * nb / 65536; + break; + } + + r.left = 0; + r.top = which * spacing; + r.bottom = which * spacing + (r2.bottom - r2.top); + r.right = r2.right - r2.left; + imagesBitmap->blitToRect(canvas, &r, &r2); + } + return WA2SLIDER_PARENT::onPaint(canvas); +} + +int Wa2Slider::corecb_onVolumeChange(int newvol) +{ + if (action != ACT_VOLUME) return 0; + realpos = (int)(((double)newvol * 65535.f) / 255.f); + invalidate(); + return 0; +} + +int Wa2Slider::corecb_onPanChange(int newpan) +{ + if (action != ACT_BALANCE) return 0; + + realpos = (int)(((double)(newpan + 127) * 65535.f) / 255.f); +invalidate(); + return 0; +} + +int Wa2Slider::corecb_onSeeked(int newpos) +{ + if (action != ACT_SEEK) return 0; + + int len = WASABI_API_MEDIACORE->core_getLength(0); + + realpos = (int)(((float)(newpos) * 65535.f) / (float)len); +invalidate(); + return 0; +} + +int Wa2Slider::corecb_onStarted() +{ + started = true; + corecb_onSeeked(0); + invalidate(); + return 0; +} + +int Wa2Slider::corecb_onStopped() +{ + started = false; + corecb_onSeeked(0); + invalidate(); + return 0; +} +void Wa2Slider::timerCallback(int id) +{ + switch (id) + { + case Wa2Slider_TIMER_POS: + corecb_onSeeked(WASABI_API_MEDIACORE->core_getPosition(0)); + break; + default: + WA2SLIDER_PARENT::timerCallback(id); + } +} diff --git a/Src/Wasabi/api/skin/widgets/wa2/xuiwa2slider.h b/Src/Wasabi/api/skin/widgets/wa2/xuiwa2slider.h new file mode 100644 index 00000000..1f24fe9c --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/wa2/xuiwa2slider.h @@ -0,0 +1,63 @@ +#ifndef _XUIWA2SLIDER_H +#define _XUIWA2SLIDER_H + +#include <api/script/objects/guiobj.h> +#include <api/skin/widgets.h> +#include <api/syscb/callbacks/corecbi.h> + +#define WA2SLIDER_PARENT GuiObjectWnd + +class Wa2Slider : public WA2SLIDER_PARENT, public CoreCallbackI +{ +public: + Wa2Slider(); + virtual ~Wa2Slider(); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + virtual int onInit(); + virtual int onPaint(Canvas *canvas); + + virtual int corecb_onVolumeChange(int newvol); + virtual int corecb_onPanChange(int newpan); + virtual int corecb_onSeeked(int newpos); + virtual int corecb_onStarted(); + virtual int corecb_onStopped(); + virtual void timerCallback(int id); + +protected: + /*static */void CreateXMLParameters(int master_handle); +private: + int realpos; + StringW images; + SkinBitmap *imagesBitmap; + int spacing; + int action; + static XMLParamPair params[]; + int xuihandle; + bool started; + + enum { + ACT_NONE = 0, + ACT_VOLUME, + ACT_BALANCE, + ACT_SEEK, + }; + + enum { + Wa2Slider_TIMER_POS = 1, + }; + enum { + WA2SLIDER_IMAGES, + WA2SLIDER_IMAGESSPACING, + WA2SLIDER_SOURCE, + WA2SLIDER_NUMPARAMS, + }; +}; + +// ----------------------------------------------------------------------- +extern const wchar_t Wa2SliderXuiObjectStr[]; +extern char Wa2SliderXuiSvcName[]; +class Wa2SliderXuiSvc : public XuiObjectSvc<Wa2Slider, Wa2SliderXuiObjectStr, Wa2SliderXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuiaddparams.cpp b/Src/Wasabi/api/skin/widgets/xuiaddparams.cpp new file mode 100644 index 00000000..aa6d5daa --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuiaddparams.cpp @@ -0,0 +1,41 @@ +#include <precomp.h> + +#include "xuiaddparams.h" +#include <api/script/scriptguid.h> + +// ----------------------------------------------------------------------- +const wchar_t AddParamsXuiObjectStr[] = L"AddParams"; // This is the xml tag +char AddParamsXuiSvcName[] = "AddParams xui object"; + +// ----------------------------------------------------------------------- +AddParams::AddParams():myxuihandle(0) { +} + +// ----------------------------------------------------------------------- +AddParams::~AddParams() { + pastlist.deleteAll(); +} + +// ----------------------------------------------------------------------- +int AddParams::setXmlParam(const wchar_t *param, const wchar_t *value) +{ + int r = ADDPARAMS_PARENT::setXmlParam(param, value); + if (!WCSCASEEQLSAFE(param, L"group") && !WCSCASEEQLSAFE(param, L"target")) { + Pair<StringW, StringW> *pair = new Pair<StringW, StringW>(param, value); + pastlist.addItem(pair); + } + return r; +} + +// ----------------------------------------------------------------------- +void AddParams::actuator_onPerform(GuiObject *target) { // guaranteed non NULL + ADDPARAMS_PARENT::actuator_onPerform(target); + XmlObject *xtarget = static_cast<XmlObject *>(target->guiobject_getScriptObject()->vcpu_getInterface(xmlObjectGuid)); + foreach(pastlist) + const wchar_t *a = pastlist.getfor()->a; + int xp = xtarget->getXmlParam(a); + StringW newval((xp == -1) ? L"" : xtarget->getXmlParamValue(xp)); + newval.cat(pastlist.getfor()->b); + xtarget->setXmlParam(a, newval); + endfor; +} diff --git a/Src/Wasabi/api/skin/widgets/xuiaddparams.h b/Src/Wasabi/api/skin/widgets/xuiaddparams.h new file mode 100644 index 00000000..1d41e36e --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuiaddparams.h @@ -0,0 +1,34 @@ +#ifndef __ADDPARAMS_H +#define __ADDPARAMS_H + +#include <api/skin/objectactuator.h> +#include <bfc/pair.h> + +#define ADDPARAMS_PARENT ObjectActuator + +extern const wchar_t AddParamsXuiObjectStr[]; +extern char AddParamsXuiSvcName[]; + +// ----------------------------------------------------------------------- +// Your wnd object class +class AddParams: public ADDPARAMS_PARENT { +public: + + AddParams(); + virtual ~AddParams(); + + virtual int setXmlParam(const wchar_t *param, const wchar_t *value); + virtual void actuator_onPerform(GuiObject *target); + virtual const wchar_t *getActuatorTag() { return AddParamsXuiObjectStr; } // for error msgs purposes + +private: + int myxuihandle; + PtrList< Pair<StringW, StringW> > pastlist; +}; + +// ----------------------------------------------------------------------- +// This defines the svc_xuiObject that exposes your wnd object + +class AddParamsXuiSvc : public XuiObjectSvc<AddParams, AddParamsXuiObjectStr, AddParamsXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuibookmarklist.cpp b/Src/Wasabi/api/skin/widgets/xuibookmarklist.cpp new file mode 100644 index 00000000..abcfacfd --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuibookmarklist.cpp @@ -0,0 +1,50 @@ +#include <precomp.h> +#include "xuibookmarklist.h" + +// ----------------------------------------------------------------------- +const wchar_t BookmarkListXuiObjectStr[] = L"BookmarkList"; // This is the xml tag +char BookmarkListXuiSvcName[] = "BookmarkList xui object"; + +XMLParamPair BookmarkList::params[] = { + {BOOKMARKLIST_SET, L""}, +}; + + +// ----------------------------------------------------------------------- +BookmarkList::BookmarkList() { + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); +} + +void BookmarkList::CreateXMLParameters(int master_handle) +{ + //BOOKMARKLIST_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +BookmarkList::~BookmarkList() +{ +} + +// ----------------------------------------------------------------------- +int BookmarkList::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return BOOKMARKLIST_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) { + case BOOKMARKLIST_SET: + set(value); + break; + default: + return 0; + } + return 1; +} + +// ----------------------------------------------------------------------- +void BookmarkList::set(const wchar_t *elementname) { +} + diff --git a/Src/Wasabi/api/skin/widgets/xuibookmarklist.h b/Src/Wasabi/api/skin/widgets/xuibookmarklist.h new file mode 100644 index 00000000..277899f8 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuibookmarklist.h @@ -0,0 +1,36 @@ +#ifndef __BOOKMARKLIST_H +#define __BOOKMARKLIST_H + +#include <api/wnd/wndclass/guiobjwnd.h> + +#define BOOKMARKLIST_PARENT GuiObjectWnd + +// ----------------------------------------------------------------------- +class BookmarkList : public BOOKMARKLIST_PARENT { + + public: + + BookmarkList(); + virtual ~BookmarkList(); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + void set(const wchar_t *elementname); + +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + + enum { + BOOKMARKLIST_SET = 0, + }; + static XMLParamPair params[]; + int myxuihandle; +}; + +// ----------------------------------------------------------------------- +extern const wchar_t BookmarkListXuiObjectStr[]; +extern char BookmarkListXuiSvcName[]; +class BookmarkListXuiSvc : public XuiObjectSvc<BookmarkList, BookmarkListXuiObjectStr, BookmarkListXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuicheckbox.cpp b/Src/Wasabi/api/skin/widgets/xuicheckbox.cpp new file mode 100644 index 00000000..599c52e7 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuicheckbox.cpp @@ -0,0 +1,165 @@ +#include <precomp.h> +#include "xuicheckbox.h" +#include <bfc/parse/paramparser.h> +#include <api/script/objects/c_script/c_text.h> + +// ----------------------------------------------------------------------- +const wchar_t ScriptCheckBoxXuiObjectStr[] = L"Wasabi:CheckBox"; // This is the xml tag +char ScriptCheckBoxXuiSvcName[] = "Wasabi:CheckBox xui object"; + +XMLParamPair ScriptCheckBox::params[] = { + {SCRIPTCHECKBOX_ACTION, L"ACTION"}, + {SCRIPTCHECKBOX_ACTIONTARGET, L"ACTION_TARGET"}, + {SCRIPTCHECKBOX_ACTIONPARAM, L"PARAM"}, +{SCRIPTCHECKBOX_RADIOID, L"RADIOID"}, + {SCRIPTCHECKBOX_RADIOVAL, L"RADIOVAL"}, + {SCRIPTCHECKBOX_TEXT, L"TEXT"}, + + }; +// ----------------------------------------------------------------------- +ScriptCheckBox::ScriptCheckBox() : SCRIPTCHECKBOX_PARENT() { + getScriptObject()->vcpu_setInterface(checkBoxGuid, (void *)static_cast<ScriptCheckBox*>(this)); + getScriptObject()->vcpu_setClassName(L"CheckBox"); // this is the script class name + getScriptObject()->vcpu_setController(checkBoxController); + + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); +} + + +void ScriptCheckBox::CreateXMLParameters(int master_handle) +{ + //SCRIPTCHECKBOX_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +// ----------------------------------------------------------------------- +ScriptCheckBox::~ScriptCheckBox() { +} + +// ----------------------------------------------------------------------- +int ScriptCheckBox::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return SCRIPTCHECKBOX_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + // Parcel the values out to the window object we multiply inherit from + switch (xmlattributeid) { + case SCRIPTCHECKBOX_TEXT: + setText(value); + break; + case SCRIPTCHECKBOX_RADIOID: + setRadioid(value); + break; + case SCRIPTCHECKBOX_RADIOVAL: + setRadioVal(value); + break; + case SCRIPTCHECKBOX_ACTION: + setAction(value); + break; + case SCRIPTCHECKBOX_ACTIONPARAM: + setActionParam(value); + break; + case SCRIPTCHECKBOX_ACTIONTARGET: + setActionTarget(value); + break; + default: + return 0; + } + return 1; +} + +void ScriptCheckBox::onToggle() { + SCRIPTCHECKBOX_PARENT::onToggle(); + Accessible *a = getAccessibleObject(); + if (a != NULL) { + a->onStateChange(); + } + CheckBoxController::onToggle(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(isActivated())); +} + +// ----------------------------------------------------------------------- +// Script Object + +CheckBoxController _checkBoxController; +CheckBoxController *checkBoxController = &_checkBoxController; + +// -- Functions table ------------------------------------- +function_descriptor_struct CheckBoxController::exportedFunction[] = { + {L"onToggle", 1, (void*)CheckBoxController::onToggle}, + {L"setChecked", 1, (void*)CheckBoxController::setChecked}, + {L"isChecked", 0, (void*)CheckBoxController::isChecked}, + {L"setText", 1, (void*)CheckBoxController::setText}, + {L"getText", 0, (void*)CheckBoxController::getText}, +}; + +ScriptObject *CheckBoxController::instantiate() { + ScriptCheckBox *sb = new ScriptCheckBox; + ASSERT(sb != NULL); + return sb->getScriptObject(); +} + +void CheckBoxController::destroy(ScriptObject *o) { + ScriptCheckBox *sb = static_cast<ScriptCheckBox *>(o->vcpu_getInterface(checkBoxGuid)); + ASSERT(sb != NULL); + delete sb; +} + +void *CheckBoxController::encapsulate(ScriptObject *o) { + return NULL; // no encapsulation for checkboxes yet +} + +void CheckBoxController::deencapsulate(void *o) { +} + +int CheckBoxController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *CheckBoxController::getExportedFunctions() { + return exportedFunction; +} + + +scriptVar CheckBoxController::onToggle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newstate) { + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, checkBoxController, newstate); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, newstate); +} + +scriptVar CheckBoxController::setChecked(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar state) { + SCRIPT_FUNCTION_INIT + ScriptCheckBox *sb = static_cast<ScriptCheckBox *>(o->vcpu_getInterface(checkBoxGuid)); + if (sb) sb->setActivated(GET_SCRIPT_INT(state)); + RETURN_SCRIPT_VOID; +} + +scriptVar CheckBoxController::isChecked(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + int a = 0; + ScriptCheckBox *sb = static_cast<ScriptCheckBox *>(o->vcpu_getInterface(checkBoxGuid)); + if (sb) a = sb->isActivated(); + return MAKE_SCRIPT_INT(a); +} + +scriptVar CheckBoxController::setText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar text) { + SCRIPT_FUNCTION_INIT + ScriptCheckBox *sb = static_cast<ScriptCheckBox *>(o->vcpu_getInterface(checkBoxGuid)); + if (sb) + sb->setText(GET_SCRIPT_STRING(text)); + RETURN_SCRIPT_VOID; +} + +scriptVar CheckBoxController::getText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ScriptCheckBox *sb = static_cast<ScriptCheckBox *>(o->vcpu_getInterface(checkBoxGuid)); + if (sb) + { + return MAKE_SCRIPT_STRING(sb->getText()); + + } + return MAKE_SCRIPT_STRING(L""); +} diff --git a/Src/Wasabi/api/skin/widgets/xuicheckbox.h b/Src/Wasabi/api/skin/widgets/xuicheckbox.h new file mode 100644 index 00000000..295ad4e9 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuicheckbox.h @@ -0,0 +1,81 @@ +#ifndef __SCRIPTCHECKBOX_H +#define __SCRIPTCHECKBOX_H + +#include <api/skin/widgets/checkbox.h> +#include <api/script/objects/c_script/h_guiobject.h> +#include <api/script/objcontroller.h> +#include <api/wnd/accessible.h> + +#define SCRIPTCHECKBOX_PARENT CheckBox + +// ----------------------------------------------------------------------- +// Your wnd object class +class ScriptCheckBox : public SCRIPTCHECKBOX_PARENT { + + public: + + ScriptCheckBox(); + virtual ~ScriptCheckBox(); + + // XuiObject automatically calls this back for all parameters registered using addParam + // encountered in the xml source + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + virtual void onToggle(); + + virtual int accessibility_getState() { return CHECKBOX_PARENT::accessibility_getState() | (isActivated() ? STATE_SYSTEM_CHECKED : 0); } +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + + // a list of IDs for our xml attributes, we use them in addParam() in the constructor + enum { + SCRIPTCHECKBOX_TEXT = 0, + SCRIPTCHECKBOX_RADIOID, + SCRIPTCHECKBOX_RADIOVAL, + SCRIPTCHECKBOX_ACTION, + SCRIPTCHECKBOX_ACTIONPARAM, + SCRIPTCHECKBOX_ACTIONTARGET, + }; + int myxuihandle; + static XMLParamPair params[]; +}; + +// ----------------------------------------------------------------------------------------------------- +class CheckBoxController : public ScriptObjectControllerI { + public: + + virtual const wchar_t *getClassName() { return L"Checkbox"; } + virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; } + virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); } + virtual int getNumFunctions(); + virtual const function_descriptor_struct *getExportedFunctions(); + virtual GUID getClassGuid() { return checkBoxGuid; } + virtual ScriptObject *instantiate(); + virtual void destroy(ScriptObject *o); + virtual void *encapsulate(ScriptObject *o); + virtual void deencapsulate(void *o); + + public: + static scriptVar onToggle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newstate); + static scriptVar setChecked(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar state); + static scriptVar isChecked(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar setText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar text); + static scriptVar getText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + + private: + + static function_descriptor_struct exportedFunction[]; +}; + +extern CheckBoxController *checkBoxController; + + +// ----------------------------------------------------------------------- +// This defines the svc_xuiObject that exposes your wnd object + +extern const wchar_t ScriptCheckBoxXuiObjectStr[]; +extern char ScriptCheckBoxXuiSvcName[]; +class ScriptCheckBoxXuiSvc : public XuiObjectSvc<ScriptCheckBox, ScriptCheckBoxXuiObjectStr, ScriptCheckBoxXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuicombobox.cpp b/Src/Wasabi/api/skin/widgets/xuicombobox.cpp new file mode 100644 index 00000000..0e9af71c --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuicombobox.cpp @@ -0,0 +1,7 @@ +#include <precomp.h> +#include "xuicombobox.h" + +// ----------------------------------------------------------------------- +const wchar_t ComboBoxXuiObjectStr[] = L"Wasabi:ComboBox"; +char ComboBoxXuiSvcName[] = "Wasabi:ComboBox xui object"; + diff --git a/Src/Wasabi/api/skin/widgets/xuicombobox.h b/Src/Wasabi/api/skin/widgets/xuicombobox.h new file mode 100644 index 00000000..4d60e0ad --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuicombobox.h @@ -0,0 +1,10 @@ +#ifndef __XUICOMBOBOX_H +#define __XUICOMBOBOX_H + +#include <api/skin/widgets/combobox.h> + +extern const wchar_t ComboBoxXuiObjectStr[]; +extern char ComboBoxXuiSvcName[]; +class ComboBoxXuiSvc : public XuiObjectSvc<ComboBox, ComboBoxXuiObjectStr, ComboBoxXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuicustomobject.cpp b/Src/Wasabi/api/skin/widgets/xuicustomobject.cpp new file mode 100644 index 00000000..559dd4f4 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuicustomobject.cpp @@ -0,0 +1,64 @@ +#include <precomp.h> +#include "xuicustomobject.h" +#include <api/wnd/notifmsg.h> + +// ----------------------------------------------------------------------- +const wchar_t CustomObjectXuiObjectStr[] = L"CustomObject"; // This is the xml tag +char CustomObjectXuiSvcName[] = "CustomObject xui object"; + +XMLParamPair XuiCustomObject::params[] = { + {CUSTOMOBJECT_SETGROUP, L"GROUPID"}, +}; + +// ----------------------------------------------------------------------- +XuiCustomObject::XuiCustomObject() +{ + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); + + ScriptObject *o = getGuiObject()->guiobject_getScriptObject(); + o->vcpu_setInterface(customObjectGuid, static_cast<CustomObject *>(this)); + +} + +void XuiCustomObject::CreateXMLParameters(int master_handle) +{ + //CUSTOMOBJECT_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); + +} +// ----------------------------------------------------------------------- +XuiCustomObject::~XuiCustomObject() { +} + +// ----------------------------------------------------------------------- +int XuiCustomObject::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return CUSTOMOBJECT_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) { + case CUSTOMOBJECT_SETGROUP: + setContent(value); + break; + default: + return 0; + } + return 1; +} + +// ----------------------------------------------------------------------- +void XuiCustomObject::setGroup(const wchar_t *elementname) { + setContent(elementname); +} + +// ----------------------------------------------------------------------- +void XuiCustomObject::customobject_setRootWnd(ifc_window *w) { + rootwndholder_setRootWnd(NULL); + groupid = L""; + setContent(groupid); + if (w != NULL) rootwndholder_setRootWnd(w); + notifyParent(ChildNotify::AUTOWHCHANGED); +} diff --git a/Src/Wasabi/api/skin/widgets/xuicustomobject.h b/Src/Wasabi/api/skin/widgets/xuicustomobject.h new file mode 100644 index 00000000..28f5227e --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuicustomobject.h @@ -0,0 +1,40 @@ +#ifndef __CustomObject_H +#define __CustomObject_H + +#include <api/wnd/wndclass/guiobjwnd.h> +#include <api/skin/widgets/customobject.h> + +#define CUSTOMOBJECT_PARENT GuiObjectWnd + +// ----------------------------------------------------------------------- +class XuiCustomObject : public CUSTOMOBJECT_PARENT, public CustomObjectI { + + public: + + XuiCustomObject(); + virtual ~XuiCustomObject(); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + void setGroup(const wchar_t *elementname); + virtual void customobject_setRootWnd(ifc_window *w); +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + + enum { + CUSTOMOBJECT_SETGROUP = 0, + }; + static XMLParamPair params[]; + int myxuihandle; + StringW groupid; +}; + + +// ----------------------------------------------------------------------- + +extern const wchar_t CustomObjectXuiObjectStr[]; +extern char CustomObjectXuiSvcName[]; +class CustomObjectXuiSvc : public XuiObjectSvc<XuiCustomObject, CustomObjectXuiObjectStr, CustomObjectXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuidownloadslist.cpp b/Src/Wasabi/api/skin/widgets/xuidownloadslist.cpp new file mode 100644 index 00000000..d79b834b --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuidownloadslist.cpp @@ -0,0 +1,411 @@ +#include <precomp.h> +#include "xuidownloadslist.h" +#include "wa2frontend.h" +#include <api/wnd/popup.h> +#include <bfc/parse/pathparse.h> + +#ifndef _WASABIRUNTIME + +BEGIN_SERVICES(DownloadsList_Svc); +DECLARE_SERVICE(XuiObjectCreator<DownloadsListXuiSvc>); +END_SERVICES(DownloadsList_Svc, _DownloadsList_Svc); + +#ifdef _X86_ +extern "C" { int _link_DownloadsListXuiSvc; } +#else +extern "C" { int __link_DownloadsListXuiSvc; } +#endif + +#endif + +// ----------------------------------------------------------------------- +const wchar_t DownloadsListXuiObjectStr[] = L"DownloadsList"; // This is the xml tag +char DownloadsListXuiSvcName[] = "DownloadsList xui object"; + +XMLParamPair DownloadsList::params[] = { + {CTLIST_NOHSCROLL, L"NOHSCROLL"}, + }; + +// ----------------------------------------------------------------------- +DownloadsList::DownloadsList () +{ + setPreventMultipleSelection(1); + ensure_on_paint = -1; + nohscroll = 1; + + setAutoSort(false); + setVirtual(0); + + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); + + DownloadsList::skinObjects.addItem(this); +} + +void DownloadsList::CreateXMLParameters(int master_handle) +{ + //DOWNLOADSLIST_PARENT::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); +} + +// ----------------------------------------------------------------------- +DownloadsList::~DownloadsList() { + for (int i = 0; i != this->getNumItems(); i++) + { + const wchar_t * w = (const wchar_t *) this->getItemData(i); + delete w; + } + DownloadsList::skinObjects.removeItem(this); +} + +// ----------------------------------------------------------------------- +int DownloadsList::onInit() +{ + DOWNLOADSLIST_PARENT::onInit(); + + addColumn(LocalesManager::GetString(L"nullsoft.browser", 19),100); + addColumn(LocalesManager::GetString(L"nullsoft.browser", 18), 95); + + ListColumn *urlCol = new ListColumn(LocalesManager::GetString(L"nullsoft.browser", 17), 0); + insertColumn(urlCol); + + ListColumn *tCol = new ListColumn(LocalesManager::GetString(L"nullsoft.browser", 20), 0); + insertColumn(tCol); + + // Load all previous downloads - we must begin from the end of our list + for (int i = activeDownloads.getNumItems()-1; i != -1; i--) + { + if (activeDownloads.enumItem(i) == NULL) + { + activeDownloads.removeByPos(i); + continue; // Next loop + } + newItem(STATUS_WAITING, activeDownloads.enumItem(i)); + } + + return 1; +} + +// Prohibit list sorting ;) +int DownloadsList::onColumnLabelClick (int col, int x, int y) +{ + //do nothing + return 1; +} +int DownloadsList::onColumnDblClick (int col, int x, int y) +{ + //do nothing + return 1; +} + +// ----------------------------------------------------------------------- +int DownloadsList::onResize() { + DOWNLOADSLIST_PARENT::onResize(); + if (nohscroll) { + RECT r; + getClientRect(&r); + int nw = r.right-r.left - getColumn(0)->getWidth() - getColumn(1)->getWidth(); + ListColumn *cLoc = getColumn(2); + ListColumn *cTit = getColumn(3); + cLoc->setWidth((int)(nw*0.65)); + cTit->setWidth((int)(nw*0.35)); + } + return 1; +} + +// ----------------------------------------------------------------------- +void DownloadsList::onDoubleClick(int itemnum) +{ + if (getItemData(itemnum) != NULL) wa2.playFile(this->getSubitemText(itemnum, 2)); +} + +// ----------------------------------------------------------------------- +int DownloadsList::onRightClick(int itemnum) +{ + DOWNLOADSLIST_PARENT::onRightClick(itemnum); + + PopupMenu p; + if (this->getItemData(itemnum) == NULL) + p.addCommand(L"Wait for file to be transferred", 666, 0 , 1); + else + { + p.addCommand(L"Play", 1, 0 , 0); + p.addCommand(L"Enqueue", 2, 0 , 0); + } + + int result = p.popAtMouse(); + + switch (result) + { + case 1: wa2.playFile(this->getSubitemText(itemnum, 2)); break; + case 2: wa2.enqueueFile(this->getSubitemText(itemnum, 2)); break; + } + + return 1; +} + +// ----------------------------------------------------------------------- +int DownloadsList::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) { + if (!_wcsicmp(action, L"play_selected")) + { + int sel = getFirstItemSelected(); + + if (sel > -1) + { + if (getItemData(sel) != NULL) wa2.playFile(this->getSubitemText(sel, 2)); + } + else + { + boolean enq = false; + for (int i = 0; i != getNumItems(); i++) + { + if (getItemData(i) != NULL) + { + if (!enq) + { + wa2.playFile(this->getSubitemText(i, 2)); + enq = true; + } + else + wa2.enqueueFile(this->getSubitemText(i, 2)); + } + } + } + return 1; + } + + return DOWNLOADSLIST_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source); +} + +// ----------------------------------------------------------------------- +/*int DownloadsList::getTextBold(LPARAM lParam) { + if (WCSCASEEQLSAFE(WASABI_API_SKIN->colortheme_enumColorSet(lParam & 0xFFFF), WASABI_API_SKIN->colortheme_getColorSet())) return 1; + return DOWNLOADSLIST_PARENT::getTextBold(lParam); +}*/ + +// ----------------------------------------------------------------------- +void DownloadsList::onSetVisible(int show) { + DOWNLOADSLIST_PARENT::onSetVisible(show); + /*if (show) loadThemes(); + else getDesktopParent()->setFocus();*/ +} + +// ----------------------------------------------------------------------- +int DownloadsList::setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value) { + if (xuihandle == _xuihandle) { + switch (xmlattrid) { + case CTLIST_NOHSCROLL: nohscroll = WTOI(value); return 1; + } + } + return DOWNLOADSLIST_PARENT::setXuiParam(_xuihandle, xmlattrid, name, value); +} + +int DownloadsList::onPaint(Canvas *canvas) { + if (ensure_on_paint > -1) ensureItemVisible(ensure_on_paint); + ensure_on_paint = -1; + DOWNLOADSLIST_PARENT::onPaint(canvas); + return 1; +} + +void DownloadsList::newItem(int status, DownloadToken token) +{ + uint64_t total=0; + const char *url = 0; + api_httpreceiver *http = WAC_API_DOWNLOADMANAGER->GetReceiver(token); + if (http) + { + total = http->content_length(); + if (url == NULL) + { + url = http->get_url();//WAC_API_DOWNLOADMANAGER->GetUrl(token); + if (!url) + { + url = ""; + } + } + } + else + { + url = ""; + } + + uint64_t downloaded = WAC_API_DOWNLOADMANAGER->GetBytesDownloaded(token); + wchar_t text[256] = {0}; + + if (total) + { + if (total == downloaded) + return; // Delete from list on skin-reload + } + + StringCchPrintfW(text, 256, L"%I64u / %d %s", downloaded, total, _(L"bytes")); + + switch (status) + { + case STATUS_WAITING: + insertItem(0, _(L"Waiting"), 0); + break; + case STATUS_TRANSFERRING: + insertItem(0, _(L"Transferring"), 0); + break; + case STATUS_FINISHED: + insertItem(0, _(L"Finished"), 0); + break; + case STATUS_ERROR: + insertItem(0, _(L"Error"), 0); + break; + default: + insertItem(0, L"", 0); + break; + } + + setSubItem(0, 1, text); + setSubItem(0, 2, AutoWide(url)); +} + +/** + * Static Managing of downloadlist + * handled via callbacks from MediaDownloader + */ +void DownloadsList::onDownloadStart (const char *url, DownloadToken token) +{ + for(int i=0; i<skinObjects.getNumItems(); i++) + { + DownloadsList *tmp = skinObjects.enumItem(i); + tmp->newItem(STATUS_WAITING, token); + activeDownloads.addItem(token, 0); // dunno if we will need this later on... + } +} + +void DownloadsList::onDownloadTick (DownloadToken token) +{ + int n = activeDownloads.searchItem(token); + if (n < 0) return; + + uint64_t total=0; + api_httpreceiver *http = WAC_API_DOWNLOADMANAGER->GetReceiver(token); + if (http) + { + total = http->content_length(); + } + + uint64_t downloaded = WAC_API_DOWNLOADMANAGER->GetBytesDownloaded(token); + uint64_t percent = 0; + + wchar_t text[256] = {0}; + wchar_t text2[64] = {0}; + + if (total) + { + percent=downloaded*100; + if (total) + percent/=total; + else + percent=0; + StringCchPrintfW(text, 256, L"%I64u / %d %s", downloaded/1024, total/1024, _(L"KB")); + StringCchPrintfW(text2, 64, L"%s %d%%", _(L"Transferring"), percent); + } + else + { + StringCchPrintfW(text, 256, L"%I64u / %d %s", downloaded, total, _(L"KB")); + StringCchPrintfW(text2, 64, _(L"Transferring")); + } + + for(int i=0; i!=skinObjects.getNumItems(); i++) + { + DownloadsList *tmp = skinObjects.enumItem(i); + + tmp->setSubItem(n, 1, text); + tmp->setItemLabel(n, text2); + } +} + +void DownloadsList::onDownloadEnd (DownloadToken token, const wchar_t * filename) +{ + int n = activeDownloads.searchItem(token); + if (n < 0) return; + + activeDownloads.setItem(NULL, n); // So we know the download is done! + + wchar_t artist[256] = {0}; + wchar_t title[256] = {0}; + wa2.getMetaData(filename, L"artist", artist, 256); + wa2.getMetaData(filename, L"title", title, 256); + + StringW display; + bool hasArtist = !!WCSICMP(artist, L""); + bool hasTitle= !!WCSICMP(title, L""); + + StringW url = L""; + + for(int i=0; i!=skinObjects.getNumItems(); i++) + { + DownloadsList *tmp = skinObjects.enumItem(i); + + if (!WCSICMP(url, L"")) + url = tmp->getSubitemText(n, 2); + + tmp->setItemLabel(n, _(L"Finished")); + tmp->setSubItem(n, 2, filename); + + if (!hasArtist && !hasTitle) + { + PathParserW pp(filename); + display = pp.getLastString(); + } + else if (!hasArtist) + display = title; + else if (!hasTitle) + display = artist; + else + display = StringPrintfW(L"%s - %s",artist,title); + + tmp->setSubItem(n, 3, display); + tmp->setItemParam(n, STATUS_FINISHED); + } +} + +void DownloadsList::onDownloadCancel(DownloadToken token) +{ + int n = activeDownloads.searchItem(token); + if (n < 0) return; + + activeDownloads.setItem(NULL, n); // So we know the download is done/cancelled! + const wchar_t * url = 0; + + for(int i=0; i!=skinObjects.getNumItems(); i++) + { + DownloadsList *tmp = skinObjects.enumItem(i); + tmp->setItemLabel(n, _(L"Cancelled")); + if (!url) url = tmp->getSubitemText(n, 2); + } + + SystemObject::onDownloadFinished((!url ? L"" : url), false, L""); +} + +void DownloadsList::onDownloadError(DownloadToken token, int code) +{ + int n = activeDownloads.searchItem(token); + if (n < 0) return; + + activeDownloads.setItem(NULL, n); // So we know the download is done/cancelled! + + const wchar_t * url = 0; + + for(int i=0; i!=skinObjects.getNumItems(); i++) + { + DownloadsList *tmp = skinObjects.enumItem(i); + wchar_t buf[64] = {0}; + StringCchPrintfW(buf, 64, L"%s: %i", _(L"Error"), code); + tmp->setItemLabel(n, buf); + if (!url) url = tmp->getSubitemText(n, 2); + } + + SystemObject::onDownloadFinished((!url ? L"" : url), false, L""); +} + +PtrList<void> DownloadsList::activeDownloads; +PtrList<DownloadsList> DownloadsList::skinObjects;
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/xuidownloadslist.h b/Src/Wasabi/api/skin/widgets/xuidownloadslist.h new file mode 100644 index 00000000..88458462 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuidownloadslist.h @@ -0,0 +1,77 @@ +#ifndef __THEMESLIST_H +#define __THEMESLIST_H + +#include "api/wnd/wndclass/listwnd.h" +#include "main.h" +//#include "../Components/wac_downloads/wac_downloads_download_manager.h" +#include "../../../../Components/wac_network/wac_network_http_receiver_api.h" +#include "../nu/AutoWide.h" +#include "api/script/objects/systemobj.h" + +#define DOWNLOADSLIST_PARENT ListWnd + +// ----------------------------------------------------------------------- +class DownloadsList : public DOWNLOADSLIST_PARENT +{ + + public: + + DownloadsList(); + virtual ~DownloadsList(); + + virtual int onInit(); + virtual void onDoubleClick(int itemnum); + virtual int onPaint(Canvas *canvas); + virtual int onRightClick(int itemnum); + virtual int onColumnDblClick(int col, int x, int y); + virtual int onColumnLabelClick(int col, int x, int y); + + virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source); + virtual int onResize(); + virtual int wantResizeCols() { return 0; } + virtual int setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value); + virtual int wantHScroll() { return !nohscroll; } + + // virtual int getTextBold(LPARAM lParam); + virtual void onSetVisible(int show); + + // Callbacks from MediaDownloader + static void onDownloadStart(const char *url, DownloadToken token); + static void onDownloadTick(DownloadToken token); + static void onDownloadEnd(DownloadToken token, const wchar_t * filename); + static void onDownloadError(DownloadToken token, int code); + static void onDownloadCancel(DownloadToken token); + + enum { + CTLIST_NOHSCROLL = 0, + }; + +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + static XMLParamPair params[]; + int xuihandle; + int nohscroll; + int ensure_on_paint; + + void newItem(int status, DownloadToken token); + + static PtrList<void> activeDownloads; + static PtrList<DownloadsList> skinObjects; + + enum DOWNLOAD_STATUS + { + STATUS_WAITING = 0, + STATUS_TRANSFERRING = 1, + STATUS_FINISHED = 2, + STATUS_ERROR = -1, + STATUS_CANCEL = -2, + }; +}; + +// ----------------------------------------------------------------------- +extern const wchar_t DownloadsListXuiObjectStr[]; +extern char DownloadsListXuiSvcName[]; +class DownloadsListXuiSvc : public XuiObjectSvc<DownloadsList, DownloadsListXuiObjectStr, DownloadsListXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuidropdownlist.cpp b/Src/Wasabi/api/skin/widgets/xuidropdownlist.cpp new file mode 100644 index 00000000..4cdc2bd6 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuidropdownlist.cpp @@ -0,0 +1,7 @@ +#include <precomp.h> +#include "xuidropdownlist.h" + +// ----------------------------------------------------------------------- +const wchar_t DropDownListXuiObjectStr[] = L"Wasabi:DropDownList"; +char DropDownListXuiSvcName[] = "Wasabi:DropDownList xui object"; + diff --git a/Src/Wasabi/api/skin/widgets/xuidropdownlist.h b/Src/Wasabi/api/skin/widgets/xuidropdownlist.h new file mode 100644 index 00000000..6e4e55af --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuidropdownlist.h @@ -0,0 +1,10 @@ +#ifndef __XUIDROPDOWNLIST_H +#define __XUIDROPDOWNLIST_H + +#include <api/skin/widgets/dropdownlist.h> + +extern const wchar_t DropDownListXuiObjectStr[]; +extern char DropDownListXuiSvcName[]; +class DropDownListXuiSvc : public XuiObjectSvc<DropDownList, DropDownListXuiObjectStr, DropDownListXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuieditbox.cpp b/Src/Wasabi/api/skin/widgets/xuieditbox.cpp new file mode 100644 index 00000000..22436de2 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuieditbox.cpp @@ -0,0 +1,6 @@ +#include <precomp.h> +#include "xuititlebox.h" + +char EditBoxXuiObjectStr[] = "Wasabi:EditBox"; +char EditBoxXuiSvcName[] = "Wasabi:EditBox xui object"; + diff --git a/Src/Wasabi/api/skin/widgets/xuieditbox.h b/Src/Wasabi/api/skin/widgets/xuieditbox.h new file mode 100644 index 00000000..6a9265ec --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuieditbox.h @@ -0,0 +1,21 @@ +#ifndef __EDITBOX_H +#define __EDITBOX_H + +#include <api/wnd/wndclass/embeddedxui.h> + +#define EDITBOX_PARENT EmbeddedXuiObject + +// ----------------------------------------------------------------------- +class EditBox : public EDITBOX_PARENT { + public: + + virtual const wchar_t *embeddedxui_getContentId() { return "wasabi.edit"; } + virtual const wchar_t *embeddedxui_getEmbeddedObjectId() { return "wasabi.edit.box"; } +}; + +// ----------------------------------------------------------------------- +extern char EditBoxXuiObjectStr[]; +extern char EditBoxXuiSvcName[]; +class EditBoxXuiSvc : public XuiObjectSvc<EditBox, EditBoxXuiObjectStr, EditBoxXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuiframe.cpp b/Src/Wasabi/api/skin/widgets/xuiframe.cpp new file mode 100644 index 00000000..919baad1 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuiframe.cpp @@ -0,0 +1,241 @@ +#include <precomp.h> +#include "xuiframe.h" +#include <tataki/canvas/ifc_canvas.h> +#include <api/script/scriptguid.h> + +const wchar_t ScriptFrameXuiObjectStr[] = L"Wasabi:Frame"; // This is the xml tag +char ScriptFrameXuiSvcName[] = "Wasabi:ScriptFrame xui object"; +XMLParamPair ScriptFrame::params[] = { + {SCRIPTFRAME_SETORIENTATION, L"ORIENTATION"}, + {SCRIPTFRAME_SETLEFT, L"LEFT"}, // TOP/BOTTOM IS ALIAS FOR LEFT/RIGHT + {SCRIPTFRAME_SETLEFT, L"TOP"}, + {SCRIPTFRAME_SETRIGHT, L"RIGHT"}, + {SCRIPTFRAME_SETRIGHT, L"BOTTOM"}, + {SCRIPTFRAME_SETFROM, L"FROM"}, + {SCRIPTFRAME_SETWIDTH, L"WIDTH"}, + {SCRIPTFRAME_SETWIDTH, L"HEIGHT"}, // HEIGHT IS AN ALIAS FOR WIDTH + {SCRIPTFRAME_SETRESIZEABLE, L"RESIZABLE"}, + {SCRIPTFRAME_SETMAXWIDTH, L"MAXWIDTH"}, + {SCRIPTFRAME_SETMAXWIDTH, L"MAXHEIGHT"}, //ALIAS + {SCRIPTFRAME_SETMINWIDTH, L"MINWIDTH"}, + {SCRIPTFRAME_SETMINWIDTH, L"MINHEIGHT"}, //ALIAS + {SCRIPTFRAME_SETV_BITMAP, L"VBITMAP"}, // to override wasabi.framewnd.verticaldivider + {SCRIPTFRAME_SETV_GRABBER, L"VGRABBER"}, // to override wasabi.framewnd.verticalgrabber +}; + +ScriptFrame::ScriptFrame() +{ + getScriptObject()->vcpu_setInterface(scriptFrameGuid, (void *)static_cast<ScriptFrame *>(this)); + getScriptObject()->vcpu_setClassName(L"Frame"); + getScriptObject()->vcpu_setController(frameController); + + setVirtual(1); + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); + + orientation = DIVIDER_VERTICAL; + from = SDP_FROMLEFT; + resizable = 1; + width = 128; + rootwndleft = rootwndright = NULL; +} + +void ScriptFrame::CreateXMLParameters(int master_handle) +{ + //SCRIPTFRAME_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +ScriptFrame::~ScriptFrame() { + if (rootwndright) { + WASABI_API_SKIN->group_destroy(rootwndright); + rootwndright = NULL; + } + if (rootwndleft) { + WASABI_API_SKIN->group_destroy(rootwndleft); + rootwndleft = NULL; + } +} + +// XuiObject automatically calls this back for all parameters registered using addParam +// encountered in the xml source +int ScriptFrame::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + + if (xuihandle != myxuihandle) + return SCRIPTFRAME_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) { + case SCRIPTFRAME_SETORIENTATION: setOrientation(value); break; + case SCRIPTFRAME_SETLEFT: setLeft(value); break; + case SCRIPTFRAME_SETRIGHT: setRight(value); break; + case SCRIPTFRAME_SETFROM: setFrom(value); break; + case SCRIPTFRAME_SETWIDTH: setWidth(value); break; + case SCRIPTFRAME_SETRESIZEABLE: setResize(value); break; + case SCRIPTFRAME_SETMAXWIDTH: setMaxWidth((!_wcsicmp(value, L"null")) ? 0 : WTOI(value)); break; + case SCRIPTFRAME_SETMINWIDTH: setMinWidth(WTOI(value)); break; + case SCRIPTFRAME_SETSNAP: setSnap(WTOI(value)); break; + case SCRIPTFRAME_SETV_BITMAP: + Set_v_bitmap(value); + break; + case SCRIPTFRAME_SETV_GRABBER: + Set_v_grabber(value); + break; + + default: + return 0; + } + return 1; +} + +int ScriptFrame::onInit() +{ + + if (!left.isempty()) rootwndleft = WASABI_API_SKIN->group_create(left); + if (!right.isempty()) rootwndright = WASABI_API_SKIN->group_create(right); + +/* GuiObject *gl = rootwndleft ? static_cast<GuiObject *>(rootwndleft->getInterface(guiObjectGuid)) : NULL; + GuiObject *gr = rootwndright ? static_cast<GuiObject *>(rootwndleft->getInterface(guiObjectGuid)) : NULL; + + if (gl) gl->guiobject_setParentGroup(getGuiObject()->guiobject_getParentGroup()); + if (gr) gr->guiobject_setParentGroup(getGuiObject()->guiobject_getParentGroup());*/ + + if (rootwndleft) rootwndleft->setParent(this); + if (rootwndright) rootwndright->setParent(this); + + setChildrenRootWnd(rootwndleft, rootwndright); + setDividerType(static_cast<FrameWndDividerType>(orientation)); + setDividerPos(from, width); + setResizeable(resizable); + + + SCRIPTFRAME_PARENT::onInit(); + return 1; +} + +void ScriptFrame::onResizeChildren(RECT leftr, RECT rightr) { +/* if (rootwndleft) rootwndleft->invalidate(); + if (rootwndright) rootwndright->invalidate();*/ + invalidate(); +} + +void ScriptFrame::setOrientation(const wchar_t *orient) { + if (!WCSICMP(orient, L"v") || !WCSICMP(orient, L"vertical")) + orientation = DIVIDER_VERTICAL; + if (!WCSICMP(orient, L"h") || !WCSICMP(orient, L"horizontal")) + orientation = DIVIDER_HORIZONTAL; +} + +void ScriptFrame::setLeft(const wchar_t *groupname) { + left = groupname; +} + +void ScriptFrame::setRight(const wchar_t *groupname) { + right = groupname; +} + +void ScriptFrame::setFrom(const wchar_t *f) { + if (!WCSICMP(f, L"l") || !WCSICMP(f, L"left") || !WCSICMP(f, L"t") || !WCSICMP(f, L"top")) + from = SDP_FROMLEFT; + if (!WCSICMP(f, L"r") || !WCSICMP(f, L"right") || !WCSICMP(f, L"b") || !WCSICMP(f, L"bottom")) + from = SDP_FROMRIGHT; +} + +void ScriptFrame::setWidth(const wchar_t *w) { + width = WTOI(w); +} + +void ScriptFrame::setResize(const wchar_t *w) { + resizable = WTOI(w); + if (isInited()) + setResizeable(resizable); +} + +FrameScriptController _frameController; +FrameScriptController *frameController = &_frameController; + +// -- Functions table ------------------------------------- +function_descriptor_struct FrameScriptController::exportedFunction[] = +{ + {L"setPosition", 1, (void*)ScriptFrame::script_vcpu_setPosition }, + {L"getPosition", 0, (void*)ScriptFrame::script_vcpu_getPosition }, +}; +// -------------------------------------------------------- + +const wchar_t *FrameScriptController::getClassName() +{ + return L"Frame"; +} + +const wchar_t *FrameScriptController::getAncestorClassName() +{ + return L"GuiObject"; +} + +ScriptObject *FrameScriptController::instantiate() +{ + ScriptFrame *t = new ScriptFrame; + ASSERT(t != NULL); + return t->getScriptObject(); +} + +void FrameScriptController::destroy(ScriptObject *o) +{ + ScriptFrame *t = static_cast<ScriptFrame *>(o->vcpu_getInterface(scriptFrameGuid)); + ASSERT(t != NULL); + delete t; +} + +void *FrameScriptController::encapsulate(ScriptObject *o) +{ + return NULL; // no encapsulation for Wasabi:Frame yet +} + +void FrameScriptController::deencapsulate(void *o) +{} + +int FrameScriptController::getNumFunctions() +{ + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *FrameScriptController::getExportedFunctions() +{ + return exportedFunction; +} + +GUID FrameScriptController::getClassGuid() +{ + return scriptFrameGuid; +} + +const wchar_t *ScriptFrame::vcpu_getClassName() +{ + return L"Frame"; +} + +scriptVar ScriptFrame::script_vcpu_setPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t) +{ + SCRIPT_FUNCTION_INIT + ASSERT(t.type == SCRIPT_INT); + ScriptFrame *fr = static_cast<ScriptFrame *>(o->vcpu_getInterface(scriptFrameGuid)); + if (fr) + fr->setDividerPosNoCfg(fr->from, ::GET_SCRIPT_INT(t)); + + RETURN_SCRIPT_VOID; +} + +scriptVar ScriptFrame::script_vcpu_getPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptFrame *fr = static_cast<ScriptFrame *>(o->vcpu_getInterface(scriptFrameGuid)); + if (fr) + { + int pos, from; + fr->getDividerPos(&from, &pos); + return MAKE_SCRIPT_INT(pos); + } + return MAKE_SCRIPT_INT(0); +} diff --git a/Src/Wasabi/api/skin/widgets/xuiframe.h b/Src/Wasabi/api/skin/widgets/xuiframe.h new file mode 100644 index 00000000..0a16e4b4 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuiframe.h @@ -0,0 +1,97 @@ +#ifndef __XUIFRAME_H +#define __XUIFRAME_H + +#include <api/wnd/wndclass/framewnd.h> +#include <api/script/objects/guiobj.h> + +#define SCRIPTFRAME_PARENT FrameWnd + +/* --------- Script Object for ScriptFrame --------- */ +class FrameScriptController : public GuiObjectScriptController +{ + public: + + virtual const wchar_t *getClassName(); + virtual const wchar_t *getAncestorClassName(); + virtual ScriptObjectController *getAncestorController() { return guiController; } + 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); + + private: + + static function_descriptor_struct exportedFunction[]; + +}; + +extern FrameScriptController *frameController; + +// ----------------------------------------------------------------------- +// Your wnd object class + +class ScriptFrame : public SCRIPTFRAME_PARENT { + + public: + + ScriptFrame(); + virtual ~ScriptFrame(); + + virtual int onInit(); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + void setOrientation(const wchar_t *elementname); + void setLeft(const wchar_t *groupname); + void setRight(const wchar_t *groupname); + void setFrom(const wchar_t *from); + void setWidth(const wchar_t *w); + void setResize(const wchar_t *r); + + virtual int wantRenderBaseTexture() { return 0; } + + void onResizeChildren(RECT leftr, RECT rightr); + + virtual const wchar_t *vcpu_getClassName(); + virtual ScriptObjectController *vcpu_getController() { return frameController; } +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + + // a list of IDs for our xml attributes, we use them in addParam() in the constructor + enum { + SCRIPTFRAME_SETORIENTATION = 0, + SCRIPTFRAME_SETLEFT, + SCRIPTFRAME_SETRIGHT, + SCRIPTFRAME_SETFROM, + SCRIPTFRAME_SETWIDTH, + SCRIPTFRAME_SETRESIZEABLE, + SCRIPTFRAME_SETMAXWIDTH, + SCRIPTFRAME_SETMINWIDTH, + SCRIPTFRAME_SETSNAP, + SCRIPTFRAME_SETV_BITMAP, + SCRIPTFRAME_SETV_GRABBER, + }; + static XMLParamPair params[]; + int myxuihandle; + StringW left, right; + ifc_window *rootwndleft, *rootwndright; + int from, orientation, resizable; + int width; + public: + static scriptVar script_vcpu_setPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t); + static scriptVar script_vcpu_getPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); +}; + + +// ----------------------------------------------------------------------- +// This defines the svc_xuiObject that exposes your wnd object + +extern const wchar_t ScriptFrameXuiObjectStr[]; +extern char ScriptFrameXuiSvcName[]; +class FrameXuiSvc : public XuiObjectSvc<ScriptFrame, ScriptFrameXuiObjectStr, ScriptFrameXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuigradientwnd.cpp b/Src/Wasabi/api/skin/widgets/xuigradientwnd.cpp new file mode 100644 index 00000000..141e6e48 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuigradientwnd.cpp @@ -0,0 +1,66 @@ +#include <precomp.h> + +#include "xuigradientwnd.h" +#ifndef _WASABIRUNTIME + +BEGIN_SERVICES(XuiGradient_Svc); +DECLARE_SERVICE(XuiObjectCreator<GradientWndXuiSvc>); +END_SERVICES(XuiGradient_Svc, _XuiGradient_Svc); + +#ifdef _X86_ +extern "C" { int _link_GradientXuiSvc; } +#else +extern "C" { int __link_GradientXuiSvc; } +#endif + +#endif + + +enum { P_X1, P_Y1, P_X2, P_Y2, P_POINTS, P_GG }; + +XMLParamPair XuiGradientWnd::params[] = { + {P_X1, L"GRADIENT_X1"}, + {P_Y1, L"GRADIENT_Y1"}, + {P_X2, L"GRADIENT_X2"}, + {P_Y2, L"GRADIENT_Y2"}, + {P_POINTS, L"POINTS"}, + {P_GG, L"GAMMAGROUP"}, + }; +XuiGradientWnd::XuiGradientWnd() +{ + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); +} + +void XuiGradientWnd::CreateXMLParameters(int master_handle) +{ + //XUIGRADIENTWND_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + { + if (params[i].id == P_GG) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); + else + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_REQUIRED); + } +} + +int XuiGradientWnd::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) +{ + if (xuihandle != myxuihandle) + return XUIGRADIENTWND_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + switch (xmlattributeid) + { + case P_X1: setX1((float)WTOF(value)); break; + case P_Y1: setY1((float)WTOF(value)); break; + case P_X2: setX2((float)WTOF(value)); break; + case P_Y2: setY2((float)WTOF(value)); break; + case P_POINTS: setPoints(value); break; + case P_GG: setGammaGroup(value); break; + default: + return 0; + } + invalidate(); // what the hell + return 1; +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/xuigradientwnd.h b/Src/Wasabi/api/skin/widgets/xuigradientwnd.h new file mode 100644 index 00000000..36aaed84 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuigradientwnd.h @@ -0,0 +1,26 @@ +#ifndef _XUIGRADIENTWND_H +#define _XUIGRADIENTWND_H + +#include <api/wnd/wndclass/gradientwnd.h> + +#define XUIGRADIENTWND_PARENT GradientWnd +class XuiGradientWnd : public XUIGRADIENTWND_PARENT { +public: + static const wchar_t *xuiobject_getXmlTag() { return L"Gradient"; } + static const char *xuiobject_getServiceName() { return "Gradient XuiObject"; } + XuiGradientWnd(); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + void parsePoints(const wchar_t *pointlist); +protected: + void CreateXMLParameters(int master_handle); +private: + int myxuihandle; + static XMLParamPair params[]; + +}; + +class GradientWndXuiSvc : public XuiObjectSvc2<XuiGradientWnd> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuigrid.cpp b/Src/Wasabi/api/skin/widgets/xuigrid.cpp new file mode 100644 index 00000000..4961a0ad --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuigrid.cpp @@ -0,0 +1,297 @@ +#include <precomp.h> +#include "xuigrid.h" +#include <tataki/canvas/canvas.h> +// ----------------------------------------------------------------------- + +const wchar_t GridXuiObjectStr[] = L"Grid"; // xml tag +char GridXuiSvcName[] = "Grid xui object"; + +XMLParamPair Grid::params[] = { + { GRID_SETTOPLEFT, L"TOPLEFT"}, + { GRID_SETTOP, L"TOP"}, + { GRID_SETTOPRIGHT, L"TOPRIGHT"}, + { GRID_SETLEFT, L"LEFT"}, + { GRID_SETMIDDLE, L"MIDDLE"}, + { GRID_SETRIGHT, L"RIGHT"}, + { GRID_SETBOTTOMLEFT, L"BOTTOMLEFT"}, + { GRID_SETBOTTOM, L"BOTTOM"}, + { GRID_SETBOTTOMRIGHT, L"BOTTOMRIGHT"}, +}; +// ----------------------------------------------------------------------- +Grid::Grid() { + setRectRgn(1); + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); + +} + +void Grid::CreateXMLParameters(int master_handle) +{ + //GRID_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +// ----------------------------------------------------------------------- +Grid::~Grid() { +} + +// ----------------------------------------------------------------------- +int Grid::onInit() { + GRID_PARENT::onInit(); + doPaint(NULL, 1); // computes the region + invalidateWindowRegion(); + return 1; +} + +// ----------------------------------------------------------------------- +int Grid::onResize() { + GRID_PARENT::onResize(); + doPaint(NULL, 1); + invalidateWindowRegion(); + return 1; +} + +// ----------------------------------------------------------------------- +int Grid::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return GRID_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) { + case GRID_SETTOPLEFT: + case GRID_SETTOP: + case GRID_SETTOPRIGHT: + case GRID_SETLEFT: + case GRID_SETMIDDLE: + case GRID_SETRIGHT: + case GRID_SETBOTTOMLEFT: + case GRID_SETBOTTOM: + case GRID_SETBOTTOMRIGHT: + setGridImage(value, xmlattributeid); + break; + default: + return 0; + } + return 1; +} + +// ----------------------------------------------------------------------- +void Grid::setGridImage(const wchar_t *elementname, int what) { + switch (what) { + case GRID_SETTOPLEFT: topleft = elementname; break; + case GRID_SETTOP: top = elementname; break; + case GRID_SETTOPRIGHT: topright = elementname; break; + case GRID_SETLEFT: left = elementname; break; + case GRID_SETMIDDLE: middle = elementname; break; + case GRID_SETRIGHT: right = elementname; break; + case GRID_SETBOTTOMLEFT: bottomleft = elementname; break; + case GRID_SETBOTTOM: bottom = elementname; break; + case GRID_SETBOTTOMRIGHT: bottomright = elementname; break; + default: return; + } + if (isInited()) invalidate(); +} + +// ----------------------------------------------------------------------- +int Grid::onPaint(Canvas *canvas) { + GRID_PARENT::onPaint(canvas); + + doPaint(canvas, 0); + + return 1; +} + + +void Grid::doPaint(Canvas *canvas, int dorgn) { + + RECT r; + getGridRect(&r); + + SkinBitmap *left_bm = left.getBitmap(); + SkinBitmap *middle_bm = middle.getBitmap(); + SkinBitmap *right_bm = right.getBitmap(); + + SkinBitmap *topleft_bm = topleft.getBitmap(); + SkinBitmap *top_bm = top.getBitmap(); + SkinBitmap *topright_bm = topright.getBitmap(); + + SkinBitmap *bottomleft_bm = bottomleft.getBitmap(); + SkinBitmap *bottom_bm = bottom.getBitmap(); + SkinBitmap *bottomright_bm = bottomright.getBitmap(); + + int left_w = left_bm ? left_bm->getWidth() : 0; + int left_h = left_bm ? left_bm->getHeight() : 0; + int top_h = top_bm ? top_bm->getHeight() : 0; + int top_w = top_bm ? top_bm->getWidth() : 0; + int topleft_h = topleft_bm ? topleft_bm->getHeight() : 0; + int topright_h = topright_bm ? topright_bm->getHeight() : 0; + int topleft_w = topleft_bm ? topleft_bm->getWidth() : 0; + int topright_w = topright_bm ? topright_bm->getWidth() : 0; + int right_w = right_bm ? right_bm->getWidth() : 0; + int right_h = right_bm ? right_bm->getHeight() : 0; + int bottom_h = bottom_bm ? bottom_bm->getHeight() : 0; + int bottom_w = bottom_bm ? bottom_bm->getWidth() : 0; + int bottomleft_h = bottomleft_bm ? bottom_bm->getHeight() : 0; + int bottomright_h = bottomright_bm ? bottom_bm->getHeight() : 0; + int bottomleft_w = bottomleft_bm ? bottomleft_bm->getWidth() : 0; + int bottomright_w = bottomright_bm ? bottomright_bm->getWidth() : 0; + int middle_w = middle_bm ? middle_bm->getWidth() : 0; + int middle_h = middle_bm ? middle_bm->getHeight() : 0; + + RECT cell; + + if (dorgn) reg.empty(); + + int paintingAlpha = 0; + if (canvas) + paintingAlpha = getPaintingAlpha(); + + // topleft + if (topleft_bm) { + cell.left = r.left; + cell.top = r.top; + cell.right = cell.left + topleft_w; + cell.bottom = r.top + topleft_h; + + if (canvas) topleft_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha); + if (dorgn) { + RegionI _r(topleft); + _r.offset(cell.left-r.left, cell.top-r.top); + reg.addRegion(&_r); + } + } + + // top + if (top_bm) { + cell.left = r.left + topleft_w; + cell.top = r.top; + cell.right = r.right - topright_w; + cell.bottom = r.top + top_h; + + if (canvas) top_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha); + if (dorgn && cell.left != cell.right) { + RegionI _r(top); + _r.scale((double)(cell.right-cell.left) / top_w, 1); + _r.offset(cell.left-r.left, cell.top-r.top); + reg.addRegion(&_r); + } + } + + // topright + + if (topright_bm) { + cell.left = r.right - topright_w; + cell.top = r.top; + cell.right = r.right; + cell.bottom = r.top + topright_h; + + if (canvas) topright_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha); + if (dorgn) { + RegionI _r(topright); + _r.offset(cell.left-r.left, cell.top-r.top); + reg.addRegion(&_r); + } + } + + // left + + if (left_bm) { + cell.left = r.left; + cell.top = r.top + topleft_h; + cell.right = r.left + left_w; + cell.bottom = r.bottom - bottomleft_h; + + if (canvas) left_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha); + if (dorgn && cell.bottom != cell.top) { + RegionI _r(left); + _r.scale(1, (double)(cell.bottom-cell.top) / left_h); + _r.offset(cell.left-r.left, cell.top-r.top); + reg.addRegion(&_r); + } + } + + // middle + + if (middle_bm) { + cell.left = r.left + left_w; + cell.top = r.top + top_h; + cell.right = r.right - right_w; + cell.bottom = r.bottom - bottom_h; + + if (canvas) middle_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha); + if (dorgn && cell.left != cell.right && cell.bottom != cell.top) { + RegionI _r(middle); + _r.scale((double)(cell.right-cell.left) / middle_w, (double)(cell.bottom-cell.top) / middle_h); + _r.offset(cell.left-r.left, cell.top-r.top); + reg.addRegion(&_r); + } + } + + // right + + if (right_bm) { + cell.left = r.right - right_w; + cell.top = r.top + top_h; + cell.right = r.right; + cell.bottom = r.bottom - bottomright_h; + + if (canvas) right_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha); + if (dorgn && cell.bottom != cell.top) { + RegionI _r(right); + _r.scale(1, (double)(cell.bottom-cell.top) / right_h); + _r.offset(cell.left-r.left, cell.top-r.top); + reg.addRegion(&_r); + } + } + + // bottomleft + + if (bottomleft_bm) { + cell.left = r.left; + cell.top = r.bottom - bottomleft_h; + cell.right = r.left + bottomleft_w; + cell.bottom = r.bottom; + + if (canvas) bottomleft_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha); + if (dorgn) { + RegionI _r(bottomleft); + _r.offset(cell.left-r.left, cell.top-r.top); + reg.addRegion(&_r); + } + } + + // bottom + + if (bottom_bm) { + cell.left = r.left + bottomleft_w; + cell.top = r.bottom - bottom_h; + cell.right = r.right - bottomright_w; + cell.bottom = r.bottom; + + if (canvas) bottom_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha); + if (dorgn && cell.right != cell.left) { + RegionI _r(bottom); + _r.scale((double)(cell.right-cell.left) / bottom_w, 1); + _r.offset(cell.left-r.left, cell.top-r.top); + reg.addRegion(&_r); + } + } + + // bottomright + + if (bottomright_bm) { + cell.left = r.right - bottomright_w; + cell.top = r.bottom - bottomright_h; + cell.right = r.right; + cell.bottom = r.bottom; + + if (canvas) bottomright_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha); + if (dorgn) { + RegionI _r(bottomright); + _r.offset(cell.left-r.left, cell.top-r.top); + reg.addRegion(&_r); + } + } +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/xuigrid.h b/Src/Wasabi/api/skin/widgets/xuigrid.h new file mode 100644 index 00000000..084c7d4c --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuigrid.h @@ -0,0 +1,59 @@ +#ifndef __GRID_H +#define __GRID_H + +#include <api/wnd/wndclass/guiobjwnd.h> +#include <tataki/bitmap/autobitmap.h> +#include <tataki/region/region.h> + +#define GRID_PARENT GuiObjectWnd + +// ----------------------------------------------------------------------- +class Grid : public GRID_PARENT { + + public: + + Grid(); + virtual ~Grid(); + + virtual int onPaint(Canvas *c); + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + void setGridImage(const wchar_t *elementname, int what); + virtual void getGridRect(RECT *r) { getClientRect(r); } + + virtual api_region *getRegion() { return ® } + virtual int onInit(); + virtual int onResize(); +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + void doPaint(Canvas *canvas, int dorgn=0); + + enum { + GRID_SETTOPLEFT= 0, + GRID_SETTOP, + GRID_SETTOPRIGHT, + GRID_SETLEFT, + GRID_SETMIDDLE, + GRID_SETRIGHT, + GRID_SETBOTTOMLEFT, + GRID_SETBOTTOM, + GRID_SETBOTTOMRIGHT, + }; + static XMLParamPair params[]; + + int myxuihandle; + + AutoSkinBitmap topleft, top, topright; + AutoSkinBitmap left, middle, right; + AutoSkinBitmap bottomleft, bottom, bottomright; + RegionI reg; +}; + + +// ----------------------------------------------------------------------- +extern const wchar_t GridXuiObjectStr[]; +extern char GridXuiSvcName[]; +class GridXuiSvc : public XuiObjectSvc<Grid, GridXuiObjectStr, GridXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuigroupxfade.cpp b/Src/Wasabi/api/skin/widgets/xuigroupxfade.cpp new file mode 100644 index 00000000..c5c7e72b --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuigroupxfade.cpp @@ -0,0 +1,120 @@ +#include <precomp.h> +#include "xuigroupxfade.h" + + +#ifndef _WASABIRUNTIME + +BEGIN_SERVICES(GroupXFade_Svc); +DECLARE_SERVICE(XuiObjectCreator<GroupXFadeXuiSvc>); +END_SERVICES(GroupXFade_Svc, _GroupXFade_Svc); + +#ifdef _X86_ +extern "C" { int _link_GroupXFadeXuiSvc; } +#else +extern "C" { int __link_GroupXFadeXuiSvc; } +#endif + +#endif + + + +XMLParamPair GroupXFade::params[] = { + {GROUPXFADE_SETGROUP, L"GROUP"}, + {GROUPXFADE_SETGROUP, L"GROUPID"}, + {GROUPXFADE_SETSPEED, L"SPEED"}, + }; +GroupXFade::GroupXFade() { + child[0] = child[1] = NULL; + curchild = 0; + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); + speed = 0.25; +} + +void GroupXFade::CreateXMLParameters(int master_handle) +{ + //GROUPXFADE_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); + +} + +GroupXFade::~GroupXFade() { + if (child[0]) { + ifc_window *w = child[0]->guiobject_getRootWnd(); + if (w) WASABI_API_SKIN->group_destroy(w); + } + if (child[1]) { + ifc_window *w = child[1]->guiobject_getRootWnd(); + if (w) WASABI_API_SKIN->group_destroy(w); + } +} + +int GroupXFade::onInit() { + GROUPXFADE_PARENT::onInit(); + return 1; +} + +int GroupXFade::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return GROUPXFADE_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch(xmlattributeid) { + case GROUPXFADE_SETGROUP: + setNewGroup(value); + return 1; + case GROUPXFADE_SETSPEED: + speed = WTOF(value); + return 1; + default: + return 0; + } +} + +int GroupXFade::onResize() { + GROUPXFADE_PARENT::onResize(); + RECT r; + getClientRect(&r); + if (child[curchild]) + child[curchild]->guiobject_getRootWnd()->resize(r.left, r.top, r.right-r.left, r.bottom-r.top); + int nextchild = curchild == 1 ? 0 : 1; + if (child[nextchild]) + child[nextchild]->guiobject_getRootWnd()->resize(r.left, r.top, r.right-r.left, r.bottom-r.top); + return 1; +} + +void GroupXFade::setNewGroup(const wchar_t *grp) { + if (child[curchild] && id[curchild].iscaseequal(grp)) return; + if (child[curchild]) { + child[curchild]->guiobject_setTargetA(0); + child[curchild]->guiobject_setTargetSpeed((float)speed); + child[curchild]->guiobject_gotoTarget(); + } + int nextchild = curchild == 1 ? 0 : 1; + if (child[nextchild]) { + ifc_window *w = child[nextchild]->guiobject_getRootWnd(); + WASABI_API_SKIN->group_destroy(w); + child[nextchild] = NULL; + } + if (grp && *grp) { + ifc_window *w = WASABI_API_SKIN->group_create(grp); + if (w) { + child[nextchild] = w->getGuiObject(); + w->setParent(this); + w->setStartHidden(1); + RECT r; + getClientRect(&r); + w->setAlpha(0); + w->init(this); + w->setVisible(1); + w->resize(r.left, r.top, r.right-r.left, r.bottom-r.top); + child[nextchild]->guiobject_setTargetA(255); + child[nextchild]->guiobject_setTargetSpeed((float)speed); + child[nextchild]->guiobject_gotoTarget(); + id[nextchild] = grp; + } + } + curchild = nextchild; +} diff --git a/Src/Wasabi/api/skin/widgets/xuigroupxfade.h b/Src/Wasabi/api/skin/widgets/xuigroupxfade.h new file mode 100644 index 00000000..50154ec5 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuigroupxfade.h @@ -0,0 +1,40 @@ +#ifndef _XUIGROUPXFADE_H +#define _XUIGROUPXFADE_H + +#include <api/wnd/wndclass/guiobjwnd.h> + +#define GROUPXFADE_PARENT GuiObjectWnd +class GroupXFade : public GROUPXFADE_PARENT { +public: + static const wchar_t *xuiobject_getXmlTag() { return L"GroupXFade"; } + static const char *xuiobject_getServiceName() { return "GroupXFade XuiObject"; } + GroupXFade(); + virtual ~GroupXFade(); + + virtual int onInit(); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + virtual int onResize(); + + enum { + GROUPXFADE_SETGROUP, + GROUPXFADE_SETSPEED, + }; + + void setNewGroup(const wchar_t *grp); +protected: + /*static */void CreateXMLParameters(int master_handle); +private: + int myxuihandle; + GuiObject *child[2]; + StringW id[2]; + int curchild; + double speed; + + static XMLParamPair params[]; +}; + + +class GroupXFadeXuiSvc : public XuiObjectSvc2<GroupXFade> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuihideobject.cpp b/Src/Wasabi/api/skin/widgets/xuihideobject.cpp new file mode 100644 index 00000000..76ff6b6d --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuihideobject.cpp @@ -0,0 +1,50 @@ +#include <precomp.h> +#include "xuihideobject.h" +// ----------------------------------------------------------------------- +const wchar_t HideObjectXuiObjectStr[] = L"HideObject"; // This is the xml tag +char HideObjectXuiSvcName[] = "HideObject xui object"; + +XMLParamPair HideObject::params[] = { + { HIDEOBJECT_HIDE, L"HIDE"}, +}; +// ----------------------------------------------------------------------- +HideObject::HideObject() : HIDEOBJECT_PARENT() +{ + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); +} + +void HideObject::CreateXMLParameters(int master_handle) +{ + //HIDEOBJECT_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + + +// ----------------------------------------------------------------------- +int HideObject::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return HIDEOBJECT_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) { + case HIDEOBJECT_HIDE: + actuator_setTarget(value); + break; + default: + return 0; + } + return 1; +} + +// ----------------------------------------------------------------------- +void HideObject::actuator_onPerform(GuiObject *target) { // guaranteed non NULL + ifc_window *w = target->guiobject_getRootWnd(); + if (w != NULL) { + w->setVisible(0); + } +} + + diff --git a/Src/Wasabi/api/skin/widgets/xuihideobject.h b/Src/Wasabi/api/skin/widgets/xuihideobject.h new file mode 100644 index 00000000..b58a04da --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuihideobject.h @@ -0,0 +1,40 @@ +#ifndef __HIDEOBJECT_H +#define __HIDEOBJECT_H + +#include <api/skin/objectactuator.h> + +#define HIDEOBJECT_PARENT ObjectActuator + +extern const wchar_t HideObjectXuiObjectStr[]; +extern char HideObjectXuiSvcName[]; +// ----------------------------------------------------------------------- +// Your wnd object class +class HideObject: public HIDEOBJECT_PARENT { + + public: + + HideObject(); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + virtual void actuator_onPerform(GuiObject *target); + virtual const wchar_t *getActuatorTag() { return HideObjectXuiObjectStr; } // for error msgs purposes +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + + int myxuihandle; + + enum { + HIDEOBJECT_HIDE= 0, + }; + static XMLParamPair params[]; + +}; + +// ----------------------------------------------------------------------- +// This defines the svc_xuiObject that exposes your wnd object + +class HideObjectXuiSvc : public XuiObjectSvc<HideObject, HideObjectXuiObjectStr, HideObjectXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuihistoryedit.cpp b/Src/Wasabi/api/skin/widgets/xuihistoryedit.cpp new file mode 100644 index 00000000..04a13e90 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuihistoryedit.cpp @@ -0,0 +1,7 @@ +#include <precomp.h> +#include "xuihistoryedit.h" + +// ----------------------------------------------------------------------- +const wchar_t HistoryEditXuiObjectStr[] = L"Wasabi:HistoryEditBox"; +char HistoryEditXuiSvcName[] = "Wasabi:HistoryEditBox xui object"; + diff --git a/Src/Wasabi/api/skin/widgets/xuihistoryedit.h b/Src/Wasabi/api/skin/widgets/xuihistoryedit.h new file mode 100644 index 00000000..be15d407 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuihistoryedit.h @@ -0,0 +1,10 @@ +#ifndef __XUIHISTORYEDITBOX_H +#define __XUIHISTORYEDITBOX_H + +#include <api/skin/widgets/historyeditbox.h> + +extern const wchar_t HistoryEditXuiObjectStr[]; +extern char HistoryEditXuiSvcName[]; +class HistoryEditXuiSvc : public XuiObjectSvc<HistoryEditBox, HistoryEditXuiObjectStr, HistoryEditXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuilist.cpp b/Src/Wasabi/api/skin/widgets/xuilist.cpp new file mode 100644 index 00000000..c8233409 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuilist.cpp @@ -0,0 +1,1734 @@ +#include <precomp.h> +#include "xuilist.h" + +#include <api/service/svc_enum.h> +#include <bfc/parse/paramparser.h> +#include <api/script/scriptguid.h> +#include <api/skin/feeds/TextFeedEnum.h> + +// The temporary memory buffer to hold our string returns. +StringW GuiListScriptController::staticStr; + + +// ----------------------------------------------------------------------- +const wchar_t ScriptListXuiObjectStr[] = L"List"; // This is the xml tag +char ScriptListXuiSvcName[] = "List xui object"; + + +XMLParamPair ScriptList::params[] = { + {SCRIPTLIST_SETITEMS, L"ITEMS"}, + {SCRIPTLIST_SETMULTISELECT, L"MULTISELECT"}, + {SCRIPTLIST_SETAUTODESELECT, L"AUTODESELECT"}, + {SCRIPTLIST_SELECT, L"SELECT"}, + {SCRIPTLIST_FEED, L"FEED"}, + {SCRIPTLIST_HOVERSELECT, L"HOVERSELECT"}, + {SCRIPTLIST_SORT, L"SORT"}, + {SCRIPTLIST_SELECTONUPDOWN, L"SELECTONUPDOWN"}, + {SCRIPTLIST_NUMCOLUMNS, L"NUMCOLUMNS"}, + {SCRIPTLIST_COLUMNWIDTHS, L"COLUMNWIDTHS"}, + {SCRIPTLIST_COLUMNLABELS, L"COLUMNLABELS"}, + }; +// ----------------------------------------------------------------------- +ScriptList::ScriptList() +{ + getScriptObject()->vcpu_setInterface(guilistGuid, (void *)static_cast<ScriptList *>(this)); + getScriptObject()->vcpu_setClassName(L"GuiList"); // this is the script class name + getScriptObject()->vcpu_setController(guiListController); + + + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); + setPreventMultipleSelection(1); + setVirtual(0); + feed = NULL; + multiselect = 0; + xmlnumcolumns = -1; + last_numcolumns = 0x80000000; // go ahead and try and be equal to that. + getGuiObject()->guiobject_getScriptObject()->vcpu_setInterface(listGuid, (void *)this); +} + +void ScriptList::CreateXMLParameters(int master_handle) +{ + SCRIPTLIST_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +// ----------------------------------------------------------------------- +ScriptList::~ScriptList() +{ + closeFeed(); +} + +// ----------------------------------------------------------------------- +int ScriptList::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) +{ + if (xuihandle != myxuihandle) + return SCRIPTLIST_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) + { + case SCRIPTLIST_SETITEMS: + items = value; + fillFromParams(); +#ifdef WASABI_COMPILE_CONFIG + if (getGuiObject()->guiobject_hasCfgAttrib()) + selectFromConfig(); +#endif + break; + case SCRIPTLIST_SETMULTISELECT: + multiselect = WTOI(value); + break; + case SCRIPTLIST_SETAUTODESELECT: + setWantAutoDeselect(WTOI(value)); + break; + case SCRIPTLIST_SELECT: + { + int i = selectEntry(value); + if (i != -1) + ensureItemVisible(i); + else + selectFirstEntry(); + break; + } + case SCRIPTLIST_FEED: + { + closeFeed(); + openFeed(value); + break; + } + case SCRIPTLIST_HOVERSELECT: + { + setHoverSelect(WTOI(value)); + break; + } + case SCRIPTLIST_SORT: + { + setAutoSort(WTOB(value)); + break; + } + case SCRIPTLIST_SELECTONUPDOWN: + { + setSelectOnUpDown(WTOI(value)); + break; + } + case SCRIPTLIST_NUMCOLUMNS: + { + xmlnumcolumns = WTOI(value); + setNumColumns(); + break; + } + case SCRIPTLIST_COLUMNWIDTHS: + { + columnwidths = value; + setColumnWidths(); + break; + } + case SCRIPTLIST_COLUMNLABELS: + { + columnlabels = value; + setColumnLabels(); + break; + } + default: + return 0; + } + return 1; +} + +// ----------------------------------------------------------------------- +int ScriptList::onInit() +{ + SCRIPTLIST_PARENT::onInit(); + + last_numcolumns = 0x80000000; + setNumColumns(); // Sets widths and labels if necessary + + setPreventMultipleSelection(!multiselect); + + // fillFromParams(); // done by setNumColumns(); + return 1; +} + +/* + Moved to script-oriented section +// ----------------------------------------------------------------------- +void ScriptList::onDoubleClick(int itemnum) { +#ifdef WASABI_COMPILE_CONFIG + saveToConfig(); +#endif +} +*/ + +/* + Moved to script-oriented section +// ----------------------------------------------------------------------- +void ScriptList::onItemSelection(int itemnum, int selected) { + SCRIPTLIST_PARENT::onItemSelection(itemnum, selected); +#ifdef WASABI_COMPILE_CONFIG + saveToConfig(); +#endif +} +*/ + + +// ----------------------------------------------------------------------- +int ScriptList::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) +{ + SCRIPTLIST_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source); + if (!_wcsicmp(action, L"select_all")) + { + selectAll(0); +#ifdef WASABI_COMPILE_CONFIG + saveToConfig(); +#endif + + } + if (!_wcsicmp(action, L"deselect_all")) + { + deselectAll(0); +#ifdef WASABI_COMPILE_CONFIG + saveToConfig(); +#endif + + } + if (!_wcsicmp(action, L"get_selection")) + { + if (source != NULL) + { + StringW res(L""); + for (int i = 0;i < getNumItems();i++) + { + if (getItemSelected(i)) + { + if (!res.isempty()) res += L";"; + res += getSubitemText(i, 0); + } + } + sendAction(source, L"set_selection", res); + } + } + return 1; +} + +void ScriptList::onSetVisible(int i) +{ + SCRIPTLIST_PARENT::onSetVisible(i); +} + +#ifdef WASABI_COMPILE_CONFIG +// ----------------------------------------------------------------------- +int ScriptList::onReloadConfig() +{ + SCRIPTLIST_PARENT::onReloadConfig(); + selectFromConfig(); + return 1; +} + +// ----------------------------------------------------------------------- +void ScriptList::saveToConfig() +{ + StringW res(L""); + for (int i = 0;i < getNumItems();i++) + { + if (getItemSelected(i)) + { + if (!res.isempty()) res += L";"; + res += getSubitemText(i, 0); + } + } + getGuiObject()->guiobject_setCfgString(res); +} + +// ----------------------------------------------------------------------- +void ScriptList::selectFromConfig() +{ + deselectAll(0); + const wchar_t *p = getGuiObject()->guiobject_getCfgString(); + if (p != NULL) + { + ParamParser pp(p); + for (int i = 0;i < pp.getNumItems();i++) + selectEntry(pp.enumItem(i), 0); + } +} +#endif + +// ----------------------------------------------------------------------- +int ScriptList::selectEntry(const wchar_t *e, int cb) +{ + for (int i = 0;i < getNumItems();i++) + { + const wchar_t *si = getSubitemText(i, 0); + if (WCSCASEEQLSAFE(si, e)) + { + setSelected(i, 1, cb); + return i; + } + } + return -1; +} + +// ----------------------------------------------------------------------- +void ScriptList::fillFromParams() +{ + deleteAllItems(); + if (!items.isempty()) + { + ParamParser pp(items); + if (xmlnumcolumns == -1) + { + // OLD WAY + for (int i = 0;i < pp.getNumItems();i++) + addItem(pp.enumItem(i), (LPARAM)NULL); + } + else + { + // NEW WAY + int i, n = pp.getNumItems(); + for (i = 0; i < n; i++) + { + StringW row = pp.enumItem(i); + ParamParser rp(row, L","); + addItem(rp.enumItem(0), (LPARAM)NULL); + int j, m = rp.getNumItems(); + for (j = 1; j < m; j++) + { + setSubItem(i, j, rp.enumItem(j)); + } + } + } + } +} + +// ----------------------------------------------------------------------- +void ScriptList::selectEntries(const wchar_t *entries, int cb) +{ + ParamParser pp(entries); + for (int i = 0;i < pp.getNumItems();i++) + selectEntry(pp.enumItem(i), cb); +} + +// ----------------------------------------------------------------------- +void ScriptList::setColumnWidths() +{ + // don't bother if there's no value. + if (columnwidths.len()) + { + ParamParser pp(columnwidths); + int i, n = MIN(pp.getNumItems(), getNumColumns()); // whichever is less. + for (i = 0; i < n; i++) + { + ListColumn *column = getColumn(i); + if (column) + { + column->setWidth(WTOI(pp.enumItem(i))); + } + } + } +} + +// ----------------------------------------------------------------------- +void ScriptList::setColumnLabels() +{ + // don't bother if there's no value. + if (columnlabels.len()) + { + ParamParser pp(columnlabels); + int i, n = MIN(pp.getNumItems(), getNumColumns()); // whichever is less. + for (i = 0; i < n; i++) + { + ListColumn *column = getColumn(i); + if (column) + { + column->setLabel(pp.enumItem(i)); + } + } + } +} + +// ----------------------------------------------------------------------- +void ScriptList::setNumColumns() +{ + if (last_numcolumns == xmlnumcolumns) return ; + + if (xmlnumcolumns == -1) + { + // the old way. + insertColumn(new ListColumn(L"", TRUE)); + } + else + { + // delete all columns. + int i, n = getNumColumns(); + for (i = 0; i < n; i++) + { + this->delColumnByPos(0); + } + // create new ones. + ParamParser cw(columnwidths); + int nw = cw.getNumItems(); + ParamParser cl(columnlabels); + int nl = cl.getNumItems(); + for (i = 0; i < xmlnumcolumns; i++) + { + const wchar_t *collabel = L""; + int colwidth = -1; // magic value for "be dynamic" + if (i < nl) + { + collabel = cl.enumItem(i); + } + if (i < nw) + { + colwidth = WTOI(cw.enumItem(i)); + } + ListColumn *pCol = new ListColumn(collabel, (colwidth < 0)); + if (colwidth >= 0) + { + pCol->setWidth(colwidth); + } + insertColumn(pCol); + } + fillFromParams(); + } + + last_numcolumns = xmlnumcolumns; +} + +// ----------------------------------------------------------------------- +void ScriptList::openFeed(const wchar_t *feedid) +{ + if (!_wcsicmp(feedid, last_feed)) return ; + feed = TextFeedEnum(feedid).getFirst(); + if (feed != NULL) + { + viewer_addViewItem(feed->getDependencyPtr()); + } + last_feed = feedid; +} + +// ----------------------------------------------------------------------- +void ScriptList::closeFeed() +{ + if (feed) + { + viewer_delViewItem(feed->getDependencyPtr()); + SvcEnum::release(feed); + } + feed = NULL; + last_feed = L""; +} + +// ----------------------------------------------------------------------- +int ScriptList::viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen) +{ + if (feed && feed->getDependencyPtr() == item) + { + if (event == svc_textFeed::Event_TEXTCHANGE) + { + setXuiParam(myxuihandle, SCRIPTLIST_SETITEMS, L"items", (const wchar_t *)ptr); + return 1; + } + } + return 0; +} + + +// ----------------------------------------------------------------------- +// Callback methods that send hooks into the Script system +void ScriptList::onSelectAll() +{ + SCRIPTLIST_PARENT::onSelectAll(); + GuiListScriptController::guilist_onSelectAll(SCRIPT_CALL, getScriptObject()); +} + +void ScriptList::onDelete() +{ + SCRIPTLIST_PARENT::onDelete(); + GuiListScriptController::guilist_onDelete(SCRIPT_CALL, getScriptObject()); +} + +void ScriptList::onDoubleClick(int itemnum) +{ + SCRIPTLIST_PARENT::onDoubleClick(itemnum); + GuiListScriptController::guilist_onDoubleClick(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(itemnum)); +#ifdef WASABI_COMPILE_CONFIG + saveToConfig(); +#endif +} + +void ScriptList::onLeftClick(int itemnum) +{ + SCRIPTLIST_PARENT::onLeftClick(itemnum); + GuiListScriptController::guilist_onLeftClick(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(itemnum)); +} + +int ScriptList::onIconLeftClick(int itemnum, int x , int y) +{ + SCRIPTLIST_PARENT::onIconLeftClick(itemnum, x, y); + scriptVar v = GuiListScriptController::guilist_onIconLeftClick(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(itemnum), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y)); + if ((v.type != SCRIPT_VOID) && (v.type != SCRIPT_OBJECT) && (v.type != SCRIPT_STRING)) + { + return GET_SCRIPT_INT(v); + } + return 0; +} + +void ScriptList::onSecondLeftClick(int itemnum) +{ + SCRIPTLIST_PARENT::onSecondLeftClick(itemnum); + GuiListScriptController::guilist_onSecondLeftClick(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(itemnum)); +} + +int ScriptList::onRightClick(int itemnum) +{ + SCRIPTLIST_PARENT::onRightClick(itemnum); + scriptVar v = GuiListScriptController::guilist_onRightClick(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(itemnum)); + if ((v.type != SCRIPT_VOID) && (v.type != SCRIPT_OBJECT) && (v.type != SCRIPT_STRING)) + { + return GET_SCRIPT_BOOLEAN(v); + } + return 0; +} + +int ScriptList::onColumnDblClick(int col, int x, int y) +{ + SCRIPTLIST_PARENT::onColumnDblClick(col, x, y); + scriptVar v = GuiListScriptController::guilist_onColumnDblClick(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(col), MAKE_SCRIPT_INT(y), MAKE_SCRIPT_INT(x)); + if ((v.type != SCRIPT_VOID) && (v.type != SCRIPT_OBJECT) && (v.type != SCRIPT_STRING)) + { + return GET_SCRIPT_BOOLEAN(v); + } + return 0; +} + +int ScriptList::onColumnLabelClick(int col, int x, int y) +{ + SCRIPTLIST_PARENT::onColumnLabelClick(col, x, y); + scriptVar v = GuiListScriptController::guilist_onColumnLabelClick(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(col), MAKE_SCRIPT_INT(y), MAKE_SCRIPT_INT(x)); + if ((v.type != SCRIPT_VOID) && (v.type != SCRIPT_OBJECT) && (v.type != SCRIPT_STRING)) + { + return GET_SCRIPT_BOOLEAN(v); + } + return 1; // don't ask me, that's what ListWnd does. +} + +void ScriptList::onItemSelection(int itemnum, int selected) +{ + SCRIPTLIST_PARENT::onItemSelection(itemnum, selected); + GuiListScriptController::guilist_onItemSelection(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(itemnum), MAKE_SCRIPT_INT(selected)); +#ifdef WASABI_COMPILE_CONFIG + saveToConfig(); +#endif +} + +// ----------------------------------------------------------------------- +// Script Object + +GuiListScriptController _guiListController; +GuiListScriptController *guiListController = &_guiListController; + +// -- Functions table ------------------------------------- +function_descriptor_struct GuiListScriptController::exportedFunction[] = { + {L"getNumItems", 0, (void*)GuiListScriptController::guilist_getNumItems }, + {L"getWantAutoDeselect", 0, (void*)guilist_getWantAutoDeselect }, + {L"setWantAutoDeselect", 1, (void*)guilist_setWantAutoDeselect }, + {L"onSetVisible", 1, (void*)guilist_onSetVisible }, + {L"setAutoSort", 1, (void*)guilist_setAutoSort }, + {L"next", 0, (void*)guilist_next }, + {L"selectCurrent", 0, (void*)guilist_selectCurrent }, + {L"selectFirstEntry", 0, (void*)guilist_selectFirstEntry }, + {L"previous", 0, (void*)guilist_previous }, + {L"pagedown", 0, (void*)guilist_pagedown }, + {L"pageup", 0, (void*)guilist_pageup }, + {L"home", 0, (void*)guilist_home }, + {L"end", 0, (void*)guilist_end }, + {L"reset", 0, (void*)guilist_reset }, + {L"addColumn", 3, (void*)guilist_addColumn }, + {L"getNumColumns", 0, (void*)guilist_getNumColumns }, + {L"getColumnWidth", 1, (void*)guilist_getColumnWidth }, + {L"setColumnWidth", 2, (void*)guilist_setColumnWidth }, + {L"getColumnLabel", 1, (void*)guilist_getColumnLabel }, + {L"setColumnLabel", 2, (void*)guilist_setColumnLabel }, + {L"getColumnNumeric", 1, (void*)guilist_getColumnNumeric }, + {L"setColumnDynamic", 2, (void*)guilist_setColumnDynamic }, + {L"isColumnDynamic", 1, (void*)guilist_isColumnDynamic }, + {L"setMinimumSize", 1, (void*)guilist_setMinimumSize }, + {L"addItem", 1, (void*)guilist_addItem }, + {L"insertItem", 2, (void*)guilist_insertItem }, + {L"getLastAddedItemPos", 0, (void*)guilist_getLastAddedItemPos }, + {L"setSubItem", 3, (void*)guilist_setSubItem }, + {L"deleteAllItems", 0, (void*)guilist_deleteAllItems }, + {L"deleteByPos", 1, (void*)guilist_deleteByPos }, + {L"getItemLabel", 2, (void*)guilist_getItemLabel }, + {L"setItemLabel", 2, (void*)guilist_setItemLabel }, + + {L"setItemIcon", 2, (void*)guilist_setItemIcon }, + {L"getItemIcon", 1, (void*)guilist_getItemIcon }, + {L"setShowIcons", 1, (void*)guilist_setShowIcons }, + {L"getShowIcons", 0, (void*)guilist_getShowIcons }, + {L"setIconWidth", 1, (void*)guilist_setIconWidth }, + {L"getIconWidth", 0, (void*)guilist_getIconWidth }, + {L"setIconHeight", 1, (void*)guilist_setIconHeight }, + {L"getIconHeight", 0, (void*)guilist_getIconHeight }, + {L"onIconLeftclick", 3, (void*)guilist_onIconLeftClick }, + + {L"getItemSelected", 1, (void*)guilist_getItemSelected }, + {L"isItemFocused", 1, (void*)guilist_isItemFocused }, + {L"getItemFocused", 0, (void*)guilist_getItemFocused }, + {L"setItemFocused", 1, (void*)guilist_setItemFocused }, + {L"ensureItemVisible", 1, (void*)guilist_ensureItemVisible }, + {L"invalidateColumns", 0, (void*)guilist_invalidateColumns }, + {L"scrollAbsolute", 1, (void*)guilist_scrollAbsolute }, + {L"scrollRelative", 1, (void*)guilist_scrollRelative }, + {L"scrollLeft", 1, (void*)guilist_scrollLeft }, + {L"scrollRight", 1, (void*)guilist_scrollRight }, + {L"scrollUp", 1, (void*)guilist_scrollUp }, + {L"scrollDown", 1, (void*)guilist_scrollDown }, + {L"getSubitemText", 2, (void*)guilist_getSubitemText }, + {L"getFirstItemSelected", 0, (void*)guilist_getFirstItemSelected }, + {L"getNextItemSelected", 1, (void*)guilist_getNextItemSelected }, + {L"selectAll", 0, (void*)guilist_selectAll }, + {L"deselectAll", 0, (void*)guilist_deselectAll }, + {L"invertSelection", 0, (void*)guilist_invertSelection }, + {L"invalidateItem", 1, (void*)guilist_invalidateItem }, + {L"getFirstItemVisible", 0, (void*)guilist_getFirstItemVisible }, + {L"getLastItemVisible", 0, (void*)guilist_getLastItemVisible }, + {L"setFontSize", 1, (void*)guilist_setFontSize }, + {L"getFontSize", 0, (void*)guilist_getFontSize }, + {L"jumpToNext", 1, (void*)guilist_jumpToNext }, + {L"scrollToItem", 1, (void*)guilist_scrollToItem }, + {L"resort", 0, (void*)guilist_resort }, + {L"getSortDirection", 0, (void*)guilist_getSortDirection }, + {L"getSortColumn", 0, (void*)guilist_getSortColumn }, + {L"setSortColumn", 1, (void*)guilist_setSortColumn }, + {L"setSortDirection", 1, (void*)guilist_setSortDirection }, + {L"getItemCount", 0, (void*)guilist_getItemCount }, + {L"setSelectionStart", 1, (void*)guilist_setSelectionStart }, + {L"setSelectionEnd", 1, (void*)guilist_setSelectionEnd }, + {L"setSelected", 2, (void*)guilist_setSelected }, + {L"toggleSelection", 2, (void*)guilist_toggleSelection }, + {L"getHeaderHeight", 0, (void*)guilist_getHeaderHeight }, + {L"getPreventMultipleSelection", 0, (void*)guilist_getPreventMultipleSelection }, + {L"setPreventMultipleSelection", 1, (void*)guilist_setPreventMultipleSelection }, + {L"moveItem", 2, (void*)guilist_moveItem }, + {L"onSelectAll", 0, (void*)guilist_onSelectAll }, + {L"onDelete", 0, (void*)guilist_onDelete }, + {L"onDoubleClick", 1, (void*)guilist_onDoubleClick }, + {L"onLeftClick", 1, (void*)guilist_onLeftClick }, + {L"onSecondLeftClick", 1, (void*)guilist_onSecondLeftClick }, + {L"onRightClick", 1, (void*)guilist_onRightClick }, + {L"onColumnDblClick", 3, (void*)guilist_onColumnDblClick }, + {L"onColumnLabelClick", 3, (void*)guilist_onColumnLabelClick }, + {L"onItemSelection", 2, (void*)guilist_onItemSelection }, + }; + +ScriptObject *GuiListScriptController::instantiate() +{ + ScriptList *sp = new ScriptList; + ASSERT(sp != NULL); + return sp->getScriptObject(); +} + +void GuiListScriptController::destroy(ScriptObject *o) +{ + ScriptList *sp = static_cast<ScriptList *>(o->vcpu_getInterface(guilistGuid)); + ASSERT(sp != NULL); + delete sp; +} + +void *GuiListScriptController::encapsulate(ScriptObject *o) +{ + return NULL; // no encapsulation for guilists yet +} + +void GuiListScriptController::deencapsulate(void *o) +{} + +int GuiListScriptController::getNumFunctions() +{ + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *GuiListScriptController::getExportedFunctions() +{ + return exportedFunction; +} + +/*int*/ scriptVar GuiListScriptController::guilist_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int a = 0; + if (sp) a = sp->getNumItems(); + return MAKE_SCRIPT_INT(a); +} + +/*int*/ scriptVar GuiListScriptController::guilist_getWantAutoDeselect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int a = 0; + if (sp) + { + sp->wantAutoDeselect(); + } + return MAKE_SCRIPT_INT(a); +} + +/*void*/ scriptVar GuiListScriptController::guilist_setWantAutoDeselect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar want) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _want = GET_SCRIPT_INT(want); + sp->setWantAutoDeselect(_want); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_onSetVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar show) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _show = GET_SCRIPT_INT(show); + sp->onSetVisible(_show); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_setAutoSort(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar dosort) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _dosort = GET_SCRIPT_INT(dosort); + sp->setAutoSort(!!_dosort); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_next(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + sp->next(); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_selectCurrent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + sp->selectCurrent(); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_selectFirstEntry(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + sp->selectFirstEntry(); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_previous(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + sp->previous(); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_pagedown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + sp->pagedown(); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_pageup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + sp->pageup(); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_home(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + sp->home(); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_end(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + sp->end(); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_reset(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + sp->reset(); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar GuiListScriptController::guilist_addColumn(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar name, /*int*/ scriptVar width, /*int*/ scriptVar numeric) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + StringW _name = GET_SCRIPT_STRING(name); + int _width = GET_SCRIPT_INT(width); + int _numeric = GET_SCRIPT_INT(numeric); + retval = sp->addColumn(_name, _width, _numeric); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_getNumColumns(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->getNumColumns(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_getColumnWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + int _column = GET_SCRIPT_INT(column); + retval = sp->getColumnWidth(_column); + } + return MAKE_SCRIPT_INT(retval); +} + +/*void*/ scriptVar GuiListScriptController::guilist_setColumnWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column, /*int*/ scriptVar newwidth) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _column = GET_SCRIPT_INT(column); + int _newwidth = GET_SCRIPT_INT(newwidth); + ListColumn *c = sp->getColumn(_column); + if (c) + { + c->setWidth(_newwidth); + } + } + RETURN_SCRIPT_VOID; +} + +/*String*/ scriptVar GuiListScriptController::guilist_getColumnLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + const wchar_t * retval = L""; + if (sp) + { + int _column = GET_SCRIPT_INT(column); + ListColumn *c = sp->getColumn(_column); + if (c) + { + retval = c->getLabel(); + } + } + + return MAKE_SCRIPT_STRING(retval); +} + +/*void*/ scriptVar GuiListScriptController::guilist_setColumnLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column, /*String*/ scriptVar newlabel) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _column = GET_SCRIPT_INT(column); + StringW _newlabel = GET_SCRIPT_STRING(newlabel); + ListColumn *c = sp->getColumn(_column); + if (c) + { + c->setLabel(_newlabel); + } + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar GuiListScriptController::guilist_getColumnNumeric(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + int _column = GET_SCRIPT_INT(column); + ListColumn *c = sp->getColumn(_column); + if (c) + { + retval = c->getNumeric(); + } + } + return MAKE_SCRIPT_INT(retval); +} + +/*void*/ scriptVar GuiListScriptController::guilist_setColumnDynamic(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column, /*int*/ scriptVar isdynamic) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _column = GET_SCRIPT_INT(column); + int _isdynamic = GET_SCRIPT_INT(isdynamic); + ListColumn *c = sp->getColumn(_column); + if (c) + { + c->setDynamic(_isdynamic); + } + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar GuiListScriptController::guilist_isColumnDynamic(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + int _column = GET_SCRIPT_INT(column); + ListColumn *c = sp->getColumn(_column); + if (c) + { + retval = c->isDynamic(); + } + } + return MAKE_SCRIPT_INT(retval); +} + +/*void*/ scriptVar GuiListScriptController::guilist_setMinimumSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar size) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _size = GET_SCRIPT_INT(size); + sp->setMinimumSize(_size); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar GuiListScriptController::guilist_addItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar label) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + StringW _label = GET_SCRIPT_STRING(label); + retval = sp->addItem(_label, 0); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_insertItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*String*/ scriptVar label) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + StringW _label = GET_SCRIPT_STRING(label); + retval = sp->insertItem(_pos, _label, 0); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_getLastAddedItemPos(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->getLastAddedItemPos(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*void*/ scriptVar GuiListScriptController::guilist_setSubItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar subpos, /*String*/ scriptVar txt) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + int _subpos = GET_SCRIPT_INT(subpos); + StringW _txt = GET_SCRIPT_STRING(txt); + sp->setSubItem(_pos, _subpos, _txt); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_deleteAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + sp->deleteAllItems(); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar GuiListScriptController::guilist_deleteByPos(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + retval = sp->deleteByPos(_pos); + } + return MAKE_SCRIPT_INT(retval); +} + +/*String*/ scriptVar GuiListScriptController::guilist_getItemLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar subpos) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + wchar_t retval[255] = { 0 }; + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + int _subpos = GET_SCRIPT_INT(subpos); + sp->getItemLabel(_pos, _subpos, retval, 254); + retval[254]=0; + } + staticStr = retval; + return MAKE_SCRIPT_STRING(staticStr); +} + +/*void*/ scriptVar GuiListScriptController::guilist_setItemLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*String*/ scriptVar text) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + StringW _text = GET_SCRIPT_STRING(text); + sp->setItemLabel(_pos, _text); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_setItemIcon(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*String*/ scriptVar bitmapId) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + StringW _bitmapId = GET_SCRIPT_STRING(bitmapId); + sp->setItemIcon(_pos, _bitmapId); + } + RETURN_SCRIPT_VOID; +} + +/*string*/ scriptVar GuiListScriptController::guilist_getItemIcon(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + SkinBitmap * bmp = sp->getItemIcon(_pos); + staticStr = bmp->getBitmapName(); + } + return MAKE_SCRIPT_STRING(staticStr); +} + +/*void*/ scriptVar GuiListScriptController::guilist_setShowIcons(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar onoff) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _onoff = GET_SCRIPT_INT(onoff); + sp->setShowIcons(_onoff); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar GuiListScriptController::guilist_getShowIcons(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->getShowIcons(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*void*/ scriptVar GuiListScriptController::guilist_setIconWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar val) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _val = GET_SCRIPT_INT(val); + sp->setIconWidth(_val); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar GuiListScriptController::guilist_getIconWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->getIconWidth(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*void*/ scriptVar GuiListScriptController::guilist_setIconHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar val) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _val = GET_SCRIPT_INT(val); + sp->setIconHeight(_val); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar GuiListScriptController::guilist_getIconHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->getIconHeight(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_getItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + retval = sp->getItemSelected(_pos); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_isItemFocused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + retval = sp->getItemFocused(_pos); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_getItemFocused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->getItemFocused(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*void*/ scriptVar GuiListScriptController::guilist_setItemFocused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + sp->setItemFocused(_pos); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_ensureItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + sp->ensureItemVisible(_pos); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_invalidateColumns(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + sp->invalidateColumns(); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar GuiListScriptController::guilist_scrollAbsolute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar x) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + int _x = GET_SCRIPT_INT(x); + retval = sp->scrollAbsolute(_x); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_scrollRelative(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar x) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + int _x = GET_SCRIPT_INT(x); + retval = sp->scrollRelative(_x); + } + return MAKE_SCRIPT_INT(retval); +} + +/*void*/ scriptVar GuiListScriptController::guilist_scrollLeft(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + //int _lines = GET_SCRIPT_INT(lines); + sp->scrollLeft(); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_scrollRight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + //int _lines = GET_SCRIPT_INT(lines); + sp->scrollRight(); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_scrollUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + //int _lines = GET_SCRIPT_INT(lines); + sp->scrollUp(); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_scrollDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + //int _lines = GET_SCRIPT_INT(lines); + sp->scrollDown(); + } + RETURN_SCRIPT_VOID; +} + +/*String*/ scriptVar GuiListScriptController::guilist_getSubitemText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar subpos) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + const wchar_t *retval = 0; + + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + int _subpos = GET_SCRIPT_INT(subpos); + retval = sp->getSubitemText(_pos, _subpos); + } + return MAKE_SCRIPT_STRING(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_getFirstItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->getFirstItemSelected(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_getNextItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lastpos) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + int _lastpos = GET_SCRIPT_INT(lastpos); + retval = sp->getNextItemSelected(_lastpos); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_selectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->selectAll(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_deselectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->deselectAll(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_invertSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->invertSelection(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_invalidateItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + retval = sp->invalidateItem(_pos); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_getFirstItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->getFirstItemVisible(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_getLastItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->getLastItemVisible(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_setFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar size) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + int _size = GET_SCRIPT_INT(size); + retval = sp->setFontSize(_size); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_getFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->getFontSize(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*void*/ scriptVar GuiListScriptController::guilist_jumpToNext(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*char*/ scriptVar c) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + char _c = GET_SCRIPT_INT(c); + sp->jumpToNext(_c); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_scrollToItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + sp->scrollToItem(_pos); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_resort(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + sp->resort(); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar GuiListScriptController::guilist_getSortDirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->getSortDirection(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_getSortColumn(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->getSortColumn(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*void*/ scriptVar GuiListScriptController::guilist_setSortColumn(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar col) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _col = GET_SCRIPT_INT(col); + sp->setSortColumn(_col); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_setSortDirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar dir) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _dir = GET_SCRIPT_INT(dir); + sp->setSortDirection(_dir); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar GuiListScriptController::guilist_getItemCount(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->getItemCount(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*void*/ scriptVar GuiListScriptController::guilist_setSelectionStart(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + sp->setSelectionStart(_pos); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_setSelectionEnd(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + sp->setSelectionEnd(_pos); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_setSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar selected) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + int _selected = GET_SCRIPT_INT(selected); + sp->setSelected(_pos, _selected); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_toggleSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar setfocus) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _pos = GET_SCRIPT_INT(pos); + int _setfocus = GET_SCRIPT_INT(setfocus); + sp->toggleSelection(_pos, _setfocus); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar GuiListScriptController::guilist_getHeaderHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->getHeaderHeight(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_getPreventMultipleSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + retval = sp->getPreventMultipleSelection(); + } + return MAKE_SCRIPT_INT(retval); +} + +/*int*/ scriptVar GuiListScriptController::guilist_setPreventMultipleSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar val) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + int retval = 0; + if (sp) + { + int _val = GET_SCRIPT_INT(val); + retval = sp->setPreventMultipleSelection(_val); + } + return MAKE_SCRIPT_INT(retval); +} + +/*void*/ scriptVar GuiListScriptController::guilist_moveItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar from, /*int*/ scriptVar to) +{ + SCRIPT_FUNCTION_INIT + ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid)); + if (sp) + { + int _from = GET_SCRIPT_INT(from); + int _to = GET_SCRIPT_INT(to); + sp->moveItem(_from, _to); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar GuiListScriptController::guilist_onSelectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS0(o, guiListController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +/*void*/ scriptVar GuiListScriptController::guilist_onDelete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS0(o, guiListController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +/*void*/ scriptVar GuiListScriptController::guilist_onDoubleClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, guiListController, itemnum); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, itemnum); +} + +/*void*/ scriptVar GuiListScriptController::guilist_onLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, guiListController, itemnum); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, itemnum); +} + +/*void*/ scriptVar GuiListScriptController::guilist_onIconLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum, /*int*/ scriptVar x, /*int*/ scriptVar y) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS3(o, guiListController, itemnum, x, y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT3(o, itemnum, x, y); +} + +/*void*/ scriptVar GuiListScriptController::guilist_onSecondLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, guiListController, itemnum); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, itemnum); +} + +/*int*/ scriptVar GuiListScriptController::guilist_onRightClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, guiListController, itemnum); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, itemnum); +} + +/*int*/ scriptVar GuiListScriptController::guilist_onColumnDblClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar col, /*int*/ scriptVar x, /*int*/ scriptVar y) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS3(o, guiListController, col, x, y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT3(o, col, x, y); +} + +/*int*/ scriptVar GuiListScriptController::guilist_onColumnLabelClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar col, /*int*/ scriptVar x, /*int*/ scriptVar y) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS3(o, guiListController, col, x, y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT3(o, col, x, y); +} + +/*void*/ scriptVar GuiListScriptController::guilist_onItemSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum, /*int*/ scriptVar selected) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS2(o, guiListController, itemnum, selected); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT2(o, itemnum, selected); +} + diff --git a/Src/Wasabi/api/skin/widgets/xuilist.h b/Src/Wasabi/api/skin/widgets/xuilist.h new file mode 100644 index 00000000..ecc5c4a9 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuilist.h @@ -0,0 +1,221 @@ +#ifndef __XUILIST_H +#define __XUILIST_H + +#include <api/wnd/wndclass/listwnd.h> +#include <api/script/objcontroller.h> +#include <bfc/depend.h> + +class svc_textFeed; + +#define SCRIPTLIST_PARENT ListWnd + +// ----------------------------------------------------------------------- +class ScriptList : public SCRIPTLIST_PARENT, public DependentViewerI { + public: + ScriptList(); + virtual ~ScriptList(); + + virtual int onInit(); + + //virtual void onDoubleClick(int itemnum); // moved to the script-handling callback. + //void onItemSelection(int itemnum, int selected); + + int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); +#ifdef WASABI_COMPILE_CONFIG + int onReloadConfig(); +#endif + + virtual int viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen); + virtual void onSetVisible(int i); + + virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source); + + // Callback methods that send hooks into the Script system + virtual void onSelectAll(); + virtual void onDelete(); + virtual void onDoubleClick(int itemnum); + virtual void onLeftClick(int itemnum); + virtual void onSecondLeftClick(int itemnum); + virtual int onRightClick(int itemnum); + virtual int onColumnDblClick(int col, int x, int y); + virtual int onColumnLabelClick(int col, int x, int y); + virtual void onItemSelection(int itemnum, int selected); + virtual int onIconLeftClick(int itemnum, int x, int y); + + + + enum { + SCRIPTLIST_SETITEMS = 0, + SCRIPTLIST_SETMULTISELECT, + SCRIPTLIST_SETAUTODESELECT, + SCRIPTLIST_SELECT, + SCRIPTLIST_FEED, + SCRIPTLIST_HOVERSELECT, + SCRIPTLIST_SORT, + SCRIPTLIST_SELECTONUPDOWN, + SCRIPTLIST_NUMCOLUMNS, + SCRIPTLIST_COLUMNWIDTHS, + SCRIPTLIST_COLUMNLABELS, + }; + +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + static XMLParamPair params[]; +#ifdef WASABI_COMPILE_CONFIG + void saveToConfig(); + void selectFromConfig(); +#endif + void fillFromParams(); + int selectEntry(const wchar_t *e, int cb=1); + void selectEntries(const wchar_t *multientry, int cb=1); + void setNumColumns(); + void setColumnWidths(); + void setColumnLabels(); + + void openFeed(const wchar_t *feedid); + void closeFeed(); + + //virtual int getColumnsHeight() { return 0; } + virtual int wantHScroll() { return 0; } + + StringW items; + StringW columnwidths; + StringW columnlabels; + int xmlnumcolumns; + int last_numcolumns; + int multiselect; + int myxuihandle; + int autosave; +#ifdef WASABI_COMPILE_CONFIG + int config_reentry; +#endif + + svc_textFeed *feed; + StringW last_feed; +}; + +// ----------------------------------------------------------------------------------------------------- +class GuiListScriptController : public ScriptObjectControllerI { + public: + + virtual const wchar_t *getClassName() { return L"GuiList"; } + virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; } + virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); } + virtual int getNumFunctions(); + virtual const function_descriptor_struct *getExportedFunctions(); + virtual GUID getClassGuid() { return guilistGuid; } + virtual ScriptObject *instantiate(); + virtual void destroy(ScriptObject *o); + virtual void *encapsulate(ScriptObject *o); + virtual void deencapsulate(void *o); + + public: + static scriptVar guilist_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_getWantAutoDeselect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_setWantAutoDeselect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar want); + static /*void*/ scriptVar guilist_onSetVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar show); + static /*void*/ scriptVar guilist_setAutoSort(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar dosort); + static /*void*/ scriptVar guilist_next(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_selectCurrent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_selectFirstEntry(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_previous(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_pagedown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_pageup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_home(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_end(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_reset(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_addColumn(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar name, /*int*/ scriptVar width, /*int*/ scriptVar numeric); + static /*int*/ scriptVar guilist_getNumColumns(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_getColumnWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column); + static /*void*/ scriptVar guilist_setColumnWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column, /*int*/ scriptVar newwidth); + static /*String*/ scriptVar guilist_getColumnLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column); + static /*void*/ scriptVar guilist_setColumnLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column, /*String*/ scriptVar newlabel); + static /*int*/ scriptVar guilist_getColumnNumeric(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column); + static /*void*/ scriptVar guilist_setColumnDynamic(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column, /*int*/ scriptVar isdynamic); + static /*int*/ scriptVar guilist_isColumnDynamic(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column); + static /*void*/ scriptVar guilist_setMinimumSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar size); + static /*int*/ scriptVar guilist_addItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar label); + static /*int*/ scriptVar guilist_insertItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*String*/ scriptVar label); + static /*int*/ scriptVar guilist_getLastAddedItemPos(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_setSubItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar subpos, /*String*/ scriptVar txt); + static /*void*/ scriptVar guilist_deleteAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_deleteByPos(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos); + static /*String*/ scriptVar guilist_getItemLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar subpos); + static /*void*/ scriptVar guilist_setItemLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*String*/ scriptVar text); + + static /*void*/ scriptVar guilist_setItemIcon(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*String*/ scriptVar bitmapId); + static /*string*/ scriptVar guilist_getItemIcon(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos); + static /*void*/ scriptVar guilist_setShowIcons(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar onoff); + static /*int*/ scriptVar guilist_getShowIcons(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_getIconWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_setIconWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val); + static /*int*/ scriptVar guilist_getIconHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_setIconHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val); + static /*int*/ scriptVar guilist_onIconLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar pos, scriptVar x, scriptVar y); + + static /*int*/ scriptVar guilist_getItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos); + static /*int*/ scriptVar guilist_isItemFocused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos); + static /*int*/ scriptVar guilist_getItemFocused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_setItemFocused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos); + static /*void*/ scriptVar guilist_ensureItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos); + static /*void*/ scriptVar guilist_invalidateColumns(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_scrollAbsolute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar x); + static /*int*/ scriptVar guilist_scrollRelative(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar x); + static /*void*/ scriptVar guilist_scrollLeft(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines); + static /*void*/ scriptVar guilist_scrollRight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines); + static /*void*/ scriptVar guilist_scrollUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines); + static /*void*/ scriptVar guilist_scrollDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines); + static /*String*/ scriptVar guilist_getSubitemText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar subpos); + static /*int*/ scriptVar guilist_getFirstItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_getNextItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lastpos); + static /*int*/ scriptVar guilist_selectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_deselectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_invertSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_invalidateItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos); + static /*int*/ scriptVar guilist_getFirstItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_getLastItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_setFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar size); + static /*int*/ scriptVar guilist_getFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_jumpToNext(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*char*/ scriptVar c); + static /*void*/ scriptVar guilist_scrollToItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos); + static /*void*/ scriptVar guilist_resort(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_getSortDirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_getSortColumn(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_setSortColumn(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar col); + static /*void*/ scriptVar guilist_setSortDirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar dir); + static /*int*/ scriptVar guilist_getItemCount(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_setSelectionStart(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos); + static /*void*/ scriptVar guilist_setSelectionEnd(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos); + static /*void*/ scriptVar guilist_setSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar selected); + static /*void*/ scriptVar guilist_toggleSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar setfocus); + static /*int*/ scriptVar guilist_getHeaderHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_getPreventMultipleSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar guilist_setPreventMultipleSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar val); + static /*void*/ scriptVar guilist_moveItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar from, /*int*/ scriptVar to); + + static /*void*/ scriptVar guilist_onSelectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_onDelete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar guilist_onDoubleClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum); + static /*void*/ scriptVar guilist_onLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum); + static /*void*/ scriptVar guilist_onSecondLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum); + static /*int*/ scriptVar guilist_onRightClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum); + static /*int*/ scriptVar guilist_onColumnDblClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar col, /*int*/ scriptVar x, /*int*/ scriptVar y); + static /*int*/ scriptVar guilist_onColumnLabelClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar col, /*int*/ scriptVar x, /*int*/ scriptVar y); + static /*void*/ scriptVar guilist_onItemSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum, /*int*/ scriptVar selected); + + private: + static function_descriptor_struct exportedFunction[]; + + static StringW staticStr; +}; + +extern GuiListScriptController *guiListController; + + +// ----------------------------------------------------------------------- +extern const wchar_t ScriptListXuiObjectStr[]; +extern char ScriptListXuiSvcName[]; +class ScriptListXuiSvc : public XuiObjectSvc<ScriptList, ScriptListXuiObjectStr, ScriptListXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuimenu.cpp b/Src/Wasabi/api/skin/widgets/xuimenu.cpp new file mode 100644 index 00000000..7113b8fb --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuimenu.cpp @@ -0,0 +1,384 @@ +#include <precomp.h> +#include "xuimenu.h" +#include <api/service/svcs/svc_action.h> + +#define MENU_TIMER_CHECK 0x100 +#define DC_MENU_CHAIN 0x101 +#define DC_MENU_REENABLE 0x102 +#define DC_MENU_INIT 0x103 +#define DC_MENU_NEXT 0x104 +#define DC_MENU_PREV 0x105 +#define DC_MENU_OPENACTION 0x106 +#define MENU_TIMER_POPKBDLOCK 0x107 +#define MENU_TIMER_DELAY 5 +extern HINSTANCE hInstance; +const wchar_t MenuXuiObjectStr[] = L"Menu"; // This is the xml tag +char MenuXuiSvcName[] = "Menu xui object"; + +static XuiMenu *xuimenu_hookingMenu = NULL; +static HHOOK hhook=NULL; +static HHOOK hhook_menuselect=NULL; +static int hookusercount = 0; + +XMLParamPair XuiMenu::params[] = { + {MENU_DOWNID, L"DOWN"}, + {MENU_HOVERID, L"HOVER"}, + {MENU_MENU, L"MENU"}, + {MENU_MENUGROUP, L"MENUGROUP"}, + {MENU_NEXT, L"NEXT"}, + {MENU_NORMALID, L"NORMAL"}, + {MENU_PREV, L"PREV"}, + }; + +XuiMenu::XuiMenu() { + timerset = 0; + disablespawn = 0; + nextinchain = NULL; + normal = NULL; + down = NULL; + isspawned = 0; + inarea = 0; + kbdhook = 0; + kbdlocktimer = 0; + submenu_isselected = 0; + submenu_selectedbymouse = 0; + submenu_selected = NULL; + first_hmenu = NULL; + cur_hmenu = NULL; + getScriptObject()->vcpu_setInterface(xuiMenuGuid, (void *)static_cast<XuiMenu *>(this)); + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); + hover = NULL; + orig_x = orig_y = 0; + menu_parent = NULL; +} + +void XuiMenu::CreateXMLParameters(int master_handle) +{ + //XUIMENU_PARENT::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); +} + +XuiMenu::~XuiMenu() { + if (timerset) killTimer(MENU_TIMER_CHECK); + if (kbdlocktimer) { killTimer(MENU_TIMER_POPKBDLOCK); WASABI_API_WND->popKeyboardLock(); } // do not set kbdlocktimer to 0, or stopKbdHook will start a timer + stopKbdHook(); +} + +int XuiMenu::onInit() { + XUIMENU_PARENT::onInit(); + postDeferredCallback(DC_MENU_INIT); + return 1; +} + +int XuiMenu::setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value) { + if (xuihandle == _xuihandle) { + switch (xmlattrid) { + case MENU_MENUGROUP: setMenuGroup(value); return 1; + case MENU_MENU: setMenu(value); return 1; + case MENU_NORMALID: setNormalId(value); return 1; + case MENU_DOWNID: setDownId(value); return 1; + case MENU_HOVERID: setHoverId(value); return 1; + case MENU_NEXT: next = value; return 1; + case MENU_PREV: prev = value; return 1; + } + } + return XUIMENU_PARENT::setXuiParam(_xuihandle, xmlattrid, name, value); +} + +void XuiMenu::setMenu(const wchar_t *m) +{ + menuid = m; + return; +} + +void XuiMenu::setMenuGroup(const wchar_t *mg) { + menugroup = mg; + return; +} + +void XuiMenu::setNormalId(const wchar_t *id) { + normalid = id; + updateObjects(); +} + +void XuiMenu::setDownId(const wchar_t *id) { + downid = id; + updateObjects(); +} + +void XuiMenu::setHoverId(const wchar_t *id) { + hoverid = id; + updateObjects(); +} + +int XuiMenu::onLeftButtonDown(int x, int y) { + XUIMENU_PARENT::onLeftButtonDown(x, y); + if (!disablespawn) + spawnMenu(); + return 1; +} + +void XuiMenu::timerCallback(int c) { + if (c == MENU_TIMER_CHECK) { + timerCheck(); + } else if (c == MENU_TIMER_POPKBDLOCK) { + kbdlocktimer = 0; + killTimer(MENU_TIMER_POPKBDLOCK); + WASABI_API_WND->popKeyboardLock(); + } + else XUIMENU_PARENT::timerCallback(c); +} + +void XuiMenu::timerCheck() { + POINT pt; + Wasabi::Std::getMousePos((long*)&pt.x, (long*)&pt.y); + if (pt.x == orig_x && pt.y == orig_y) return; + nextinchain = NULL; + ifc_window *w = WASABI_API_WND->rootWndFromPoint(&pt); + if (w != NULL) { + XuiMenu *x = static_cast<XuiMenu *>(w->getInterface(xuiMenuGuid)); + switchToMenu(x); + } +} + +void XuiMenu::switchToMenu(XuiMenu *x) { + if (x != NULL && x != this && x != nextinchain) + { + if (WCSCASEEQLSAFE(x->getMenuGroup(), getMenuGroup())) + { + killTimer(MENU_TIMER_CHECK); + timerset = 0; + nextinchain = x; + stopKbdHook(); + cancelMenu(); + } + } +} + +void XuiMenu::spawnMenu(int monitor) { + + Wasabi::Std::getMousePos(&orig_x, &orig_y); + + isspawned = 1; + onOpenMenu(); + + if (monitor) { setTimer(MENU_TIMER_CHECK, MENU_TIMER_DELAY); timerset = 1; startKbdHook(); } + + StringW actionstr = StringPrintfW(L"MENU:%s", menuid); + + svc_action *act = ActionEnum(actionstr).getNext(); + if (act) { + RECT r; + getClientRect(&r); + clientToScreen(&r); + act->onAction(actionstr, NULL, r.left, r.bottom, NULL, 0, this); + SvcEnum::release(act); + } + + if (monitor) { + if (timerset) { killTimer(MENU_TIMER_CHECK); timerset = 0; } + stopKbdHook(); + } + disablespawn = 1; + if (nextinchain) { + postDeferredCallback(DC_MENU_CHAIN); + } + postDeferredCallback(DC_MENU_REENABLE); + + isspawned = 0; + onCloseMenu(); +} + +int XuiMenu::onDeferredCallback(intptr_t p1, intptr_t p2) { + if (p1 == DC_MENU_CHAIN) { + XuiMenu *x = nextinchain; + nextinchain = NULL; + x->spawnMenu(); + } else if (p1 == DC_MENU_REENABLE) { + disablespawn = 0; + } else if (p1 == DC_MENU_INIT) { + updateObjects(); + } else if (p1 == DC_MENU_NEXT) { + _nextMenu(); + } else if (p1 == DC_MENU_PREV) { + _previousMenu(); + } else if (p1 == DC_MENU_OPENACTION) { + spawnMenu(); + WASABI_API_WND->kbdReset(); + } else return XUIMENU_PARENT::onDeferredCallback(p1, p2); + return 1; +} + +void XuiMenu::cancelMenu() { + #ifdef WIN32 + + PostMessage(gethWnd(), WM_LBUTTONDOWN, 0, 0xdeadc0de); + PostMessage(gethWnd(), WM_LBUTTONUP, 0, 0xdeadc0de); + + #else + + #error port me! you should close that menu which is in its own message pump now (oh and btw, you don't know shit about the menu itself because it's spawned by an action). have fun! + + #endif +} + +void XuiMenu::onOpenMenu() { + updateObjects(); + script_onOpenMenu(); +} + +void XuiMenu::onCloseMenu() { + updateObjects(); + WASABI_API_WND->kbdReset(); + script_onCloseMenu(); +} + +void XuiMenu::updateObjects() +{ + normal = findObject(normalid); + down = findObject(downid); + hover = findObject(hoverid); + if (normal) normal->guiobject_getRootWnd()->setVisible(!isspawned); + if (down) down->guiobject_getRootWnd()->setVisible(isspawned); + if (hover) hover->guiobject_getRootWnd()->setVisible(!isspawned && inarea); +} + +void XuiMenu::onEnterArea() { + XUIMENU_PARENT::onEnterArea(); + inarea = 1; + updateObjects(); +} + +void XuiMenu::onLeaveArea() { + XUIMENU_PARENT::onLeaveArea(); + inarea = 0; + updateObjects(); +} + +int XuiMenu::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) +{ + if (!_wcsicmp(action, L"open")) { openAction(); } + //else if (STRCASEEQL(action, "preopen")) { inarea = 1; updateObjects(); startKbdHook(); } + else if (!_wcsicmp(action, L"close")) cancelMenu(); + else return XUIMENU_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source); + return 1; +} + +LRESULT CALLBACK xuimenu_KeyboardProc(int code, WPARAM wParam, LPARAM lParam) { + if (code >= 0 && xuimenu_hookingMenu != NULL) { + if (code != HC_NOREMOVE && !(lParam & (1 << 31))) { + switch (wParam) { + case VK_LEFT: xuimenu_hookingMenu->onTrappedLeft(); break; + case VK_RIGHT: xuimenu_hookingMenu->onTrappedRight(); break; + //case VK_ESCAPE: DebugString("Escape trapped!\n"); break; + } + } + } + if (hhook) return CallNextHookEx(hhook, code, wParam, lParam); + return 1; +} + +LRESULT CALLBACK xuimenu_msgProc(int code, WPARAM wParam, LPARAM lParam) { + if (code >= 0 && xuimenu_hookingMenu != NULL) { + MSG *msg = (MSG *)lParam; + if (msg->message == WM_MENUSELECT) { + xuimenu_hookingMenu->onMenuSelect(msg->hwnd, (HMENU)msg->lParam, LOWORD(msg->wParam), HIWORD(msg->wParam)); + } + } + if (hhook_menuselect) return CallNextHookEx(hhook_menuselect, code, wParam, lParam); + return 1; +} + +void XuiMenu::startKbdHook() { + if (kbdhook) return; + if (kbdlocktimer) { killTimer(MENU_TIMER_POPKBDLOCK); kbdlocktimer = 0; } + else WASABI_API_WND->pushKeyboardLock(); + xuimenu_hookingMenu = this; + if (hhook == NULL) { + hhook = SetWindowsHookEx(WH_KEYBOARD, xuimenu_KeyboardProc, 0, GetCurrentThreadId()); + hhook_menuselect = SetWindowsHookEx(WH_MSGFILTER, xuimenu_msgProc, 0, GetCurrentThreadId()); + hookusercount = 1; + } else hookusercount++; + kbdhook = 1; +} + +void XuiMenu::stopKbdHook() { + if (!kbdhook) return; + if (nextinchain) { + if (!kbdlocktimer) { + kbdlocktimer = 1; + setTimer(MENU_TIMER_POPKBDLOCK, 500); + } + } else WASABI_API_WND->popKeyboardLock(); + if (xuimenu_hookingMenu == this) xuimenu_hookingMenu = NULL; + first_hmenu = NULL; + submenu_isselected = 0; + submenu_selectedbymouse = 0; + submenu_selected = NULL; + cur_hmenu = NULL; + menu_parent = NULL; + if (--hookusercount == 0) { + UnhookWindowsHookEx(hhook_menuselect); + UnhookWindowsHookEx(hhook); + hhook = NULL; + hhook_menuselect = NULL; + } + kbdhook = 0; +} + +void XuiMenu::onMenuSelect(HWND hwnd, HMENU menu, int item, int flags) { + if (first_hmenu == NULL) first_hmenu = menu; + cur_hmenu = menu; + menu_parent = hwnd; + +// DebugString("Menu Item Selected! HMENU = %X, item = %d, flags = %d, submenu = %X\n", menu, item, flags, flags & MF_POPUP); + + if (flags & MF_POPUP) { submenu_isselected = 1; submenu_selected = GetSubMenu(menu, item); submenu_selectedbymouse = flags & MF_MOUSESELECT; } + else { submenu_isselected = 0; submenu_selected = NULL; submenu_selectedbymouse = 0; } +} + +void XuiMenu::onTrappedLeft() { + if (cur_hmenu == first_hmenu) + xuimenu_hookingMenu->previousMenu(); +} + +void XuiMenu::onTrappedRight() { + if (!submenu_isselected) + nextMenu(); + else if (submenu_selectedbymouse) + PostMessage(menu_parent, WM_KEYDOWN, VK_DOWN, 0); +} + + +void XuiMenu::openAction() { + postDeferredCallback(DC_MENU_OPENACTION); +} + +void XuiMenu::previousMenu() { + postDeferredCallback(DC_MENU_PREV); +} + +void XuiMenu::nextMenu() { + postDeferredCallback(DC_MENU_NEXT); +} + +void XuiMenu::_nextMenu() { + GuiObject *o = findObject(next); + if (o) { + XuiMenu *menu = static_cast<XuiMenu*>(o->guiobject_getScriptObject()->vcpu_getInterface(xuiMenuGuid)); + if (menu) switchToMenu(menu); + } +} + +void XuiMenu::_previousMenu() { + GuiObject *o = findObject(prev); + if (o) { + XuiMenu *menu = static_cast<XuiMenu*>(o->guiobject_getScriptObject()->vcpu_getInterface(xuiMenuGuid)); + if (menu) switchToMenu(menu); + } +} + diff --git a/Src/Wasabi/api/skin/widgets/xuimenu.h b/Src/Wasabi/api/skin/widgets/xuimenu.h new file mode 100644 index 00000000..2629f980 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuimenu.h @@ -0,0 +1,110 @@ +#ifndef _XUIMENU_H +#define _XUIMENU_H + +#include <api/wnd/wndclass/guiobjwnd.h> + +/*<?<autoheader/>*/ +#include "xuimenuso.h" +/*?>*/ + +#define XUIMENU_PARENT XuiMenuScriptObject + +// {A0211C57-DCED-45ae-AEA6-56014B5898E8} +static const GUID xuiMenuGuid = +{ 0xa0211c57, 0xdced, 0x45ae, { 0xae, 0xa6, 0x56, 0x1, 0x4b, 0x58, 0x98, 0xe8 } }; + +/*<?<classdecl name="XuiMenu" factory="ScriptObject" />*/ +class XuiMenu : public XuiMenuScriptObject +{ +/*?>*/ + public: + friend LRESULT CALLBACK xuimenu_KeyboardProc(int code, WPARAM wParam, LPARAM lParam); + friend LRESULT CALLBACK xuimenu_msgProc(int code, WPARAM wParam, LPARAM lParam); + + XuiMenu(); + virtual ~XuiMenu(); + + virtual int onInit(); + virtual int onLeftButtonDown(int x, int y); + int setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value); + virtual void timerCallback(int c); + virtual int onDeferredCallback(intptr_t p1, intptr_t p2); + + SCRIPT void setMenuGroup(const wchar_t *mg); + SCRIPT const wchar_t *getMenuGroup() { return menugroup; } + + SCRIPT void setMenu(const wchar_t *m); + SCRIPT const wchar_t *getMenu() { return menuid; } + + SCRIPT void spawnMenu(int monitor = 1); + SCRIPT void cancelMenu(); + + SCRIPT void setNormalId(const wchar_t *id); + SCRIPT void setDownId(const wchar_t *id); + SCRIPT void setHoverId(const wchar_t *id); + + SCRIPT EVENT virtual void onOpenMenu(); + SCRIPT EVENT virtual void onCloseMenu(); + + virtual void onEnterArea(); + virtual void onLeaveArea(); + virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source); + + SCRIPT void nextMenu(); + SCRIPT void previousMenu(); + + enum { + MENU_MENU = 0, + MENU_MENUGROUP, + MENU_NORMALID, + MENU_DOWNID, + MENU_HOVERID, + MENU_NEXT, + MENU_PREV, + }; + +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + static XMLParamPair params[]; + void onMenuSelect(HWND hwnd, HMENU menu, int menuitem, int flags); + void startKbdHook(); + void stopKbdHook(); + void updateObjects(); + void timerCheck(); + void switchToMenu(XuiMenu *menu); + void _nextMenu(); + void _previousMenu(); + void openAction(); + void onTrappedLeft(); + void onTrappedRight(); + StringW menugroup; + StringW menuid; + int xuihandle; + XuiMenu *nextinchain; + int timerset; + int disablespawn; + GuiObject *normal; + GuiObject *down; + GuiObject *hover; + StringW next, prev; + int isspawned; + StringW normalid, downid, hoverid; + int inarea; + int kbdhook; + int orig_x, orig_y; + int kbdlocktimer; + int submenu_isselected; + int submenu_selectedbymouse; + HMENU submenu_selected; + HWND menu_parent; + HMENU first_hmenu; + HMENU cur_hmenu; +}; + +// ----------------------------------------------------------------------- +extern const wchar_t MenuXuiObjectStr[]; +extern char MenuXuiSvcName[]; +class MenuXuiSvc : public XuiObjectSvc<XuiMenu, MenuXuiObjectStr, MenuXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuimenuso.cpp b/Src/Wasabi/api/skin/widgets/xuimenuso.cpp new file mode 100644 index 00000000..8c48f210 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuimenuso.cpp @@ -0,0 +1,271 @@ +// ---------------------------------------------------------------------------- +// Generated by ScriptObjectFactory [Sun Dec 14 07:21:52 2003] +// +// File : xuimenuso.cpp +// Class : XuiMenuScriptObject +// class layer : Automatic Object Scripting +// ---------------------------------------------------------------------------- +#include <precomp.h> + +#include "xuimenuso.h" +#include "xuimenu.h" + +// ScriptController Instance +static XuiMenuScriptController _xuiMenuScriptController;XuiMenuScriptController *xuiMenuScriptController = &_xuiMenuScriptController; + +// Function Descriptor Table +function_descriptor_struct XuiMenuScriptController::exportedFunctions[] = { + {L"setMenuGroup", 1, script_setMenuGroup }, + {L"getMenuGroup", 0, script_getMenuGroup }, + {L"setMenu", 1, script_setMenu }, + {L"getMenu", 0, script_getMenu }, + {L"spawnMenu", 1, script_spawnMenu }, + {L"cancelMenu", 0, script_cancelMenu }, + {L"setNormalId", 1, script_setNormalId }, + {L"setDownId", 1, script_setDownId }, + {L"setHoverId", 1, script_setHoverId }, + {L"onOpenMenu", 0, script_onOpenMenu }, + {L"onCloseMenu", 0, script_onCloseMenu }, + {L"nextMenu", 0, script_nextMenu }, + {L"previousMenu", 0, script_previousMenu }, +}; + +// Script Object Methods +XuiMenuScriptObject::XuiMenuScriptObject() { + if (!getScriptObject()) return; + xuiMenuScriptObject_init(); +} + +XuiMenuScriptObject::~XuiMenuScriptObject() { +} + +void XuiMenuScriptObject::xuiMenuScriptObject_init() { + // Assign the script interface to this instance. + getScriptObject()->vcpu_setInterface(XuiMenuScriptGuid, (void *)static_cast<XuiMenu*>(this)); + // Assign the class name to this instance. + getScriptObject()->vcpu_setClassName(L"Menu"); + // Assign the controller instance to this script object instance. + getScriptObject()->vcpu_setController(xuiMenuScriptController); +} + +// Script Object Methods + +void XuiMenuScriptObject::script_onOpenMenu() { + XuiMenuScriptController::script_onOpenMenu(SCRIPT_CALL, getScriptObject()); +} + +void XuiMenuScriptObject::script_onCloseMenu() { + XuiMenuScriptController::script_onCloseMenu(SCRIPT_CALL, getScriptObject()); +} + +scriptVar /*void */ XuiMenuScriptController::script_setMenuGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*const char **/ mg) { + // Begin all script methods with the init block. + SCRIPT_FUNCTION_INIT; + // Find the proper pointer for the "this" object, _pSO. + XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid)); + if (_pObj) { + // Then properly call the hosted object; + _pObj->setMenuGroup(GET_SCRIPT_STRING(mg)); + } + RETURN_SCRIPT_VOID; +} + +scriptVar /*const char **/ XuiMenuScriptController::script_getMenuGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) { + // Begin all script methods with the init block. + SCRIPT_FUNCTION_INIT; + // Find the proper pointer for the "this" object, _pSO. + XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid)); + + if (_pObj) + return MAKE_SCRIPT_STRING(_pObj->getMenuGroup()); + + return MAKE_SCRIPT_STRING(L""); +} + +scriptVar /*void */ XuiMenuScriptController::script_setMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*const char **/ m) { + // Begin all script methods with the init block. + SCRIPT_FUNCTION_INIT; + // Find the proper pointer for the "this" object, _pSO. + XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid)); + if (_pObj) { + // Then properly call the hosted object; + _pObj->setMenu(GET_SCRIPT_STRING(m)); + } + RETURN_SCRIPT_VOID; +} + +scriptVar /*const char **/ XuiMenuScriptController::script_getMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) { + // Begin all script methods with the init block. + SCRIPT_FUNCTION_INIT; + // Find the proper pointer for the "this" object, _pSO. + XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid)); + + if (_pObj) + return MAKE_SCRIPT_STRING(_pObj->getMenu()); + + return MAKE_SCRIPT_STRING(L""); +} + +scriptVar /*void */ XuiMenuScriptController::script_spawnMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*int */ monitor) { + // Begin all script methods with the init block. + SCRIPT_FUNCTION_INIT; + // Find the proper pointer for the "this" object, _pSO. + XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid)); + if (_pObj) { + // Then properly call the hosted object; + _pObj->spawnMenu(GET_SCRIPT_INT(monitor)); + } + RETURN_SCRIPT_VOID; +} + +scriptVar /*void */ XuiMenuScriptController::script_cancelMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) { + // Begin all script methods with the init block. + SCRIPT_FUNCTION_INIT; + // Find the proper pointer for the "this" object, _pSO. + XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid)); + if (_pObj) { + // Then properly call the hosted object; + _pObj->cancelMenu(); + } + RETURN_SCRIPT_VOID; +} + +scriptVar /*void */ XuiMenuScriptController::script_setNormalId(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*const char **/ id) { + // Begin all script methods with the init block. + SCRIPT_FUNCTION_INIT; + // Find the proper pointer for the "this" object, _pSO. + XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid)); + if (_pObj) + { + // Then properly call the hosted object; + _pObj->setNormalId(GET_SCRIPT_STRING(id)); + } + RETURN_SCRIPT_VOID; +} + +scriptVar /*void */ XuiMenuScriptController::script_setDownId(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*const char **/ id) { + // Begin all script methods with the init block. + SCRIPT_FUNCTION_INIT; + // Find the proper pointer for the "this" object, _pSO. + XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid)); + if (_pObj) { + // Then properly call the hosted object; + _pObj->setDownId(GET_SCRIPT_STRING(id)); + } + RETURN_SCRIPT_VOID; +} + +scriptVar /*void */ XuiMenuScriptController::script_setHoverId(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*const char **/ id) { + // Begin all script methods with the init block. + SCRIPT_FUNCTION_INIT; + // Find the proper pointer for the "this" object, _pSO. + XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid)); + if (_pObj) { + // Then properly call the hosted object; + _pObj->setHoverId(GET_SCRIPT_STRING(id)); + } + RETURN_SCRIPT_VOID; +} + +scriptVar /*void */ XuiMenuScriptController::script_onOpenMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) { + // Begin all script methods with the init block + SCRIPT_FUNCTION_INIT; + // Honnor C++ hooks + PROCESS_HOOKS0(_pSO, xuiMenuScriptController); + // If there are no script hooks to execute, we abort here. + SCRIPT_FUNCTION_CHECKABORTEVENT; + // Otherwise we execute the script methods by calling this. + SCRIPT_EXEC_EVENT0(_pSO); +} + +scriptVar /*void */ XuiMenuScriptController::script_onCloseMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) { + // Begin all script methods with the init block + SCRIPT_FUNCTION_INIT; + // Honnor C++ hooks + PROCESS_HOOKS0(_pSO, xuiMenuScriptController); + // If there are no script hooks to execute, we abort here. + SCRIPT_FUNCTION_CHECKABORTEVENT; + // Otherwise we execute the script methods by calling this. + SCRIPT_EXEC_EVENT0(_pSO); +} + +scriptVar /*void */ XuiMenuScriptController::script_nextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) { + // Begin all script methods with the init block. + SCRIPT_FUNCTION_INIT; + // Find the proper pointer for the "this" object, _pSO. + XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid)); + if (_pObj) { + // Then properly call the hosted object; + _pObj->nextMenu(); + } + RETURN_SCRIPT_VOID; +} + +scriptVar /*void */ XuiMenuScriptController::script_previousMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) { + // Begin all script methods with the init block. + SCRIPT_FUNCTION_INIT; + // Find the proper pointer for the "this" object, _pSO. + XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid)); + if (_pObj) { + // Then properly call the hosted object; + _pObj->previousMenu(); + } + RETURN_SCRIPT_VOID; +} + +// Script Controller + +// This method returns the human readable name of the class in script files. +const wchar_t *XuiMenuScriptController::getClassName() { + return L"Menu"; +} + +// This method returns the human readable name of the parent of this class. +const wchar_t *XuiMenuScriptController::getAncestorClassName() { + return XUIMENU_SCRIPTPARENTCLASS; +} + +// This method returns the controller object for the parent class. +ScriptObjectController *XuiMenuScriptController::getAncestorController() { + return WASABI_API_MAKI->maki_getController(guiObjectGuid); +} + +// This method returns the number of methods this class publishes. +int XuiMenuScriptController::getNumFunctions() { + return sizeof(exportedFunctions) / sizeof(function_descriptor_struct); +} + +// This method returns the block of published function descriptors. +const function_descriptor_struct *XuiMenuScriptController::getExportedFunctions() { + return exportedFunctions; +} + +// This method returns the GUID assigned to this script class. +GUID XuiMenuScriptController::getClassGuid() { + return XuiMenuScriptGuid; +} + +// This method creates and returns a new script class instance. +ScriptObject *XuiMenuScriptController::instantiate() { + XuiMenu*_pObj = new XuiMenu(); + ASSERT(_pObj != NULL); + return _pObj->XuiMenuScriptObject::getScriptObject(); +} + +// This method deletes a given script class instance. +void XuiMenuScriptController::destroy(ScriptObject *o) { + XuiMenu*_pObj = static_cast<XuiMenu*>(o->vcpu_getInterface(XuiMenuScriptGuid)); + ASSERT(_pObj != NULL); + delete _pObj; +} + +// This method returns an encapsulated interface for the given instance. +void *XuiMenuScriptController::encapsulate(ScriptObject *o) { + // No automatic encapsulation + return NULL; +} + +// This method frees a previously encapsulated interface. +void XuiMenuScriptController::deencapsulate(void *o) { +} + diff --git a/Src/Wasabi/api/skin/widgets/xuimenuso.h b/Src/Wasabi/api/skin/widgets/xuimenuso.h new file mode 100644 index 00000000..3c09555e --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuimenuso.h @@ -0,0 +1,76 @@ +// ---------------------------------------------------------------------------- +// Generated by ScriptObjectFactory [Sun Dec 14 07:21:52 2003] +// +// File : xuimenuso.h +// Class : XuiMenuScriptObject +// class layer : Automatic Object Scripting +// ---------------------------------------------------------------------------- + +#ifndef __XUIMENUSCRIPTOBJECT_H +#define __XUIMENUSCRIPTOBJECT_H + +class XuiMenu; + +#include <api/script/objects/rootobj.h> +#include <api/script/objcontroller.h> + +#define XUIMENU_SCRIPTPARENT GuiObjectWnd +#define XUIMENU_SCRIPTPARENTCLASS L"GuiObject" + +// ---------------------------------------------------------------------------- +// {73C00594-961F-401B-9B1B-672427AC4165} +static const GUID XuiMenuScriptGuid = +{ 0x73c00594, 0x961f, 0x401b, { 0x9b, 0x1b, 0x67, 0x24, 0x27, 0xac, 65, 101 } }; +// ----------------------------------------------------------------------------- + +class XuiMenuScriptObject : public XUIMENU_SCRIPTPARENT { +protected: + XuiMenuScriptObject(); + virtual ~XuiMenuScriptObject(); + +public: + void xuiMenuScriptObject_init(); + +public: + virtual void script_onOpenMenu(); + virtual void script_onCloseMenu(); +private: +}; + +// ----------------------------------------------------------------------------- +class XuiMenuScriptController : 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); + +public: + static scriptVar script_setMenuGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar mg); + static scriptVar script_getMenuGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO); + static scriptVar script_setMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar m); + static scriptVar script_getMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO); + static scriptVar script_spawnMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar monitor); + static scriptVar script_cancelMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO); + static scriptVar script_setNormalId(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar id); + static scriptVar script_setDownId(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar id); + static scriptVar script_setHoverId(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar id); + static scriptVar script_onOpenMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO); + static scriptVar script_onCloseMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO); + static scriptVar script_nextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO); + static scriptVar script_previousMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO); + +private:static function_descriptor_struct exportedFunctions[]; +}; + +extern XuiMenuScriptController *xuiMenuScriptController; +// ---------------------------------------------------------------------------- + +#endif // __XUIMENUSCRIPTOBJECT_H diff --git a/Src/Wasabi/api/skin/widgets/xuiobjdirwnd.cpp b/Src/Wasabi/api/skin/widgets/xuiobjdirwnd.cpp new file mode 100644 index 00000000..90ac1aaa --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuiobjdirwnd.cpp @@ -0,0 +1,57 @@ +#include <precomp.h> + +#include "xuiobjdirwnd.h" + +const wchar_t ScriptObjDirWndXuiObjectStr[] = L"ObjDirView"; // This is the xml tag +char ScriptObjDirWndXuiSvcName[] = "ObjDirView xui object"; + +XMLParamPair ScriptObjDirWnd::params[] = { + {DEFAULTDISPLAY, L"DEFAULTDISPLAY"}, + {SCRIPTOBJDIRWND_DIR, L"DIR"}, + {DISPLAYTARGET, L"DISPLAYTARGET"}, + {FORCEVIRTUAL, L"FORCEVIRTUAL"}, + {SCRIPTOBJDIRWND_ACTION_TARGET, L"TARGET"}, + }; + +ScriptObjDirWnd::ScriptObjDirWnd() +{ + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); +} + +void ScriptObjDirWnd::CreateXMLParameters(int master_handle) +{ + //SCRIPTOBJDIRWND_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +ScriptObjDirWnd::~ScriptObjDirWnd() { } + +int ScriptObjDirWnd::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return SCRIPTOBJDIRWND_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + switch (xmlattributeid) { + case SCRIPTOBJDIRWND_DIR: + setTargetDirName(value); + break; + case SCRIPTOBJDIRWND_ACTION_TARGET: + setActionTarget(value); + break; + case DISPLAYTARGET: + setDisplayTarget(value); + break; + case DEFAULTDISPLAY: + setDefaultDisplay(value); + break; + case FORCEVIRTUAL: + setVirtual(WTOI(value)); + break; + default: + return 0; + } + return 1; +} + diff --git a/Src/Wasabi/api/skin/widgets/xuiobjdirwnd.h b/Src/Wasabi/api/skin/widgets/xuiobjdirwnd.h new file mode 100644 index 00000000..f28c0b9a --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuiobjdirwnd.h @@ -0,0 +1,32 @@ +#ifndef _XUIOBJDIRWND_H +#define _XUIOBJDIRWND_H + +#include <api/skin/widgets/objdirwnd.h> + +#define SCRIPTOBJDIRWND_PARENT ObjDirWnd +class ScriptObjDirWnd : public SCRIPTOBJDIRWND_PARENT { +public: + ScriptObjDirWnd(); + virtual ~ScriptObjDirWnd(); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); +protected: + /*static */void CreateXMLParameters(int master_handle); +private: + +enum { + SCRIPTOBJDIRWND_DIR=10, + SCRIPTOBJDIRWND_ACTION_TARGET=20, + DISPLAYTARGET, + DEFAULTDISPLAY, + FORCEVIRTUAL, +}; +static XMLParamPair params[]; + int myxuihandle; +}; + +extern const wchar_t ScriptObjDirWndXuiObjectStr[]; +extern char ScriptObjDirWndXuiSvcName[]; +class ScriptObjDirWndXuiSvc : public XuiObjectSvc<ScriptObjDirWnd, ScriptObjDirWndXuiObjectStr, ScriptObjDirWndXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuioswndhost.cpp b/Src/Wasabi/api/skin/widgets/xuioswndhost.cpp new file mode 100644 index 00000000..4835271f --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuioswndhost.cpp @@ -0,0 +1,306 @@ +#include <precomp.h> +#include "xuioswndhost.h" +#include <api/wnd/notifmsg.h> +#include <bfc/parse/paramparser.h> +#include <tataki/region/region.h> +#include <api/wndmgr/layout.h> +// ----------------------------------------------------------------------- +const wchar_t OSWndHostXuiObjectStr[] = L"OSWndHost"; // This is the xml tag +char OSWndHostXuiSvcName[] = "OSWndHost xui object"; + +XMLParamPair XuiOSWndHost::params[] = { + {XUIOSWNDHOST_SETHWND, L"HWND"}, + {XUIOSWNDHOST_SETOFFSETS, L"OFFSETS"}, + }; +// ----------------------------------------------------------------------- +XuiOSWndHost::XuiOSWndHost() { + hosted=false; + setStartHidden(1); + setVisible(0); + visible_start_state=1; + setVirtual(0); // we are a real window, with an hwnd and shit + hasregionrect = 0; + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); + + ScriptObject *o = getGuiObject()->guiobject_getScriptObject(); + o->vcpu_setInterface(osWndHostGuid, static_cast<OSWndHost *>(this)); +} + +void XuiOSWndHost::CreateXMLParameters(int master_handle) +{ + //XUIOSWNDHOST_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +// ----------------------------------------------------------------------- +XuiOSWndHost::~XuiOSWndHost() { +} + +void XuiOSWndHost::onSetVisible(int show) +{ + visible_start_state = show; + XUIOSWNDHOST_PARENT::onSetVisible(show); +} + +// ----------------------------------------------------------------------- +int XuiOSWndHost::onPaint(Canvas *c) { + XUIOSWNDHOST_PARENT::onPaint(c); + RECT r; + getClientRect(&r); + c->fillRect(&r, 0); + return 1; +} + +// ----------------------------------------------------------------------- +int XuiOSWndHost::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return XUIOSWNDHOST_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) { + case XUIOSWNDHOST_SETHWND: { +#ifdef _WIN64 + HWND wnd = (HWND)_wtoi64(value); +#else + HWND wnd = (HWND)WTOI(value); +#endif + if (IsWindow(wnd)) + oswndhost_host(wnd); + break; + } + case XUIOSWNDHOST_SETOFFSETS: { + ParamParser pp(value, L","); + RECT r={0,0,0,0}; + if (pp.getNumItems() > 0) + r.left = WTOI(pp.enumItem(0)); + if (pp.getNumItems() > 1) + r.top = WTOI(pp.enumItem(1)); + if (pp.getNumItems() > 2) + r.right = WTOI(pp.enumItem(2)); + if (pp.getNumItems() > 3) + r.bottom = WTOI(pp.enumItem(3)); + oswndhost_setRegionOffsets(&r); + break; + } + default: + return 0; + } + return 1; +} + +// ----------------------------------------------------------------------- +void XuiOSWndHost::oswndhost_setRegionOffsets(RECT *r) { + if (r == NULL) { + hasregionrect = 0; + if (wnd != NULL && isPostOnInit()) { + SetWindowRgn(wnd, NULL, 0); + onResize(); + } + return; + } + regionrect = *r; + hasregionrect = 1; + //if (isPostOnInit()) + //onResize(); +} + +void XuiOSWndHost::doOnResize() +{ + if (wnd != NULL) + { + RECT r; + getClientRect(&r); + if (renderRatioActive()) + { + //CUT: double ra = getRenderRatio(); + multRatio(&r); + } + + if (hasregionrect) { + r.left -= regionrect.left; + r.top -= regionrect.top; + r.right += regionrect.right; + r.bottom += regionrect.bottom; + } + SetWindowPos(wnd, NULL, r.left, r.top, r.right-r.left, r.bottom-r.top, SWP_NOZORDER|SWP_NOACTIVATE/*|SWP_NOCOPYBITS|SWP_NOREDRAW*/); + + if (hasregionrect) { + RECT cr={0,0,r.right-r.left,r.bottom-r.top}; + RECT wndr={cr.left+regionrect.left, cr.top+regionrect.top, cr.right-regionrect.right, cr.bottom-regionrect.bottom}; + + RegionI reg(&wndr); + SetWindowRgn(wnd, reg.makeWindowRegion(), TRUE); + //InvalidateRgn(wnd, reg.getOSHandle(), FALSE); + } + //else + //InvalidateRect(wnd, NULL, TRUE); + + //UpdateWindow(wnd); + //repaint(); + } +} +int XuiOSWndHost::onAfterResize() +{ + if (!XUIOSWNDHOST_PARENT::onAfterResize()) return 0; + doHost(); + doOnResize(); + + + return 1; +} +// ----------------------------------------------------------------------- + +#define STYLE_FILTER (WS_OVERLAPPEDWINDOW | WS_POPUPWINDOW | WS_DLGFRAME | WS_CHILD) +#define EXSTYLE_FILTER (WS_EX_OVERLAPPEDWINDOW | WS_EX_PALETTEWINDOW | WS_EX_CONTROLPARENT) + +void XuiOSWndHost::doHost() +{ + if (wnd && !hosted) + { + onBeforeReparent(1); + oldparent = GetAncestor(wnd, GA_PARENT); + /* + bool blah=false; + RECT r; + if (IsWindowVisible(wnd)) + { + + GetWindowRect(wnd, &r); + MapWindowPoints(HWND_DESKTOP, oldparent, (LPPOINT)&r, 2); + blah=true; + } +*/ + // remember if WS_POPUP or WS_CHILD was set so we can reset it when we unhost + + DWORD style; + style = GetWindowLongPtrW(wnd, GWL_STYLE); + savedStyle = (style & STYLE_FILTER); + SetWindowLongPtrW(wnd, GWL_STYLE, (style & ~(STYLE_FILTER)) | WS_CHILD); + style = GetWindowLongPtrW(wnd, GWL_EXSTYLE); + savedExStyle = (style & EXSTYLE_FILTER); + SetWindowLongPtrW(wnd, GWL_EXSTYLE, (style & ~(EXSTYLE_FILTER)) | WS_EX_CONTROLPARENT); + + GetWindowRect(wnd, &oldrect); + + SetParent(wnd, gethWnd()); + //if (blah) + //InvalidateRect(oldparent, &r, FALSE); + //UpdateWindow(oldparent); + SendMessageW(gethWnd(), 0x0127, MAKEWPARAM(3/*UIS_INITIALIZE*/, 3/*UISF_HIDEACCEL | UISF_HIDEFOCUS*/), 0L); + onAfterReparent(1); + dropVirtualCanvas(); // we don't need a canvas anymore, save the memory! + hosted=true; + doOnResize(); + setVisible(visible_start_state); + } +} + +// ----------------------------------------------------------------------- +void XuiOSWndHost::oswndhost_host(HWND oswnd) +{ + ASSERT(IsWindow(oswnd)); + wnd = oswnd; + if (isPostOnInit()) + doHost(); +} + +// ----------------------------------------------------------------------- +void XuiOSWndHost::oswndhost_unhost() { + if (wnd == NULL) return; + onBeforeReparent(0); + + if (IsWindow(wnd)) { + // set back the old flags + + DWORD style; + style = GetWindowLongPtrW(wnd, GWL_STYLE); + SetWindowLongPtrW(wnd, GWL_STYLE, ((style & ~STYLE_FILTER) | savedStyle)); + style = GetWindowLongPtrW(wnd, GWL_EXSTYLE); + SetWindowLongPtrW(wnd, GWL_EXSTYLE, ((style & ~EXSTYLE_FILTER) | savedExStyle)); + + int config_aot = ((GetWindowLong(WASABI_API_WND->main_getRootWnd()->gethWnd(), GWL_EXSTYLE) & WS_EX_TOPMOST) != 0); + + SetWindowPos(wnd, config_aot ? HWND_TOPMOST : HWND_NOTOPMOST, + oldrect.left, oldrect.top, oldrect.right-oldrect.left, oldrect.bottom-oldrect.top, + SWP_NOZORDER | (( 0 == config_aot) ? SWP_NOACTIVATE : 0)); + + SetParent(wnd, oldparent); + + if (hasregionrect) SetWindowRgn(wnd, NULL, 0); +// InvalidateRect(wnd, NULL, TRUE); + hosted=false; + + } + + onAfterReparent(0); + + hasregionrect = 0; + wnd = NULL; +} + +int XuiOSWndHost::onUserMessage(int msg, int w, int l, int *r) { + switch (msg) { + case OSWNDHOST_REQUEST_IDEAL_SIZE: + onDeferredCallback/*postDeferredCallback*/(DCB_OSWNDHOST_REQUEST_IDEAL_SIZE, (intptr_t)(new DCBIdealSize(w, l))); + *r = 1; + return 1; + } + return XUIOSWNDHOST_PARENT::onUserMessage(msg, w, l, r); // do default handling +} + +int XuiOSWndHost::onDeferredCallback(intptr_t p1, intptr_t p2) { + switch (p1) { + case DCB_OSWNDHOST_REQUEST_IDEAL_SIZE: + { + DCBIdealSize *ideal = (DCBIdealSize *)p2; + if (ideal == NULL) break; + + ifc_window *p=getDesktopParent(); // Gets the group/layout at the base of the wnd tree, the desktop hwnd + if (p == NULL) { + delete ideal; + break; + } + Layout *l = static_cast<Layout *>(p->getInterface(layoutGuid)); + if (l) + l->beginResize(); + RECT r,r2; + getClientRect(&r); // the size of this wnd + if (renderRatioActive()) multRatio(&r); + + p->getWindowRect(&r2); // the size of the desktop parent + + // take borders into account + int neww = ideal->m_idealwidth+((r2.right-r2.left)-(r.right-r.left)); + int newh = ideal->m_idealheight+((r2.bottom-r2.top)-(r.bottom-r.top)); + + // take layout min/max values into account + int min_w = p->getPreferences(MINIMUM_W); + int min_h = p->getPreferences(MINIMUM_H); + int max_w = p->getPreferences(MAXIMUM_W); + int max_h = p->getPreferences(MAXIMUM_H); + if (min_w != AUTOWH) neww = MAX(min_w, neww); + if (min_h != AUTOWH) newh = MAX(min_h, newh); + if (max_w != AUTOWH) neww = MIN(max_w, neww); + if (max_h != AUTOWH) newh = MIN(max_h, newh); + + //CUT: RECT res={r2.left,r2.top,neww,newh}; + p->resize(r2.left, r2.top, neww, newh); + if (l) + l->endResize(); + delete ideal; + return 1; + } + + } + return XUIOSWNDHOST_PARENT::onDeferredCallback(p1, p2); +} + +void XuiOSWndHost::onBeforeReparent(int i) { +} + +void XuiOSWndHost::onAfterReparent(int i) { +} + diff --git a/Src/Wasabi/api/skin/widgets/xuioswndhost.h b/Src/Wasabi/api/skin/widgets/xuioswndhost.h new file mode 100644 index 00000000..05359563 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuioswndhost.h @@ -0,0 +1,78 @@ +#ifndef __OSWndHost_H +#define __OSWndHost_H + +#include <api/wnd/wndclass/guiobjwnd.h> +#include <api/wnd/wndclass/oswndhost.h> + +#define XUIOSWNDHOST_PARENT GuiObjectWnd + +#define DCB_OSWNDHOST_REQUEST_IDEAL_SIZE 2048 + +#define OSWNDHOST_REQUEST_IDEAL_SIZE WM_USER + DCB_OSWNDHOST_REQUEST_IDEAL_SIZE + +class DCBIdealSize { + public: + DCBIdealSize(int idealwidth, int idealheight) : m_idealwidth(idealwidth), m_idealheight(idealheight) {} + int m_idealwidth; + int m_idealheight; +}; + +// ----------------------------------------------------------------------- +class XuiOSWndHost : public XUIOSWNDHOST_PARENT, public OSWndHostI +{ + + public: + + XuiOSWndHost(); + virtual ~XuiOSWndHost(); + virtual int onPaint(Canvas *c); + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + virtual int wantRedrawOnResize() { return 0; } + virtual int onAfterResize(); + void setHWND(const char *hwnd); + HWND getHWND() { return wnd; } + void setHWND(HWND hwnd) { wnd = hwnd; } + virtual void oswndhost_host(HWND oswnd); + virtual void oswndhost_unhost(); + virtual void oswndhost_setRegionOffsets(RECT *r); + + virtual int onUserMessage(int msg, int w, int l, int *r); + virtual int onDeferredCallback(intptr_t p1, intptr_t p2); + + virtual void onBeforeReparent(int host); + virtual void onAfterReparent(int host); + virtual int handleRatio() { return 0; } + virtual int handleDesktopAlpha() { return 0; } + void onSetVisible(int show); +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + void doOnResize(); + void doHost(); + + enum { + XUIOSWNDHOST_SETHWND = 0, + XUIOSWNDHOST_SETOFFSETS = 1, + }; + static XMLParamPair params[]; + int myxuihandle; + RECT regionrect; + int hasregionrect; + HWND wnd; + HWND oldparent; + DWORD savedStyle; + DWORD savedExStyle; + + RECT oldrect; + bool hosted; + int visible_start_state; +}; + + +// ----------------------------------------------------------------------- + +extern const wchar_t OSWndHostXuiObjectStr[]; +extern char OSWndHostXuiSvcName[]; +class OSWndHostXuiSvc : public XuiObjectSvc<XuiOSWndHost, OSWndHostXuiObjectStr, OSWndHostXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuipathpicker.cpp b/Src/Wasabi/api/skin/widgets/xuipathpicker.cpp new file mode 100644 index 00000000..45c2d27e --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuipathpicker.cpp @@ -0,0 +1,73 @@ +#include <precomp.h> +#include "xuipathpicker.h" + +// ----------------------------------------------------------------------- +const wchar_t PathPickerXuiObjectStr[] = L"Wasabi:PathPicker"; +char PathPickerXuiSvcName[] = "Wasabi:PathPicker xui object"; + +// ----------------------------------------------------------------------- +ScriptPathPicker::ScriptPathPicker() { + getScriptObject()->vcpu_setInterface(pathPickerGuid, (void *)static_cast<PathPicker *>(this)); + getScriptObject()->vcpu_setClassName(L"PathPicker"); // this is the script class name + getScriptObject()->vcpu_setController(pathPickerController); +} + +// ----------------------------------------------------------------------- +ScriptPathPicker::~ScriptPathPicker() { +} + +// ----------------------------------------------------------------------- +// Script Object + +PathPickerScriptController _pathPickerController; +PathPickerScriptController *pathPickerController = &_pathPickerController; + +// -- Functions table ------------------------------------- +function_descriptor_struct PathPickerScriptController::exportedFunction[] = { + {L"getPath", 0, (void*)PathPickerScriptController::PathPicker_getPath}, + {L"onPathChanged", 1, (void*)PathPickerScriptController::PathPicker_onPathChanged}, +}; + +ScriptObject *PathPickerScriptController::instantiate() { + ScriptPathPicker *sddl = new ScriptPathPicker; + ASSERT(sddl != NULL); + return sddl->getScriptObject(); +} + +void PathPickerScriptController::destroy(ScriptObject *o) { + ScriptPathPicker *sddl= static_cast<ScriptPathPicker *>(o->vcpu_getInterface(pathPickerGuid)); + ASSERT(sddl != NULL); + delete sddl; +} + +void *PathPickerScriptController::encapsulate(ScriptObject *o) { + return NULL; // no encapsulation +} + +void PathPickerScriptController::deencapsulate(void *o) { +} + +int PathPickerScriptController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *PathPickerScriptController::getExportedFunctions() { + return exportedFunction; +} + + +scriptVar PathPickerScriptController::PathPicker_getPath(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ScriptPathPicker *sddl = static_cast<ScriptPathPicker*>(o->vcpu_getInterface(pathPickerGuid)); + const wchar_t *p=L""; + if (sddl) p = sddl->getPath(); + return MAKE_SCRIPT_STRING(p); +} + +// PathPickerScriptController::PathPicker_onNewPath(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(newpath)); +scriptVar PathPickerScriptController::PathPicker_onPathChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newpath) { + SCRIPT_FUNCTION_INIT; + PROCESS_HOOKS1(o, pathPickerController, newpath); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, newpath); +} diff --git a/Src/Wasabi/api/skin/widgets/xuipathpicker.h b/Src/Wasabi/api/skin/widgets/xuipathpicker.h new file mode 100644 index 00000000..05ca69b0 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuipathpicker.h @@ -0,0 +1,53 @@ +#ifndef __XUIPATHPICKER_H +#define __XUIPATHPICKER_H + +#include <api/skin/widgets/pathpicker.h> +#include <api/script/objcontroller.h> + +#define SCRIPTPATHPICKER_PARENT PathPicker + +// ----------------------------------------------------------------------- +// Your wnd object class + +class ScriptPathPicker: public SCRIPTPATHPICKER_PARENT { + + public: + + ScriptPathPicker(); + virtual ~ScriptPathPicker(); + + private: +}; + +// ----------------------------------------------------------------------- +class PathPickerScriptController: public ScriptObjectControllerI { +public: + virtual const wchar_t *getClassName() { return L"PathPicker"; } + virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; } + virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); } + virtual int getNumFunctions(); + virtual const function_descriptor_struct *getExportedFunctions(); + virtual GUID getClassGuid() { return pathPickerGuid; } + virtual ScriptObject *instantiate(); + virtual void destroy(ScriptObject *o); + virtual void *encapsulate(ScriptObject *o); + virtual void deencapsulate(void *o); + +private: + + static function_descriptor_struct exportedFunction[]; + static scriptVar PathPicker_getPath(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar PathPicker_onPathChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newpath); +}; + +extern PathPickerScriptController *pathPickerController; + + +// ----------------------------------------------------------------------- +// This defines the svc_xuiObject that exposes your wnd object + +extern const wchar_t PathPickerXuiObjectStr[]; +extern char PathPickerXuiSvcName[]; +class PathPickerXuiSvc : public XuiObjectSvc<ScriptPathPicker, PathPickerXuiObjectStr, PathPickerXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuiprogressgrid.cpp b/Src/Wasabi/api/skin/widgets/xuiprogressgrid.cpp new file mode 100644 index 00000000..edb9e918 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuiprogressgrid.cpp @@ -0,0 +1,162 @@ +#include <precomp.h> +#include "xuiprogressgrid.h" +#include <tataki/canvas/ifc_canvas.h> +#include <bfc/string/stringdict.h> +#include <api/core/api_core.h> + +#define ProgressGrid_TIMER_POS 1 +#define PROGRESSGRID_INTERVAL 500 + +#ifndef _WASABIRUNTIME + +BEGIN_SERVICES(ProgressGrid_Svc); +DECLARE_SERVICE(XuiObjectCreator<ProgressGridXuiSvc>); +END_SERVICES(ProgressGrid_Svc, _ProgressGrid_Svc); + +#ifdef _X86_ +extern "C" { int _link_ProgressGridXuiSvc; } +#else +extern "C" { int __link_ProgressGridXuiSvc; } +#endif + +#endif + +BEGIN_STRINGDICTIONARY(_pgorientationvalues) +SDI(L"top", PROGRESSGRID_TOP); +SDI(L"left", PROGRESSGRID_LEFT); +SDI(L"right", PROGRESSGRID_RIGHT); +SDI(L"bottom", PROGRESSGRID_BOTTOM); +END_STRINGDICTIONARY(_pgorientationvalues, pgorientationvalues) + +// ----------------------------------------------------------------------- + +const wchar_t ProgressGridXuiObjectStr[] = L"ProgressGrid"; // xml tag +char ProgressGridXuiSvcName[] = "ProgressGrid xui object"; +XMLParamPair ProgressGrid::params[] = { + { PROGRESSGRID_SETORIENTATION, L"ORIENTATION"}, + { PROGRESSGRID_SETINTERVAL, L"INTERVAL"}, +}; + +// ----------------------------------------------------------------------- +ProgressGrid::ProgressGrid() { + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); + + orientation = PROGRESSGRID_RIGHT; + progress = 0; + started = 0; + update_interval = PROGRESSGRID_INTERVAL; +} + +void ProgressGrid::CreateXMLParameters(int master_handle) +{ + //PROGRESSGRID_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +// ----------------------------------------------------------------------- +ProgressGrid::~ProgressGrid() { + killTimer(ProgressGrid_TIMER_POS); + WASABI_API_MEDIACORE->core_delCallback(0, this); +} + +// ----------------------------------------------------------------------- +int ProgressGrid::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return PROGRESSGRID_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) { + case PROGRESSGRID_SETORIENTATION: + setOrientation(value); + break; + + case PROGRESSGRID_SETINTERVAL: + if ((update_interval = WTOI(value)) <= 20) + update_interval = PROGRESSGRID_INTERVAL; + break; + + default: + return 0; + } + return 1; +} + +// ----------------------------------------------------------------------- +void ProgressGrid::setOrientation(const wchar_t *or) { + int a = pgorientationvalues.getId(or); + if (orientation == a) return; + orientation = a; + invalidate(); +} + +// ----------------------------------------------------------------------- +void ProgressGrid::getGridRect(RECT *r) { + RECT cr; + getClientRect(&cr); + float p = started ? progress : 0.0f; + int height = (int)((float)(cr.bottom - cr.top) * p); + int width = (int)((float)(cr.right - cr.left) * p); + + switch (orientation) { + case PROGRESSGRID_LEFT: cr.left = cr.right - width; break; + case PROGRESSGRID_TOP: cr.top = cr.bottom - height; break; + case PROGRESSGRID_RIGHT: cr.right = cr.left + width; break; + case PROGRESSGRID_BOTTOM: cr.bottom = cr.top + height; break; + } + *r = cr; +} + +// ----------------------------------------------------------------------- +int ProgressGrid::onInit() { + PROGRESSGRID_PARENT::onInit(); + timerCallback(ProgressGrid_TIMER_POS); + setTimer(ProgressGrid_TIMER_POS, update_interval); + WASABI_API_MEDIACORE->core_addCallback(0, this); + if (WASABI_API_MEDIACORE->core_getStatus(0) != 0) started = 1; else started = 0; + return 1; +} + +// ----------------------------------------------------------------------- +int ProgressGrid::corecb_onSeeked(int newpos) { + if(!started) corecb_onStarted(); + int len = WASABI_API_MEDIACORE->core_getLength(0); + if (newpos == -1 || len <= 0) setProgress(0); + else setProgress(((float)newpos/(float)len)); + return 0; +} + +// ----------------------------------------------------------------------- +int ProgressGrid::corecb_onStarted() { + started = 1; + invalidate(); + return 0; +} + +// ----------------------------------------------------------------------- +int ProgressGrid::corecb_onStopped() { + started = 0; + progress = 0.0f; + invalidate(); + return 0; +} + +void ProgressGrid::setProgress(float p) { + if (progress == p) return; + progress = p; + invalidate(); +} + +void ProgressGrid::timerCallback(int id) { + switch (id) { + case ProgressGrid_TIMER_POS: { + int playpos = WASABI_API_MEDIACORE->core_getPosition(0); + corecb_onSeeked(playpos); + } + break; + default: + PROGRESSGRID_PARENT::timerCallback(id); + } +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/xuiprogressgrid.h b/Src/Wasabi/api/skin/widgets/xuiprogressgrid.h new file mode 100644 index 00000000..ba215bfa --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuiprogressgrid.h @@ -0,0 +1,59 @@ +#ifndef __PROGRESSGRID_H +#define __PROGRESSGRID_H + +#include <api/wnd/wndclass/guiobjwnd.h> +#include "xuigrid.h" +#include <api/syscb/callbacks/corecbi.h> + +#define PROGRESSGRID_PARENT Grid + +enum { + PROGRESSGRID_TOP = 0, + PROGRESSGRID_LEFT = 1, + PROGRESSGRID_RIGHT = 2, + PROGRESSGRID_BOTTOM = 3, +}; + +// ----------------------------------------------------------------------- +class ProgressGrid : public PROGRESSGRID_PARENT, public CoreCallbackI { + + public: + + ProgressGrid(); + virtual ~ProgressGrid(); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + virtual void setOrientation(const wchar_t *or); + virtual void getGridRect(RECT *r); + + virtual void setProgress(float p); // 0..1 + + virtual int onInit(); + virtual int corecb_onSeeked(int newpos); + virtual int corecb_onStarted(); + virtual int corecb_onStopped(); + virtual void timerCallback(int id); +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + + enum { + PROGRESSGRID_SETORIENTATION = 0, + PROGRESSGRID_SETINTERVAL = 1, + }; + static XMLParamPair params[]; + int orientation; + int myxuihandle; + float progress; + int started; + int update_interval; +}; + + +// ----------------------------------------------------------------------- +extern const wchar_t ProgressGridXuiObjectStr[]; +extern char ProgressGridXuiSvcName[]; +class ProgressGridXuiSvc : public XuiObjectSvc<ProgressGrid, ProgressGridXuiObjectStr, ProgressGridXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuiradiogroup.cpp b/Src/Wasabi/api/skin/widgets/xuiradiogroup.cpp new file mode 100644 index 00000000..c25ee183 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuiradiogroup.cpp @@ -0,0 +1,17 @@ +#include <precomp.h> +#include "xuiradiogroup.h" +#include <bfc/parse/paramparser.h> +#include <api/script/objects/c_script/c_text.h> + +// ----------------------------------------------------------------------- +const wchar_t ScriptRadioGroupXuiObjectStr[] = L"Wasabi:RadioGroup"; // This is the xml tag +char ScriptRadioGroupXuiSvcName[] = "Wasabi:RadioGroup xui object"; + +// ----------------------------------------------------------------------- +ScriptRadioGroup::ScriptRadioGroup() : SCRIPTRADIOGROUP_PARENT(), myxuihandle(0) { +} + +// ----------------------------------------------------------------------- +ScriptRadioGroup::~ScriptRadioGroup() { +} + diff --git a/Src/Wasabi/api/skin/widgets/xuiradiogroup.h b/Src/Wasabi/api/skin/widgets/xuiradiogroup.h new file mode 100644 index 00000000..7ac7e636 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuiradiogroup.h @@ -0,0 +1,30 @@ +#ifndef __SCRIPTRADIOGROUP_H +#define __SCRIPTRADIOGROUP_H + +#include <api/skin/widgets/guiradiogroup.h> +#include <api/script/objects/c_script/h_guiobject.h> + +#define SCRIPTRADIOGROUP_PARENT GuiRadioGroup + +// ----------------------------------------------------------------------- +// Your wnd object class +class ScriptRadioGroup : public SCRIPTRADIOGROUP_PARENT { + + public: + + ScriptRadioGroup(); + virtual ~ScriptRadioGroup(); + + private: + + int myxuihandle; +}; + +// ----------------------------------------------------------------------- +// This defines the svc_xuiObject that exposes your wnd object + +extern const wchar_t ScriptRadioGroupXuiObjectStr[]; +extern char ScriptRadioGroupXuiSvcName[]; +class ScriptRadioGroupXuiSvc : public XuiObjectSvc<ScriptRadioGroup, ScriptRadioGroupXuiObjectStr, ScriptRadioGroupXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuirect.cpp b/Src/Wasabi/api/skin/widgets/xuirect.cpp new file mode 100644 index 00000000..dd692893 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuirect.cpp @@ -0,0 +1,186 @@ +#include <precomp.h> +#include "xuirect.h" + +#include <tataki/canvas/ifc_canvas.h> +#include <bfc/parse/paramparser.h> +#include <api/skin/skinfilter.h> +#include <api/wnd/PaintCanvas.h> + +#define BLTSIZE 1 + + +namespace RectEdges +{ +enum { LEFT = 1, RIGHT = 2, TOP = 4, BOTTOM = 8 }; +}; +using namespace RectEdges; + +XMLParamPair ScriptRect::params[] = { + {SCRIPTRECT_SETCOLOR, L"COLOR"}, + {SCRIPTRECT_EDGES, L"EDGES"}, + {SCRIPTRECT_SETFILLED, L"FILLED"}, + {SCRIPTRECT_GAMMAGROUP, L"GAMMAGROUP"}, + {SCRIPTRECT_THICKNESS, L"THICKNESS"}, + }; + +ScriptRect::ScriptRect() + : pixel(BLTSIZE, BLTSIZE, NULL) +{ + filled = 0; + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); + color.setColorGroup(L""); + + resetPixel(); + edges = LEFT | RIGHT | TOP | BOTTOM; + thickness = 1; +} + +void ScriptRect::CreateXMLParameters(int master_handle) +{ + //SCRIPTRECT_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + if (params[i].id == SCRIPTRECT_SETCOLOR) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_REQUIRED); + else + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +ScriptRect::~ScriptRect() +{} + +int ScriptRect::onInit() +{ + SCRIPTRECT_PARENT::onInit(); + return 1; +} + +int ScriptRect::onPaint(Canvas *c) +{ + if (c == NULL) + { + PaintCanvas pc; + if (!pc.beginPaint(this)) return 0; + return ScriptRect::onPaint(&pc); + } + + // check for colors changing on us + if (!color.iteratorValid()) resetPixel(); + + //RECT src = {0, 0, BLTSIZE, BLTSIZE}; + if (filled) + { + RECT dst; + getClientRect(&dst); + c->fillRectAlpha(&dst, color.v(), getPaintingAlpha()); +// pixel./*getSkinBitmap()->*/stretchToRectAlpha(c, &src, &dst, getPaintingAlpha()); + } + else + { + RECT dst, odst; + getClientRect(&odst); + if (edges & TOP) + { + dst = odst; + dst.bottom = dst.top + thickness; + c->fillRectAlpha(&dst, color.v(), getPaintingAlpha()); + //pixel./*getSkinBitmap()->*/stretchToRectAlpha(c, &src, &dst, getPaintingAlpha()); + } + if (edges & BOTTOM) + { + dst = odst; + dst.top = dst.bottom - thickness; + c->fillRectAlpha(&dst, color.v(), getPaintingAlpha()); + //pixel./*getSkinBitmap()->*/stretchToRectAlpha(c, &src, &dst, getPaintingAlpha()); + } + if (edges & RIGHT) + { + dst = odst; + dst.top++; dst.bottom--; + dst.left = dst.right - thickness; + c->fillRectAlpha(&dst, color.v(), getPaintingAlpha()); + //pixel./*getSkinBitmap()->*/stretchToRectAlpha(c, &src, &dst, getPaintingAlpha()); + } + if (edges & LEFT) + { + dst = odst; + dst.right = dst.left + thickness; + c->fillRectAlpha(&dst, color.v(), getPaintingAlpha()); + //pixel./*getSkinBitmap()->*/stretchToRectAlpha(c, &src, &dst, getPaintingAlpha()); + + } + } + + return 1; +} + +int ScriptRect::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) +{ + if (xuihandle != myxuihandle) + return SCRIPTRECT_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) + { + case SCRIPTRECT_SETCOLOR: + { + ARGB32 prev_color = color; + color.setElementName(value); + //CUT color = WASABI_API_SKIN->skin_getColorElement((char*)value); + if (color.v() != prev_color) + { + //CUT? ApplySkinFilters::apply(NULL, getXmlParamByName("gammagroup"), &color, BLTSIZE, BLTSIZE); + resetPixel(); + invalidate(); + } + } + break; + case SCRIPTRECT_GAMMAGROUP: + { + ARGB32 prev_color = color; + color.setColorGroup(value); + if (color.v() != prev_color) + { + resetPixel(); + invalidate(); + } + } + break; + case SCRIPTRECT_SETFILLED: + { + int was_filled = filled; + filled = WTOI(value); + if (was_filled != filled) invalidate(); + } + break; + case SCRIPTRECT_EDGES: + { + int prev_edges = edges; + ParamParser pp((const wchar_t *)value); + edges = 0; + edges |= !!pp.hasString(L"left") * LEFT; + edges |= !!pp.hasString(L"right") * RIGHT; + edges |= !!pp.hasString(L"top") * TOP; + edges |= !!pp.hasString(L"bottom") * BOTTOM; + if (edges != prev_edges) invalidate(); + } + break; + case SCRIPTRECT_THICKNESS: + { + int prev_thickness = thickness; + thickness = WTOI(value); + if (thickness < 1) thickness = 1; + if (thickness != prev_thickness) invalidate(); + } + break; + default: + return 0; + } + return 1; +} + +void ScriptRect::resetPixel() +{ + pixel.fillBits(0xFF000000 | RGBTOBGR(color.v())); +} diff --git a/Src/Wasabi/api/skin/widgets/xuirect.h b/Src/Wasabi/api/skin/widgets/xuirect.h new file mode 100644 index 00000000..e986d6d1 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuirect.h @@ -0,0 +1,43 @@ +#ifndef _XUIRECT_H +#define _XUIRECT_H + +#include <api/wnd/wndclass/guiobjwnd.h> +#include <tataki/color/skinclr.h> +#include <tataki/canvas/bltcanvas.h> +#define SCRIPTRECT_PARENT GuiObjectWnd +class ScriptRect : public SCRIPTRECT_PARENT { +public: + static const wchar_t *xuiobject_getXmlTag() { return L"Rect"; } + static const char *xuiobject_getServiceName() { return "Rect XuiObject"; } + + ScriptRect(); + virtual ~ScriptRect(); + + virtual int onInit(); + + virtual int onPaint(Canvas *c); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + +protected: + /*static */void CreateXMLParameters(int master_handle); +private: + enum { + SCRIPTRECT_SETCOLOR = 0, + SCRIPTRECT_SETFILLED, + SCRIPTRECT_EDGES, + SCRIPTRECT_THICKNESS, + SCRIPTRECT_GAMMAGROUP, +}; + static XMLParamPair params[]; + void resetPixel(); + + int myxuihandle; + SkinColor color; + int filled, edges, thickness; + BltCanvas pixel; +}; + +class ScriptRectXuiSvc : public XuiObjectSvc2<ScriptRect> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuisendparams.cpp b/Src/Wasabi/api/skin/widgets/xuisendparams.cpp new file mode 100644 index 00000000..64a03633 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuisendparams.cpp @@ -0,0 +1,37 @@ +#include <precomp.h> +#include "xuisendparams.h" +#include <api/script/scriptguid.h> + +// ----------------------------------------------------------------------- +const wchar_t SendParamsXuiObjectStr[] = L"SendParams"; // This is the xml tag +char SendParamsXuiSvcName[] = "SendParams xui object"; + +// ----------------------------------------------------------------------- +SendParams::SendParams():myxuihandle(0) { +} + +// ----------------------------------------------------------------------- +SendParams::~SendParams() { + pastlist.deleteAll(); +} + +// ----------------------------------------------------------------------- +int SendParams::setXmlParam(const wchar_t *param, const wchar_t *value) +{ + int r = SENDPARAMS_PARENT::setXmlParam(param, value); + if (!WCSCASEEQLSAFE(param, L"group") && !WCSCASEEQLSAFE(param, L"target")) { + Pair<StringW, StringW> *pair = new Pair<StringW, StringW>(param, value); + pastlist.addItem(pair); + } + return r; +} + +// ----------------------------------------------------------------------- +void SendParams::actuator_onPerform(GuiObject *target) { // guaranteed non NULL + SENDPARAMS_PARENT::actuator_onPerform(target); + XmlObject *xtarget = static_cast<XmlObject *>(target->guiobject_getScriptObject()->vcpu_getInterface(xmlObjectGuid)); + foreach(pastlist) + xtarget->setXmlParam(pastlist.getfor()->a, pastlist.getfor()->b); + endfor; +} + diff --git a/Src/Wasabi/api/skin/widgets/xuisendparams.h b/Src/Wasabi/api/skin/widgets/xuisendparams.h new file mode 100644 index 00000000..0096ed89 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuisendparams.h @@ -0,0 +1,36 @@ +#ifndef __SENDPARAMS_H +#define __SENDPARAMS_H + +#include <api/skin/objectactuator.h> +#include <bfc/pair.h> + +#define SENDPARAMS_PARENT ObjectActuator + +extern const wchar_t SendParamsXuiObjectStr[]; +extern char SendParamsXuiSvcName[]; + +// ----------------------------------------------------------------------- +// Your wnd object class +class SendParams: public SENDPARAMS_PARENT { + + public: + + SendParams(); + virtual ~SendParams(); + + virtual int setXmlParam(const wchar_t *param, const wchar_t *value); + virtual void actuator_onPerform(GuiObject *target); + virtual const wchar_t *getActuatorTag() { return SendParamsXuiObjectStr; } // for error msgs purposes + + private: + + int myxuihandle; + PtrList< Pair<StringW, StringW> > pastlist; +}; + +// ----------------------------------------------------------------------- +// This defines the svc_xuiObject that exposes your wnd object + +class SendParamsXuiSvc : public XuiObjectSvc<SendParams, SendParamsXuiObjectStr, SendParamsXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuistatus.cpp b/Src/Wasabi/api/skin/widgets/xuistatus.cpp new file mode 100644 index 00000000..efc10ddd --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuistatus.cpp @@ -0,0 +1,98 @@ +#include <precomp.h> +#include "xuistatus.h" + +const wchar_t StatusXuiObjectStr[] = L"LayoutStatus"; // This is the xml tag +char StatusXuiSvcName[] = "Status xui object"; + +LayoutStatusController _layoutStatusController; +LayoutStatusController *layoutStatusController = &_layoutStatusController; + + +XMLParamPair XuiStatus::params[] = { + {EXCLUDE, L"EXCLUDE"}, + {INCLUDE, L"INCLUDEONLY"}, + }; + +XuiStatus::XuiStatus() { + getScriptObject()->vcpu_setInterface(layoutStatusGuid, (void *)static_cast<XuiStatus *>(this)); + getScriptObject()->vcpu_setClassName(L"LayoutStatus"); // this is the script class name + getScriptObject()->vcpu_setController(layoutStatusController); + + myxuihandle = newXuiHandle(); +CreateXMLParameters(myxuihandle); +} + +void XuiStatus::CreateXMLParameters(int master_handle) +{ + //XUISTATUS_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +int XuiStatus::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return XUISTATUS_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + switch (xmlattributeid) { + case EXCLUDE: + setExclude(value); + break; + case INCLUDE: + setIncludeOnly(value); + break; + default: + return 0; + } + return 1; +} + +// ----------------------------------------------------------------------- +void XuiStatus::callme(const wchar_t *str) +{ + fakeButtonPush(str); +} + +// ----------------------------------------------------------------------- +// Script Object + +// -- Functions table ------------------------------------- +function_descriptor_struct LayoutStatusController::exportedFunction[] = { + {L"callme", 1, (void*)LayoutStatusController::layoutstatus_callme }, +}; + +ScriptObject *LayoutStatusController::instantiate() { + XuiStatus *xs = new XuiStatus; + ASSERT(xs != NULL); + return xs->getScriptObject(); +} + +void LayoutStatusController::destroy(ScriptObject *o) { + XuiStatus *xs = static_cast<XuiStatus *>(o->vcpu_getInterface(layoutStatusGuid)); + ASSERT(xs!= NULL); + delete xs; +} + +void *LayoutStatusController::encapsulate(ScriptObject *o) { + return NULL; // no encapsulation for layoutstatus yet +} + +void LayoutStatusController::deencapsulate(void *o) { +} + +int LayoutStatusController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *LayoutStatusController::getExportedFunctions() { + return exportedFunction; +} + + +scriptVar LayoutStatusController::layoutstatus_callme(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str) { + SCRIPT_FUNCTION_INIT + XuiStatus *xs = static_cast<XuiStatus *>(o->vcpu_getInterface(layoutStatusGuid)); + if (xs) xs->callme(GET_SCRIPT_STRING(str)); + RETURN_SCRIPT_VOID; +} + diff --git a/Src/Wasabi/api/skin/widgets/xuistatus.h b/Src/Wasabi/api/skin/widgets/xuistatus.h new file mode 100644 index 00000000..972190e3 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuistatus.h @@ -0,0 +1,54 @@ +#ifndef __XUISTATUS_H +#define __XUISTATUS_H + +#include <api/wnd/wndclass/status.h> +#include <api/script/objcontroller.h> + +#define XUISTATUS_PARENT StatusBar +class XuiStatus : public XUISTATUS_PARENT { +public: + XuiStatus(); + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + virtual void callme(const wchar_t *txt); +protected: + /*static */void CreateXMLParameters(int master_handle); +private: + +enum { + EXCLUDE, INCLUDE +}; + static XMLParamPair params[]; + int myxuihandle; +}; + +extern const wchar_t StatusXuiObjectStr[]; +extern char StatusXuiSvcName[]; +class LayoutStatusXuiSvc : public XuiObjectSvc<XuiStatus, StatusXuiObjectStr, StatusXuiSvcName> {}; + +// ----------------------------------------------------------------------------------------------------- +class LayoutStatusController : public ScriptObjectControllerI { + public: + + virtual const wchar_t *getClassName() { return L"LayoutStatus"; } + virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; } + virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); } + virtual int getNumFunctions(); + virtual const function_descriptor_struct *getExportedFunctions(); + virtual GUID getClassGuid() { return layoutStatusGuid; } + virtual ScriptObject *instantiate(); + virtual void destroy(ScriptObject *o); + virtual void *encapsulate(ScriptObject *o); + virtual void deencapsulate(void *o); + + public: + static scriptVar layoutstatus_callme(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str); + + private: + + static function_descriptor_struct exportedFunction[]; +}; + +extern LayoutStatusController *layoutStatusController; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuitabsheet.cpp b/Src/Wasabi/api/skin/widgets/xuitabsheet.cpp new file mode 100644 index 00000000..4b777e64 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuitabsheet.cpp @@ -0,0 +1,217 @@ +#include <precomp.h> +#include "xuitabsheet.h" +#include <bfc/parse/paramparser.h> +static ScriptTabSheetController TabsheetController; +ScriptTabSheetController *tabsheetController=&TabsheetController; + +// ----------------------------------------------------------------------- +const wchar_t ScriptTabSheetXuiObjectStr[] = L"Wasabi:TabSheet"; // This is the xml tag +char ScriptTabSheetXuiSvcName[] = "Wasabi:TabSheet xui object"; + +XMLParamPair ScriptTabSheet::params[] = { + + {SCRIPTTABSHEET_SETCHILDREN, L"CHILDREN"}, + {SCRIPTTABSHEET_SETCONTENTMARGINBOTTOM, L"CONTENT_MARGIN_BOTTOM"}, + {SCRIPTTABSHEET_SETCONTENTMARGINLEFT, L"CONTENT_MARGIN_LEFT"}, + {SCRIPTTABSHEET_SETCONTENTMARGINRIGHT, L"CONTENT_MARGIN_RIGHT"}, + {SCRIPTTABSHEET_SETCONTENTMARGINTOP, L"CONTENT_MARGIN_TOP"}, + {SCRIPTTABSHEET_SETTYPE, L"TYPE"}, + {SCRIPTTABSHEET_SETWINDOWTYPE, L"WINDOWTYPE"}, + }; +// ----------------------------------------------------------------------- +ScriptTabSheet::ScriptTabSheet() : TypeSheet(0) { + getScriptObject()->vcpu_setInterface(tabsheetGuid, (void *)static_cast<ScriptTabSheet*>(this)); + getScriptObject()->vcpu_setClassName(L"TabSheet"); // this is the script class name + getScriptObject()->vcpu_setController(tabsheetController); + + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); + + wndtype = 0; + type = TABSHEET_GROUPS; + left_margin = right_margin = bottom_margin = top_margin = 0; +} + +void ScriptTabSheet::CreateXMLParameters(int master_handle) +{ + //SCRIPTTABSHEET_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +// ----------------------------------------------------------------------- +ScriptTabSheet::~ScriptTabSheet() { + children_id.deleteAll(); +} + +// ----------------------------------------------------------------------- +int ScriptTabSheet::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) +{ + if (xuihandle != myxuihandle) + return SCRIPTTABSHEET_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) + { + case SCRIPTTABSHEET_SETWINDOWTYPE: + setWindowType(value); + break; + case SCRIPTTABSHEET_SETCHILDREN: + setChildrenIds(value); + break; + case SCRIPTTABSHEET_SETTYPE: + setType(value); + break; + case SCRIPTTABSHEET_SETCONTENTMARGINLEFT: + case SCRIPTTABSHEET_SETCONTENTMARGINTOP: + case SCRIPTTABSHEET_SETCONTENTMARGINRIGHT: + case SCRIPTTABSHEET_SETCONTENTMARGINBOTTOM: + setContentMarginX(value, xmlattributeid); + break; + default: + return 0; + } + return 1; +} + +// ----------------------------------------------------------------------- +void ScriptTabSheet::setWindowType(const wchar_t *paramvalue) { + if (WCSEQLSAFE(wndtype, paramvalue)) return; + wndtype = paramvalue; + reloadChildren(); +} + +// ----------------------------------------------------------------------- +void ScriptTabSheet::setChildrenIds(const wchar_t *paramvalue) { + if (WCSEQLSAFE(paramvalue, L"")) { + children_id.removeAll(); + } + ParamParser pp(paramvalue); + for (int i=0;i<pp.getNumItems();i++) + children_id.addItem(new StringW(pp.enumItem(i))); + reloadChildren(); +} + +// ----------------------------------------------------------------------- +void ScriptTabSheet::setType(const wchar_t *paramvalue) { + int ttype = WTOI(paramvalue); + if (type == ttype) return; + type = ttype; + setButtonType(type); +} + +// ----------------------------------------------------------------------- +void ScriptTabSheet::reloadChildren() { + if (!isInited()) return; + killChildren(); + for (int i=0;i<children_id.getNumItems();i++) { + GuiObjectWnd *w = new GuiObjectWnd; + //w->abstract_setAllowDeferredContent(1); + w->setContent(children_id.enumItem(i)->getValue()); + addChild(w); + } + TypeSheet::setWindowType(wndtype); + if (!wndtype.isempty()) + TypeSheet::load(); +} + +// ----------------------------------------------------------------------- +int ScriptTabSheet::onInit() { + int r = SCRIPTTABSHEET_PARENT::onInit(); + setButtonType(type); + reloadChildren(); + return r; +} + +void ScriptTabSheet::setContentMarginX(const wchar_t *value, int what) { + switch (what) { + case SCRIPTTABSHEET_SETCONTENTMARGINLEFT: + setContentMarginLeft(WTOI(value)); + break; + case SCRIPTTABSHEET_SETCONTENTMARGINTOP: + setContentMarginTop(WTOI(value)); + break; + case SCRIPTTABSHEET_SETCONTENTMARGINRIGHT: + setContentMarginRight(WTOI(value)); + break; + case SCRIPTTABSHEET_SETCONTENTMARGINBOTTOM: + setContentMarginBottom(WTOI(value)); + break; + } +} + +// ----------------------------------------------------------------------- +// Script Object + +// -- Functions table ------------------------------------- +function_descriptor_struct ScriptTabSheetController::exportedFunction[] = { + {L"getCurPage", 0, (void*)ScriptTabSheetController::tabsheet_getCurPage }, + {L"setCurPage", 1, (void*)ScriptTabSheetController::tabsheet_setCurPage }, +}; + +ScriptObject *ScriptTabSheetController::instantiate() { + ScriptTabSheet *sts = new ScriptTabSheet; + ASSERT(sts != NULL); + return sts->getScriptObject(); +} + +void ScriptTabSheetController::destroy(ScriptObject *o) { + ScriptTabSheet *sts = static_cast<ScriptTabSheet *>(o->vcpu_getInterface(tabsheetGuid)); + ASSERT(sts != NULL); + delete sts; +} + +void *ScriptTabSheetController::encapsulate(ScriptObject *o) { + return NULL; // no encapsulation for tabsheet yet +} + +void ScriptTabSheetController::deencapsulate(void *o) { +} + +int ScriptTabSheetController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *ScriptTabSheetController::getExportedFunctions() { + return exportedFunction; +} + + +scriptVar ScriptTabSheetController::tabsheet_getCurPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ScriptTabSheet *sts = static_cast<ScriptTabSheet *>(o->vcpu_getInterface(tabsheetGuid)); + int a = 0; + if (sts) a = sts->getCurPage(); + return MAKE_SCRIPT_INT(a); +} + +scriptVar ScriptTabSheetController::tabsheet_getNumPages(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ScriptTabSheet *sts = static_cast<ScriptTabSheet *>(o->vcpu_getInterface(tabsheetGuid)); + int a = 0; + if (sts) a = sts->getNumPages(); + return MAKE_SCRIPT_INT(a); +} + +scriptVar ScriptTabSheetController::tabsheet_setCurPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a) { + SCRIPT_FUNCTION_INIT + ScriptTabSheet *sts = static_cast<ScriptTabSheet *>(o->vcpu_getInterface(tabsheetGuid)); + int _a = GET_SCRIPT_INT(a); + if (sts) sts->setCurPage(_a); + RETURN_SCRIPT_VOID; +} + +scriptVar ScriptTabSheetController::tabsheet_nextPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ScriptTabSheet *sts = static_cast<ScriptTabSheet *>(o->vcpu_getInterface(tabsheetGuid)); + if (sts) sts->nextPage(); + RETURN_SCRIPT_VOID; +} + +scriptVar ScriptTabSheetController::tabsheet_previousPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ScriptTabSheet *sts = static_cast<ScriptTabSheet *>(o->vcpu_getInterface(tabsheetGuid)); + if (sts) sts->previousPage(); + RETURN_SCRIPT_VOID; +} diff --git a/Src/Wasabi/api/skin/widgets/xuitabsheet.h b/Src/Wasabi/api/skin/widgets/xuitabsheet.h new file mode 100644 index 00000000..efb17222 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuitabsheet.h @@ -0,0 +1,91 @@ +#ifndef __SCRIPTTABSHEET_H +#define __SCRIPTTABSHEET_H + +#include <api/wnd/wndclass/typesheet.h> +#include <api/script/objcontroller.h> + +#define SCRIPTTABSHEET_PARENT TypeSheet + +// ----------------------------------------------------------------------- +// Your wnd object class + +class ScriptTabSheet : public SCRIPTTABSHEET_PARENT { + + public: + + ScriptTabSheet(); + virtual ~ScriptTabSheet(); + + // XuiObject automatically calls this back for all parameters registered using addParam + // encountered in the xml source + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + void setWindowType(const wchar_t *elementname); + void setChildrenIds(const wchar_t *paramvalue); + void setType(const wchar_t *element); + virtual int onInit(); + + void setContentMarginX(const wchar_t *value, int what); +protected: + void CreateXMLParameters(int master_handle); + private: + + // a list of IDs for our xml attributes, we use them in addParam() in the constructor + enum { + SCRIPTTABSHEET_SETWINDOWTYPE = 0, + SCRIPTTABSHEET_SETCHILDREN, + SCRIPTTABSHEET_SETTYPE, + SCRIPTTABSHEET_SETCONTENTMARGINLEFT, + SCRIPTTABSHEET_SETCONTENTMARGINTOP, + SCRIPTTABSHEET_SETCONTENTMARGINRIGHT, + SCRIPTTABSHEET_SETCONTENTMARGINBOTTOM, + }; + static XMLParamPair params[]; + int myxuihandle; + PtrList<StringW> children_id; + void reloadChildren(); + int type; + StringW wndtype; + + int left_margin, right_margin, top_margin, bottom_margin; +}; + + +// ----------------------------------------------------------------------- +// This defines the svc_xuiObject that exposes your wnd object + +extern const wchar_t ScriptTabSheetXuiObjectStr[]; +extern char ScriptTabSheetXuiSvcName[]; +class ScriptTabSheetXuiSvc : public XuiObjectSvc<ScriptTabSheet, ScriptTabSheetXuiObjectStr, ScriptTabSheetXuiSvcName> {}; + +// ----------------------------------------------------------------------------------------------------- +class ScriptTabSheetController : public ScriptObjectControllerI { + public: + + virtual const wchar_t *getClassName() { return L"TabSheet"; } + virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; } + virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); } + virtual int getNumFunctions(); + virtual const function_descriptor_struct *getExportedFunctions(); + virtual GUID getClassGuid() { return tabsheetGuid; } + virtual ScriptObject *instantiate(); + virtual void destroy(ScriptObject *o); + virtual void *encapsulate(ScriptObject *o); + virtual void deencapsulate(void *o); + + public: + static scriptVar tabsheet_getCurPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar tabsheet_setCurPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a); + static scriptVar tabsheet_getNumPages(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar tabsheet_nextPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar tabsheet_previousPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + + private: + + static function_descriptor_struct exportedFunction[]; +}; + +extern ScriptTabSheetController *tabsheetController; + +#endif + diff --git a/Src/Wasabi/api/skin/widgets/xuithemeslist.cpp b/Src/Wasabi/api/skin/widgets/xuithemeslist.cpp new file mode 100644 index 00000000..c86c8142 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuithemeslist.cpp @@ -0,0 +1,365 @@ +#include <precomp.h> +#include "xuithemeslist.h" +#include <api/wnd/popup.h> +#include "../Agave/Language/api_language.h" +#include "resource.h" + +#ifndef _WASABIRUNTIME + +BEGIN_SERVICES(ColorThemesList_Svc); +DECLARE_SERVICE(XuiObjectCreator<ColorThemesListXuiSvc>); +DECLARE_SERVICE(XuiObjectCreator<NakedColorThemesListXuiSvc>); +DECLARE_SERVICE(ActionCreator<ThemesSlotActionSvc>); +END_SERVICES(ColorThemesList_Svc, _ColorThemesList_Svc); + +#ifdef _X86_ +extern "C" { int _link_ColorThemesListXuiSvc; } +#else +extern "C" { int __link_ColorThemesListXuiSvc; } +#endif + +#endif + +int ThemesSlotActionSvc::onActionId(int pvtid, const wchar_t *action, const wchar_t *param, int p1, int p2, void *data, int datalen, ifc_window *source) { + PopupMenu p_load; + for (int i=0;i<10;i++) + { + StringW s = ColorThemesList::getSlot(i), no_set = WASABI_API_LNGSTRINGW(IDS_NO_SET); + p_load.addCommand(StringPrintfW(WASABI_API_LNGSTRINGW(IDS_SLOT_X_X), i+1, s.isempty() ? no_set/*L"no set"*/ : s), 200+i, 0, s.isempty()); + } + int r = p_load.popAtMouse(); + if (r >= 200 && r < 210) + { + StringW set = ColorThemesList::getSlot(r-200); + if (!set.isempty()) + WASABI_API_SKIN->colortheme_setColorSet(set); + } + return 1; +} + +// ----------------------------------------------------------------------- +const wchar_t ColorThemesListXuiObjectStr[] = L"ColorThemes:List"; // This is the xml tag +char ColorThemesListXuiSvcName[] = "ColorThemes:List xui object"; +const wchar_t NakedColorThemesListXuiObjectStr[] = L"ColorThemes:Mgr"; // This is the xml tag +char NakedColorThemesListXuiSvcName[] = "ColorThemes:Mgr xui object"; + +XMLParamPair ColorThemesList::params[] = { + {CTLIST_NOHSCROLL, L"NOHSCROLL"}, +}; + +// ----------------------------------------------------------------------- +ColorThemesList::ColorThemesList() { + setPreventMultipleSelection(1); + ensure_on_paint = -1; + setAutoSort(1); + nohscroll = 0; + xuihandle = newXuiHandle(); + CreateXMLParameters(xuihandle); + WASABI_API_SYSCB->syscb_registerCallback(static_cast<SkinCallbackI*>(this)); +} + +void ColorThemesList::CreateXMLParameters(int master_handle) +{ + //THEMESLIST_PARENT::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); +} + +// ----------------------------------------------------------------------- +ColorThemesList::~ColorThemesList() { + WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SkinCallbackI*>(this)); +} + +// ----------------------------------------------------------------------- +NakedColorThemesList::NakedColorThemesList() { + xuihandle = newXuiHandle(); + WASABI_API_SYSCB->syscb_registerCallback(static_cast<SkinCallbackI*>(this)); +} + +// ----------------------------------------------------------------------- +NakedColorThemesList::~NakedColorThemesList() { + items.deleteAll(); + WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SkinCallbackI*>(this)); +} + +// ----------------------------------------------------------------------- +int ColorThemesList::onInit() { + THEMESLIST_PARENT::onInit(); + addColumn(L"Theme",250); + //loadThemes(); + return 1; +} + +// ----------------------------------------------------------------------- +int ColorThemesList::onResize() { + THEMESLIST_PARENT::onResize(); + if (nohscroll) { + RECT r; + getClientRect(&r); + ListColumn *col = getColumn(0); + col->setWidth(r.right-r.left-4); + } + return 1; +} + +// ----------------------------------------------------------------------- +void ColorThemesList::onDoubleClick(int itemnum) { + colorthemes_switch(); +} + +// ----------------------------------------------------------------------- +int ColorThemesList::onRightClick(int itemnum) { + THEMESLIST_PARENT::onRightClick(itemnum); + PopupMenu p_save; + PopupMenu p_load; + PopupMenu p; + StringW no_set = WASABI_API_LNGSTRINGW(IDS_NO_SET); + + for (int i=0;i<10;i++) + { + StringW s = getSlot(i); + p_save.addCommand(StringPrintfW(WASABI_API_LNGSTRINGW(IDS_SLOT_X_X), i+1, s.isempty() ? no_set : s), 100+i); + } + for (int i=0;i<10;i++) { + StringW s = getSlot(i); + p_load.addCommand(StringPrintfW(WASABI_API_LNGSTRINGW(IDS_SLOT_X_X), i+1, s.isempty() ? no_set : s), 200+i, 0, s.isempty()); + } + + p.addSubMenu(&p_load, WASABI_API_LNGSTRINGW(IDS_XUITHEME_LOAD)); + p.addSubMenu(&p_save, WASABI_API_LNGSTRINGW(IDS_XUITHEME_SAVE)); + + int r = p.popAtMouse(); + if (r >= 100 && r < 110) { + int sel = getFirstItemSelected(); + if (sel >= 0) { + wchar_t set[256+11]=L""; + getItemLabel(sel, 0, set, 255); set[255] = 0; + int p = (getItemData(sel) & 0xFFFF0000) >> 16; + if (p) + WCSCPYN(set, StringPrintfW(L"{coloredit}%s", set), 255+11); + setSlot(r-100, set); + } + } + else if (r >= 200 && r < 210) { + StringW set = getSlot(r-200); + if (!set.isempty()) + WASABI_API_SKIN->colortheme_setColorSet(set); + } + return 1; +} + +void ColorThemesList::setSlot(int i, const wchar_t *set) { + WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"%s/slot%d", WASABI_API_SKIN->getSkinName(), i+1), set); +} + +const wchar_t *ColorThemesList::getSlot(int i) { + static wchar_t set[256]=L""; + WASABI_API_CONFIG->getStringPrivate(StringPrintfW(L"%s/slot%d", WASABI_API_SKIN->getSkinName(), i+1), set, 256, L""); + return set; +} + +// ----------------------------------------------------------------------- +int ColorThemesList::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) { + if (!_wcsicmp(action, L"colorthemes_switch")) { colorthemes_switch(); return 1; } + if (!_wcsicmp(action, L"colorthemes_next")) { colorthemes_next(); return 1; } + if (!_wcsicmp(action, L"colorthemes_previous")) { colorthemes_previous(); return 1; } + return THEMESLIST_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source); +} + +// ----------------------------------------------------------------------- +int NakedColorThemesList::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) { + if (!_wcsicmp(action, L"colorthemes_next")) { colorthemes_next(); return 1; } + if (!_wcsicmp(action, L"colorthemes_previous")) { colorthemes_previous(); return 1; } + return THEMESLIST2_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source); +} + +// ----------------------------------------------------------------------- +void ColorThemesList::colorthemes_switch() { + int sel = getFirstItemSelected(); + if (sel >= 0) { + wchar_t set[256+11]=L""; + getItemLabel(sel, 0, set, 255); set[255] = 0; + int p = (getItemData(sel) & 0xFFFF0000) >> 16; + if (p) + WCSCPYN(set, StringPrintfW(L"{coloredit}%s", set), 255+11); + WASABI_API_SKIN->colortheme_setColorSet(set); + } +} + +// ----------------------------------------------------------------------- +void ColorThemesList::colorthemes_advance(int n) +{ + StringW curs = WASABI_API_SKIN->colortheme_getColorSet(); + curs.trunc(255); + wchar_t txt[256+11] = {0}; + int i; + for (i=0;i<getNumItems();i++) + { + getItemLabel(i, 0, txt, 255); + int p = (getItemData(i) & 0xFFFF0000) >> 16; + txt[256] = 0; + if (p) + WCSCPYN(txt, StringPrintfW(L"{coloredit}%s", txt), 255+11); + if (!_wcsicmp(txt, curs)) + break; + } + if (i >= WASABI_API_SKIN->colortheme_getNumColorSets()) return; + i += n; + if (i < 0) i = WASABI_API_SKIN->colortheme_getNumColorSets()-1; + i %= WASABI_API_SKIN->colortheme_getNumColorSets(); + getItemLabel(i, 0, txt, 255); txt[255] = 0; + int p = (getItemData(i) & 0xFFFF0000) >> 16; + if (p) + WCSCPYN(txt, StringPrintfW(L"{coloredit}%s", txt), 255+11); + ensure_on_paint = i; + WASABI_API_SKIN->colortheme_setColorSet(txt); + invalidate(); +} + +// ----------------------------------------------------------------------- +int ColorThemesList::getTextBold(LPARAM lParam) { + if (WCSCASEEQLSAFE(WASABI_API_SKIN->colortheme_enumColorSet(lParam & 0xFFFF), WASABI_API_SKIN->colortheme_getColorSet())) return 1; + return THEMESLIST_PARENT::getTextBold(lParam); +} + +// ----------------------------------------------------------------------- +void ColorThemesList::colorthemes_next() { + colorthemes_advance(1); +} + +// ----------------------------------------------------------------------- +void ColorThemesList::colorthemes_previous() { + colorthemes_advance(-1); +} + +// ----------------------------------------------------------------------- +void NakedColorThemesList::colorthemes_advance(int n) { + StringW curs = WASABI_API_SKIN->colortheme_getColorSet(); + curs.trunc(255); + wchar_t txt[256+11] = {0}; + int i; + for (i=0;i<items.getNumItems();i++) + { + WCSCPYN(txt, items.enumItem(i)->getName(), 256); + int p = (items.enumItem(i)->getData() & 0xFFFF0000) >> 16; + txt[256] = 0; + if (p) + { + WCSCPYN(txt, StringPrintfW(L"{coloredit}%s", txt), 255+11); + } + if (!_wcsicmp(txt, curs)) + break; + } + if (i >= WASABI_API_SKIN->colortheme_getNumColorSets()) return; + i += n; + if (i < 0) i = WASABI_API_SKIN->colortheme_getNumColorSets()-1; + i %= WASABI_API_SKIN->colortheme_getNumColorSets(); + WCSCPYN(txt, items.enumItem(i)->getName(), 256); + int p = (items.enumItem(i)->getData() & 0xFFFF0000) >> 16; + if (p) + { + WCSCPYN(txt, StringPrintfW(L"{coloredit}%s", txt), 255+11); + } + WASABI_API_SKIN->colortheme_setColorSet(txt); +} + +// ----------------------------------------------------------------------- +void NakedColorThemesList::colorthemes_next() { + colorthemes_advance(1); +} + +// ----------------------------------------------------------------------- +void NakedColorThemesList::colorthemes_previous() { + colorthemes_advance(-1); +} + +// ----------------------------------------------------------------------- +void ColorThemesList::onSetVisible(int show) { + THEMESLIST_PARENT::onSetVisible(show); + if (show) loadThemes(); + else getDesktopParent()->setFocus(); +} + +// ----------------------------------------------------------------------- +void NakedColorThemesList::onSetVisible(int show) { + THEMESLIST2_PARENT::onSetVisible(show); + if (show) loadThemes(); +} + +// ----------------------------------------------------------------------- +void ColorThemesList::loadThemes() +{ + setAutoSort(0); + deleteAllItems(); + const wchar_t *curset = WASABI_API_SKIN->colortheme_getColorSet(); + for (int i=0;i<WASABI_API_SKIN->colortheme_getNumColorSets();i++) { + const wchar_t *set = WASABI_API_SKIN->colortheme_enumColorSet(i); + int p = 0; + if (!_wcsnicmp(set, L"{coloredit}", 11)) { + set += 11; + p = 1 << 16; + } + addItem(set, p | i); + } + + setAutoSort(1); + resort(); + + if (curset != NULL) { + wchar_t set[256+11]=L""; + for (int i=0;i<WASABI_API_SKIN->colortheme_getNumColorSets();i++) + { + getItemLabel(i, 0, set, 255); set[255]=0; + int p = (getItemData(i) & 0xFFFF0000) >> 16; + if (p) + WCSCPYN(set, StringPrintfW(L"{coloredit}%s", set), 255+11); + if (set && !_wcsicmp(curset,set)) + { + setSelected(i, 1); + ensureItemVisible(i); + return; + } + } + } +} + +// ----------------------------------------------------------------------- +void NakedColorThemesList::loadThemes() +{ + items.setAutoSort(0); + items.deleteAll(); + //CUT: const wchar_t *curset = WASABI_API_SKIN->colortheme_getColorSet(); + for (int i=0;i<WASABI_API_SKIN->colortheme_getNumColorSets();i++) + { + const wchar_t *set = WASABI_API_SKIN->colortheme_enumColorSet(i); + int p = 0; + if (!_wcsnicmp(set, L"{coloredit}", 11)) + { + set += 11; + p = 1 << 16; + } + NakedItem *n = new NakedItem(set, p|i); + items.addItem(n); + } + items.setAutoSort(1); + items.sort(TRUE); +} + +// ----------------------------------------------------------------------- +int ColorThemesList::setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value) { + if (xuihandle == _xuihandle) { + switch (xmlattrid) { + case CTLIST_NOHSCROLL: nohscroll = WTOI(value); return 1; + } + } + return THEMESLIST_PARENT::setXuiParam(_xuihandle, xmlattrid, name, value); +} + +int ColorThemesList::onPaint(Canvas *canvas) { + if (ensure_on_paint > -1) ensureItemVisible(ensure_on_paint); + ensure_on_paint = -1; + THEMESLIST_PARENT::onPaint(canvas); + return 1; +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/widgets/xuithemeslist.h b/Src/Wasabi/api/skin/widgets/xuithemeslist.h new file mode 100644 index 00000000..8c4a3df9 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuithemeslist.h @@ -0,0 +1,128 @@ +#ifndef __THEMESLIST_H +#define __THEMESLIST_H + +#include <api/wnd/wndclass/listwnd.h> +#include <api/skin/nakedobject.h> +#include <api/service/svcs/svc_action.h> + +class ThemesSlotActionSvc : public svc_actionI { +public: + ThemesSlotActionSvc() { + registerAction(L"ThemesSlotsMenu", 0); + } + virtual ~ThemesSlotActionSvc() {} + virtual int onActionId(int pvtid, const wchar_t *action, const wchar_t *param=NULL, int p1=0, int p2=0, void *data=NULL, int datalen=0, ifc_window *source=NULL); + static const char *getServiceName() { return "ThemesSlotMenu Service"; } +}; + +#define THEMESLIST_PARENT ListWnd +#define THEMESLIST2_PARENT NakedObject + +// ----------------------------------------------------------------------- +class ColorThemesList : public THEMESLIST_PARENT, public SkinCallbackI +{ + + public: + + ColorThemesList(); + virtual ~ColorThemesList(); + + virtual int onInit(); + virtual void onDoubleClick(int itemnum); + virtual int onPaint(Canvas *canvas); + virtual int onRightClick(int itemnum); + + virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source); + virtual int onResize(); + virtual int wantResizeCols() { return 0; } + virtual int setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value); + virtual int wantHScroll() { return !nohscroll; } + + virtual int getTextBold(LPARAM lParam); + virtual void onSetVisible(int show); + + virtual int skincb_onColorThemesListChanged() { loadThemes(); return 1;} + + enum { + CTLIST_NOHSCROLL = 0, + }; + + static void setSlot(int s, const wchar_t *set); + static const wchar_t *getSlot(int s); +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + static XMLParamPair params[]; + void colorthemes_switch(); + void colorthemes_next(); + void colorthemes_previous(); + void colorthemes_advance(int i); + void loadThemes(); + int xuihandle; + int nohscroll; + int ensure_on_paint; +}; + +// ----------------------------------------------------------------------- +class NakedItem +{ + public: + NakedItem(const wchar_t *_name, int _p) : name(_name), data(_p) {} + virtual ~NakedItem() {} + const wchar_t *getName() { return name; } + int getData() { return data; } + private: + StringW name; + int data; +}; + +// ----------------------------------------------------------------------- +class NakedItemSort { +public: + // comparator for sorting + static int compareItem(NakedItem *p1, NakedItem *p2) { + return _wcsicmp(p1->getName(), p2->getName()); + } + // comparator for searching + static int compareAttrib(const wchar_t *attrib, NakedItem *item) { + return _wcsicmp(attrib, item->getName()); + } +}; + + +// ----------------------------------------------------------------------- +class NakedColorThemesList : public THEMESLIST2_PARENT, public SkinCallbackI +{ + + public: + + NakedColorThemesList(); + virtual ~NakedColorThemesList(); + + virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source); + + virtual void onSetVisible(int show); + + virtual int skincb_onColorThemesListChanged() { loadThemes(); return 1;} + + private: + + PtrListQuickSorted<NakedItem, NakedItemSort> items; + void colorthemes_switch(); + void colorthemes_next(); + void colorthemes_previous(); + void colorthemes_advance(int i); + void loadThemes(); + int xuihandle; +}; + + +// ----------------------------------------------------------------------- +extern const wchar_t ColorThemesListXuiObjectStr[]; +extern char ColorThemesListXuiSvcName[]; +class ColorThemesListXuiSvc : public XuiObjectSvc<ColorThemesList, ColorThemesListXuiObjectStr, ColorThemesListXuiSvcName> {}; +extern const wchar_t NakedColorThemesListXuiObjectStr[]; +extern char NakedColorThemesListXuiSvcName[]; +class NakedColorThemesListXuiSvc : public XuiObjectSvc<NakedColorThemesList, NakedColorThemesListXuiObjectStr, NakedColorThemesListXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuititlebox.cpp b/Src/Wasabi/api/skin/widgets/xuititlebox.cpp new file mode 100644 index 00000000..ba0d8e5a --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuititlebox.cpp @@ -0,0 +1,59 @@ +#include <precomp.h> +#include "xuititlebox.h" + +// ----------------------------------------------------------------------- +const wchar_t ScriptTitleBoxXuiObjectStr[] = L"Wasabi:TitleBox"; // This is the xml tag +char ScriptTitleBoxXuiSvcName[] = "Wasabi:TitleBox xui object"; + +XMLParamPair ScriptTitleBox::params[] = { + {SCRIPTTITLEBOX_CENTERED, L"CENTERED"}, + {SCRIPTTITLEBOX_CONTENT, L"CONTENT"}, + {SCRIPTTITLEBOX_SUFFIX, L"SUFFIX"}, + {SCRIPTTITLEBOX_TITLE, L"TITLE"}, + }; +// ----------------------------------------------------------------------- +ScriptTitleBox::ScriptTitleBox() : SCRIPTTITLEBOX_PARENT() +{ + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); +} + +void ScriptTitleBox::CreateXMLParameters(int master_handle) +{ + //SCRIPTTITLEBOX_PARENT::CreateXMLParameters(master_handle); +int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +// ----------------------------------------------------------------------- +ScriptTitleBox::~ScriptTitleBox() +{} + +// ----------------------------------------------------------------------- +int ScriptTitleBox::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) +{ + if (xuihandle != myxuihandle) + return SCRIPTTITLEBOX_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + // Parcel the values out to the window object we multiply inherit from + switch (xmlattributeid) + { + case SCRIPTTITLEBOX_TITLE: + setTitle(value); + break; + case SCRIPTTITLEBOX_CONTENT: + setChildGroup(value); + break; + case SCRIPTTITLEBOX_CENTERED: + setCentered(WTOI(value)); + break; + case SCRIPTTITLEBOX_SUFFIX: + setSuffix(value); + break; + default: + return 0; + } + return 1; +} diff --git a/Src/Wasabi/api/skin/widgets/xuititlebox.h b/Src/Wasabi/api/skin/widgets/xuititlebox.h new file mode 100644 index 00000000..804e25ab --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuititlebox.h @@ -0,0 +1,44 @@ +#ifndef __SCRIPTTITLEBOX_H +#define __SCRIPTTITLEBOX_H + +#include <api/skin/widgets/titlebox.h> +#include <api/script/objects/c_script/h_guiobject.h> +#include <api/wnd/accessible.h> + +#define SCRIPTTITLEBOX_PARENT TitleBox + +// ----------------------------------------------------------------------- +// Your wnd object class +class ScriptTitleBox : public SCRIPTTITLEBOX_PARENT { + + public: + + ScriptTitleBox(); + virtual ~ScriptTitleBox(); + + // XuiObject automatically calls this back for all parameters registered using addParam + // encountered in the xml source + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + + // a list of IDs for our xml attributes, we use them in addParam() in the constructor + enum { + SCRIPTTITLEBOX_TITLE= 0, + SCRIPTTITLEBOX_CONTENT, + SCRIPTTITLEBOX_CENTERED, + SCRIPTTITLEBOX_SUFFIX, + }; + int myxuihandle; + static XMLParamPair params[]; +}; + +// ----------------------------------------------------------------------- +// This defines the svc_xuiObject that exposes your wnd object + +extern const wchar_t ScriptTitleBoxXuiObjectStr[]; +extern char ScriptTitleBoxXuiSvcName[]; +class ScriptTitleBoxXuiSvc : public XuiObjectSvc<ScriptTitleBox, ScriptTitleBoxXuiObjectStr, ScriptTitleBoxXuiSvcName> {}; + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuitree.cpp b/Src/Wasabi/api/skin/widgets/xuitree.cpp new file mode 100644 index 00000000..66483656 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuitree.cpp @@ -0,0 +1,2644 @@ +#include <precomp.h> +#include "xuitree.h" + +#include <api/service/svc_enum.h> +#include <bfc/parse/hierarchyparser.h> +#include <api/script/scriptguid.h> +#include <api/skin/feeds/TextFeedEnum.h> + +// The temporary memory buffer to hold our string returns. +StringW GuiTreeScriptController::staticStr; + +class ScriptTreeItem; + +// ----------------------------------------------------------------------- +// class TreeItemScript -- This is the tree item type inserted into +// the tree if a script or XML piece is inserting items into the tree. +class TreeItemScript : public TreeItem +{ +public: + TreeItemScript(const wchar_t *label = NULL, ScriptTreeItem *_scriptitem = NULL) : scriptitem(_scriptitem), TreeItem(label) + {} + virtual ~TreeItemScript() + {} + virtual void onTreeAdd() + { + if (scriptitem) TreeItemScriptController::treeitem_onTreeAdd(SCRIPT_CALL, scriptitem->getScriptObject()); + } + virtual void onTreeRemove() + { + if (scriptitem) TreeItemScriptController::treeitem_onTreeRemove(SCRIPT_CALL, scriptitem->getScriptObject()); + } + virtual void onSelect() + { + if (scriptitem) TreeItemScriptController::treeitem_onSelect(SCRIPT_CALL, scriptitem->getScriptObject()); + } + virtual void onDeselect() + { + if (scriptitem) TreeItemScriptController::treeitem_onDeselect(SCRIPT_CALL, scriptitem->getScriptObject()); + } + virtual int onLeftDoubleClick() + { + scriptVar retval; + if (scriptitem) + retval = TreeItemScriptController::treeitem_onLeftDoubleClick(SCRIPT_CALL, scriptitem->getScriptObject()); + if ((retval.type == SCRIPT_VOID) + || (retval.type == SCRIPT_OBJECT) + || (retval.type == SCRIPT_STRING)) + return 0; + return GET_SCRIPT_INT(retval); + } + virtual int onRightDoubleClick() + { + scriptVar retval; + if (scriptitem) retval = TreeItemScriptController::treeitem_onRightDoubleClick(SCRIPT_CALL, scriptitem->getScriptObject()); + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) return 0; + return GET_SCRIPT_INT(retval); + } + // return 1 if you eat the key + virtual int onChar(UINT key) + { + scriptVar retval; + if (scriptitem) retval = TreeItemScriptController::treeitem_onChar(SCRIPT_CALL, scriptitem->getScriptObject(), MAKE_SCRIPT_INT(key)); + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) return 0; + return GET_SCRIPT_INT(retval); + } + // these are called after the expand/collapse happens + virtual void onExpand() + { + if (scriptitem) TreeItemScriptController::treeitem_onExpand(SCRIPT_CALL, scriptitem->getScriptObject()); + } + virtual void onCollapse() + { + if (scriptitem) TreeItemScriptController::treeitem_onCollapse(SCRIPT_CALL, scriptitem->getScriptObject()); + } + virtual int onBeginLabelEdit() + { + scriptVar retval; + if (scriptitem) retval = TreeItemScriptController::treeitem_onBeginLabelEdit(SCRIPT_CALL, scriptitem->getScriptObject()); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = TreeItem::onBeginLabelEdit(); + } + return retv; + } + virtual int onEndLabelEdit(const wchar_t *newlabel) + { + scriptVar retval; + if (scriptitem) + retval = TreeItemScriptController::treeitem_onEndLabelEdit(SCRIPT_CALL, scriptitem->getScriptObject(), MAKE_SCRIPT_STRING(newlabel)); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = TreeItem::onEndLabelEdit(newlabel); + } + return retv; + } + virtual int onContextMenu(int x, int y) + { + scriptVar retval; + if (scriptitem) retval = TreeItemScriptController::treeitem_onContextMenu(SCRIPT_CALL, scriptitem->getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) ); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = TreeItem::onContextMenu(x, y); + } + return retv; + } +protected: + ScriptTreeItem *scriptitem; +}; + + +// ----------------------------------------------------------------------- +const wchar_t ScriptTreeXuiObjectStr[] = L"Tree"; // This is the xml tag +char ScriptTreeXuiSvcName[] = "Tree xui object"; + + +XMLParamPair ScriptTree::params[] = { + {SCRIPTTREE_CHILDTABS, L"CHILDTABS"}, + {SCRIPTTREE_EXPANDROOT, L"EXPANDROOT"}, + {SCRIPTTREE_FEED, L"FEED"}, + {SCRIPTTREE_SETITEMS, L"ITEMS"}, + {SCRIPTTREE_SORTED, L"SORTED"}, + }; +// ----------------------------------------------------------------------- +ScriptTree::ScriptTree() +{ + getScriptObject()->vcpu_setInterface(guitreeGuid, (void *)static_cast<ScriptTree *>(this)); + getScriptObject()->vcpu_setClassName(L"GuiTree"); // this is the script class name + getScriptObject()->vcpu_setController(guiTreeController); + + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); + + feed = NULL; + childtabs = 1; + expandroot = 1; +} + +void ScriptTree::CreateXMLParameters(int master_handle) +{ + //SCRIPTTREE_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +// ----------------------------------------------------------------------- +ScriptTree::~ScriptTree() +{ + closeFeed(); + + // Clean up the ScriptTreeItems owned by this guy. + TreeItem *item = enumRootItem(0); + while (item != NULL) + { + // Delete this item. + ScriptTreeItem *dead = NULL; + //if (TISC::g_scriptitems.getItem(item, &dead) && (dead != NULL)) + //{ // true if it found something. + // TISC::g_scriptitems.delItem(item); + // delete dead; + // // DebugString(" === deleting tree item (%08X, %08X, %08X)\n", item, dead, this); + // continue; + //} + auto it = TISC::g_scriptitems.find(item); + if (TISC::g_scriptitems.end() != it) + { + dead = it->second; + delete dead; + TISC::g_scriptitems.erase(it); + continue; + } + else + { + // DebugString(" !!! ORPHAN TREE ITEM (%08X, %08X, %08X)\n", item, 0, this); + } + + // Figure out who the next item to process should be. + + // 1) Children first. + TreeItem *child = item->getChild(); + if (child != NULL) + { + item = child; + } + else + { + // 2) Siblings next. + TreeItem *sibling = item->getSibling(); + if (sibling != NULL) + { + item = sibling; + } + else + { + // 3) Zip up parent chain last. + TreeItem *item_parent, *parent_sibling; + item_parent = item->getParent(); + item = NULL; // at this point if we do not assign, we are NULL. + while (item_parent != NULL) + { + parent_sibling = item_parent->getSibling(); + if (parent_sibling != NULL) + { + item = parent_sibling; + break; + } + item_parent = item_parent->getParent(); + } + // 4) Uhhh.... you're null. All done. Go home. + } + } + } + + /* + + // delete all of our script items from g_scriptitems + int i = 0; + TreeItem *next = enumRootItem(0); + while (next) { // go through all of our items + ScriptTreeItem *dead = NULL; + if (TISC::g_scriptitems.getItem(next, &dead) && (dead != NULL)) { // true if it found something. + TISC::g_scriptitems.delItem(next); + delete dead; + // DebugString(" === deleting tree item (%08X, %08X)\n", next, dead); + } else { + // DebugString(" !!! ORPHAN TREE ITEM (%08X, %08X)\n", next, i); + } + TreeItem *next = enumAllItems(i++); + } + + */ + // some items will wind up leaked into g_scriptitems, most likely. +} + +// ----------------------------------------------------------------------- +int ScriptTree::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) +{ + if (xuihandle != myxuihandle) + return SCRIPTTREE_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) + { + case SCRIPTTREE_SETITEMS: + items = value; + fillFromParams(); +#ifdef WASABI_COMPILE_CONFIG + if (getGuiObject()->guiobject_hasCfgAttrib()) + selectFromConfig(); +#endif + break; + case SCRIPTTREE_FEED: + { + closeFeed(); + openFeed(value); + break; + } + case SCRIPTTREE_SORTED: + { + setSorted(WTOB(value)); + break; + } + case SCRIPTTREE_CHILDTABS: + { + childtabs = WTOI(value); + break; + } + case SCRIPTTREE_EXPANDROOT: + { + expandRoot(WTOI(value)); + break; + } + default: + return 0; + } + return 1; +} + +// ----------------------------------------------------------------------- +int ScriptTree::onInit() +{ + SCRIPTTREE_PARENT::onInit(); + + fillFromParams(); + return 1; +} + +// ----------------------------------------------------------------------- +int ScriptTree::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) +{ + SCRIPTTREE_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source); + if (!WCSICMP(action, L"get_selection")) + { + if (source != NULL) + { + StringW res(L""); + + // Hmmmmm..... multiselection trees? + + sendAction(source, L"set_selection", res); + } + } + return 1; +} + +// ----------------------------------------------------------------------- +ScriptTreeItem *ScriptTree::bindScriptTreeItem(TreeItem *item) +{ + ASSERT(item != NULL); + // find this tree item in our map of tree items. + ScriptTreeItem *si = NULL; + //TISC::g_scriptitems.getItem(item, &si); + auto it = TISC::g_scriptitems.find(item); + if (TISC::g_scriptitems.end() == it) + { + // if there was no scriptobject in our map already, make one + // for this tree item and place it in our map. + si = new ScriptTreeItem(item, this); + TISC::g_scriptitems.insert({ item, si }); + } + else + { + si = it->second; + } + return si; +} + +// ----------------------------------------------------------------------- +int ScriptTree::destroyScriptTreeItem(ScriptTreeItem *item) +{ + ASSERT(item != NULL); + // find this tree item in our map of tree items. + TreeItem *ti = item->getItem(); + if (ti) + { + ScriptTreeItem *check = NULL; + //TISC::g_scriptitems.getItem(ti, &check); // this is a doublecheck on who owns who. + auto it = TISC::g_scriptitems.find(ti); + + if (TISC::g_scriptitems.end() != it) + { + // remove the treeitem from the tree + this->removeTreeItem(ti); // (removes without deleting) + // remove the scripttreeitem from the map + TISC::g_scriptitems.erase(it); + // and delete.(phew! bomb disposal!) + delete ti; + delete item; + return 1; // yes, we deleted it. + } + } + return 0; // Not ours, don't wanna delete it. Someone else can Deal With It. +} + +// ----------------------------------------------------------------------- +void ScriptTree::onSetVisible(int i) +{ + SCRIPTTREE_PARENT::onSetVisible(i); +} + +#ifdef WASABI_COMPILE_CONFIG +// ----------------------------------------------------------------------- +int ScriptTree::onReloadConfig() +{ + SCRIPTTREE_PARENT::onReloadConfig(); + selectFromConfig(); + return 1; +} + +// ----------------------------------------------------------------------- +void ScriptTree::saveToConfig() +{} + +// ----------------------------------------------------------------------- +void ScriptTree::selectFromConfig() +{} +#endif + +// ----------------------------------------------------------------------- +int ScriptTree::selectEntry(const wchar_t *e, int cb) +{ + return -1; +} + +// ----------------------------------------------------------------------- +void ScriptTree::expandRoot(int val) +{ + if (val) + { + expandroot = 1; + int count; + TreeItem *rootitem; + for (count = 0, rootitem = enumRootItem(count); rootitem; rootitem = enumRootItem(++count)) + { + rootitem->expand(); + } + } + else + { + expandroot = 0; + } +} + +// ----------------------------------------------------------------------- +void ScriptTree::fillFromHPNode(HPNode *node, TreeItem *parent) +{ + // Go through the given node's children and add items for them + // to the corresponding parent item. + int i, n = node->getNumChildren(); + for (i = 0; i < n; i++) + { + // Here's a child node + HPNode *child_node = static_cast<HPNode *>(node->enumChild(i)); + // Make a script-aware tree item and script item to correspond to it, labelled with the child_node's name + ScriptTreeItem *si = new ScriptTreeItem; + TreeItem *child_item = new TreeItemScript((*child_node)(), si); + si->setItem(child_item); + si->setScriptTree(this); + // Add the script and tree items to the scriptitems map + TISC::g_scriptitems.insert({ child_item, si }); + // DebugString(StringPrintf(" === NEW NODE ITEM (%08X, %08X, %08X)\n", child_item, si, this); + // Add the child item to either ourselves or the given parent. + addTreeItem(child_item, parent, getSorted(), childtabs); + // And then continue to fill from that node. + fillFromHPNode(child_node, child_item); + } +} + +// ----------------------------------------------------------------------- +void ScriptTree::fillFromParams() +{ + deleteAllItems(); + if (!items.isempty()) + { + HierarchyParser hierarchy(items); + fillFromHPNode(hierarchy.rootNode()); + } + // If we want our roots opened, do so now. + expandRoot(expandroot); +} + +// ----------------------------------------------------------------------- +void ScriptTree::selectEntries(const wchar_t *entries, int cb) +{} + +// ----------------------------------------------------------------------- +void ScriptTree::openFeed(const wchar_t *feedid) +{ + if (!_wcsicmp(feedid, last_feed)) return ; + feed = TextFeedEnum(feedid).getFirst(); + if (feed != NULL) + { + viewer_addViewItem(feed->getDependencyPtr()); + setXuiParam(myxuihandle, SCRIPTTREE_SETITEMS, L"items", feed->getFeedText(feedid)); + } + last_feed = feedid; +} + +// ----------------------------------------------------------------------- +void ScriptTree::closeFeed() +{ + if (feed) + { + viewer_delViewItem(feed->getDependencyPtr()); + SvcEnum::release(feed); + } + feed = NULL; + last_feed = L""; +} + +// ----------------------------------------------------------------------- +int ScriptTree::viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen) +{ + if (feed == dynamic_guid_cast<svc_textFeed>(item, classguid)) + { + if (event == svc_textFeed::Event_TEXTCHANGE) + { + setXuiParam(myxuihandle, SCRIPTTREE_SETITEMS, L"items", (const wchar_t *)ptr); + return 1; + } + } + return 0; +} + +// ----------------------------------------------------------------------- +// Callback methods that send hooks into the Script system + +int ScriptTree::onLeftButtonDown(int x, int y) +{ + scriptVar retval; + retval = GuiTreeScriptController::guitree_onLeftButtonDown(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) ); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = SCRIPTTREE_PARENT::onLeftButtonDown(x, y); + } + return retv; +} + +int ScriptTree::onLeftButtonUp(int x, int y) +{ + scriptVar retval; + retval = GuiTreeScriptController::guitree_onLeftButtonUp(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) ); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = SCRIPTTREE_PARENT::onLeftButtonUp(x, y); + } + return retv; +} + +int ScriptTree::onRightButtonUp(int x, int y) +{ + scriptVar retval; + retval = GuiTreeScriptController::guitree_onRightButtonUp(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) ); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = SCRIPTTREE_PARENT::onRightButtonUp(x, y); + } + return retv; +} + +int ScriptTree::onMouseMove(int x, int y) +{ + scriptVar retval; + retval = GuiTreeScriptController::guitree_onMouseMove(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) ); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = SCRIPTTREE_PARENT::onMouseMove(x, y); + } + return retv; +} + +int ScriptTree::wantAutoContextMenu() +{ + scriptVar retval; + retval = GuiTreeScriptController::guitree_wantAutoContextMenu(SCRIPT_CALL, getScriptObject() ); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = SCRIPTTREE_PARENT::wantAutoContextMenu(); + } + return retv; +} + +int ScriptTree::onLeftButtonDblClk(int x, int y) +{ + scriptVar retval; + retval = GuiTreeScriptController::guitree_onLeftButtonDblClk(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) ); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = SCRIPTTREE_PARENT::onLeftButtonDblClk(x, y); + } + return retv; +} + +int ScriptTree::onRightButtonDblClk(int x, int y) +{ + scriptVar retval; + retval = GuiTreeScriptController::guitree_onRightButtonDblClk(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) ); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = SCRIPTTREE_PARENT::onRightButtonDblClk(x, y); + } + return retv; +} + +int ScriptTree::onMouseWheelUp(int clicked, int lines) +{ + scriptVar retval; + retval = GuiTreeScriptController::guitree_onMouseWheelUp(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(clicked), MAKE_SCRIPT_INT(lines) ); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = SCRIPTTREE_PARENT::onMouseWheelUp(clicked, lines); + } + return retv; +} + +int ScriptTree::onMouseWheelDown(int clicked, int lines) +{ + scriptVar retval; + retval = GuiTreeScriptController::guitree_onMouseWheelDown(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(clicked), MAKE_SCRIPT_INT(lines) ); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = SCRIPTTREE_PARENT::onMouseWheelDown(clicked, lines); + } + return retv; +} + +int ScriptTree::onContextMenu(int x, int y) +{ + scriptVar retval; + retval = GuiTreeScriptController::guitree_onContextMenu(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) ); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = SCRIPTTREE_PARENT::onContextMenu(x, y); + } + return retv; +} + +int ScriptTree::onChar(wchar_t c) +{ + scriptVar retval; + retval = GuiTreeScriptController::guitree_onChar(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(c)); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = SCRIPTTREE_PARENT::onChar(c); + } + return retv; +} + +int ScriptTree::onKeyDown(int keycode) +{ + scriptVar retval; + retval = GuiTreeScriptController::guitree_onKeyDown(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(keycode) ); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = SCRIPTTREE_PARENT::onKeyDown(keycode); + } + return retv; +} + +void ScriptTree::onItemRecvDrop(TreeItem *item) +{ + ScriptTreeItem *sti_item = bindScriptTreeItem(item); + GuiTreeScriptController::guitree_onItemRecvDrop(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(sti_item->getScriptObject()) ); +} + +void ScriptTree::onLabelChange(TreeItem *item) +{ + ScriptTreeItem *sti_item = bindScriptTreeItem(item); + GuiTreeScriptController::guitree_onLabelChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(sti_item->getScriptObject()) ); +} + +void ScriptTree::onItemSelected(TreeItem *item) +{ + ScriptTreeItem *sti_item = bindScriptTreeItem(item); + GuiTreeScriptController::guitree_onItemSelected(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(sti_item->getScriptObject()) ); +} + +void ScriptTree::onItemDeselected(TreeItem *item) +{ + ScriptTreeItem *sti_item = bindScriptTreeItem(item); + GuiTreeScriptController::guitree_onItemDeselected(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(sti_item->getScriptObject()) ); +} + +int ScriptTree::onKillFocus() +{ + scriptVar retval; + retval = GuiTreeScriptController::guitree_onKillFocus(SCRIPT_CALL, getScriptObject() ); + int retv = 0; + if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) + { + retv = -1; + } + if (!retv) + { + retv = GET_SCRIPT_INT(retval); + } + if (retv < 1) + { + retv = SCRIPTTREE_PARENT::onKillFocus(); + } + return retv; +} + + + + + +// ----------------------------------------------------------------------- +// Script Object + +GuiTreeScriptController _guiTreeController; +GuiTreeScriptController *guiTreeController = &_guiTreeController; + +// -- Functions table ------------------------------------- +function_descriptor_struct GuiTreeScriptController::exportedFunction[] = { + {L"getNumRootItems", 0, (void*)GuiTreeScriptController::guitree_getNumRootItems }, + {L"enumRootItem", 1, (void*)GuiTreeScriptController::guitree_enumRootItem }, + + {L"onLeftButtonDown", 2, (void*)GuiTreeScriptController::guitree_onLeftButtonDown }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y); + {L"onLeftButtonUp", 2, (void*)GuiTreeScriptController::guitree_onLeftButtonUp }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y); + {L"onRightButtonUp", 2, (void*)GuiTreeScriptController::guitree_onRightButtonUp }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y); + {L"onMouseMove", 2, (void*)GuiTreeScriptController::guitree_onMouseMove }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y); + {L"onWantAutoContextMenu", 0, (void*)GuiTreeScriptController::guitree_wantAutoContextMenu }, // ); + {L"onLeftButtonDblClk", 2, (void*)GuiTreeScriptController::guitree_onLeftButtonDblClk }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y); + {L"onRightButtonDblClk", 2, (void*)GuiTreeScriptController::guitree_onRightButtonDblClk }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y); + {L"onMouseWheelUp", 2, (void*)GuiTreeScriptController::guitree_onMouseWheelUp }, // , /*Int*/ scriptVar clicked, /*Int*/ scriptVar lines); + {L"onMouseWheelDown", 2, (void*)GuiTreeScriptController::guitree_onMouseWheelDown }, // , /*Int*/ scriptVar clicked, /*Int*/ scriptVar lines); + {L"onContextMenu", 2, (void*)GuiTreeScriptController::guitree_onContextMenu }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y); + {L"onChar", 1, (void*)GuiTreeScriptController::guitree_onChar }, // , /*Int*/ scriptVar c); + {L"onKeyDown", 1, (void*)GuiTreeScriptController::guitree_onKeyDown }, // , /*Int*/ scriptVar keycode); + {L"onItemRecvDrop", 1, (void*)GuiTreeScriptController::guitree_onItemRecvDrop }, // , /*TreeItem*/ scriptVar item); + {L"onLabelChange", 1, (void*)GuiTreeScriptController::guitree_onLabelChange }, // , /*TreeItem*/ scriptVar item); + {L"onItemSelected", 1, (void*)GuiTreeScriptController::guitree_onItemSelected }, // , /*TreeItem*/ scriptVar item); + {L"onItemDeselected", 1, (void*)GuiTreeScriptController::guitree_onItemDeselected }, // , /*TreeItem*/ scriptVar item); + {L"onKillFocus", 0, (void*)GuiTreeScriptController::guitree_onKillFocus }, // ); + {L"jumpToNext", 1, (void*)GuiTreeScriptController::guitree_jumpToNext }, // , /*Int*/ scriptVar c); + {L"ensureItemVisible", 1, (void*)GuiTreeScriptController::guitree_ensureItemVisible }, // , /*TreeItem*/ scriptVar item); + {L"getContentsWidth", 0, (void*)GuiTreeScriptController::guitree_getContentsWidth }, // ); + {L"getContentsHeight", 0, (void*)GuiTreeScriptController::guitree_getContentsHeight }, // ); + {L"addTreeItem", 4, (void*)GuiTreeScriptController::guitree_addTreeItem }, // , /*TreeItem*/ scriptVar item, /*TreeItem*/ scriptVar par, /*Int*/ scriptVar sorted, /*Int*/ scriptVar haschildtab); + {L"removeTreeItem", 1, (void*)GuiTreeScriptController::guitree_removeTreeItem }, // , /*TreeItem*/ scriptVar item); + {L"moveTreeItem", 2, (void*)GuiTreeScriptController::guitree_moveTreeItem }, // , /*TreeItem*/ scriptVar item, /*TreeItem*/ scriptVar newparent); + {L"deleteAllItems", 0, (void*)GuiTreeScriptController::guitree_deleteAllItems }, // ); + {L"expandItem", 1, (void*)GuiTreeScriptController::guitree_expandItem }, // , /*TreeItem*/ scriptVar item); + {L"expandItemDeferred", 1, (void*)GuiTreeScriptController::guitree_expandItemDeferred }, // , /*TreeItem*/ scriptVar item); + {L"collapseItem", 1, (void*)GuiTreeScriptController::guitree_collapseItem }, // , /*TreeItem*/ scriptVar item); + {L"collapseItemDeferred", 1, (void*)GuiTreeScriptController::guitree_collapseItemDeferred }, // , /*TreeItem*/ scriptVar item); + {L"selectItem", 1, (void*)GuiTreeScriptController::guitree_selectItem }, // , /*TreeItem*/ scriptVar item); + {L"selectItemDeferred", 1, (void*)GuiTreeScriptController::guitree_selectItemDeferred }, // , /*TreeItem*/ scriptVar item); + {L"delItemDeferred", 1, (void*)GuiTreeScriptController::guitree_delItemDeferred }, // , /*TreeItem*/ scriptVar item); + {L"hiliteItem", 1, (void*)GuiTreeScriptController::guitree_hiliteItem }, // , /*TreeItem*/ scriptVar item); + {L"unhiliteItem", 1, (void*)GuiTreeScriptController::guitree_unhiliteItem }, // , /*TreeItem*/ scriptVar item); + {L"getCurItem", 0, (void*)GuiTreeScriptController::guitree_getCurItem }, // ); + {L"hitTest", 2, (void*)GuiTreeScriptController::guitree_hitTest }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y); + {L"editItemLabel", 1, (void*)GuiTreeScriptController::guitree_editItemLabel }, // , /*TreeItem*/ scriptVar item); + {L"cancelEditLabel", 1, (void*)GuiTreeScriptController::guitree_cancelEditLabel }, // , /*Int*/ scriptVar destroyit); + {L"setAutoEdit", 1, (void*)GuiTreeScriptController::guitree_setAutoEdit }, // , /*Int*/ scriptVar ae); + {L"getAutoEdit", 0, (void*)GuiTreeScriptController::guitree_getAutoEdit }, // ); + {L"getByLabel", 2, (void*)GuiTreeScriptController::guitree_getByLabel }, // , /*TreeItem*/ scriptVar item, /*String*/ scriptVar name); + {L"setSorted", 1, (void*)GuiTreeScriptController::guitree_setSorted }, // , /*Int*/ scriptVar dosort); + {L"getSorted", 0, (void*)GuiTreeScriptController::guitree_getSorted }, // ); + {L"sortTreeItems", 0, (void*)GuiTreeScriptController::guitree_sortTreeItems }, // ); + {L"getSibling", 1, (void*)GuiTreeScriptController::guitree_getSibling }, // , /*TreeItem*/ scriptVar item); + {L"setAutoCollapse", 1, (void*)GuiTreeScriptController::guitree_setAutoCollapse }, // , /*Int*/ scriptVar doautocollapse); + {L"setFontSize", 1, (void*)GuiTreeScriptController::guitree_setFontSize }, // , /*Int*/ scriptVar newsize); + {L"getFontSize", 0, (void*)GuiTreeScriptController::guitree_getFontSize }, // ); + {L"getNumVisibleChildItems", 1, (void*)GuiTreeScriptController::guitree_getNumVisibleChildItems }, // , /*TreeItem*/ scriptVar c); + {L"getNumVisibleItems", 0, (void*)GuiTreeScriptController::guitree_getNumVisibleItems }, // ); + {L"enumVisibleItems", 1, (void*)GuiTreeScriptController::guitree_enumVisibleItems }, // , /*Int*/ scriptVar n); + {L"enumVisibleChildItems", 2, (void*)GuiTreeScriptController::guitree_enumVisibleChildItems }, // , /*TreeItem*/ scriptVar c, /*Int*/ scriptVar n); + {L"enumAllItems", 1, (void*)GuiTreeScriptController::guitree_enumAllItems }, // , /*Int*/ scriptVar n); + {L"getItemRectX", 1, (void*)GuiTreeScriptController::guitree_getItemRectX }, // , /*TreeItem*/ scriptVar item); + {L"getItemRectY", 1, (void*)GuiTreeScriptController::guitree_getItemRectY }, // , /*TreeItem*/ scriptVar item); + {L"getItemRectW", 1, (void*)GuiTreeScriptController::guitree_getItemRectW }, // , /*TreeItem*/ scriptVar item); + {L"getItemRectH", 1, (void*)GuiTreeScriptController::guitree_getItemRectH }, // , /*TreeItem*/ scriptVar item); + // {L"getItemFromPoint", 2, (void*)GuiTreeScriptController::guitree_getItemFromPoint }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y); + + }; + +ScriptObject *GuiTreeScriptController::instantiate() +{ + ScriptTree *sp = new ScriptTree; + ASSERT(sp != NULL); + return sp->getScriptObject(); +} + +void GuiTreeScriptController::destroy(ScriptObject *o) +{ + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + ASSERT(sp != NULL); + delete sp; +} + +void *GuiTreeScriptController::encapsulate(ScriptObject *o) +{ + return NULL; // no encapsulation for guitrees yet +} + +void GuiTreeScriptController::deencapsulate(void *o) +{} + +int GuiTreeScriptController::getNumFunctions() +{ + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *GuiTreeScriptController::getExportedFunctions() +{ + return exportedFunction; +} + +/*int*/ scriptVar GuiTreeScriptController::guitree_getNumRootItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree*>(o->vcpu_getInterface(guitreeGuid)); + int a = 0; + if (sp != NULL) + { + a = sp->getNumRootItems(); + } + return MAKE_SCRIPT_INT(a); +} + +/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_enumRootItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar which) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree*>(o->vcpu_getInterface(guitreeGuid)); + scriptVar retval = MAKE_SCRIPT_OBJECT(NULL); + if (sp != NULL) + { + TreeItem *a = NULL; + int _which = GET_SCRIPT_INT(which); + a = sp->enumRootItem(_which); + if (a != NULL) + { + ScriptTreeItem *item = sp->bindScriptTreeItem(a); + if (item != NULL) + { + retval = MAKE_SCRIPT_OBJECT(item->getScriptObject()); + } + } + } + return retval; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_onLeftButtonDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS2(o, guiTreeController, x, y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT2(o, x, y); +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_onLeftButtonUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS2(o, guiTreeController, x, y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT2(o, x, y); +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_onRightButtonUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS2(o, guiTreeController, x, y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT2(o, x, y); +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_onMouseMove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS2(o, guiTreeController, x, y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT2(o, x, y); +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_wantAutoContextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS0(o, guiTreeController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_onLeftButtonDblClk(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS2(o, guiTreeController, x, y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT2(o, x, y); +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_onRightButtonDblClk(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS2(o, guiTreeController, x, y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT2(o, x, y); +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_onMouseWheelUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar clicked, /*Int*/ scriptVar lines) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS2(o, guiTreeController, clicked, lines); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT2(o, clicked, lines); +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_onMouseWheelDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar clicked, /*Int*/ scriptVar lines) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS2(o, guiTreeController, clicked, lines); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT2(o, clicked, lines); +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_onContextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS2(o, guiTreeController, x, y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT2(o, x, y); +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_onChar(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar c) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, guiTreeController, c); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, c); +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_onKeyDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar keycode) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, guiTreeController, keycode); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, keycode); +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_onItemRecvDrop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, guiTreeController, item); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, item); +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_onLabelChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, guiTreeController, item); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, item); +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_onItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, guiTreeController, item); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, item); +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_onItemDeselected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, guiTreeController, item); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, item); +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_onKillFocus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS0(o, guiTreeController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +// ------------------------------------------------------------------------- +/*Void*/ scriptVar GuiTreeScriptController::guitree_jumpToNext(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar c) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + int _c = GET_SCRIPT_INT(c); + if (sp != NULL) + { + sp->jumpToNext(_c); + } + RETURN_SCRIPT_VOID; +} + + +/*Void*/ scriptVar GuiTreeScriptController::guitree_ensureItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + if (sp != NULL) + { + sp->ensureItemVisible(_item); + } + RETURN_SCRIPT_VOID; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_getContentsWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + scriptVar retval = MAKE_SCRIPT_INT(0); + if (sp != NULL) + { + int a = 0; + a = sp->getContentsWidth(); + retval = MAKE_SCRIPT_INT(a); + } + return retval; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_getContentsHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + scriptVar retval = MAKE_SCRIPT_INT(0); + if (sp != NULL) + { + int a = 0; + a = sp->getContentsHeight(); + retval = MAKE_SCRIPT_INT(a); + } + return retval; +} + +/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_addTreeItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item, scriptVar par, scriptVar sorted, scriptVar haschildtab) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_par = NULL; + ScriptObject *so_par = GET_SCRIPT_OBJECT(par); + if (so_par) + { + ScriptTreeItem *sti_par = static_cast<ScriptTreeItem *>(so_par->vcpu_getInterface(treeitemGuid)); + if (sti_par) + { + _par = sti_par->getItem(); + } + } + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + int _haschildtab = GET_SCRIPT_INT(haschildtab); + int _sorted = GET_SCRIPT_INT(sorted); + scriptVar retval = MAKE_SCRIPT_OBJECT(NULL); + if (sp != NULL) + { + TreeItem *a = NULL; + a = sp->addTreeItem(_item, _par, _sorted, _haschildtab); + if (a != NULL) + { + ScriptTreeItem *item = sp->bindScriptTreeItem(a); + if (item != NULL) + { + retval = MAKE_SCRIPT_OBJECT(item->getScriptObject()); + } + } + } + return retval; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_removeTreeItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + scriptVar retval = MAKE_SCRIPT_INT(0); + if (sp != NULL) + { + int a = 0; + a = sp->removeTreeItem(_item); + retval = MAKE_SCRIPT_INT(a); + } + return retval; +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_moveTreeItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item, scriptVar newparent) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_newparent = NULL; + ScriptObject *so_newparent = GET_SCRIPT_OBJECT(newparent); + if (so_newparent) + { + ScriptTreeItem *sti_newparent = static_cast<ScriptTreeItem *>(so_newparent->vcpu_getInterface(treeitemGuid)); + if (sti_newparent) + { + _newparent = sti_newparent->getItem(); + } + } + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + if (sp != NULL) + { + sp->moveTreeItem(_item, _newparent); + } + RETURN_SCRIPT_VOID; +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_deleteAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + if (sp != NULL) + { + sp->deleteAllItems(); + } + RETURN_SCRIPT_VOID; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_expandItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + scriptVar retval = MAKE_SCRIPT_INT(0); + if (sp != NULL) + { + int a = 0; + a = sp->expandItem(_item); + retval = MAKE_SCRIPT_INT(a); + } + return retval; +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_expandItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + if (sp != NULL) + { + sp->expandItemDeferred(_item); + } + RETURN_SCRIPT_VOID; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_collapseItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + scriptVar retval = MAKE_SCRIPT_INT(0); + if (sp != NULL) + { + int a = 0; + a = sp->collapseItem(_item); + retval = MAKE_SCRIPT_INT(a); + } + return retval; +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_collapseItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + if (sp != NULL) + { + sp->collapseItemDeferred(_item); + } + RETURN_SCRIPT_VOID; +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_selectItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + if (sp != NULL) + { + sp->selectItem(_item); + } + RETURN_SCRIPT_VOID; +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_selectItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + if (sp != NULL) + { + sp->selectItemDeferred(_item); + } + RETURN_SCRIPT_VOID; +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_delItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + if (sp != NULL) + { + sp->delItemDeferred(_item); + } + RETURN_SCRIPT_VOID; +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_hiliteItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + if (sp != NULL) + { + sp->hiliteItem(_item); + } + RETURN_SCRIPT_VOID; +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_unhiliteItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + if (sp != NULL) + { + sp->unhiliteItem(_item); + } + RETURN_SCRIPT_VOID; +} + +/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_getCurItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + scriptVar retval = MAKE_SCRIPT_OBJECT(NULL); + if (sp != NULL) + { + TreeItem *a = NULL; + a = sp->getCurItem(); + if (a != NULL) + { + ScriptTreeItem *item = sp->bindScriptTreeItem(a); + if (item != NULL) + { + retval = MAKE_SCRIPT_OBJECT(item->getScriptObject()); + } + } + } + return retval; +} + +/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_hitTest(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + int _y = GET_SCRIPT_INT(y); + int _x = GET_SCRIPT_INT(x); + scriptVar retval = MAKE_SCRIPT_OBJECT(NULL); + if (sp != NULL) + { + TreeItem *a = NULL; + a = sp->hitTest(_x, _y); + if (a != NULL) + { + ScriptTreeItem *item = sp->bindScriptTreeItem(a); + if (item != NULL) + { + retval = MAKE_SCRIPT_OBJECT(item->getScriptObject()); + } + } + } + return retval; +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_editItemLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + if (sp != NULL) + { + sp->editItemLabel(_item); + } + RETURN_SCRIPT_VOID; +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_cancelEditLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar destroyit) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + int _destroyit = GET_SCRIPT_INT(destroyit); + if (sp != NULL) + { + sp->cancelEditLabel(_destroyit); + } + RETURN_SCRIPT_VOID; +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_setAutoEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar ae) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + int _ae = GET_SCRIPT_INT(ae); + if (sp != NULL) + { + sp->setAutoEdit(_ae); + } + RETURN_SCRIPT_VOID; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_getAutoEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + scriptVar retval = MAKE_SCRIPT_INT(0); + if (sp != NULL) + { + int a = 0; + a = sp->getAutoEdit(); + retval = MAKE_SCRIPT_INT(a); + } + return retval; +} + +/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_getByLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item, /*String*/ scriptVar name) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + StringW _name = GET_SCRIPT_STRING(name); + scriptVar retval = MAKE_SCRIPT_OBJECT(NULL); + if (sp != NULL) + { + TreeItem *a = NULL; + a = sp->getByLabel(_item, _name); + if (a != NULL) + { + ScriptTreeItem *item = sp->bindScriptTreeItem(a); + if (item != NULL) + { + retval = MAKE_SCRIPT_OBJECT(item->getScriptObject()); + } + } + } + return retval; +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_setSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar dosort) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + int _dosort = GET_SCRIPT_INT(dosort); + if (sp != NULL) + { + sp->setSorted(!!_dosort); + } + RETURN_SCRIPT_VOID; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_getSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + scriptVar retval = MAKE_SCRIPT_OBJECT(NULL); + if (sp != NULL) + { + int a = NULL; + a = sp->getSorted(); + retval = MAKE_SCRIPT_INT(a); + } + return retval; +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_sortTreeItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + if (sp != NULL) + { + sp->sortTreeItems(); + } + RETURN_SCRIPT_VOID; +} + +/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_getSibling(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + scriptVar retval = MAKE_SCRIPT_OBJECT(NULL); + if (sp != NULL) + { + TreeItem *a = NULL; + a = sp->getSibling(_item); + if (a != NULL) + { + ScriptTreeItem *item = sp->bindScriptTreeItem(a); + if (item != NULL) + { + retval = MAKE_SCRIPT_OBJECT(item->getScriptObject()); + } + } + } + return retval; +} + +/*Void*/ scriptVar GuiTreeScriptController::guitree_setAutoCollapse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar doautocollapse) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + int _doautocollapse = GET_SCRIPT_INT(doautocollapse); + if (sp != NULL) + { + sp->setAutoCollapse(!!_doautocollapse); + } + RETURN_SCRIPT_VOID; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_setFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newsize) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + int _newsize = GET_SCRIPT_INT(newsize); + scriptVar retval = MAKE_SCRIPT_INT(0); + if (sp != NULL) + { + int a = 0; + a = sp->setFontSize(_newsize); + retval = MAKE_SCRIPT_INT(a); + } + return retval; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_getFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + scriptVar retval = MAKE_SCRIPT_INT(0); + if (sp != NULL) + { + int a = 0; + a = sp->getFontSize(); + retval = MAKE_SCRIPT_INT(a); + } + return retval; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_getNumVisibleChildItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar c) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_c = NULL; + ScriptObject *so_c = GET_SCRIPT_OBJECT(c); + if (so_c) + { + ScriptTreeItem *sti_c = static_cast<ScriptTreeItem *>(so_c->vcpu_getInterface(treeitemGuid)); + if (sti_c) + { + _c = sti_c->getItem(); + } + } + scriptVar retval = MAKE_SCRIPT_INT(0); + if (sp != NULL) + { + int a = 0; + a = sp->getNumVisibleChildItems(_c); + retval = MAKE_SCRIPT_INT(a); + } + return retval; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_getNumVisibleItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + scriptVar retval = MAKE_SCRIPT_INT(0); + if (sp != NULL) + { + int a = 0; + a = sp->getNumVisibleItems(); + retval = MAKE_SCRIPT_INT(a); + } + return retval; +} + +/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_enumVisibleItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + int _n = GET_SCRIPT_INT(n); + scriptVar retval = MAKE_SCRIPT_OBJECT(NULL); + if (sp != NULL) + { + TreeItem *a = NULL; + a = sp->enumVisibleItems(_n); + if (a != NULL) + { + ScriptTreeItem *item = sp->bindScriptTreeItem(a); + if (item != NULL) + { + retval = MAKE_SCRIPT_OBJECT(item->getScriptObject()); + } + } + } + return retval; +} + +/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_enumVisibleChildItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar c, scriptVar n) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_c = NULL; + ScriptObject *so_c = GET_SCRIPT_OBJECT(c); + if (so_c) + { + ScriptTreeItem *sti_c = static_cast<ScriptTreeItem *>(so_c->vcpu_getInterface(treeitemGuid)); + if (sti_c) + { + _c = sti_c->getItem(); + } + } + int _n = GET_SCRIPT_INT(n); + scriptVar retval = MAKE_SCRIPT_OBJECT(NULL); + if (sp != NULL) + { + TreeItem *a = NULL; + a = sp->enumVisibleChildItems(_c, _n); + if (a != NULL) + { + ScriptTreeItem *item = sp->bindScriptTreeItem(a); + if (item != NULL) + { + retval = MAKE_SCRIPT_OBJECT(item->getScriptObject()); + } + } + } + return retval; +} + +/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_enumAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + int _n = GET_SCRIPT_INT(n); + scriptVar retval = MAKE_SCRIPT_OBJECT(NULL); + if (sp != NULL) + { + TreeItem *a = NULL; + a = sp->enumAllItems(_n); + if (a != NULL) + { + ScriptTreeItem *item = sp->bindScriptTreeItem(a); + if (item != NULL) + { + retval = MAKE_SCRIPT_OBJECT(item->getScriptObject()); + } + } + } + return retval; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_getItemRectX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + scriptVar retval = MAKE_SCRIPT_INT(0); + if (sp != NULL) + { + int a = 0; + RECT r; + sp->getItemRect(_item, &r); + a = r.left; + retval = MAKE_SCRIPT_INT(a); + } + return retval; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_getItemRectY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + scriptVar retval = MAKE_SCRIPT_INT(0); + if (sp != NULL) + { + int a = 0; + RECT r; + sp->getItemRect(_item, &r); + a = r.top; + retval = MAKE_SCRIPT_INT(a); + } + return retval; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_getItemRectW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + scriptVar retval = MAKE_SCRIPT_INT(0); + if (sp != NULL) + { + int a = 0; + RECT r; + sp->getItemRect(_item, &r); + a = r.left - r.right; + retval = MAKE_SCRIPT_INT(a); + } + return retval; +} + +/*Int*/ scriptVar GuiTreeScriptController::guitree_getItemRectH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + TreeItem *_item = NULL; + ScriptObject *so_item = GET_SCRIPT_OBJECT(item); + if (so_item) + { + ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid)); + if (sti_item) + { + _item = sti_item->getItem(); + } + } + scriptVar retval = MAKE_SCRIPT_INT(0); + if (sp != NULL) + { + int a = 0; + RECT r; + sp->getItemRect(_item, &r); + a = r.bottom - r.top; + retval = MAKE_SCRIPT_INT(a); + } + return retval; +} + +#if 0 // Not implemented in TreeWnd, dammit. +/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_getItemFromPoint(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) +{ + SCRIPT_FUNCTION_INIT + ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid)); + int _y = GET_SCRIPT_INT(y); + int _x = GET_SCRIPT_INT(x); + scriptVar retval = MAKE_SCRIPT_OBJECT(NULL); + if (sp != NULL) + { + TreeItem *a = NULL; + POINT p = {_x, _y}; + a = sp->getItemFromPoint(&p); + if (a != NULL) + { + ScriptTreeItem *item = sp->bindScriptTreeItem(a); + if (item != NULL) + { + retval = MAKE_SCRIPT_OBJECT(item->getScriptObject()); + } + } + } + return retval; +} +#endif + +// ----------------------------------------------------------------------- +// Script Object For The Tree Item + +ScriptTreeItem::ScriptTreeItem(TreeItem *_item, ScriptTree *_tree) : item(_item), tree(_tree), SCRIPTTREEITEM_SCRIPTPARENT() +{ + getScriptObject()->vcpu_setInterface(treeitemGuid, (void *)static_cast<ScriptTreeItem *>(this)); + getScriptObject()->vcpu_setClassName(L"TreeItem"); + getScriptObject()->vcpu_setController(treeItemController); +} + +ScriptTreeItem::~ScriptTreeItem() +{} + +int ScriptTreeItem::getNumChildren() +{ + ASSERT(item); + return item->getNumChildren(); +} + +void ScriptTreeItem::setLabel(const wchar_t *label) +{ + ASSERT(item); + item->setLabel(label); +} + +const wchar_t *ScriptTreeItem::getLabel() +{ + ASSERT(item); + return item->getLabel(); +} + +void ScriptTreeItem::ensureVisible() +{ + ASSERT(item); + item->ensureVisible(); +} + +TreeItem *ScriptTreeItem::getNthChild(int nth) +{ + ASSERT(item); + return item->getNthChild(nth); +} + +TreeItem *ScriptTreeItem::getChild() +{ + ASSERT(item); + return item->getChild(); +} + +TreeItem *ScriptTreeItem::getChildSibling(TreeItem *_item) +{ + ASSERT(item); + return item->getChildSibling(_item); +} + +TreeItem *ScriptTreeItem::getSibling() +{ + ASSERT(item); + return item->getSibling(); +} + +TreeItem *ScriptTreeItem::getParent() +{ + ASSERT(item); + return item->getParent(); +} + +void ScriptTreeItem::editLabel() +{ + ASSERT(item); + item->editLabel(); +} + +bool ScriptTreeItem::hasSubItems() +{ + ASSERT(item); + return item->hasSubItems(); +} + +void ScriptTreeItem::setSorted(int issorted) +{ + ASSERT(item); + item->setSorted(issorted); +} + +void ScriptTreeItem::setChildTab(int haschildtab) +{ + ASSERT(item); + item->setChildTab(haschildtab); +} + +bool ScriptTreeItem::isSorted() +{ + ASSERT(item); + return item->isSorted(); +} + +bool ScriptTreeItem::isCollapsed() +{ + ASSERT(item); + return item->isCollapsed(); +} + +bool ScriptTreeItem::isExpanded() +{ + ASSERT(item); + return item->isExpanded(); +} + +void ScriptTreeItem::invalidate() +{ + ASSERT(item); + item->invalidate(); +} + +bool ScriptTreeItem::isSelected() +{ + ASSERT(item); + return item->isSelected(); +} + +bool ScriptTreeItem::isHilited() +{ + ASSERT(item); + return item->isHilited(); +} + +void ScriptTreeItem::setHilited(bool ishilited) +{ + ASSERT(item); + item->setHilited(ishilited); +} + +int ScriptTreeItem::collapse() +{ + ASSERT(item); + return item->collapse(); +} + +int ScriptTreeItem::expand() +{ + ASSERT(item); + return item->expand(); +} + +#if 0 +// This was never implemented! +void ScriptTreeItem::setCurrent(bool tf) +{ + ASSERT(item); + item->setCurrent(tf); +} +#endif + +TreeWnd *ScriptTreeItem::getTree() +{ + ASSERT(item); + return item->getTree(); +} + +// ----------------------------------------------------------------------- +// Script Controller For The Tree Item + +TreeItemScriptController _treeItemController; +TreeItemScriptController *treeItemController = &_treeItemController; + +// -- Functions table ------------------------------------- +function_descriptor_struct TreeItemScriptController::exportedFunction[] = { + {L"getNumChildren", 0, (void*)TreeItemScriptController::treeitem_getNumChildren }, + {L"setLabel", 1, (void*)TreeItemScriptController::treeitem_setLabel }, + {L"getLabel", 0, (void*)TreeItemScriptController::treeitem_getLabel }, + {L"ensureVisible", 0, (void*)TreeItemScriptController::treeitem_ensureVisible }, + {L"getNthChild", 1, (void*)TreeItemScriptController::treeitem_getNthChild }, + {L"getChild", 0, (void*)TreeItemScriptController::treeitem_getChild }, + {L"getChildSibling", 1, (void*)TreeItemScriptController::treeitem_getChildSibling }, + {L"getSibling", 0, (void*)TreeItemScriptController::treeitem_getSibling }, + {L"getParent", 0, (void*)TreeItemScriptController::treeitem_getParent }, + {L"editLabel", 0, (void*)TreeItemScriptController::treeitem_editLabel }, + {L"hasSubItems", 0, (void*)TreeItemScriptController::treeitem_hasSubItems }, + {L"setSorted", 1, (void*)TreeItemScriptController::treeitem_setSorted }, + {L"setChildTab", 1, (void*)TreeItemScriptController::treeitem_setChildTab }, + {L"isSorted", 0, (void*)TreeItemScriptController::treeitem_isSorted }, + {L"isCollapsed", 0, (void*)TreeItemScriptController::treeitem_isCollapsed }, + {L"isExpanded", 0, (void*)TreeItemScriptController::treeitem_isExpanded }, + {L"invalidate", 0, (void*)TreeItemScriptController::treeitem_invalidate }, + {L"isSelected", 0, (void*)TreeItemScriptController::treeitem_isSelected }, + {L"isHilited", 0, (void*)TreeItemScriptController::treeitem_isHilited }, + {L"setHilited", 1, (void*)TreeItemScriptController::treeitem_setHilited }, + {L"collapse", 0, (void*)TreeItemScriptController::treeitem_collapse }, + {L"expand", 0, (void*)TreeItemScriptController::treeitem_expand }, + {L"getTree", 0, (void*)TreeItemScriptController::treeitem_getTree }, + + {L"onTreeAdd", 0, (void*)TreeItemScriptController::treeitem_onTreeAdd }, + {L"onTreeRemove", 0, (void*)TreeItemScriptController::treeitem_onTreeRemove }, + {L"onSelect", 0, (void*)TreeItemScriptController::treeitem_onSelect }, + {L"onDeselect", 0, (void*)TreeItemScriptController::treeitem_onDeselect }, + {L"onLeftDoubleClick", 0, (void*)TreeItemScriptController::treeitem_onLeftDoubleClick }, + {L"onRightDoubleClick", 0, (void*)TreeItemScriptController::treeitem_onRightDoubleClick }, + {L"onChar", 1, (void*)TreeItemScriptController::treeitem_onChar }, + {L"onExpand", 0, (void*)TreeItemScriptController::treeitem_onExpand }, + {L"onCollapse", 0, (void*)TreeItemScriptController::treeitem_onCollapse }, + {L"onBeginLabelEdit", 0, (void*)TreeItemScriptController::treeitem_onBeginLabelEdit }, + {L"onEndLabelEdit", 1, (void*)TreeItemScriptController::treeitem_onEndLabelEdit }, + {L"onContextMenu", 2, (void*)TreeItemScriptController::treeitem_onContextMenu }, + + }; + +StringW TreeItemScriptController::staticStr; +ScriptTreeMap TreeItemScriptController::g_scriptitems; + +ScriptObject *TreeItemScriptController::instantiate() +{ + ScriptTreeItem *sp = new ScriptTreeItem; + ASSERT(sp != NULL); + TreeItem *child_item = new TreeItemScript(L"", sp); + ASSERT(child_item != NULL); + sp->setItem(child_item); + TISC::g_scriptitems.insert({ child_item, sp }); + // We're not attached to a tree. that's okay! + return sp->getScriptObject(); +} + +// If the script asks to delete the item, delete the internal item as well. +// We tell the owning ScriptTree to remove this object. +void TreeItemScriptController::destroy(ScriptObject *o) +{ + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + ASSERT(sp != NULL); + if (!sp->destroyScriptTreeItem()) + { + auto item = sp->getItem(); + // Ask the owner tree to do it for us, but if not owned, we do it ourselves. + if (item) + { + //TISC::g_scriptitems.delItem(sp->getItem()); + auto it = TISC::g_scriptitems.find(item); + if (TISC::g_scriptitems.end() != it) + { + TISC::g_scriptitems.erase(it); + } + } + // AND we delete our item, since we're not a part of a tree that will do it for us. + delete item; + delete sp; + } +} + +void *TreeItemScriptController::encapsulate(ScriptObject *o) +{ + return NULL; // no encapsulation for guitrees yet +} + +void TreeItemScriptController::deencapsulate(void *o) +{} + +int TreeItemScriptController::getNumFunctions() +{ + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *TreeItemScriptController::getExportedFunctions() +{ + return exportedFunction; +} + +/*int*/ scriptVar TreeItemScriptController::treeitem_getNumChildren(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + int a = 0; + if (sp != NULL) + { + a = sp->getNumChildren(); + } + return MAKE_SCRIPT_INT(a); +} + +/*void*/ scriptVar TreeItemScriptController::treeitem_setLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar label) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + StringW _label = GET_SCRIPT_STRING(label); + if (sp != NULL) + { + sp->setLabel(_label); + } + RETURN_SCRIPT_VOID; +} + +/*String*/ scriptVar TreeItemScriptController::treeitem_getLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + if (sp != NULL) + { + staticStr = sp->getLabel(); + } + return MAKE_SCRIPT_STRING(staticStr); +} + +/*void*/ scriptVar TreeItemScriptController::treeitem_ensureVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + if (sp != NULL) + { + sp->ensureVisible(); + } + RETURN_SCRIPT_VOID; +} + +/*TreeItem*/ scriptVar TreeItemScriptController::treeitem_getNthChild(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar nth) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + int _nth = GET_SCRIPT_INT(nth); + TreeItem *a = NULL; + if (sp != NULL) + { + a = sp->getNthChild(_nth); + } + ScriptTree *tree = sp->getScriptTree(); + ScriptTreeItem *retval = NULL; + if (tree && a) + { + retval = tree->bindScriptTreeItem(a); + } + if (retval) + { + return MAKE_SCRIPT_OBJECT(retval->getScriptObject()); + } + return MAKE_SCRIPT_OBJECT(NULL); // Return NULL +} + +/*TreeItem*/ scriptVar TreeItemScriptController::treeitem_getChild(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + TreeItem *a = NULL; + if (sp != NULL) + { + a = sp->getChild(); + } + ScriptTree *tree = sp->getScriptTree(); + ScriptTreeItem *retval = NULL; + if (tree && a) + { + retval = tree->bindScriptTreeItem(a); + } + if (retval) + { + return MAKE_SCRIPT_OBJECT(retval->getScriptObject()); + } + return MAKE_SCRIPT_OBJECT(NULL); // Return NULL +} + +/*TreeItem*/ scriptVar TreeItemScriptController::treeitem_getChildSibling(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar _item) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + TreeItem *__item = NULL; + ScriptObject *io = GET_SCRIPT_OBJECT(_item); + if (io) + { + ScriptTreeItem *sio = static_cast<ScriptTreeItem *>(io->vcpu_getInterface(treeitemGuid)); + if (sio) + { + __item = sio->getItem(); + } + } + TreeItem *a = NULL; + if (sp != NULL) + { + a = sp->getChildSibling(__item); + } + ScriptTree *tree = sp->getScriptTree(); + ScriptTreeItem *retval = NULL; + if (tree && a) + { + retval = tree->bindScriptTreeItem(a); + } + if (retval) + { + return MAKE_SCRIPT_OBJECT(retval->getScriptObject()); + } + return MAKE_SCRIPT_OBJECT(NULL); // Return NULL +} + +/*TreeItem*/ scriptVar TreeItemScriptController::treeitem_getSibling(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + TreeItem *a = NULL; + if (sp != NULL) + { + a = sp->getSibling(); + } + ScriptTree *tree = sp->getScriptTree(); + ScriptTreeItem *retval = NULL; + if (tree && a) + { + retval = tree->bindScriptTreeItem(a); + } + if (retval) + { + return MAKE_SCRIPT_OBJECT(retval->getScriptObject()); + } + return MAKE_SCRIPT_OBJECT(NULL); // Return NULL +} + +/*TreeItem*/ scriptVar TreeItemScriptController::treeitem_getParent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + TreeItem *a = NULL; + if (sp != NULL) + { + a = sp->getParent(); + } + ScriptTree *tree = sp->getScriptTree(); + ScriptTreeItem *retval = NULL; + if (tree && a) + { + retval = tree->bindScriptTreeItem(a); + } + if (retval) + { + return MAKE_SCRIPT_OBJECT(retval->getScriptObject()); + } + return MAKE_SCRIPT_OBJECT(NULL); // Return NULL +} + +/*void*/ scriptVar TreeItemScriptController::treeitem_editLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + if (sp != NULL) + { + sp->editLabel(); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar TreeItemScriptController::treeitem_hasSubItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + int a = 0; + if (sp != NULL) + { + a = sp->hasSubItems(); + } + return MAKE_SCRIPT_INT(a); +} + +/*void*/ scriptVar TreeItemScriptController::treeitem_setSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar issorted) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + int _issorted = GET_SCRIPT_INT(issorted); + if (sp != NULL) + { + sp->setSorted(_issorted); + } + RETURN_SCRIPT_VOID; +} + +/*void*/ scriptVar TreeItemScriptController::treeitem_setChildTab(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar haschildtab) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + int _haschildtab = GET_SCRIPT_INT(haschildtab); + if (sp != NULL) + { + sp->setChildTab(_haschildtab); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar TreeItemScriptController::treeitem_isSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + int a = 0; + if (sp != NULL) + { + a = sp->isSorted(); + } + return MAKE_SCRIPT_INT(a); +} + +/*int*/ scriptVar TreeItemScriptController::treeitem_isCollapsed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + int a = 0; + if (sp != NULL) + { + a = sp->isCollapsed(); + } + return MAKE_SCRIPT_INT(a); +} + +/*int*/ scriptVar TreeItemScriptController::treeitem_isExpanded(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + int a = 0; + if (sp != NULL) + { + a = sp->isExpanded(); + } + return MAKE_SCRIPT_INT(a); +} + +/*void*/ scriptVar TreeItemScriptController::treeitem_invalidate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + if (sp != NULL) + { + sp->invalidate(); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar TreeItemScriptController::treeitem_isSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + int a = 0; + if (sp != NULL) + { + a = sp->isSelected(); + } + return MAKE_SCRIPT_INT(a); +} + +/*int*/ scriptVar TreeItemScriptController::treeitem_isHilited(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + int a = 0; + if (sp != NULL) + { + a = sp->isHilited(); + } + return MAKE_SCRIPT_INT(a); +} + +/*void*/ scriptVar TreeItemScriptController::treeitem_setHilited(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar ishilited) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + int _ishilited = GET_SCRIPT_INT(ishilited); + if (sp != NULL) + { + sp->setHilited(!!_ishilited); + } + RETURN_SCRIPT_VOID; +} + +/*int*/ scriptVar TreeItemScriptController::treeitem_collapse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + int a = 0; + if (sp != NULL) + { + a = sp->collapse(); + } + return MAKE_SCRIPT_INT(a); +} + +/*int*/ scriptVar TreeItemScriptController::treeitem_expand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + int a = 0; + if (sp != NULL) + { + a = sp->expand(); + } + return MAKE_SCRIPT_INT(a); +} + +#if 0 +// This was never implemented! +/*void*/ scriptVar TreeItemScriptController::treeitem_setCurrent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar tf) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + int _tf = GET_SCRIPT_INT(tf); + if (sp != NULL) + { + sp->setCurrent(_tf); + } + RETURN_SCRIPT_VOID; +} +#endif + +/*GuiTree*/ scriptVar TreeItemScriptController::treeitem_getTree(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid)); + ScriptTree *a = NULL; + ScriptObject *retval = NULL; + if (sp != NULL) + { + a = sp->getScriptTree(); + } + if (a) + { + retval = a->getScriptObject(); + } + return MAKE_SCRIPT_OBJECT(retval); +} + +/*void*/ scriptVar TreeItemScriptController::treeitem_onTreeAdd(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS0(o, guiTreeController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +/*void*/ scriptVar TreeItemScriptController::treeitem_onTreeRemove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS0(o, guiTreeController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +/*void*/ scriptVar TreeItemScriptController::treeitem_onSelect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS0(o, guiTreeController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +/*void*/ scriptVar TreeItemScriptController::treeitem_onDeselect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS0(o, guiTreeController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +/*int*/ scriptVar TreeItemScriptController::treeitem_onLeftDoubleClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS0(o, guiTreeController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +/*int*/ scriptVar TreeItemScriptController::treeitem_onRightDoubleClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS0(o, guiTreeController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +/*int*/ scriptVar TreeItemScriptController::treeitem_onChar(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar _key) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, guiTreeController, _key); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, _key); +} + +/*void*/ scriptVar TreeItemScriptController::treeitem_onExpand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS0(o, guiTreeController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +/*void*/ scriptVar TreeItemScriptController::treeitem_onCollapse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS0(o, guiTreeController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +/*int*/ scriptVar TreeItemScriptController::treeitem_onBeginLabelEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS0(o, guiTreeController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +/*int*/ scriptVar TreeItemScriptController::treeitem_onEndLabelEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar _newlabel) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS1(o, guiTreeController, _newlabel); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT1(o, _newlabel); +} + +/*int*/ scriptVar TreeItemScriptController::treeitem_onContextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar _x, /*int*/ scriptVar _y) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS2(o, guiTreeController, _x, _y); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT2(o, _x, _y); +} diff --git a/Src/Wasabi/api/skin/widgets/xuitree.h b/Src/Wasabi/api/skin/widgets/xuitree.h new file mode 100644 index 00000000..2d386440 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuitree.h @@ -0,0 +1,326 @@ +#ifndef __XUITREE_H +#define __XUITREE_H + +#include <map> +#include <api/wnd/wndclass/treewnd.h> +#include <api/script/objcontroller.h> +#include <bfc/depend.h> + +class HPNode; +class ScriptTreeItem; +class svc_textFeed; + +#define SCRIPTTREE_PARENT TreeWnd + +typedef std::map<TreeItem *,ScriptTreeItem *> ScriptTreeMap; + +// ----------------------------------------------------------------------- +class ScriptTree : public SCRIPTTREE_PARENT, public DependentViewerI { + + public: + + ScriptTree(); + virtual ~ScriptTree(); + + virtual int onInit(); + + int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + int onReloadConfig(); + + virtual int viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen); + virtual void onSetVisible(int i); + + virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source); + + // Find a ScriptTreeItem to wrap a TreeItem + ScriptTreeItem *bindScriptTreeItem(TreeItem *item); + + // Someone is deleting a ScriptTreeItem so we should stop tracking it. + int destroyScriptTreeItem(ScriptTreeItem *item); + + // Transfer a TreeItem from our tree to a different tree (or global space) + int transferScriptTreeItem(TreeItem *item, ScriptTree *tree); + + // Callback methods that send hooks into the Script system + virtual int onLeftButtonDown(int x, int y); + virtual int onLeftButtonUp(int x, int y); + virtual int onRightButtonUp(int x, int y); + virtual int onMouseMove(int x, int y); + virtual int wantAutoContextMenu(); + virtual int onLeftButtonDblClk(int x, int y); + virtual int onRightButtonDblClk(int x, int y); + virtual int onMouseWheelUp(int clicked, int lines); + virtual int onMouseWheelDown(int clicked, int lines); + virtual int onContextMenu(int x, int y); + virtual int onChar(wchar_t c); + virtual int onKeyDown(int keycode); + virtual void onItemRecvDrop(TreeItem *item); + virtual void onLabelChange(TreeItem *item); + virtual void onItemSelected(TreeItem *item); + virtual void onItemDeselected(TreeItem *item); + virtual int onKillFocus(); + + + + // Valid XML Params for Tree + enum { + SCRIPTTREE_SETITEMS = 0, + SCRIPTTREE_FEED, + SCRIPTTREE_SORTED, + SCRIPTTREE_CHILDTABS, + SCRIPTTREE_EXPANDROOT, + }; + +protected: + /*static */void CreateXMLParameters(int master_handle); + + private: + +#ifdef WASABI_COMPILE_CONFIG + void saveToConfig(); + void selectFromConfig(); +#endif + void expandRoot(int val); + + void fillFromParams(); + void fillFromHPNode(HPNode *node, TreeItem *parent = NULL); + + int selectEntry(const wchar_t *e, int cb=1); + void selectEntries(const wchar_t *multientry, int cb=1); + + void openFeed(const wchar_t *feedid); + void closeFeed(); + + StringW items; + int myxuihandle; + int childtabs; + int expandroot; + svc_textFeed *feed; + StringW last_feed; + static XMLParamPair params[]; + +// ScriptTreeMap scriptitems; +}; + +// ----------------------------------------------------------------------------------------------------- +class GuiTreeScriptController : public ScriptObjectControllerI { + public: + + virtual const wchar_t *getClassName() { return L"GuiTree"; } + virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; } + virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); } + virtual int getNumFunctions(); + virtual const function_descriptor_struct *getExportedFunctions(); + virtual GUID getClassGuid() { return guitreeGuid; } + virtual ScriptObject *instantiate(); + virtual void destroy(ScriptObject *o); + virtual void *encapsulate(ScriptObject *o); + virtual void deencapsulate(void *o); + + public: + static scriptVar /*int*/ guitree_getNumRootItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar /*TreeItem*/ guitree_enumRootItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ which); + + static /*Int*/ scriptVar guitree_onLeftButtonDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y); + static /*Int*/ scriptVar guitree_onLeftButtonUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y); + static /*Int*/ scriptVar guitree_onRightButtonUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y); + static /*Int*/ scriptVar guitree_onMouseMove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y); + static /*Int*/ scriptVar guitree_wantAutoContextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*Int*/ scriptVar guitree_onLeftButtonDblClk(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y); + static /*Int*/ scriptVar guitree_onRightButtonDblClk(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y); + static /*Int*/ scriptVar guitree_onMouseWheelUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar clicked, /*Int*/ scriptVar lines); + static /*Int*/ scriptVar guitree_onMouseWheelDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar clicked, /*Int*/ scriptVar lines); + static /*Int*/ scriptVar guitree_onContextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y); + static /*Int*/ scriptVar guitree_onChar(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar c); + static /*Int*/ scriptVar guitree_onKeyDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar keycode); + static /*Void*/ scriptVar guitree_onItemRecvDrop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Void*/ scriptVar guitree_onLabelChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Void*/ scriptVar guitree_onItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Void*/ scriptVar guitree_onItemDeselected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Int*/ scriptVar guitree_onKillFocus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + + static /*Void*/ scriptVar guitree_jumpToNext(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar c); + static /*Void*/ scriptVar guitree_ensureItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Int*/ scriptVar guitree_getContentsWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*Int*/ scriptVar guitree_getContentsHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*TreeItem*/ scriptVar guitree_addTreeItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item, /*TreeItem*/ scriptVar par, /*Int*/ scriptVar sorted, /*Int*/ scriptVar haschildtab); + static /*Int*/ scriptVar guitree_removeTreeItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Void*/ scriptVar guitree_moveTreeItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item, /*TreeItem*/ scriptVar newparent); + static /*Void*/ scriptVar guitree_deleteAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*Int*/ scriptVar guitree_expandItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Void*/ scriptVar guitree_expandItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Int*/ scriptVar guitree_collapseItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Void*/ scriptVar guitree_collapseItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Void*/ scriptVar guitree_selectItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Void*/ scriptVar guitree_selectItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Void*/ scriptVar guitree_delItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Void*/ scriptVar guitree_hiliteItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Void*/ scriptVar guitree_unhiliteItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*TreeItem*/ scriptVar guitree_getCurItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*TreeItem*/ scriptVar guitree_hitTest(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y); + static /*Void*/ scriptVar guitree_editItemLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Void*/ scriptVar guitree_cancelEditLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar destroyit); + static /*Void*/ scriptVar guitree_setAutoEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar ae); + static /*Int*/ scriptVar guitree_getAutoEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*TreeItem*/ scriptVar guitree_getByLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item, /*String*/ scriptVar name); + static /*Void*/ scriptVar guitree_setSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar dosort); + static /*Int*/ scriptVar guitree_getSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*Void*/ scriptVar guitree_sortTreeItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*TreeItem*/ scriptVar guitree_getSibling(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Void*/ scriptVar guitree_setAutoCollapse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar doautocollapse); + static /*Int*/ scriptVar guitree_setFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar newsize); + static /*Int*/ scriptVar guitree_getFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*Int*/ scriptVar guitree_getNumVisibleChildItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar c); + static /*Int*/ scriptVar guitree_getNumVisibleItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*TreeItem*/ scriptVar guitree_enumVisibleItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar n); + static /*TreeItem*/ scriptVar guitree_enumVisibleChildItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar c, /*Int*/ scriptVar n); + static /*TreeItem*/ scriptVar guitree_enumAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar n); + static /*Int*/ scriptVar guitree_getItemRectX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Int*/ scriptVar guitree_getItemRectY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Int*/ scriptVar guitree_getItemRectW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); + static /*Int*/ scriptVar guitree_getItemRectH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item); +// static /*TreeItem*/ scriptVar guitree_getItemFromPoint(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y); + + private: + static function_descriptor_struct exportedFunction[]; + + static StringW staticStr; +}; + +extern GuiTreeScriptController *guiTreeController; + + +// ----------------------------------------------------------------------- +extern const wchar_t ScriptTreeXuiObjectStr[]; +extern char ScriptTreeXuiSvcName[]; +class ScriptTreeXuiSvc : public XuiObjectSvc<ScriptTree, ScriptTreeXuiObjectStr, ScriptTreeXuiSvcName> {}; + + + +// ----------------------------------------------------------------------- +#define SCRIPTTREEITEM_SCRIPTPARENT RootObjectInstance + +class ScriptTreeItem : public SCRIPTTREEITEM_SCRIPTPARENT { +public: + ScriptTreeItem(TreeItem *_item = NULL, ScriptTree *_tree = NULL); + virtual ~ScriptTreeItem(); + + TreeItem *getItem() {return item;} + void setItem(TreeItem *_item) {item = _item;} + ScriptTree *getScriptTree() {return tree;} + void setScriptTree(ScriptTree *_tree) {tree = _tree;} + + int destroyScriptTreeItem() { + if (tree) return tree->destroyScriptTreeItem(this); // CAREFUL, WE GET OURSELVES DELETED HERE!!!!!!!! + return 0; + } + +// These methods all thunk directly to the TreeItem +public: + int getNumChildren(); + void setLabel(const wchar_t *label); + const wchar_t *getLabel(); + void ensureVisible(); + TreeItem *getNthChild(int nth); + TreeItem *getChild(); + TreeItem *getChildSibling(TreeItem *_item); + TreeItem *getSibling(); + TreeItem *getParent(); + void editLabel(); + bool hasSubItems(); + void setSorted(int issorted); + void setChildTab(int haschildtab); + bool isSorted(); + bool isCollapsed(); + bool isExpanded(); + void invalidate(); + bool isSelected(); + bool isHilited(); + void setHilited(bool ishilited); + int collapse(); + int expand(); +// void setCurrent(bool tf); + TreeWnd *getTree(); + +private: + ScriptTreeItem *bindScriptTreeItem(TreeItem *item) { + if (tree) return tree->bindScriptTreeItem(item); + return NULL; + } + + TreeItem *item; + ScriptTree *tree; +}; + + +// ----------------------------------------------------------------------------------------------------- +class TreeItemScriptController : public ScriptObjectControllerI { + public: + + virtual const wchar_t *getClassName() { return L"TreeItem"; } + virtual const wchar_t *getAncestorClassName() { return L"Object"; } + virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(rootObjectGuid); } + virtual int getNumFunctions(); + virtual const function_descriptor_struct *getExportedFunctions(); + virtual GUID getClassGuid() { return treeitemGuid; } + virtual ScriptObject *instantiate(); + virtual void destroy(ScriptObject *o); + virtual void *encapsulate(ScriptObject *o); + virtual void deencapsulate(void *o); + + public: + static /*int*/ scriptVar treeitem_getNumChildren(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar treeitem_setLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar label); + static /*String*/ scriptVar treeitem_getLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar treeitem_ensureVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*TreeItem*/ scriptVar treeitem_getNthChild(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar nth); + static /*TreeItem*/ scriptVar treeitem_getChild(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*TreeItem*/ scriptVar treeitem_getChildSibling(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar _item); + static /*TreeItem*/ scriptVar treeitem_getSibling(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*TreeItem*/ scriptVar treeitem_getParent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar treeitem_editLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar treeitem_hasSubItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar treeitem_setSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar issorted); + static /*void*/ scriptVar treeitem_setChildTab(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar haschildtab); + static /*int*/ scriptVar treeitem_isSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar treeitem_isCollapsed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar treeitem_isExpanded(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar treeitem_invalidate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar treeitem_isSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar treeitem_isHilited(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar treeitem_setHilited(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar ishilited); + static /*int*/ scriptVar treeitem_collapse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar treeitem_expand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); +// static /*void*/ scriptVar treeitem_setCurrent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar tf); + static /*GuiTree*/ scriptVar treeitem_getTree(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + + static /*void*/ scriptVar treeitem_onTreeAdd(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar treeitem_onTreeRemove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar treeitem_onSelect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*void*/ scriptVar treeitem_onDeselect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar treeitem_onLeftDoubleClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) ; + static /*int*/ scriptVar treeitem_onRightDoubleClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) ; + static /*int*/ scriptVar treeitem_onChar(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar _key) ; + static /*void*/ scriptVar treeitem_onExpand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) ; + static /*void*/ scriptVar treeitem_onCollapse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) ; + static /*int*/ scriptVar treeitem_onBeginLabelEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static /*int*/ scriptVar treeitem_onEndLabelEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar _newlabel); + static /*int*/ scriptVar treeitem_onContextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar _x, /*int*/ scriptVar _y); + + + private: + static function_descriptor_struct exportedFunction[]; + + static StringW staticStr; + + friend ScriptTree; + static ScriptTreeMap g_scriptitems; // items not living in trees are tracked here. + +}; + +extern TreeItemScriptController *treeItemController; + +#define TISC TreeItemScriptController + + +#endif diff --git a/Src/Wasabi/api/skin/widgets/xuiwndholder.cpp b/Src/Wasabi/api/skin/widgets/xuiwndholder.cpp new file mode 100644 index 00000000..8cd3e116 --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuiwndholder.cpp @@ -0,0 +1,272 @@ +#include <precomp.h> +#include "xuiwndholder.h" +#include <tataki/canvas/ifc_canvas.h> +#include <bfc/parse/paramparser.h> +#include <api/script/objects/sregion.h> + +// ----------------------------------------------------------------------- +const wchar_t WindowHolderXuiObjectStr[] = L"WindowHolder"; // This is the xml tag +const wchar_t WindowHolderXuiObjectStrCompat[] = L"Component"; // This is the old xml tag + +char WindowHolderXuiSvcName[] = "WindowHolder xui object"; +char WindowHolderXuiSvcNameCompat[] = "Component xui object"; + +// {7DB51C8C-36C0-4585-9240-A2DB22B1B8F7} +static const GUID pvt_xuiWindowHolder = +{ 0x7db51c8c, 0x36c0, 0x4585, { 0x92, 0x40, 0xa2, 0xdb, 0x22, 0xb1, 0xb8, 0xf7 } }; + +XMLParamPair XuiWindowHolder::params[] = { + {XUIWNDHOLDER_ADDHOLD, L"PARAM"}, + {XUIWNDHOLDER_ADDHOLD, L"COMPONENT"}, + {XUIWNDHOLDER_ADDHOLD, L"HOLD"}, + {XUIWNDHOLDER_SETNOSHOWCMDBAR, L"NOSHOWCMDBAR"}, + {XUIWNDHOLDER_SETNOANIMRECTS, L"NOANIMATEDRECTS"}, + {XUIWNDHOLDER_SETNOANIMRECTS, L"DISABLEANIMATEDRECTS"}, + {XUIWNDHOLDER_SETAUTOOPEN, L"AUTOOPEN"}, + {XUIWNDHOLDER_SETAUTOCLOSE, L"AUTOCLOSE"}, + {XUIWNDHOLDER_SETAUTOFOCUS, L"AUTOFOCUS"}, + {XUIWNDHOLDER_SETAUTOAVAILABLE, L"AUTOAVAILABLE"}, + }; +// ----------------------------------------------------------------------- +XuiWindowHolder::XuiWindowHolder() { + getScriptObject()->vcpu_setInterface(windowHolderGuid, (void *)static_cast<WindowHolder *>(this)); + getScriptObject()->vcpu_setInterface(pvt_xuiWindowHolder, (void *)static_cast<XuiWindowHolder *>(this)); + getScriptObject()->vcpu_setClassName(L"WindowHolder"); // this is the script class name + getScriptObject()->vcpu_setController(windowHolderController); + + myxuihandle = newXuiHandle(); + CreateXMLParameters(myxuihandle); + + setXmlParam(L"autofocus", L"1"); +} +void XuiWindowHolder::CreateXMLParameters(int master_handle) +{ + //XUIWNDHOLDER_PARENT::CreateXMLParameters(master_handle); + int numParams = sizeof(params) / sizeof(params[0]); + hintNumberOfParams(myxuihandle, numParams); + for (int i = 0;i < numParams;i++) + addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED); +} + +XuiWindowHolder::~XuiWindowHolder() { +} + +void XuiWindowHolder::setRegionFromMap(ScriptObject *map, int byte, int inverse) { +} + +void XuiWindowHolder::setRegion(ScriptObject *_region) { +//#pragma CHAT("bas", "lone", "I implemented setRegion for ya once SRegion is safe") +#if 1// if SRegion were cross-dll safe this would work + const GUID regionGuid = +{ 0x3a370c02, 0x3cbf, 0x439f, { 0x84, 0xf1, 0x86, 0x88, 0x5b, 0xcf, 0x1e, 0x36 } }; + void *reg = _region->vcpu_getInterface(regionGuid); + ASSERT(reg != NULL); + SRegion *sr = static_cast<SRegion*>(reg); + ASSERT(sr != NULL); + api_region *region = sr->getRegion(); + ASSERT(region != NULL); + api_region *clone = region->clone(); + clone->scale(getRenderRatio(), getRenderRatio()); + ifc_window *curRootWnd = getCurRootWnd(); + if (curRootWnd) + { +#ifdef _WIN32 + OSWINDOWHANDLE osWnd = curRootWnd->gethWnd(); + if (osWnd) + SetWindowRgn(osWnd, clone->makeWindowRegion(), TRUE); +#else +#warning port me + // can probably use a mask here +#endif + } + region->disposeClone(clone); +#endif +} + +// ----------------------------------------------------------------------- +int XuiWindowHolder::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return XUIWNDHOLDER_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + + switch (xmlattributeid) + { + case XUIWNDHOLDER_ADDHOLD: + if (!WCSICMP(value, L"@ALL@") || !WCSICMP(value, L"guid:default")) + { + setAcceptAllGuids(1); + setAcceptAllGroups(1); + } else { + setAcceptAllGuids(0); + setAcceptAllGroups(0); + ParamParser pp(value); + for (int i=0;i<pp.getNumItems();i++) { + const wchar_t *e = pp.enumItem(i); + if (*e == '{' || !WCSNICMP(e, L"guid:", 5)) { + GUID *g = parseGUID(e); + if (g) + addAcceptGuid(*g); + } + else + addAcceptGroup(e); + } + } + break; + case XUIWNDHOLDER_SETNOSHOWCMDBAR: + setNoCmdBar(WTOI(value)); + break; + case XUIWNDHOLDER_SETNOANIMRECTS: + setNoAnim(WTOI(value)); + break; + case XUIWNDHOLDER_SETAUTOOPEN: + setAutoOpen(WTOI(value)); + break; + case XUIWNDHOLDER_SETAUTOCLOSE: + setAutoClose(WTOI(value)); + break; + case XUIWNDHOLDER_SETAUTOFOCUS: + setAutoFocus(WTOI(value)); + break; + case XUIWNDHOLDER_SETAUTOAVAILABLE: + setAutoAvailable(WTOI(value)); + break; + default: + return 0; + } + return 1; +} + +GUID *XuiWindowHolder::parseGUID(const wchar_t *id) { + if (WCSNICMP(id, L"guid:{",6)==0) { + static GUID g; + id+=5; + g = nsGUID::fromCharW(id); + return &g; + } + if (id && *id == '{') { + static GUID g; + g = nsGUID::fromCharW(id); + return &g; + } + if(WCSICMP(id,L"guid:avs")==0) { + static GUID g={ 10, 12, 16, { 255, 123, 1, 1, 66, 99, 69, 12 } }; + return &g; + } + if (WCSICMP(id,L"guid:pl")==0 || WCSICMP(id,L"guid:playlist")==0) { + static GUID g={ 0x45f3f7c1, 0xa6f3, 0x4ee6, { 0xa1, 0x5e, 0x12, 0x5e, 0x92, 0xfc, 0x3f, 0x8d } }; + return &g; + } + if (WCSICMP(id,L"guid:ml")==0 || WCSICMP(id,L"guid:musiclibrary")==0 || WCSICMP(id,L"guid:library")==0) { + static GUID g={ 0x6b0edf80, 0xc9a5, 0x11d3, { 0x9f, 0x26, 0x00, 0xc0, 0x4f, 0x39, 0xff, 0xc6 } }; + return &g; + } + if(WCSICMP(id,L"guid:null")==0) { + static GUID g=INVALID_GUID; + return &g; + } + if(WCSICMP(id,L"guid:player")==0) { + static GUID g = { 0xe6323f86, 0x1724, 0x4cd3, { 0x9d, 0x87, 0x70, 0x59, 0x1f, 0xc1, 0x6e, 0x5e } }; + return &g; + } + + return NULL; +} + +// ----------------------------------------------------------------------- +// Script Object + +WindowHolderScriptController _windowHolderController; +WindowHolderScriptController *windowHolderController = &_windowHolderController; + +// -- Functions table ------------------------------------- +function_descriptor_struct WindowHolderScriptController::exportedFunction[] = { + {L"getGUID", 1, (void*)WindowHolderScriptController::script_getGUID }, + {L"setRegionFromMap", 3, (void*)WindowHolderScriptController::script_setRegionFromMap }, + {L"setRegion", 1, (void*)WindowHolderScriptController::script_setRegion }, + {L"getContent", 0, (void*)WindowHolderScriptController::script_getContent}, + {L"getComponentName", 0, (void*)WindowHolderScriptController::script_getComponentName}, +}; + +ScriptObject *WindowHolderScriptController::instantiate() { + XuiWindowHolder *wh = new XuiWindowHolder; + ASSERT(wh != NULL); + return wh->getScriptObject(); +} + +void WindowHolderScriptController::destroy(ScriptObject *o) { + XuiWindowHolder *wh = static_cast<XuiWindowHolder *>(o->vcpu_getInterface(pvt_xuiWindowHolder)); + ASSERT(wh != NULL); + delete wh; +} + +void *WindowHolderScriptController::encapsulate(ScriptObject *o) { + return NULL; // no encapsulation for windowholder yet +} + +void WindowHolderScriptController::deencapsulate(void *o) { +} + +int WindowHolderScriptController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *WindowHolderScriptController::getExportedFunctions() { + return exportedFunction; +} + +scriptVar WindowHolderScriptController::script_getComponentName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + XuiWindowHolder *wh = static_cast<XuiWindowHolder*>(o->vcpu_getInterface(pvt_xuiWindowHolder)); + + if (wh) + { + ifc_window *ro = wh->getCurRootWnd(); + if (ro) + { + return MAKE_SCRIPT_STRING(ro->getRootWndName()); + } + } + return MAKE_SCRIPT_STRING(L""); +} + +scriptVar WindowHolderScriptController::script_getGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + XuiWindowHolder *wh = static_cast<XuiWindowHolder*>(o->vcpu_getInterface(pvt_xuiWindowHolder)); + + if (wh) + { + static wchar_t guidstr[256]; + nsGUID::toCharW(wh->getCurGuid(), guidstr); + return MAKE_SCRIPT_STRING(guidstr); + } + return MAKE_SCRIPT_STRING(L""); +} + +scriptVar WindowHolderScriptController::script_setRegionFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inv) { + SCRIPT_FUNCTION_INIT + XuiWindowHolder *xu = static_cast<XuiWindowHolder*>(o->vcpu_getInterface(pvt_xuiWindowHolder)); + if (xu) xu->setRegionFromMap(GET_SCRIPT_OBJECT(map), GET_SCRIPT_INT(byte), GET_SCRIPT_INT(inv)); + RETURN_SCRIPT_VOID; +} + +scriptVar WindowHolderScriptController::script_setRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg) { + SCRIPT_FUNCTION_INIT + XuiWindowHolder *xu= static_cast<XuiWindowHolder*>(o->vcpu_getInterface(pvt_xuiWindowHolder)); + if (xu) xu->setRegion(GET_SCRIPT_OBJECT(reg)); + RETURN_SCRIPT_VOID; +} + +scriptVar WindowHolderScriptController::script_getContent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + XuiWindowHolder *xu= static_cast<XuiWindowHolder*>(o->vcpu_getInterface(pvt_xuiWindowHolder)); + if (xu) { + ifc_window *w = xu->getRootWndPtr(); + if (w) { + GuiObject *o = w->getGuiObject(); + if (o) + return MAKE_SCRIPT_OBJECT(o->guiobject_getScriptObject()); + } + } + RETURN_SCRIPT_NULL; +} diff --git a/Src/Wasabi/api/skin/widgets/xuiwndholder.h b/Src/Wasabi/api/skin/widgets/xuiwndholder.h new file mode 100644 index 00000000..13edc05a --- /dev/null +++ b/Src/Wasabi/api/skin/widgets/xuiwndholder.h @@ -0,0 +1,80 @@ +#ifndef __XUIWNDHOLDER_H +#define __XUIWNDHOLDER_H + +#include <api/wnd/wndclass/wndholder.h> +#include <api/script/scriptguid.h> +#include <api/script/objcontroller.h> + +#define XUIWNDHOLDER_PARENT WindowHolderWnd + +// ----------------------------------------------------------------------- +class XuiWindowHolder : public XUIWNDHOLDER_PARENT +{ + + public: + + XuiWindowHolder(); + virtual ~XuiWindowHolder(); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + void setRegionFromMap(ScriptObject *map, int byte, int inverse); + void setRegion(ScriptObject *region); + static GUID *parseGUID(const wchar_t *id); + +protected: + /*static */void CreateXMLParameters(int master_handle); + private: + + enum { + XUIWNDHOLDER_ADDHOLD = 10, + XUIWNDHOLDER_SETNOSHOWCMDBAR = 20, + XUIWNDHOLDER_SETNOANIMRECTS = 30, + XUIWNDHOLDER_SETAUTOOPEN = 40, + XUIWNDHOLDER_SETAUTOCLOSE = 50, + XUIWNDHOLDER_SETAUTOFOCUS = 60, + XUIWNDHOLDER_SETAUTOAVAILABLE = 70, + }; + static XMLParamPair params[]; + int myxuihandle; +}; + +// ----------------------------------------------------------------------------------------------------- +class WindowHolderScriptController: public ScriptObjectControllerI { + public: + + virtual const wchar_t *getClassName() { return L"WindowHolder"; } + virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; } + virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); } + virtual int getNumFunctions(); + virtual const function_descriptor_struct *getExportedFunctions(); + virtual GUID getClassGuid() { return windowHolderGuid; } + virtual ScriptObject *instantiate(); + virtual void destroy(ScriptObject *o); + virtual void *encapsulate(ScriptObject *o); + virtual void deencapsulate(void *o); + + public: + static scriptVar script_getGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_setRegionFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inv); + static scriptVar script_setRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg); + static scriptVar script_getContent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar script_getComponentName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + + private: + + static function_descriptor_struct exportedFunction[]; +}; + +extern WindowHolderScriptController *windowHolderController; + + +// ----------------------------------------------------------------------- +extern const wchar_t WindowHolderXuiObjectStr[]; +extern const wchar_t WindowHolderXuiObjectStrCompat[]; +extern char WindowHolderXuiSvcName[]; +extern char WindowHolderXuiSvcNameCompat[]; +class WindowHolderXuiSvc : public XuiObjectSvc<XuiWindowHolder, WindowHolderXuiObjectStr, WindowHolderXuiSvcName> {}; +class WindowHolderXuiSvc2 : public XuiObjectSvc<XuiWindowHolder, WindowHolderXuiObjectStrCompat, WindowHolderXuiSvcNameCompat> {}; + +#endif diff --git a/Src/Wasabi/api/skin/xmlobject.cpp b/Src/Wasabi/api/skin/xmlobject.cpp new file mode 100644 index 00000000..b7e43ccf --- /dev/null +++ b/Src/Wasabi/api/skin/xmlobject.cpp @@ -0,0 +1,174 @@ +#include <precomp.h> +#include <bfc/bfc_assert.h> +#include "xmlobject.h" +#include <new> +#define PILENODE_AUTOINCREMENT 50 + +/* + +CreateXMLParameters(int master_handle) +addParam(master_handle, this_handle, name, id) + +master_handle is key into array of name/this-handle/id + + +*/ +class DeleteOnClose +{ +public: + ~DeleteOnClose() + { + allocd.freeAll(); + } + PtrList<XmlObjectParam> allocd; +}; +DeleteOnClose deleter; +template <class t_> +struct PileNode +{ + PileNode(int num) + { + sizePile = num; + pile = (t_ *)MALLOC(sizeof(t_) * num); + deleter.allocd.addItem(pile); + } + void Rebuild(int num) + { + sizePile = num; + pile = (t_ *)MALLOC(sizeof(t_) * num); + deleter.allocd.addItem(pile); + } + size_t sizePile; + t_ *pile; + void *Get() + { + sizePile--; + return pile++; + } +}; +template <class t_> +struct PileList +{ + PileList(int numPtrs, PileList<t_> *_next = 0) : node(numPtrs), next(_next) + { + } + PileNode<t_> node; + PileList *next; + void *Get() + { + if (node.sizePile) + { + return node.Get(); + } + else + { + while (next && !next->node.sizePile) + { + PileList<t_> *temp = next; + next = temp->next; + delete temp; + } + if (next) + return next->Get(); + else + { + node.Rebuild(PILENODE_AUTOINCREMENT); + return node.Get(); + } + } + } +}; + +PileList<XmlObjectParam> *paramPile = 0; + +XmlObjectParam::XmlObjectParam(int xmlhandle, wchar_t *xmlattribute, int xmlattributeid) + : xmlattributename(xmlattribute), attributeid(xmlattributeid), handle(xmlhandle) +{ +KEYWORDUPPER(xmlattribute); +} + +#define CBCLASS XmlObjectI +START_DISPATCH; +CB(SETXMLPARAM, setXmlParam); +CB(GETXMLPARAMVALUE, getXmlParamValue); +CB(GETXMLPARAM, getXmlParam); +END_DISPATCH; + +XmlObjectI::XmlObjectI() +{ + handlepos = 0; +} + +XmlObjectI::~XmlObjectI() +{ + params.removeAll(); +} + +void XmlObjectI::addParam(int xmlhandle, XMLParamPair ¶m, int unused) +//void XmlObjectI::addXmlParam(int xmlhandle, const wchar_t *xmlattribute, int xmlattributeid) +{ + if (!paramPile) + paramPile = new PileList<XmlObjectParam>(PILENODE_AUTOINCREMENT); + + params.addItem(new(paramPile->Get()) XmlObjectParam(xmlhandle, param.name, param.id)); +} + +int XmlObjectI::setXmlParamById(int xmlhandle, int xmlattribute, const wchar_t *param, const wchar_t *value) +{ + return 0; +} + +int XmlObjectI::setXmlParam(const wchar_t *param, const wchar_t *value) +{ + int pos = -1; + int r = 0; + params.findItem(param, &pos); + if (pos >= 0) + { + XmlObjectParam *xuop = params.enumItem(pos); + ASSERT(xuop != NULL); + r = setXmlParamById(xuop->getXmlHandle(), xuop->getXmlAttributeId(), param, value); + xuop->setLastValue(value); + } + else + { + onUnknownXmlParam(param, value); + } + return r; +} + +const wchar_t *XmlObjectI::getXmlParamValue(int n) +{ + return params.enumItem(n)->getLastValue(); +} + +int XmlObjectI::getXmlParam(const wchar_t *param) +{ + int pos=-1; + params.findItem(param, &pos); + return pos; +} + +const wchar_t *XmlObjectI::getXmlParamByName(const wchar_t *paramname) +{ + int pos = getXmlParam(paramname); + if (pos < 0) return NULL; + return getXmlParamValue(pos); +} + +int XmlObjectI::newXmlHandle() +{ + return handlepos++; +} + +int XmlObjectI::onUnknownXmlParam(const wchar_t *paramname, const wchar_t *strvalue) +{ + return 0; +} + +void XmlObjectI::hintNumberOfParams(int xmlhandle, int numParams) +{ + paramPile = new PileList<XmlObjectParam>(numParams, paramPile); + + params.setMinimumSize(params.getNumItems() + numParams); +}
\ No newline at end of file diff --git a/Src/Wasabi/api/skin/xmlobject.h b/Src/Wasabi/api/skin/xmlobject.h new file mode 100644 index 00000000..1a45797f --- /dev/null +++ b/Src/Wasabi/api/skin/xmlobject.h @@ -0,0 +1,132 @@ +#ifndef __XMLOBJECT_H +#define __XMLOBJECT_H + +#include <bfc/nsguid.h> +#include <bfc/ptrlist.h> +#include <bfc/dispatch.h> +#include <bfc/string/StringW.h> +#include <bfc/wasabi_std.h> + +#define XML_ATTRIBUTE_IMPLIED 0 +#define XML_ATTRIBUTE_REQUIRED 1 + +class XmlObject : public Dispatchable +{ +public: + int setXmlParam(const wchar_t *name, const wchar_t *strvalue); + const wchar_t *getXmlParamValue(int n); + int getXmlParam(const wchar_t *paramname); + + enum + { + SETXMLPARAM=10, + GETXMLPARAMVALUE=40, + GETXMLPARAM=50, + }; +}; + +inline int XmlObject::setXmlParam(const wchar_t *name, const wchar_t *strvalue) +{ + return _call(SETXMLPARAM, 0, name, strvalue); +} + +inline const wchar_t *XmlObject::getXmlParamValue(int n) +{ + return _call(GETXMLPARAMVALUE, (const wchar_t *)0, n); +} + +inline int XmlObject::getXmlParam(const wchar_t *paramname) +{ + return _call(GETXMLPARAM, 0, paramname); +} + +class XmlObjectParam +{ + +public: + + XmlObjectParam(int xmlhandle, wchar_t *xmlattribute, int xmlattributeid); + virtual ~XmlObjectParam() {} + + const wchar_t *getXmlAttribute() + { + return xmlattributename; + } + int getXmlAttributeId() + { + return attributeid; + } + int getXmlHandle() + { + return handle; + } + void setLastValue(const wchar_t *val) + { + lastvalue = val; + } + const wchar_t *getLastValue() + { + return lastvalue; + } + +private: + const wchar_t *xmlattributename; + StringW lastvalue; + int attributeid; + int handle; + +}; + +class XmlObjectParamSort +{ +public: + static inline int compareItem(XmlObjectParam *p1, XmlObjectParam*p2) + { + return wcscmp(p1->getXmlAttribute(), p2->getXmlAttribute()); + } + static inline int compareAttrib(const wchar_t *attrib, XmlObjectParam *item) + { + return WCSICMP(attrib, item->getXmlAttribute()); + } +}; + +struct XMLParamPair +{ + int id; + wchar_t name[64]; +}; + +class XmlObjectI : public XmlObject +{ +public: + XmlObjectI(); + virtual ~XmlObjectI(); + + virtual int setXmlParam(const wchar_t *name, const wchar_t *strvalue); // receives from system + virtual int setXmlParamById(int xmlhandle, int xmlattributeid, const wchar_t *name, const wchar_t *strvalue); // distributes to inheritors + virtual const wchar_t *getXmlParamValue(int n); + virtual int getXmlParam(const wchar_t *paramname); + const wchar_t *getXmlParamByName(const wchar_t *paramname); + void addParam(int xmlhandle, XMLParamPair ¶m, int unused=0); + //void addXmlParam(int xmlhandle, const wchar_t *xmlattribute, int xmlattributeid); +protected: + virtual int onUnknownXmlParam(const wchar_t *param, const wchar_t *value); + int newXmlHandle(); + void hintNumberOfParams(int xmlhandle, int params); + +private: + XmlObjectParam *enumParam(int n) + { + return params[n]; + } + + PtrListInsertSorted<XmlObjectParam, XmlObjectParamSort> params; + int handlepos; + +protected: + + RECVS_DISPATCH; +}; + + +#endif |