diff options
Diffstat (limited to 'utils/hlfaceposer/faceposertoolwindow.cpp')
| -rw-r--r-- | utils/hlfaceposer/faceposertoolwindow.cpp | 746 |
1 files changed, 746 insertions, 0 deletions
diff --git a/utils/hlfaceposer/faceposertoolwindow.cpp b/utils/hlfaceposer/faceposertoolwindow.cpp new file mode 100644 index 0000000..7997a35 --- /dev/null +++ b/utils/hlfaceposer/faceposertoolwindow.cpp @@ -0,0 +1,746 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#include "hlfaceposer.h" +#include "faceposertoolwindow.h" +#include "utlvector.h" +#include "tier1/strtools.h" +#include "MDLViewer.h" +#include "choreowidgetdrawhelper.h" +#include "StudioModel.h" +#include "faceposer_models.h" + +extern MDLViewer *g_MDLViewer; + +static CUtlVector< IFacePoserToolWindow * > g_Tools; +IFacePoserToolWindow *IFacePoserToolWindow::s_pActiveTool = NULL; + +bool IFacePoserToolWindow::s_bToolsCanDraw; +static CUtlVector< IFacePoserToolWindow * > s_NeedRedraw; + + +IFacePoserToolWindow::IFacePoserToolWindow( char const *toolname, char const *displaynameroot ) +{ + m_bAutoProcess = false; + m_bUseForMainWindowTitle = false; + SetToolName( toolname ); + m_szPrefix[0]=0; + m_szSuffix[0]=0; + + SetDisplayNameRoot( displaynameroot ); + + g_Tools.AddToTail( this ); + + m_nToolFrameCount = 0; +} + +mxWindow *IFacePoserToolWindow::GetMxWindow( void ) +{ + return dynamic_cast< mxWindow * >( this ); +} + +IFacePoserToolWindow *IFacePoserToolWindow::GetActiveTool( void ) +{ + if ( s_pActiveTool ) + return s_pActiveTool; + + if ( GetToolCount() > 0 ) + return GetTool( 0 ); + + return NULL; +} + +void IFacePoserToolWindow::SetActiveTool( IFacePoserToolWindow *tool ) +{ + if ( tool != s_pActiveTool && s_pActiveTool ) + { + InvalidateRect( (HWND)s_pActiveTool->GetMxWindow()->getHandle(), NULL, TRUE ); + InvalidateRect( (HWND)tool->GetMxWindow()->getHandle(), NULL, TRUE ); + } + s_pActiveTool = tool; +} + +void IFacePoserToolWindow::Think( float dt ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *name - +//----------------------------------------------------------------------------- +void IFacePoserToolWindow::SetToolName( char const *name ) +{ + Q_strncpy( m_szToolName, name, sizeof( m_szToolName ) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : char const +//----------------------------------------------------------------------------- +char const *IFacePoserToolWindow::GetToolName( void ) const +{ + return m_szToolName; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *name - +//----------------------------------------------------------------------------- +void IFacePoserToolWindow::SetDisplayNameRoot( char const *name ) +{ + Q_snprintf( m_szDisplayRoot, sizeof( m_szDisplayRoot ), "%s", name ); + ComputeNewTitle(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : char const +//----------------------------------------------------------------------------- +char const *IFacePoserToolWindow::GetDisplayNameRoot( void ) const +{ + return m_szDisplayRoot; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *suffix - +//----------------------------------------------------------------------------- +void IFacePoserToolWindow::SetSuffix( char const *suffix ) +{ + Q_snprintf( m_szSuffix, sizeof( m_szSuffix ), "%s", suffix ); + ComputeNewTitle(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *prefix - +//----------------------------------------------------------------------------- +void IFacePoserToolWindow::SetPrefix( char const *prefix ) +{ + Q_snprintf( m_szPrefix, sizeof( m_szPrefix ), "%s", prefix ); + ComputeNewTitle(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : char const +//----------------------------------------------------------------------------- +char const *IFacePoserToolWindow::GetWindowTitle( void ) const +{ + return m_szWindowTitle; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : use - +//----------------------------------------------------------------------------- +void IFacePoserToolWindow::SetUseForMainWindowTitle( bool use ) +{ + m_bUseForMainWindowTitle = use; + if ( use ) + { + g_MDLViewer->setLabel( m_szWindowTitle ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void IFacePoserToolWindow::ComputeNewTitle( void ) +{ + Q_snprintf( m_szWindowTitle, sizeof( m_szWindowTitle ), "%s%s%s", m_szPrefix, m_szDisplayRoot, m_szSuffix ); + if ( GetMxWindow() ) + { + GetMxWindow()->setLabel( m_szWindowTitle ); + } + if ( !m_bUseForMainWindowTitle ) + return; + + g_MDLViewer->setLabel( m_szWindowTitle ); +} + +IFacePoserToolWindow::~IFacePoserToolWindow( void ) +{ + g_Tools.FindAndRemove( this ); +} + +struct ToolTranslate +{ + char const *toolname; + float xfrac; + float yfrac; + float wfrac; + float hfrac; + bool locked; +}; + +static ToolTranslate s_ToolTranslate[]= +{ + { "3D View", 0.0, 0.0, 0.4, 0.5, false }, + { "ControlPanel", 0.4, 0.0, 0.2, 0.25, false }, + { "FlexPanel", 0.6, 0.0, 0.4, 0.25, false }, + { "RampTool", 0.4, 0.25, 0.6, 0.25, false }, + { "CChoreoView", 0.0, 0.5, 1.0, 0.45, false }, +// { "Status Window", 0.0, 0.85, 1.0, 0.15, false }, +}; + +static bool TranslateToolPos( char const *toolname, int workspacew, int workspaceh, int& x, int& y, int &w, int &h, bool& locked ) +{ + int c = ARRAYSIZE( s_ToolTranslate ); + + for ( int i = 0; i < c; ++i ) + { + ToolTranslate& tt = s_ToolTranslate[ i ]; + + if ( !Q_stricmp( toolname, tt.toolname ) ) + { + x = (int)((float)workspacew * tt.xfrac + 0.5f ); + y = (int)((float)workspaceh * tt.yfrac + 0.5f ); + w = (int)((float)workspacew * tt.wfrac + 0.5f ); + h = (int)((float)workspaceh * tt.hfrac + 0.5f ); + locked = tt.locked; + return true; + } + } + + return false; +} + +static int s_nToolCount = 0; + +void IFacePoserToolWindow::LoadPosition( void ) +{ + bool visible; + bool locked; + bool zoomed; + int x, y, w, h; + + FacePoser_LoadWindowPositions( GetToolName(), visible, x, y, w, h, locked, zoomed ); + + if ( w == 0 || h == 0 ) + { + int idx = g_Tools.Find( this ); + Assert( idx != g_Tools.InvalidIndex() ); + if ( idx == 0 ) + { + s_nToolCount = 0; + } + + zoomed = false; + locked = false; + visible = true; + + // Just do a simple tiling + w = g_MDLViewer->w2() * 0.5; + h = g_MDLViewer->h2() * 0.5; + + x = g_MDLViewer->w2() * 0.25f + s_nToolCount * 20; + y = s_nToolCount * 20; + + bool translated = TranslateToolPos + ( + GetToolName(), + g_MDLViewer->w2(), + g_MDLViewer->h2(), + x, + y, + w, + h, + locked + ); + if ( !translated ) + { + ++s_nToolCount; + visible = false; + } + } + + GetMxWindow()->setBounds( x, y, w, h ); + if ( locked ^ IsLocked() ) + { + ToggleLockedState(); + } + GetMxWindow()->setVisible( visible ); +} + +void IFacePoserToolWindow::SavePosition( void ) +{ + bool visible; + int xpos, ypos, width, height; + + visible = GetMxWindow()->isVisible(); + xpos = GetMxWindow()->x(); + ypos = GetMxWindow()->y(); + width = GetMxWindow()->w(); + height = GetMxWindow()->h(); + + // xpos and ypos are screen space + POINT pt; + pt.x = xpos; + pt.y = ypos; + + // Convert from screen space to relative to client area of parent window so + // the setBounds == MoveWindow call will offset to the same location + if ( GetMxWindow()->getParent() ) + { + ScreenToClient( (HWND)GetMxWindow()->getParent()->getHandle(), &pt ); + xpos = (short)pt.x; + ypos = (short)pt.y; + } + + FacePoser_SaveWindowPositions( GetToolName(), visible, xpos, ypos, width, height, IsLocked(), false ); +} + +int IFacePoserToolWindow::GetToolCount( void ) +{ + return g_Tools.Count(); +} + +IFacePoserToolWindow *IFacePoserToolWindow::GetTool( int index ) +{ + return g_Tools[ index ]; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void IFacePoserToolWindow::InitTools( void ) +{ + int c = GetToolCount(); + int i; + for ( i = 0; i < c ; i++ ) + { + IFacePoserToolWindow *tool = GetTool( i ); + + FacePoser_MakeToolWindow( tool->GetMxWindow(), true ); + tool->GetMxWindow()->setLabel( tool->GetWindowTitle() ); + } +} + +void IFacePoserToolWindow::ShutdownTools( void ) +{ + int c = GetToolCount(); + int i; + for ( i = 0; i < c ; i++ ) + { + IFacePoserToolWindow *tool = GetTool( i ); + tool->Shutdown(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : dt - +//----------------------------------------------------------------------------- +void IFacePoserToolWindow::ToolThink( float dt ) +{ + int c = GetToolCount(); + int i; + for ( i = 0; i < c ; i++ ) + { + IFacePoserToolWindow *tool = GetTool( i ); + tool->Think( dt ); + } + + // Don't self animate, all animation driven by thinking of various tools now + + if ( !ShouldAutoProcess() ) + { + c = models->Count(); + for ( i = 0; i < c; i++ ) + { + StudioModel *m = models->GetStudioModel( i ); + if ( m ) + { + m->AdvanceFrame ( dt ); + } + } + } +} + +bool IFacePoserToolWindow::IsLocked( void ) +{ + mxWindow *w = GetMxWindow(); + if ( !w ) + return false; + + return !FacePoser_HasWindowStyle( w, WS_SYSMENU ); +} + +void IFacePoserToolWindow::ToggleLockedState( void ) +{ + mxWindow *w = GetMxWindow(); + if ( !w ) + return; + + bool visible = w->isVisible(); + + bool islocked = IsLocked(); + if ( islocked ) + { + FacePoser_MakeToolWindow( w, true ); + } + else + { + FacePoser_RemoveWindowStyle( w, WS_OVERLAPPEDWINDOW ); + FacePoser_AddWindowExStyle( w, WS_EX_OVERLAPPEDWINDOW ); + } + + w->setVisible( false ); + + // If visible, force it to redraw, etc. + if ( visible ) + { + w->setVisible( true ); + } +} + +#define LOCK_INSET 2 +#define LOCK_SIZE 8 + +void IFacePoserToolWindow:: GetLockRect( RECT& rc ) +{ + mxWindow *w = GetMxWindow(); + Assert( w ); + if ( !w ) + return; + + GetCloseRect( rc ); + + OffsetRect( &rc, - ( LOCK_SIZE + 2 * LOCK_INSET ), 0 ); +} + +void IFacePoserToolWindow::GetCloseRect( RECT& rc ) +{ + mxWindow *w = GetMxWindow(); + Assert( w ); + if ( !w ) + return; + + rc.right = w->w2() - LOCK_INSET; + rc.left = rc.right - LOCK_SIZE; + rc.top = LOCK_INSET; + rc.bottom = rc.top + LOCK_SIZE; +} + +bool IFacePoserToolWindow::HandleToolEvent( mxEvent *event ) +{ + bool handled = false; + switch ( event->event ) + { + default: + break; + case mxEvent::Close: + { + g_MDLViewer->UpdateWindowMenu(); + handled = true; + } + break; + case mxEvent::ParentNotify: + { + mxWindow *w = GetMxWindow(); + if ( w ) + { + HWND wnd = (HWND)w->getHandle(); + SetFocus( wnd ); + SetWindowPos( wnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + SetActiveTool( this ); + } + handled = true; + } + break; + case mxEvent::PosChanged: + { + SetActiveTool( this ); + mxWindow *w = GetMxWindow(); + if ( w ) + { + SetFocus( (HWND)w->getHandle() ); + } + handled = true; + } + break; + case mxEvent::MouseDown: + case mxEvent::MouseUp: + { + bool isup = event->event == mxEvent::MouseUp; + + mxWindow *w = GetMxWindow(); + + if ( !isup && w ) + { + SetFocus( (HWND)w->getHandle() ); + SetWindowPos( (HWND)w->getHandle(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + + SetActiveTool( this ); + } + + if ( w && IsLocked() ) + { + RECT captionRect; + captionRect.left = 0; + captionRect.right = w->w2(); + captionRect.top = 0; + captionRect.bottom = GetCaptionHeight(); + + POINT pt; + pt.x = (short)event->x; + pt.y = (short)event->y; + + if ( PtInRect( &captionRect, pt ) ) + { + handled = !isup; + + // Right button anywhere + if ( event->buttons & mxEvent::MouseRightButton ) + { + if ( isup ) + { + ToggleLockedState(); + } + } + + // Left button on lock icon + RECT lockRect, closeRect; + GetLockRect( lockRect ); + GetCloseRect( closeRect ); + + if ( PtInRect( &lockRect, pt ) ) + { + if ( isup ) + { + ToggleLockedState(); + } + } + + if ( PtInRect( &closeRect, pt ) ) + { + if ( isup ) + { + w->setVisible( !w->isVisible() ); + g_MDLViewer->UpdateWindowMenu(); + } + } + } + } + } + break; + case mxEvent::NCMouseUp: + { + if ( event->buttons & mxEvent::MouseRightButton ) + { + ToggleLockedState(); + handled = true; + } + } + break; + + case mxEvent::NCMouseDown: + case mxEvent::Focus: + { + SetActiveTool( this ); + // don't mark handled = true, do this passively + } + break; + } + + return handled; +} + +void IFacePoserToolWindow::HandleToolRedraw( CChoreoWidgetDrawHelper& helper ) +{ + if ( !IsLocked() ) + return; + + mxWindow *w = GetMxWindow(); + if ( !w ) + return; + + ++m_nToolFrameCount; + + RECT lockRect, closeRect; + GetLockRect( lockRect ); + GetCloseRect( closeRect ); + + RECT captionRect; + helper.GetClientRect( captionRect ); + RECT rcClient = captionRect; + captionRect.bottom = captionRect.top + LOCK_SIZE + 2 * LOCK_INSET; + + COLORREF textColor = GetSysColor( COLOR_MENUTEXT ); //GetSysColor( COLOR_INACTIVECAPTIONTEXT ); + + if ( IsActiveTool() ) + { + helper.DrawFilledRect( GetSysColor( COLOR_ACTIVECAPTION ), captionRect ); + } + else + { + helper.DrawFilledRect( GetSysColor( COLOR_INACTIVECAPTION ), captionRect ); + } + + captionRect.top += 1; + + InflateRect( &captionRect, -LOCK_INSET, 0 ); + + helper.DrawColoredText( "Small Fonts", 9, FW_NORMAL, textColor, captionRect, + GetWindowTitle() ); + + //RECT rcFrame = captionRect; + //rcFrame.left = rcFrame.right - 50; + //rcFrame.right = rcFrame.left + 30; + // helper.DrawColoredText( "Small Fonts", 9, FW_NORMAL, textColor, rcFrame, va( "%i", m_nToolFrameCount ) ); + + lockRect.bottom++; + OffsetRect( &lockRect, 1, 1 ); + helper.DrawColoredTextCharset( "Marlett", 8, FW_NORMAL, SYMBOL_CHARSET, textColor, lockRect, "v" ); + + closeRect.bottom++; + helper.DrawOutlinedRect( textColor, PS_SOLID, 1, closeRect ); + OffsetRect( &closeRect, 1, 1 ); + helper.DrawColoredTextCharset( "Marlett", 8, FW_NORMAL, SYMBOL_CHARSET, textColor, closeRect, "r" ); + + rcClient.top += captionRect.bottom; + + helper.StartClipping( rcClient ); +} + +int IFacePoserToolWindow::GetCaptionHeight( void ) +{ + if ( !IsLocked() ) + return 0; + + return LOCK_SIZE + 2 * LOCK_INSET; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : autoprocess - +//----------------------------------------------------------------------------- +void IFacePoserToolWindow::SetAutoProcess( bool autoprocess ) +{ + m_bAutoProcess = autoprocess; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool IFacePoserToolWindow::GetAutoProcess( void ) const +{ + return m_bAutoProcess; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool IFacePoserToolWindow::IsActiveTool( void ) +{ + if ( this == s_pActiveTool ) + return true; + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool IFacePoserToolWindow::IsAnyToolScrubbing( void ) +{ + int c = GetToolCount(); + int i; + for ( i = 0; i < c ; i++ ) + { + IFacePoserToolWindow *tool = GetTool( i ); + if ( tool->IsScrubbing() ) + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool IFacePoserToolWindow::IsAnyToolProcessing( void ) +{ + int c = GetToolCount(); + int i; + for ( i = 0; i < c ; i++ ) + { + IFacePoserToolWindow *tool = GetTool( i ); + if ( tool->IsProcessing() ) + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool IFacePoserToolWindow::ShouldAutoProcess( void ) +{ + IFacePoserToolWindow *tool = GetActiveTool(); + if ( !tool ) + return false; + + return tool->GetAutoProcess(); +} + +void IFacePoserToolWindow::EnableToolRedraw( bool enabled ) +{ + MDLCACHE_CRITICAL_SECTION_( g_pMDLCache ); + + s_bToolsCanDraw = enabled; + + if ( s_bToolsCanDraw ) + { + int c = s_NeedRedraw.Count(); + int i; + for ( i = 0; i < c; i++ ) + { + IFacePoserToolWindow *tool = s_NeedRedraw[ i ]; + tool->GetMxWindow()->redraw(); + } + + s_NeedRedraw.Purge(); + } +} + +bool IFacePoserToolWindow::ToolCanDraw() +{ + if ( !s_bToolsCanDraw ) + { + if ( s_NeedRedraw.Find( this ) == s_NeedRedraw.InvalidIndex() ) + { + s_NeedRedraw.AddToTail( this ); + } + + return false; + } + + return true; +} + +void IFacePoserToolWindow::OnModelChanged() +{ +} + +void IFacePoserToolWindow::ModelChanged() +{ + int c = GetToolCount(); + int i; + for ( i = 0; i < c ; i++ ) + { + IFacePoserToolWindow *tool = GetTool( i ); + tool->OnModelChanged(); + } +} + + |