Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

591 lines
16 KiB

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// BINDINGS.CPP
//
// Keyboard Shortcuts
//=====================================================================================//
#include "vxconsole.h"
#define ID_BINDINGS_LISTVIEW 100
// column id
#define ID_BIND_KEYCODE 0
#define ID_BIND_MENUNAME 1
#define ID_BIND_COMMAND 2
typedef struct
{ const CHAR* name;
int width;
int subItemIndex;
} label_t;
typedef struct
{
int keyCode;
const char *pKeyString;
char *pMenuName;
char *pCommandString;
} bind_t;
// {VK_F1, "F1", "WireFrame", "incrementvar mat_wireframe 0 2 1"},
// {VK_F2, "F2", "FullBright", "incrementvar mat_fullbright 0 2 1"},
// {VK_F3, "F3", "Impulse 101", "impulse 101"},
// {VK_F4, "F4", "Screenshot", "*screenshot"},
bind_t g_bindings[MAX_BINDINGS] =
{
{VK_F1, "F1", NULL, NULL},
{VK_F2, "F2", NULL, NULL},
{VK_F3, "F3", NULL, NULL},
{VK_F4, "F4", NULL, NULL},
{VK_F5, "F5", NULL, NULL},
{VK_F6, "F6", NULL, NULL},
{VK_F7, "F7", NULL, NULL},
{VK_F8, "F8", NULL, NULL},
{VK_F9, "F9", NULL, NULL},
{VK_F10, "F10", NULL, NULL},
{VK_F11, "F11", NULL, NULL},
{VK_F12, "F12", NULL, NULL},
};
label_t g_bindings_labels[] =
{
{"Key", 80, ID_BIND_KEYCODE},
{"Menu Name", 150, ID_BIND_MENUNAME},
{"Command", 400, ID_BIND_COMMAND},
};
HWND g_bindings_hWnd;
HWND g_bindings_hWndListView;
RECT g_bindings_windowRect;
char g_bindingsModify_menuName[256];
char g_bindingsModify_command[256];
char g_bindingsModify_keyCode[256];
//-----------------------------------------------------------------------------
// Bindings_ModifyEntry
//
//-----------------------------------------------------------------------------
void Bindings_ModifyEntry( int i, const char *pMenuName, const char *pCommandString )
{
if ( g_bindings[i].pMenuName && g_bindings[i].pMenuName[0] )
Sys_Free( g_bindings[i].pMenuName );
g_bindings[i].pMenuName = Sys_CopyString( pMenuName );
if ( g_bindings[i].pCommandString && g_bindings[i].pCommandString[0] )
Sys_Free( g_bindings[i].pCommandString );
g_bindings[i].pCommandString = Sys_CopyString( pCommandString );
}
//-----------------------------------------------------------------------------
// Bindings_GetSelectedItem
//
//-----------------------------------------------------------------------------
int Bindings_GetSelectedItem()
{
int i;
int selection = -1;
int state;
for ( i=0; i<MAX_BINDINGS; i++ )
{
state = ListView_GetItemState( g_bindings_hWndListView, i, LVIS_SELECTED );
if ( state == LVIS_SELECTED )
{
selection = i;
break;
}
}
return selection;
}
//-----------------------------------------------------------------------------
// Bindings_TranslateKey
//
//-----------------------------------------------------------------------------
bool Bindings_TranslateKey( int vkKeyCode )
{
int i;
for ( i=0; i<MAX_BINDINGS; i++ )
{
if ( !g_bindings[i].pCommandString || !g_bindings[i].pCommandString[0] )
continue;
if ( vkKeyCode == g_bindings[i].keyCode )
{
ProcessCommand( g_bindings[i].pCommandString );
return true;
}
}
return false;
}
//-----------------------------------------------------------------------------
// Bindings_MenuSelection
//
//-----------------------------------------------------------------------------
bool Bindings_MenuSelection( int wID )
{
int index;
index = wID - IDM_BINDINGS_BIND1;
if ( index < 0 || index > MAX_BINDINGS-1 )
return false;
// as if the key were pressed...
return ( Bindings_TranslateKey( g_bindings[index].keyCode ) );
}
//-----------------------------------------------------------------------------
// Bindings_UpdateMenu
//
// Builds the dynamic menu
//-----------------------------------------------------------------------------
void Bindings_UpdateMenu()
{
HMENU hMenu;
HMENU hNewMenu;
MENUITEMINFO menuItemInfo;
int i;
int numAdded;
char menuBuff[64];
hMenu = GetMenu( g_hDlgMain );
if ( !hMenu )
return;
memset( &menuItemInfo, 0, sizeof( menuItemInfo ) );
menuItemInfo.cbSize = sizeof( MENUITEMINFO );
numAdded = 0;
hNewMenu = CreatePopupMenu();
menuItemInfo.fMask = MIIM_ID|MIIM_FTYPE|MIIM_STRING;
menuItemInfo.fType = MFT_STRING;
for ( i=MAX_BINDINGS-1; i>=0; i-- )
{
if ( !g_bindings[i].pCommandString || !g_bindings[i].pCommandString[0] )
continue;
menuItemInfo.wID = IDM_BINDINGS_BIND1+i;
sprintf( menuBuff, "%s\tF%d", g_bindings[i].pMenuName, g_bindings[i].keyCode-VK_F1+1 );
menuItemInfo.dwTypeData = ( LPSTR )menuBuff;
InsertMenuItem( hNewMenu, 0, true, &menuItemInfo );
numAdded++;
}
if ( numAdded )
{
// add seperator
menuItemInfo.fMask = MIIM_FTYPE;
menuItemInfo.fType = MFT_SEPARATOR;
InsertMenuItem( hNewMenu, 0, true, &menuItemInfo );
}
menuItemInfo.fMask = MIIM_ID|MIIM_FTYPE|MIIM_STRING;
menuItemInfo.fType = MFT_STRING;
menuItemInfo.wID = IDM_BINDINGS_EDIT;
menuItemInfo.dwTypeData = "Edit...";
InsertMenuItem( hNewMenu, 0, true, &menuItemInfo );
// delete the previous menu
menuItemInfo.fMask = MIIM_SUBMENU;
GetMenuItemInfo( hMenu, IDM_BINDINGS, false, &menuItemInfo );
if ( menuItemInfo.hSubMenu )
DestroyMenu( menuItemInfo.hSubMenu );
else
{
// add a new menu at the tail of the app menu
AppendMenu( hMenu, MF_STRING, ( UINT_PTR )IDM_BINDINGS, "Bindings" );
}
// add the new menu to bar
menuItemInfo.fMask = MIIM_SUBMENU;
menuItemInfo.hSubMenu = hNewMenu;
SetMenuItemInfo( hMenu, IDM_BINDINGS, false, &menuItemInfo );
DrawMenuBar( g_hDlgMain );
}
//-----------------------------------------------------------------------------
// BindingsModifyDlg_Proc
//
//-----------------------------------------------------------------------------
BOOL CALLBACK BindingsModifyDlg_Proc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch ( message )
{
case WM_INITDIALOG:
SetDlgItemText( hWnd, IDC_MODIFYBIND_KEYCODE, g_bindingsModify_keyCode );
SetDlgItemText( hWnd, IDC_MODIFYBIND_MENUNAME, g_bindingsModify_menuName );
SetDlgItemText( hWnd, IDC_MODIFYBIND_COMMAND, g_bindingsModify_command );
return ( TRUE );
case WM_COMMAND:
switch ( LOWORD( wParam ) )
{
case IDC_OK:
GetDlgItemText( hWnd, IDC_MODIFYBIND_MENUNAME, g_bindingsModify_menuName, sizeof( g_bindingsModify_menuName ) );
GetDlgItemText( hWnd, IDC_MODIFYBIND_COMMAND, g_bindingsModify_command, sizeof( g_bindingsModify_command ) );
case IDCANCEL:
case IDC_CANCEL:
EndDialog( hWnd, wParam );
return ( TRUE );
}
break;
}
return ( FALSE );
}
//-----------------------------------------------------------------------------
// BindingsModifyDlg_Open
//
//-----------------------------------------------------------------------------
void BindingsModifyDlg_Open( int selection )
{
int result;
sprintf( g_bindingsModify_keyCode, "F%d", selection+1 );
strcpy( g_bindingsModify_menuName, g_bindings[selection].pMenuName );
strcpy( g_bindingsModify_command, g_bindings[selection].pCommandString );
result = DialogBox( g_hInstance, MAKEINTRESOURCE( IDD_MODIFYBIND ), g_hDlgMain, ( DLGPROC )BindingsModifyDlg_Proc );
if ( LOWORD( result ) != IDC_OK )
return;
// accept changes and update
Bindings_ModifyEntry( selection, g_bindingsModify_menuName, g_bindingsModify_command );
ListView_RedrawItems( g_bindings_hWndListView, 0, MAX_BINDINGS-1 );
UpdateWindow( g_bindings_hWndListView );
Bindings_UpdateMenu();
}
//-----------------------------------------------------------------------------
// Bindings_LoadConfig
//
//-----------------------------------------------------------------------------
void Bindings_LoadConfig()
{
char valueBuff[256];
char keyBuff[32];
char menuName[256];
char commandString[256];
char *ptr;
char *token;
int keyCode;
int i;
int numArgs;
char buff[256];
for ( i=0; i<MAX_BINDINGS; i++ )
{
menuName[0] = '\0';
commandString[0] = '\0';
sprintf( keyBuff, "bind%d", i );
Sys_GetRegistryString( keyBuff, valueBuff, "", sizeof( valueBuff ) );
// parse and populate valid values
ptr = valueBuff;
token = Sys_GetToken( &ptr, false, NULL );
if ( token[0] )
keyCode = atoi( token );
token = Sys_GetToken( &ptr, false, NULL );
if ( token[0] )
strcpy( menuName, token );
token = Sys_GetToken( &ptr, false, NULL );
if ( token[0] )
strcpy( commandString, token );
Bindings_ModifyEntry( i, menuName, commandString );
}
Sys_GetRegistryString( "bindingsWindowRect", buff, "", sizeof( buff ) );
numArgs = sscanf( buff, "%d %d %d %d", &g_bindings_windowRect.left, &g_bindings_windowRect.top, &g_bindings_windowRect.right, &g_bindings_windowRect.bottom );
if ( numArgs != 4 )
memset( &g_bindings_windowRect, 0, sizeof( g_bindings_windowRect ) );
}
//-----------------------------------------------------------------------------
// Bindings_SaveConfig
//
//-----------------------------------------------------------------------------
void Bindings_SaveConfig()
{
char valueBuff[256];
char buff[256];
char keyBuff[32];
char *pMenuName;
char *pCommandString;
int len;
int i;
WINDOWPLACEMENT wp;
if ( g_bindings_hWnd )
{
memset( &wp, 0, sizeof( wp ) );
wp.length = sizeof( WINDOWPLACEMENT );
GetWindowPlacement( g_bindings_hWnd, &wp );
g_bindings_windowRect = wp.rcNormalPosition;
sprintf( buff, "%d %d %d %d", wp.rcNormalPosition.left, wp.rcNormalPosition.top, wp.rcNormalPosition.right, wp.rcNormalPosition.bottom );
Sys_SetRegistryString( "bindingsWindowRect", buff );
}
for ( i=0; i<MAX_BINDINGS; i++ )
{
sprintf( keyBuff, "bind%d", i );
pMenuName = g_bindings[i].pMenuName;
if ( !pMenuName )
pMenuName = "";
pCommandString = g_bindings[i].pCommandString;
if ( !pCommandString )
pCommandString = "";
len = _snprintf( valueBuff, sizeof( valueBuff ), "%d \"%s\" \"%s\"", g_bindings[i].keyCode, pMenuName, pCommandString );
if ( len == -1 )
{
// kill it
valueBuff[0] = '\0';
}
Sys_SetRegistryString( keyBuff, valueBuff );
}
}
//-----------------------------------------------------------------------------
// Bindings_SizeWindow
//
//-----------------------------------------------------------------------------
void Bindings_SizeWindow( HWND hwnd, int cx, int cy )
{
if ( cx==0 || cy==0 )
{
RECT rcClient;
GetClientRect( hwnd, &rcClient );
cx = rcClient.right;
cy = rcClient.bottom;
}
// position the ListView
SetWindowPos( g_bindings_hWndListView, NULL, 0, 0, cx, cy, SWP_NOZORDER );
}
//-----------------------------------------------------------------------------
// Bindings_WndProc
//
//-----------------------------------------------------------------------------
LRESULT CALLBACK Bindings_WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
WORD wID = LOWORD( wParam );
bind_t* pBind;
int selection;
switch ( message )
{
case WM_CREATE:
return 0L;
case WM_DESTROY:
Bindings_SaveConfig();
Bindings_UpdateMenu();
g_bindings_hWnd = NULL;
return 0L;
case WM_SIZE:
Bindings_SizeWindow( hwnd, LOWORD( lParam ), HIWORD( lParam ) );
return 0L;
case WM_NOTIFY:
switch ( ( ( LPNMHDR )lParam )->code )
{
case LVN_GETDISPINFO:
NMLVDISPINFO* plvdi;
plvdi = ( NMLVDISPINFO* )lParam;
pBind = ( bind_t* )plvdi->item.lParam;
switch ( plvdi->item.iSubItem )
{
case ID_BIND_KEYCODE:
plvdi->item.pszText = ( LPSTR )pBind->pKeyString;
return 0L;
case ID_BIND_MENUNAME:
plvdi->item.pszText = pBind->pMenuName;
return 0L;
case ID_BIND_COMMAND:
plvdi->item.pszText = pBind->pCommandString;
return 0L;
default:
break;
}
break;
case NM_DBLCLK:
NMITEMACTIVATE *pnmitem;
pnmitem = ( LPNMITEMACTIVATE )lParam;
BindingsModifyDlg_Open( pnmitem->iItem );
break;
}
break;
case WM_COMMAND:
switch ( wID )
{
case IDM_BINDOPTIONS_MODIFY:
selection = Bindings_GetSelectedItem();
if ( selection >= 0 )
BindingsModifyDlg_Open( selection );
return 0L;
case IDM_BINDOPTIONS_DELETE:
selection = Bindings_GetSelectedItem();
if ( selection >= 0 )
{
Bindings_ModifyEntry( selection, "", "" );
ListView_RedrawItems( g_bindings_hWndListView, 0, MAX_BINDINGS-1 );
UpdateWindow( g_bindings_hWndListView );
Bindings_UpdateMenu();
}
return 0L;
}
break;
}
return ( DefWindowProc( hwnd, message, wParam, lParam ) );
}
//-----------------------------------------------------------------------------
// Bindings_Open
//
//-----------------------------------------------------------------------------
void Bindings_Open()
{
RECT clientRect;
HWND hWnd;
int i;
LVITEM lvi;
if ( g_bindings_hWnd )
{
// only one instance
if ( IsIconic( g_bindings_hWnd ) )
ShowWindow( g_bindings_hWnd, SW_RESTORE );
SetForegroundWindow( g_bindings_hWnd );
return;
}
hWnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
"BINDINGSCLASS",
"Edit Bindings",
WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_SIZEBOX|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,
0,
0,
600,
300,
g_hDlgMain,
NULL,
g_hInstance,
NULL );
g_bindings_hWnd = hWnd;
GetClientRect( g_bindings_hWnd, &clientRect );
hWnd = CreateWindow(
WC_LISTVIEW,
"",
WS_VISIBLE|WS_CHILD|LVS_REPORT|LVS_SHOWSELALWAYS|LVS_SINGLESEL|LVS_NOSORTHEADER,
0,
0,
clientRect.right-clientRect.left,
clientRect.bottom-clientRect.top,
g_bindings_hWnd,
( HMENU )ID_BINDINGS_LISTVIEW,
g_hInstance,
NULL );
g_bindings_hWndListView = hWnd;
// init list view columns
for ( i=0; i<sizeof( g_bindings_labels )/sizeof( g_bindings_labels[0] ); i++ )
{
LVCOLUMN lvc;
memset( &lvc, 0, sizeof( lvc ) );
lvc.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM;
lvc.iSubItem = 0;
lvc.cx = g_bindings_labels[i].width;
lvc.fmt = LVCFMT_LEFT;
lvc.pszText = ( LPSTR )g_bindings_labels[i].name;
ListView_InsertColumn( g_bindings_hWndListView, i, &lvc );
}
ListView_SetBkColor( g_bindings_hWndListView, g_backgroundColor );
ListView_SetTextBkColor( g_bindings_hWndListView, g_backgroundColor );
DWORD style = LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP;
ListView_SetExtendedListViewStyleEx( g_bindings_hWndListView, style, style );
// populate list view
for ( i=0; i<MAX_BINDINGS; i++ )
{
int itemCount = ListView_GetItemCount( g_bindings_hWndListView );
// setup and insert at end of list
memset( &lvi, 0, sizeof( lvi ) );
lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
lvi.iItem = itemCount;
lvi.iSubItem = 0;
lvi.state = 0;
lvi.stateMask = 0;
lvi.pszText = LPSTR_TEXTCALLBACK;
lvi.lParam = ( LPARAM )&g_bindings[i];
ListView_InsertItem( g_bindings_hWndListView, &lvi );
}
// set the first item selected
ListView_SetItemState( g_bindings_hWndListView, 0, LVIS_SELECTED, LVIS_SELECTED );
SetFocus( g_bindings_hWndListView );
if ( g_bindings_windowRect.right && g_bindings_windowRect.bottom )
MoveWindow( g_bindings_hWnd, g_bindings_windowRect.left, g_bindings_windowRect.top, g_bindings_windowRect.right-g_bindings_windowRect.left, g_bindings_windowRect.bottom-g_bindings_windowRect.top, FALSE );
ShowWindow( g_bindings_hWnd, SHOW_OPENWINDOW );
}
//-----------------------------------------------------------------------------
// Bindings_Init
//
//-----------------------------------------------------------------------------
bool Bindings_Init()
{
// set up our window class
WNDCLASS wndclass;
memset( &wndclass, 0, sizeof( wndclass ) );
wndclass.style = 0;
wndclass.lpfnWndProc = Bindings_WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = g_hInstance;
wndclass.hIcon = g_hIcons[ICON_APPLICATION];
wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
wndclass.hbrBackground = g_hBackgroundBrush;
wndclass.lpszMenuName = MAKEINTRESOURCE( MENU_BINDOPTIONS );
wndclass.lpszClassName = "BINDINGSCLASS";
if ( !RegisterClass( &wndclass ) )
return false;
Bindings_LoadConfig();
Bindings_UpdateMenu();
return true;
}