void FSequencerTimeSliderController::DrawTicks( FSlateWindowElementList& OutDrawElements, const struct FScrubRangeToScreen& RangeToScreen, FDrawTickArgs& InArgs ) const
{
	float MinDisplayTickSpacing = ScrubConstants::MinDisplayTickSpacing;
	if (SequencerSnapValues::IsTimeSnapIntervalFrameRate(TimeSliderArgs.Settings->GetTimeSnapInterval()) && TimeSliderArgs.Settings->GetShowFrameNumbers())
	{
		MinDisplayTickSpacing = TimeSliderArgs.Settings->GetTimeSnapInterval();
	}

	const float Spacing = DetermineOptimalSpacing( RangeToScreen.PixelsPerInput, ScrubConstants::MinPixelsPerDisplayTick, MinDisplayTickSpacing );

	// Sub divisions
	// @todo Sequencer may need more robust calculation
	const int32 Divider = 10;
	// For slightly larger halfway tick mark
	const int32 HalfDivider = Divider / 2;
	// Find out where to start from
	int32 OffsetNum = FMath::FloorToInt(RangeToScreen.ViewInput.GetLowerBoundValue() / Spacing);
	
	FSlateFontInfo SmallLayoutFont( FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Regular.ttf"), 8 );

	TArray<FVector2D> LinePoints;
	LinePoints.AddUninitialized(2);

	float Seconds = 0;
	while( (Seconds = OffsetNum*Spacing) < RangeToScreen.ViewInput.GetUpperBoundValue() )
	{
		// X position local to start of the widget area
		float XPos = RangeToScreen.InputToLocalX( Seconds );
		uint32 AbsOffsetNum = FMath::Abs(OffsetNum);

		if ( AbsOffsetNum % Divider == 0 )
		{
			FVector2D Offset( XPos, InArgs.TickOffset );
			FVector2D TickSize( 0.0f, InArgs.MajorTickHeight );

			LinePoints[0] = FVector2D( 0.0f,1.0f);
			LinePoints[1] = TickSize;

			// lines should not need anti-aliasing
			const bool bAntiAliasLines = false;

			// Draw each tick mark
			FSlateDrawElement::MakeLines(
				OutDrawElements,
				InArgs.StartLayer,
				InArgs.AllottedGeometry.ToPaintGeometry( Offset, TickSize ),
				LinePoints,
				InArgs.ClippingRect,
				InArgs.DrawEffects,
				InArgs.TickColor,
				bAntiAliasLines
				);

			if( !InArgs.bOnlyDrawMajorTicks )
			{
				FString FrameString;
				if (SequencerSnapValues::IsTimeSnapIntervalFrameRate(TimeSliderArgs.Settings->GetTimeSnapInterval()) && TimeSliderArgs.Settings->GetShowFrameNumbers())
				{
					FrameString = FString::Printf( TEXT("%d"), TimeToFrame(Seconds));
				}
				else
				{
					FrameString = Spacing == ScrubConstants::MinDisplayTickSpacing ? FString::Printf( TEXT("%.3f"), Seconds ) : FString::Printf( TEXT("%.2f"), Seconds );
				}

				// Space the text between the tick mark but slightly above
				const TSharedRef< FSlateFontMeasure > FontMeasureService = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
				FVector2D TextSize = FontMeasureService->Measure(FrameString, SmallLayoutFont);
				FVector2D TextOffset( XPos + 5.f, InArgs.bMirrorLabels ? 3.f : FMath::Abs( InArgs.AllottedGeometry.Size.Y - (InArgs.MajorTickHeight+3.f) ) );
				FSlateDrawElement::MakeText(
					OutDrawElements,
					InArgs.StartLayer+1, 
					InArgs.AllottedGeometry.ToPaintGeometry( TextOffset, TextSize ), 
					FrameString, 
					SmallLayoutFont, 
					InArgs.ClippingRect, 
					InArgs.DrawEffects,
					InArgs.TickColor*0.65f 
				);
			}
		}
		else if( !InArgs.bOnlyDrawMajorTicks )
		{
			// Compute the size of each tick mark.  If we are half way between to visible values display a slightly larger tick mark
			const float MinorTickHeight = AbsOffsetNum % HalfDivider == 0 ? 6.0f : 2.0f;

			FVector2D Offset(XPos, InArgs.bMirrorLabels ? 0.0f : FMath::Abs( InArgs.AllottedGeometry.Size.Y - MinorTickHeight ) );
			FVector2D TickSize(0.0f, MinorTickHeight);

			LinePoints[0] = FVector2D(0.0f,1.0f);
			LinePoints[1] = TickSize;

			const bool bAntiAlias = false;
			// Draw each sub mark
			FSlateDrawElement::MakeLines(
				OutDrawElements,
				InArgs.StartLayer,
				InArgs.AllottedGeometry.ToPaintGeometry( Offset, TickSize ),
				LinePoints,
				InArgs.ClippingRect,
				InArgs.DrawEffects,
				InArgs.TickColor,
				bAntiAlias
			);
		}
		// Advance to next tick mark
		++OffsetNum;
	}
}
int32 FSequencerTimeSliderController::OnPaintTimeSlider( bool bMirrorLabels, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const
{
	const bool bEnabled = bParentEnabled;
	const ESlateDrawEffect::Type DrawEffects = bEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect;

	TRange<float> LocalViewRange = TimeSliderArgs.ViewRange.Get();
	const float LocalViewRangeMin = LocalViewRange.GetLowerBoundValue();
	const float LocalViewRangeMax = LocalViewRange.GetUpperBoundValue();
	const float LocalSequenceLength = LocalViewRangeMax-LocalViewRangeMin;
	
	FVector2D Scale = FVector2D(1.0f,1.0f);
	if ( LocalSequenceLength > 0)
	{
		FScrubRangeToScreen RangeToScreen( LocalViewRange, AllottedGeometry.Size );
	
		const float MajorTickHeight = 9.0f;
	
		FDrawTickArgs Args;
		Args.AllottedGeometry = AllottedGeometry;
		Args.bMirrorLabels = bMirrorLabels;
		Args.bOnlyDrawMajorTicks = false;
		Args.TickColor = FLinearColor::White;
		Args.ClippingRect = MyClippingRect;
		Args.DrawEffects = DrawEffects;
		Args.StartLayer = LayerId;
		Args.TickOffset = bMirrorLabels ? 0.0f : FMath::Abs( AllottedGeometry.Size.Y - MajorTickHeight );
		Args.MajorTickHeight = MajorTickHeight;

		DrawTicks( OutDrawElements, RangeToScreen, Args );

		FPaintPlaybackRangeArgs PlaybackRangeArgs(
			bMirrorLabels ? FEditorStyle::GetBrush("Sequencer.Timeline.PlayRange_Bottom_L") : FEditorStyle::GetBrush("Sequencer.Timeline.PlayRange_Top_L"),
			bMirrorLabels ? FEditorStyle::GetBrush("Sequencer.Timeline.PlayRange_Bottom_R") : FEditorStyle::GetBrush("Sequencer.Timeline.PlayRange_Top_R"),
			6.f
		);
		LayerId = DrawPlaybackRange(AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, RangeToScreen, PlaybackRangeArgs);

		float HalfSize = FMath::CeilToFloat(ScrubHandleSize/2.0f);

		// Draw the scrub handle
		float XPos = RangeToScreen.InputToLocalX( TimeSliderArgs.ScrubPosition.Get() );

		// Should draw above the text
		const int32 ArrowLayer = LayerId + 2;
		FPaintGeometry MyGeometry =	AllottedGeometry.ToPaintGeometry( FVector2D( XPos-HalfSize, 0 ), FVector2D( ScrubHandleSize, AllottedGeometry.Size.Y ) );
		FLinearColor ScrubColor = InWidgetStyle.GetColorAndOpacityTint();

		// @todo Sequencer this color should be specified in the style
		ScrubColor.A = ScrubColor.A*0.75f;
		ScrubColor.B *= 0.1f;
		ScrubColor.G *= 0.2f;
		FSlateDrawElement::MakeBox( 
			OutDrawElements,
			ArrowLayer, 
			MyGeometry,
			bMirrorLabels ? ScrubHandleUp : ScrubHandleDown,
			MyClippingRect, 
			DrawEffects, 
			ScrubColor
			);

		// Draw the current time next to the scrub handle
		float Time = TimeSliderArgs.ScrubPosition.Get();

		FString FrameString;
		if (SequencerSnapValues::IsTimeSnapIntervalFrameRate(TimeSliderArgs.Settings->GetTimeSnapInterval()) && TimeSliderArgs.Settings->GetShowFrameNumbers())
		{
			float FrameRate = 1.0f/TimeSliderArgs.Settings->GetTimeSnapInterval();
			float FrameTime = Time * FrameRate;
			int32 Frame = SequencerHelpers::TimeToFrame(Time, FrameRate);
					
			const float FrameTolerance = 0.001f;
			if (FMath::IsNearlyEqual(FrameTime, (float)Frame, FrameTolerance))
			{
				FrameString = FString::Printf( TEXT("%d"), TimeToFrame(Time));
			}
			else
			{
				FrameString = FString::Printf( TEXT("%.3f"), FrameTime);
			}
		}
		else
		{
			FrameString = FString::Printf( TEXT("%.2f"), Time );
		}

		FSlateFontInfo SmallLayoutFont( FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Regular.ttf"), 10 );

		const TSharedRef< FSlateFontMeasure > FontMeasureService = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
		FVector2D TextSize = FontMeasureService->Measure(FrameString, SmallLayoutFont);

		// Flip the text position if getting near the end of the view range
		if ((AllottedGeometry.Size.X - XPos) < (TextSize.X + 14.f))
		{
			XPos = XPos - TextSize.X - 12.f;
		}
		else
		{
			XPos = XPos + 10.f;
		}

		FVector2D TextOffset( XPos,  Args.bMirrorLabels ? TextSize.Y-6.f : Args.AllottedGeometry.Size.Y - (Args.MajorTickHeight+TextSize.Y) );

		FSlateDrawElement::MakeText(
			OutDrawElements,
			Args.StartLayer+1, 
			Args.AllottedGeometry.ToPaintGeometry( TextOffset, TextSize ), 
			FrameString, 
			SmallLayoutFont, 
			Args.ClippingRect, 
			Args.DrawEffects,
			Args.TickColor 
		);
		
		if (MouseDragType == DRAG_SETTING_RANGE)
		{
			float MouseStartPosX = RangeToScreen.InputToLocalX(MouseDownRange[0]);
			float MouseEndPosX = RangeToScreen.InputToLocalX(MouseDownRange[1]);

			float RangePosX = MouseStartPosX < MouseEndPosX ? MouseStartPosX : MouseEndPosX;
			float RangeSizeX = FMath::Abs(MouseStartPosX - MouseEndPosX);

			FSlateDrawElement::MakeBox(
				OutDrawElements,
				LayerId+1,
				AllottedGeometry.ToPaintGeometry( FVector2D(RangePosX, 0.f), FVector2D(RangeSizeX, AllottedGeometry.Size.Y) ),
				bMirrorLabels ? ScrubHandleDown : ScrubHandleUp,
				MyClippingRect,
				DrawEffects,
				MouseStartPosX < MouseEndPosX ? FLinearColor(0.5f, 0.5f, 0.5f) : FLinearColor(0.25f, 0.3f, 0.3f)
			);
		}

		return ArrowLayer;
	}

	return LayerId;
}
Beispiel #3
0
int TextProc(
/************************************************************************/
HWND 	hWindow,
LPARAM 	lParam,
UINT 	msg)
{
int x, y;
BOOL fCancel = NO;
WORD wKey;
STRING szString;
static BOOL bTrackObject;
static int xMove, yMove;

if ( bTrackObject )
	{
	ToyProc( hWindow, lParam, msg );
	bTrackObject = Tool.bActive;
	Tool.bActive = YES;
	return( TRUE );
	}

x = LOWORD( lParam );
y = HIWORD( lParam );
switch (msg)
    {
    case WM_CREATE:	// The first mouse down message
	Tool.bActive = YES;
	break; // Never get sent since Tool.bActive is already set in the dialog

    case WM_LBUTTONDOWN:
	// Call the sticker mover tool first to see if he wants to take over
	Tool.bActive = NO;
	ToyProc( hWindow, lParam, WM_CREATE );
	if ( bTrackObject = Tool.bActive )
		{
		ToyProc( hWindow, lParam, msg );
		break;
		}
	if ( bTextBegun )
		Tool.bActive = YES;
	xMove = x;
	yMove = y;
//	TextMove(hWindow, x, y);
	break;

    case WM_LBUTTONUP:
	break;

	case WM_SETCURSOR:
	return( SetToolCursor( hWindow, ID_MOVE_OBJECT, ID_PLAY_OBJECT ) );

    case WM_MOUSEMOVE:	// sent when ToolActive is on
	if ( Tool.bActive && Window.fLButtonDown )
		TextOffset(hWindow, x - xMove, y - yMove);
	xMove = x;
	yMove = y;
	break;

    case WM_KILLFOCUS:
	break;

    case WM_SETFOCUS:
//	TextDisplayCaret( hWindow, NULL );
	break;

    case WM_CHAR:
	wKey = (WORD)lParam;
	TextKeystroke(hWindow, wKey);
	if ( wKey == VK_RETURN )
		{
		TextAnchor( hWindow );
		RandomizeActiveColor();
		break;
		}
	szString[0] = '_';
	szString[1] = wKey;
	szString[2] = '\0';
	Lowercase( szString );
	SoundStartResource( szString, NO/*bLoop*/, NULL/*hInstance*/ );
	break;

    case WM_KEYDOWN:
	wKey = lParam;
	switch (wKey)
		{
		case VK_UP:
			TextRMove(hWindow, 0, -1);
			break;
		case VK_DOWN:
			TextRMove(hWindow, 0, 1);
			break;
		case VK_LEFT:
			TextRMove(hWindow, -1, 0);
			break;
		case VK_RIGHT:
			TextRMove(hWindow, 1, 0);
			break;
		default:
			break;
		}
	break;

    case WM_DESTROY:	// The cancel and DeactivateTool() message
	fCancel = (lParam == 1L);
	if ( fCancel )
		{ // an "escape" cancel
		TextKeystroke( hWindow, VK_ESCAPE );
		}
	else
		{ // a deactivate
		TextKeystroke( hWindow, VK_RETURN );
		TextAnchor( hWindow );
		RandomizeActiveColor();
		HideCaret( hWindow );
		DestroyCaret();
		AstralUpdateWindow( hWindow );
		}
	break;

    case WM_LBUTTONDBLCLK:
	break;
    }
return(TRUE);
}