ActorJointBrowseEdit.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Memory/SystemAllocator.h>
  9. #include <Editor/ActorJointBrowseEdit.h>
  10. #include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/NodeSelectionWindow.h>
  11. #include <EMotionFX/CommandSystem/Source/CommandManager.h>
  12. #include <EMotionFX/Source/ActorManager.h>
  13. #include <QTreeWidget>
  14. namespace EMStudio
  15. {
  16. AZ_CLASS_ALLOCATOR_IMPL(ActorJointBrowseEdit, AZ::SystemAllocator)
  17. ActorJointBrowseEdit::ActorJointBrowseEdit(QWidget* parent)
  18. : AzQtComponents::BrowseEdit(parent)
  19. {
  20. connect(this, &AzQtComponents::BrowseEdit::attachedButtonTriggered, this, &ActorJointBrowseEdit::OnBrowseButtonClicked);
  21. connect(this, &AzQtComponents::BrowseEdit::textEdited, this, &ActorJointBrowseEdit::OnTextEdited);
  22. SetSingleJointSelection(m_singleJointSelection);
  23. setClearButtonEnabled(true);
  24. setLineEditReadOnly(true);
  25. }
  26. void ActorJointBrowseEdit::SetSingleJointSelection(bool singleSelectionEnabled)
  27. {
  28. m_singleJointSelection = singleSelectionEnabled;
  29. UpdatePlaceholderText();
  30. }
  31. void ActorJointBrowseEdit::UpdatePlaceholderText()
  32. {
  33. const QString placeholderText = QString("Select joint%1").arg(m_singleJointSelection ? "" : "s");
  34. setPlaceholderText(placeholderText);
  35. }
  36. void ActorJointBrowseEdit::OnBrowseButtonClicked()
  37. {
  38. const EMotionFX::ActorInstance* actorInstance = GetActorInstance();
  39. if (!actorInstance)
  40. {
  41. AZ_Warning("EMotionFX", false, "Cannot open joint selection window. Please select an actor instance first.");
  42. return;
  43. }
  44. CommandSystem::SelectionList selectionList;
  45. for (const SelectionItem& selectedJoint : m_selectedJoints)
  46. {
  47. EMotionFX::Node* node = selectedJoint.GetNode();
  48. if (node)
  49. {
  50. selectionList.AddNode(node);
  51. }
  52. }
  53. AZ_Warning("EMotionFX", m_singleJointSelection && selectionList.GetNumSelectedNodes() > 1,
  54. "Single selection actor joint window has multiple pre-selected joints.");
  55. m_previouslySelectedJoints = m_selectedJoints;
  56. m_jointSelectionWindow = new NodeSelectionWindow(this, m_singleJointSelection);
  57. connect(m_jointSelectionWindow, &NodeSelectionWindow::rejected, this, &ActorJointBrowseEdit::OnSelectionRejected);
  58. connect(m_jointSelectionWindow->GetNodeHierarchyWidget()->GetTreeWidget(), &QTreeWidget::itemSelectionChanged, this, &ActorJointBrowseEdit::OnSelectionChanged);
  59. connect(m_jointSelectionWindow->GetNodeHierarchyWidget(), &NodeHierarchyWidget::OnSelectionDone, this, &ActorJointBrowseEdit::OnSelectionDone);
  60. NodeSelectionWindow::connect(m_jointSelectionWindow, &QDialog::finished, [=]([[maybe_unused]] int resultCode)
  61. {
  62. m_jointSelectionWindow->deleteLater();
  63. m_jointSelectionWindow = nullptr;
  64. });
  65. m_jointSelectionWindow->open();
  66. m_jointSelectionWindow->Update(actorInstance->GetID(), &selectionList);
  67. }
  68. void ActorJointBrowseEdit::SetSelectedJoints(const AZStd::vector<SelectionItem>& selectedJoints)
  69. {
  70. if (m_singleJointSelection && selectedJoints.size() > 1)
  71. {
  72. AZ_Warning("EMotionFX", true, "Cannot select multiple joints for single selection actor joint browse edit. Only the first joint will be selected.");
  73. m_selectedJoints = {selectedJoints[0]};
  74. }
  75. else
  76. {
  77. m_selectedJoints = selectedJoints;
  78. }
  79. QString text;
  80. const size_t numJoints = m_selectedJoints.size();
  81. switch (numJoints)
  82. {
  83. case 0:
  84. {
  85. // Leave text empty (shows placeholder text).
  86. break;
  87. }
  88. case 1:
  89. {
  90. text = m_selectedJoints[0].GetNodeName();
  91. break;
  92. }
  93. default:
  94. {
  95. text = QString("%1 joints").arg(numJoints);
  96. }
  97. }
  98. setText(text);
  99. }
  100. void ActorJointBrowseEdit::OnSelectionDone(const AZStd::vector<SelectionItem>& selectedJoints)
  101. {
  102. SetSelectedJoints(selectedJoints);
  103. emit SelectionDone(selectedJoints);
  104. }
  105. void ActorJointBrowseEdit::OnSelectionChanged()
  106. {
  107. if (m_jointSelectionWindow)
  108. {
  109. NodeHierarchyWidget* hierarchyWidget = m_jointSelectionWindow->GetNodeHierarchyWidget();
  110. hierarchyWidget->UpdateSelection();
  111. AZStd::vector<SelectionItem>& selectedJoints = hierarchyWidget->GetSelectedItems();
  112. emit SelectionChanged(selectedJoints);
  113. }
  114. }
  115. void ActorJointBrowseEdit::OnSelectionRejected()
  116. {
  117. emit SelectionRejected(m_previouslySelectedJoints);
  118. }
  119. void ActorJointBrowseEdit::OnTextEdited(const QString& text)
  120. {
  121. if (text.isEmpty())
  122. {
  123. OnSelectionDone(/*selectedJoints=*/{});
  124. }
  125. }
  126. EMotionFX::ActorInstance* ActorJointBrowseEdit::GetActorInstance() const
  127. {
  128. const CommandSystem::SelectionList& selectionList = CommandSystem::GetCommandManager()->GetCurrentSelection();
  129. EMotionFX::ActorInstance* actorInstance = selectionList.GetSingleActorInstance();
  130. if (actorInstance)
  131. {
  132. return actorInstance;
  133. }
  134. EMotionFX::Actor* actor = selectionList.GetSingleActor();
  135. if (actor)
  136. {
  137. const size_t numActorInstances = EMotionFX::GetActorManager().GetNumActorInstances();
  138. for (size_t i = 0; i < numActorInstances; ++i)
  139. {
  140. EMotionFX::ActorInstance* actorInstance2 = EMotionFX::GetActorManager().GetActorInstance(i);
  141. if (actorInstance2->GetActor() == actor)
  142. {
  143. return actorInstance2;
  144. }
  145. }
  146. }
  147. return nullptr;
  148. }
  149. } // namespace EMStudio