summaryrefslogtreecommitdiff
path: root/utils/hlfaceposer/choreochannelwidget.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/hlfaceposer/choreochannelwidget.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'utils/hlfaceposer/choreochannelwidget.cpp')
-rw-r--r--utils/hlfaceposer/choreochannelwidget.cpp1207
1 files changed, 1207 insertions, 0 deletions
diff --git a/utils/hlfaceposer/choreochannelwidget.cpp b/utils/hlfaceposer/choreochannelwidget.cpp
new file mode 100644
index 0000000..d41b209
--- /dev/null
+++ b/utils/hlfaceposer/choreochannelwidget.cpp
@@ -0,0 +1,1207 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include <stdio.h>
+#include <mxtk/mxPopupMenu.h>
+#include "hlfaceposer.h"
+#include "choreochannelwidget.h"
+#include "choreoeventwidget.h"
+#include "choreoactorwidget.h"
+#include "choreochannel.h"
+#include "choreowidgetdrawhelper.h"
+#include "choreoview.h"
+#include "choreoevent.h"
+#include "choreoviewcolors.h"
+#include "utlrbtree.h"
+#include "utllinkedlist.h"
+#include "iclosecaptionmanager.h"
+#include "PhonemeEditor.h"
+#include "SoundEmitterSystem/isoundemittersystembase.h"
+#include "filesystem.h"
+
+#define AUDIO_HEIGHT 18
+#define STREAM_FONT "Tahoma"
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *parent -
+//-----------------------------------------------------------------------------
+CChoreoChannelWidget::CChoreoChannelWidget( CChoreoActorWidget *parent )
+: CChoreoWidget( parent )
+{
+ m_pChannel = NULL;
+ m_pParent = parent;
+ m_bHasAudio = false;
+ m_nBaseHeight = 0;
+ m_nSelectorEventIndex = -1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CChoreoChannelWidget::~CChoreoChannelWidget( void )
+{
+ for ( int i = 0 ; i < m_Events.Size(); i++ )
+ {
+ CChoreoEventWidget *e = m_Events[ i ];
+ delete e;
+ }
+ m_Events.RemoveAll();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Create child windows
+//-----------------------------------------------------------------------------
+void CChoreoChannelWidget::Create( void )
+{
+ Assert( m_pChannel );
+
+ // Create objects for children
+ for ( int i = 0; i < m_pChannel->GetNumEvents(); i++ )
+ {
+ CChoreoEvent *e = m_pChannel->GetEvent( i );
+ Assert( e );
+ if ( !e )
+ {
+ continue;
+ }
+
+ CChoreoEventWidget *eventWidget = new CChoreoEventWidget( this );
+ eventWidget->SetEvent( e );
+ eventWidget->Create();
+
+ AddEvent( eventWidget );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : mx -
+// Output : float
+//-----------------------------------------------------------------------------
+float CChoreoChannelWidget::GetTimeForMousePosition( int mx )
+{
+ int dx = mx - m_pView->GetLabelWidth();
+ float windowfrac = ( float ) dx / ( float ) ( w() - m_pView->GetLabelWidth() );
+ float time = m_pView->GetStartTime() + windowfrac * ( m_pView->GetEndTime() - m_pView->GetStartTime() );
+ return time;
+}
+
+static bool EventStartTimeLessFunc( CChoreoEventWidget * const &p1, CChoreoEventWidget * const &p2 )
+{
+ CChoreoEventWidget *w1;
+ CChoreoEventWidget *w2;
+
+ w1 = const_cast< CChoreoEventWidget * >( p1 );
+ w2 = const_cast< CChoreoEventWidget * >( p2 );
+
+ CChoreoEvent *e1;
+ CChoreoEvent *e2;
+
+ e1 = w1->GetEvent();
+ e2 = w2->GetEvent();
+
+ return e1->GetStartTime() < e2->GetStartTime();
+}
+
+void CChoreoChannelWidget::LayoutEventInRow( CChoreoEventWidget *event, int row, RECT& rc )
+{
+ int itemHeight = BaseClass::GetItemHeight();
+
+ RECT rcEvent;
+ rcEvent.left = m_pView->GetPixelForTimeValue( event->GetEvent()->GetStartTime() );
+ if ( event->GetEvent()->HasEndTime() )
+ {
+ rcEvent.right = m_pView->GetPixelForTimeValue( event->GetEvent()->GetEndTime() );
+ }
+ else
+ {
+ rcEvent.right = rcEvent.left + 8;
+ }
+ rcEvent.top = rc.top + ( row ) * itemHeight + 2;
+ rcEvent.bottom = rc.top + ( row + 1 ) * itemHeight - 2;
+ event->Layout( rcEvent );
+}
+
+static bool EventCollidesWithRows( CUtlLinkedList< CChoreoEventWidget *, int >& list, CChoreoEventWidget *event )
+{
+ float st = event->GetEvent()->GetStartTime();
+ float ed = event->GetEvent()->HasEndTime() ? event->GetEvent()->GetEndTime() : event->GetEvent()->GetStartTime();
+
+ for ( int i = list.Head(); i != list.InvalidIndex(); i = list.Next( i ) )
+ {
+ CChoreoEvent *test = list[ i ]->GetEvent();
+
+ float teststart = test->GetStartTime();
+ float testend = test->HasEndTime() ? test->GetEndTime() : test->GetStartTime();
+
+ // See if spans overlap
+ if ( teststart >= ed )
+ continue;
+ if ( testend <= st )
+ continue;
+
+ return true;
+ }
+
+ return false;
+}
+
+int CChoreoChannelWidget::GetVerticalStackingCount( bool layout, RECT *rc )
+{
+ CUtlRBTree< CChoreoEventWidget * > sorted( 0, 0, EventStartTimeLessFunc );
+
+ CUtlVector< CUtlLinkedList< CChoreoEventWidget *, int > > rows;
+
+ int i;
+ // Sort items
+ int c = m_Events.Size();
+ for ( i = 0; i < c; i++ )
+ {
+ sorted.Insert( m_Events[ i ] );
+ }
+
+ for ( i = sorted.FirstInorder(); i != sorted.InvalidIndex(); i = sorted.NextInorder( i ) )
+ {
+ CChoreoEventWidget *event = sorted[ i ];
+ Assert( event );
+ if ( !rows.Count() )
+ {
+ rows.AddToTail();
+
+ CUtlLinkedList< CChoreoEventWidget *, int >& list = rows[ 0 ];
+ list.AddToHead( event );
+
+ if ( layout )
+ {
+ LayoutEventInRow( event, 0, *rc );
+ }
+ continue;
+ }
+
+ // Does it come totally after what's in rows[0]?
+ int rowCount = rows.Count();
+ bool addrow = true;
+
+ for ( int j = 0; j < rowCount; j++ )
+ {
+ CUtlLinkedList< CChoreoEventWidget *, int >& list = rows[ j ];
+
+ if ( !EventCollidesWithRows( list, event ) )
+ {
+ // Update row event list
+ list.AddToHead( event );
+ addrow = false;
+ if ( layout )
+ {
+ LayoutEventInRow( event, j, *rc );
+ }
+ break;
+ }
+ }
+
+ if ( addrow )
+ {
+ // Add a new row
+ int idx = rows.AddToTail();
+ CUtlLinkedList< CChoreoEventWidget *, int >& list = rows[ idx ];
+ list.AddToHead( event );
+ if ( layout )
+ {
+ LayoutEventInRow( event, rows.Count() - 1, *rc );
+ }
+ }
+ }
+
+ return max( 1, rows.Count() );
+}
+
+int CChoreoChannelWidget::GetItemHeight( void )
+{
+ int itemHeight = BaseClass::GetItemHeight();
+ int stackCount = GetVerticalStackingCount( false, NULL );
+
+ CheckHasAudio();
+
+ int h = stackCount * itemHeight;
+
+ // Remember the base height
+ m_nBaseHeight = h;
+
+ if ( m_bHasAudio && m_pView->GetShowCloseCaptionData() )
+ {
+ h += 2 * AUDIO_HEIGHT;
+ }
+
+ return h;
+}
+
+bool CChoreoChannelWidget::CheckHasAudio()
+{
+ m_bHasAudio = false;
+ // Create objects for children
+ for ( int i = 0; i < m_Events.Size(); i++ )
+ {
+ CChoreoEventWidget *event = m_Events[ i ];
+ if ( event->GetEvent()->GetType() == CChoreoEvent::SPEAK )
+ {
+ m_bHasAudio = true;
+ break;
+ }
+ }
+ return m_bHasAudio;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : rc -
+//-----------------------------------------------------------------------------
+void CChoreoChannelWidget::Layout( RECT& rc )
+{
+ setBounds( rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top );
+
+ GetVerticalStackingCount( true, &rc );
+ CheckHasAudio();
+
+ /*
+ // Create objects for children
+ for ( int i = 0; i < m_Events.Size(); i++ )
+ {
+ CChoreoEventWidget *event = m_Events[ i ];
+ Assert( event );
+ if ( !event )
+ {
+ continue;
+ }
+
+ RECT rcEvent;
+ rcEvent.left = m_pView->GetPixelForTimeValue( event->GetEvent()->GetStartTime() );
+ if ( event->GetEvent()->HasEndTime() )
+ {
+ rcEvent.right = m_pView->GetPixelForTimeValue( event->GetEvent()->GetEndTime() );
+ }
+ else
+ {
+ rcEvent.right = rcEvent.left + 8;
+ }
+ rcEvent.top = rc.top + 2;
+ rcEvent.bottom = rc.bottom - 2;
+ event->Layout( rcEvent );
+ }
+ */
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CChoreoChannelWidget::redraw( CChoreoWidgetDrawHelper& drawHelper )
+{
+ if ( !getVisible() )
+ return;
+
+ CChoreoChannel *channel = GetChannel();
+ if ( !channel )
+ return;
+
+ RECT rcText;
+ rcText = getBounds();
+
+ rcText.right = m_pView->GetLabelWidth();
+
+ if ( !channel->GetActive() )
+ {
+ RECT rcBg = rcText;
+ InflateRect( &rcBg, -5, -5 );
+
+ drawHelper.DrawFilledRect( RGB( 210, 210, 210 ), rcBg );
+ }
+
+ RECT rcName = rcText;
+
+ rcName.left += 20;
+ char n[ 512 ];
+ V_strcpy_safe( n, channel->GetName() );
+
+ drawHelper.DrawColoredText( "Arial",
+ m_pView->GetFontSize() + 2,
+ FW_HEAVY,
+ channel->GetActive() ? COLOR_CHOREO_CHANNELNAME : COLOR_CHOREO_ACTORNAME_INACTIVE,
+ rcName, n );
+
+ if ( !channel->GetActive() )
+ {
+ strcpy( n, "(inactive)" );
+
+ RECT rcInactive = rcName;
+ int len = drawHelper.CalcTextWidth( "Arial", m_pView->GetFontSize(), 500, n );
+ rcInactive.left = rcInactive.right - len;
+ //rcInactive.top += 3;
+ //rcInactive.bottom = rcInactive.top + m_pView->GetFontSize() - 2;
+
+ drawHelper.DrawColoredText( "Arial", m_pView->GetFontSize() - 2, 500,
+ COLOR_CHOREO_ACTORNAME_INACTIVE, rcInactive, n );
+ }
+
+ rcName.left -= 20;
+
+ RECT rcEventArea = getBounds();
+ rcEventArea.left = m_pView->GetLabelWidth() + 1;
+ rcEventArea.top -= 20;
+
+ drawHelper.StartClipping( rcEventArea );
+
+ if ( m_bHasAudio )
+ {
+ RenderCloseCaptionExpandCollapseRect( drawHelper, rcEventArea );
+ if ( m_pView->GetShowCloseCaptionData() )
+ {
+ RenderCloseCaptionExpandCollapseRect( drawHelper, rcEventArea );
+ RenderCloseCaptionInfo( drawHelper, rcEventArea );
+ RenderCloseCaptions( drawHelper, rcEventArea );
+ RenderCloseCaptionSelectors( drawHelper, rcEventArea );
+ }
+ }
+
+ for ( int j = GetNumEvents()-1; j >= 0; j-- )
+ {
+ CChoreoEventWidget *event = GetEvent( j );
+ if ( event )
+ {
+ event->redraw( drawHelper );
+ }
+ }
+
+ drawHelper.StopClipping();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : drawHelper -
+// rcEventArea -
+//-----------------------------------------------------------------------------
+void CChoreoChannelWidget::RenderCloseCaptionInfo( CChoreoWidgetDrawHelper& drawHelper, RECT& rcEventArea )
+{
+ wchar_t wstr[ 1024 ];
+ COLORREF barColor = RGB( 100, 200, 255 );
+
+ {
+ RECT rcText = rcEventArea;
+ rcText.left += 2;
+ rcText.top = rcEventArea.bottom - 15;
+ rcText.bottom = rcText.top + 12;
+ drawHelper.DrawColoredText( "Arial", m_pView->GetFontSize() - 2, 500,
+ COLOR_CHOREO_TEXT, rcText, "token/data:" );
+ }
+
+ // Walk the events looking for SPEAK events (esp if marked as MASTER with >= 1 slave)
+ for ( int j = GetNumEvents()-1; j >= 0; j-- )
+ {
+ CChoreoEventWidget *event = GetEvent( j );
+ CChoreoEvent *e = event->GetEvent();
+
+ if ( e->GetType() != CChoreoEvent::SPEAK )
+ continue;
+
+ if ( e->GetCloseCaptionType() == CChoreoEvent::CC_SLAVE )
+ continue;
+
+ char const *label = "";
+
+ bool showState = false;
+ bool stateValid = false;
+
+ if ( e->GetCloseCaptionType() == CChoreoEvent::CC_MASTER )
+ {
+ showState = true;
+ if ( e->GetNumSlaves() >= 1 )
+ {
+ barColor = RGB( 100, 200, 255 );
+ label = e->GetCloseCaptionToken();
+ }
+ else
+ {
+ barColor = RGB( 100, 150, 100 );
+ label = e->GetParameters();
+ }
+
+ char cctoken[ CChoreoEvent::MAX_CCTOKEN_STRING ];
+ if ( e->GetPlaybackCloseCaptionToken( cctoken, sizeof( cctoken ) ) )
+ {
+ stateValid = closecaptionmanager->LookupUnicodeText( GetCloseCaptionLanguageId(), cctoken, wstr, sizeof( wstr ) / sizeof( wchar_t ) );
+ }
+ }
+ else
+ {
+ barColor = RGB( 150, 150, 150 );
+ label = "-disabled-";
+ }
+
+ // Found one!!!
+ RECT rcEvent = event->getBounds();
+
+ float bestEndTime = max( e->GetEndTime(), e->GetLastSlaveEndTime() );
+ int pixeloffset = (int)( ( bestEndTime - e->GetStartTime() ) * m_pView->GetPixelsPerSecond() + 0.5f );
+
+ rcEvent.right = rcEvent.left + pixeloffset;
+ rcEvent.top = rcEventArea.bottom - 3;
+ rcEvent.bottom = rcEventArea.bottom;
+
+
+ drawHelper.DrawFilledRect( barColor, rcEvent );
+
+ RECT rcTriangle;
+ rcTriangle = rcEvent;
+ rcTriangle.right = rcTriangle.left + 3;
+ rcTriangle.left -= 3;
+
+ OffsetRect( &rcTriangle, 0, -6 );
+ rcTriangle.bottom += 6;
+ drawHelper.DrawTriangleMarker( rcTriangle, barColor, true );
+
+ rcTriangle.left = rcEvent.right - 3;
+ rcTriangle.right = rcEvent.right + 3;
+
+ drawHelper.DrawTriangleMarker( rcTriangle, barColor, true );
+
+ RECT rcText = rcEvent;
+ rcText.bottom = rcText.top + 12;
+ OffsetRect( &rcText, 5, -12 );
+
+ if ( showState )
+ {
+ int stateMarkWidth = 12;
+ RECT rcState = rcText;
+ rcState.right = rcState.left + stateMarkWidth;
+ rcText.left += stateMarkWidth;
+
+ COLORREF symColor = stateValid ? RGB( 40, 100, 40 ) : RGB( 200, 40, 40 );
+
+ drawHelper.DrawColoredTextCharset(
+ "Marlett",
+ m_pView->GetFontSize() - 2,
+ 500,
+ SYMBOL_CHARSET,
+ symColor,
+ rcState,
+ stateValid ? "a" : "r" );
+
+ }
+
+ if ( e->IsSuppressingCaptionAttenuation() )
+ {
+ drawHelper.DrawColoredText( "Arial", m_pView->GetFontSize() - 2, 500,
+ RGB( 80, 80, 100 ), rcText, "%s [no attenuate]", label );
+
+ }
+ else
+ {
+ drawHelper.DrawColoredText( "Arial", m_pView->GetFontSize() - 2, 500,
+ RGB( 80, 80, 100 ), rcText, label );
+ }
+
+
+
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : drawHelper -
+// rcEventArea -
+//-----------------------------------------------------------------------------
+void CChoreoChannelWidget::RenderCloseCaptions( CChoreoWidgetDrawHelper& drawHelper, RECT& rcEventArea )
+{
+ {
+ RECT rcText = rcEventArea;
+ rcText.top = rcEventArea.top + m_nBaseHeight + AUDIO_HEIGHT + 5;
+ rcText.bottom = rcText.top + 12;
+ rcText.left += 12;
+ drawHelper.DrawColoredText( "Arial", m_pView->GetFontSize() - 2, 500,
+ COLOR_CHOREO_TEXT, rcText, "%s", CSentence::NameForLanguage( GetCloseCaptionLanguageId() ) );
+
+ // Previous
+ GetCloseCaptionLanguageRect( rcText, true );
+ drawHelper.DrawColoredTextCharset(
+ "Marlett",
+ m_pView->GetFontSize(),
+ 500,
+ SYMBOL_CHARSET,
+ COLOR_CHOREO_TEXT,
+ rcText,
+ "3" );
+
+ // Next
+ GetCloseCaptionLanguageRect( rcText, false );
+ drawHelper.DrawColoredTextCharset(
+ "Marlett",
+ m_pView->GetFontSize(),
+ 500,
+ SYMBOL_CHARSET,
+ COLOR_CHOREO_TEXT,
+ rcText,
+ "4" );
+ }
+
+ // Walk the events looking for SPEAK events (esp if marked as MASTER with >= 1 slave)
+ for ( int j = GetNumEvents()-1; j >= 0; j-- )
+ {
+ CChoreoEventWidget *event = GetEvent( j );
+ CChoreoEvent *e = event->GetEvent();
+
+ if ( e->GetType() != CChoreoEvent::SPEAK )
+ continue;
+
+ if ( e->GetCloseCaptionType() == CChoreoEvent::CC_SLAVE ||
+ e->GetCloseCaptionType() == CChoreoEvent::CC_DISABLED )
+ continue;
+
+ char cctoken[ CChoreoEvent::MAX_CCTOKEN_STRING ];
+
+ bool valid = e->GetPlaybackCloseCaptionToken( cctoken, sizeof( cctoken ) );
+ if ( !valid )
+ continue;
+
+ wchar_t wstr[ 1024 ];
+
+ valid = closecaptionmanager->LookupStrippedUnicodeText( GetCloseCaptionLanguageId(), cctoken, wstr, sizeof( wstr ) / sizeof( wchar_t ) );
+
+ // Found one!!!
+ RECT rcEvent = event->getBounds();
+
+ float bestEndTime = max( e->GetEndTime(), e->GetLastSlaveEndTime() );
+ int pixeloffset = (int)( ( bestEndTime - e->GetStartTime() ) * m_pView->GetPixelsPerSecond() + 0.5f );
+
+ rcEvent.right = rcEvent.left + pixeloffset;
+ rcEvent.top = rcEventArea.top + m_nBaseHeight + AUDIO_HEIGHT + 5;
+ rcEvent.bottom = rcEvent.top + 12;
+ rcEvent.left += 5;
+
+ COLORREF textColor = valid ? RGB( 80, 80, 100 ) : RGB( 225, 40, 40 );
+
+ drawHelper.DrawColoredTextW( STREAM_FONT, m_pView->GetFontSize() - 2, 500,
+ textColor, rcEvent, wstr );
+
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : CChoreoChannel
+//-----------------------------------------------------------------------------
+CChoreoChannel *CChoreoChannelWidget::GetChannel( void )
+{
+ return m_pChannel;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *channel -
+//-----------------------------------------------------------------------------
+void CChoreoChannelWidget::SetChannel( CChoreoChannel *channel )
+{
+ m_pChannel = channel;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *event -
+//-----------------------------------------------------------------------------
+void CChoreoChannelWidget::AddEvent( CChoreoEventWidget *event )
+{
+ m_Events.AddToTail( event );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *event -
+//-----------------------------------------------------------------------------
+void CChoreoChannelWidget::RemoveEvent( CChoreoEventWidget *event )
+{
+ m_Events.FindAndRemove( event );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : num -
+// Output : CChoreoEventWidget
+//-----------------------------------------------------------------------------
+CChoreoEventWidget *CChoreoChannelWidget::GetEvent( int num )
+{
+ return m_Events[ num ];
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : int
+//-----------------------------------------------------------------------------
+int CChoreoChannelWidget::GetNumEvents( void )
+{
+ return m_Events.Size();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *event -
+//-----------------------------------------------------------------------------
+void CChoreoChannelWidget::MoveEventToTail( CChoreoEventWidget *event )
+{
+ for ( int i = 0; i < GetNumEvents(); i++ )
+ {
+ CChoreoEventWidget *ew = GetEvent( i );
+ if ( ew == event )
+ {
+ m_Events.Remove( i );
+ m_Events.AddToTail( ew );
+ break;
+ }
+ }
+}
+
+int CChoreoChannelWidget::GetChannelItemUnderMouse( int mx, int my )
+{
+ m_nSelectorEventIndex = -1;
+
+ if ( !m_bHasAudio )
+ return CLOSECAPTION_NONE;
+
+ RECT rcCCArea;
+ GetCloseCaptionExpandCollapseRect( rcCCArea );
+
+ POINT pt;
+ pt.x = mx;
+ pt.y = my;
+
+ if ( PtInRect( &rcCCArea, pt ) )
+ {
+ return CLOSECAPTION_EXPANDCOLLAPSE;
+ }
+
+ // previous
+ GetCloseCaptionLanguageRect( rcCCArea, true );
+ if ( PtInRect( &rcCCArea, pt ) )
+ {
+ return CLOSECAPTION_PREVLANGUAGE;
+ }
+
+ // next language
+ GetCloseCaptionLanguageRect( rcCCArea, false );
+ if ( PtInRect( &rcCCArea, pt ) )
+ {
+ return CLOSECAPTION_NEXTLANGUAGE;
+ }
+
+ CUtlVector< CloseCaptionInfo > vecSelectors;
+ GetCloseCaptions( vecSelectors );
+ int c = vecSelectors.Count();
+ if ( vecSelectors.Count() > 0 )
+ {
+ int i;
+ for ( i = 0; i < c; ++i )
+ {
+ CloseCaptionInfo& check = vecSelectors[ i ];
+ if ( check.isSelector && PtInRect( &check.rcSelector, pt ) )
+ {
+ m_nSelectorEventIndex = check.eventindex;
+ return CLOSECAPTION_SELECTOR;
+ }
+ }
+
+ for ( i = 0; i < c; ++i )
+ {
+ CloseCaptionInfo& check = vecSelectors[ i ];
+ if ( PtInRect( &check.rcCaption, pt ) )
+ {
+ m_nSelectorEventIndex = check.eventindex;
+ return CLOSECAPTION_CAPTION;
+ }
+ }
+ }
+
+ return CLOSECAPTION_NONE;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CChoreoChannelWidget::HandleSelectorClicked()
+{
+ if ( m_nSelectorEventIndex < 0 )
+ return;
+
+ if ( m_nSelectorEventIndex >= m_Events.Count() )
+ return;
+
+ CChoreoEvent *event = GetEvent( m_nSelectorEventIndex )->GetEvent();
+ SetUsingCombinedFieldByTokenName( event->GetCloseCaptionToken(), !event->IsUsingCombinedFile() );
+}
+
+void CChoreoChannelWidget::SetUsingCombinedFieldByTokenName( char const *token, bool usingcombinedfile )
+{
+ int c = GetNumEvents();
+ for ( int i = 0; i < c; ++i )
+ {
+ CChoreoEvent *e = GetEvent( i )->GetEvent();
+ if ( !Q_stricmp( e->GetCloseCaptionToken(), token ) )
+ {
+ e->SetUsingCombinedFile( usingcombinedfile );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : CChoreoEvent
+//-----------------------------------------------------------------------------
+CChoreoEvent *CChoreoChannelWidget::GetCaptionClickedEvent()
+{
+ if ( m_nSelectorEventIndex < 0 )
+ return NULL;
+
+ if ( m_nSelectorEventIndex >= m_Events.Count() )
+ return NULL;
+
+ CChoreoEvent *event = GetEvent( m_nSelectorEventIndex )->GetEvent();
+ return event;
+}
+
+void CChoreoChannelWidget::GetCloseCaptionExpandCollapseRect( RECT& rc )
+{
+ Assert( m_bHasAudio );
+
+ rc = getBounds();
+ rc.left = m_pView->GetLabelWidth() + 2;
+ rc.right = rc.left + 12;
+
+ rc.top += 2;
+ rc.bottom = rc.top + 12;
+}
+
+void CChoreoChannelWidget::GetCloseCaptionLanguageRect( RECT& rc, bool previous )
+{
+ Assert( m_bHasAudio );
+
+ RECT rcEventArea = getBounds();
+ rcEventArea.left = m_pView->GetLabelWidth() + 1;
+ rcEventArea.top -= 20;
+
+ rc = rcEventArea;
+ rc.top = rcEventArea.top + m_nBaseHeight + AUDIO_HEIGHT + 5;
+ rc.bottom = rc.top + 12;
+ rc.left += 2;
+ rc.right = rc.left + 12;
+
+ if ( !previous )
+ {
+ int textlen = CChoreoWidgetDrawHelper::CalcTextWidth
+ (
+ "Arial",
+ m_pView->GetFontSize()-2,
+ 500,
+ CSentence::NameForLanguage( GetCloseCaptionLanguageId() )
+ );
+
+ OffsetRect( &rc, textlen + 10, 0 );
+ }
+}
+
+void CChoreoChannelWidget::RenderCloseCaptionSelectors( CChoreoWidgetDrawHelper& drawHelper, RECT& rcEventArea )
+{
+ CUtlVector< CloseCaptionInfo > vecSelectors;
+ GetCloseCaptions( vecSelectors );
+ int c = vecSelectors.Count();
+ if ( vecSelectors.Count() > 0 )
+ {
+ for ( int i = 0; i < c; ++i )
+ {
+ CloseCaptionInfo& check = vecSelectors[ i ];
+
+ if ( !check.isSelector )
+ continue;
+
+ CChoreoEventWidget *e = GetEvent( check.eventindex );
+ if ( !e )
+ continue;
+
+ CChoreoEvent *event = e->GetEvent();
+
+ bool upArrow = !event->IsUsingCombinedFile();
+ COLORREF clr = RGB( 63, 63, 63 ); // upArrow ? RGB( 255, 0, 0 ) : RGB( 0, 0, 255 );
+
+ RECT rc = check.rcSelector;
+
+ POINT endpt;
+ endpt.x = rc.right - 2;
+
+ if ( upArrow )
+ {
+ endpt.y = rc.top - 9;
+ }
+ else
+ {
+ endpt.y = rc.bottom + 9;
+ }
+
+ POINT startpt;
+ startpt.x = ( rc.left + rc.right ) * 0.5;
+ startpt.y = ( rc.top + rc.bottom ) * 0.5;
+
+ drawHelper.DrawCircle(
+ clr,
+ endpt.x,
+ endpt.y,
+ 3 , true );
+
+ drawHelper.DrawColoredLine( clr, PS_SOLID, 1, startpt.x, startpt.y, endpt.x, endpt.y );
+
+
+ drawHelper.DrawCircle(
+ clr,
+ startpt.x,
+ startpt.y,
+ 7, true );
+ }
+ }
+}
+
+void CChoreoChannelWidget::GetCloseCaptions( CUtlVector< CloseCaptionInfo >& selectors )
+{
+ selectors.RemoveAll();
+
+ // Walk the events looking for SPEAK events (esp if marked as MASTER with >= 1 slave)
+ for ( int j = GetNumEvents()-1; j >= 0; j-- )
+ {
+ CChoreoEventWidget *event = GetEvent( j );
+ CChoreoEvent *e = event->GetEvent();
+
+ if ( e->GetType() != CChoreoEvent::SPEAK )
+ continue;
+
+ CChoreoEvent::CLOSECAPTION capType = e->GetCloseCaptionType();
+
+ if ( capType == CChoreoEvent::CC_SLAVE )
+ continue;
+
+ bool isSelector = ( e->GetNumSlaves() >= 1 ) && capType == CChoreoEvent::CC_MASTER;
+
+ // Found one!!!
+ RECT rcEvent = event->getBounds();
+ RECT rcCaption = rcEvent;
+
+ rcEvent.right = rcEvent.left + 16;
+ OffsetRect( &rcEvent, -16, rcEvent.bottom - rcEvent.top );
+ rcEvent.bottom = rcEvent.top + 16;
+
+ CloseCaptionInfo ccs;
+ ccs.rcSelector = rcEvent;
+ ccs.isSelector = isSelector;
+
+ rcCaption.top += rcEvent.bottom - rcEvent.top;
+
+ RECT rcEventArea = getBounds();
+
+ rcCaption.bottom = rcEventArea.bottom;
+
+ // Now compute true right edge
+ float bestEndTime = max( e->GetEndTime(), e->GetLastSlaveEndTime() );
+ int pixeloffset = (int)( ( bestEndTime - e->GetStartTime() ) * m_pView->GetPixelsPerSecond() + 0.5f );
+ rcCaption.right = rcCaption.left + pixeloffset;
+
+ ccs.rcCaption = rcCaption;
+
+ ccs.eventindex = j;
+ selectors.AddToTail( ccs );
+ }
+}
+
+
+void CChoreoChannelWidget::RenderCloseCaptionExpandCollapseRect( CChoreoWidgetDrawHelper& drawHelper, RECT& rcEventArea )
+{
+ if ( !m_bHasAudio )
+ return;
+
+ RECT rcCCArea;
+ GetCloseCaptionExpandCollapseRect( rcCCArea );
+
+ COLORREF symColor = RGB( 100, 100, 100 );
+
+ drawHelper.DrawColoredTextCharset(
+ "Marlett",
+ m_pView->GetFontSize(),
+ 900,
+ SYMBOL_CHARSET,
+ symColor,
+ rcCCArea,
+ m_pView->GetShowCloseCaptionData() ? "6" : "4" );
+}
+
+void CChoreoChannelWidget::GetMasterAndSlaves( CChoreoEvent *master, CUtlVector< CChoreoEvent * >& fulllist )
+{
+ // Old
+ int c = GetNumEvents();
+ int i;
+ for ( i = 0; i < c; ++i )
+ {
+ CChoreoEvent *e = GetEvent( i )->GetEvent();
+ if ( !Q_stricmp( master->GetCloseCaptionToken(), e->GetCloseCaptionToken() ) )
+ {
+ if ( fulllist.Find( e ) == fulllist.InvalidIndex() )
+ {
+ fulllist.AddToTail( e );
+ }
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : drawHelper -
+// rcBounds -
+//-----------------------------------------------------------------------------
+void CChoreoChannelWidget::redrawStatus( CChoreoWidgetDrawHelper& drawHelper, RECT& rcClient, int areaUnderMouse )
+{
+ if ( !getVisible() )
+ return;
+
+ if ( areaUnderMouse != CLOSECAPTION_CAPTION )
+ return;
+
+ CChoreoEvent *e = GetCaptionClickedEvent();
+ if ( !e )
+ return;
+
+ int deflateborder = 1;
+ int fontsize = 9;
+
+ // Now draw the label
+ RECT rcEventLabel;
+ rcEventLabel = rcClient;
+
+ InflateRect( &rcEventLabel, 0, -deflateborder );
+
+ // rcEventLabel.top += 2;
+ rcEventLabel.left += 2;
+ //rcEventLabel.top = rcEventLabel.bottom - 2 * ( fontsize + 2 ) - 1;
+ //rcEventLabel.bottom = rcEventLabel.top + fontsize + 2;
+
+ /*
+ HDC dc = drawHelper.GrabDC();
+
+ int leftAdd = 16;
+
+ if ( CChoreoEventWidget::GetImage( event->GetType() ) )
+ {
+ mxbitmapdata_t *image = CChoreoEventWidget::GetImage( event->GetType() );
+ if ( image )
+ {
+ RECT rcFixed = rcEventLabel;
+ drawHelper.OffsetSubRect( rcFixed );
+ DrawBitmapToDC( dc, rcFixed.left, rcFixed.top, leftAdd, leftAdd,
+ *image );
+ }
+ }
+
+ // Draw Type Name:
+ //rcEventLabel.top -= 4;
+
+ rcEventLabel.left = rcClient.left + 32;
+ rcEventLabel.bottom = rcEventLabel.top + fontsize + 2;
+ // OffsetRect( &rcEventLabel, 0, 2 );
+
+ int len = drawHelper.CalcTextWidth( "Arial", fontsize, FW_NORMAL, "%s event \"%s\"",
+ event->NameForType( event->GetType() ), event->GetName() );
+ drawHelper.DrawColoredText( "Arial", fontsize, FW_NORMAL, COLOR_INFO_TEXT, rcEventLabel, "%s event \"%s\"",
+ event->NameForType( event->GetType() ), event->GetName() );
+
+ OffsetRect( &rcEventLabel, 0, fontsize + 2 );
+
+ drawHelper.DrawColoredText( "Arial", fontsize, FW_NORMAL, COLOR_INFO_TEXT,
+ rcEventLabel, "parameters \"%s\"", GetLabelText() );
+ */
+
+ char const *label = "";
+
+ bool showState = false;
+ bool stateValid = false;
+
+ wchar_t wstr[ 1024 ];
+ COLORREF labelColor = COLOR_INFO_TEXT;
+
+ if ( e->GetCloseCaptionType() == CChoreoEvent::CC_MASTER )
+ {
+ showState = true;
+ if ( e->GetNumSlaves() >= 1 )
+ {
+ label = e->GetCloseCaptionToken();
+ }
+ else
+ {
+ label = e->GetParameters();
+ }
+ }
+ else if ( e->GetCloseCaptionType() == CChoreoEvent::CC_SLAVE )
+ {
+ showState = true;
+ label = e->GetCloseCaptionToken();
+ }
+ else
+ {
+ label = "-disabled-";
+ }
+
+ char cctoken[ CChoreoEvent::MAX_CCTOKEN_STRING ];
+ if ( showState && e->GetPlaybackCloseCaptionToken( cctoken, sizeof( cctoken ) ) )
+ {
+ stateValid = closecaptionmanager->LookupUnicodeText( GetCloseCaptionLanguageId(), cctoken, wstr, sizeof( wstr ) / sizeof( wchar_t ) );
+ }
+
+ RECT rcText = rcEventLabel;
+
+ rcText.left += 250;
+ rcText.bottom = rcText.top + fontsize + 1;
+
+ if ( showState )
+ {
+ int stateMarkWidth = 12;
+ RECT rcState = rcText;
+ rcState.right = rcState.left + stateMarkWidth;
+ rcText.left += stateMarkWidth;
+
+ COLORREF symColor = stateValid ? RGB( 40, 100, 40 ) : RGB( 200, 40, 40 );
+
+ drawHelper.DrawColoredTextCharset(
+ "Marlett",
+ fontsize+2,
+ 500,
+ SYMBOL_CHARSET,
+ symColor,
+ rcState,
+ stateValid ? "a" : "r" );
+
+ }
+
+ drawHelper.DrawColoredText( "Arial", fontsize, 500,
+ labelColor, rcText, "closecaption token: %s", label );
+
+ RECT saveText = rcText;
+
+ COLORREF statusClr = RGB( 20, 150, 20 );
+
+ if ( e->GetCloseCaptionType() != CChoreoEvent::CC_DISABLED )
+ {
+ if ( e->GetNumSlaves() >= 1 ||
+ e->GetCloseCaptionType() == CChoreoEvent::CC_SLAVE )
+ {
+
+ bool combinedValid = m_pView->ValidateCombinedSoundCheckSum( e );
+
+ OffsetRect( &rcText, 0, fontsize + 3 );
+
+ char cf[ 256 ];
+ Q_strncpy( cf, "(no file)", sizeof( cf ) );
+
+ // Get the filename, including expansion for gender
+ e->ComputeCombinedBaseFileName( cf, sizeof( cf ), e->IsCombinedUsingGenderToken() );
+ bool gendermacro = Q_stristr( cf, SOUNDGENDER_MACRO ) ? true : false;
+
+ char exist[ 256 ];
+
+ if ( gendermacro )
+ {
+ bool valid[2];
+ char actualfile[ 256 ];
+ soundemitter->GenderExpandString( GENDER_MALE, cf, actualfile, sizeof( actualfile ) );
+ valid[ 0 ] = filesystem->FileExists( actualfile );
+ soundemitter->GenderExpandString( GENDER_FEMALE, cf, actualfile, sizeof( actualfile ) );
+ valid[ 1 ] = filesystem->FileExists( actualfile );
+
+ if ( !valid[ 0 ] || !valid[ 1 ] )
+ {
+ statusClr = RGB( 255, 0, 0 );
+ }
+
+ Q_snprintf( exist, sizeof( exist ), "%s", valid ? "exist" : "missing!" );
+ }
+ else
+ {
+ bool valid = filesystem->FileExists( cf );
+ if ( !valid )
+ {
+ statusClr = RGB( 255, 0, 0 );
+ }
+
+ Q_snprintf( exist, sizeof( exist ), "%s", valid ? "exists" : "missing!" );
+ }
+
+ RECT rcPartial = rcText;
+
+ char sz[ 256 ];
+ Q_snprintf( sz, sizeof( sz ),
+ "combined file active [ %s ] gender[ %s ] up-to-date[ ",
+ e->IsUsingCombinedFile() ? "yes" : "no",
+ e->IsCombinedUsingGenderToken() ? "yes" : "no" );
+
+ int len = drawHelper.CalcTextWidth( "Arial", fontsize, 500, sz );
+
+ drawHelper.DrawColoredText( "Arial", fontsize, 500,
+ labelColor, rcPartial, sz );
+
+ rcPartial.left += len;
+
+ Q_snprintf( sz, sizeof( sz ),
+ "%s",
+ combinedValid ? "yes" : "no" );
+
+ len = drawHelper.CalcTextWidth( "Arial", fontsize, 500, sz );
+
+ drawHelper.DrawColoredText( "Arial", fontsize, 500,
+ combinedValid ? RGB( 20, 150, 20 ) : RGB( 255, 0, 0 ),
+ rcPartial, sz );
+
+ rcPartial.left += len;
+
+ Q_snprintf( sz, sizeof( sz ),
+ " ]: %s, %s ",
+ cf,
+ gendermacro ? "files" : "file" );
+
+ len = drawHelper.CalcTextWidth( "Arial", fontsize, 500, sz );
+
+ drawHelper.DrawColoredText( "Arial", fontsize, 500,
+ labelColor, rcPartial, sz );
+
+ rcPartial.left += len;
+
+ drawHelper.DrawColoredText( "Arial", fontsize, 500,
+ statusClr, rcPartial, exist );
+
+ }
+
+ rcText = saveText;
+
+ OffsetRect( &rcText, 400, 0 );
+
+ // Print out script file for sound
+ int soundindex = soundemitter->GetSoundIndex( cctoken );
+ if ( soundindex >= 0 )
+ {
+ char const *scriptfile = soundemitter->GetSourceFileForSound( soundindex );
+ Assert( scriptfile );
+ if ( scriptfile )
+ {
+ drawHelper.DrawColoredText( "Arial", fontsize, 500,
+ labelColor, rcText, "sound script: %s", scriptfile );
+ }
+ }
+ else
+ {
+ drawHelper.DrawColoredText( "Arial", fontsize, 500,
+ RGB( 255, 0, 0 ), rcText, "sound not in game_sounds script files!" );
+ }
+ }
+} \ No newline at end of file