guitree.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. #include <precomp.h>
  2. #include "guitree.h"
  3. #include <api/skin/skinparse.h>
  4. #include <api/syscb/callbacks/wndcb.h>
  5. #ifdef WASABI_COMPILE_WNDMGR
  6. #include <api/wndmgr/autopopup.h>
  7. #endif
  8. #include <api/skin/skin.h>
  9. #include <bfc/bfc_assert.h>
  10. GuiTree *guiTree=NULL;
  11. 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)
  12. {
  13. if (p)
  14. {
  15. for (size_t i=0;i!=p->getNbItems();i++)
  16. params.addItem(p->getItemName(i), p->getItemValue(i));
  17. }
  18. object_type = type;
  19. object_name = name;
  20. scriptId = scriptid;
  21. rootpath = path;
  22. guid = g;
  23. idx=-1;
  24. seccount = incrementor++;
  25. wndtype = windowtype;
  26. tag = xuitag;
  27. }
  28. int GuiTreeItem::incrementor=0;
  29. GuiTreeItem::~GuiTreeItem() {
  30. }
  31. int GuiTreeItem::getScriptId() {
  32. return scriptId;
  33. }
  34. ifc_xmlreaderparams *GuiTreeItem::getParams()
  35. {
  36. // TODO: benski> helps replicate old logic.. we really fix the parts of the code that are assuming getValue() always succeeds with this returned object
  37. if (params.getNbItems())
  38. return &params;
  39. else
  40. return 0;
  41. }
  42. const wchar_t *GuiTreeItem::getXmlRootPath() {
  43. return rootpath;
  44. }
  45. int GuiTreeItem::getType() {
  46. return object_type;
  47. }
  48. const wchar_t *GuiTreeItem::getName()
  49. {
  50. return object_name;
  51. }
  52. SkinItem *GuiTreeItem::getAncestor() {
  53. if (object_type == XML_TAG_GROUPDEF)
  54. return guiTree->getGroupDefAncestor(this);
  55. if (object_type == XML_TAG_CONTAINER)
  56. return guiTree->getContainerAncestor(this);
  57. return NULL;
  58. }
  59. GuiTree::GuiTree() {
  60. cached=-1;
  61. cachedtype=-1;
  62. cached_guid_idx=-1;
  63. cached_guid=INVALID_GUID;
  64. lastdefinedgroupdef = NULL;
  65. }
  66. GuiTree::~GuiTree() {
  67. list.deleteAll();
  68. groupdefs.removeAll();
  69. wndtypes.removeAll();
  70. //groupdefsbyguid.removeAll();
  71. }
  72. void GuiTree::addItem(int object_type, const wchar_t *name, ifc_xmlreaderparams *params, int scriptid, const wchar_t *rootpath) {
  73. cached = -1;
  74. cached_guid_idx = -1;
  75. GUID guid=INVALID_GUID;
  76. const wchar_t *wtype=NULL;
  77. int has_ancestor=0;
  78. const wchar_t *xuitag=NULL;
  79. const wchar_t *_id = NULL;
  80. if (params)
  81. {
  82. _id = params->getItemValue(L"id");
  83. xuitag = params->getItemValue(L"xuitag");
  84. #ifdef WASABI_COMPILE_WNDMGR
  85. if (params->getItemValueInt(L"register_autopopup"))
  86. AutoPopup::registerGroupId(scriptid, _id, params->getItemValue(L"name"));
  87. #endif
  88. const wchar_t *strguid = params->getItemValue(L"guid");
  89. if (strguid)
  90. guid = nsGUID::fromCharW(strguid);
  91. wtype = params->getItemValue(L"windowtype");
  92. }
  93. if (object_type == XML_TAG_GROUPDEF && params)
  94. {
  95. has_ancestor = (getGroupDef(_id) != NULL);
  96. }
  97. GuiTreeItem *item = new GuiTreeItem(object_type, name, params, scriptid, rootpath, guid, wtype, xuitag);
  98. item->setIdx(list.getNumItems());
  99. list.addItem(item);
  100. if (object_type == XML_TAG_GROUPDEF && params) {
  101. lastdefinedgroupdef = item;
  102. // groupdefsbyguid.setAutoSort(0);
  103. groupdefs.addItem(item);
  104. // groupdefsbyguid.addItem(item);
  105. if (wtype && *wtype) {
  106. wndtypes.addItem(item);
  107. deferredInvalidateType(wtype);
  108. }
  109. if (xuitag && *xuitag) {
  110. xuigroupdefs.addItem(item);
  111. }
  112. if (has_ancestor)
  113. deferredInvalidateGroup(_id);
  114. } else if (object_type == XML_TAG_CONTAINER && params && (params->getItemValueInt(L"dynamic", 0) == 1)) {
  115. containers_by_id.setAutoSort(0);
  116. containers_by_id.addItem(item);
  117. }
  118. }
  119. int GuiTree::getNumObject() {
  120. return list.getNumItems();
  121. }
  122. int GuiTree::getNumObject(int object_type) {
  123. if (cachedtype == object_type && cached != -1) return cached;
  124. int n=0;
  125. for (int i=0;i<list.getNumItems();i++) {
  126. GuiTreeItem *it = list.enumItem(i);
  127. if (it->getType() == object_type)
  128. n++;
  129. }
  130. cachedtype = object_type;
  131. cached = n;
  132. return n;
  133. }
  134. SkinItem *GuiTree::getObject(int object_type, int nth) {
  135. int n=0;
  136. for (int i=0;i<list.getNumItems();i++) {
  137. GuiTreeItem *it = list.enumItem(i);
  138. if (it && it->getType() == object_type) {
  139. if (n++ == nth) return it;
  140. }
  141. }
  142. return NULL;
  143. }
  144. SkinItem *GuiTree::getGroupDef(const wchar_t *id)
  145. {
  146. return groupdefs.findLastItem(id);
  147. }
  148. SkinItem *GuiTree::getXuiGroupDef(const wchar_t *xuitag)
  149. {
  150. xuigroupdefs.sort(); // doesn't sort if not necessary
  151. return xuigroupdefs.findLastItem(xuitag);
  152. }
  153. SkinItem *GuiTree::getGroupDefAncestor(SkinItem *_item)
  154. {
  155. //groupdefs.sort(); // doesn't sort if not necessary
  156. int pos = -1;
  157. GuiTreeItem *item = static_cast<GuiTreeItem *>(_item);
  158. if (!item) return NULL;
  159. ASSERT(item->getParams() != NULL);
  160. const wchar_t *iid = item->getParams()->getItemValue(L"id");
  161. pos = groupdefs.searchItem(item);
  162. if (pos <= 0) return NULL;
  163. pos--;
  164. GuiTreeItem *ritem = groupdefs.enumItem(pos);
  165. if (!ritem) return NULL;
  166. ASSERT(ritem->getParams() != NULL);
  167. if (WCSICMP(iid, ritem->getParams()->getItemValue(L"id"))) return NULL;
  168. return ritem;
  169. }
  170. SkinItem *GuiTree::getContainerAncestor(SkinItem *_item) {
  171. int pos = -1;
  172. GuiTreeItem *item = static_cast<GuiTreeItem *>(_item);
  173. if (!item) return NULL;
  174. ASSERT(item->getParams() != NULL);
  175. const wchar_t *iid = item->getParams()->getItemValue(L"id");
  176. pos = containers_by_id.searchItem(item);
  177. if (pos <= 0) return NULL;
  178. pos--;
  179. GuiTreeItem *ritem = containers_by_id.enumItem(pos);
  180. if (!ritem) return NULL;
  181. ASSERT(ritem->getParams() != NULL);
  182. if (WCSICMP(iid, ritem->getParams()->getItemValue(L"id"))) return NULL;
  183. return ritem;
  184. }
  185. /*int GuiTree::getGroupDef(GUID guid) {
  186. groupdefsbyguid.sort(); // doesn't sort if not necessary
  187. GuiTreeItem *item = groupdefsbyguid.findItem(reinterpret_cast<const char *>(&guid));
  188. if (item)
  189. return item->getIdx();
  190. return -1;
  191. }*/
  192. SkinItem *GuiTree::enumGroupDefOfType(const wchar_t *type, int n) {
  193. int c = 0;
  194. foreach(wndtypes)
  195. GuiTreeItem *item = wndtypes.getfor();
  196. if (WCSCASEEQLSAFE(type, item->getWindowType())) {
  197. if (c == n) {
  198. /* if (item->getGuid() != INVALID_GUID) { // see if it has a GUID, in which case we need to instantiate the last overriden version
  199. int n = getGroupDef(item->getGuid());
  200. if (n != -1) return n;
  201. }*/
  202. // take its groupid and find its latest overriden version
  203. ifc_xmlreaderparams *p = item->getParams();
  204. if (p)
  205. {
  206. const wchar_t *id = p->getItemValue(L"id");
  207. if (id)
  208. {
  209. SkinItem *m = getGroupDef(id);
  210. if (m != NULL) return m;
  211. }
  212. }
  213. return item;
  214. }
  215. c++;
  216. }
  217. endfor;
  218. return NULL;
  219. }
  220. int GuiTree::getObjectType(SkinItem *item) {
  221. GuiTreeItem *i = static_cast<GuiTreeItem *>(item);
  222. return i->getType();
  223. }
  224. PtrList<GuiTreeItem> *GuiTree::getList() {
  225. return &list;
  226. }
  227. PtrList<GuiTreeItem> *GuiTree::getGroupList() {
  228. return &groupdefs;
  229. }
  230. SkinItem *GuiTree::getContainerById(const wchar_t *id)
  231. {
  232. containers_by_id.sort(); // doesn't sort if not necessary
  233. return containers_by_id.findLastItem(id);
  234. }
  235. void GuiTree::removeSkinPart(int scriptid) {
  236. for (int i=0;i<list.getNumItems();i++) {
  237. GuiTreeItem *item = list.enumItem(i);
  238. if (item->getScriptId() == scriptid) {
  239. ifc_xmlreaderparams *par = item->getParams();
  240. if (item->getType() == XML_TAG_CONTAINER && par != NULL) {
  241. int p = containers_by_id.searchItem(item);
  242. if (p != -1)
  243. containers_by_id.removeByPos(p);
  244. }
  245. if (item->getType() == XML_TAG_GROUPDEF && par != NULL)
  246. {
  247. const wchar_t *grpid = par->getItemValue(L"id");
  248. if (grpid)
  249. {
  250. int p = groupdefs.searchItem(item);
  251. if (p != -1)
  252. groupdefs.removeByPos(p);
  253. p = xuigroupdefs.searchItem(item);
  254. if (p != -1)
  255. xuigroupdefs.removeByPos(p);
  256. p = wndtypes.searchItem(item);
  257. if (p != -1) {
  258. deferredInvalidateType(item->getWindowType());
  259. wndtypes.removeByPos(p);
  260. }
  261. deferredInvalidateGroup(grpid);
  262. }
  263. }
  264. delete item;
  265. list.removeByPos(i);
  266. i--;
  267. }
  268. }
  269. foreach(list)
  270. list.getfor()->setIdx(foreach_index);
  271. endfor;
  272. }
  273. void GuiTree::reset() {
  274. list.deleteAll();
  275. groupdefs.removeAll();
  276. wndtypes.removeAll();
  277. xuigroupdefs.removeAll();
  278. containers_by_id.removeAll();
  279. }
  280. void GuiTree::deferredInvalidateGroup(const wchar_t *id) {
  281. if (!Skin::isDynamicGroupReloadEnabled()) return;
  282. if (!id || !*id) return;
  283. StringW *s = new StringW;
  284. s->setValue(id);
  285. GuiTreeCB *cb = new GuiTreeCB;
  286. cb->cmd = INVALIDATEGRP;
  287. cb->ptr = s;
  288. timerclient_postDeferredCallback(CB_GUITREE, reinterpret_cast<intptr_t>(cb));
  289. }
  290. void GuiTree::deferredInvalidateType(const wchar_t *type) {
  291. if (!Skin::isDynamicGroupReloadEnabled()) return;
  292. StringW *s = new StringW;
  293. s->setValue(type);
  294. GuiTreeCB *cb = new GuiTreeCB;
  295. cb->cmd = INVALIDATETYPE;
  296. cb->ptr = s;
  297. timerclient_postDeferredCallback(CB_GUITREE, reinterpret_cast<intptr_t>(cb));
  298. }
  299. int GuiTree::timerclient_onDeferredCallback(intptr_t param1, intptr_t param2)
  300. {
  301. if (param1 == CB_GUITREE) {
  302. GuiTreeCB *c = reinterpret_cast<GuiTreeCB *>(param2);
  303. switch (c->cmd) {
  304. case INVALIDATEGRP: {
  305. StringW *s = reinterpret_cast<StringW *>(c->ptr);
  306. WndInfo wi;
  307. wi.groupid = s->getValue();
  308. wi.wndtype = NULL;
  309. wi.guid = INVALID_GUID;
  310. WASABI_API_SYSCB->syscb_issueCallback(SysCallback::WINDOW, WndCallback::GROUPCHANGE, reinterpret_cast<intptr_t>(&wi));
  311. delete s;
  312. break;
  313. }
  314. case INVALIDATETYPE: {
  315. StringW *s = reinterpret_cast<StringW *>(c->ptr);
  316. WndInfo wi;
  317. ZERO(wi);
  318. wi.wndtype = s->getValue();
  319. wi.guid = INVALID_GUID;
  320. WASABI_API_SYSCB->syscb_issueCallback(SysCallback::WINDOW, WndCallback::TYPECHANGE, reinterpret_cast<intptr_t>(&wi));
  321. delete s;
  322. break;
  323. }
  324. }
  325. return 1;
  326. }
  327. return GUITREE_PARENT::timerclient_onDeferredCallback(param1, param2);
  328. }
  329. int GuiTree::getObjectIdx(SkinItem *item) {
  330. if (item == NULL) return -1;
  331. return (static_cast<GuiTreeItem*>(item))->getIdx();
  332. }