2021-09-28 13:33:17 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "SStateTreeViewRow.h"
# include "SStateTreeView.h"
# include "EditorFontGlyphs.h"
2023-06-20 13:49:25 -04:00
# include "StateTreeEditor.h"
2023-06-15 11:38:28 -04:00
# include "StateTreeEditorData.h"
2021-09-28 13:33:17 -04:00
# include "StateTreeEditorStyle.h"
# include "Widgets/Text/SInlineEditableTextBlock.h"
# include "Widgets/Layout/SScrollBox.h"
2023-06-15 11:38:28 -04:00
# include "Widgets/Layout/SSpacer.h"
2023-12-05 17:55:30 -05:00
# include "StateTree.h"
2021-09-28 13:33:17 -04:00
# include "StateTreeState.h"
2022-02-03 09:13:49 -05:00
# include "StateTreeTaskBase.h"
2021-09-28 13:33:17 -04:00
# include "StateTreeViewModel.h"
2023-01-19 00:48:07 -05:00
# include "Widgets/Views/SListView.h"
2024-04-05 03:37:02 -04:00
# include "TextStyleDecorator.h"
# include "Widgets/Text/SRichTextBlock.h"
2021-09-28 13:33:17 -04:00
# define LOCTEXT_NAMESPACE "StateTreeEditor"
2023-09-26 11:50:26 -04:00
namespace UE : : StateTree : : Editor
{
FLinearColor LerpColorSRGB ( const FLinearColor ColorA , FLinearColor ColorB , float T )
{
const FColor A = ColorA . ToFColorSRGB ( ) ;
const FColor B = ColorB . ToFColorSRGB ( ) ;
return FLinearColor ( FColor (
static_cast < uint8 > ( FMath : : RoundToInt ( static_cast < float > ( A . R ) * ( 1.f - T ) + static_cast < float > ( B . R ) * T ) ) ,
static_cast < uint8 > ( FMath : : RoundToInt ( static_cast < float > ( A . G ) * ( 1.f - T ) + static_cast < float > ( B . G ) * T ) ) ,
static_cast < uint8 > ( FMath : : RoundToInt ( static_cast < float > ( A . B ) * ( 1.f - T ) + static_cast < float > ( B . B ) * T ) ) ,
static_cast < uint8 > ( FMath : : RoundToInt ( static_cast < float > ( A . A ) * ( 1.f - T ) + static_cast < float > ( B . A ) * T ) ) ) ) ;
}
} // UE:StateTree::Editor
2023-12-14 02:55:56 -05:00
void SStateTreeViewRow : : Construct ( const FArguments & InArgs , const TSharedRef < STableViewBase > & InOwnerTableView , TWeakObjectPtr < UStateTreeState > InState , const TSharedPtr < SScrollBox > & ViewBox , TSharedPtr < FStateTreeViewModel > InStateTreeViewModel )
2021-09-28 13:33:17 -04:00
{
StateTreeViewModel = InStateTreeViewModel ;
WeakState = InState ;
2023-06-15 11:38:28 -04:00
const UStateTreeState * State = InState . Get ( ) ;
2024-04-05 03:37:02 -04:00
WeakEditorData = State ! = nullptr ? State - > GetTypedOuter < UStateTreeEditorData > ( ) : nullptr ;
2021-09-28 13:33:17 -04:00
2023-06-05 13:12:19 -04:00
ConstructInternal ( STableRow : : FArguments ( )
2024-04-11 04:14:59 -04:00
. Padding ( 5.f )
2023-03-14 13:35:46 -04:00
. OnDragDetected ( this , & SStateTreeViewRow : : HandleDragDetected )
. OnCanAcceptDrop ( this , & SStateTreeViewRow : : HandleCanAcceptDrop )
. OnAcceptDrop ( this , & SStateTreeViewRow : : HandleAcceptDrop )
. Style ( & FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTableRowStyle > ( " StateTree.Selection " ) )
, InOwnerTableView ) ;
2021-09-28 13:33:17 -04:00
2022-04-05 03:20:57 -04:00
static const FLinearColor LinkBackground = FLinearColor ( FColor ( 84 , 84 , 84 ) ) ;
2023-06-05 13:12:19 -04:00
static constexpr FLinearColor IconTint = FLinearColor ( 1 , 1 , 1 , 0.5f ) ;
2022-06-30 03:06:38 -04:00
2021-09-28 13:33:17 -04:00
this - > ChildSlot
2022-10-31 15:13:40 -04:00
. HAlign ( HAlign_Fill )
[
SNew ( SBox )
2023-05-08 13:32:14 -04:00
. MinDesiredWidth_Lambda ( [ WeakOwnerViewBox = ViewBox . ToWeakPtr ( ) ] ( )
2023-03-14 13:35:46 -04:00
{
2023-05-08 13:32:14 -04:00
// Captured as weak ptr so we don't prevent our parent widget from being destroyed (circular pointer reference).
if ( const TSharedPtr < SScrollBox > OwnerViewBox = WeakOwnerViewBox . Pin ( ) )
{
// Make the row at least as wide as the view.
// The -1 is needed or we'll see a scrollbar.
return OwnerViewBox - > GetTickSpaceGeometry ( ) . GetLocalSize ( ) . X - 1 ;
}
return 0.f ;
2023-03-14 13:35:46 -04:00
} )
2022-06-30 03:06:38 -04:00
[
2022-10-31 15:13:40 -04:00
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Fill )
. HAlign ( HAlign_Left )
. AutoWidth ( )
[
SNew ( SExpanderArrow , SharedThis ( this ) )
. ShouldDrawWires ( true )
2024-04-11 04:14:59 -04:00
. IndentAmount ( 32.f )
2022-10-31 15:13:40 -04:00
. BaseIndentLevel ( 0 )
]
2021-09-28 13:33:17 -04:00
2022-10-31 15:13:40 -04:00
+ SHorizontalBox : : Slot ( )
2023-03-14 13:35:46 -04:00
. VAlign ( VAlign_Fill )
. HAlign ( HAlign_Left )
2024-04-11 04:14:59 -04:00
. Padding ( FMargin ( 0.f , 4.f ) )
2022-10-31 15:13:40 -04:00
. AutoWidth ( )
[
SNew ( SBox )
2024-04-11 04:14:59 -04:00
. HeightOverride ( 28.f )
2022-10-31 15:13:40 -04:00
. VAlign ( VAlign_Fill )
[
SNew ( SBorder )
2023-06-05 13:12:19 -04:00
. BorderImage ( FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTree.State.Border " ) )
2023-03-14 13:35:46 -04:00
. BorderBackgroundColor ( this , & SStateTreeViewRow : : GetActiveStateColor )
2022-10-31 15:13:40 -04:00
[
SNew ( SHorizontalBox )
2023-04-12 07:59:16 -04:00
// Sub tree marker
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
SNew ( SBox )
2024-04-11 04:14:59 -04:00
. WidthOverride ( 4.f )
. HeightOverride ( 28.f )
2023-04-12 07:59:16 -04:00
[
SNew ( SBorder )
. BorderImage ( FAppStyle : : GetBrush ( " WhiteBrush " ) )
. BorderBackgroundColor ( this , & SStateTreeViewRow : : GetSubTreeMarkerColor )
]
]
// State Box
2022-10-31 15:13:40 -04:00
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
SNew ( SBox )
2024-04-11 04:14:59 -04:00
. HeightOverride ( 28.f )
2023-03-14 13:35:46 -04:00
. VAlign ( VAlign_Fill )
2022-10-31 15:13:40 -04:00
[
2023-03-14 13:35:46 -04:00
SNew ( SBorder )
. BorderImage ( FAppStyle : : GetBrush ( " WhiteBrush " ) )
. BorderBackgroundColor ( this , & SStateTreeViewRow : : GetTitleColor )
2024-04-11 04:14:59 -04:00
. Padding ( FMargin ( 4.f , 0.f , 12.f , 0.f ) )
2023-06-05 13:12:19 -04:00
. IsEnabled_Lambda ( [ InState ]
{
const UStateTreeState * State = InState . Get ( ) ;
return State ! = nullptr & & State - > bEnabled ;
} )
2023-03-14 13:35:46 -04:00
[
2023-06-15 11:38:28 -04:00
SNew ( SOverlay )
+ SOverlay : : Slot ( )
2023-03-14 13:35:46 -04:00
[
2023-06-15 11:38:28 -04:00
SNew ( SHorizontalBox )
2024-04-12 07:21:04 -04:00
// Warnings
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
SNew ( SBox )
. Padding ( FMargin ( 0.f , 0.f , 4.f , 0.f ) )
. Visibility ( this , & SStateTreeViewRow : : GetWarningsVisibility )
[
SNew ( SImage )
. Image ( FAppStyle : : Get ( ) . GetBrush ( " Icons.Warning " ) )
. ToolTipText ( this , & SStateTreeViewRow : : GetWarningsTooltipText )
]
]
2023-06-15 11:38:28 -04:00
// Conditions icon
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
2023-03-14 13:35:46 -04:00
[
2023-06-15 11:38:28 -04:00
SNew ( SBox )
2024-04-11 04:14:59 -04:00
. Padding ( FMargin ( 0.f , 0.f , 4.f , 0.f ) )
2023-06-15 11:38:28 -04:00
. Visibility ( this , & SStateTreeViewRow : : GetConditionVisibility )
[
SNew ( SImage )
. ColorAndOpacity ( IconTint )
. Image ( FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.Conditions " ) )
. ToolTipText ( LOCTEXT ( " StateHasEnterConditions " , " State selection is guarded with enter conditions. " ) )
]
]
// Selector icon
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
SNew ( SBox )
2024-04-11 04:14:59 -04:00
. Padding ( FMargin ( 0.f , 0.f , 4.f , 0.f ) )
2023-06-15 11:38:28 -04:00
[
SNew ( SImage )
. Image ( this , & SStateTreeViewRow : : GetSelectorIcon )
. ColorAndOpacity ( IconTint )
. ToolTipText ( this , & SStateTreeViewRow : : GetSelectorTooltip )
]
]
// State Name
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
SAssignNew ( NameTextBlock , SInlineEditableTextBlock )
. Style ( FStateTreeEditorStyle : : Get ( ) , " StateTree.State.TitleInlineEditableText " )
. OnVerifyTextChanged_Lambda ( [ ] ( const FText & NewLabel , FText & OutErrorMessage )
{
return ! NewLabel . IsEmptyOrWhitespace ( ) ;
} )
. OnTextCommitted ( this , & SStateTreeViewRow : : HandleNodeLabelTextCommitted )
. Text ( this , & SStateTreeViewRow : : GetStateDesc )
. ToolTipText ( this , & SStateTreeViewRow : : GetStateTypeTooltip )
. Clipping ( EWidgetClipping : : ClipToBounds )
. IsSelected ( this , & SStateTreeViewRow : : IsStateSelected )
2023-03-14 13:35:46 -04:00
]
2023-06-21 10:32:41 -04:00
// State ID
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
SNew ( STextBlock )
. Visibility_Lambda ( [ ] ( )
{
return UE : : StateTree : : Editor : : GbDisplayItemIds ? EVisibility : : Visible : EVisibility : : Collapsed ;
} )
. Text ( this , & SStateTreeViewRow : : GetStateIDDesc )
. TextStyle ( FStateTreeEditorStyle : : Get ( ) , " StateTree.Details " )
]
2023-03-14 13:35:46 -04:00
]
2023-06-15 11:38:28 -04:00
+ SOverlay : : Slot ( )
2023-03-14 13:35:46 -04:00
[
2023-06-15 11:38:28 -04:00
SNew ( SHorizontalBox )
// State breakpoint box
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Top )
. HAlign ( HAlign_Left )
. AutoWidth ( )
2023-03-14 13:35:46 -04:00
[
2023-06-15 11:38:28 -04:00
SNew ( SBox )
2024-04-11 04:14:59 -04:00
. Padding ( FMargin ( - 12.f , - 6.f , 0.f , 0.f ) )
2023-06-15 11:38:28 -04:00
[
SNew ( SImage )
. DesiredSizeOverride ( FVector2D ( 12.f , 12.f ) )
. Image ( FStateTreeEditorStyle : : Get ( ) . GetBrush ( TEXT ( " StateTreeEditor.Debugger.Breakpoint.EnabledAndValid " ) ) )
. Visibility ( this , & SStateTreeViewRow : : GetStateBreakpointVisibility )
. ToolTipText ( this , & SStateTreeViewRow : : GetStateBreakpointTooltipText )
]
2023-03-14 13:35:46 -04:00
]
]
]
2022-06-30 03:06:38 -04:00
]
]
2023-04-12 07:59:16 -04:00
// Linked State box
2022-06-30 03:06:38 -04:00
+ SHorizontalBox : : Slot ( )
2023-04-12 07:59:16 -04:00
. VAlign ( VAlign_Fill )
2022-06-30 03:06:38 -04:00
. AutoWidth ( )
[
2023-04-12 07:59:16 -04:00
SNew ( SBox )
2024-04-11 04:14:59 -04:00
. HeightOverride ( 28.f )
2023-04-12 07:59:16 -04:00
. VAlign ( VAlign_Fill )
. Visibility ( this , & SStateTreeViewRow : : GetLinkedStateVisibility )
[
SNew ( SBorder )
. BorderImage ( FAppStyle : : GetBrush ( " WhiteBrush " ) )
. BorderBackgroundColor ( LinkBackground )
2024-04-11 04:14:59 -04:00
. Padding ( FMargin ( 6.f , 0.f , 12.f , 0.f ) )
2023-04-12 07:59:16 -04:00
[
// Link icon
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
2024-04-11 04:14:59 -04:00
. Padding ( FMargin ( 0.f , 0.f , 4.f , 0.f ) )
2023-04-12 07:59:16 -04:00
[
SNew ( SImage )
. ColorAndOpacity ( IconTint )
. Image ( FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.StateLinked " ) )
]
2021-09-28 13:33:17 -04:00
2023-04-12 07:59:16 -04:00
// Linked State
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
SNew ( STextBlock )
. Text ( this , & SStateTreeViewRow : : GetLinkedStateDesc )
. TextStyle ( FStateTreeEditorStyle : : Get ( ) , " StateTree.Details " )
]
]
]
2022-06-30 03:06:38 -04:00
]
2023-06-05 13:12:19 -04:00
// Tasks
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Fill )
. AutoWidth ( )
[
SNew ( SBox )
. VAlign ( VAlign_Fill )
. Visibility ( this , & SStateTreeViewRow : : GetTasksVisibility )
[
CreateTasksWidget ( )
]
]
2022-04-05 03:20:57 -04:00
]
]
]
2023-03-14 13:35:46 -04:00
2022-06-30 03:06:38 -04:00
// Completed transitions
2021-09-28 13:33:17 -04:00
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
2024-04-11 04:14:59 -04:00
SNew ( SBox )
. Visibility ( this , & SStateTreeViewRow : : GetCompletedTransitionVisibility )
2022-06-30 03:06:38 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
. Padding ( FMargin ( 8.f , 0.f , 0.f , 0.f ) )
2023-06-20 13:49:25 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SOverlay )
+ SOverlay : : Slot ( )
2023-06-20 13:49:25 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SImage )
. Image ( this , & SStateTreeViewRow : : GetCompletedTransitionsIcon )
. ColorAndOpacity ( IconTint )
]
+ SOverlay : : Slot ( )
[
// Breakpoint box
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Top )
. HAlign ( HAlign_Left )
. AutoWidth ( )
2023-06-20 13:49:25 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SBox )
. Padding ( FMargin ( 0.f , - 10.f , 0.f , 0.f ) )
[
SNew ( SImage )
. DesiredSizeOverride ( FVector2D ( 10.f , 10.f ) )
. Image ( FStateTreeEditorStyle : : Get ( ) . GetBrush ( TEXT ( " StateTreeEditor.Debugger.Breakpoint.EnabledAndValid " ) ) )
. Visibility ( this , & SStateTreeViewRow : : GetCompletedTransitionBreakpointVisibility )
. ToolTipText_Lambda ( [ this ]
{
return FText : : Format ( LOCTEXT ( " TransitionBreakpointTooltip " , " Break when executing transition: {0} " ) ,
GetCompletedTransitionWithBreakpointDesc ( ) ) ;
} )
]
2023-06-20 13:49:25 -04:00
]
]
]
2024-04-11 04:14:59 -04:00
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
. Padding ( FMargin ( 4.f , 0.f , 0.f , 0.f ) )
[
SNew ( SRichTextBlock )
. Text ( this , & SStateTreeViewRow : : GetCompletedTransitionsDesc )
. TextStyle ( & FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Normal " ) )
. OverflowPolicy ( ETextOverflowPolicy : : Ellipsis )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Normal " ) ) )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " b " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Bold " ) ) )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " i " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Italic " ) ) )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " s " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Subdued " ) ) )
]
2022-06-30 03:06:38 -04:00
]
2021-09-28 13:33:17 -04:00
]
2022-06-30 03:06:38 -04:00
// Succeeded transitions
2021-09-28 13:33:17 -04:00
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
2024-04-11 04:14:59 -04:00
SNew ( SBox )
. Visibility ( this , & SStateTreeViewRow : : GetSucceededTransitionVisibility )
2022-06-30 03:06:38 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. Padding ( FMargin ( 8.f , 0.f , 0.f , 0.f ) )
. AutoWidth ( )
2023-06-20 13:49:25 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SImage )
. Image ( FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.Transition.Succeeded " ) )
2023-06-20 13:49:25 -04:00
]
2024-04-11 04:14:59 -04:00
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
2023-06-20 13:49:25 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SOverlay )
+ SOverlay : : Slot ( )
2023-06-20 13:49:25 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SImage )
. Image ( this , & SStateTreeViewRow : : GetSucceededTransitionIcon )
. ColorAndOpacity ( IconTint )
]
+ SOverlay : : Slot ( )
[
// Breakpoint box
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Top )
. HAlign ( HAlign_Left )
. AutoWidth ( )
2023-06-20 13:49:25 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SBox )
. Padding ( FMargin ( 0.f , - 10.f , 0.f , 0.f ) )
[
SNew ( SImage )
. DesiredSizeOverride ( FVector2D ( 10.f , 10.f ) )
. Image ( FStateTreeEditorStyle : : Get ( ) . GetBrush ( TEXT ( " StateTreeEditor.Debugger.Breakpoint.EnabledAndValid " ) ) )
. Visibility ( this , & SStateTreeViewRow : : GetSucceededTransitionBreakpointVisibility )
. ToolTipText_Lambda ( [ this ]
{
return FText : : Format ( LOCTEXT ( " TransitionBreakpointTooltip " , " Break when executing transition: {0} " ) ,
GetSucceededTransitionWithBreakpointDesc ( ) ) ;
} )
]
2023-06-20 13:49:25 -04:00
]
]
]
2024-04-11 04:14:59 -04:00
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
. Padding ( FMargin ( 4.f , 0.f , 0.f , 0.f ) )
[
SNew ( SRichTextBlock )
. Text ( this , & SStateTreeViewRow : : GetSucceededTransitionDesc )
. TextStyle ( & FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Normal " ) )
. OverflowPolicy ( ETextOverflowPolicy : : Ellipsis )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Normal " ) ) )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " b " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Bold " ) ) )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " i " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Italic " ) ) )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " s " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Subdued " ) ) )
]
2022-06-30 03:06:38 -04:00
]
2021-09-28 13:33:17 -04:00
]
2022-06-30 03:06:38 -04:00
// Failed transitions
2021-09-28 13:33:17 -04:00
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
2024-04-11 04:14:59 -04:00
SNew ( SBox )
. Visibility ( this , & SStateTreeViewRow : : GetFailedTransitionVisibility )
2022-06-30 03:06:38 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. Padding ( FMargin ( 8.f , 0.f , 0.f , 0.f ) )
. AutoWidth ( )
2023-06-20 13:49:25 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SImage )
. Image ( FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.Transition.Failed " ) )
2023-06-20 13:49:25 -04:00
]
2024-04-11 04:14:59 -04:00
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
2023-06-20 13:49:25 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SOverlay )
+ SOverlay : : Slot ( )
2023-06-20 13:49:25 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SImage )
. Image ( this , & SStateTreeViewRow : : GetFailedTransitionIcon )
. ColorAndOpacity ( IconTint )
]
+ SOverlay : : Slot ( )
[
// Breakpoint box
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Top )
. HAlign ( HAlign_Left )
. AutoWidth ( )
2023-06-20 13:49:25 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SBox )
. Padding ( FMargin ( 0.f , - 10.f , 0.f , 0.f ) )
[
SNew ( SImage )
. DesiredSizeOverride ( FVector2D ( 10.f , 10.f ) )
. Image ( FStateTreeEditorStyle : : Get ( ) . GetBrush ( TEXT ( " StateTreeEditor.Debugger.Breakpoint.EnabledAndValid " ) ) )
. Visibility ( this , & SStateTreeViewRow : : GetFailedTransitionBreakpointVisibility )
. ToolTipText_Lambda ( [ this ]
{
return FText : : Format ( LOCTEXT ( " TransitionBreakpointTooltip " , " Break when executing transition: {0} " ) ,
GetFailedTransitionWithBreakpointDesc ( ) ) ;
} )
]
2023-06-20 13:49:25 -04:00
]
]
]
2024-04-11 04:14:59 -04:00
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
. Padding ( FMargin ( 4.f , 0.f , 0.f , 0.f ) )
[
SNew ( SRichTextBlock )
. Text ( this , & SStateTreeViewRow : : GetFailedTransitionDesc )
. TextStyle ( & FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Normal " ) )
. OverflowPolicy ( ETextOverflowPolicy : : Ellipsis )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Normal " ) ) )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " b " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Bold " ) ) )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " i " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Italic " ) ) )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " s " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Subdued " ) ) )
]
2022-06-30 03:06:38 -04:00
]
2021-09-28 13:33:17 -04:00
]
2023-06-20 13:49:25 -04:00
2022-06-30 03:06:38 -04:00
// Transitions
2021-09-28 13:33:17 -04:00
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
2024-04-11 04:14:59 -04:00
SNew ( SBox )
. Visibility ( this , & SStateTreeViewRow : : GetConditionalTransitionsVisibility )
2022-06-30 03:06:38 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. Padding ( FMargin ( 8.f , 0.f , 0.f , 0.f ) )
. AutoWidth ( )
2023-06-20 13:49:25 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SImage )
. Image ( FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.Transition.Condition " ) )
2023-06-20 13:49:25 -04:00
]
2024-04-11 04:14:59 -04:00
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
2023-06-20 13:49:25 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SOverlay )
+ SOverlay : : Slot ( )
2023-06-20 13:49:25 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SImage )
. Image ( FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.Transition.Goto " ) )
. ColorAndOpacity ( IconTint )
]
+ SOverlay : : Slot ( )
[
// Breakpoint box
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Top )
. HAlign ( HAlign_Left )
. AutoWidth ( )
2023-06-20 13:49:25 -04:00
[
2024-04-11 04:14:59 -04:00
SNew ( SBox )
. Padding ( FMargin ( 0.f , - 10.f , 0.f , 0.f ) )
[
SNew ( SImage )
. DesiredSizeOverride ( FVector2D ( 10.f , 10.f ) )
. Image ( FStateTreeEditorStyle : : Get ( ) . GetBrush ( TEXT ( " StateTreeEditor.Debugger.Breakpoint.EnabledAndValid " ) ) )
. Visibility ( this , & SStateTreeViewRow : : GetConditionalTransitionsBreakpointVisibility )
. ToolTipText_Lambda ( [ this ]
{
return FText : : Format ( LOCTEXT ( " TransitionBreakpointTooltip " , " Break when executing transition: {0} " ) ,
GetConditionalTransitionsWithBreakpointDesc ( ) ) ;
} )
]
2023-06-20 13:49:25 -04:00
]
]
]
2024-04-11 04:14:59 -04:00
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
. Padding ( FMargin ( 4.f , 0.f , 0.f , 0.f ) )
[
SNew ( SRichTextBlock )
. Text ( this , & SStateTreeViewRow : : GetConditionalTransitionsDesc )
. TextStyle ( & FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Normal " ) )
. OverflowPolicy ( ETextOverflowPolicy : : Ellipsis )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Normal " ) ) )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " b " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Bold " ) ) )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " i " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Italic " ) ) )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " s " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " Normal.Subdued " ) ) )
]
2022-06-30 03:06:38 -04:00
]
2021-09-28 13:33:17 -04:00
]
]
] ;
}
2023-06-05 13:12:19 -04:00
TSharedRef < SHorizontalBox > SStateTreeViewRow : : CreateTasksWidget ( )
{
const TSharedRef < SHorizontalBox > TasksBox = SNew ( SHorizontalBox ) ;
2024-04-05 03:37:02 -04:00
const UStateTreeEditorData * EditorData = WeakEditorData . Get ( ) ;
2023-06-05 13:12:19 -04:00
const UStateTreeState * State = WeakState . Get ( ) ;
2024-04-05 03:37:02 -04:00
if ( ! EditorData | | ! State | | State - > Tasks . IsEmpty ( ) )
2023-06-05 13:12:19 -04:00
{
return TasksBox ;
}
2024-04-05 03:37:02 -04:00
const int32 NumTasks = State - > Tasks . Num ( ) ;
2023-06-15 11:38:28 -04:00
2024-04-05 03:37:02 -04:00
// The task descriptions can get long. Make some effort to limit how long they can get.
constexpr float ReferenceWidth = 1000.0f ;
const float MaxTaskWidth = FMath : : RoundToFloat ( FMath : : Max ( 150.0f , ReferenceWidth / static_cast < float > ( FMath : : Max ( 1 , NumTasks ) ) ) ) ;
for ( int32 TaskIndex = 0 ; TaskIndex < NumTasks ; TaskIndex + + )
2023-06-05 13:12:19 -04:00
{
2024-04-05 03:37:02 -04:00
const FStateTreeEditorNode & TaskNode = State - > Tasks [ TaskIndex ] ;
if ( const FStateTreeTaskBase * Task = TaskNode . Node . GetPtr < FStateTreeTaskBase > ( ) )
2023-06-05 13:12:19 -04:00
{
2023-06-15 11:38:28 -04:00
FGuid TaskId = State - > Tasks [ TaskIndex ] . ID ;
2023-06-05 13:12:19 -04:00
auto IsTaskEnabledFunc = [ WeakState = WeakState , TaskIndex ]
{
const UStateTreeState * State = WeakState . Get ( ) ;
if ( State ! = nullptr & & State - > Tasks . IsValidIndex ( TaskIndex ) )
{
if ( const FStateTreeTaskBase * Task = State - > Tasks [ TaskIndex ] . Node . GetPtr < FStateTreeTaskBase > ( ) )
{
return ( State - > bEnabled & & Task - > bTaskEnabled ) ;
}
2023-06-15 11:38:28 -04:00
}
2023-06-05 13:12:19 -04:00
return true ;
} ;
2023-06-15 11:38:28 -04:00
2024-04-05 03:37:02 -04:00
auto IsTaskBreakpointEnabledFunc = [ WeakEditorData = WeakEditorData , TaskId ]
2023-06-15 11:38:28 -04:00
{
# if WITH_STATETREE_DEBUGGER
const UStateTreeEditorData * EditorData = WeakEditorData . Get ( ) ;
if ( EditorData ! = nullptr & & EditorData - > HasAnyBreakpoint ( TaskId ) )
{
return EVisibility : : Visible ;
}
# endif // WITH_STATETREE_DEBUGGER
return EVisibility : : Hidden ;
} ;
2023-06-05 13:12:19 -04:00
2024-04-05 03:37:02 -04:00
auto GetTaskBreakpointTooltipFunc = [ WeakEditorData = WeakEditorData , TaskId ]
2023-06-15 11:38:28 -04:00
{
# if WITH_STATETREE_DEBUGGER
if ( const UStateTreeEditorData * EditorData = WeakEditorData . Get ( ) )
{
const bool bHasBreakpointOnEnter = EditorData - > HasBreakpoint ( TaskId , EStateTreeBreakpointType : : OnEnter ) ;
const bool bHasBreakpointOnExit = EditorData - > HasBreakpoint ( TaskId , EStateTreeBreakpointType : : OnExit ) ;
if ( bHasBreakpointOnEnter & & bHasBreakpointOnExit )
{
return LOCTEXT ( " StateTreeTaskBreakpointOnEnterAndOnExitTooltip " , " Break when entering or exiting task " ) ;
}
if ( bHasBreakpointOnEnter )
{
return LOCTEXT ( " StateTreeTaskBreakpointOnEnterTooltip " , " Break when entering task " ) ;
}
if ( bHasBreakpointOnExit )
{
return LOCTEXT ( " StateTreeTaskBreakpointOnExitTooltip " , " Break when exiting task " ) ;
}
}
# endif // WITH_STATETREE_DEBUGGER
return FText : : GetEmpty ( ) ;
} ;
2023-06-05 13:12:19 -04:00
TasksBox - > AddSlot ( )
. AutoWidth ( )
. VAlign ( VAlign_Fill )
[
SNew ( SBorder )
. VAlign ( VAlign_Center )
. BorderImage ( FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTree.Task.Rect " ) )
2023-09-26 11:50:26 -04:00
. BorderBackgroundColor ( this , & SStateTreeViewRow : : GetTitleColor )
2023-06-15 11:38:28 -04:00
. Padding ( 0 )
. IsEnabled_Lambda ( IsTaskEnabledFunc )
2023-06-05 13:12:19 -04:00
[
2023-06-15 11:38:28 -04:00
SNew ( SOverlay )
+ SOverlay : : Slot ( )
[
2024-04-05 03:37:02 -04:00
SNew ( SBox )
. MaxDesiredWidth ( MaxTaskWidth )
[
SNew ( SRichTextBlock )
. Margin ( FMargin ( 6.f , 0.f ) )
. Text ( this , & SStateTreeViewRow : : GetTaskDesc , TaskId , EStateTreeNodeFormatting : : RichText )
. ToolTipText ( this , & SStateTreeViewRow : : GetTaskDesc , TaskId , EStateTreeNodeFormatting : : Text )
. TextStyle ( & FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " StateTree.Task.Title " ) )
. OverflowPolicy ( ETextOverflowPolicy : : Ellipsis )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " StateTree.Task.Title " ) ) )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " b " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " StateTree.Task.Title.Bold " ) ) )
+ SRichTextBlock : : Decorator ( FTextStyleDecorator : : Create ( TEXT ( " s " ) , FStateTreeEditorStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " StateTree.Task.Title.Subdued " ) ) )
]
2023-06-15 11:38:28 -04:00
]
+ SOverlay : : Slot ( )
[
// Task Breakpoint box
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Top )
. HAlign ( HAlign_Left )
. AutoWidth ( )
[
SNew ( SBox )
. Padding ( FMargin ( 0.0f , - 10.0f , 0.0f , 0.0f ) )
[
SNew ( SImage )
. DesiredSizeOverride ( FVector2D ( 10.f , 10.f ) )
. Image ( FStateTreeEditorStyle : : Get ( ) . GetBrush ( TEXT ( " StateTreeEditor.Debugger.Breakpoint.EnabledAndValid " ) ) )
. Visibility_Lambda ( IsTaskBreakpointEnabledFunc )
. ToolTipText_Lambda ( GetTaskBreakpointTooltipFunc )
]
]
]
2023-06-05 13:12:19 -04:00
]
] ;
}
}
return TasksBox ;
}
2022-09-01 09:06:53 -04:00
void SStateTreeViewRow : : RequestRename ( ) const
2021-09-28 13:33:17 -04:00
{
if ( NameTextBlock )
{
NameTextBlock - > EnterEditingMode ( ) ;
}
}
FSlateColor SStateTreeViewRow : : GetTitleColor ( ) const
{
2023-09-26 11:50:26 -04:00
const UStateTreeState * State = WeakState . Get ( ) ;
2024-04-05 03:37:02 -04:00
const UStateTreeEditorData * EditorData = WeakEditorData . Get ( ) ;
2023-09-26 11:50:26 -04:00
if ( State ! = nullptr & & EditorData ! = nullptr )
2021-09-28 13:33:17 -04:00
{
2023-09-26 11:50:26 -04:00
if ( const FStateTreeEditorColor * FoundColor = EditorData - > FindColor ( State - > ColorRef ) )
2021-09-28 13:33:17 -04:00
{
2023-09-26 11:50:26 -04:00
if ( IsRootState ( ) | | State - > Type = = EStateTreeStateType : : Subtree )
{
return UE : : StateTree : : Editor : : LerpColorSRGB ( FoundColor - > Color , FColor : : Black , 0.25f ) ;
}
return FoundColor - > Color ;
2021-09-28 13:33:17 -04:00
}
}
return FLinearColor ( FColor ( 31 , 151 , 167 ) ) ;
}
2023-03-14 13:35:46 -04:00
FSlateColor SStateTreeViewRow : : GetActiveStateColor ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
if ( StateTreeViewModel & & StateTreeViewModel - > IsStateActiveInDebugger ( * State ) )
{
return FLinearColor : : Yellow ;
}
2023-04-12 07:59:16 -04:00
if ( StateTreeViewModel & & StateTreeViewModel - > IsSelected ( State ) )
{
return FLinearColor ( FColor ( 236 , 134 , 39 ) ) ;
}
}
return FLinearColor : : Transparent ;
}
FSlateColor SStateTreeViewRow : : GetSubTreeMarkerColor ( ) const
{
// Show color for subtree.
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
if ( IsRootState ( ) | | State - > Type = = EStateTreeStateType : : Subtree )
{
2023-09-26 11:50:26 -04:00
const FSlateColor TitleColor = GetTitleColor ( ) ;
return UE : : StateTree : : Editor : : LerpColorSRGB ( TitleColor . GetSpecifiedColor ( ) , FLinearColor : : White , 0.2f ) ;
2023-04-12 07:59:16 -04:00
}
2023-03-14 13:35:46 -04:00
}
return GetTitleColor ( ) ;
}
2021-09-28 13:33:17 -04:00
FText SStateTreeViewRow : : GetStateDesc ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
return FText : : FromName ( State - > Name ) ;
}
return FText : : FromName ( FName ( ) ) ;
}
2023-06-21 10:32:41 -04:00
FText SStateTreeViewRow : : GetStateIDDesc ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
return FText : : FromString ( * LexToString ( State - > ID ) ) ;
}
return FText : : FromName ( FName ( ) ) ;
}
2021-09-28 13:33:17 -04:00
EVisibility SStateTreeViewRow : : GetConditionVisibility ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
2021-10-21 04:08:20 -04:00
return State - > EnterConditions . Num ( ) > 0 ? EVisibility : : Visible : EVisibility : : Collapsed ;
2021-09-28 13:33:17 -04:00
}
return EVisibility : : Collapsed ;
}
2023-06-15 11:38:28 -04:00
EVisibility SStateTreeViewRow : : GetStateBreakpointVisibility ( ) const
2023-03-14 13:35:46 -04:00
{
2023-06-15 11:38:28 -04:00
# if WITH_STATETREE_DEBUGGER
const UStateTreeState * State = WeakState . Get ( ) ;
2024-04-05 03:37:02 -04:00
const UStateTreeEditorData * EditorData = WeakEditorData . Get ( ) ;
2023-06-15 11:38:28 -04:00
if ( State ! = nullptr & & EditorData ! = nullptr )
2023-03-14 13:35:46 -04:00
{
2023-06-15 11:38:28 -04:00
return ( EditorData ! = nullptr & & EditorData - > HasAnyBreakpoint ( State - > ID ) ) ? EVisibility : : Visible : EVisibility : : Hidden ;
}
# endif // WITH_STATETREE_DEBUGGER
return EVisibility : : Hidden ;
}
FText SStateTreeViewRow : : GetStateBreakpointTooltipText ( ) const
{
# if WITH_STATETREE_DEBUGGER
const UStateTreeState * State = WeakState . Get ( ) ;
2024-04-05 03:37:02 -04:00
const UStateTreeEditorData * EditorData = WeakEditorData . Get ( ) ;
2023-06-15 11:38:28 -04:00
if ( State ! = nullptr & & EditorData ! = nullptr )
{
const bool bHasBreakpointOnEnter = EditorData - > HasBreakpoint ( State - > ID , EStateTreeBreakpointType : : OnEnter ) ;
const bool bHasBreakpointOnExit = EditorData - > HasBreakpoint ( State - > ID , EStateTreeBreakpointType : : OnExit ) ;
if ( bHasBreakpointOnEnter & & bHasBreakpointOnExit )
2023-03-14 13:35:46 -04:00
{
2023-06-15 11:38:28 -04:00
return LOCTEXT ( " StateTreeStateBreakpointOnEnterAndOnExitTooltip " , " Break when entering or exiting state " ) ;
}
if ( bHasBreakpointOnEnter )
{
return LOCTEXT ( " StateTreeStateBreakpointOnEnterTooltip " , " Break when entering state " ) ;
}
if ( bHasBreakpointOnExit )
{
return LOCTEXT ( " StateTreeStateBreakpointOnExitTooltip " , " Break when exiting state " ) ;
2023-03-14 13:35:46 -04:00
}
}
2023-06-15 11:38:28 -04:00
# endif // WITH_STATETREE_DEBUGGER
return FText : : GetEmpty ( ) ;
2023-03-14 13:35:46 -04:00
}
2022-04-28 03:54:07 -04:00
2023-04-12 07:59:16 -04:00
const FSlateBrush * SStateTreeViewRow : : GetSelectorIcon ( ) const
2022-04-28 03:54:07 -04:00
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
2023-04-12 07:59:16 -04:00
if ( State - > SelectionBehavior = = EStateTreeStateSelectionBehavior : : None )
2022-04-28 03:54:07 -04:00
{
2023-04-12 07:59:16 -04:00
return FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.SelectNone " ) ;
2022-04-28 03:54:07 -04:00
}
2023-04-12 07:59:16 -04:00
else if ( State - > SelectionBehavior = = EStateTreeStateSelectionBehavior : : TryEnterState )
2022-04-28 03:54:07 -04:00
{
2023-04-12 07:59:16 -04:00
return FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.TryEnterState " ) ;
2022-04-28 03:54:07 -04:00
}
2023-04-12 07:59:16 -04:00
else if ( State - > SelectionBehavior = = EStateTreeStateSelectionBehavior : : TrySelectChildrenInOrder )
2022-04-28 03:54:07 -04:00
{
2024-03-28 10:25:37 -04:00
if ( State - > Children . IsEmpty ( )
| | State - > Type = = EStateTreeStateType : : Linked
| | State - > Type = = EStateTreeStateType : : LinkedAsset )
2023-04-12 07:59:16 -04:00
{
// Backwards compatible behavior
return FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.TryEnterState " ) ;
}
else
{
return FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.TrySelectChildrenInOrder " ) ;
}
}
2024-04-16 13:32:28 -04:00
else if ( State - > SelectionBehavior = = EStateTreeStateSelectionBehavior : : TrySelectChildrenAtUniformRandom )
{
if ( State - > Children . IsEmpty ( ) )
{
return FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.TryEnterState " ) ;
}
return FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.TrySelectCHildrenAtRandom " ) ;
}
2023-04-12 07:59:16 -04:00
else if ( State - > SelectionBehavior = = EStateTreeStateSelectionBehavior : : TryFollowTransitions )
{
return FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.TryFollowTransitions " ) ;
2022-04-28 03:54:07 -04:00
}
}
2023-04-12 07:59:16 -04:00
return nullptr ;
2022-04-28 03:54:07 -04:00
}
2023-04-12 07:59:16 -04:00
FText SStateTreeViewRow : : GetSelectorTooltip ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
const UEnum * Enum = StaticEnum < EStateTreeStateSelectionBehavior > ( ) ;
check ( Enum ) ;
const int32 Index = Enum - > GetIndexByValue ( ( int64 ) State - > SelectionBehavior ) ;
if ( State - > SelectionBehavior = = EStateTreeStateSelectionBehavior : : None )
{
return Enum - > GetToolTipTextByIndex ( Index ) ;
}
else if ( State - > SelectionBehavior = = EStateTreeStateSelectionBehavior : : TryEnterState )
{
return Enum - > GetToolTipTextByIndex ( Index ) ;
}
else if ( State - > SelectionBehavior = = EStateTreeStateSelectionBehavior : : TrySelectChildrenInOrder )
{
2024-04-11 04:14:59 -04:00
if ( State - > Children . IsEmpty ( )
| | State - > Type = = EStateTreeStateType : : Linked
| | State - > Type = = EStateTreeStateType : : LinkedAsset )
2023-04-12 07:59:16 -04:00
{
const int32 EnterStateIndex = Enum - > GetIndexByValue ( ( int64 ) EStateTreeStateSelectionBehavior : : TryEnterState ) ;
return FText : : Format ( LOCTEXT ( " ConvertedToEnterState " , " {0} \n Automatically converted from '{1}' becase the State has no child States. " ) ,
Enum - > GetToolTipTextByIndex ( EnterStateIndex ) , UEnum : : GetDisplayValueAsText ( State - > SelectionBehavior ) ) ;
}
else
{
return Enum - > GetToolTipTextByIndex ( Index ) ;
}
}
else if ( State - > SelectionBehavior = = EStateTreeStateSelectionBehavior : : TryFollowTransitions )
{
return Enum - > GetToolTipTextByIndex ( Index ) ;
}
}
return FText : : GetEmpty ( ) ;
}
FText SStateTreeViewRow : : GetStateTypeTooltip ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
const UEnum * Enum = StaticEnum < EStateTreeStateType > ( ) ;
check ( Enum ) ;
const int32 Index = Enum - > GetIndexByValue ( ( int64 ) State - > Type ) ;
return Enum - > GetToolTipTextByIndex ( Index ) ;
}
return FText : : GetEmpty ( ) ;
}
2024-04-05 03:37:02 -04:00
FText SStateTreeViewRow : : GetTaskDesc ( FGuid TaskID , EStateTreeNodeFormatting Formatting ) const
{
FText TaskName ;
const UStateTreeState * State = WeakState . Get ( ) ;
const UStateTreeEditorData * EditorData = WeakEditorData . Get ( ) ;
if ( EditorData ! = nullptr
& & State ! = nullptr )
{
const FStateTreeEditorNode * TaskNode = State - > Tasks . FindByPredicate ( [ & TaskID ] ( const FStateTreeEditorNode & Node )
{
return Node . ID = = TaskID ;
} ) ;
if ( TaskNode )
{
if ( UE : : StateTree : : Editor : : GbDisplayItemIds )
{
TaskName = FText : : Format ( LOCTEXT ( " TaskNameWithID " , " {0} ({1}) " ) , EditorData - > GetNodeDescription ( * TaskNode , Formatting ) , FText : : AsCultureInvariant ( * LexToString ( TaskID ) ) ) ;
}
else
{
TaskName = EditorData - > GetNodeDescription ( * TaskNode , Formatting ) ;
}
}
}
return TaskName ;
}
2023-04-12 07:59:16 -04:00
2021-09-28 13:33:17 -04:00
EVisibility SStateTreeViewRow : : GetTasksVisibility ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
int32 ValidCount = 0 ;
2021-10-21 04:08:20 -04:00
for ( int32 i = 0 ; i < State - > Tasks . Num ( ) ; i + + )
2021-09-28 13:33:17 -04:00
{
2023-03-14 13:35:46 -04:00
if ( State - > Tasks [ i ] . Node . GetPtr < FStateTreeTaskBase > ( ) )
2021-09-28 13:33:17 -04:00
{
2021-10-21 04:08:20 -04:00
ValidCount + + ;
2021-09-28 13:33:17 -04:00
}
}
return ValidCount > 0 ? EVisibility : : Visible : EVisibility : : Collapsed ;
}
return EVisibility : : Collapsed ;
}
2022-04-05 03:20:57 -04:00
EVisibility SStateTreeViewRow : : GetLinkedStateVisibility ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
2023-11-30 07:03:20 -05:00
return ( State - > Type = = EStateTreeStateType : : Linked | | State - > Type = = EStateTreeStateType : : LinkedAsset ) ? EVisibility : : Visible : EVisibility : : Collapsed ;
2022-04-05 03:20:57 -04:00
}
return EVisibility : : Collapsed ;
}
2024-04-12 07:21:04 -04:00
bool SStateTreeViewRow : : GetStateWarnings ( FText * OutText ) const
{
bool bHasWarnings = false ;
const UStateTreeState * State = WeakState . Get ( ) ;
if ( ! State )
{
return bHasWarnings ;
}
// Linked States cannot have children.
if ( ( State - > Type = = EStateTreeStateType : : Linked
| | State - > Type = = EStateTreeStateType : : LinkedAsset )
& & State - > Children . Num ( ) > 0 )
{
if ( OutText )
{
* OutText = LOCTEXT ( " LinkedStateChildWarning " , " Linked State cannot have child states, because the state selection will enter to the linked state on activation. " ) ;
}
bHasWarnings = true ;
}
return bHasWarnings ;
}
2022-04-05 03:20:57 -04:00
FText SStateTreeViewRow : : GetLinkedStateDesc ( ) const
{
const UStateTreeState * State = WeakState . Get ( ) ;
if ( ! State )
{
return FText : : GetEmpty ( ) ;
}
if ( State - > Type = = EStateTreeStateType : : Linked )
{
2022-09-30 11:31:57 -04:00
return FText : : FromName ( State - > LinkedSubtree . Name ) ;
2022-04-05 03:20:57 -04:00
}
2023-11-30 07:03:20 -05:00
else if ( State - > Type = = EStateTreeStateType : : LinkedAsset )
{
2023-12-04 03:46:59 -05:00
return FText : : FromString ( GetNameSafe ( State - > LinkedAsset . Get ( ) ) ) ;
2023-11-30 07:03:20 -05:00
}
2022-04-05 03:20:57 -04:00
return FText : : GetEmpty ( ) ;
}
2024-04-12 07:21:04 -04:00
EVisibility SStateTreeViewRow : : GetWarningsVisibility ( ) const
{
return GetStateWarnings ( nullptr ) ? EVisibility : : Visible : EVisibility : : Collapsed ;
}
FText SStateTreeViewRow : : GetWarningsTooltipText ( ) const
{
FText Warnings = FText : : GetEmpty ( ) ;
GetStateWarnings ( & Warnings ) ;
return Warnings ;
}
2022-09-01 09:06:53 -04:00
bool SStateTreeViewRow : : HasParentTransitionForTrigger ( const UStateTreeState & State , const EStateTreeTransitionTrigger Trigger ) const
2021-09-28 13:33:17 -04:00
{
2022-09-01 09:06:53 -04:00
EStateTreeTransitionTrigger CombinedTrigger = EStateTreeTransitionTrigger : : None ;
2021-09-28 13:33:17 -04:00
for ( const UStateTreeState * ParentState = State . Parent ; ParentState ! = nullptr ; ParentState = ParentState - > Parent )
{
2021-10-21 04:08:20 -04:00
for ( const FStateTreeTransition & Transition : ParentState - > Transitions )
2021-09-28 13:33:17 -04:00
{
2022-09-01 09:06:53 -04:00
CombinedTrigger | = Transition . Trigger ;
2021-09-28 13:33:17 -04:00
}
}
2022-09-01 09:06:53 -04:00
return EnumHasAllFlags ( CombinedTrigger , Trigger ) ;
2021-09-28 13:33:17 -04:00
}
2023-06-14 06:17:56 -04:00
FText SStateTreeViewRow : : GetLinkDescription ( const FStateTreeStateLink & Link )
{
switch ( Link . LinkType )
{
case EStateTreeTransitionType : : None :
2024-04-11 04:14:59 -04:00
return LOCTEXT ( " TransitionNoneStyled " , " <i>None</> " ) ;
2023-06-14 06:17:56 -04:00
break ;
case EStateTreeTransitionType : : Succeeded :
2024-04-11 04:14:59 -04:00
return LOCTEXT ( " TransitionTreeSucceededStyled " , " <i>Succeeded</> " ) ;
2023-06-14 06:17:56 -04:00
break ;
case EStateTreeTransitionType : : Failed :
2024-04-11 04:14:59 -04:00
return LOCTEXT ( " TransitionTreeFailedStyled " , " <i>Failed</> " ) ;
2023-06-14 06:17:56 -04:00
break ;
case EStateTreeTransitionType : : NextState :
2024-04-11 04:14:59 -04:00
return LOCTEXT ( " TransitionNextStateStyled " , " <i>Next</> " ) ;
2023-06-14 06:17:56 -04:00
break ;
2023-10-17 16:15:53 -04:00
case EStateTreeTransitionType : : NextSelectableState :
2024-04-11 04:14:59 -04:00
return LOCTEXT ( " TransitionNextSelectableStateStyled " , " <i>Next Selectable</s> " ) ;
2023-10-17 16:15:53 -04:00
break ;
2023-06-14 06:17:56 -04:00
case EStateTreeTransitionType : : GotoState :
return FText : : FromName ( Link . Name ) ;
break ;
default :
ensureMsgf ( false , TEXT ( " Unhandled transition type. " ) ) ;
break ;
}
return FText : : GetEmpty ( ) ;
} ;
2024-04-11 04:14:59 -04:00
bool SStateTreeViewRow : : IsLeafState ( ) const
{
const UStateTreeState * State = WeakState . Get ( ) ;
return State
& & State - > Children . Num ( ) = = 0
& & ! IsRootState ( )
& & ( State - > Type = = EStateTreeStateType : : State
| | State - > Type = = EStateTreeStateType : : Linked
| | State - > Type = = EStateTreeStateType : : LinkedAsset ) ;
}
2023-06-20 13:49:25 -04:00
FText SStateTreeViewRow : : GetTransitionsDesc ( const UStateTreeState & State , const EStateTreeTransitionTrigger Trigger , const FTransitionDescFilterOptions FilterOptions ) const
2021-09-28 13:33:17 -04:00
{
TArray < FText > DescItems ;
2024-04-05 03:37:02 -04:00
const UStateTreeEditorData * TreeEditorData = WeakEditorData . Get ( ) ;
2023-06-20 13:49:25 -04:00
2021-10-21 04:08:20 -04:00
for ( const FStateTreeTransition & Transition : State . Transitions )
2021-09-28 13:33:17 -04:00
{
2023-06-20 13:49:25 -04:00
// Apply filter for enabled/disabled transitions
if ( ( FilterOptions . Enabled = = ETransitionDescRequirement : : RequiredTrue & & Transition . bTransitionEnabled = = false )
| | ( FilterOptions . Enabled = = ETransitionDescRequirement : : RequiredFalse & & Transition . bTransitionEnabled ) )
{
continue ;
}
# if WITH_STATETREE_DEBUGGER
// Apply filter for transitions with/without breakpoint
const bool bHasBreakpoint = TreeEditorData ! = nullptr & & TreeEditorData - > HasBreakpoint ( Transition . ID , EStateTreeBreakpointType : : OnTransition ) ;
if ( ( FilterOptions . WithBreakpoint = = ETransitionDescRequirement : : RequiredTrue & & bHasBreakpoint = = false )
| | ( FilterOptions . WithBreakpoint = = ETransitionDescRequirement : : RequiredFalse & & bHasBreakpoint ) )
{
continue ;
}
# endif // WITH_STATETREE_DEBUGGER
const bool bMatch = FilterOptions . bUseMask ? EnumHasAnyFlags ( Transition . Trigger , Trigger ) : Transition . Trigger = = Trigger ;
2022-09-01 09:06:53 -04:00
if ( bMatch )
2021-09-28 13:33:17 -04:00
{
2023-06-14 06:17:56 -04:00
DescItems . Add ( GetLinkDescription ( Transition . State ) ) ;
2021-09-28 13:33:17 -04:00
}
}
2023-06-14 06:17:56 -04:00
// Find states from transition tasks
if ( EnumHasAnyFlags ( Trigger , EStateTreeTransitionTrigger : : OnTick | EStateTreeTransitionTrigger : : OnEvent ) )
{
auto AddLinksFromStruct = [ & DescItems ] ( FStateTreeDataView Struct )
{
if ( ! Struct . IsValid ( ) )
{
return ;
}
for ( TPropertyValueIterator < FStructProperty > It ( Struct . GetStruct ( ) , Struct . GetMemory ( ) ) ; It ; + + It )
{
const UScriptStruct * StructType = It . Key ( ) - > Struct ;
if ( StructType = = TBaseStructure < FStateTreeStateLink > : : Get ( ) )
{
const FStateTreeStateLink & Link = * static_cast < const FStateTreeStateLink * > ( It . Value ( ) ) ;
if ( Link . LinkType ! = EStateTreeTransitionType : : None )
{
DescItems . Add ( GetLinkDescription ( Link ) ) ;
}
}
}
} ;
for ( const FStateTreeEditorNode & Task : State . Tasks )
{
AddLinksFromStruct ( FStateTreeDataView ( Task . Node . GetScriptStruct ( ) , const_cast < uint8 * > ( Task . Node . GetMemory ( ) ) ) ) ;
AddLinksFromStruct ( Task . GetInstance ( ) ) ;
}
AddLinksFromStruct ( FStateTreeDataView ( State . SingleTask . Node . GetScriptStruct ( ) , const_cast < uint8 * > ( State . SingleTask . Node . GetMemory ( ) ) ) ) ;
AddLinksFromStruct ( State . SingleTask . GetInstance ( ) ) ;
}
2024-04-11 04:14:59 -04:00
if ( IsLeafState ( )
2021-09-28 13:33:17 -04:00
& & DescItems . Num ( ) = = 0
2022-09-01 09:06:53 -04:00
& & EnumHasAnyFlags ( Trigger , EStateTreeTransitionTrigger : : OnStateCompleted ) )
2021-09-28 13:33:17 -04:00
{
2022-09-01 09:06:53 -04:00
if ( HasParentTransitionForTrigger ( State , Trigger ) )
2021-09-28 13:33:17 -04:00
{
2024-04-11 04:14:59 -04:00
DescItems . Add ( LOCTEXT ( " TransitionActionHandleInParentStyled " , " <i>Parent</> " ) ) ;
2021-09-28 13:33:17 -04:00
}
else
{
2024-04-11 04:14:59 -04:00
DescItems . Add ( LOCTEXT ( " TransitionActionRoot " , " <i>Root</> " ) ) ;
2021-09-28 13:33:17 -04:00
}
}
return FText : : Join ( FText : : FromString ( TEXT ( " , " ) ) , DescItems ) ;
}
2024-04-11 04:14:59 -04:00
const FSlateBrush * SStateTreeViewRow : : GetTransitionsIcon ( const UStateTreeState & State , const EStateTreeTransitionTrigger Trigger , const FTransitionDescFilterOptions FilterOptions ) const
2021-09-28 13:33:17 -04:00
{
enum EIconType
{
IconNone = 0 ,
2024-04-11 04:14:59 -04:00
IconGoto = 1 < < 0 ,
IconNext = 1 < < 1 ,
IconParent = 1 < < 2 ,
2023-03-14 13:35:46 -04:00
} ;
2021-09-28 13:33:17 -04:00
uint8 IconType = IconNone ;
2024-04-05 03:37:02 -04:00
const UStateTreeEditorData * EditorData = WeakEditorData . Get ( ) ;
2023-06-20 13:49:25 -04:00
2021-10-21 04:08:20 -04:00
for ( const FStateTreeTransition & Transition : State . Transitions )
2021-09-28 13:33:17 -04:00
{
2023-06-20 13:49:25 -04:00
// Apply filter for enabled/disabled transitions
if ( ( FilterOptions . Enabled = = ETransitionDescRequirement : : RequiredTrue & & Transition . bTransitionEnabled = = false )
| | ( FilterOptions . Enabled = = ETransitionDescRequirement : : RequiredFalse & & Transition . bTransitionEnabled ) )
{
continue ;
}
# if WITH_STATETREE_DEBUGGER
// Apply filter for transitions with/without breakpoint
2024-04-05 03:37:02 -04:00
const bool bHasBreakpoint = EditorData ! = nullptr & & EditorData - > HasBreakpoint ( Transition . ID , EStateTreeBreakpointType : : OnTransition ) ;
2023-06-20 13:49:25 -04:00
if ( ( FilterOptions . WithBreakpoint = = ETransitionDescRequirement : : RequiredTrue & & bHasBreakpoint = = false )
| | ( FilterOptions . WithBreakpoint = = ETransitionDescRequirement : : RequiredFalse & & bHasBreakpoint ) )
{
continue ;
}
# endif // WITH_STATETREE_DEBUGGER
2021-09-28 13:33:17 -04:00
// The icons here depict "transition direction", not the type specifically.
2023-06-20 13:49:25 -04:00
const bool bMatch = FilterOptions . bUseMask ? EnumHasAnyFlags ( Transition . Trigger , Trigger ) : Transition . Trigger = = Trigger ;
2022-09-01 09:06:53 -04:00
if ( bMatch )
2021-09-28 13:33:17 -04:00
{
2023-01-23 12:48:04 -05:00
switch ( Transition . State . LinkType )
2021-09-28 13:33:17 -04:00
{
2023-01-23 12:48:04 -05:00
case EStateTreeTransitionType : : None :
2024-04-11 04:14:59 -04:00
IconType | = IconGoto ;
2021-09-28 13:33:17 -04:00
break ;
case EStateTreeTransitionType : : Succeeded :
2024-04-11 04:14:59 -04:00
IconType | = IconGoto ;
2021-09-28 13:33:17 -04:00
break ;
case EStateTreeTransitionType : : Failed :
2024-04-11 04:14:59 -04:00
IconType | = IconGoto ;
2021-09-28 13:33:17 -04:00
break ;
case EStateTreeTransitionType : : NextState :
2023-10-17 16:15:53 -04:00
case EStateTreeTransitionType : : NextSelectableState :
2024-04-11 04:14:59 -04:00
IconType | = IconNext ;
2021-09-28 13:33:17 -04:00
break ;
case EStateTreeTransitionType : : GotoState :
2024-04-11 04:14:59 -04:00
IconType | = IconGoto ;
2021-09-28 13:33:17 -04:00
break ;
default :
ensureMsgf ( false , TEXT ( " Unhandled transition type. " ) ) ;
break ;
}
}
}
if ( FMath : : CountBits ( static_cast < uint64 > ( IconType ) ) > 1 )
{
// Prune down to just one icon.
2024-04-11 04:14:59 -04:00
IconType = IconGoto ;
2021-09-28 13:33:17 -04:00
}
2024-04-11 04:14:59 -04:00
if ( IsLeafState ( )
2023-03-14 13:35:46 -04:00
& & IconType = = IconNone
& & EnumHasAnyFlags ( Trigger , EStateTreeTransitionTrigger : : OnStateCompleted ) )
2021-09-28 13:33:17 -04:00
{
2023-12-14 02:55:56 -05:00
// Transition is handled on parent state, or implicit Root.
2024-04-11 04:14:59 -04:00
IconType = IconParent ;
2021-09-28 13:33:17 -04:00
}
2024-04-01 18:02:13 -04:00
switch ( IconType )
2021-09-28 13:33:17 -04:00
{
2024-04-11 04:14:59 -04:00
case IconGoto :
return FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.Transition.Goto " ) ;
case IconNext :
return FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.Transition.Next " ) ;
case IconParent :
return FStateTreeEditorStyle : : Get ( ) . GetBrush ( " StateTreeEditor.Transition.Parent " ) ;
2024-04-01 18:02:13 -04:00
default :
2024-04-11 04:14:59 -04:00
break ;
2024-03-25 11:46:14 -04:00
}
2024-04-11 04:14:59 -04:00
return nullptr ;
2021-09-28 13:33:17 -04:00
}
2022-09-01 09:06:53 -04:00
EVisibility SStateTreeViewRow : : GetTransitionsVisibility ( const UStateTreeState & State , const EStateTreeTransitionTrigger Trigger ) const
2021-09-28 13:33:17 -04:00
{
2023-05-08 13:32:14 -04:00
// Handle completed, succeeded and failed transitions.
2022-09-05 09:08:59 -04:00
if ( EnumHasAnyFlags ( Trigger , EStateTreeTransitionTrigger : : OnStateCompleted ) )
2022-09-01 09:06:53 -04:00
{
2022-09-05 09:08:59 -04:00
EStateTreeTransitionTrigger HandledTriggers = EStateTreeTransitionTrigger : : None ;
bool bExactMatch = false ;
2022-09-01 09:06:53 -04:00
for ( const FStateTreeTransition & Transition : State . Transitions )
{
2023-06-20 13:49:25 -04:00
// Skip disabled transitions
if ( Transition . bTransitionEnabled = = false )
{
continue ;
}
2022-09-05 09:08:59 -04:00
HandledTriggers | = Transition . Trigger ;
bExactMatch | = ( Transition . Trigger = = Trigger ) ;
2023-06-20 13:49:25 -04:00
if ( bExactMatch )
{
break ;
}
2022-09-01 09:06:53 -04:00
}
2021-09-28 13:33:17 -04:00
2022-09-05 09:08:59 -04:00
// Assume that leaf states should have completion transitions.
2024-04-11 04:14:59 -04:00
if ( ! bExactMatch & & IsLeafState ( ) )
2022-09-05 09:08:59 -04:00
{
// Find the missing transition type, note: Completed = Succeeded|Failed.
const EStateTreeTransitionTrigger MissingTriggers = HandledTriggers ^ EStateTreeTransitionTrigger : : OnStateCompleted ;
return MissingTriggers = = Trigger ? EVisibility : : Visible : EVisibility : : Collapsed ;
}
return bExactMatch ? EVisibility : : Visible : EVisibility : : Collapsed ;
}
2023-06-14 06:17:56 -04:00
// Find states from transition tasks
if ( EnumHasAnyFlags ( Trigger , EStateTreeTransitionTrigger : : OnTick | EStateTreeTransitionTrigger : : OnEvent ) )
{
auto HasAnyLinksInStruct = [ ] ( FStateTreeDataView Struct ) - > bool
{
if ( ! Struct . IsValid ( ) )
{
return false ;
}
for ( TPropertyValueIterator < FStructProperty > It ( Struct . GetStruct ( ) , Struct . GetMemory ( ) ) ; It ; + + It )
{
const UScriptStruct * StructType = It . Key ( ) - > Struct ;
if ( StructType = = TBaseStructure < FStateTreeStateLink > : : Get ( ) )
{
const FStateTreeStateLink & Link = * static_cast < const FStateTreeStateLink * > ( It . Value ( ) ) ;
if ( Link . LinkType ! = EStateTreeTransitionType : : None )
{
return true ;
}
}
}
return false ;
} ;
for ( const FStateTreeEditorNode & Task : State . Tasks )
{
if ( HasAnyLinksInStruct ( FStateTreeDataView ( Task . Node . GetScriptStruct ( ) , const_cast < uint8 * > ( Task . Node . GetMemory ( ) ) ) )
| | HasAnyLinksInStruct ( Task . GetInstance ( ) ) )
{
return EVisibility : : Visible ;
}
}
if ( HasAnyLinksInStruct ( FStateTreeDataView ( State . SingleTask . Node . GetScriptStruct ( ) , const_cast < uint8 * > ( State . SingleTask . Node . GetMemory ( ) ) ) )
| | HasAnyLinksInStruct ( State . SingleTask . GetInstance ( ) ) )
{
return EVisibility : : Visible ;
}
}
2022-09-05 09:08:59 -04:00
// Handle the test
2021-10-21 04:08:20 -04:00
for ( const FStateTreeTransition & Transition : State . Transitions )
2021-09-28 13:33:17 -04:00
{
2023-06-20 13:49:25 -04:00
// Skip disabled transitions
if ( Transition . bTransitionEnabled = = false )
{
continue ;
}
2022-09-05 09:08:59 -04:00
if ( EnumHasAnyFlags ( Trigger , Transition . Trigger ) )
{
return EVisibility : : Visible ;
}
2021-09-28 13:33:17 -04:00
}
2022-09-05 09:08:59 -04:00
return EVisibility : : Collapsed ;
2021-09-28 13:33:17 -04:00
}
2023-06-20 13:49:25 -04:00
EVisibility SStateTreeViewRow : : GetTransitionsBreakpointVisibility ( const UStateTreeState & State , const EStateTreeTransitionTrigger Trigger ) const
{
# if WITH_STATETREE_DEBUGGER
2024-04-05 03:37:02 -04:00
if ( const UStateTreeEditorData * EditorData = WeakEditorData . Get ( ) )
2023-06-20 13:49:25 -04:00
{
for ( const FStateTreeTransition & Transition : State . Transitions )
{
if ( Transition . bTransitionEnabled & & EnumHasAnyFlags ( Trigger , Transition . Trigger ) )
{
2024-04-05 03:37:02 -04:00
if ( EditorData - > HasBreakpoint ( Transition . ID , EStateTreeBreakpointType : : OnTransition ) )
2023-06-20 13:49:25 -04:00
{
return GetTransitionsVisibility ( State , Trigger ) ;
}
}
}
}
# endif // WITH_STATETREE_DEBUGGER
return EVisibility : : Collapsed ;
}
2021-09-28 13:33:17 -04:00
EVisibility SStateTreeViewRow : : GetCompletedTransitionVisibility ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
2022-09-01 09:06:53 -04:00
return GetTransitionsVisibility ( * State , EStateTreeTransitionTrigger : : OnStateCompleted ) ;
2021-09-28 13:33:17 -04:00
}
return EVisibility : : Visible ;
}
2023-06-20 13:49:25 -04:00
EVisibility SStateTreeViewRow : : GetCompletedTransitionBreakpointVisibility ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
return GetTransitionsBreakpointVisibility ( * State , EStateTreeTransitionTrigger : : OnStateCompleted ) ;
}
return EVisibility : : Visible ;
}
2021-09-28 13:33:17 -04:00
FText SStateTreeViewRow : : GetCompletedTransitionsDesc ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
2022-09-01 09:06:53 -04:00
return GetTransitionsDesc ( * State , EStateTreeTransitionTrigger : : OnStateCompleted ) ;
2021-09-28 13:33:17 -04:00
}
return LOCTEXT ( " Invalid " , " Invalid " ) ;
}
2023-06-20 13:49:25 -04:00
FText SStateTreeViewRow : : GetCompletedTransitionWithBreakpointDesc ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
FTransitionDescFilterOptions FilterOptions ;
FilterOptions . WithBreakpoint = ETransitionDescRequirement : : RequiredTrue ;
return GetTransitionsDesc ( * State , EStateTreeTransitionTrigger : : OnStateCompleted , FilterOptions ) ;
}
return FText : : GetEmpty ( ) ;
}
2024-04-11 04:14:59 -04:00
const FSlateBrush * SStateTreeViewRow : : GetCompletedTransitionsIcon ( ) const
2021-09-28 13:33:17 -04:00
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
2022-09-01 09:06:53 -04:00
return GetTransitionsIcon ( * State , EStateTreeTransitionTrigger : : OnStateCompleted ) ;
2021-09-28 13:33:17 -04:00
}
2024-04-11 04:14:59 -04:00
return nullptr ;
2021-09-28 13:33:17 -04:00
}
EVisibility SStateTreeViewRow : : GetSucceededTransitionVisibility ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
2022-09-01 09:06:53 -04:00
return GetTransitionsVisibility ( * State , EStateTreeTransitionTrigger : : OnStateSucceeded ) ;
2021-09-28 13:33:17 -04:00
}
return EVisibility : : Collapsed ;
}
2023-06-20 13:49:25 -04:00
EVisibility SStateTreeViewRow : : GetSucceededTransitionBreakpointVisibility ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
return GetTransitionsBreakpointVisibility ( * State , EStateTreeTransitionTrigger : : OnStateSucceeded ) ;
}
return EVisibility : : Collapsed ;
}
2021-09-28 13:33:17 -04:00
FText SStateTreeViewRow : : GetSucceededTransitionDesc ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
2022-09-01 09:06:53 -04:00
return GetTransitionsDesc ( * State , EStateTreeTransitionTrigger : : OnStateSucceeded ) ;
2021-09-28 13:33:17 -04:00
}
return FText : : GetEmpty ( ) ;
}
2023-06-20 13:49:25 -04:00
FText SStateTreeViewRow : : GetSucceededTransitionWithBreakpointDesc ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
FTransitionDescFilterOptions FilterOptions ;
FilterOptions . WithBreakpoint = ETransitionDescRequirement : : RequiredTrue ;
return GetTransitionsDesc ( * State , EStateTreeTransitionTrigger : : OnStateSucceeded , FilterOptions ) ;
}
return FText : : GetEmpty ( ) ;
}
2024-04-11 04:14:59 -04:00
const FSlateBrush * SStateTreeViewRow : : GetSucceededTransitionIcon ( ) const
2021-09-28 13:33:17 -04:00
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
2022-09-01 09:06:53 -04:00
return GetTransitionsIcon ( * State , EStateTreeTransitionTrigger : : OnStateSucceeded ) ;
2021-09-28 13:33:17 -04:00
}
2024-04-11 04:14:59 -04:00
return nullptr ;
2021-09-28 13:33:17 -04:00
}
EVisibility SStateTreeViewRow : : GetFailedTransitionVisibility ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
2022-09-01 09:06:53 -04:00
return GetTransitionsVisibility ( * State , EStateTreeTransitionTrigger : : OnStateFailed ) ;
2021-09-28 13:33:17 -04:00
}
return EVisibility : : Collapsed ;
}
2023-06-20 13:49:25 -04:00
EVisibility SStateTreeViewRow : : GetFailedTransitionBreakpointVisibility ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
return GetTransitionsBreakpointVisibility ( * State , EStateTreeTransitionTrigger : : OnStateFailed ) ;
}
return EVisibility : : Collapsed ;
}
2021-09-28 13:33:17 -04:00
FText SStateTreeViewRow : : GetFailedTransitionDesc ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
2022-09-01 09:06:53 -04:00
return GetTransitionsDesc ( * State , EStateTreeTransitionTrigger : : OnStateFailed ) ;
2021-09-28 13:33:17 -04:00
}
return LOCTEXT ( " Invalid " , " Invalid " ) ;
}
2023-06-20 13:49:25 -04:00
FText SStateTreeViewRow : : GetFailedTransitionWithBreakpointDesc ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
FTransitionDescFilterOptions FilterOptions ;
FilterOptions . WithBreakpoint = ETransitionDescRequirement : : RequiredTrue ;
return GetTransitionsDesc ( * State , EStateTreeTransitionTrigger : : OnStateFailed , FilterOptions ) ;
}
return FText : : GetEmpty ( ) ;
}
2024-04-11 04:14:59 -04:00
const FSlateBrush * SStateTreeViewRow : : GetFailedTransitionIcon ( ) const
2021-09-28 13:33:17 -04:00
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
2022-09-01 09:06:53 -04:00
return GetTransitionsIcon ( * State , EStateTreeTransitionTrigger : : OnStateFailed ) ;
2021-09-28 13:33:17 -04:00
}
2024-04-11 04:14:59 -04:00
return nullptr ;
2021-09-28 13:33:17 -04:00
}
EVisibility SStateTreeViewRow : : GetConditionalTransitionsVisibility ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
2022-09-01 09:06:53 -04:00
return GetTransitionsVisibility ( * State , EStateTreeTransitionTrigger : : OnTick | EStateTreeTransitionTrigger : : OnEvent ) ;
2021-09-28 13:33:17 -04:00
}
return EVisibility : : Collapsed ;
}
2023-06-20 13:49:25 -04:00
EVisibility SStateTreeViewRow : : GetConditionalTransitionsBreakpointVisibility ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
return GetTransitionsBreakpointVisibility ( * State , EStateTreeTransitionTrigger : : OnTick | EStateTreeTransitionTrigger : : OnEvent ) ;
}
return EVisibility : : Collapsed ;
}
2021-09-28 13:33:17 -04:00
FText SStateTreeViewRow : : GetConditionalTransitionsDesc ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
2023-06-20 13:49:25 -04:00
FTransitionDescFilterOptions FilterOptions ;
FilterOptions . bUseMask = true ;
return GetTransitionsDesc ( * State , EStateTreeTransitionTrigger : : OnTick | EStateTreeTransitionTrigger : : OnEvent , FilterOptions ) ;
}
return FText : : GetEmpty ( ) ;
}
FText SStateTreeViewRow : : GetConditionalTransitionsWithBreakpointDesc ( ) const
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
FTransitionDescFilterOptions FilterOptions ;
FilterOptions . WithBreakpoint = ETransitionDescRequirement : : RequiredTrue ;
FilterOptions . bUseMask = true ;
return GetTransitionsDesc ( * State , EStateTreeTransitionTrigger : : OnTick | EStateTreeTransitionTrigger : : OnEvent , FilterOptions ) ;
2021-09-28 13:33:17 -04:00
}
2022-09-01 09:06:53 -04:00
return FText : : GetEmpty ( ) ;
2021-09-28 13:33:17 -04:00
}
2022-04-28 03:54:07 -04:00
bool SStateTreeViewRow : : IsRootState ( ) const
2021-09-28 13:33:17 -04:00
{
// Routines can be identified by not having parent state.
const UStateTreeState * State = WeakState . Get ( ) ;
return State ? State - > Parent = = nullptr : false ;
}
2022-09-01 09:06:53 -04:00
bool SStateTreeViewRow : : IsStateSelected ( ) const
2021-09-28 13:33:17 -04:00
{
if ( const UStateTreeState * State = WeakState . Get ( ) )
{
if ( StateTreeViewModel )
{
return StateTreeViewModel - > IsSelected ( State ) ;
}
}
return false ;
}
2022-09-01 09:06:53 -04:00
void SStateTreeViewRow : : HandleNodeLabelTextCommitted ( const FText & NewLabel , ETextCommit : : Type CommitType ) const
2021-09-28 13:33:17 -04:00
{
if ( StateTreeViewModel )
{
if ( UStateTreeState * State = WeakState . Get ( ) )
{
StateTreeViewModel - > RenameState ( State , FName ( * FText : : TrimPrecedingAndTrailing ( NewLabel ) . ToString ( ) ) ) ;
}
}
}
2022-09-01 09:06:53 -04:00
FReply SStateTreeViewRow : : HandleDragDetected ( const FGeometry & , const FPointerEvent & ) const
2021-09-28 13:33:17 -04:00
{
return FReply : : Handled ( ) . BeginDragDrop ( FActionTreeViewDragDrop : : New ( WeakState . Get ( ) ) ) ;
}
2022-09-30 11:31:57 -04:00
TOptional < EItemDropZone > SStateTreeViewRow : : HandleCanAcceptDrop ( const FDragDropEvent & DragDropEvent , EItemDropZone DropZone , TWeakObjectPtr < UStateTreeState > TargetState ) const
2021-09-28 13:33:17 -04:00
{
2022-09-01 09:06:53 -04:00
const TSharedPtr < FActionTreeViewDragDrop > DragDropOperation = DragDropEvent . GetOperationAs < FActionTreeViewDragDrop > ( ) ;
2021-09-28 13:33:17 -04:00
if ( DragDropOperation . IsValid ( ) )
{
// Cannot drop on selection or child of selection.
2022-09-30 11:31:57 -04:00
if ( StateTreeViewModel & & StateTreeViewModel - > IsChildOfSelection ( TargetState . Get ( ) ) )
2021-09-28 13:33:17 -04:00
{
return TOptional < EItemDropZone > ( ) ;
}
return DropZone ;
}
return TOptional < EItemDropZone > ( ) ;
}
2022-09-30 11:31:57 -04:00
FReply SStateTreeViewRow : : HandleAcceptDrop ( const FDragDropEvent & DragDropEvent , EItemDropZone DropZone , TWeakObjectPtr < UStateTreeState > TargetState ) const
2021-09-28 13:33:17 -04:00
{
2022-09-01 09:06:53 -04:00
const TSharedPtr < FActionTreeViewDragDrop > DragDropOperation = DragDropEvent . GetOperationAs < FActionTreeViewDragDrop > ( ) ;
2021-09-28 13:33:17 -04:00
if ( DragDropOperation . IsValid ( ) )
{
if ( StateTreeViewModel )
{
if ( DropZone = = EItemDropZone : : AboveItem )
{
2022-09-30 11:31:57 -04:00
StateTreeViewModel - > MoveSelectedStatesBefore ( TargetState . Get ( ) ) ;
2021-09-28 13:33:17 -04:00
}
else if ( DropZone = = EItemDropZone : : BelowItem )
{
2022-09-30 11:31:57 -04:00
StateTreeViewModel - > MoveSelectedStatesAfter ( TargetState . Get ( ) ) ;
2021-09-28 13:33:17 -04:00
}
else
{
2022-09-30 11:31:57 -04:00
StateTreeViewModel - > MoveSelectedStatesInto ( TargetState . Get ( ) ) ;
2021-09-28 13:33:17 -04:00
}
return FReply : : Handled ( ) ;
}
}
return FReply : : Unhandled ( ) ;
}
# undef LOCTEXT_NAMESPACE