예제 #1
0
void FHittestGrid::BeginFrame( const FSlateRect& HittestArea )
{
	//LogGrid();

	GridOrigin = HittestArea.GetTopLeft();
	const FVector2D GridSize = HittestArea.GetSize();
	NumCells = FIntPoint( FMath::CeilToInt(GridSize.X / CellSize.X), FMath::CeilToInt(GridSize.Y / CellSize.Y) );
	WidgetsCachedThisFrame->Empty();
	Cells.Reset( NumCells.X * NumCells.Y );	
	Cells.SetNum( NumCells.X * NumCells.Y );
}
예제 #2
0
int32 SSplitter::GetHandleBeingResizedFromMousePosition( float PhysicalSplitterHandleSize, float HitDetectionSplitterHandleSize, FVector2D LocalMousePos, const TArray<FLayoutGeometry>& ChildGeometries )
{
	const int32 AxisIndex = (SplitterOrientation == Orient_Horizontal) ? 0 : 1;
	const float HalfHitDetectionSplitterHandleSize = ( HitDetectionSplitterHandleSize / 2 );
	const float HalfPhysicalSplitterHandleSize = ( PhysicalSplitterHandleSize / 2 );

	// Search for the two widgets between which the cursor currently resides.
	for ( int32 ChildIndex = 1; ChildIndex < ChildGeometries.Num(); ++ChildIndex )
	{
		FSlateRect PrevChildRect = ChildGeometries[ChildIndex - 1].GetRectInParentSpace();
		FVector2D NextChildOffset = ChildGeometries[ChildIndex].GetOffsetInParentSpace();
		float PrevBound = PrevChildRect.GetTopLeft().Component(AxisIndex) + PrevChildRect.GetSize().Component(AxisIndex) - HalfHitDetectionSplitterHandleSize + HalfPhysicalSplitterHandleSize;
		float NextBound = NextChildOffset.Component(AxisIndex) + HalfHitDetectionSplitterHandleSize - HalfPhysicalSplitterHandleSize;

		if ( LocalMousePos.Component(AxisIndex) > PrevBound && LocalMousePos.Component(AxisIndex) < NextBound )
		{
			return ChildIndex - 1;
		}
	}

	return INDEX_NONE;
}
예제 #3
0
void SProfilerThreadView::DrawUIStackNodes() const
{
//	SCOPE_LOG_TIME_FUNC();
	check( PaintState );
	const double ThreadViewOffsetPx = PositionXMS*NumPixelsPerMillisecond;
	PaintState->LayerId++;

	static const FSlateBrush* BorderBrush = FEditorStyle::GetBrush( "Profiler.ThreadView.SampleBorder" );
	const FColor GameThreadColor = FColorList::Red;
	const FColor RenderThreadColor = FColorList::Blue;
	const FColor ThreadColors[2] = {GameThreadColor, RenderThreadColor};

	// Draw nodes.
	for( const auto& RowOfNodes : ProfilerUIStream.LinearRowsOfNodes )
	{
		int32 NodeIndex = 0;
		for( const auto& UIStackNode : RowOfNodes )
		{
			NodeIndex++;
			// Check if the node is visible.
			//if( UIStackNode->IsVisible() )
			{
				const FVector2D PositionPx = UIStackNode->GetLocalPosition( ThreadViewOffsetPx, PositionY ) * FVector2D( 1.0f, NUM_PIXELS_PER_ROW );
				const FVector2D SizePx = FVector2D( FMath::Max( UIStackNode->WidthPx - 1.0, 0.0 ), NUM_PIXELS_PER_ROW );
				const FSlateRect ClippedNodeRect = PaintState->LocalClippingRect.IntersectionWith( FSlateRect( PositionPx, PositionPx + SizePx ) );

				// Check if this node is inside the visible area.
				if( ClippedNodeRect.IsEmpty() )
				{
					continue;
				}

				FColor NodeColor = UIStackNode->bIsCombined ? ThreadColors[UIStackNode->ThreadIndex].WithAlpha( 64 ) : ThreadColors[UIStackNode->ThreadIndex].WithAlpha( 192 );
				NodeColor.G += NodeIndex % 2 ? 0 : 64;

				// Draw a cycle counter for this profiler UI stack node.
				FSlateDrawElement::MakeBox
				(
					PaintState->OutDrawElements,
					PaintState->LayerId,
					PaintState->AllottedGeometry.ToPaintGeometry( ClippedNodeRect.GetTopLeft(), ClippedNodeRect.GetSize() ),
					BorderBrush,
					PaintState->AbsoluteClippingRect,
					PaintState->DrawEffects,
					NodeColor
				);
			}
		}
	}

	// @TODO yrx 2014-04-29 Separate layer for makebox, makeshadowtext, maketext.
	PaintState->LayerId++;

	const float MarkerPosYOffsetPx = ((float)NUM_PIXELS_PER_ROW - PaintState->SummaryFont8Height)*0.5f;
	
	// Draw nodes' descriptions.
	for( const auto& RowOfNodes : ProfilerUIStream.LinearRowsOfNodes )
	{
		for( const auto& UIStackNode : RowOfNodes )
		{
			const FVector2D PositionPx = UIStackNode->GetLocalPosition( ThreadViewOffsetPx, PositionY ) * FVector2D( 1.0f, NUM_PIXELS_PER_ROW );
			const FVector2D SizePx = FVector2D( UIStackNode->WidthPx, NUM_PIXELS_PER_ROW );
			const FSlateRect ClippedNodeRect = PaintState->LocalClippingRect.IntersectionWith( FSlateRect( PositionPx, PositionPx + SizePx ) );

			// Check if this node is inside the visible area.
			if( ClippedNodeRect.IsEmpty() )
			{
				continue;
			}

			FString StringStatName = UIStackNode->StatName.GetPlainNameString();
			FString StringStatNameWithTime = StringStatName + FString::Printf( TEXT( " (%.4f MS)" ), UIStackNode->GetDurationMS() );
			if( UIStackNode->bIsCulled )
			{
				StringStatName += TEXT( " [C]" );
				StringStatNameWithTime += TEXT( " [C]" );
			}

			// Update position of the text to be always visible and try to center it.
			const float StatNameWidthPx = PaintState->FontMeasureService->Measure( StringStatName, PaintState->SummaryFont8 ).X;
			const float StatNameWithTimeWidthPx = PaintState->FontMeasureService->Measure( StringStatNameWithTime, PaintState->SummaryFont8 ).X;
			const float TextAreaWidthPx = ClippedNodeRect.GetSize().X;

			bool bUseShortVersion = true;
			FVector2D AdjustedPositionPx;
			// Center the stat name with timing if we can.
			if( TextAreaWidthPx > StatNameWithTimeWidthPx )
			{
				AdjustedPositionPx = FVector2D( ClippedNodeRect.Left + (TextAreaWidthPx - StatNameWithTimeWidthPx)*0.5f, PositionPx.Y + MarkerPosYOffsetPx );
				bUseShortVersion = false;
			}
			// Center the stat name.
			else if( TextAreaWidthPx > StatNameWidthPx )
			{
				AdjustedPositionPx = FVector2D( ClippedNodeRect.Left + (TextAreaWidthPx - StatNameWidthPx)*0.5f, PositionPx.Y + MarkerPosYOffsetPx );
			}
			// Move to the edge.
			else
			{
				AdjustedPositionPx = FVector2D( ClippedNodeRect.Left, PositionPx.Y + MarkerPosYOffsetPx );
			}

			const FVector2D AbsolutePositionPx = PaintState->AllottedGeometry.LocalToAbsolute( ClippedNodeRect.GetTopLeft() );
			const FSlateRect AbsoluteClippingRect = FSlateRect( AbsolutePositionPx, AbsolutePositionPx + ClippedNodeRect.GetSize() );
			
			DrawText( bUseShortVersion ? StringStatName : StringStatNameWithTime, PaintState->SummaryFont8, AdjustedPositionPx, FColorList::White, FColorList::Black, FVector2D( 1.0f, 1.0f ), &AbsoluteClippingRect );
		}
	}
}
예제 #4
0
void SProfilerThreadView::DrawFramesBackgroundAndTimelines() const
{
	static const FSlateColorBrush SolidWhiteBrush = FSlateColorBrush( FColorList::White );

	check( PaintState );
	const double ThreadViewOffsetPx = PositionXMS*NumPixelsPerMillisecond;
	PaintState->LayerId++;
	TArray<FVector2D> LinePoints;

	// Draw frames background for easier reading.
	for( const auto& ThreadNode : ProfilerUIStream.ThreadNodes )
	{
		if( ThreadNode.StatName == NAME_GameThread )
		{
			const FVector2D PositionPx = ThreadNode.GetLocalPosition( ThreadViewOffsetPx, -1.0f );
			const FVector2D SizePx = FVector2D( ThreadNode.WidthPx, PaintState->Size2D().Y );

			const FSlateRect ClippedFrameBackgroundRect = PaintState->LocalClippingRect.IntersectionWith( FSlateRect( PositionPx, PositionPx + SizePx ) );

			FSlateDrawElement::MakeBox
			(
				PaintState->OutDrawElements,
				PaintState->LayerId,
				PaintState->AllottedGeometry.ToPaintGeometry( ClippedFrameBackgroundRect.GetTopLeft(), ClippedFrameBackgroundRect.GetSize() ),
				&SolidWhiteBrush,
				PaintState->AbsoluteClippingRect,
				PaintState->DrawEffects,
				ThreadNode.FrameIndex % 2 ? FColorList::White.WithAlpha( 64 ) : FColorList::White.WithAlpha( 128 )
			);

			// Check if this frame time marker is inside the visible area.
			const float LocalPositionXPx = PositionPx.X + SizePx.X;
			if( LocalPositionXPx < 0.0f || LocalPositionXPx > PaintState->Size2D().X )
			{
				continue;
			}

			LinePoints.Reset( 2 );
			LinePoints.Add( FVector2D( LocalPositionXPx, 0.0f ) );
			LinePoints.Add( FVector2D( LocalPositionXPx, PaintState->Size2D().Y ) );

			// Draw frame time marker.
			FSlateDrawElement::MakeLines
			(
				PaintState->OutDrawElements,
				PaintState->LayerId,
				PaintState->AllottedGeometry.ToPaintGeometry(),
				LinePoints,
				PaintState->AbsoluteClippingRect,
				PaintState->DrawEffects,
				PaintState->WidgetStyle.GetColorAndOpacityTint() * FColorList::SkyBlue,
				false
			);
		}
	}

	PaintState->LayerId++;

	const double PositionXStartPx = FMath::TruncToFloat( PositionXMS*NumPixelsPerMillisecond / (double)NUM_PIXELS_BETWEEN_TIMELINE )*(double)NUM_PIXELS_BETWEEN_TIMELINE;
	const double PositionXEndPx = PositionXStartPx + RangeXMS*NumPixelsPerMillisecond;

	for( double TimelinePosXPx = PositionXStartPx; TimelinePosXPx < PositionXEndPx; TimelinePosXPx += (double)NUM_PIXELS_BETWEEN_TIMELINE )
	{
		LinePoints.Reset( 2 );
		LinePoints.Add( FVector2D( TimelinePosXPx - ThreadViewOffsetPx, 0.0f ) );
		LinePoints.Add( FVector2D( TimelinePosXPx - ThreadViewOffsetPx, PaintState->Size2D().Y ) );

		// Draw time line.
		FSlateDrawElement::MakeLines
		(
			PaintState->OutDrawElements,
			PaintState->LayerId,
			PaintState->AllottedGeometry.ToPaintGeometry(),
			LinePoints,
			PaintState->AbsoluteClippingRect,
			PaintState->DrawEffects,
			PaintState->WidgetStyle.GetColorAndOpacityTint() * FColorList::LimeGreen,
			false
		);
	}
}