SimulatedObjectSelectionWidget.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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 <AzQtComponents/Components/FilteredSearchWidget.h>
  9. #include "SimulatedObjectSelectionWidget.h"
  10. #include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.h>
  11. #include <MCore/Source/StringConversions.h>
  12. #include <MCore/Source/LogManager.h>
  13. #include <EMotionFX/Source/SimulatedObjectSetup.h>
  14. #include <QLabel>
  15. #include <QSizePolicy>
  16. #include <QTreeWidget>
  17. #include <QPixmap>
  18. #include <QPushButton>
  19. #include <QVBoxLayout>
  20. #include <QIcon>
  21. #include <QHeaderView>
  22. namespace EMStudio
  23. {
  24. SimulatedObjectSelectionWidget::SimulatedObjectSelectionWidget(QWidget* parent)
  25. : QWidget(parent)
  26. {
  27. m_searchWidget = new AzQtComponents::FilteredSearchWidget(this);
  28. connect(m_searchWidget, &AzQtComponents::FilteredSearchWidget::TextFilterChanged, this, &SimulatedObjectSelectionWidget::OnTextFilterChanged);
  29. m_treeWidget = new QTreeWidget();
  30. m_treeWidget->setColumnCount(1);
  31. const QStringList headerList { "Name" };
  32. m_treeWidget->setHeaderLabels(headerList);
  33. m_treeWidget->setSortingEnabled(false);
  34. m_treeWidget->setSelectionMode(QAbstractItemView::MultiSelection);
  35. m_treeWidget->setAlternatingRowColors(true);
  36. m_treeWidget->setExpandsOnDoubleClick(true);
  37. m_treeWidget->setAnimated(true);
  38. m_treeWidget->header()->setSectionsMovable(false);
  39. QVBoxLayout* layout = new QVBoxLayout(this);
  40. layout->setMargin(0);
  41. layout->addWidget(m_searchWidget);
  42. layout->addWidget(m_treeWidget);
  43. connect(m_treeWidget, &QTreeWidget::itemSelectionChanged, this, &SimulatedObjectSelectionWidget::UpdateSelection);
  44. connect(m_treeWidget, &QTreeWidget::itemDoubleClicked, this, &SimulatedObjectSelectionWidget::ItemDoubleClicked);
  45. }
  46. void SimulatedObjectSelectionWidget::Update(EMotionFX::Actor* actor, const AZStd::vector<AZStd::string>& selectedSimulatedObjects)
  47. {
  48. m_actor = actor;
  49. m_selectedSimulatedObjectNames = selectedSimulatedObjects;
  50. m_oldSelectedSimulatedObjectNames = selectedSimulatedObjects;
  51. Update();
  52. }
  53. void SimulatedObjectSelectionWidget::AddSimulatedObjectToInterface(const EMotionFX::SimulatedObject* object)
  54. {
  55. // Make sure we only show the simulated objects that are wanted after the name are filtering
  56. if (m_searchWidgetText.empty() || AzFramework::StringFunc::Find(object->GetName(), m_searchWidgetText) != AZStd::string::npos)
  57. {
  58. QTreeWidgetItem* item = new QTreeWidgetItem(m_treeWidget);
  59. m_treeWidget->addTopLevelItem(item);
  60. item->setText(0, object->GetName().c_str());
  61. item->setExpanded(true);
  62. // Check if the given object is selected
  63. if (AZStd::find(m_oldSelectedSimulatedObjectNames.begin(), m_oldSelectedSimulatedObjectNames.end(), object->GetName()) != m_oldSelectedSimulatedObjectNames.end())
  64. {
  65. item->setSelected(true);
  66. }
  67. }
  68. }
  69. void SimulatedObjectSelectionWidget::Update()
  70. {
  71. m_treeWidget->clear();
  72. m_treeWidget->blockSignals(true);
  73. const AZStd::vector<EMotionFX::SimulatedObject*>& simulatedObjects = m_actor->GetSimulatedObjectSetup()->GetSimulatedObjects();
  74. for (const EMotionFX::SimulatedObject* simulatedObject : simulatedObjects)
  75. {
  76. AddSimulatedObjectToInterface(simulatedObject);
  77. }
  78. m_treeWidget->blockSignals(false);
  79. UpdateSelection();
  80. }
  81. AZStd::vector<AZStd::string>& SimulatedObjectSelectionWidget::GetSelectedSimulatedObjectNames()
  82. {
  83. UpdateSelection();
  84. return m_selectedSimulatedObjectNames;
  85. }
  86. void SimulatedObjectSelectionWidget::UpdateSelection()
  87. {
  88. QList<QTreeWidgetItem*> selectedItems = m_treeWidget->selectedItems();
  89. m_selectedSimulatedObjectNames.clear();
  90. const uint32 numSelectedItems = selectedItems.count();
  91. m_selectedSimulatedObjectNames.reserve(numSelectedItems);
  92. // Iterate through the selected items in the tree widget.
  93. AZStd::string itemName;
  94. for (uint32 i = 0; i < numSelectedItems; ++i)
  95. {
  96. QTreeWidgetItem* item = selectedItems[i];
  97. itemName = item->text(0).toUtf8().data();
  98. // Skip the object that we can't find as they also shouldn't be selectable.
  99. const EMotionFX::SimulatedObject* object = m_actor->GetSimulatedObjectSetup()->FindSimulatedObjectByName(itemName.c_str());
  100. if (!object)
  101. {
  102. continue;
  103. }
  104. // Check if the selected item is a simulated object
  105. if (AZStd::find(m_selectedSimulatedObjectNames.begin(), m_selectedSimulatedObjectNames.end(), itemName) == m_selectedSimulatedObjectNames.end())
  106. {
  107. m_selectedSimulatedObjectNames.emplace_back(itemName);
  108. }
  109. }
  110. }
  111. void SimulatedObjectSelectionWidget::ItemDoubleClicked(QTreeWidgetItem* item, int column)
  112. {
  113. AZ_UNUSED(item);
  114. AZ_UNUSED(column);
  115. UpdateSelection();
  116. if (!m_selectedSimulatedObjectNames.empty())
  117. {
  118. emit OnDoubleClicked(m_selectedSimulatedObjectNames[0]);
  119. }
  120. }
  121. void SimulatedObjectSelectionWidget::OnTextFilterChanged(const QString& text)
  122. {
  123. m_searchWidgetText = text.toUtf8().data();
  124. AZStd::to_lower(m_searchWidgetText.begin(), m_searchWidgetText.end());
  125. Update();
  126. }
  127. } // namespace EMStudio