static bool FindWidgetsUnderPoint(const FVector2D& InHitTestPoint, const FVector2D& InWindowPosition, const TSharedRef<FWidgetReflectorNodeBase>& InWidget, TArray<TSharedRef<FWidgetReflectorNodeBase>>& OutWidgets)
			{
				const bool bNeedsHitTesting = InWidget->GetHitTestInfo().IsHitTestVisible || InWidget->GetHitTestInfo().AreChildrenHitTestVisible;
				if (bNeedsHitTesting)
				{
					const FSlateRect HitTestRect = FSlateRect::FromPointAndExtent(
						InWidget->GetAccumulatedLayoutTransform().GetTranslation() - InWindowPosition, 
						TransformPoint(InWidget->GetAccumulatedLayoutTransform().GetScale(), InWidget->GetLocalSize())
						);

					if (HitTestRect.ContainsPoint(InHitTestPoint))
					{
						OutWidgets.Add(InWidget);

						if (InWidget->GetHitTestInfo().AreChildrenHitTestVisible)
						{
							for (const auto& ChildWidget : InWidget->GetChildNodes())
							{
								if (FindWidgetsUnderPoint(InHitTestPoint, InWindowPosition, ChildWidget, OutWidgets))
								{
									return true;
								}
							}
						}

						return InWidget->GetHitTestInfo().IsHitTestVisible;
					}
				}

				return false;
			}
Example #2
0
void SSequencerTrackArea::GenerateLayoutNodeWidgetsRecursive( const TArray< TSharedRef<FSequencerDisplayNode> >& Nodes )
{
	for( int32 NodeIndex = 0; NodeIndex < Nodes.Num(); ++NodeIndex )
	{
		TSharedRef<FSequencerDisplayNode> Node = Nodes[NodeIndex];

		// The section area encompasses multiple logical child nodes so we do not generate children that arent section areas (they would not be top level nodes in that case)
		if( Node->GetType() == ESequencerNode::Track )
		{
			GenerateWidgetForNode( Node );	

			GenerateLayoutNodeWidgetsRecursive( Node->GetChildNodes() );
		}
	}
}
void SAnimationOutlinerView::GenerateWidgetForNode( TSharedRef<FSequencerDisplayNode>& InLayoutNode )
{
	Children.Add( 
		SNew( SAnimationOutlinerTreeNode, InLayoutNode)
		.OnSelectionChanged( this, &SAnimationOutlinerView::OnSelectionChanged )
		);

	// Object nodes do not generate widgets for their children
	if( InLayoutNode->GetType() != ESequencerNode::Object )
	{
		const TArray< TSharedRef<FSequencerDisplayNode> >& ChildNodes = InLayoutNode->GetChildNodes();
		
		for( int32 ChildIndex = 0; ChildIndex < ChildNodes.Num(); ++ChildIndex )
		{
			TSharedRef<FSequencerDisplayNode> ChildNode = ChildNodes[ChildIndex];
			GenerateWidgetForNode( ChildNode );
		}
	}
}
/**
 * Recursively filters nodes
 *
 * @param StartNode			The node to start from
 * @param FilterStrings		The filter strings which need to be matched
 * @param OutFilteredNodes	The list of all filtered nodes
 */
static bool FilterNodesRecursive( const TSharedRef<FSequencerDisplayNode>& StartNode, const TArray<FString>& FilterStrings, TSet< TSharedRef< const FSequencerDisplayNode> >& OutFilteredNodes )
{
	// Assume the filter is acceptable
	bool bFilterAcceptable = true;

	// Check each string in the filter strings list against 
	for (int32 TestNameIndex = 0; TestNameIndex < FilterStrings.Num(); ++TestNameIndex)
	{
		const FString& TestName = FilterStrings[TestNameIndex];

		if ( !StartNode->GetDisplayName().ToString().Contains( TestName ) ) 
		{
			bFilterAcceptable = false;
			break;
		}
	}

	// Whether or the start node is in the filter
	bool bInFilter = false;

	if( bFilterAcceptable )
	{
		// This node is now filtered
		OutFilteredNodes.Add( StartNode );
		bInFilter = true;
	}

	// Check each child node to determine if it is filtered
	const TArray< TSharedRef<FSequencerDisplayNode> >& ChildNodes = StartNode->GetChildNodes();
	for( int32 ChildIndex = 0; ChildIndex < ChildNodes.Num(); ++ChildIndex )
	{
		// Mark the parent as filtered if any child node was filtered
		bFilterAcceptable |= FilterNodesRecursive( ChildNodes[ChildIndex], FilterStrings, OutFilteredNodes );
		if( bFilterAcceptable && !bInFilter )
		{
			OutFilteredNodes.Add( StartNode );
			bInFilter = true;
		}
	}

	return bFilterAcceptable;
}
Example #5
0
void SSequencerTrackArea::Update( TSharedPtr<FSequencerNodeTree> InSequencerNodeTree )
{
	ScrollBox->ClearChildren();

	const TArray< TSharedRef<FSequencerDisplayNode> >& RootNodes = InSequencerNodeTree->GetRootNodes();

	for( int32 RootNodeIndex = 0; RootNodeIndex < RootNodes.Num(); ++RootNodeIndex )
	{
		TSharedRef<FSequencerDisplayNode> RootNode = RootNodes[RootNodeIndex];

		// Generate a widget for each root node
		GenerateWidgetForNode( RootNode );

		// Generate a node for each children of the root node
		GenerateLayoutNodeWidgetsRecursive( RootNode->GetChildNodes() );
	}

	// @todo Sequencer - Remove this expensive operation
	ScrollBox->SlatePrepass();

	CurveEditor->SetSequencerNodeTree(InSequencerNodeTree);
}