diff options
Diffstat (limited to 'utils/hlfaceposer/choreochannelwidget.cpp')
| -rw-r--r-- | utils/hlfaceposer/choreochannelwidget.cpp | 1207 |
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 |