1
0

wndholder.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. #include <precomp.h>
  2. #include "wndholder.h"
  3. #include <api/service/svcs/svc_wndcreate.h>
  4. #include <api/service/svc_enum.h>
  5. #include <api/syscb/callbacks/wndcb.h>
  6. //#pragma CHAT("lone", "benski", "needs to dispatch Layout & Containers!")
  7. #include <api/wndmgr/container.h>
  8. #include <api/wndmgr/layout.h>
  9. #define CBCLASS WindowHolderI
  10. START_DISPATCH;
  11. CB(WNDHOLDER_ONINSERTWINDOW, onInsertWindow);
  12. VCB(WNDHOLDER_ONREMOVEWINDOW, onRemoveWindow);
  13. CB(WNDHOLDER_WANTGUID, wantGuid);
  14. CB(WNDHOLDER_WANTGROUP, wantGroup);
  15. CB(WNDHOLDER_GETROOTWNDPTR, getRootWndPtr);
  16. CB(WNDHOLDER_GETCURGROUPID, getCurGroupId);
  17. CB(WNDHOLDER_GETCURGUID, getCurGuid);
  18. CB(WNDHOLDER_GETCURROOTWND, getCurRootWnd);
  19. CB(WNDHOLDER_GETCURID, getCurId);
  20. CB(WNDHOLDER_ISGENERICGUID, acceptsGenericGuid);
  21. CB(WNDHOLDER_ISGENERICGROUP, acceptsGenericGroup);
  22. VCB(WNDHOLDER_CANCELDEFERREDREMOVE, cancelDeferredRemove);
  23. VCB(WNDHOLDER_ONNEEDRELOADGRP, wndholder_onNeedReloadGroup);
  24. CB(WNDHOLDER_WANTAUTOFOCUS, wndholder_wantAutoFocus);
  25. CB(WNDHOLDER_ISAUTOAVAILABLE, wndholder_isAutoAvailable);
  26. END_DISPATCH;
  27. WindowHolderI::WindowHolderI() {
  28. wnd = NULL;
  29. dr = NULL;
  30. generic_guid = 1;
  31. generic_group = 1;
  32. cur_guid = INVALID_GUID;
  33. cur_groupid = NULL;
  34. wc_svc = NULL;
  35. WASABI_API_WNDMGR->wndholder_register(this);
  36. }
  37. WindowHolderI::~WindowHolderI() {
  38. delete dr;
  39. if (wnd != NULL) {
  40. if (wc_svc) {
  41. ifc_window *w = wnd;
  42. wnd = NULL;
  43. wc_svc->destroyWindow(w);
  44. SvcEnum::release(wc_svc);
  45. wc_svc = NULL;
  46. } else {
  47. ifc_window *w = wnd;
  48. wnd = NULL;
  49. WASABI_API_SKIN->group_destroy(w);
  50. }
  51. }
  52. accepted_groups.deleteAll();
  53. accepted_guids.deleteAll();
  54. WASABI_API_WNDMGR->wndholder_unregister(this);
  55. }
  56. ifc_window *WindowHolderI::onInsertWindow(GUID g, const wchar_t *groupid)
  57. {
  58. cancelDeferredRemove();
  59. defered_guid = INVALID_GUID;
  60. if (wnd != NULL) return NULL;
  61. cur_groupid = groupid;
  62. if (g != INVALID_GUID)
  63. {
  64. cur_guid = g;
  65. wchar_t cguid[256] = {0};
  66. nsGUID::toCharW(g, cguid);
  67. cur_id = cguid;
  68. } else
  69. cur_id = groupid;
  70. wnd = createWindow(g == INVALID_GUID ? NULL : &g, groupid);
  71. if (!wnd) {
  72. cur_guid = INVALID_GUID;
  73. cur_id = L"";
  74. cur_groupid = L"";
  75. }
  76. if (wnd) {
  77. onInsert(wnd, cur_id);
  78. } else {
  79. if (g != INVALID_GUID) {
  80. defered_guid = g;
  81. }
  82. }
  83. return wnd;
  84. }
  85. void WindowHolderI::onRemoveWindow(int deferred) {
  86. if (deferred) {
  87. if (!dr)
  88. dr = new DeferredRemove(this);
  89. dr->post();
  90. return;
  91. }
  92. if (wnd != NULL) {
  93. ifc_window *w = getCurRootWnd();
  94. onRemove(w, cur_id);
  95. destroyWindow();
  96. cur_guid = INVALID_GUID;
  97. cur_groupid = NULL;
  98. defered_guid = INVALID_GUID;
  99. }
  100. }
  101. void WindowHolderI::cancelDeferredRemove() {
  102. delete dr;
  103. dr = NULL;
  104. }
  105. void WindowHolderI::wndholder_onNeedReloadGroup(const wchar_t *id)
  106. {
  107. if (cur_groupid.isempty()) return;
  108. ifc_window *w = getCurRootWnd();
  109. if (w == NULL) return;
  110. if (w->isInited() && !WCSICMP(cur_groupid, id))
  111. {
  112. onRemove(w, cur_id);
  113. destroyWindow();
  114. createWindow(&INVALID_GUID, id);
  115. onInsert(wnd, cur_id);
  116. }
  117. }
  118. ifc_window *WindowHolderI::createWindow(const GUID *g, const wchar_t *groupid)
  119. {
  120. ASSERT(wnd == NULL);
  121. if (g != NULL && *g != INVALID_GUID) {
  122. wc_svc = WindowCreateByGuidEnum(*g).getFirst();
  123. if (wc_svc)
  124. wnd = wc_svc->createWindowByGuid(*g, getRootWndPtr());
  125. }
  126. else if (groupid != NULL)
  127. {
  128. wc_svc = NULL;
  129. wnd = WASABI_API_SKIN->group_create(groupid);
  130. }
  131. if (wnd) {
  132. if (!wnd->isInited()) {
  133. if (!wnd->getParent()) wnd->setParent(getRootWndPtr());
  134. wnd->init(getRootWndPtr());
  135. }
  136. }
  137. return wnd;
  138. }
  139. void WindowHolderI::destroyWindow() {
  140. ASSERT(wnd != NULL);
  141. ifc_window *w = wnd->getDesktopParent();
  142. if (wc_svc) {
  143. ifc_window *w = wnd;
  144. wnd = NULL;
  145. wc_svc->destroyWindow(w);
  146. SvcEnum::release(wc_svc);
  147. wc_svc = NULL;
  148. } else {
  149. ifc_window *w = wnd;
  150. wnd = NULL;
  151. WASABI_API_SKIN->group_destroy(w);
  152. }
  153. if (w != NULL) {
  154. if (w->getInterface(layoutGuid)) {
  155. static_cast<Layout *>(w)->updateTransparency();
  156. }
  157. }
  158. }
  159. void WindowHolderI::addAcceptGuid(GUID g) {
  160. accepted_guids.addItem(new GUID(g));
  161. }
  162. void WindowHolderI::addAcceptGroup(const wchar_t *groupid)
  163. {
  164. accepted_groups.addItem(new StringW(groupid));
  165. }
  166. void WindowHolderI::setAcceptAllGuids(int tf) {
  167. generic_guid = tf;
  168. }
  169. void WindowHolderI::setAcceptAllGroups(int tf) {
  170. generic_group = tf;
  171. }
  172. int WindowHolderI::wantGuid(GUID g) {
  173. if (acceptsGenericGuid()) return 1;
  174. for (int i=0;i<accepted_guids.getNumItems();i++) {
  175. if (*accepted_guids.enumItem(i) == g) return 1;
  176. }
  177. return 0;
  178. }
  179. int WindowHolderI::wantGroup(const wchar_t *groupid)
  180. {
  181. if (acceptsGenericGroup()) return 1;
  182. for (int i=0;i<accepted_groups.getNumItems();i++) {
  183. if (!WCSICMP(accepted_groups.enumItem(i)->getValue(), groupid))
  184. return 1;
  185. }
  186. return 0;
  187. }
  188. GUID *WindowHolderI::getFirstAcceptedGuid() {
  189. if (accepted_guids.getNumItems() == 0) return NULL;
  190. return accepted_guids.enumItem(0);
  191. }
  192. const wchar_t *WindowHolderI::getFirstAcceptedGroup()
  193. {
  194. if (accepted_guids.getNumItems() == 0)
  195. return NULL;
  196. return
  197. accepted_groups.enumItem(0)->getValue();
  198. }
  199. int WindowHolderI::wndholder_wantAutoFocus() {
  200. return 1;
  201. }
  202. WindowHolderWnd::WindowHolderWnd() {
  203. autoavail = 1;
  204. autoopen = 1;
  205. autoclose = 0;
  206. nocmdbar = 0;
  207. noanim = 0;
  208. has_wnd = 0;
  209. autofocus = 1;
  210. WASABI_API_SYSCB->syscb_registerCallback(this);
  211. }
  212. WindowHolderWnd::~WindowHolderWnd() {
  213. if (has_wnd) {
  214. notifyOnRemove();
  215. }
  216. WASABI_API_SYSCB->syscb_deregisterCallback(this);
  217. }
  218. int WindowHolderWnd::onResize() {
  219. WINDOWHOLDER_PARENT::onResize();
  220. if (getCurRootWnd()) {
  221. RECT r;
  222. getClientRect(&r);
  223. if (!getCurRootWnd()->handleRatio())
  224. multRatio(&r);
  225. getCurRootWnd()->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
  226. }
  227. return 1;
  228. }
  229. int WindowHolderWnd::handleRatio() {
  230. return 1;
  231. }
  232. int WindowHolderWnd::handleDesktopAlpha() {
  233. if (getCurRootWnd()) return getCurRootWnd()->handleDesktopAlpha();
  234. return 1;
  235. }
  236. int WindowHolderWnd::handleTransparency() {
  237. if (getCurRootWnd()) return getCurRootWnd()->handleTransparency();
  238. return 1;
  239. }
  240. int WindowHolderWnd::onInit() {
  241. WINDOWHOLDER_PARENT::onInit();
  242. if (isVisible() && autoopen && getFirstAcceptedGuid()) {
  243. onInsertWindow(*getFirstAcceptedGuid(), NULL);
  244. } else if (isVisible() && autoopen && getFirstAcceptedGroup()) {
  245. onInsertWindow(INVALID_GUID, getFirstAcceptedGroup());
  246. }
  247. return 1;
  248. }
  249. #define DC_NOTIFYONREMOVE 0x205
  250. void WindowHolderWnd::onRemove(ifc_window *w, const wchar_t *id)
  251. {
  252. ifc_window *dw = getDesktopParent();
  253. if (dw) dw->removeMinMaxEnforcer(this);
  254. postDeferredCallback(DC_NOTIFYONREMOVE);
  255. }
  256. int WindowHolderWnd::onDeferredCallback(intptr_t p1, intptr_t p2) {
  257. if (p1 == DC_NOTIFYONREMOVE) {
  258. notifyOnRemove();
  259. } else return WINDOWHOLDER_PARENT::onDeferredCallback(p1, p2);
  260. return 1;
  261. }
  262. void WindowHolderWnd::onInsert(ifc_window *w, const wchar_t *id)
  263. {
  264. if (isPostOnInit())
  265. onResize();
  266. ifc_window *dw = getDesktopParent();
  267. if (dw) dw->addMinMaxEnforcer(this);
  268. notifyOnInsert();
  269. if (wndholder_wantAutoFocus()) w->setFocus();
  270. }
  271. int WindowHolderWnd::getPreferences(int what) {
  272. if (getCurRootWnd()) return getCurRootWnd()->getPreferences(what);
  273. return WINDOWHOLDER_PARENT::getPreferences(what);
  274. }
  275. void WindowHolderWnd::notifyOnRemove() {
  276. has_wnd = 0;
  277. Layout *l = getGuiObject()->guiobject_getParentLayout();
  278. if (l != NULL) {
  279. Container *c = l->getParentContainer();
  280. if (c != NULL) {
  281. c->notifyRemoveContent(this);
  282. }
  283. }
  284. }
  285. void WindowHolderWnd::notifyOnInsert() {
  286. has_wnd = 1;
  287. Layout *l = getGuiObject()->guiobject_getParentLayout();
  288. if (l != NULL) {
  289. Container *c = l->getParentContainer();
  290. if (c != NULL)
  291. {
  292. c->notifyAddContent(this, getCurGroupId(), getCurGuid());
  293. }
  294. }
  295. }
  296. int WindowHolderWnd::onGroupChange(const wchar_t *grpid)
  297. {
  298. WINDOWHOLDER_PARENT::onGroupChange(grpid);
  299. wndholder_onNeedReloadGroup(grpid);
  300. return 1;
  301. }
  302. void WindowHolderWnd::onSetVisible(int show) {
  303. if (show && getCurRootWnd() == NULL) {
  304. if (autoopen && getFirstAcceptedGuid()) {
  305. onInsertWindow(*getFirstAcceptedGuid(), NULL);
  306. } else if (autoopen && getFirstAcceptedGroup()) {
  307. onInsertWindow(INVALID_GUID, getFirstAcceptedGroup());
  308. }
  309. } else if (!show && getCurRootWnd() != NULL) {
  310. if (autoclose && WASABI_API_SKIN->skin_getVersion() >= 1.0)
  311. onRemoveWindow(0);
  312. }
  313. if (getDeferedGuid() != INVALID_GUID) {
  314. if (show) {
  315. #ifdef ON_CREATE_EXTERNAL_WINDOW_GUID
  316. int y;
  317. ON_CREATE_EXTERNAL_WINDOW_GUID(getDeferedGuid(), y);
  318. #endif
  319. }
  320. }
  321. WINDOWHOLDER_PARENT::onSetVisible(show);
  322. }
  323. int WindowHolderWnd::wndholder_wantAutoFocus() {
  324. return autofocus;
  325. }