Torque3D Documentation / _generateds / VTimeLineControl.cpp

VTimeLineControl.cpp

Engine/source/Verve/GUI/VTimeLineControl.cpp

More...

Public Variables

Public Functions

DefineEngineMethod(VTimeLineControl , getSelection , const char * , () , "( )" )
DefineEngineMethod(VTimeLineControl , setSelection , void , (bool active, S32 time, S32 duration) , (true, -1, 1) , "( pActive, [pTime, pDuration] )" )
DefineEngineMethod(VTimeLineControl , toPoint , S32 , (S32 time) , (0) , "( pTime )" )
DefineEngineMethod(VTimeLineControl , toTime , S32 , (S32 point) , (0) , "( pPoint )" )
DefineEngineMethod(VTimeLineControl , updateDuration , void , () , "( )" )

Detailed Description

Public Variables

const S32 gUnitsPerSec 

Public Functions

DefineEngineMethod(VTimeLineControl , getSelection , const char * , () , "( )" )

DefineEngineMethod(VTimeLineControl , setSelection , void , (bool active, S32 time, S32 duration) , (true, -1, 1) , "( pActive, [pTime, pDuration] )" )

DefineEngineMethod(VTimeLineControl , toPoint , S32 , (S32 time) , (0) , "( pTime )" )

DefineEngineMethod(VTimeLineControl , toTime , S32 , (S32 point) , (0) , "( pPoint )" )

DefineEngineMethod(VTimeLineControl , updateDuration , void , () , "( )" )

IMPLEMENT_CONOBJECT(VTimeLineControl )

  1
  2//-----------------------------------------------------------------------------
  3// Verve
  4// Copyright (C) 2014 - Violent Tulip
  5//
  6// Permission is hereby granted, free of charge, to any person obtaining a copy
  7// of this software and associated documentation files (the "Software"), to
  8// deal in the Software without restriction, including without limitation the
  9// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 10// sell copies of the Software, and to permit persons to whom the Software is
 11// furnished to do so, subject to the following conditions:
 12//
 13// The above copyright notice and this permission notice shall be included in
 14// all copies or substantial portions of the Software.
 15//
 16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 21// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 22// IN THE SOFTWARE.
 23//-----------------------------------------------------------------------------
 24#include "Verve/GUI/VTimeLineControl.h"
 25#include "console/consoleTypes.h"
 26#include "gfx/gfxDrawUtil.h"
 27#include "gui/core/guiCanvas.h"
 28
 29//-----------------------------------------------------------------------------
 30
 31const S32 gUnitsPerSec = 200;
 32
 33//-----------------------------------------------------------------------------
 34IMPLEMENT_CONOBJECT( VTimeLineControl );
 35//-----------------------------------------------------------------------------
 36
 37VTimeLineControl::VTimeLineControl( void ) :
 38        mIsController( true ),
 39        mController( NULL ),
 40        mDurationOffset( 50 )
 41{
 42    mSelection.Active    = false;
 43    mSelection.StartTime = 0;
 44    mSelection.EndTime   = 0;
 45}
 46
 47void VTimeLineControl::initPersistFields( void )
 48{
 49    Parent::initPersistFields();
 50
 51    addField( "IsController",   TypeBool,              Offset( mIsController,   VTimeLineControl ) );
 52    addField( "Controller",     TYPEID<VController>(), Offset( mController,     VTimeLineControl ) );
 53    addField( "DurationOffset", TypeS32,               Offset( mDurationOffset, VTimeLineControl ) );
 54}
 55
 56//-----------------------------------------------------------------------------
 57//
 58// Mouse Methods.
 59//
 60//-----------------------------------------------------------------------------
 61
 62void VTimeLineControl::onMouseDown( const GuiEvent &pEvent )
 63{
 64    Parent::onMouseDown( pEvent );
 65
 66    if ( !mIsController || !mController || mController->isPlaying() )
 67    {
 68        return;
 69    }
 70
 71    if ( !isMouseLocked() )
 72    {
 73        GuiCanvas *canvas = getRoot();
 74        if ( canvas->getMouseLockedControl() )
 75        {
 76            GuiEvent event;
 77            canvas->getMouseLockedControl()->onMouseLeave( event );
 78            canvas->mouseUnlock( canvas->getMouseLockedControl() );
 79        }
 80
 81        // Lock.
 82        mouseLock();
 83    }
 84
 85    // Calculate Time.
 86    const Point2I hitPoint = globalToLocalCoord( pEvent.mousePoint );
 87    const S32     time     = mClamp( toTime( hitPoint.x ), 0, mController->getDuration() );
 88
 89    // Selection?
 90    if (  pEvent.modifier & SI_SHIFT )
 91    {
 92        if ( !mSelection.Active )
 93        {
 94            // Selection Active.
 95            mSelection.Active    = true;
 96            mSelection.StartTime = mController->getTime();
 97            mSelection.EndTime   = time;
 98        }
 99        else
100        {
101            // Update Selection.
102            mSelection.EndTime = time;
103        }
104
105        // Callback.
106        Con::executef( this, "onSelectionUpdate" );
107    }
108    else
109    {
110        if ( mSelection.Active )
111        {
112            // Selection Invalid.
113            mSelection.Active = false;
114
115            // Callback.
116            Con::executef( this, "onSelectionUpdate" );
117        }
118    }
119
120    // Set First Responder.
121    setFirstResponder();
122
123    if ( pEvent.modifier & SI_CTRL )
124    {
125        // Set Time, No Reset.
126        mController->setTime( time );
127    }
128    else
129    {
130        // Reset.
131        mController->reset( time );
132    }
133}
134
135void VTimeLineControl::onMouseUp( const GuiEvent &pEvent )
136{
137    if ( isMouseLocked() )
138    {
139        // Unlock.
140        mouseUnlock();
141    }
142
143    if ( mIsController && mController && !mController->isPlaying() )
144    {
145        // Stop without Reset.
146        mController->stop( false );
147    }
148}
149
150void VTimeLineControl::onMouseDragged( const GuiEvent &pEvent )
151{
152    Parent::onMouseDragged( pEvent );
153
154    if ( !mIsController || !mController || mController->isPlaying() )
155    {
156        return;
157    }
158
159    // Calculate Time.
160    const Point2I hitPoint = globalToLocalCoord( pEvent.mousePoint );
161    const S32     time     = mClamp( toTime( hitPoint.x ), 0, mController->getDuration() );
162
163    if (  pEvent.modifier & SI_SHIFT )
164    {
165        if ( mSelection.Active )
166        {
167            // Update Selection.
168            mSelection.EndTime = time;
169
170            // Callback.
171            Con::executef( this, "onSelectionUpdate" );
172        }
173    }
174    else
175    {
176        if ( mSelection.Active )
177        {
178            // Selection Invalid.
179            mSelection.Active = false;
180
181            // Callback.
182            Con::executef( this, "onSelectionUpdate" );
183        }
184    }
185
186    if ( pEvent.modifier & SI_CTRL )
187    {
188        // Set Time, No Reset.
189        mController->setTime( time );
190    }
191    else if ( !mSelection.Active )
192    {
193        // Reset.
194        mController->reset( time );
195    }
196}
197
198void VTimeLineControl::onRightMouseDown( const GuiEvent &pEvent )
199{
200    Parent::onRightMouseDown( pEvent );
201
202    if ( !mIsController || !mController || mController->isPlaying() )
203    {
204        return;
205    }
206
207    // Calculate Time.
208    const Point2I hitPoint = globalToLocalCoord( pEvent.mousePoint );
209    const S32     time     = mClamp( toTime( hitPoint.x ), 0, mController->getDuration() );
210
211    // Set First Responder.
212    setFirstResponder();
213
214    if ( mSelection.Active )
215    {
216        const S32 minTime = getMin( mSelection.StartTime, mSelection.EndTime );
217        const S32 maxTime = getMax( mSelection.StartTime, mSelection.EndTime );
218        if ( time >= minTime && time <= maxTime )
219        {
220            // Callback.
221            onMouseEvent( "onSelectionRightClick", pEvent );
222
223            // Don't Update Time.
224            return;
225        }
226        else
227        {
228            if ( mSelection.Active )
229            {
230                // Selection Invalid.
231                mSelection.Active = false;
232
233                // Callback.
234                Con::executef( this, "onSelectionUpdate" );
235            }
236        }
237    }
238
239    // Reset.
240    mController->reset( time );
241}
242
243void VTimeLineControl::onMouseEvent( const char *pEventName, const GuiEvent &pEvent )
244{
245    // Argument Buffers.
246    char argBuffer[3][32];
247
248    // Format Event-Position Buffer.
249    dSprintf( argBuffer[0], 32, "%d %d", pEvent.mousePoint.x, pEvent.mousePoint.y );
250
251    // Format Event-Modifier Buffer.
252    dSprintf( argBuffer[1], 32, "%d", pEvent.modifier );
253
254    // Format Mouse-Click Count Buffer.
255    dSprintf( argBuffer[2], 32, "%d", pEvent.mouseClickCount );
256
257    // Call Scripts.
258    Con::executef( this, pEventName, argBuffer[0], argBuffer[1], argBuffer[2] );
259}
260
261//-----------------------------------------------------------------------------
262//
263// Render Methods.
264//
265//-----------------------------------------------------------------------------
266
267void VTimeLineControl::onPreRender( void )
268{
269    setUpdate();
270}
271
272void VTimeLineControl::onRender( Point2I offset, const RectI &updateRect )
273{
274    if ( !mController )
275    {
276        // Default Render.
277        Parent::onRender( offset, updateRect );
278
279        // Quit.
280        return;
281    }
282
283    // Render Properties.
284    const S32 tickOffset        = toPoint( 0 );
285    const S32 timeLineWidth     = toPoint( mController->getDuration() ) - tickOffset;
286    const F32 tickStep          = 0.5f;
287    const S32 tickInterval      = ( mIsController ) ? getWidth() : timeLineWidth;
288    const S32 tickIntervalCount = ( S32 )mFloor( tickInterval / ( gUnitsPerSec * tickStep ) ) + 1;
289
290    // Tick Render Proeprties.
291    const Point2I tickExtent( 0, getHeight() - 1 );
292
293    // Text Render Properties.
294    const Point2I textExtent( gUnitsPerSec, mProfile->mFontSize );
295    const Point2I textOffset( 4, -mProfile->mFontSize );
296
297    // Render Border.
298    GFX->getDrawUtil()->drawRectFill( RectI( offset + Point2I( tickOffset + 1, 1 ), Point2I( timeLineWidth - 1, getHeight() - 1 ) ), mProfile->mFillColorHL );
299    
300    // Font Color.
301    GFX->getDrawUtil()->setBitmapModulation( mProfile->mFontColor );
302
303    for ( S32 i = 0; i < tickIntervalCount; i++ )
304    {
305        // Tick Position.
306        const Point2I tickPosition = offset + Point2I( tickOffset + i * ( gUnitsPerSec * tickStep ), 0 );
307
308        // Line Color.
309        const ColorI lineColor = ( ( i % 2 ) ) ? mProfile->mBorderColorHL : mProfile->mBorderColor;
310
311        // Draw Line.
312        GFX->getDrawUtil()->drawLine( tickPosition, tickPosition + tickExtent, lineColor );
313
314        if ( mIsController )
315        {
316            // Render Times.
317            renderJustifiedText( tickPosition + tickExtent + textOffset, textExtent, avar( "%.2f", ( F32 )( i * tickStep ) ) );
318        }
319    }
320
321    // Render Children
322    renderChildControls( offset, updateRect );
323
324    if ( mSelection.Active )
325    {
326        // Selection Width.
327        const S32 selectionWidth = mCeil( mAbs( toPoint( mSelection.EndTime ) - toPoint( mSelection.StartTime ) ) );
328        
329        // Selection Position.
330        const S32 selectionPositionX = toPoint( getMin( mSelection.StartTime, mSelection.EndTime ) );
331
332        // Selection Properties.
333        const Point2I selectionExtent( selectionWidth, getHeight() );
334        const Point2I selectionPosition = offset + Point2I( selectionPositionX, 0 );
335
336        // Render Time Cue.
337        GFX->getDrawUtil()->drawRectFill( RectI( selectionPosition, selectionExtent ), ColorI( 0, 0, 0, 128 ) );
338
339        if ( mIsController )
340        {
341            // Buffer.
342            char buffer[2][128];
343            dSprintf( buffer[0], 128, "%.2f", ( F32 )( mSelection.StartTime / 1000.f ) );
344            dSprintf( buffer[1], 128, "%.2f", ( F32 )( mSelection.EndTime / 1000.f ) );
345
346            if ( mSelection.StartTime < mSelection.EndTime )
347            {
348                // Fetch Width.
349                const S32 textWidth = mProfile->mFont->getStrWidth( buffer[0] );
350
351                // Text Position.
352                const Point2I startText = Point2I( getMax( ( S32 )( selectionPosition.x - ( textWidth + 2 ) ), updateRect.point.x + 4 ), selectionPosition.y + 2 );
353                const Point2I endText   = Point2I( getMin( ( S32 )( selectionPosition.x + selectionWidth + 4 ), updateRect.point.x + updateRect.extent.x - ( textWidth + 2 ) ), selectionPosition.y + 2 );
354
355                // Render Time Text.
356                renderJustifiedText( startText, textExtent, buffer[0] );
357                renderJustifiedText( endText, textExtent, buffer[1] );
358            }
359            else
360            {
361                // Fetch Width.
362                const S32 textWidth = mProfile->mFont->getStrWidth( buffer[1] );
363
364                // Text Position.
365                const Point2I startText = Point2I( getMax( ( S32 )( selectionPosition.x - ( textWidth + 2 ) ), updateRect.point.x + 4 ), selectionPosition.y + 2 );
366                const Point2I endText   = Point2I( getMin( ( S32 )( selectionPosition.x + selectionWidth + 4 ), updateRect.point.x + updateRect.extent.x - ( textWidth + 2 ) ), selectionPosition.y + 2 );
367
368                // Render Time Text.
369                renderJustifiedText( startText, textExtent, buffer[1] );
370                renderJustifiedText( endText, textExtent, buffer[0] );
371            }
372        }
373    }
374
375    if ( mController && !mSelection.Active )
376    {
377        // Time Cue Properties.
378        const Point2I timeCueExtent( ( mIsController ) ? 4 : 2, getHeight() );
379        const Point2I timeCuePosition = offset + Point2I( toPoint( mController->getTime() ) - ( timeCueExtent.x / 2 ), 0 );
380
381        // Render Time Cue.
382        GFX->getDrawUtil()->drawRectFill( RectI( timeCuePosition, timeCueExtent ), ColorI( 0,0,0,128 ) );
383
384        if ( mIsController )
385        {
386            // Buffer.
387            char buffer[128];
388            dSprintf( buffer, 128, "%.2f", ( F32 )( mController->getTime() / 1000.f ) );
389
390            // Fetch Width.
391            const S32 textWidth = mProfile->mFont->getStrWidth( buffer );
392
393            // Text Position.
394            const Point2I textPosition( getMin( getMax( timeCuePosition.x + 6, updateRect.point.x + 4 ), updateRect.point.x + updateRect.extent.x - ( textWidth + 2 ) ), timeCuePosition.y + 2 );
395
396            // Render Time Text.
397            renderJustifiedText( textPosition, textExtent, buffer );
398        }
399    }
400}
401
402//-----------------------------------------------------------------------------
403//
404// Console Methods.
405//
406//-----------------------------------------------------------------------------
407
408DefineEngineMethod( VTimeLineControl, toPoint, S32, (S32 time), (0), "( pTime )" )
409{
410    return object->toPoint(time);
411}
412
413S32 VTimeLineControl::toTime( const S32 &pPoint )
414{
415    return ( ( S32 )( 1000.f * ( F32 )pPoint / gUnitsPerSec ) - mDurationOffset );
416}
417
418DefineEngineMethod( VTimeLineControl, toTime, S32, (S32 point), (0), "( pPoint )" )
419{
420    return object->toTime(point);
421}
422
423S32 VTimeLineControl::toPoint( const S32 &pTime )
424{
425    return ( S32 )( gUnitsPerSec * ( ( F32 )( pTime + mDurationOffset ) / 1000.f ) );
426}
427
428DefineEngineMethod( VTimeLineControl, getSelection, const char *, (),, "( )" )
429{
430    const S32 minTime = getMin( object->mSelection.StartTime, object->mSelection.EndTime );
431    const S32 maxTime = getMax( object->mSelection.StartTime, object->mSelection.EndTime );
432
433    // Fetch Return Buffer.
434    char *retBuffer = Con::getReturnBuffer( 256 );
435
436    // Write.
437    dSprintf( retBuffer, 256, "%d %d %d", object->mSelection.Active, minTime, maxTime - minTime );
438
439    // Return.
440    return retBuffer;
441}
442
443DefineEngineMethod( VTimeLineControl, setSelection, void, (bool active, S32 time, S32 duration), (true, -1, 1), "( pActive, [pTime, pDuration] )" )
444{
445    object->mSelection.Active = active;
446    if (time != -1)
447    {
448        object->mSelection.StartTime = time;
449        object->mSelection.EndTime   = object->mSelection.StartTime + duration;
450    }
451}
452
453DefineEngineMethod( VTimeLineControl, updateDuration, void, (),, "( )" )
454{
455    object->updateDuration();
456}
457
458void VTimeLineControl::updateDuration( void )
459{
460    if ( !mController )
461    {
462        // No Controller.
463        return;
464    }
465
466    // Add 500ms.
467    const S32 length = toPoint( mController->getDuration() + 500 );
468
469    // Set Min Extent.
470    setMinExtent( Point2I( length, getHeight() ) );
471
472    if ( getWidth() < length )
473    {
474        // Conform to Min Extent.
475        setExtent( length, getHeight() );
476    }
477}
478