summaryrefslogtreecommitdiff
path: root/utils/hlfaceposer/faceposertoolwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/hlfaceposer/faceposertoolwindow.cpp')
-rw-r--r--utils/hlfaceposer/faceposertoolwindow.cpp746
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();
+ }
+}
+
+