FindEntityItemModel.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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 "FindEntityItemModel.h"
  9. #include <AzFramework/StringFunc/StringFunc.h>
  10. #include <AzToolsFramework/Entity/EditorEntityHelpers.h>
  11. #include <LyShine/Bus/UiElementBus.h>
  12. #include <LyShine/Bus/UiCanvasBus.h>
  13. #include <QObject>
  14. #include <QWidget>
  15. #include <QPalette>
  16. #include <QBrush>
  17. FindEntityItemModel::FindEntityItemModel(QObject* parent)
  18. : QAbstractItemModel(parent)
  19. , m_entityFilteredState()
  20. , m_entityMatchState()
  21. {
  22. }
  23. void FindEntityItemModel::Initialize(AZ::EntityId canvasEntityId)
  24. {
  25. beginResetModel();
  26. m_canvasEntityId = canvasEntityId;
  27. endResetModel();
  28. }
  29. int FindEntityItemModel::rowCount(const QModelIndex& parent) const
  30. {
  31. int childCount = 0;
  32. auto parentId = GetEntityFromIndex(parent);
  33. if (parentId.IsValid())
  34. {
  35. UiElementBus::EventResult(childCount, parentId, &UiElementBus::Events::GetNumChildElements);
  36. }
  37. else
  38. {
  39. // Root element
  40. UiCanvasBus::EventResult(childCount, m_canvasEntityId, &UiCanvasBus::Events::GetNumChildElements);
  41. }
  42. return childCount;
  43. }
  44. int FindEntityItemModel::columnCount(const QModelIndex& /*parent*/) const
  45. {
  46. return ColumnCount;
  47. }
  48. QModelIndex FindEntityItemModel::index(int row, int column, const QModelIndex& parent) const
  49. {
  50. // sanity check
  51. if (!hasIndex(row, column, parent) || (parent.isValid() && parent.column() != 0) || (row < 0 || row >= rowCount(parent)))
  52. {
  53. return QModelIndex();
  54. }
  55. auto parentId = GetEntityFromIndex(parent);
  56. AZ::EntityId childId;
  57. if (parentId.IsValid())
  58. {
  59. UiElementBus::EventResult(childId, parentId, &UiElementBus::Events::GetChildEntityId, row);
  60. }
  61. else
  62. {
  63. // Root element
  64. UiCanvasBus::EventResult(childId, m_canvasEntityId, &UiCanvasBus::Events::GetChildElementEntityId, row);
  65. }
  66. return createIndex(row, column, static_cast<AZ::u64>(childId));
  67. }
  68. QVariant FindEntityItemModel::data(const QModelIndex& index, int role) const
  69. {
  70. auto id = GetEntityFromIndex(index);
  71. if (id.IsValid())
  72. {
  73. switch (index.column())
  74. {
  75. case ColumnName:
  76. return DataForName(index, role);
  77. }
  78. }
  79. return QVariant();
  80. }
  81. QModelIndex FindEntityItemModel::parent(const QModelIndex& index) const
  82. {
  83. auto id = GetEntityFromIndex(index);
  84. if (id.IsValid())
  85. {
  86. AZ::EntityId parentId;
  87. UiElementBus::EventResult(parentId, id, &UiElementBus::Events::GetParentEntityId);
  88. return GetIndexFromEntity(parentId, index.column());
  89. }
  90. return QModelIndex();
  91. }
  92. QModelIndex FindEntityItemModel::GetIndexFromEntity(const AZ::EntityId& entityId, int column) const
  93. {
  94. if (entityId.IsValid())
  95. {
  96. AZ::EntityId parentId;
  97. UiElementBus::EventResult(parentId, entityId, &UiElementBus::Events::GetParentEntityId);
  98. if (parentId.IsValid())
  99. {
  100. AZStd::size_t row = 0;
  101. UiElementBus::EventResult(row, parentId, &UiElementBus::Events::GetIndexOfChildByEntityId, entityId);
  102. return createIndex(static_cast<int>(row), column, static_cast<AZ::u64>(entityId));
  103. }
  104. }
  105. return QModelIndex();
  106. }
  107. AZ::EntityId FindEntityItemModel::GetEntityFromIndex(const QModelIndex& index) const
  108. {
  109. return index.isValid() ? AZ::EntityId(static_cast<AZ::u64>(index.internalId())) : AZ::EntityId();
  110. }
  111. void FindEntityItemModel::SearchStringChanged(const AZStd::string& filter)
  112. {
  113. m_filterString = filter;
  114. InvalidateFilter();
  115. }
  116. void FindEntityItemModel::SearchFilterChanged(const AZStd::vector<AZ::Uuid>& componentFilters)
  117. {
  118. m_componentFilters = AZStd::move(componentFilters);
  119. InvalidateFilter();
  120. }
  121. QVariant FindEntityItemModel::DataForName(const QModelIndex& index, int role) const
  122. {
  123. auto id = GetEntityFromIndex(index);
  124. switch (role)
  125. {
  126. case Qt::DisplayRole:
  127. case Qt::EditRole:
  128. {
  129. AZStd::string name;
  130. UiElementBus::EventResult(name, id, &UiElementBus::Events::GetName);
  131. return QString(name.data());
  132. }
  133. case Qt::ForegroundRole:
  134. {
  135. const QColor notMatchedTextColor(130, 130, 130);
  136. // We use the parent's palette because the GUI Application palette is returning the wrong colors
  137. auto parentWidgetPtr = static_cast<QWidget*>(QObject::parent());
  138. return QBrush(IsMatch(id) ? parentWidgetPtr->palette().color(QPalette::Text) : notMatchedTextColor);
  139. }
  140. case VisibilityRole:
  141. {
  142. return !IsFiltered(id);
  143. }
  144. }
  145. return QVariant();
  146. }
  147. void FindEntityItemModel::InvalidateFilter()
  148. {
  149. FilterEntity(AZ::EntityId());
  150. }
  151. bool FindEntityItemModel::FilterEntity(const AZ::EntityId& entityId)
  152. {
  153. bool isFilterMatch = true;
  154. if (m_filterString.size() > 0)
  155. {
  156. if (entityId.IsValid())
  157. {
  158. AZStd::string name;
  159. UiElementBus::EventResult(name, entityId, &UiElementBus::Events::GetName);
  160. if (AzFramework::StringFunc::Find(name.c_str(), m_filterString.c_str()) == AZStd::string::npos)
  161. {
  162. isFilterMatch = false;
  163. }
  164. }
  165. }
  166. // If we matched the filter string and have any component filters, make sure we match those too
  167. if (isFilterMatch && m_componentFilters.size() > 0)
  168. {
  169. if (entityId.IsValid())
  170. {
  171. bool hasMatchingComponent = false;
  172. for (AZ::Uuid& componentType : m_componentFilters)
  173. {
  174. if (AzToolsFramework::EntityHasComponentOfType(entityId, componentType))
  175. {
  176. hasMatchingComponent = true;
  177. break;
  178. }
  179. }
  180. isFilterMatch &= hasMatchingComponent;
  181. }
  182. }
  183. AzToolsFramework::EntityIdList children;
  184. if (entityId.IsValid())
  185. {
  186. UiElementBus::EventResult(children, entityId, &UiElementBus::Events::GetChildEntityIds);
  187. }
  188. else
  189. {
  190. // Root element
  191. UiCanvasBus::EventResult(children, m_canvasEntityId, &UiCanvasBus::Events::GetChildElementEntityIds);
  192. }
  193. m_entityMatchState[entityId] = isFilterMatch;
  194. for (auto childId : children)
  195. {
  196. isFilterMatch |= FilterEntity(childId);
  197. }
  198. m_entityFilteredState[entityId] = !isFilterMatch;
  199. return isFilterMatch;
  200. }
  201. bool FindEntityItemModel::IsFiltered(const AZ::EntityId& entityId) const
  202. {
  203. auto hiddenItr = m_entityFilteredState.find(entityId);
  204. return hiddenItr != m_entityFilteredState.end() && hiddenItr->second;
  205. }
  206. bool FindEntityItemModel::IsMatch(const AZ::EntityId& entityId) const
  207. {
  208. auto matchItr = m_entityMatchState.find(entityId);
  209. return matchItr == m_entityMatchState.end() || matchItr->second;
  210. }
  211. #include <moc_FindEntityItemModel.cpp>