winamp/Src/Plugins/General/gen_ff/wa2wndembed.cpp

947 lines
29 KiB
C++

#include <precomp.h>
#include "wa2wndembed.h"
#include "wa2frontend.h"
#include "wa2buckitems.h"
#include "embedwndguid.h"
#include "main.h"
#include <api/wnd/bucketitem.h>
#include "resource.h"
#include <api/wnd/wndclass/wndholder.h>
#include <api/wndmgr/layout.h>
#include "wa2cfgitems.h"
#include "gen.h"
#include "../Agave/Language/api_language.h"
extern TList<HWND> forcedoffwnds;
#define BUCKETITEM_WNDTYPE L"buck"
#define WINAMP_OPTIONS_WINDOWSHADE_PL 40266
ReentryFilterObject wndMsgFilter;
int embedTable[] = {
IPC_GETWND_PE,
#ifdef MINIBROWSER_SUPPORT
IPC_GETWND_MB,
#endif
IPC_GETWND_VIDEO};
extern int switching_skin;
extern int going_fixedform;
extern int going_freeform;
extern HINSTANCE hInstance;
//-----------------------------------------------------------------------------------------------
void WaOsWndHost::onBeforeReparent(int host)
{
#if defined(_WIN64)
embedWindowState *ws = (embedWindowState *)GetWindowLong(getHWND(), GWLP_USERDATA);
#else
embedWindowState* ws = (embedWindowState*)GetWindowLong(getHWND(), GWL_USERDATA);
#endif
// 0x49474541 is related to keeping windows shown on litestep desktops
if (ws == NULL || (int)ws == 0x49474541)
{
HWND w = getHWND();
if (w == wa2.getWnd(IPC_GETWND_VIDEO))
{
// this tells the video to not trigger its callback on windowposchanged, otherwise it will generate a new IPC_ONSHOW
SendMessageW(w, WM_USER + 0x2, 0, 1);
}
return ;
}
ws->extra_data[EMBED_STATE_EXTRA_REPARENTING] = 1; // tell winamp to ignore show/hide events
if (!host)
{
ShowWindow(getHWND(), SW_HIDE);
if (!transfer && ((switching_skin && !Wa2WndEmbed::hadRememberedWndVisible(getHWND())) || !switching_skin))
{
PostMessage(getHWND(), WM_USER + 101, 0, 0);
}
}
}
//-----------------------------------------------------------------------------------------------
void WaOsWndHost::onAfterReparent(int host)
{
#if defined(_WIN64)
embedWindowState *ws = (embedWindowState *)GetWindowLong(getHWND(), GWLP_USERDATA);
#else
embedWindowState* ws = (embedWindowState*)GetWindowLong(getHWND(), GWL_USERDATA);
#endif
// 0x49474541 is related to keeping windows shown on litestep desktops
if (ws == NULL || (int)ws == 0x49474541)
{
HWND w = getHWND();
if (w == wa2.getWnd(IPC_GETWND_VIDEO))
{
// stop preventing handling of video windowposchanged
SendMessageW(w, WM_USER + 0x2, 0, 0);
}
return ;
}
ws->extra_data[EMBED_STATE_EXTRA_REPARENTING] = 0; // tell winamp NOT to ignore show/hide events anymore
}
//-----------------------------------------------------------------------------------------------
int WaOsWndHost::onGetFocus()
{
XuiOSWndHost::onGetFocus();
ifc_window *z = findWindowByInterface(windowHolderGuid);
if (z)
{
WindowHolder *wh = static_cast<WindowHolder*>(z->getInterface(windowHolderGuid));
if (wh && wh->wndholder_wantAutoFocus())
{
HWND w = getHWND();
if (IsWindow(w)) SetFocus(w);
}
}
return 1;
}
//-----------------------------------------------------------------------------------------------
int WaOsWndHost::wantFocus()
{
ifc_window *w = findWindowByInterface(windowHolderGuid);
if (w)
{
WindowHolder *wh = static_cast<WindowHolder*>(w->getInterface(windowHolderGuid));
if (wh)
{
return wh->wndholder_wantAutoFocus();
}
}
return 0;
}
//-----------------------------------------------------------------------------------------------
int WaOsWndHost::onMouseWheelUp(int click, int lines)
{
return 1;
}
//-----------------------------------------------------------------------------------------------
int WaOsWndHost::onMouseWheelDown(int click, int lines)
{
return 1;
}
//-----------------------------------------------------------------------------------------------
void VideoLayoutMonitor::hook_onResize(int x, int y, int w, int h)
{
SendMessageW(wa2.getWnd(IPC_GETWND_VIDEO), WM_TIMER, 12345, 0);
}
//-----------------------------------------------------------------------------------------------
void VideoLayoutMonitor::hook_onMove()
{
SendMessageW(wa2.getWnd(IPC_GETWND_VIDEO), WM_TIMER, 12345, 0);
}
//-----------------------------------------------------------------------------------------------
Wa2WndEmbed::Wa2WndEmbed()
{
WASABI_API_SYSCB->syscb_registerCallback(static_cast<WndCallbackI*>(this));
}
//-----------------------------------------------------------------------------------------------
Wa2WndEmbed::~Wa2WndEmbed()
{
WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<WndCallbackI*>(this));
wa2wndstatus.deleteAll();
}
extern int we_have_ml;
//-----------------------------------------------------------------------------------------------
int Wa2WndEmbed::testGuid(GUID g)
{
if (embedWndGuidMgr.testGuid(g)) return 1;
/* if (embedWndGuids.Data2 == g.Data2 && // embed wnd check :)
embedWndGuids.Data3 == g.Data3 &&
!memcmp(embedWndGuids.Data4,g.Data4,8)) return 1;*/
return (g == pleditWndGuid || g == videoWndGuid
#ifdef MINIBROWSER_SUPPORT
|| g == minibrowserWndGuid
#endif
|| (we_have_ml && g == library_guid)
);
}
int make_sure_library_is_here_at_startup = 0;
extern int m_loading_at_startup;
//-----------------------------------------------------------------------------------------------
ifc_window *Wa2WndEmbed::createWindowByGuid(GUID g, ifc_window *parent)
{
if (m_loading_at_startup)
if (g == library_guid)
make_sure_library_is_here_at_startup = 1;
WaOsWndHost *oldhost = NULL;
if (embedWndGuidMgr.testGuid(g) && !embedWndGuidMgr.getEmbedWindowState(g))
return NULL;
// first check if this window is already open in a host, and if so, remove it from the wndholder
foreach(wndhosts)
if (wndhosts.getfor()->g == g)
{
WaOsWndHost *host = wndhosts.getfor()->host;
oldhost = host;
host->setTransfering(1);
host->oswndhost_unhost();
Layout *l = static_cast<Layout *>(host->getDesktopParent());
if (l)
{
Container *c = l->getParentContainer();
if (c)
{
if (!WCSCASEEQLSAFE(c->getId(), L"main"))
{
c->close(); // deferred if needed
}
else
{
softclose:
ifc_window *wnd = host->findWindowByInterface(windowHolderGuid);
if (wnd != NULL)
{
WindowHolder *wh = static_cast<WindowHolder *>(wnd->getInterface(windowHolderGuid));
if (wh != NULL)
{
wh->onRemoveWindow(1);
}
}
}
}
else goto softclose;
}
}
endfor;
// now host the wnd in a new host
WaOsWndHost *host = new WaOsWndHost();
viewer_addViewItem(host);
EmbedEntry *ee = new EmbedEntry();
wndhosts.addItem(ee);
ee->g = g;
ee->host = host;
ee->monitor = NULL;
ee->dep = host->getDependencyPtr();
ee->cmds = NULL;
if (g == pleditWndGuid)
{
RECT r = {10, 20, 5, 38};
host->oswndhost_setRegionOffsets(&r);
host->oswndhost_host(wa2.getWnd(IPC_GETWND_PE));
ee->whichwnd = IPC_GETWND_PE;
host->setName((L"Playlist Editor")/*(WASABI_API_LNGSTRINGW(IDS_PLAYLIST_EDITOR)*/);
GuiObject *go = parent->getGuiObject();
PlaylistAppCmds *plEditAppCmds = new PlaylistAppCmds();
ee->cmds = plEditAppCmds;
go->guiobject_addAppCmds(plEditAppCmds);
plWnd = parent; //parent->getDesktopParent();
//ShowWindow(host->getHWND(), SW_NORMAL);
}
else if (g == videoWndGuid)
{
RECT r = {11, 20, 8, 38};
host->oswndhost_setRegionOffsets(&r);
#ifdef VIDDEBUG
DebugString("Video : Window service creates the host\n");
#endif
HWND vid = wa2.getWnd(IPC_GETWND_VIDEO);
host->oswndhost_host(vid);
((WaOsWndHost *)host)->setNoTransparency();
ee->whichwnd = IPC_GETWND_VIDEO;
host->setName(WASABI_API_LNGSTRINGW(IDS_VIDEO));
ifc_window *lw = parent->getDesktopParent();
if (lw)
{
GuiObject *o = lw->getGuiObject();
if (o)
{
ee->monitor = new VideoLayoutMonitor(o->guiobject_getScriptObject());
}
}
SetTimer(vid, 12345, 250, NULL);
GuiObject *go = parent->getGuiObject();
VideoAppCmds *videoAppCmds = new VideoAppCmds();
ee->cmds = videoAppCmds;
go->guiobject_addAppCmds(videoAppCmds);
vidWnd = parent; //parent->getDesktopParent();
//ShowWindow(host->getHWND(), SW_NORMAL);
#ifdef MINIBROWSER_SUPPORT
}
else if (g == minibrowserWndGuid)
{
RECT r = {10, 20, 5, 38};
host->oswndhost_setRegionOffsets(&r);
host->oswndhost_host(wa2.getWnd(IPC_GETWND_MB));
ee->whichwnd = IPC_GETWND_MB;
host->setName("Minibrowser");
GuiObject *go = parent->getGuiObject();
mbWnd = parent; //parent->getDesktopParent();
MinibrowserAppCmds *mbAppCmds = new MinibrowserAppCmds();
ee->cmds = mbAppCmds;
go->guiobject_addAppCmds(mbAppCmds);
//ShowWindow(host->getHWND(), SW_NORMAL);
#endif
}
else if (embedWndGuidMgr.testGuid(g)) /*(embedWndGuids.Data2 == g.Data2 &&
embedWndGuids.Data3 == g.Data3 &&
!memcmp(embedWndGuids.Data4,g.Data4,8))*/
{
embedWindowState *ws = embedWndGuidMgr.getEmbedWindowState(g);
ASSERT(ws != NULL);
if (0 == (WS_BORDER & GetWindowLongPtrW(ws->me, GWL_STYLE)))
{
RECT r = {11, 20, 8, 14};
host->oswndhost_setRegionOffsets(&r);
}
else
host->oswndhost_setRegionOffsets(NULL);
ws->extra_data[EMBED_STATE_EXTRA_HOSTCOUNT]++;
ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = (intptr_t)parent; //parent->getDesktopParent();
ee->whichwnd = (intptr_t)ws;
if (ws->flags & EMBED_FLAGS_NOTRANSPARENCY) host->setNoTransparency();
host->oswndhost_host(ws->me);
wchar_t buf[512] = {0};
GetWindowTextW(ws->me, buf, 512);
host->setName(buf);
}
else
{
wndhosts.removeItem(ee);
delete host;
delete ee;
return NULL;
}
wa2.setOnTop(cfg_options_alwaysontop.getValueAsInt());
return host;
}
//-----------------------------------------------------------------------------------------------
int Wa2WndEmbed::testType(const wchar_t *windowtype)
{
return !_wcsicmp(windowtype, BUCKETITEM_WNDTYPE) || !_wcsicmp(windowtype, L"plsc");
}
//-----------------------------------------------------------------------------------------------
ifc_window *Wa2WndEmbed::createWindowOfType(const wchar_t *windowtype, ifc_window *parent, int n)
{
if (!_wcsicmp(windowtype, BUCKETITEM_WNDTYPE))
{
switch (n)
{
case 0:
{
PlBucketItem *bi = new PlBucketItem();
bi->setBitmaps(L"winamp.thinger.pledit", NULL, L"winamp.thinger.pledit.hilited", L"winamp.thinger.pledit.selected");
bucketitems.addItem(bi);
return bi;
}
case 1:
{
MlBucketItem *bi = new MlBucketItem();
bi->setBitmaps(L"winamp.thinger.library", NULL, L"winamp.thinger.library.hilited", L"winamp.thinger.library.selected");
bucketitems.addItem(bi);
return bi;
}
case 2:
{
VidBucketItem *bi = new VidBucketItem();
bi->setBitmaps(L"winamp.thinger.video", NULL, L"winamp.thinger.video.hilited", L"winamp.thinger.video.selected");
bucketitems.addItem(bi);
return bi;
}
case 3:
{
VisBucketItem *bi = new VisBucketItem();
bi->setBitmaps(L"winamp.thinger.vis", NULL, L"winamp.thinger.vis.hilited", L"winamp.thinger.vis.selected");
bucketitems.addItem(bi);
return bi;
}
// cases must be contiguous, enumerator stops at first NULL
#ifdef MINIBROWSER_SUPPORT
case 4:
{
MbBucketItem *bi = new MbBucketItem();
bi->setBitmaps(hInstance, IDB_MB_TAB_NORMAL, NULL, IDB_MB_TAB_HILITED, IDB_MB_TAB_SELECTED);
bucketitems.addItem(bi);
return bi;
}
#endif
// n is enumertor, not whichwnd
// we also need some way for the embeddedwnd to expose at least one bitmap (ideally 3) so we can make a nice bucketitem here (this code uses a pledit icon)
/* default:
if (n > 1024)
{
EmbedBucketItem *bi = new EmbedBucketItem();
bi->setBitmaps(hInstance, IDB_PLEDIT_TAB_NORMAL, NULL, IDB_PLEDIT_TAB_HILITED, IDB_PLEDIT_TAB_SELECTED);
bucketitems.addItem(bi);
return bi;
}
break;*/
}
}
else if (!_wcsicmp(windowtype, L"plsc"))
{
switch (n)
{
case 0:
pldirs.addItem(new PlDirObject);
return pldirs.getLast();
}
}
return NULL;
}
//-----------------------------------------------------------------------------------------------
int Wa2WndEmbed::destroyWindow(ifc_window *w)
{
foreach(bucketitems)
Wa2BucketItem *i = bucketitems.getfor();
ifc_window *rw = i;
if (rw == w)
{
delete i;
return 1;
}
endfor;
foreach(wndhosts)
EmbedEntry *ee = wndhosts.getfor();
WaOsWndHost *x = ee->host;
if (WASABI_API_WND->rootwndIsValid(x))
{
ifc_window *rw = x;
if (rw == w)
{
ReentryFilter f(&wndMsgFilter, ee->whichwnd);
if (!f.mustLeave())
{
// this would hide the winamp window, which is probably not what we want to do (it should remain visible if it
// was visible, no?
// well, no, because we don't only run this in skin unloading, but also when a window gets destroyed (this is the wndcreation
// service being called to free what it created) -- this won't happen for mmd3/pledit because mmd3 has a static window for
// everything, which means that when you click close on it, it doesn't destroy it but hides it, so this code isn't called. but
// if you load another skin (ie: NonStep), and you close the pledit, it immediately reappears with the wa2 look since oswndhost_unhost
// reset the flags, region and parent to what they were before the window was embedded
// i think that what we need is to save which windows were visible (and their location) before switching to freeform
// and to restore them when we go back to wa2 mode. this will also be more consistant with the freeform behavior of
// remembering visible status and coordinates on a per skin basis (since otherwise freeform dockings get screwed)
// it also makes sense when we consider that we are going to need to remove all windowshade modes from the embedded
// windows when going freeform.
// see new functions: rememberVisibleWindows() and restoreVisibleWindows()
// in any case, we need to hide the window here, at least temporarily in the case of skin unloading
{
if (ee->whichwnd > 1024)
{
embedWindowState *ws = NULL;
//embedWindowState *ws = (embedWindowState *)ee->whichwnd;
HWND hHost, hContent;
hHost = (NULL != x) ? x->getHWND() : NULL;
hContent = (NULL != hHost) ? (HWND)SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)hHost, IPC_FF_GETCONTENTWND) : NULL;
if (NULL != hContent)
{
ws = (embedWindowState *)GetWindowLongPtrW(hContent, GWLP_USERDATA);
}
else
{
embedWndGuidMgr.retireEmbedWindowState((embedWindowState *)ee->whichwnd);
}
if (NULL != ws &&
!(wa2.isValidEmbedWndState(ws) && --ws->hostcount != 0))
{
if (0 != (EMBED_FLAGS_FFCALLBACK & ws->flags) &&
NULL != ws->callback)
{
ws->callback(ws, FFC_DESTROYEMBED, (LPARAM)w);
}
x->oswndhost_unhost();
if (wa2.isValidEmbedWndState(ws))
ws->wasabi_window = NULL;
if (!x->isTransfering() && wa2.isValidEmbedWndState(ws))
{
if (IsWindow(x->getHWND()))
{
SendMessageW(ws->me, WM_USER + 101, 0, 0);
}
embedWndGuidMgr.retireEmbedWindowState(ws);
}
}
}
else
{
if (ee->whichwnd == IPC_GETWND_VIDEO) KillTimer(wa2.getWnd(ee->whichwnd), 12345);
x->oswndhost_unhost();
if (!x->isTransfering())
wa2.setWindowVisible(ee->whichwnd, 0);
#ifdef VIDDEBUG
if (ee->whichwnd == IPC_GETWND_VIDEO) DebugString("Video : Window service asks WA2 to close the window\n");
#endif
}
}
}
wndhosts.removeItem(ee);
embedWindowState *ws = NULL;
HWND thiswnd = NULL;
if (ee->whichwnd > 1024)
{
if (IsWindow(x->getHWND()))
thiswnd = x->getHWND();
//ws=(embedWindowState *)ee->whichwnd;
//thiswnd=ws->me;
}
else thiswnd = wa2.getWnd(ee->whichwnd);
//moved to xuioswndhost
//SetWindowLong(thiswnd,GWL_STYLE,GetWindowLong(thiswnd,GWL_STYLE)&~(WS_CHILDWINDOW));
switch (ee->whichwnd)
{
case IPC_GETWND_PE: plWnd = NULL; break;
#ifdef MINIBROWSER_SUPPORT
case IPC_GETWND_MB: mbWnd = NULL; break;
#endif
case IPC_GETWND_VIDEO:
#ifdef VIDDEBUG
DebugString("Video : Window service destroys host\n");
#endif
vidWnd = NULL;
break;
default:
if (ee->whichwnd > 1024 && ws && thiswnd != NULL)
{
ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = 0;
}
break;
}
if (ee->cmds)
{
GuiObject *o = w->getParent()->getGuiObject();
o->guiobject_removeAppCmds(ee->cmds);
}
x->oswndhost_unhost(); // ignored if already done by reentryfiltered code
delete ee->monitor;
delete ee->cmds;
delete x;
if (ee->whichwnd > 1024 && ws)
{
if (forcedoffwnds.haveItem(ws->me))
{
RECT r;
GetWindowRect(ws->me, &r);
SetWindowPos(ws->me, NULL, r.left + 20000, r.top + 20000, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOZORDER);
forcedoffwnds.delItem(ws->me);
}
}
delete ee;
SetFocus(wa2.getMainWindow());
return 1;
}
endfor;
foreach (pldirs)
PlDirObject *pldir = pldirs.getfor();
if (pldir == w)
{
delete pldir;
return 1;
}
endfor;
}
return 0;
}
//-----------------------------------------------------------------------------------------------
int Wa2WndEmbed::viewer_onEvent(ifc_window *item, int event, intptr_t param, void *ptr, size_t ptrlen)
{
if (event == ifc_window::Event_SETVISIBLE)
{
/* if (!param) {
// the wnd may be going away, but then again, it might just be hidden to show an alternate layout of the same
// container, so before continuing, we need to check if it's actually going away. There is of course an exception
// in that if the window is hosted by a wndholder with autoclose="1", we should mirror the hiding state regardless
// of the container state
api_window *whr = item->getParent();
int except = 0;
if (whr) {
GuiObject *go = whr->getGuiObject();
if (go) {
const char *par = go->guiobject_getXmlParam("autoclose");
if (!par || (par && ATOI(par) == 1)) except = 1;
}
}
if (!except) {
api_window *lr = item->getDesktopParent();
if (lr) {
Layout *l = static_cast<Layout *>(lr->getInterface(layoutGuid));
if (l) {
Container *c = l->getParentContainer();
if (c) {
if (c->isVisible()) return 1;
}
}
}
}
}*/
foreach(wndhosts)
EmbedEntry *ee = wndhosts.getfor();
XuiOSWndHost *x = ee->host;
ifc_window *rw = x;
if (rw == item)
{
{
ReentryFilter f(&wndMsgFilter, ee->whichwnd);
if (f.mustLeave()) continue;
}
if (ee->whichwnd > 1024)
{
embedWindowState *ws = (embedWindowState *)ee->whichwnd;
if (!param && wa2.isValidEmbedWndState(ws))
{
if (IsWindow(ws->me))
SendMessageW(ws->me, WM_USER + 101, 0, 0);
ifc_window *rwh = x->findWindowByInterface(windowHolderGuid);
if (rwh != NULL)
{
WindowHolder *wh = static_cast<WindowHolder *>(rwh->getInterface(windowHolderGuid));
if (wh != NULL)
{
wh->onRemoveWindow(1);
}
}
if (wa2.isValidEmbedWndState(ws)) ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = NULL;
}
else if (wa2.isValidEmbedWndState(ws))
{
ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = (intptr_t)item->getParent();
ShowWindow(ws->me, SW_NORMAL);
}
}
else
{
ReentryFilter f(&wndMsgFilter, ee->whichwnd);
#ifdef VIDDEBUG
if (ee->whichwnd == IPC_GETWND_VIDEO && param != wa2.isWindowVisible(ee->whichwnd)) DebugString("Video : Detected that the host is %s, syncing\n", param ? "shown" : "hidden");
#endif
wa2.setWindowVisible(ee->whichwnd, param);
}
}
endfor;
}
return 1;
}
int Wa2WndEmbed::onShowWindow(Container *c, GUID guid, const wchar_t *groupid)
{
foreach(wndhosts)
EmbedEntry *ee = wndhosts.getfor();
if (ee->g == guid)
{
ReentryFilter f(&wndMsgFilter, ee->whichwnd);
if (f.mustLeave()) return 1;
if (guid == videoWndGuid) wa2.setWindowVisible(IPC_GETWND_VIDEO, 1);
#ifdef MINIBROWSER_SUPPORT
else if (guid == minibrowserWndGuid) wa2.setWindowVisible(IPC_GETWND_MB, 1);
#endif
else if (guid == pleditWndGuid) wa2.setWindowVisible(IPC_GETWND_PE, 1);
}
endfor;
return 1;
}
int Wa2WndEmbed::onHideWindow(Container *c, GUID guid, const wchar_t *groupid)
{
/* if (guid == INVALID_GUID) return 1;
embedWindowState *ws = embedWndGuidMgr.getEmbedWindowState(guid);
if (ws != NULL && wa2.isValidEmbedWndState(ws)) {
if (IsWindow(ws->me))
SendMessageW(ws->me,WM_USER+101,0,0);
api_window *x = (api_window*)ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND];
if (x && WASABI_API_WND->rootwndIsValid(x)) {
api_window *rwh = x->findWindowByInterface(windowHolderGuid);
if (rwh != NULL) {
WindowHolder *wh = static_cast<WindowHolder *>(rwh->getInterface(windowHolderGuid));
if (wh != NULL) {
wh->onRemoveWindow(1);
}
}
}
ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = NULL;
}
*/
foreach(wndhosts)
EmbedEntry *ee = wndhosts.getfor();
if (ee->g == guid)
{
ReentryFilter f(&wndMsgFilter, ee->whichwnd);
if (f.mustLeave()) return 1;
if (ee->host->isTransfering()) return 1;
ifc_window *dp = ee->host->getDesktopParent();
if (dp)
{
Layout *l = static_cast<Layout*>(dp->getInterface(layoutGuid));
if (l)
{
if (l->getParentContainer() != c) return 1;
}
}
if (guid == videoWndGuid) wa2.setWindowVisible(IPC_GETWND_VIDEO, 0);
#ifdef MINIBROWSER_SUPPORT
else if (guid == minibrowserWndGuid) wa2.setWindowVisible(IPC_GETWND_MB, 0);
#endif
else if (guid == pleditWndGuid) wa2.setWindowVisible(IPC_GETWND_PE, 0);
}
endfor;
return 1;
}
extern wchar_t *INI_FILE;
int Wa2WndEmbed::embedRememberProc(embedWindowState *p, embedEnumStruct *parms)
{
WndStatus *ws = new WndStatus;
ws->wndcode = -1; // if you insert a wnd that is not in embedTable, put -1 as wndcode
ws->wnd = p->me;
ws->visible = IsWindowVisible(p->me);
GetWindowRect(p->me, &ws->position);
// ws->position=p->r;
wa2wndstatus.addItem(ws);
// only store the ml window position if not loading on startup
if(going_freeform && !m_loading_at_startup)
{
HWND mlwnd = wa2.getMediaLibrary();
if(GetWindow(p->me, GW_CHILD) == mlwnd)
{
WritePrivateProfileStringW(L"gen_ff", L"classicmlwidth", StringPrintfW(L"%d", ws->position.right - ws->position.left), INI_FILE);
WritePrivateProfileStringW(L"gen_ff", L"classicmlheight", StringPrintfW(L"%d", ws->position.bottom - ws->position.top), INI_FILE);
}
}
return 0;
}
extern int m_loading_at_startup;
//-----------------------------------------------------------------------------------------------
// todo: remember and restore windowshade modes
void Wa2WndEmbed::rememberVisibleWindows()
{
wa2wndstatus.deleteAll();
for (int i = 0;i < sizeof(embedTable) / sizeof(embedTable[0]);i++)
{
HWND w = wa2.getWnd(embedTable[i]);
WndStatus *ws = new WndStatus;
ws->wndcode = embedTable[i]; // if you insert a wnd that is not in embedTable, put -1 as wndcode
ws->wnd = w;
ws->visible = wa2.isWindowVisible(embedTable[i]);
GetWindowRect(w, &ws->position);
if (going_freeform)
{
if (embedTable[i] == IPC_GETWND_PE)
{
int peheight = ws->position.bottom - ws->position.top;
int pewidth = ws->position.right - ws->position.left;
if (!m_loading_at_startup)
{
WritePrivateProfileStringW(L"gen_ff", L"classicplwidth", StringPrintfW(L"%d", pewidth), INI_FILE);
WritePrivateProfileStringW(L"gen_ff", L"classicplheight", StringPrintfW(L"%d", peheight), INI_FILE);
}
int classicpews = wa2.isWindowShade(IPC_GETWND_PE);
if (!m_loading_at_startup || GetPrivateProfileIntW(L"gen_ff", L"classicplws", -1, INI_FILE) == -1)
WritePrivateProfileStringW(L"gen_ff", L"classicplws", classicpews ? L"1" : L"0", INI_FILE);
if (classicpews)
SendMessageW(wa2.getMainWindow(), WM_COMMAND, WINAMP_OPTIONS_WINDOWSHADE_PL, 0);
GetWindowRect(w, &ws->position);
}
}
wa2wndstatus.addItem(ws);
}
embedEnumStruct cs = { embedRememberProc, 0};
SendMessageW(wa2.getMainWindow(), WM_WA_IPC, (WPARAM)&cs, IPC_EMBED_ENUM);
}
int Wa2WndEmbed::hadRememberedWndVisible(HWND w)
{
int n = wa2wndstatus.getNumItems();
for (int i = 0;i < n;i++)
{
WndStatus *ws = wa2wndstatus.enumItem(i);
if (ws->wnd == w && ws->visible)
return 1;
}
return 0;
}
void Wa2WndEmbed::restoreVisibleWindows()
{
int n = wa2wndstatus.getNumItems();
HWND mlwnd = wa2.getMediaLibrary();
for (int i = 0;i < n;i++)
{
WndStatus *ws = wa2wndstatus.enumItem(i);
if (going_fixedform && !m_loading_at_startup)
{
if (embedTable[i] == IPC_GETWND_PE)
{
int classicpews = GetPrivateProfileIntW(L"gen_ff", L"classicplws", 0, INI_FILE);
if (classicpews)
{
SendMessageW(wa2.getMainWindow(), WM_COMMAND, WINAMP_OPTIONS_WINDOWSHADE_PL, 0);
}
int classicwidth = GetPrivateProfileIntW(L"gen_ff", L"classicplwidth", 275, INI_FILE);
int classicheight = GetPrivateProfileIntW(L"gen_ff", L"classicplheight", 145, INI_FILE);
wa2.setPlEditWidthHeight(classicwidth, classicheight);
}
if(GetWindow(ws->wnd, GW_CHILD) == mlwnd)
{
// only restore the ml window size if we were able to read in saved values
int mlwidth = GetPrivateProfileIntW(L"gen_ff", L"classicmlwidth", -1, INI_FILE);
int mlheight = GetPrivateProfileIntW(L"gen_ff", L"classicmlheight", -1, INI_FILE);
if(mlwidth != -1 && mlheight != -1)
SetWindowPos(ws->wnd, 0, 0, 0, mlwidth, mlheight, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
}
}
// FG> as of oct19, this function only restores state for windows that WERE visible
// because there is no reason to hide one, since this function is designed to bring
// back those windows that were here in one mode, but aren't so anymore in another
if (ws->visible)
{
if (ws->wndcode != -1)
{
wa2.setWindowVisible(ws->wndcode, ws->visible);
}
else
{
ShowWindow(ws->wnd, ws->visible ? SW_SHOWNA : SW_HIDE);
}
}
}
}
PtrList<WndStatus> Wa2WndEmbed::wa2wndstatus;
//-----------------------------------------------------------------------------------------------
PlaylistAppCmds::PlaylistAppCmds()
: addCmd(L"Add", PL_ADD, AppCmds::SIDE_LEFT, 0),
remCmd(L"Rem", PL_REM, AppCmds::SIDE_LEFT, 0),
selCmd(L"Sel", PL_SEL, AppCmds::SIDE_LEFT, 0),
miscCmd(L"Misc", PL_MISC, AppCmds::SIDE_LEFT, 0),
listCmd(L"List", PL_LIST, AppCmds::SIDE_RIGHT, 0)
{
appcmds_addCmd(&addCmd);
appcmds_addCmd(&remCmd);
appcmds_addCmd(&selCmd);
appcmds_addCmd(&miscCmd);
appcmds_addCmd(&listCmd);
}
void PlaylistAppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
{
switch (id)
{
case PL_ADD:
wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_ADD, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
break;
case PL_REM:
wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_REM, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
break;
case PL_SEL:
wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_SEL, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
break;
case PL_MISC:
wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_MISC, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
break;
case PL_LIST:
wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_LIST, buttonRect->right, buttonRect->top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN);
break;
}
}
#ifdef MINIBROWSER_SUPPORT
//-----------------------------------------------------------------------------------------------
MinibrowserAppCmds::MinibrowserAppCmds()
{
appcmds_addCmd(new CmdRec("Back", MB_BACK, AppCmds::SIDE_LEFT, 1));
appcmds_addCmd(new CmdRec("Forward", MB_FORWARD, AppCmds::SIDE_LEFT, 1));
appcmds_addCmd(new CmdRec("Stop", MB_STOP, AppCmds::SIDE_LEFT, 1));
appcmds_addCmd(new CmdRec("Reload", MB_RELOAD, AppCmds::SIDE_LEFT, 1));
appcmds_addCmd(new CmdRec("Misc", MB_MISC, AppCmds::SIDE_RIGHT, 1));
}
void MinibrowserAppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
{
switch (id)
{
case MB_BACK:
wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_BACK);
break;
case MB_FORWARD:
wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_FORWARD);
break;
case MB_STOP:
wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_STOP);
break;
case MB_RELOAD:
wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_RELOAD);
break;
case MB_MISC:
wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBPOPUP_MISC, buttonRect->right, buttonRect->top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN);
break;
}
}
#endif
//-----------------------------------------------------------------------------------------------
VideoAppCmds::VideoAppCmds()
{
appcmds_addCmd(new CmdRec(L"Fullscreen", VID_FULLSCREEN, AppCmds::SIDE_LEFT, 1));
appcmds_addCmd(new CmdRec(L"1x", VID_1X, AppCmds::SIDE_LEFT, 1));
appcmds_addCmd(new CmdRec(L"2x", VID_2X, AppCmds::SIDE_LEFT, 1));
appcmds_addCmd(new CmdRec(L"TV", VID_LIB, AppCmds::SIDE_LEFT, 1));
appcmds_addCmd(new CmdRec(L"Misc", VID_MISC, AppCmds::SIDE_RIGHT, 1));
}
void VideoAppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
{
switch (id)
{
case VID_FULLSCREEN:
wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_FULLSCREEN);
break;
case VID_1X:
wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_1X);
break;
case VID_2X:
wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_2X);
break;
case VID_LIB:
wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_LIB);
break;
case VID_MISC:
wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDPOPUP_MISC, buttonRect->right, buttonRect->top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN);
break;
}
}