|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "hlfaceposer.h"
#include <mxtk/mx.h>
#include "resource.h"
#include "PhonemeProperties.h"
#include "expressions.h"
#include "expclass.h"
#include "mdlviewer.h"
static CPhonemeParams g_Params;
static int g_nPhonemeCount = 0; static HWND *g_rgButtons = NULL;
#define IDC_PHONEME 2000
#define PHONEME_WIDTH 50
#define PHONEME_HEIGHT 18
#define PHONEME_GAP 10
#define PHONEME_VGAP 5
typedef long (__stdcall *WINPROCTYPE)( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); static WINPROCTYPE lpfnOldButtonProc;
static BOOL CALLBACK PhonemeBtnProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch ( uMsg ) { case WM_MOUSEMOVE: { HWND dialog = GetParent( hwnd ); if ( dialog ) { // Get the hint text item
HWND helpText = GetDlgItem( dialog, IDC_STATIC_HELPTEXT ); if ( helpText ) { CExpression *exp = ( CExpression * )GetWindowLong( (HWND)hwnd, GWL_USERDATA ); if ( exp ) { SendMessage( helpText, WM_SETTEXT, 0, (LPARAM)exp->description ); } } } } return 0; default: break; }
return CallWindowProc( lpfnOldButtonProc, hwnd, uMsg, wParam, lParam ); }
//-----------------------------------------------------------------------------
// Purpose:
// Input : phoneme -
// Output : static void
//-----------------------------------------------------------------------------
static void ClickedPhoneme( HWND hwndDlg, int phoneme ) { HWND ctrl = GetDlgItem( hwndDlg, IDC_EDIT_PHONEME ); if ( !ctrl ) return;
if ( !g_Params.m_bMultiplePhoneme ) { g_Params.m_szName[ 0 ] = 0; } else { SendMessage( ctrl, WM_GETTEXT, (WPARAM)sizeof( g_Params.m_szName ), (LPARAM)g_Params.m_szName ); } if ( phoneme >= g_nPhonemeCount || phoneme < 0 ) { Assert( 0 ); return; }
HWND button = g_rgButtons[ phoneme ]; CExpression *exp = ( CExpression * )GetWindowLong( (HWND)button, GWL_USERDATA ); if ( exp ) { if ( strlen( g_Params.m_szName ) > 0 ) { strcat( g_Params.m_szName, " " ); } strcat( g_Params.m_szName, exp->name );
if ( g_Params.m_bMultiplePhoneme ) { SetFocus( ctrl ); SendMessage( ctrl, WM_SETTEXT, 0, (LPARAM)g_Params.m_szName ); SendMessage( ctrl, EM_SETSEL, 0, MAKELONG(0, 0xffff) ); } } }
//-----------------------------------------------------------------------------
// Purpose:
// Input : hwndDlg -
// Output : static void
//-----------------------------------------------------------------------------
static void CreateAndLayoutControls( HWND hwndDlg, CPhonemeParams* params ) { g_nPhonemeCount = 0; // Find phomemes
// Make sure phonemes are loaded
FacePoser_EnsurePhonemesLoaded();
CExpClass *cl = expressions->FindClass( "phonemes", true ); if ( !cl ) return;
g_nPhonemeCount = cl->GetNumExpressions(); if ( g_nPhonemeCount == 0 ) return;
g_rgButtons = new HWND[ g_nPhonemeCount ]; Assert( g_rgButtons );
int columns = 7; int rows = ( g_nPhonemeCount / columns ) + 1;
int dialogW = columns * ( PHONEME_WIDTH + PHONEME_GAP ) + 2 * PHONEME_GAP; int dialogH = rows * ( PHONEME_HEIGHT + PHONEME_VGAP ) + 40 + 55 + 30;
int startx = PHONEME_GAP; int starty = 40;
if ( params->m_bPositionDialog ) { int top = params->m_nTop - dialogH - 5; int left = params->m_nLeft;
MoveWindow( hwndDlg, left, top, dialogW, dialogH, TRUE ); } else { MoveWindow( hwndDlg, ( GetSystemMetrics( SM_CXFULLSCREEN ) - dialogW ) / 2, ( GetSystemMetrics( SM_CYFULLSCREEN ) - dialogH ) / 2, dialogW, dialogH, TRUE ); }
HWND ctrl = GetDlgItem( hwndDlg, IDOK ); if ( ctrl ) { MoveWindow( ctrl, dialogW - 220, dialogH - 58, 100, 20, TRUE ); } ctrl = GetDlgItem( hwndDlg, IDCANCEL ); if ( ctrl ) { MoveWindow( ctrl, dialogW - 110, dialogH - 58, 100, 20, TRUE ); } ctrl = GetDlgItem( hwndDlg, IDC_PHONEMETEXTPROMPT ); if ( ctrl ) { MoveWindow( ctrl, startx, dialogH - 55, 50, 20, TRUE ); } ctrl = GetDlgItem( hwndDlg, IDC_EDIT_PHONEME ); if ( ctrl ) { MoveWindow( ctrl, startx + 50, dialogH - 58, 100, 20, TRUE ); } ctrl = GetDlgItem( hwndDlg, IDC_STATIC_HELPTEXT ); if ( ctrl ) { MoveWindow( ctrl, startx, dialogH - 85, dialogW - startx - 20, 20, TRUE ); }
int r = 0; int c = 0; for ( int i = 0; i < g_nPhonemeCount; i++ ) { CExpression *exp = cl->GetExpression( i ); if ( !exp ) continue;
HWND button = CreateWindowEx( 0, "BUTTON", va( "%s", exp->name ), WS_CHILD | WS_VISIBLE | BS_LEFT, startx + c * ( PHONEME_WIDTH + PHONEME_GAP ), starty + r * ( PHONEME_HEIGHT + PHONEME_VGAP ), PHONEME_WIDTH, PHONEME_HEIGHT, hwndDlg, (HMENU)( IDC_PHONEME + i ), (HINSTANCE)GetModuleHandle( 0 ), NULL ); Assert( button ); SetWindowLong( (HWND)button, GWL_USERDATA, (LONG)exp );
// Subclass it
lpfnOldButtonProc = (WINPROCTYPE)SetWindowLong( (HWND)button, GWL_WNDPROC, (LONG)PhonemeBtnProc );
SendMessage ((HWND)button, WM_SETFONT, (WPARAM) (HFONT) GetStockObject (ANSI_VAR_FONT), MAKELPARAM (TRUE, 0));
g_rgButtons[ i ] = button;
c++; if ( c >= columns ) { r++; c = 0; } } }
//-----------------------------------------------------------------------------
// Purpose:
// Input : hwndDlg -
// Output : static void
//-----------------------------------------------------------------------------
static void DestroyControls( HWND hwndDlg ) { for ( int i = 0 ; i < g_nPhonemeCount; i++ ) { if ( g_rgButtons[ i ] ) { DestroyWindow( g_rgButtons[ i ] ); g_rgButtons[ i ] = NULL; } }
delete[] g_rgButtons; g_nPhonemeCount = 0; }
//-----------------------------------------------------------------------------
// Purpose:
// Input : hwndDlg -
// Output : static void
//-----------------------------------------------------------------------------
static void PhonemePropertiesDialogExit( HWND hwndDlg, int exitCode ) { DestroyControls( hwndDlg );
EndDialog( hwndDlg, exitCode ); }
//-----------------------------------------------------------------------------
// Purpose:
// Input : allowmultiple -
// *input -
// *output -
// Output : static bool
//-----------------------------------------------------------------------------
static bool ValidatePhonemeString( bool allowmultiple, char const *input, char *output ) { // Make sure phonemes are loaded
FacePoser_EnsurePhonemesLoaded();
CExpClass *cl = expressions->FindClass( "phonemes", true ); if ( !cl ) return false;
if ( !input || !input[ 0 ] ) return false;
// Go one by one
int count = 1; char phoneme[ 128 ]; char *in, *out;
*output = 0;
in = (char *)input; do { out = phoneme;
while ( *in > 32 ) { *out++ = *in++; } *out = 0;
// Validate phoneme entered
for ( int i = 0; i < g_nPhonemeCount; i++ ) { CExpression *exp = cl->GetExpression( i ); if ( !exp ) continue; if ( !stricmp( exp->name, phoneme ) ) { // Found it
if ( count != 1 ) { strcat( output, " " ); } strcat( output, phoneme ); break; } }
if ( !*in ) break;
// Skip whitespace
in++; count++;
// Only keep first one
if ( !allowmultiple ) break;
} while ( 1 );
return true; }
//-----------------------------------------------------------------------------
// Purpose:
// Input : hwndDlg -
// uMsg -
// wParam -
// lParam -
// Output : static BOOL CALLBACK
//-----------------------------------------------------------------------------
static BOOL CALLBACK PhonemePropertiesDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch(uMsg) { case WM_INITDIALOG: // Insert code here to put the string (to find and replace with)
// into the edit controls.
// ...
{ g_Params.PositionSelf( hwndDlg );
SetWindowText( hwndDlg, g_Params.m_szDialogTitle );
CreateAndLayoutControls( hwndDlg, &g_Params );
HWND control = GetDlgItem( hwndDlg, IDC_PHONEMENAME ); if ( control ) { SendMessage( control, WM_SETTEXT , 0, ( LPARAM )( g_Params.m_bMultiplePhoneme ? "Click or enter one or more phonemes from list below" : va( "Phoneme/Viseme: %s", g_Params.m_szName ) ) ); }
control = GetDlgItem( hwndDlg, IDC_EDIT_PHONEME ); if ( control ) { SetFocus( control ); SendMessage( control, WM_SETTEXT , 0, ( LPARAM )g_Params.m_szName ); SendMessage( control, EM_SETSEL, 0, MAKELONG(0, 0xffff) ); return FALSE; } } return TRUE; case WM_COMMAND: { int cmd = LOWORD( wParam );
if ( ( cmd >= IDC_PHONEME ) && ( cmd < ( IDC_PHONEME + g_nPhonemeCount ) ) ) { ClickedPhoneme( hwndDlg, cmd - IDC_PHONEME ); if ( !g_Params.m_bMultiplePhoneme ) { PhonemePropertiesDialogExit( hwndDlg, 1 ); } } else if ( cmd != IDC_EDIT_PHONEME ) { switch ( cmd ) { case IDOK: { // Retrieve text
char szPhoneme[ 256 ]; HWND ctrl = GetDlgItem( hwndDlg, IDC_EDIT_PHONEME ); if ( ctrl ) { SendMessage( ctrl, WM_GETTEXT, (WPARAM)sizeof( szPhoneme ), (LPARAM)szPhoneme ); ValidatePhonemeString( g_Params.m_bMultiplePhoneme, szPhoneme, g_Params.m_szName ); } PhonemePropertiesDialogExit( hwndDlg, 1 ); } break; case IDCANCEL: PhonemePropertiesDialogExit( hwndDlg, 0 ); break; } } } return TRUE; } return FALSE; }
//-----------------------------------------------------------------------------
// Purpose:
// Input : *view -
// *actor -
// Output : int
//-----------------------------------------------------------------------------
int PhonemeProperties( CPhonemeParams *params ) { g_Params = *params;
int retval = DialogBox( (HINSTANCE)GetModuleHandle( 0 ), MAKEINTRESOURCE( IDD_PHONEMEPROPERTIES ), (HWND)g_MDLViewer->getHandle(), (DLGPROC)PhonemePropertiesDialogProc );
*params = g_Params;
return retval; }
|