aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/api/wnd/wndclass/wndholder.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Wasabi/api/wnd/wndclass/wndholder.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Wasabi/api/wnd/wndclass/wndholder.cpp')
-rw-r--r--Src/Wasabi/api/wnd/wndclass/wndholder.cpp369
1 files changed, 369 insertions, 0 deletions
diff --git a/Src/Wasabi/api/wnd/wndclass/wndholder.cpp b/Src/Wasabi/api/wnd/wndclass/wndholder.cpp
new file mode 100644
index 00000000..272298a3
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/wndholder.cpp
@@ -0,0 +1,369 @@
+#include <precomp.h>
+#include "wndholder.h"
+#include <api/service/svcs/svc_wndcreate.h>
+#include <api/service/svc_enum.h>
+#include <api/syscb/callbacks/wndcb.h>
+
+//#pragma CHAT("lone", "benski", "needs to dispatch Layout & Containers!")
+#include <api/wndmgr/container.h>
+#include <api/wndmgr/layout.h>
+
+#define CBCLASS WindowHolderI
+START_DISPATCH;
+ CB(WNDHOLDER_ONINSERTWINDOW, onInsertWindow);
+ VCB(WNDHOLDER_ONREMOVEWINDOW, onRemoveWindow);
+ CB(WNDHOLDER_WANTGUID, wantGuid);
+ CB(WNDHOLDER_WANTGROUP, wantGroup);
+ CB(WNDHOLDER_GETROOTWNDPTR, getRootWndPtr);
+ CB(WNDHOLDER_GETCURGROUPID, getCurGroupId);
+ CB(WNDHOLDER_GETCURGUID, getCurGuid);
+ CB(WNDHOLDER_GETCURROOTWND, getCurRootWnd);
+ CB(WNDHOLDER_GETCURID, getCurId);
+ CB(WNDHOLDER_ISGENERICGUID, acceptsGenericGuid);
+ CB(WNDHOLDER_ISGENERICGROUP, acceptsGenericGroup);
+ VCB(WNDHOLDER_CANCELDEFERREDREMOVE, cancelDeferredRemove);
+ VCB(WNDHOLDER_ONNEEDRELOADGRP, wndholder_onNeedReloadGroup);
+ CB(WNDHOLDER_WANTAUTOFOCUS, wndholder_wantAutoFocus);
+ CB(WNDHOLDER_ISAUTOAVAILABLE, wndholder_isAutoAvailable);
+END_DISPATCH;
+
+WindowHolderI::WindowHolderI() {
+ wnd = NULL;
+ dr = NULL;
+ generic_guid = 1;
+ generic_group = 1;
+ cur_guid = INVALID_GUID;
+ cur_groupid = NULL;
+ wc_svc = NULL;
+ WASABI_API_WNDMGR->wndholder_register(this);
+}
+
+WindowHolderI::~WindowHolderI() {
+ delete dr;
+ if (wnd != NULL) {
+ if (wc_svc) {
+ ifc_window *w = wnd;
+ wnd = NULL;
+ wc_svc->destroyWindow(w);
+ SvcEnum::release(wc_svc);
+ wc_svc = NULL;
+ } else {
+ ifc_window *w = wnd;
+ wnd = NULL;
+ WASABI_API_SKIN->group_destroy(w);
+ }
+ }
+ accepted_groups.deleteAll();
+ accepted_guids.deleteAll();
+ WASABI_API_WNDMGR->wndholder_unregister(this);
+}
+
+ifc_window *WindowHolderI::onInsertWindow(GUID g, const wchar_t *groupid)
+{
+ cancelDeferredRemove();
+
+ defered_guid = INVALID_GUID;
+ if (wnd != NULL) return NULL;
+
+ cur_groupid = groupid;
+ if (g != INVALID_GUID)
+ {
+ cur_guid = g;
+ wchar_t cguid[256] = {0};
+ nsGUID::toCharW(g, cguid);
+ cur_id = cguid;
+ } else
+ cur_id = groupid;
+
+ wnd = createWindow(g == INVALID_GUID ? NULL : &g, groupid);
+ if (!wnd) {
+ cur_guid = INVALID_GUID;
+ cur_id = L"";
+ cur_groupid = L"";
+ }
+ if (wnd) {
+ onInsert(wnd, cur_id);
+ } else {
+ if (g != INVALID_GUID) {
+ defered_guid = g;
+ }
+ }
+ return wnd;
+}
+
+void WindowHolderI::onRemoveWindow(int deferred) {
+ if (deferred) {
+ if (!dr)
+ dr = new DeferredRemove(this);
+ dr->post();
+ return;
+ }
+ if (wnd != NULL) {
+ ifc_window *w = getCurRootWnd();
+ onRemove(w, cur_id);
+ destroyWindow();
+ cur_guid = INVALID_GUID;
+ cur_groupid = NULL;
+ defered_guid = INVALID_GUID;
+ }
+}
+
+void WindowHolderI::cancelDeferredRemove() {
+ delete dr;
+ dr = NULL;
+}
+
+void WindowHolderI::wndholder_onNeedReloadGroup(const wchar_t *id)
+{
+ if (cur_groupid.isempty()) return;
+ ifc_window *w = getCurRootWnd();
+ if (w == NULL) return;
+ if (w->isInited() && !WCSICMP(cur_groupid, id))
+ {
+ onRemove(w, cur_id);
+ destroyWindow();
+ createWindow(&INVALID_GUID, id);
+ onInsert(wnd, cur_id);
+ }
+}
+
+ifc_window *WindowHolderI::createWindow(const GUID *g, const wchar_t *groupid)
+{
+ ASSERT(wnd == NULL);
+ if (g != NULL && *g != INVALID_GUID) {
+ wc_svc = WindowCreateByGuidEnum(*g).getFirst();
+ if (wc_svc)
+ wnd = wc_svc->createWindowByGuid(*g, getRootWndPtr());
+ }
+ else if (groupid != NULL)
+ {
+ wc_svc = NULL;
+ wnd = WASABI_API_SKIN->group_create(groupid);
+ }
+ if (wnd) {
+ if (!wnd->isInited()) {
+ if (!wnd->getParent()) wnd->setParent(getRootWndPtr());
+ wnd->init(getRootWndPtr());
+ }
+ }
+ return wnd;
+}
+
+void WindowHolderI::destroyWindow() {
+ ASSERT(wnd != NULL);
+
+ ifc_window *w = wnd->getDesktopParent();
+
+ if (wc_svc) {
+ ifc_window *w = wnd;
+ wnd = NULL;
+ wc_svc->destroyWindow(w);
+ SvcEnum::release(wc_svc);
+ wc_svc = NULL;
+ } else {
+ ifc_window *w = wnd;
+ wnd = NULL;
+ WASABI_API_SKIN->group_destroy(w);
+ }
+
+ if (w != NULL) {
+ if (w->getInterface(layoutGuid)) {
+ static_cast<Layout *>(w)->updateTransparency();
+ }
+ }
+
+}
+
+void WindowHolderI::addAcceptGuid(GUID g) {
+ accepted_guids.addItem(new GUID(g));
+}
+
+void WindowHolderI::addAcceptGroup(const wchar_t *groupid)
+{
+ accepted_groups.addItem(new StringW(groupid));
+}
+
+void WindowHolderI::setAcceptAllGuids(int tf) {
+ generic_guid = tf;
+}
+
+void WindowHolderI::setAcceptAllGroups(int tf) {
+ generic_group = tf;
+}
+
+int WindowHolderI::wantGuid(GUID g) {
+ if (acceptsGenericGuid()) return 1;
+ for (int i=0;i<accepted_guids.getNumItems();i++) {
+ if (*accepted_guids.enumItem(i) == g) return 1;
+ }
+ return 0;
+}
+
+int WindowHolderI::wantGroup(const wchar_t *groupid)
+{
+ if (acceptsGenericGroup()) return 1;
+ for (int i=0;i<accepted_groups.getNumItems();i++) {
+ if (!WCSICMP(accepted_groups.enumItem(i)->getValue(), groupid))
+ return 1;
+ }
+ return 0;
+}
+
+GUID *WindowHolderI::getFirstAcceptedGuid() {
+ if (accepted_guids.getNumItems() == 0) return NULL;
+ return accepted_guids.enumItem(0);
+}
+
+const wchar_t *WindowHolderI::getFirstAcceptedGroup()
+{
+ if (accepted_guids.getNumItems() == 0)
+ return NULL;
+ return
+ accepted_groups.enumItem(0)->getValue();
+}
+
+int WindowHolderI::wndholder_wantAutoFocus() {
+ return 1;
+}
+
+WindowHolderWnd::WindowHolderWnd() {
+ autoavail = 1;
+ autoopen = 1;
+ autoclose = 0;
+ nocmdbar = 0;
+ noanim = 0;
+ has_wnd = 0;
+ autofocus = 1;
+ WASABI_API_SYSCB->syscb_registerCallback(this);
+}
+
+WindowHolderWnd::~WindowHolderWnd() {
+ if (has_wnd) {
+ notifyOnRemove();
+ }
+ WASABI_API_SYSCB->syscb_deregisterCallback(this);
+}
+
+int WindowHolderWnd::onResize() {
+ WINDOWHOLDER_PARENT::onResize();
+ if (getCurRootWnd()) {
+ RECT r;
+ getClientRect(&r);
+ if (!getCurRootWnd()->handleRatio())
+ multRatio(&r);
+ getCurRootWnd()->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
+ }
+ return 1;
+}
+
+int WindowHolderWnd::handleRatio() {
+ return 1;
+}
+
+int WindowHolderWnd::handleDesktopAlpha() {
+ if (getCurRootWnd()) return getCurRootWnd()->handleDesktopAlpha();
+ return 1;
+}
+
+int WindowHolderWnd::handleTransparency() {
+ if (getCurRootWnd()) return getCurRootWnd()->handleTransparency();
+ return 1;
+}
+
+int WindowHolderWnd::onInit() {
+ WINDOWHOLDER_PARENT::onInit();
+ if (isVisible() && autoopen && getFirstAcceptedGuid()) {
+ onInsertWindow(*getFirstAcceptedGuid(), NULL);
+ } else if (isVisible() && autoopen && getFirstAcceptedGroup()) {
+ onInsertWindow(INVALID_GUID, getFirstAcceptedGroup());
+ }
+ return 1;
+}
+
+#define DC_NOTIFYONREMOVE 0x205
+
+void WindowHolderWnd::onRemove(ifc_window *w, const wchar_t *id)
+{
+ ifc_window *dw = getDesktopParent();
+ if (dw) dw->removeMinMaxEnforcer(this);
+ postDeferredCallback(DC_NOTIFYONREMOVE);
+}
+
+int WindowHolderWnd::onDeferredCallback(intptr_t p1, intptr_t p2) {
+ if (p1 == DC_NOTIFYONREMOVE) {
+ notifyOnRemove();
+ } else return WINDOWHOLDER_PARENT::onDeferredCallback(p1, p2);
+ return 1;
+}
+
+void WindowHolderWnd::onInsert(ifc_window *w, const wchar_t *id)
+{
+ if (isPostOnInit())
+ onResize();
+ ifc_window *dw = getDesktopParent();
+ if (dw) dw->addMinMaxEnforcer(this);
+ notifyOnInsert();
+ if (wndholder_wantAutoFocus()) w->setFocus();
+}
+
+int WindowHolderWnd::getPreferences(int what) {
+ if (getCurRootWnd()) return getCurRootWnd()->getPreferences(what);
+ return WINDOWHOLDER_PARENT::getPreferences(what);
+}
+
+void WindowHolderWnd::notifyOnRemove() {
+ has_wnd = 0;
+ Layout *l = getGuiObject()->guiobject_getParentLayout();
+ if (l != NULL) {
+ Container *c = l->getParentContainer();
+ if (c != NULL) {
+ c->notifyRemoveContent(this);
+ }
+ }
+}
+
+void WindowHolderWnd::notifyOnInsert() {
+ has_wnd = 1;
+ Layout *l = getGuiObject()->guiobject_getParentLayout();
+ if (l != NULL) {
+ Container *c = l->getParentContainer();
+ if (c != NULL)
+ {
+ c->notifyAddContent(this, getCurGroupId(), getCurGuid());
+ }
+ }
+}
+
+int WindowHolderWnd::onGroupChange(const wchar_t *grpid)
+{
+ WINDOWHOLDER_PARENT::onGroupChange(grpid);
+ wndholder_onNeedReloadGroup(grpid);
+ return 1;
+}
+
+void WindowHolderWnd::onSetVisible(int show) {
+ if (show && getCurRootWnd() == NULL) {
+ if (autoopen && getFirstAcceptedGuid()) {
+ onInsertWindow(*getFirstAcceptedGuid(), NULL);
+ } else if (autoopen && getFirstAcceptedGroup()) {
+ onInsertWindow(INVALID_GUID, getFirstAcceptedGroup());
+ }
+ } else if (!show && getCurRootWnd() != NULL) {
+ if (autoclose && WASABI_API_SKIN->skin_getVersion() >= 1.0)
+ onRemoveWindow(0);
+ }
+ if (getDeferedGuid() != INVALID_GUID) {
+ if (show) {
+ #ifdef ON_CREATE_EXTERNAL_WINDOW_GUID
+ int y;
+ ON_CREATE_EXTERNAL_WINDOW_GUID(getDeferedGuid(), y);
+ #endif
+ }
+ }
+ WINDOWHOLDER_PARENT::onSetVisible(show);
+}
+
+int WindowHolderWnd::wndholder_wantAutoFocus() {
+ return autofocus;
+}
+