dolphin/Externals/MusicMod/Player/Src/Prefs.cpp

566 lines
16 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 "Prefs.h"
#include "Util.h"
#include "Font.h"
#include "Console.h"
#include <map>
using namespace std;
#define CLASSNAME_PREFS TEXT( "CLASSNAME_PREFS" )
#define TITLE_PREFS TEXT( "Preferences" )
#define PAGE_WIDTH 409
#define PAGE_HEIGHT 400
#define GAP_LEFT 4
#define GAP_RIGHT 5
#define GAP_TOP 4
#define GAP_BOTTOM 5
#define SPLITTER_WIDTH 6
#define SPLITTER_HEIGHT 6
#define BOTTOM_SPACE 36
#define BUTTON_WIDTH 80
#define PREFS_WIDTH 606
#define PREFS_HEIGHT ( GAP_TOP + PAGE_HEIGHT + BOTTOM_SPACE )
struct PrefRecCompare
{
bool operator()( const prefsDlgRec * a, const prefsDlgRec * b ) const
{
if( a->hInst < b->hInst ) return true;
if( a->dlgID < b->dlgID ) return true;
return strcmp( a->name, b->name ) < 0;
}
};
map<prefsDlgRec *, HTREEITEM, PrefRecCompare> rec_to_item;
struct AllWeNeed
{
prefsDlgRec * PageData;
HWND hwnd;
};
HWND WindowPrefs = NULL;
HWND WindowPage = NULL;
HWND WindowTree = NULL;
HWND ButtonClose = NULL;
HTREEITEM root = NULL;
HWND hCurrentPage = NULL;
// bool bKeepFocus = false;
LRESULT CALLBACK WndprocPrefs( HWND hwnd, UINT message, WPARAM wp, LPARAM lp );
LRESULT CALLBACK WndprocTree( HWND hwnd, UINT message, WPARAM wp, LPARAM lp );
WNDPROC WndprocTreeBackup = NULL;
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Prefs::Create()
{
if( WindowPrefs ) return false;
// Register class
WNDCLASS wc = {
0, // UINT style
WndprocPrefs, // 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_PREFS // LPCTSTR lpszClassName
};
if( !RegisterClass( &wc ) ) return false;
const int cxScreen = GetSystemMetrics( SM_CXFULLSCREEN );
const int cyScreen = GetSystemMetrics( SM_CYFULLSCREEN );
// Create window
WindowPrefs = CreateWindowEx(
WS_EX_WINDOWEDGE | // DWORD dwExStyle
WS_EX_TOOLWINDOW, //
CLASSNAME_PREFS, // LPCTSTR lpClassName
TITLE_PREFS, // LPCTSTR lpWindowName
WS_OVERLAPPED | // DWORD dwStyle
// WS_VISIBLE | //
WS_CLIPCHILDREN | //
WS_SYSMENU, //
( cxScreen - PREFS_WIDTH ) / 2, // int x
( cyScreen - PREFS_HEIGHT ) / 2, // int y
PREFS_WIDTH, // int nWidth
PREFS_HEIGHT, // int nHeight
NULL, // HWND hWndParent
NULL, // HMENU hMenu
g_hInstance, // HINSTANCE hInstance
NULL // LPVOID lpParam
);
if( !WindowPrefs )
{
UnregisterClass( CLASSNAME_PREFS, g_hInstance );
return false;
}
RECT r;
GetClientRect( WindowPrefs, &r );
////////////////////////////////////////////////////////////////////////////////
const int iWidth = PREFS_WIDTH * 2 - r.right;
const int iHeight = PREFS_HEIGHT * 2 - r.bottom;
SetWindowPos(
WindowPrefs,
NULL,
( cxScreen - iWidth ) / 2,
( cyScreen - iHeight ) / 2,
iWidth,
iHeight,
SWP_NOZORDER
);
GetClientRect( WindowPrefs, &r );
////////////////////////////////////////////////////////////////////////////////
LoadCommonControls();
const int iTreeWidth = ( r.right - r.left ) - PAGE_WIDTH - GAP_LEFT - GAP_RIGHT - SPLITTER_WIDTH;
WindowTree = CreateWindowEx(
WS_EX_CLIENTEDGE, // DWORD dwExStyle
WC_TREEVIEW, // LPCTSTR lpClassName
NULL, // LPCTSTR lpWindowName
WS_VSCROLL | // DWORD dwStyle
WS_VISIBLE | //
WS_CHILD | //
WS_TABSTOP | //
TVS_HASLINES | //
TVS_LINESATROOT | //
TVS_HASBUTTONS | //
TVS_SHOWSELALWAYS | //
TVS_DISABLEDRAGDROP | //
TVS_NONEVENHEIGHT, //
GAP_LEFT, // int x
GAP_TOP, // int y
iTreeWidth, // int nWidth
PAGE_HEIGHT, // int nHeight
WindowPrefs, // HWND hWndParent
NULL, // HMENU hMenu
g_hInstance, // HINSTANCE hInstance
NULL // LPVOID lpParam
);
if( !WindowTree )
{
; //...
}
Font::Apply( WindowTree );
// Exchange window procedure
WndprocTreeBackup = ( WNDPROC )GetWindowLong( WindowTree, GWL_WNDPROC );
if( WndprocTreeBackup != NULL )
{
SetWindowLong( WindowTree, GWL_WNDPROC, ( LONG )WndprocTree );
}
const int iPageLeft = GAP_LEFT + iTreeWidth + SPLITTER_WIDTH;
WindowPage = CreateWindowEx(
0, // DWORD dwExStyle
TEXT( "Static" ), // LPCTSTR lpClassName
TEXT( "Nothing to see here" ), // LPCTSTR lpWindowName
WS_TABSTOP | // DWORD dwStyle
WS_VISIBLE | //
WS_CHILD | //
SS_CENTER | //
SS_CENTERIMAGE, //
iPageLeft, // int x
GAP_TOP, // int y
PAGE_WIDTH, // int nWidth
PAGE_HEIGHT, // int nHeight
WindowPrefs, // HWND hWndParent
NULL, // HMENU hMenu
g_hInstance, // HINSTANCE hInstance
NULL // LPVOID lpParam
);
if( !WindowPage )
{
; //...
}
Font::Apply( WindowPage );
const int iButtonLeft = ( r.right - r.left ) - GAP_RIGHT - BUTTON_WIDTH - 1;
const int iButtonTop = ( r.bottom - r.top ) - BOTTOM_SPACE + SPLITTER_HEIGHT;
ButtonClose = CreateWindowEx(
0, // DWORD dwExStyle
TEXT( "Button" ), // LPCTSTR lpClassName
TEXT( "Close" ), // LPCTSTR lpWindowName
WS_TABSTOP | // DWORD dwStyle
WS_VISIBLE | //
WS_CHILD | //
BS_PUSHBUTTON | //
BS_TEXT | //
BS_VCENTER, //
iButtonLeft, // int x
iButtonTop, // int y
BUTTON_WIDTH, // int nWidth
BOTTOM_SPACE - SPLITTER_HEIGHT - GAP_BOTTOM, // int nHeight
WindowPrefs, // HWND hWndParent
NULL, // HMENU hMenu
g_hInstance, // HINSTANCE hInstance
NULL // LPVOID lpParam
);
Font::Apply( ButtonClose );
AllWeNeed * awn_root = new AllWeNeed;
// memset( &awn_root->PageData, 0, sizeof( prefsDlgRec ) );
awn_root->PageData = NULL;
awn_root->hwnd = NULL;
TV_INSERTSTRUCT tvi = {
root, // HTREEITEM hParent
TVI_SORT, // HTREEITEM hInsertAfter
{
TVIF_PARAM | TVIF_STATE | TVIF_TEXT, // UINT mask
NULL, // HTREEITEM hItem
TVIS_EXPANDED | TVIS_SELECTED, // UINT state
0, // UINT stateMask
TEXT( "General" ), // LPSTR pszText
8, // int cchTextMax
0, // int iImage
0, // int iSelectedImage
0, // int cChildren
( LPARAM )awn_root // LPARAM lParam
}
};
root = TreeView_InsertItem( WindowTree, &tvi );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Prefs::Destroy()
{
if( !WindowPrefs ) return false;
DestroyWindow( WindowPrefs );
UnregisterClass( CLASSNAME_PREFS, g_hInstance );
WindowPrefs = NULL;
DestroyWindow( WindowTree );
WindowTree = NULL;
DestroyWindow( WindowPage );
WindowPage = NULL;
DestroyWindow( ButtonClose );
ButtonClose = NULL;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Prefs_Show( HTREEITEM item )
{
if( !WindowPrefs ) return false;
// Select and load associated page
TreeView_SelectItem( WindowTree, item );
if( !IsWindowVisible( WindowPrefs ) )
{
ShowWindow( WindowPrefs, SW_SHOW );
}
SetActiveWindow( WindowPrefs );
SetFocus( WindowTree );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Prefs::Show()
{
return Prefs_Show( root );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Prefs::Show( prefsDlgRec * PageData )
{
map<prefsDlgRec *, HTREEITEM, PrefRecCompare>::iterator iter = rec_to_item.find( PageData );
if( iter != rec_to_item.end() )
{
return Prefs_Show( iter->second );
}
else
{
return Prefs_Show( root );
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Prefs::AddPage( prefsDlgRec * PageData )
{
// TODO unicode!
if( !WindowPrefs ) return false;
// Backup
char * NameBackup = new char[ strlen( PageData->name ) + 1 ];
strcpy( NameBackup, PageData->name );
prefsDlgRec * PageDataBackup = new prefsDlgRec;
memcpy( PageDataBackup, PageData, sizeof( prefsDlgRec ) );
PageDataBackup->name = NameBackup;
AllWeNeed * awn = new AllWeNeed;
awn->PageData = PageDataBackup;
awn->hwnd = NULL;
TV_INSERTSTRUCT tvi = {
root, // HTREEITEM hParent
TVI_SORT, // HTREEITEM hInsertAfter
{ //
TVIF_PARAM | TVIF_STATE | TVIF_TEXT, // UINT mask
NULL, // HTREEITEM hItem
TVIS_EXPANDED | TVIS_SELECTED, // UINT state
0, // UINT stateMask
PageDataBackup->name, // LPSTR pszText
( int )strlen( PageDataBackup->name ) + 1, // int cchTextMax
0, // int iImage
0, // int iSelectedImage
0, // int cChildren
( LPARAM )awn // LPARAM lParam
}
};
HTREEITEM new_item = TreeView_InsertItem( WindowTree, &tvi );
TreeView_Expand( WindowTree, root, TVE_EXPAND );
rec_to_item.insert( pair<prefsDlgRec *, HTREEITEM>( PageDataBackup, new_item ) );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndprocPrefs( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
{
switch( message )
{
case WM_NOTIFY:
{
NMHDR * nmhdr = ( NMHDR * )lp;
if( ( nmhdr->hwndFrom == WindowTree ) && ( nmhdr->code == TVN_SELCHANGING ) )
{
NMTREEVIEW * nmtv = ( NMTREEVIEW * )lp;
TVITEM * OldPage = &nmtv->itemOld;
TVITEM * NewPage = &nmtv->itemNew;
// Destroy old window
AllWeNeed * old_awn = ( AllWeNeed * )OldPage->lParam;
if( old_awn && old_awn->hwnd && IsWindow( old_awn->hwnd ) )
{
DestroyWindow( old_awn->hwnd );
old_awn->hwnd = NULL;
}
// Create new window
AllWeNeed * new_awn = ( AllWeNeed * )NewPage->lParam;
if( new_awn )
{
prefsDlgRec * PageData = new_awn->PageData;
if( PageData && PageData->hInst ) // root has NULL here
{
if( !PageData->proc )
{
MessageBox( 0, TEXT( "proc NULL" ), TEXT( "" ), 0 );
PageData->proc = ( void * )WndprocPrefs;
}
/*
RECT r;
GetWindowRect( WindowPage, &r );
const int iWidth = r.right - r.left;
const int iHeight = r.bottom - r.top;
POINT p = { r.left, r.top };
ScreenToClient( WindowPrefs, &p );
MoveWindow( WindowPage, p.x, p.y, iWidth - 10, iHeight - 10, FALSE );
*/
// bKeepFocus = true;
HWND hPage = CreateDialog(
PageData->hInst, // HINSTANCE hInstance,
( LPCTSTR )PageData->dlgID, // LPCTSTR lpTemplate,
WindowPage, // HWND hWndParent,
( DLGPROC )PageData->proc // DLGPROC lpDialogFunc
);
new_awn->hwnd = hPage;
// MoveWindow( WindowPage, p.x, p.y, iWidth, iHeight, FALSE );
ShowWindow( hPage, SW_SHOW );
UpdateWindow( hPage );
SetFocus( WindowTree );
/*
SetActiveWindow( hPage );
SetActiveWindow( hwnd );
*/
hCurrentPage = hPage;
// bKeepFocus = false;
}
/*
else
{
MessageBox( 0, TEXT( "hInst NULL" ), TEXT( "" ), 0 );
}
*/
}
else
{
MessageBox( 0, TEXT( "awn NULL" ), TEXT( "" ), 0 );
}
}
break;
}
case WM_COMMAND:
switch( HIWORD( wp ) )
{
case BN_CLICKED:
if( ( HWND )lp == ButtonClose )
{
PostMessage( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
}
break;
}
break;
case WM_SYSCOMMAND:
if( ( wp & 0xFFF0 ) == SC_CLOSE )
{
ShowWindow( hwnd, SW_HIDE );
// Destroy current page so the settings are saved
// (currently be selecting the empty page
TreeView_SelectItem( WindowTree, root );
/*
if( hCurrentPage && IsWindow( hCurrentPage ) )
{
DestroyWindow( hCurrentPage );
hCurrentPage = NULL;
}
*/
return 0;
}
break;
case WM_KEYDOWN:
switch( wp )
{
case VK_ESCAPE:
PostMessage( WindowPrefs, WM_SYSCOMMAND, SC_CLOSE, 0 );
break;
}
break;
/*
case WM_KILLFOCUS:
if( bKeepFocus )
{
return 1;
}
break;
*/
}
return DefWindowProc( hwnd, message, wp, lp );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndprocTree( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
{
switch( message )
{
case WM_KEYDOWN:
switch( wp )
{
case VK_ESCAPE:
PostMessage( WindowPrefs, WM_SYSCOMMAND, SC_CLOSE, 0 );
break;
}
break;
}
return CallWindowProc( WndprocTreeBackup, hwnd, message, wp, lp );
}