SEzAbleTreeViewWidget.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. // Fill out your copyright notice in the Description page of Project Settings.
  2. #include "SEzAbleTreeViewWidget.h"
  3. #include "SlateOptMacros.h"
  4. #include "SPositiveActionButton.h"
  5. #include "Widgets/Layout/SScrollBox.h"
  6. #include "SEzAbleTreeViewRowWidget.h"
  7. #include "AbleTreeEditorCommands.h"
  8. #define LOCTEXT_NAMESPACE "AbleStateTreeEditor"
  9. BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
  10. void SEzAbleTreeViewWidget::Construct(const FArguments& InArgs, TSharedPtr<FEzAbleTreeViewOperationMode> InAbleTreeViewOperationMode)
  11. {
  12. AbleTreeViewOperationMode = InAbleTreeViewOperationMode;
  13. AbleTreeViewOperationMode->GetOnStateAdded().AddSP(this, &SEzAbleTreeViewWidget::HandleModelStateAdded);
  14. TSharedRef<SScrollBar> HorizontalScrollBar = SNew(SScrollBar)
  15. .Orientation(Orient_Horizontal)
  16. .Thickness(FVector2D(12.0f, 12.0f));
  17. TSharedRef<SScrollBar> VerticalScrollBar = SNew(SScrollBar)
  18. .Orientation(Orient_Vertical)
  19. .Thickness(FVector2D(12.0f, 12.0f));
  20. AbleTreeViewOperationMode->GetSubTrees(Subtrees);
  21. // UEzAbilityState* AbilityState = NewObject<UEzAbilityState>();
  22. // UEzAbilityState* AbilitySub = NewObject<UEzAbilityState>();
  23. // TestStrongState.Add(AbilityState);
  24. // TestState.Add(TestStrongState[0]);
  25. TreeView = SNew(STreeView<TWeakObjectPtr<UEzAbilityState>>)
  26. .OnGenerateRow(this, &SEzAbleTreeViewWidget::HandleGenerateRow)
  27. .OnGetChildren(this, &SEzAbleTreeViewWidget::HandleGetChildren)
  28. .OnSelectionChanged(this, &SEzAbleTreeViewWidget::HandleTreeSelectionChanged)
  29. .OnExpansionChanged(this, &SEzAbleTreeViewWidget::HandleTreeExpansionChanged)
  30. .OnContextMenuOpening(this, &SEzAbleTreeViewWidget::HandleContextMenuOpening )
  31. .TreeItemsSource(&Subtrees)
  32. .ItemHeight(32)
  33. .AllowOverscroll(EAllowOverscroll::No)
  34. .ExternalScrollbar(VerticalScrollBar);
  35. ChildSlot
  36. [
  37. SNew(SVerticalBox)
  38. + SVerticalBox::Slot()
  39. .VAlign(VAlign_Center)
  40. .AutoHeight()
  41. [
  42. SNew(SBorder)
  43. .BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
  44. .Padding(2.0f)
  45. [
  46. SNew(SHorizontalBox)
  47. // New State
  48. + SHorizontalBox::Slot()
  49. .VAlign(VAlign_Center)
  50. .Padding(4.0f, 2.0f)
  51. .AutoWidth()
  52. [
  53. SNew(SPositiveActionButton)
  54. .ToolTipText(LOCTEXT("AddStateToolTip", "Add New State"))
  55. .Icon(FAppStyle::Get().GetBrush("Icons.Plus"))
  56. .Text(LOCTEXT("AddState", "Add State"))
  57. .OnClicked(this, &SEzAbleTreeViewWidget::HandleAddStateButton)
  58. ]
  59. ]
  60. ]
  61. + SVerticalBox::Slot()
  62. .Padding(0.0f, 6.0f, 0.0f, 0.0f)
  63. [
  64. SNew(SHorizontalBox)
  65. + SHorizontalBox::Slot()
  66. .FillWidth(1.0f)
  67. .Padding(0.0f)
  68. [
  69. SAssignNew(ViewBox, SScrollBox)
  70. .Orientation(Orient_Horizontal)
  71. .ExternalScrollbar(HorizontalScrollBar)
  72. + SScrollBox::Slot()
  73. .FillSize(1.0f)
  74. [
  75. TreeView.ToSharedRef()
  76. ]
  77. ]
  78. + SHorizontalBox::Slot()
  79. .AutoWidth()
  80. [
  81. VerticalScrollBar
  82. ]
  83. ]
  84. + SVerticalBox::Slot()
  85. .AutoHeight()
  86. [
  87. HorizontalScrollBar
  88. ]
  89. ];
  90. if (CommandList = AbleTreeViewOperationMode->AbleTreeViewCommandList)
  91. {
  92. BindCommands();
  93. }
  94. UpdateTree(true);
  95. }
  96. END_SLATE_FUNCTION_BUILD_OPTIMIZATION
  97. FReply SEzAbleTreeViewWidget::HandleAddStateButton()
  98. {
  99. if (AbleTreeViewOperationMode == nullptr)
  100. {
  101. return FReply::Handled();
  102. }
  103. TArray<UEzAbilityState*> SelectedStates;
  104. //AbleTreeViewOperationMode->GetSelectedStates(SelectedStates);
  105. //UStateTreeState* FirstSelectedState = SelectedStates.Num() > 0 ? SelectedStates[0] : nullptr;
  106. // if (FirstSelectedState != nullptr)
  107. // {
  108. // // If the state is root, add child state, else sibling.
  109. // if (FirstSelectedState->Parent == nullptr)
  110. // {
  111. // StateTreeViewModel->AddChildState(FirstSelectedState);
  112. // TreeView->SetItemExpansion(FirstSelectedState, true);
  113. // }
  114. // else
  115. // {
  116. // StateTreeViewModel->AddState(FirstSelectedState);
  117. // }
  118. // }
  119. // else
  120. // {
  121. // // Add root state at the lowest level.
  122. // StateTreeViewModel->AddState(nullptr);
  123. // }
  124. AbleTreeViewOperationMode->AddState(nullptr);
  125. return FReply::Handled();
  126. }
  127. TSharedRef<ITableRow> SEzAbleTreeViewWidget::HandleGenerateRow(TWeakObjectPtr<UEzAbilityState> InState, const TSharedRef<STableViewBase>& InOwnerTableView)
  128. {
  129. return SNew(SEzAbleTreeViewRowWidget, InOwnerTableView, InState, ViewBox);
  130. }
  131. void SEzAbleTreeViewWidget::HandleGetChildren(TWeakObjectPtr<UEzAbilityState> InParent, TArray<TWeakObjectPtr<UEzAbilityState>>& OutChildren)
  132. {
  133. //Test Code.
  134. //UE_LOG(LogTemp, Log, TEXT("EZAbleTreeViewWidget HandleGetChildren"));
  135. //InParent->AddChildState(FName());
  136. if (const UEzAbilityState* Parent = InParent.Get())
  137. {
  138. OutChildren.Append(Parent->Children);
  139. }
  140. }
  141. void SEzAbleTreeViewWidget::UpdateTree(bool bExpandPersistent /*= false*/)
  142. {
  143. TreeView->RequestTreeRefresh();
  144. }
  145. void SEzAbleTreeViewWidget::HandleTreeSelectionChanged(TWeakObjectPtr<UEzAbilityState> InSelectedItem, ESelectInfo::Type SelectionType)
  146. {
  147. if (!AbleTreeViewOperationMode)
  148. {
  149. return;
  150. }
  151. // Do not report code based selection changes.
  152. if (SelectionType == ESelectInfo::Direct)
  153. {
  154. return;
  155. }
  156. TArray<TWeakObjectPtr<UEzAbilityState>> SelectedItems = TreeView->GetSelectedItems();
  157. bUpdatingSelection = true;
  158. AbleTreeViewOperationMode->SetSelection(SelectedItems);
  159. bUpdatingSelection = false;
  160. }
  161. void SEzAbleTreeViewWidget::HandleTreeExpansionChanged(TWeakObjectPtr<UEzAbilityState> InSelectedItem, bool bExpanded)
  162. {
  163. }
  164. TSharedPtr<SWidget> SEzAbleTreeViewWidget::HandleContextMenuOpening()
  165. {
  166. if (!AbleTreeViewOperationMode)
  167. {
  168. return nullptr;
  169. }
  170. FMenuBuilder MenuBuilder(true, CommandList);
  171. MenuBuilder.AddSubMenu(
  172. LOCTEXT("AddState", "Add State"),
  173. FText(),
  174. FNewMenuDelegate::CreateLambda([this](FMenuBuilder& MenuBuilder)
  175. {
  176. MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().AddSiblingState);
  177. MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().AddChildState);
  178. }),
  179. /*bInOpenSubMenuOnClick =*/false,
  180. FSlateIcon(FAppStyle::GetAppStyleSetName(), "Icons.Plus")
  181. );
  182. MenuBuilder.AddSeparator();
  183. MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().CutStates);
  184. MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().CopyStates);
  185. MenuBuilder.AddSubMenu(
  186. LOCTEXT("Paste", "Paste"),
  187. FText(),
  188. FNewMenuDelegate::CreateLambda([this](FMenuBuilder& MenuBuilder)
  189. {
  190. MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().PasteStatesAsSiblings);
  191. MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().PasteStatesAsChildren);
  192. }),
  193. /*bInOpenSubMenuOnClick =*/false,
  194. FSlateIcon(FAppStyle::GetAppStyleSetName(), "GenericCommands.Paste")
  195. );
  196. MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().DuplicateStates);
  197. MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().DeleteStates);
  198. MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().RenameState);
  199. MenuBuilder.AddSeparator();
  200. MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().EnableStates);
  201. //#if WITH_STATETREE_TRACE_DEBUGGER
  202. MenuBuilder.AddSeparator();
  203. MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().EnableOnEnterStateBreakpoint);
  204. MenuBuilder.AddMenuEntry(FAbleTreeEditorCommands::Get().EnableOnExitStateBreakpoint);
  205. //#endif // WITH_STATETREE_TRACE_DEBUGGER
  206. return MenuBuilder.MakeWidget();
  207. }
  208. void SEzAbleTreeViewWidget::HandleModelStateAdded(UEzAbilityState* ParentState, UEzAbilityState* NewState)
  209. {
  210. TreeView->RequestTreeRefresh();
  211. }
  212. bool SEzAbleTreeViewWidget::HasSelection() const
  213. {
  214. return AbleTreeViewOperationMode && AbleTreeViewOperationMode->HasSelection();
  215. }
  216. void SEzAbleTreeViewWidget::BindCommands()
  217. {
  218. const FAbleTreeEditorCommands& Commands = FAbleTreeEditorCommands::Get();
  219. CommandList->MapAction(
  220. Commands.DeleteStates,
  221. FExecuteAction::CreateSP(this, &SEzAbleTreeViewWidget::HandleDeleteStates),
  222. FCanExecuteAction::CreateSP(this, &SEzAbleTreeViewWidget::HasSelection));
  223. }
  224. void SEzAbleTreeViewWidget::HandleDeleteStates()
  225. {
  226. if (AbleTreeViewOperationMode)
  227. {
  228. AbleTreeViewOperationMode->RemoveSelectedStates();
  229. TreeView->RequestTreeRefresh();
  230. }
  231. }
  232. FReply SEzAbleTreeViewWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent)
  233. {
  234. if (CommandList->ProcessCommandBindings(InKeyEvent))
  235. {
  236. return FReply::Handled();
  237. }
  238. else
  239. {
  240. return SCompoundWidget::OnKeyDown(MyGeometry, InKeyEvent);
  241. }
  242. }
  243. #undef LOCTEXT_NAMESPACE