Kaynağa Gözat

添加右键菜单

maboren 2 ay önce
ebeveyn
işleme
94b57bba85

+ 43 - 0
Ability/Plugins/EzAbility/Source/EzAbilityEditor/Private/AbleTreeEditorCommands.cpp

@@ -0,0 +1,43 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "AbleTreeEditorCommands.h"
+#include "Styling/AppStyle.h"
+
+#define LOCTEXT_NAMESPACE "StateTreeEditor"
+
+FAbleTreeEditorCommands::FAbleTreeEditorCommands() 
+	: TCommands(
+		TEXT("AbleTreeEditor"), // Context name for fast lookup
+		LOCTEXT("AbleTreeEditor", "StateTree Editor"), // Localized context name for displaying
+		NAME_None,
+		TEXT("StateTreeEditorStyle")
+	)
+{
+}
+
+void FAbleTreeEditorCommands::RegisterCommands()
+{
+	UI_COMMAND(Compile, "Compile", "Compile the current StateTree.", EUserInterfaceActionType::Button, FInputChord(EKeys::F7));
+	UI_COMMAND(SaveOnCompile_Never, "Never", "Sets the save-on-compile option to 'Never', meaning that your StateTree will not be saved when they are compiled", EUserInterfaceActionType::RadioButton, FInputChord());
+	UI_COMMAND(SaveOnCompile_SuccessOnly, "On Success Only", "Sets the save-on-compile option to 'Success Only', meaning that your StateTree will be saved whenever they are successfully compiled", EUserInterfaceActionType::RadioButton, FInputChord());
+	UI_COMMAND(SaveOnCompile_Always, "Always", "Sets the save-on-compile option to 'Always', meaning that your StateTree will be saved whenever they are compiled (even if there were errors)", EUserInterfaceActionType::RadioButton, FInputChord());
+	UI_COMMAND(LogCompilationResult, "Log compilation result", "After a StateTree compiles, log the internal content of the StateTree.", EUserInterfaceActionType::ToggleButton, FInputChord());
+
+	UI_COMMAND(AddSiblingState, "Add Sibling State", "Add a Sibling State", EUserInterfaceActionType::Button, FInputChord());
+	UI_COMMAND(AddChildState, "Add Child State", "Add a Child State", EUserInterfaceActionType::Button, FInputChord());
+	UI_COMMAND(CutStates, "Cut", "Cut Selected States", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Control, EKeys::X));
+	UI_COMMAND(CopyStates, "Copy", "Copy Selected States", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Control, EKeys::C));
+	UI_COMMAND(PasteStatesAsSiblings, "Paste As Siblings", "Paste States as Siblings", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Control, EKeys::V));
+	UI_COMMAND(PasteStatesAsChildren, "Paste As Children", "Paste States as Children", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Control | EModifierKey::Shift, EKeys::V));
+	UI_COMMAND(DuplicateStates, "Duplicate", "Duplicate Selected States", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Control, EKeys::D));
+	UI_COMMAND(DeleteStates, "Delete", "Delete Selected States", EUserInterfaceActionType::Button, FInputChord(EKeys::Delete));
+	UI_COMMAND(RenameState, "Rename", "Rename Selected State", EUserInterfaceActionType::Button, FInputChord(EKeys::F2));
+	UI_COMMAND(EnableStates, "State Enabled", "Enables Selected States", EUserInterfaceActionType::Check, FInputChord());
+
+//#if WITH_STATETREE_TRACE_DEBUGGER
+	UI_COMMAND(EnableOnEnterStateBreakpoint, "Break on Enter", "Adds or removes a breakpoint when entering the selected state(s)", EUserInterfaceActionType::Check, FInputChord(EKeys::F9));
+	UI_COMMAND(EnableOnExitStateBreakpoint, "Break on Exit", "Adds or removes a breakpoint when exiting the selected state(s)", EUserInterfaceActionType::Check, FInputChord(EModifierKey::Shift, EKeys::F9));
+//#endif //WITH_STATETREE_TRACE_DEBUGGER
+}
+
+#undef LOCTEXT_NAMESPACE

+ 1 - 0
Ability/Plugins/EzAbility/Source/EzAbilityEditor/Private/EzAbilityViewModule.cpp

@@ -1,5 +1,6 @@
 #include "EzAbilityViewModule.h"
 #include "EzAbilityViewPortSummoner.h"
+#include "AbleTreeEditorCommands.h"
 
 #define LOCTEXT_NAMESPACE "EzAbilityViewModule"
 

+ 58 - 0
Ability/Plugins/EzAbility/Source/EzAbilityEditor/Private/EzAbleTreeViewOperationMode.cpp

@@ -3,6 +3,7 @@
 
 #include "EzAbleTreeViewOperationMode.h"
 #include "EzAbilityState.h"
+#include "AbleTreeEditorCommands.h"
 
 #define LOCTEXT_NAMESPACE "AbleTreeEditor"
 
@@ -25,6 +26,8 @@ void FEzAbleTreeViewOperationMode::Init(UEzAbilityEditorData* InTreeData)
 	TreeDataWeak = InTreeData;
 
 	GEditor->RegisterForUndo(this);
+
+	FAbleTreeEditorCommands::Register();
 }
 
 void FEzAbleTreeViewOperationMode::PostUndo(bool bSuccess)
@@ -105,6 +108,61 @@ void FEzAbleTreeViewOperationMode::AddState(UEzAbilityState* AfterState)
 }
 
 
+void FEzAbleTreeViewOperationMode::RemoveSelectedStates()
+{
+// 	UEzAbilityEditorData* TreeData = TreeDataWeak.Get();
+// 	if (TreeData == nullptr)
+// 	{
+// 		return;
+// 	}
+// 
+// 	TArray<UEzAbilityState*> States;
+// 	GetSelectedStates(States);
+// 
+// 	// Remove items whose parent also exists in the selection.
+// 	UE::StateTree::Editor::RemoveContainedChildren(States);
+// 
+// 	if (States.Num() > 0)
+// 	{
+// 		const FScopedTransaction Transaction(LOCTEXT("DeleteStateTransaction", "Delete State"));
+// 
+// 		TSet<UStateTreeState*> AffectedParents;
+// 
+// 		for (UStateTreeState* StateToRemove : States)
+// 		{
+// 			if (StateToRemove)
+// 			{
+// 				StateToRemove->Modify();
+// 
+// 				UStateTreeState* ParentState = StateToRemove->Parent;
+// 				if (ParentState != nullptr)
+// 				{
+// 					AffectedParents.Add(ParentState);
+// 					ParentState->Modify();
+// 				}
+// 				else
+// 				{
+// 					AffectedParents.Add(nullptr);
+// 					TreeData->Modify();
+// 				}
+// 
+// 				TArray<TObjectPtr<UStateTreeState>>& ArrayToRemoveFrom = ParentState ? ParentState->Children : TreeData->SubTrees;
+// 				const int32 ItemIndex = ArrayToRemoveFrom.Find(StateToRemove);
+// 				if (ItemIndex != INDEX_NONE)
+// 				{
+// 					ArrayToRemoveFrom.RemoveAt(ItemIndex);
+// 					StateToRemove->Parent = nullptr;
+// 				}
+// 
+// 			}
+// 		}
+// 
+// 		OnStatesRemoved.Broadcast(AffectedParents);
+// 
+// 		ClearSelection();
+// 	}
+}
+
 void FEzAbleTreeViewOperationMode::GetSubTrees(TArray<TWeakObjectPtr<UEzAbilityState>>& OutSubtrees) const
 {
 	OutSubtrees.Reset();

+ 85 - 0
Ability/Plugins/EzAbility/Source/EzAbilityEditor/Private/SEzAbleTreeViewWidget.cpp

@@ -6,6 +6,7 @@
 #include "SPositiveActionButton.h"
 #include "Widgets/Layout/SScrollBox.h"
 #include "SEzAbleTreeViewRowWidget.h"
+#include "AbleTreeEditorCommands.h"
 
 #define LOCTEXT_NAMESPACE "AbleStateTreeEditor"
 
@@ -34,6 +35,9 @@ void SEzAbleTreeViewWidget::Construct(const FArguments& InArgs, TSharedPtr<FEzAb
 	TreeView = SNew(STreeView<TWeakObjectPtr<UEzAbilityState>>)
 		.OnGenerateRow(this, &SEzAbleTreeViewWidget::HandleGenerateRow)
 		.OnGetChildren(this, &SEzAbleTreeViewWidget::HandleGetChildren)
+		.OnSelectionChanged(this, &SEzAbleTreeViewWidget::HandleTreeSelectionChanged)
+		.OnExpansionChanged(this, &SEzAbleTreeViewWidget::HandleTreeExpansionChanged)
+		.OnContextMenuOpening(this, &SEzAbleTreeViewWidget::HandleContextMenuOpening )
 		.TreeItemsSource(&Subtrees)
 		.ItemHeight(32)
 		.AllowOverscroll(EAllowOverscroll::No)
@@ -162,9 +166,90 @@ void SEzAbleTreeViewWidget::UpdateTree(bool bExpandPersistent /*= false*/)
 	TreeView->RequestTreeRefresh();
 }
 
+void SEzAbleTreeViewWidget::HandleTreeSelectionChanged(TWeakObjectPtr<UEzAbilityState> InSelectedItem, ESelectInfo::Type SelectionType)
+{
+	
+}
+
+void SEzAbleTreeViewWidget::HandleTreeExpansionChanged(TWeakObjectPtr<UEzAbilityState> InSelectedItem, bool bExpanded)
+{
+	
+}
+
+TSharedPtr<SWidget> SEzAbleTreeViewWidget::HandleContextMenuOpening()
+{
+	if (!AbleTreeViewOperationMode)
+	{
+		return nullptr;
+	}
+
+	FMenuBuilder MenuBuilder(true, CommandList);
+
+	MenuBuilder.AddSubMenu(
+		LOCTEXT("AddState", "Add State"),
+		FText(),
+		FNewMenuDelegate::CreateLambda([this](FMenuBuilder& MenuBuilder)
+			{							
+				MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().AddSiblingState);
+				MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().AddChildState);
+			}),
+		/*bInOpenSubMenuOnClick =*/false,
+		FSlateIcon(FAppStyle::GetAppStyleSetName(), "Icons.Plus")
+	);
+
+	MenuBuilder.AddSeparator();
+
+	MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().CutStates);
+	MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().CopyStates);
+
+	MenuBuilder.AddSubMenu(
+		LOCTEXT("Paste", "Paste"),
+		FText(),
+		FNewMenuDelegate::CreateLambda([this](FMenuBuilder& MenuBuilder)
+			{
+				MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().PasteStatesAsSiblings);
+				MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().PasteStatesAsChildren);
+			}),
+		/*bInOpenSubMenuOnClick =*/false,
+		FSlateIcon(FAppStyle::GetAppStyleSetName(), "GenericCommands.Paste")
+	);
+
+	MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().DuplicateStates);
+	MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().DeleteStates);
+	MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().RenameState);
+	MenuBuilder.AddSeparator();
+	MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().EnableStates);
+
+//#if WITH_STATETREE_TRACE_DEBUGGER
+	MenuBuilder.AddSeparator();
+	MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().EnableOnEnterStateBreakpoint);
+	MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().EnableOnExitStateBreakpoint);
+//#endif // WITH_STATETREE_TRACE_DEBUGGER
+
+	return MenuBuilder.MakeWidget();
+}
+
 void SEzAbleTreeViewWidget::HandleModelStateAdded(UEzAbilityState* ParentState, UEzAbilityState* NewState)
 {	
 	TreeView->RequestTreeRefresh();
 }
 
+void SEzAbleTreeViewWidget::BindCommands()
+{
+	const FAbleTreeEditorCommands& Commands = FAbleTreeEditorCommands::Get();
+
+	CommandList->MapAction(
+		Commands.DeleteStates,
+		FExecuteAction::CreateSP(this, &SStateTreeView::HandleDeleteStates),
+		FCanExecuteAction::CreateSP(this, &SStateTreeView::HasSelection));
+}
+
+void SEzAbleTreeViewWidget::HandleDeleteStates()
+{
+	if (AbleTreeViewOperationMode)
+	{
+		AbleTreeViewOperationMode->RemoveSelectedStates();
+	}
+}
+
 #undef LOCTEXT_NAMESPACE

+ 40 - 0
Ability/Plugins/EzAbility/Source/EzAbilityEditor/Public/AbleTreeEditorCommands.h

@@ -0,0 +1,40 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include "Framework/Commands/Commands.h"
+
+
+/**
+ * StateTree editor command set.
+ */
+class FAbleTreeEditorCommands : public TCommands<FAbleTreeEditorCommands>
+{
+public:
+	FAbleTreeEditorCommands();
+
+	// TCommands<> overrides
+	virtual void RegisterCommands() override;
+
+	TSharedPtr<FUICommandInfo> Compile;
+	TSharedPtr<FUICommandInfo> SaveOnCompile_Never;
+	TSharedPtr<FUICommandInfo> SaveOnCompile_SuccessOnly;
+	TSharedPtr<FUICommandInfo> SaveOnCompile_Always;
+	TSharedPtr<FUICommandInfo> LogCompilationResult;
+
+	TSharedPtr<FUICommandInfo> AddSiblingState;
+	TSharedPtr<FUICommandInfo> AddChildState;
+	TSharedPtr<FUICommandInfo> RenameState;
+	TSharedPtr<FUICommandInfo> CutStates;
+	TSharedPtr<FUICommandInfo> CopyStates;
+	TSharedPtr<FUICommandInfo> PasteStatesAsSiblings;
+	TSharedPtr<FUICommandInfo> PasteStatesAsChildren;
+	TSharedPtr<FUICommandInfo> DuplicateStates;
+	TSharedPtr<FUICommandInfo> DeleteStates;
+	TSharedPtr<FUICommandInfo> EnableStates;
+
+//#if WITH_STATETREE_TRACE_DEBUGGER
+	TSharedPtr<FUICommandInfo> EnableOnEnterStateBreakpoint;
+	TSharedPtr<FUICommandInfo> EnableOnExitStateBreakpoint;
+//#endif // WITH_STATETREE_TRACE_DEBUGGER
+};

+ 14 - 4
Ability/Plugins/EzAbility/Source/EzAbilityEditor/Public/SEzAbleTreeViewWidget.h

@@ -27,7 +27,16 @@ public:
 	void HandleGetChildren(TWeakObjectPtr<UEzAbilityState> InParent, TArray<TWeakObjectPtr<UEzAbilityState>>& OutChildren);
 	void UpdateTree(bool bExpandPersistent = false);
 
+	void HandleTreeSelectionChanged(TWeakObjectPtr<UEzAbilityState> InSelectedItem, ESelectInfo::Type SelectionType);
+	void HandleTreeExpansionChanged(TWeakObjectPtr<UEzAbilityState> InSelectedItem, bool bExpanded);
+	TSharedPtr<SWidget> HandleContextMenuOpening();
 	void HandleModelStateAdded(UEzAbilityState* ParentState, UEzAbilityState* NewState);
+
+	void BindCommands();
+
+	//Action Handlers
+	void HandleDeleteStates();
+
 public:
 
 	TSharedPtr<FEzAbleTreeViewOperationMode> AbleTreeViewOperationMode;
@@ -36,9 +45,10 @@ public:
 	TSharedPtr<SScrollBox> ViewBox;
 	TArray<TWeakObjectPtr<UEzAbilityState>>				   Subtrees;
 
+	TSharedPtr<FUICommandList> CommandList;
 
-	TArray<TWeakObjectPtr<UEzAbilityState>> TestState;
-	TArray<TObjectPtr<UEzAbilityState>>	TestStrongState;
-
-	TObjectPtr<UEzAbilityState>	TestAddState;
+// 	TArray<TWeakObjectPtr<UEzAbilityState>> TestState;
+// 	TArray<TObjectPtr<UEzAbilityState>>	TestStrongState;
+// 
+// 	TObjectPtr<UEzAbilityState>	TestAddState;
 };