Ejemplo n.º 1
0
int32 SPanel::PaintArrangedChildren( const FPaintArgs& Args, const FArrangedChildren& ArrangedChildren, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled  ) const
{
	// Because we paint multiple children, we must track the maximum layer id that they produced in case one of our parents
	// wants to an overlay for all of its contents.
	int32 MaxLayerId = LayerId;

	const FPaintArgs NewArgs = Args.WithNewParent(this);

	for (int32 ChildIndex = 0; ChildIndex < ArrangedChildren.Num(); ++ChildIndex)
	{
		const FArrangedWidget& CurWidget = ArrangedChildren[ChildIndex];

		bool bWereOverlapping;
		FSlateRect ChildClipRect = MyClippingRect.IntersectionWith(CurWidget.Geometry.GetClippingRect(), bWereOverlapping);
		
		if ( bWereOverlapping )
		{
			const int32 CurWidgetsMaxLayerId = CurWidget.Widget->Paint(NewArgs, CurWidget.Geometry, ChildClipRect, OutDrawElements, LayerId, InWidgetStyle, ShouldBeEnabled(bParentEnabled));
			MaxLayerId = FMath::Max(MaxLayerId, CurWidgetsMaxLayerId);
		}		
		
	}
	
	return MaxLayerId;
}
void SClippingHorizontalBox::OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const
{
	// If WrapButton hasn't been initialized, that means AddWrapButton() hasn't 
	// been called and this method isn't going to behave properly
	check(WrapButton.IsValid());

	SHorizontalBox::OnArrangeChildren(AllottedGeometry, ArrangedChildren);

	// Remove children that are clipped by the allotted geometry
	const int32 NumChildren = ArrangedChildren.Num(); 
	int32 IndexClippedAt = NumChildren;
	for (int32 ChildIdx = NumChildren - 2; ChildIdx >= 0; --ChildIdx)
	{
		const FArrangedWidget& CurWidget = ArrangedChildren[ChildIdx];
		if (FMath::TruncToInt(CurWidget.Geometry.AbsolutePosition.X + CurWidget.Geometry.Size.X * CurWidget.Geometry.Scale) > FMath::TruncToInt(AllottedGeometry.AbsolutePosition.X + AllottedGeometry.Size.X * CurWidget.Geometry.Scale))
		{
			ArrangedChildren.Remove(ChildIdx);
			IndexClippedAt = ChildIdx;
		}
	}

	if (IndexClippedAt == NumChildren)
	{
		// None of the children are being clipped, so remove the wrap button
		ArrangedChildren.Remove(ArrangedChildren.Num() - 1);
	}
	else
	{
		// Right align the wrap button
		FArrangedWidget& ArrangedButton = ArrangedChildren[ArrangedChildren.Num() - 1];
		ArrangedButton.Geometry = AllottedGeometry.MakeChild(ArrangedButton.Geometry.Size, FSlateLayoutTransform(AllottedGeometry.Size - ArrangedButton.Geometry.Size));
		const int32 WrapButtonXPosition = FMath::TruncToInt(ArrangedButton.Geometry.AbsolutePosition.X);

		// Further remove any children that the wrap button overlaps with
		for (int32 ChildIdx = IndexClippedAt - 1; ChildIdx >= 0; --ChildIdx)
		{
			const FArrangedWidget& CurWidget = ArrangedChildren[ChildIdx];
			if (FMath::TruncToInt(CurWidget.Geometry.AbsolutePosition.X + CurWidget.Geometry.Size.X * CurWidget.Geometry.Scale) > WrapButtonXPosition)
			{
				ArrangedChildren.Remove(ChildIdx);
			}
		}
	}
}
void FBehaviorTreeConnectionDrawingPolicy::Draw(TMap<TSharedRef<SWidget>, FArrangedWidget>& PinGeometries, FArrangedChildren& ArrangedNodes)
{
	// Build an acceleration structure to quickly find geometry for the nodes
	NodeWidgetMap.Empty();
	for (int32 NodeIndex = 0; NodeIndex < ArrangedNodes.Num(); ++NodeIndex)
	{
		FArrangedWidget& CurWidget = ArrangedNodes[NodeIndex];
		TSharedRef<SGraphNode> ChildNode = StaticCastSharedRef<SGraphNode>(CurWidget.Widget);
		NodeWidgetMap.Add(ChildNode->GetNodeObj(), NodeIndex);
	}

	// Now draw
	FConnectionDrawingPolicy::Draw(PinGeometries, ArrangedNodes);
}
Ejemplo n.º 4
0
int32 SWidget::FindChildUnderPosition( const FArrangedChildren& Children, const FVector2D& ArrangedSpacePosition )
{
	const int32 NumChildren = Children.Num();
	for( int32 ChildIndex=NumChildren-1; ChildIndex >= 0; --ChildIndex )
	{
		const FArrangedWidget& Candidate = Children[ChildIndex];
		const bool bCandidateUnderCursor = 
			// Candidate is physically under the cursor
			Candidate.Geometry.IsUnderLocation( ArrangedSpacePosition );

		if (bCandidateUnderCursor)
		{
			return ChildIndex;
		}
	}

	return INDEX_NONE;
}
Ejemplo n.º 5
0
void SGraphPanel::OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const
{
	SNodePanel::OnArrangeChildren(AllottedGeometry, ArrangedChildren);

	FArrangedChildren MyArrangedChildren(ArrangedChildren.GetFilter());
	for (int32 ChildIndex = 0; ChildIndex < ArrangedChildren.Num(); ++ChildIndex)
	{
		FArrangedWidget& CurWidget = ArrangedChildren[ChildIndex];
		TSharedRef<SGraphNode> ChildNode = StaticCastSharedRef<SGraphNode>(CurWidget.Widget);

		TArray<FOverlayWidgetInfo> OverlayWidgets = ChildNode->GetOverlayWidgets(false, CurWidget.Geometry.Size);

		for (int32 WidgetIndex = 0; WidgetIndex < OverlayWidgets.Num(); ++WidgetIndex)
		{
			FOverlayWidgetInfo& OverlayInfo = OverlayWidgets[WidgetIndex];

			MyArrangedChildren.AddWidget(AllottedGeometry.MakeChild( OverlayInfo.Widget.ToSharedRef(), CurWidget.Geometry.Position + OverlayInfo.OverlayOffset, OverlayInfo.Widget->GetDesiredSize(), GetZoomAmount() ));
		}
	}

	ArrangedChildren.Append(MyArrangedChildren);
}
Ejemplo n.º 6
0
/**
 * Move focus either forward on backward in the path level specified by PathLevel.
 * That is, this movement of focus will modify the subtree under Widgets(PathLevel).
 *
 * @param PathLevel       The level in this WidgetPath whose focus to move.
 * @param MoveDirectin    Move focus forward or backward?
 *
 * @return true if the focus moved successfully, false if we were unable to move focus
 */
bool FWidgetPath::MoveFocus(int32 PathLevel, EUINavigation NavigationType)
{
	check(NavigationType == EUINavigation::Next || NavigationType == EUINavigation::Previous);

	const int32 MoveDirectionAsInt = (NavigationType == EUINavigation::Next)
		? +1
		: -1;


	if ( PathLevel == Widgets.Num()-1 )
	{
		// We are the currently focused widget because we are at the very bottom of focus path.
		if (NavigationType == EUINavigation::Next)
		{
			// EFocusMoveDirection::Next implies descend, so try to find a focusable descendant.
			return ExtendPathTo( FFocusableWidgetMatcher() );
		}
		else
		{
			// EFocusMoveDirection::Previous implies move focus up a level.
			return false;
		}
		
	}
	else if ( Widgets.Num() > 1 )
	{
		// We are not the last widget in the path.
		// GOAL: Look for a focusable descendant to the left or right of the currently focused path.
	
		// Arrange the children so we can iterate through them regardless of widget type.
		FArrangedChildren ArrangedChildren(EVisibility::Visible);
		Widgets[PathLevel].Widget->ArrangeChildren( Widgets[PathLevel].Geometry, ArrangedChildren );

		// Find the currently focused child among the children.
		int32 FocusedChildIndex = ArrangedChildren.FindItemIndex( Widgets[PathLevel+1] );
		FocusedChildIndex = (FocusedChildIndex) % ArrangedChildren.Num() + MoveDirectionAsInt;

		// Now actually search for the widget.
		for( ; FocusedChildIndex < ArrangedChildren.Num() && FocusedChildIndex >= 0; FocusedChildIndex += MoveDirectionAsInt )
		{
			// Neither disabled widgets nor their children can be focused.
			if ( ArrangedChildren[FocusedChildIndex].Widget->IsEnabled() )
			{
				// Look for a focusable descendant.
				FArrangedChildren PathToFocusableChild = GeneratePathToWidget(FFocusableWidgetMatcher(), ArrangedChildren[FocusedChildIndex], NavigationType);
				// Either we found a focusable descendant, or an immediate child that is focusable.
				const bool bFoundNextFocusable = ( PathToFocusableChild.Num() > 0 ) || ArrangedChildren[FocusedChildIndex].Widget->SupportsKeyboardFocus();
				if ( bFoundNextFocusable )
				{
					// We found the next focusable widget, so make this path point at the new widget by:
					// First, truncating the FocusPath up to the current level (i.e. PathLevel).
					Widgets.Remove( PathLevel+1, Widgets.Num()-PathLevel-1 );
					// Second, add the immediate child that is focus or whose descendant is focused.
					Widgets.AddWidget( ArrangedChildren[FocusedChildIndex] );
					// Add path to focused descendants if any.
					Widgets.Append( PathToFocusableChild );
					// We successfully moved focus!
					return true;
				}
			}
		}		
		
	}

	return false;
}