Selaa lähdekoodia

增加删除功能

maboren 2 kuukautta sitten
vanhempi
commit
58616508ad

+ 156 - 53
Ability/Plugins/EzAbility/Source/EzAbilityEditor/Private/EzAbleTreeViewOperationMode.cpp

@@ -8,7 +8,8 @@
 #define LOCTEXT_NAMESPACE "AbleTreeEditor"
 
 FEzAbleTreeViewOperationMode::FEzAbleTreeViewOperationMode()
- : TreeDataWeak(nullptr)
+ : TreeDataWeak(nullptr),
+   AbleTreeViewCommandList(MakeShared<FUICommandList>())
 {
 	
 }
@@ -26,7 +27,7 @@ void FEzAbleTreeViewOperationMode::Init(UEzAbilityEditorData* InTreeData)
 	TreeDataWeak = InTreeData;
 
 	GEditor->RegisterForUndo(this);
-
+	//AbleTreeViewCommandList = MakeShared<FUICommandList>();
 	FAbleTreeEditorCommands::Register();
 }
 
@@ -108,59 +109,161 @@ void FEzAbleTreeViewOperationMode::AddState(UEzAbilityState* AfterState)
 }
 
 
+void FEzAbleTreeViewOperationMode::ClearSelection()
+{
+	SelectedStates.Reset();
+
+	const TArray<TWeakObjectPtr<UEzAbilityState>> SelectedStatesArr;
+	OnSelectionChanged.Broadcast(SelectedStatesArr);
+}
+
+void FEzAbleTreeViewOperationMode::SetSelection(UEzAbilityState* Selected)
+{
+	SelectedStates.Reset();
+
+	SelectedStates.Add(Selected);
+
+	TArray<TWeakObjectPtr<UEzAbilityState>> SelectedStatesArr;
+	SelectedStatesArr.Add(Selected);
+	OnSelectionChanged.Broadcast(SelectedStatesArr);
+}
+
+void FEzAbleTreeViewOperationMode::SetSelection(const TArray<TWeakObjectPtr<UEzAbilityState>>& InSelectedStates)
+{
+	SelectedStates.Reset();
+
+	for (const TWeakObjectPtr<UEzAbilityState>& State : InSelectedStates)
+	{
+		if (State.Get())
+		{
+			SelectedStates.Add(State);
+		}
+	}
+
+	TArray<FGuid> SelectedTaskIDArr;
+	OnSelectionChanged.Broadcast(InSelectedStates);
+}
+
+bool FEzAbleTreeViewOperationMode::HasSelection() const
+{
+	return SelectedStates.Num() > 0;
+}
+
 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();
-// 	}
+	UEzAbilityEditorData* TreeData = TreeDataWeak.Get();
+	if (TreeData == nullptr)
+	{
+		return;
+	}
+
+	TArray<UEzAbilityState*> States;
+	GetSelectedStates(States);
+
+	// Remove items whose parent also exists in the selection.
+	RemoveContainedChildren(States);
+	//UE::StateTree::Editor::RemoveContainedChildren(States);
+
+	if (States.Num() > 0)
+	{
+		const FScopedTransaction Transaction(LOCTEXT("DeleteStateTransaction", "Delete State"));
+
+		TSet<UEzAbilityState*> AffectedParents;
+
+		for (UEzAbilityState* StateToRemove : States)
+		{
+			if (StateToRemove)
+			{
+				StateToRemove->Modify();
+
+				UEzAbilityState* ParentState = StateToRemove->Parent;
+				if (ParentState != nullptr)
+				{
+					AffectedParents.Add(ParentState);
+					ParentState->Modify();
+				}
+				else
+				{
+					AffectedParents.Add(nullptr);
+					TreeData->Modify();
+				}
+
+				TArray<TObjectPtr<UEzAbilityState>>& 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::GetSelectedStates(TArray<UEzAbilityState*>& OutSelectedStates) const
+{
+	OutSelectedStates.Reset();
+	for (const TWeakObjectPtr<UEzAbilityState>& WeakState : SelectedStates)
+	{
+		if (UEzAbilityState* State = WeakState.Get())
+		{
+			OutSelectedStates.Add(State);
+		}
+	}
+}
+
+void FEzAbleTreeViewOperationMode::GetSelectedStates(TArray<TWeakObjectPtr<UEzAbilityState>>& OutSelectedStates) const
+{
+	OutSelectedStates.Reset();
+	for (const TWeakObjectPtr<UEzAbilityState>& WeakState : SelectedStates)
+	{
+		if (WeakState.Get())
+		{
+			OutSelectedStates.Add(WeakState);
+		}
+	}
+}
+
+void FEzAbleTreeViewOperationMode::RemoveContainedChildren(TArray<UEzAbilityState*>& States)
+{
+	TSet<UEzAbilityState*> UniqueStates;
+	for (UEzAbilityState* State : States)
+	{
+		UniqueStates.Add(State);
+	}
+
+	for (int32 i = 0; i < States.Num(); )
+	{
+		UEzAbilityState* State = States[i];
+
+		// Walk up the parent state sand if the current state
+		// exists in any of them, remove it.
+		UEzAbilityState* StateParent = State->Parent;
+		bool bShouldRemove = false;
+		while (StateParent)
+		{
+			if (UniqueStates.Contains(StateParent))
+			{
+				bShouldRemove = true;
+				break;
+			}
+			StateParent = StateParent->Parent;
+		}
+
+		if (bShouldRemove)
+		{
+			States.RemoveAt(i);
+		}
+		else
+		{
+			i++;
+		}
+	}
 }
 
 void FEzAbleTreeViewOperationMode::GetSubTrees(TArray<TWeakObjectPtr<UEzAbilityState>>& OutSubtrees) const

+ 43 - 3
Ability/Plugins/EzAbility/Source/EzAbilityEditor/Private/SEzAbleTreeViewWidget.cpp

@@ -103,7 +103,13 @@ void SEzAbleTreeViewWidget::Construct(const FArguments& InArgs, TSharedPtr<FEzAb
 		];
 
 
+		if (CommandList = AbleTreeViewOperationMode->AbleTreeViewCommandList)
+		{
+			BindCommands();	
+		}
+
 	UpdateTree(true);
+	
 }
 END_SLATE_FUNCTION_BUILD_OPTIMIZATION
 
@@ -168,7 +174,22 @@ void SEzAbleTreeViewWidget::UpdateTree(bool bExpandPersistent /*= false*/)
 
 void SEzAbleTreeViewWidget::HandleTreeSelectionChanged(TWeakObjectPtr<UEzAbilityState> InSelectedItem, ESelectInfo::Type SelectionType)
 {
-	
+	if (!AbleTreeViewOperationMode)
+	{
+		return;
+	}
+
+	// Do not report code based selection changes.
+	if (SelectionType == ESelectInfo::Direct)
+	{
+		return;
+	}
+
+	TArray<TWeakObjectPtr<UEzAbilityState>> SelectedItems = TreeView->GetSelectedItems();
+
+	bUpdatingSelection = true;
+	AbleTreeViewOperationMode->SetSelection(SelectedItems);
+	bUpdatingSelection = false;
 }
 
 void SEzAbleTreeViewWidget::HandleTreeExpansionChanged(TWeakObjectPtr<UEzAbilityState> InSelectedItem, bool bExpanded)
@@ -234,14 +255,20 @@ void SEzAbleTreeViewWidget::HandleModelStateAdded(UEzAbilityState* ParentState,
 	TreeView->RequestTreeRefresh();
 }
 
+
+bool SEzAbleTreeViewWidget::HasSelection() const
+{
+	return AbleTreeViewOperationMode && AbleTreeViewOperationMode->HasSelection();
+}
+
 void SEzAbleTreeViewWidget::BindCommands()
 {
 	const FAbleTreeEditorCommands& Commands = FAbleTreeEditorCommands::Get();
 
 	CommandList->MapAction(
 		Commands.DeleteStates,
-		FExecuteAction::CreateSP(this, &SStateTreeView::HandleDeleteStates),
-		FCanExecuteAction::CreateSP(this, &SStateTreeView::HasSelection));
+		FExecuteAction::CreateSP(this, &SEzAbleTreeViewWidget::HandleDeleteStates),
+		FCanExecuteAction::CreateSP(this, &SEzAbleTreeViewWidget::HasSelection));
 }
 
 void SEzAbleTreeViewWidget::HandleDeleteStates()
@@ -249,6 +276,19 @@ void SEzAbleTreeViewWidget::HandleDeleteStates()
 	if (AbleTreeViewOperationMode)
 	{
 		AbleTreeViewOperationMode->RemoveSelectedStates();
+		TreeView->RequestTreeRefresh();
+	}
+}
+
+FReply SEzAbleTreeViewWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent)
+{
+	if (CommandList->ProcessCommandBindings(InKeyEvent))
+	{
+		return FReply::Handled();
+	}
+	else
+	{
+		return SCompoundWidget::OnKeyDown(MyGeometry, InKeyEvent);
 	}
 }
 

+ 24 - 0
Ability/Plugins/EzAbility/Source/EzAbilityEditor/Public/EzAbleTreeViewOperationMode.h

@@ -18,6 +18,8 @@ class EZABILITYEDITOR_API FEzAbleTreeViewOperationMode : public FEditorUndoClien
 public:
 	
 	DECLARE_MULTICAST_DELEGATE_TwoParams(FOnStateAdded, UEzAbilityState* /*ParentState*/, UEzAbilityState* /*NewState*/);
+	DECLARE_MULTICAST_DELEGATE_OneParam(FOnSelectionChanged, const TArray<TWeakObjectPtr<UEzAbilityState>>& /*SelectedStates*/);
+	DECLARE_MULTICAST_DELEGATE_OneParam(FOnStatesRemoved, const TSet<UEzAbilityState*>& /*AffectedParents*/);
 
 	FEzAbleTreeViewOperationMode();
 	virtual ~FEzAbleTreeViewOperationMode() override;
@@ -28,14 +30,36 @@ public:
 	virtual void PostRedo(bool bSuccess) override;
 
 	void AddState(UEzAbilityState* AfterState);
+	void ClearSelection();
+	void SetSelection(UEzAbilityState* Selected);
+	void SetSelection(const TArray<TWeakObjectPtr<UEzAbilityState>>& InSelection);
+	bool HasSelection() const;
+	void RemoveSelectedStates();
+	void GetSelectedStates(TArray<UEzAbilityState*>& OutSelectedStates) const;
+	void GetSelectedStates(TArray<TWeakObjectPtr<UEzAbilityState>>& OutSelectedStates) const;
 
+	//in namespace
+	void RemoveContainedChildren(TArray<UEzAbilityState*>& States);
 
 	FOnStateAdded& GetOnStateAdded() { return OnStateAdded; }
 	void GetSubTrees(TArray<TWeakObjectPtr<UEzAbilityState>>& OutSubtrees) const;
+
+
+	// Called each time the selection changes.
+	FOnSelectionChanged& GetOnSelectionChanged() { return OnSelectionChanged; }
+
+	// Called each time a states are removed.
+	FOnStatesRemoved& GetOnStatesRemoved() { return OnStatesRemoved; }
+
+	//Test Code..
+	/** The command list used by the tree view. Stored here, so that other windows (e.g. debugger) can add commands to it, even if the tree view is not spawned yet. */
+	TSharedRef<FUICommandList>			AbleTreeViewCommandList;
 protected:
 
 	TWeakObjectPtr<UEzAbilityEditorData> TreeDataWeak;
 	TSet<TWeakObjectPtr<UEzAbilityState>> SelectedStates;
 
 	FOnStateAdded OnStateAdded;
+	FOnSelectionChanged OnSelectionChanged;
+	FOnStatesRemoved OnStatesRemoved;
 };

+ 7 - 0
Ability/Plugins/EzAbility/Source/EzAbilityEditor/Public/SEzAbleTreeViewWidget.h

@@ -32,11 +32,16 @@ public:
 	TSharedPtr<SWidget> HandleContextMenuOpening();
 	void HandleModelStateAdded(UEzAbilityState* ParentState, UEzAbilityState* NewState);
 
+
+	bool HasSelection() const;
 	void BindCommands();
 
 	//Action Handlers
 	void HandleDeleteStates();
 
+private:
+	virtual FReply OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent) override;
+
 public:
 
 	TSharedPtr<FEzAbleTreeViewOperationMode> AbleTreeViewOperationMode;
@@ -47,6 +52,8 @@ public:
 
 	TSharedPtr<FUICommandList> CommandList;
 
+	bool bUpdatingSelection;
+
 // 	TArray<TWeakObjectPtr<UEzAbilityState>> TestState;
 // 	TArray<TObjectPtr<UEzAbilityState>>	TestStrongState;
 //