dolphin/Branches/MusicMod/Player/Src/PluginManager.cpp
2009-01-03 01:38:44 +00:00

1143 lines
28 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <webmaster@hartwork.org>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "PluginManager.h"
#include "Plugin.h"
#include "InputPlugin.h"
#include "OutputPlugin.h"
#include "VisPlugin.h"
#include "DspPlugin.h"
#include "GenPlugin.h"
#include "Console.h"
#include "Main.h"
#include "Util.h"
#include "Config.h"
#define MENU_INPUT_CONFIG 1
#define MENU_INPUT_ABOUT 2
#define MENU_OUTPUT_CONFIG 1
#define MENU_OUTPUT_ABOUT 2
#define MENU_OUTPUT_SEP 3
#define MENU_OUTPUT_ACTIVE 4
#define MENU_OUTPUT_LOAD 5
#define MENU_GEN_CONFIG 1
#define MENU_GEN_SEP 2
#define MENU_GEN_LOAD 3
HWND WindowManager = NULL; // extern
HWND WindowListView = NULL;
WNDPROC WndprocListViewBackup = NULL;
LRESULT CALLBACK WndprocListView( HWND hwnd, UINT message, WPARAM wp, LPARAM lp );
LRESULT CALLBACK WndprocManager( HWND hwnd, UINT message, WPARAM wp, LPARAM lp );
HMENU input_menu = NULL;
HMENU output_menu = NULL;
HMENU gen_menu = NULL;
bool bManagerGrid;
ConfBool cbManagerGrid( &bManagerGrid, "ManagerGrid", CONF_MODE_PUBLIC, true );
bool bManagerVisible;
WINDOWPLACEMENT WinPlaceManager;
void WinPlaceManagerCallback( ConfVar * var )
{
if( !IsWindow( WindowManager ) ) return;
GetWindowPlacement( WindowManager, &WinPlaceManager );
// MSDN: If the window identified by the hWnd parameter
// is maximized, the showCmd member is SW_SHOWMAXIMIZED.
// If the window is minimized, showCmd is SW_SHOWMINIMIZED.
// Otherwise, it is SW_SHOWNORMAL.
if( !bManagerVisible )
{
WinPlaceManager.showCmd = SW_HIDE;
}
}
RECT rManagerDefault = { 500, 400, 1000, 700 };
ConfWinPlaceCallback cwpcWinPlaceManager(
&WinPlaceManager,
TEXT( "WinPlaceManager" ),
&rManagerDefault,
WinPlaceManagerCallback
);
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
#define CLASSNAME_PAPMC TEXT( "PLAINAMP_PMC" )
#define PAPMC_TITLE TEXT( "Plugin Manager" )
bool PluginManager::Build()
{
LoadCommonControls();
// Register class
WNDCLASS wc = {
0, // UINT style
WndprocManager, // WNDPROC lpfnWndProc
0, // int cbClsExtra
0, // int cbWndExtra
g_hInstance, // HINSTANCE hInstance
NULL, // HICON hIcon
LoadCursor( NULL, IDC_ARROW ), // HCURSOR hCursor
( HBRUSH )COLOR_WINDOW, // HBRUSH hbrBackground
NULL, // LPCTSTR lpszMenuName
CLASSNAME_PAPMC // LPCTSTR lpszClassName
};
if( !RegisterClass( &wc ) ) return false;
WindowManager = CreateWindowEx(
WS_EX_TOOLWINDOW, // DWORD dwExStyle
CLASSNAME_PAPMC, // LPCTSTR lpClassName
PAPMC_TITLE, // LPCTSTR lpWindowName
WS_OVERLAPPEDWINDOW | // DWORD dwStyle
WS_CLIPCHILDREN, //
rManagerDefault.left, // int x
rManagerDefault.top, // int y
rManagerDefault.right - rManagerDefault.left, // int nWidth
rManagerDefault.bottom - rManagerDefault.top, // int nHeight
NULL, // HWND hWndParent
NULL, // HMENU hMenu
g_hInstance, // HINSTANCE hInstance
NULL // LPVOID lpParam
);
RECT r;
GetClientRect( WindowManager, &r );
WindowListView = CreateWindowEx(
WS_EX_CLIENTEDGE, // DWORD dwExStyle
WC_LISTVIEW, // LPCTSTR lpClassName
NULL, // LPCTSTR lpWindowName
WS_VSCROLL | // DWORD dwStyle
LVS_REPORT | //
LVS_SORTASCENDING | //
LVS_SINGLESEL | //
WS_CHILD | //
WS_VISIBLE, //
0, // int x
0, // int y
r.right - r.left, // int nWidth
r.bottom - r.top, // int nHeight
WindowManager, // HWND hWndParent
NULL, // HMENU hMenu
g_hInstance, // HINSTANCE hInstance
NULL // LPVOID lpParam
);
if( !WindowListView ) return false;
ListView_SetExtendedListViewStyle(
WindowListView,
LVS_EX_FULLROWSELECT |
( bManagerGrid ? LVS_EX_GRIDLINES : 0 ) |
LVS_EX_HEADERDRAGDROP
);
// (0) File
LVCOLUMN lvc = {
LVCF_TEXT | LVCF_WIDTH | LVCF_FMT, // UINT mask;
LVCFMT_LEFT, // int fmt;
100, // int cx;
TEXT( "File" ), // LPTSTR pszText;
5, // int cchTextMax;
0, // int iSubItem;
0, // int iOrder;
0 // int iImage;
};
ListView_InsertColumn( WindowListView, 0, &lvc );
// (1) Status
lvc.pszText = TEXT( "Status" );
lvc.cchTextMax = 7;
ListView_InsertColumn( WindowListView, 1, &lvc );
// (2) Name
lvc.cx = 220;
lvc.pszText = TEXT( "Name" );
lvc.cchTextMax = 5;
ListView_InsertColumn( WindowListView, 2, &lvc );
// (3) Type
lvc.pszText = TEXT( "Type" );
lvc.cchTextMax = 5;
ListView_InsertColumn( WindowListView, 3, &lvc );
bManagerVisible = ( WinPlaceManager.showCmd != SW_HIDE );
SetWindowPlacement( WindowManager, &WinPlaceManager );
// Exchange window procedure
WndprocListViewBackup = ( WNDPROC )GetWindowLong( WindowListView, GWL_WNDPROC );
if( WndprocListViewBackup != NULL )
{
SetWindowLong( WindowListView, GWL_WNDPROC, ( LONG )WndprocListView );
}
// Build context menu
input_menu = CreatePopupMenu();
AppendMenu( input_menu, MF_STRING, MENU_INPUT_CONFIG, TEXT( "Config" ) );
AppendMenu( input_menu, MF_STRING, MENU_INPUT_ABOUT, TEXT( "About" ) );
output_menu = CreatePopupMenu();
AppendMenu( output_menu, MF_STRING, MENU_OUTPUT_CONFIG, TEXT( "Config" ) );
AppendMenu( output_menu, MF_STRING, MENU_OUTPUT_ABOUT, TEXT( "About" ) );
AppendMenu( output_menu, MF_SEPARATOR | MF_GRAYED | MF_DISABLED, MENU_OUTPUT_SEP, NULL );
AppendMenu( output_menu, MF_STRING, MENU_OUTPUT_ACTIVE, TEXT( "Active" ) );
AppendMenu( output_menu, MF_STRING, MENU_OUTPUT_LOAD, TEXT( " " ) );
gen_menu = CreatePopupMenu();
AppendMenu( gen_menu, MF_STRING, MENU_GEN_CONFIG, TEXT( "Config" ) );
AppendMenu( gen_menu, MF_SEPARATOR | MF_GRAYED | MF_DISABLED, MENU_GEN_SEP, NULL );
AppendMenu( gen_menu, MF_STRING, MENU_GEN_LOAD, TEXT( " " ) );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool PluginManager::Fill()
{
if( !WindowListView ) return false;
LVITEM lvi;
memset( &lvi, 0, sizeof( LVITEM ) );
lvi.mask = LVIF_TEXT | LVIF_PARAM;
Plugin * plugin;
int iIndex;
vector<Plugin *>::iterator iter = plugins.begin();
while( iter != plugins.end() )
{
lvi.mask = LVIF_TEXT | LVIF_PARAM;
plugin = *iter;
lvi.iItem = 0;
lvi.lParam = ( LPARAM )plugin;
// (0) File
lvi.iSubItem = 0;
lvi.pszText = plugin->GetFilename();
lvi.cchTextMax = plugin->GetFilenameLen() + 1;
iIndex = ListView_InsertItem( WindowListView, &lvi );
lvi.iItem = iIndex;
lvi.mask = LVIF_TEXT;
// (1) Status
lvi.iSubItem = 1;
if( plugin->IsLoaded() )
{
if( plugin->IsActive() )
{
lvi.pszText = TEXT( "Active" );
}
else
{
lvi.pszText = TEXT( "Loaded" );
}
lvi.cchTextMax = 7;
}
else
{
lvi.pszText = TEXT( "Not loaded" );
lvi.cchTextMax = 11;
}
ListView_SetItem( WindowListView, &lvi );
// (2) Name
lvi.iSubItem = 2;
lvi.pszText = plugin->GetName();
lvi.cchTextMax = plugin->GetNameLen() + 1;
ListView_SetItem( WindowListView, &lvi );
// (3) Type
lvi.iSubItem = 3;
lvi.pszText = plugin->GetTypeString();
lvi.cchTextMax = plugin->GetTypeStringLen() + 1;
ListView_SetItem( WindowListView, &lvi );
iter++;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool PluginManager::Destroy()
{
if( !WindowListView ) return false;
DestroyWindow( WindowManager );
DestroyMenu( input_menu );
DestroyMenu( output_menu );
DestroyMenu( gen_menu );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool PluginManager::Popup()
{
if( !WindowListView ) return false;
if( !IsWindowVisible( WindowManager ) )
ShowWindow( WindowManager, SW_SHOW );
SetActiveWindow( WindowManager );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void UpdatePluginStatus( Plugin * plugin, bool bLoaded, bool bActive )
{
LVFINDINFO lvfi = {
LVFI_PARAM, // UINT flags
NULL, // LPCTSTR psz
( LPARAM )plugin, // LPARAM lParam
POINT(), // POINT pt
0 // UINT vkDirection
};
int iIndex = ListView_FindItem( WindowListView, -1, &lvfi );
if( iIndex != -1 )
{
LVITEM lvi;
memset( &lvi, 0, sizeof( LVITEM ) );
lvi.mask = LVIF_TEXT;
lvi.iItem = iIndex;
lvi.iSubItem = 1;
if( bLoaded )
{
if( bActive )
{
lvi.pszText = TEXT( "Active" );
}
else
{
lvi.pszText = TEXT( "Loaded" );
}
lvi.cchTextMax = 7;
}
else
{
lvi.pszText = TEXT( "Not loaded" );
lvi.cchTextMax = 11;
}
ListView_SetItem( WindowListView, &lvi );
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ContextMenuInput( InputPlugin * input, POINT * p )
{
BOOL iIndex = TrackPopupMenu(
input_menu,
TPM_LEFTALIGN |
TPM_TOPALIGN |
TPM_NONOTIFY |
TPM_RETURNCMD |
TPM_RIGHTBUTTON,
p->x,
p->y,
0,
WindowManager,
NULL
);
switch( iIndex )
{
case MENU_INPUT_ABOUT:
input->About( WindowManager );
break;
case MENU_INPUT_CONFIG:
input->Config( WindowManager );
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ContextMenuOutput( OutputPlugin * output, POINT * p )
{
const bool bLoaded = output->IsLoaded();
const bool bActive = output->IsActive();
EnableMenuItem(
output_menu,
MENU_OUTPUT_CONFIG,
bLoaded ? MF_ENABLED : MF_GRAYED | MF_DISABLED
);
EnableMenuItem(
output_menu,
MENU_OUTPUT_ABOUT,
bLoaded ? MF_ENABLED : MF_GRAYED | MF_DISABLED
);
EnableMenuItem(
output_menu,
MENU_OUTPUT_ACTIVE,
bLoaded ? MF_ENABLED : MF_GRAYED | MF_DISABLED
);
CheckMenuItem(
output_menu,
MENU_OUTPUT_ACTIVE,
bActive ? MF_CHECKED : MF_UNCHECKED
);
MENUITEMINFO mii = { 0 };
mii.cbSize = sizeof( MENUITEMINFO );
mii.fMask = MIIM_STATE | MIIM_STRING;
mii.fState = bActive ? MFS_GRAYED | MFS_DISABLED : MFS_ENABLED;
mii.dwTypeData = ( LPTSTR )( bLoaded ? TEXT( "Unload" ) : TEXT( "Load" ) );
mii.cch = bLoaded ? 7 : 5;
SetMenuItemInfo(
output_menu, // HMENU hMenu
MENU_OUTPUT_LOAD, // UINT uItem
FALSE, // BOOL fByPosition,
&mii // LPMENUITEMINFO lpmii
);
BOOL iIndex = TrackPopupMenu(
output_menu,
TPM_LEFTALIGN |
TPM_TOPALIGN |
TPM_NONOTIFY |
TPM_RETURNCMD |
TPM_RIGHTBUTTON,
p->x,
p->y,
0,
WindowManager,
NULL
);
switch( iIndex )
{
case MENU_OUTPUT_CONFIG:
output->Config( WindowManager );
break;
case MENU_OUTPUT_ABOUT:
output->About( WindowManager );
break;
case MENU_OUTPUT_ACTIVE:
{
if( Playback::IsPlaying() )
{
MessageBox( WindowManager, TEXT( "Cannot do this while playing!" ), TEXT( "Error" ), MB_ICONERROR );
break;
}
if( bActive )
output->Stop();
else
output->Start();
const bool bActiveNew = output->IsActive();
if( bActiveNew != bActive )
{
UpdatePluginStatus( output, bLoaded, bActiveNew );
}
break;
}
case MENU_OUTPUT_LOAD:
{
if( bLoaded )
output->Unload();
else
output->Load();
const bool bLoadedNew = output->IsLoaded();
if( bLoadedNew != bLoaded )
{
UpdatePluginStatus( output, bLoadedNew, bActive );
}
break;
}
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ContextMenuVis( VisPlugin * vis, POINT * p )
{
HMENU vis_menu = CreatePopupMenu();
const bool bLoaded = vis->IsLoaded();
const bool bPluginActive = vis->IsActive();
VisModule * mod;
HMENU * menus = NULL;
const int iModCount = ( int )vis->modules.size();
if( iModCount == 1 )
{
// Single module
mod = vis->modules[ 0 ];
const UINT uFlagsActive = MF_STRING |
( mod->IsActive() ? MF_CHECKED : MF_UNCHECKED ) |
( bLoaded ? MF_ENABLED : MF_DISABLED | MF_GRAYED );
const UINT uFlagsConfig = MF_STRING |
( bLoaded ? MF_ENABLED : MF_DISABLED | MF_GRAYED );
AppendMenu( vis_menu, uFlagsActive, 1, TEXT( "Active" ) );
AppendMenu( vis_menu, uFlagsConfig, 2, TEXT( "Config" ) );
}
else
{
// Two or more
menus = new HMENU[ iModCount ];
int iIndex = 0;
vector <VisModule *>::iterator iter = vis->modules.begin();
while( iter != vis->modules.end() )
{
mod = *iter;
menus[ iIndex ] = CreatePopupMenu();
UINT uFlags = MF_STRING | ( mod->IsActive() ? MF_CHECKED : MF_UNCHECKED );
AppendMenu( menus[ iIndex ], uFlags, iIndex * 2 + 1, TEXT( "Active" ) );
AppendMenu( menus[ iIndex ], MF_STRING, iIndex * 2 + 2, TEXT( "Config" ) );
uFlags = MF_STRING | MF_POPUP | ( ( !bLoaded || ( bPluginActive && !mod->IsActive() ) ) ? MF_GRAYED | MF_DISABLED : 0 );
AppendMenu( vis_menu, uFlags, ( UINT_PTR )menus[ iIndex ], mod->GetName() );
iIndex++;
iter++;
}
}
const int iPos = ( int )vis->modules.size() * 2 + 1;
AppendMenu( vis_menu, MF_SEPARATOR | MF_GRAYED | MF_DISABLED, iPos, NULL );
AppendMenu(
vis_menu,
MF_STRING | ( bPluginActive ? MF_DISABLED | MF_GRAYED : MF_ENABLED ),
iPos + 1,
bLoaded ? TEXT( "Unload" ) : TEXT( "Load" )
);
BOOL iIndex = TrackPopupMenu(
vis_menu, // HMENU hMenu
TPM_LEFTALIGN | // UINT uFlags
TPM_TOPALIGN | // .
TPM_NONOTIFY | // .
TPM_RETURNCMD | // .
TPM_RIGHTBUTTON, // .
p->x, // int x
p->y, // int y
0, // int nReserved
WindowManager, // HWND hWnd
NULL // HWND prcRect
);
if( iIndex )
{
if( iIndex >= iPos )
{
// Load/unload
if( bLoaded )
vis->Unload();
else
vis->Load();
const bool bLoadedNew = vis->IsLoaded();
if( bLoadedNew != bLoaded )
UpdatePluginStatus( vis, bLoadedNew, FALSE );
}
else
{
int iWhich = ( iIndex - 1 ) / 2;
if( iIndex & 1 )
{
// Active
const bool bPluginActive = vis->IsActive();
if( !vis->modules[ iWhich ]->IsActive() )
vis->modules[ iWhich ]->Start();
else
vis->modules[ iWhich ]->Stop();
const bool bPluginActiveNew = vis->IsActive();
if( bPluginActiveNew && ( bPluginActiveNew != bPluginActive ) )
UpdatePluginStatus( vis, TRUE, bPluginActiveNew );
}
else
{
// Config
vis->modules[ iWhich ]->Config();
}
}
}
DestroyMenu( vis_menu );
if( iModCount > 1 )
{
for( int i = 0; i < iModCount; i++ )
DestroyMenu( menus[ i ] );
delete [] menus;
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ContextMenuDsp( DspPlugin * dsp, POINT * p )
{
HMENU context_menu = CreatePopupMenu();
const bool bLoaded = dsp->IsLoaded();
const bool bPluginActive = dsp->IsActive();
DspModule * mod;
HMENU * menus = NULL;
HMENU * add_rem_menus = NULL;
const int iEach = ( 3 * active_dsp_count + 2 );
const int iModCount = ( int )dsp->modules.size();
if( iModCount == 1 )
{
// Single module
mod = dsp->modules[ 0 ];
add_rem_menus = new HMENU[ 2 ];
add_rem_menus[ 0 ] = CreatePopupMenu();
add_rem_menus[ 1 ] = CreatePopupMenu();
int i;
TCHAR szHere[ 12 ];
for( i = 0; i < active_dsp_count; i++ )
{
TCHAR * szName = active_dsp_mods[ i ]->GetName();
// Entry for "Add"
_stprintf( szHere, TEXT( "Here (%i)" ), i + 1 );
AppendMenu(
add_rem_menus[ 0 ],
MF_STRING,
2 * i + 1,
szHere
);
AppendMenu(
add_rem_menus[ 0 ],
MF_STRING | MF_DISABLED | MF_GRAYED,
2 * i + 2,
szName
);
// Entry for "Remove"
AppendMenu(
add_rem_menus[ 1 ],
MF_STRING,
2 * active_dsp_count + 2 + i,
szName
);
}
_stprintf( szHere, TEXT( "Here (%i)" ), i + 1 );
AppendMenu(
add_rem_menus[ 0 ],
MF_STRING,
2 * i + 1,
szHere
);
// Main entries
const UINT uFlagsAdd = MF_STRING | MF_POPUP |
( ( bLoaded && !mod->IsActive() ) ? 0 : MF_DISABLED | MF_GRAYED );
const UINT uFlagsRemove = MF_STRING | MF_POPUP |
( ( bLoaded && active_dsp_count ) ? 0 : MF_GRAYED | MF_DISABLED );
const UINT uFlagsConfig = MF_STRING |
( ( bLoaded && mod->IsActive() ) ? 0 : MF_DISABLED | MF_GRAYED );
AppendMenu(
context_menu,
uFlagsAdd,
( UINT_PTR )add_rem_menus[ 0 ],
TEXT( "Add" )
);
AppendMenu(
context_menu,
uFlagsRemove,
( UINT_PTR )add_rem_menus[ 1 ],
TEXT( "Remove" )
);
AppendMenu(
context_menu,
uFlagsConfig,
3 * active_dsp_count + 1 + 1,
TEXT( "Config" )
);
}
else
{
// Two or more
menus = new HMENU[ iModCount ];
add_rem_menus = new HMENU[ 2 * iModCount ];
int iIndex = 0;
vector <DspModule *>::iterator iter = dsp->modules.begin();
while( iter != dsp->modules.end() )
{
mod = *iter;
menus[ iIndex ] = CreatePopupMenu();
add_rem_menus[ 2 * iIndex ] = CreatePopupMenu();
add_rem_menus[ 2 * iIndex + 1 ] = CreatePopupMenu();
int i;
TCHAR szHere[ 12 ];
for( i = 0; i < active_dsp_count; i++ )
{
TCHAR * szName = active_dsp_mods[ i ]->GetName();
// Entry for "Add"
_stprintf( szHere, TEXT( "Here (%i)" ), i + 1 );
AppendMenu(
add_rem_menus[ 2 * iIndex ],
MF_STRING,
( iIndex * iEach ) + ( 2 * i + 1 ),
szHere
);
AppendMenu(
add_rem_menus[ 2 * iIndex ],
MF_STRING | MF_DISABLED | MF_GRAYED,
( iIndex * iEach ) + ( 2 * i + 2 ),
szName
);
// Entry for "Remove"
AppendMenu(
add_rem_menus[ 2 * iIndex + 1 ],
MF_STRING,
( iIndex * iEach ) + ( 2 * active_dsp_count + 2 + i ),
szName
);
}
_stprintf( szHere, TEXT( "Here (%i)" ), i + 1 );
AppendMenu(
add_rem_menus[ 2 * iIndex ],
MF_STRING,
( iIndex * iEach ) + ( 2 * i + 1 ),
szHere
);
AppendMenu(
menus[ iIndex ],
MF_STRING | MF_POPUP | ( mod->IsActive() ? MF_DISABLED | MF_GRAYED : 0 ),
( UINT_PTR )add_rem_menus[ 2 * iIndex ],
TEXT( "Add" )
);
AppendMenu(
menus[ iIndex ],
MF_STRING | MF_POPUP | ( active_dsp_count ? 0 : MF_GRAYED | MF_DISABLED ),
( UINT_PTR )add_rem_menus[ 2 * iIndex + 1 ],
TEXT( "Remove" )
);
AppendMenu(
menus[ iIndex ],
MF_STRING | ( mod->IsActive() ? 0 : MF_DISABLED | MF_GRAYED ),
( iIndex * iEach ) + ( 3 * active_dsp_count + 1 + 1 ),
TEXT( "Config" )
);
AppendMenu( context_menu, MF_STRING | MF_POPUP | ( bLoaded ? 0 : ( MF_DISABLED | MF_GRAYED ) ), ( UINT_PTR )menus[ iIndex ], mod->GetName() );
iIndex++;
iter++;
}
}
const int iPos = ( int )dsp->modules.size() * ( 3 * active_dsp_count + 1 + 1 ) + 1;
AppendMenu( context_menu, MF_SEPARATOR | MF_GRAYED | MF_DISABLED, iPos, NULL );
UINT uFlags = MF_STRING;
AppendMenu(
context_menu,
uFlags | ( bPluginActive ? MF_DISABLED | MF_GRAYED : MF_ENABLED ),
iPos + 1,
bLoaded ? TEXT( "Unload" ) : TEXT( "Load" )
);
BOOL iIndex = TrackPopupMenu(
context_menu, // HMENU hMenu
TPM_LEFTALIGN | // UINT uFlags
TPM_TOPALIGN | // .
TPM_NONOTIFY | // .
TPM_RETURNCMD | // .
TPM_RIGHTBUTTON, // .
p->x, // int x
p->y, // int y
0, // int nReserved
WindowManager, // HWND hWnd
NULL // HWND prcRect
);
/*
Example menu
Mod1
Add
Here [ 1]
Active1 [ 2]
Here [ 3]
Active2 [ 4]
Here [ 5]
Remove
Active1 [ 6]
Active2 [ 7]
Config [ 8]
Mod2
Add
Here [ 9]
Active1 [10]
...
---
Load/Unload [11]
*/
if( iIndex )
{
if( iIndex >= iPos )
{
// Load/unload
if( bLoaded )
dsp->Unload();
else
dsp->Load();
const bool bLoadedNew = dsp->IsLoaded();
if( bLoadedNew != bLoaded )
UpdatePluginStatus( dsp, bLoadedNew, FALSE );
}
else
{
int iWhichMod = ( iIndex - 1 ) / iEach;
int iRem = iIndex % iEach;
if( iRem == 0 )
{
// Config
dsp->modules[ iWhichMod ]->Config();
}
else if( iRem < 2 * active_dsp_count + 2 )
{
// Add module
const bool bPluginActive = dsp->IsActive();
dsp->modules[ iWhichMod ]->Start( iRem / 2 );
const bool bPluginActiveNew = dsp->IsActive();
if( bPluginActiveNew != bPluginActive )
{
UpdatePluginStatus( dsp, TRUE, bPluginActiveNew );
}
}
else
{
// Remove module
const bool bPluginActive = dsp->IsActive();
iWhichMod = iRem - ( 2 * active_dsp_count + 2 );
/*
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "REM <%i> <%i>" ), iIndex, iWhichMod );
Console::Append( szBuffer );
*/
active_dsp_mods[ iWhichMod ]->Stop();
const bool bPluginActiveNew = dsp->IsActive();
if( bPluginActiveNew != bPluginActive )
{
UpdatePluginStatus( dsp, TRUE, bPluginActiveNew );
}
}
}
}
DestroyMenu( context_menu );
if( iModCount > 1 )
{
for( int i = 0; i < iModCount; i++ )
DestroyMenu( menus[ i ] );
delete [] menus;
}
for( int j = 0; j < iModCount; j++ )
DestroyMenu( add_rem_menus[ j ] );
delete [] add_rem_menus;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ContextMenuGen( GenPlugin * gen, POINT * p )
{
const bool bLoaded = gen->IsLoaded();
EnableMenuItem(
gen_menu,
MENU_GEN_CONFIG,
bLoaded ? MF_ENABLED : MF_GRAYED | MF_DISABLED
);
MENUITEMINFO mii = { 0 };
mii.cbSize = sizeof( MENUITEMINFO );
mii.fMask = MIIM_STATE | MIIM_STRING;
mii.fState = gen->AllowRuntimeUnload() ? MFS_ENABLED : MFS_GRAYED | MFS_DISABLED;
mii.dwTypeData = ( LPTSTR )( bLoaded ? TEXT( "Unload" ) : TEXT( "Load and activate" ) );
mii.cch = bLoaded ? 7 : 18;
SetMenuItemInfo(
gen_menu, // HMENU hMenu
MENU_GEN_LOAD, // UINT uItem
FALSE, // BOOL fByPosition,
&mii // LPMENUITEMINFO lpmii
);
BOOL iIndex = TrackPopupMenu(
gen_menu,
TPM_LEFTALIGN |
TPM_TOPALIGN |
TPM_NONOTIFY |
TPM_RETURNCMD |
TPM_RIGHTBUTTON,
p->x,
p->y,
0,
WindowManager,
NULL
);
switch( iIndex )
{
case MENU_GEN_CONFIG:
gen->Config();
break;
case MENU_GEN_LOAD:
{
if( bLoaded )
gen->Unload();
else
gen->Load();
const bool bLoadedNew = gen->IsLoaded();
if( bLoadedNew != bLoaded )
{
UpdatePluginStatus( gen, bLoadedNew, bLoadedNew );
}
break;
}
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ContextMenu( Plugin * plugin, POINT * p )
{
if( !plugin ) return;
switch( plugin->GetType() )
{
case PLUGIN_TYPE_INPUT:
ContextMenuInput( ( InputPlugin * )plugin, p );
break;
case PLUGIN_TYPE_OUTPUT:
ContextMenuOutput( ( OutputPlugin * )plugin, p );
break;
case PLUGIN_TYPE_VIS:
ContextMenuVis( ( VisPlugin * )plugin, p );
break;
case PLUGIN_TYPE_DSP:
ContextMenuDsp( ( DspPlugin * )plugin, p );
break;
case PLUGIN_TYPE_GEN:
ContextMenuGen( ( GenPlugin * )plugin, p );
break;
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndprocListView( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
{
static bool bContextOpen = false;
switch( message )
{
case WM_CONTEXTMENU:
{
if( ( HWND )wp != WindowListView ) break;
if( bContextOpen ) break;
bContextOpen = true;
////////////////////////////////////////////////////////////////////////////////
POINT p = { LOWORD( lp ), HIWORD( lp ) };
ScreenToClient( WindowListView, &p );
// Which item?
LVHITTESTINFO hti;
memset( &hti, 0, sizeof( LVHITTESTINFO ) );
hti.pt = p;
ListView_HitTest( WindowListView, &hti );
// Which plugin?
LVITEM lvi;
memset( &lvi, 0, sizeof( LVITEM ) );
lvi.mask = LVIF_PARAM;
lvi.iItem = hti.iItem;
lvi.iSubItem = 0;
if( !ListView_GetItem( WindowListView, &lvi ) )
{
bContextOpen = false;
break;
}
Plugin * plugin = ( Plugin * )lvi.lParam;
// Context menu
p.x = LOWORD( lp );
p.y = HIWORD( lp );
ContextMenu( plugin, &p );
////////////////////////////////////////////////////////////////////////////////
bContextOpen = false;
break;
}
}
return CallWindowProc( WndprocListViewBackup, hwnd, message, wp, lp );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndprocManager( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
{
switch( message )
{
case WM_SIZE:
{
// Resize children
RECT client;
GetClientRect( WindowManager, &client );
if( WindowListView )
MoveWindow( WindowListView, 0, 0, client.right - client.left, client.bottom - client.top, TRUE );
break;
}
case WM_SYSCOMMAND:
if( ( wp & 0xFFF0 ) == SC_CLOSE )
{
ShowWindow( hwnd, SW_HIDE );
return 0;
}
break;
case WM_DESTROY:
cwpcWinPlaceManager.TriggerCallback();
cwpcWinPlaceManager.RemoveCallback();
break;
case WM_SHOWWINDOW:
bManagerVisible = ( wp == TRUE );
break;
}
return DefWindowProc( hwnd, message, wp, lp );
}