PropertyHandlerEntityIdComboBox.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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 "EditorCommon.h"
  9. #include "PropertyHandlerEntityIdComboBox.h"
  10. #include <AzToolsFramework/UI/PropertyEditor/PropertyQTConstants.h>
  11. #include <AzToolsFramework/UI/PropertyEditor/DHQComboBox.hxx>
  12. #include <QBoxLayout>
  13. void PropertyHandlerEntityIdComboBox::WriteGUIValuesIntoProperty(size_t index, PropertyEntityIdComboBoxCtrl* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node)
  14. {
  15. Q_UNUSED(index);
  16. Q_UNUSED(node);
  17. instance = GUI->value();
  18. }
  19. bool PropertyHandlerEntityIdComboBox::ReadValuesIntoGUI(size_t index, PropertyEntityIdComboBoxCtrl* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node)
  20. {
  21. Q_UNUSED(index);
  22. Q_UNUSED(node);
  23. GUI->setValue(instance);
  24. return false;
  25. }
  26. QWidget* PropertyHandlerEntityIdComboBox::CreateGUI(QWidget* pParent)
  27. {
  28. PropertyEntityIdComboBoxCtrl* newCtrl = aznew PropertyEntityIdComboBoxCtrl(pParent);
  29. QObject::connect(newCtrl, &PropertyEntityIdComboBoxCtrl::valueChanged, this, [newCtrl]()
  30. {
  31. AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(
  32. &AzToolsFramework::PropertyEditorGUIMessages::Bus::Events::RequestWrite, newCtrl);
  33. });
  34. return newCtrl;
  35. }
  36. void PropertyHandlerEntityIdComboBox::ConsumeAttribute(PropertyEntityIdComboBoxCtrl* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName)
  37. {
  38. (void)debugName;
  39. if (attrib == AZ_CRC_CE("EnumValue"))
  40. {
  41. AZStd::pair<AZ::EntityId, AZStd::string> guiEnumValue;
  42. AZStd::pair<AZ::EntityId, AZStd::string> enumValue;
  43. AZ::Edit::EnumConstant<AZ::u64> enumConstant;
  44. if (attrValue->Read<AZ::Edit::EnumConstant<AZ::u64>>(enumConstant))
  45. {
  46. guiEnumValue.first = AZ::EntityId(enumConstant.m_value);
  47. guiEnumValue.second = enumConstant.m_description;
  48. GUI->addEnumValue(guiEnumValue);
  49. }
  50. else
  51. {
  52. // Legacy path. Support temporarily for compatibility.
  53. if (attrValue->Read< AZStd::pair<AZ::EntityId, AZStd::string> >(enumValue))
  54. {
  55. guiEnumValue = static_cast<AZStd::pair<AZ::EntityId, AZStd::string>>(enumValue);
  56. GUI->addEnumValue(guiEnumValue);
  57. }
  58. else
  59. {
  60. AZStd::pair<AZ::EntityId, const char*> enumValueConst;
  61. if (attrValue->Read< AZStd::pair<AZ::EntityId, const char*> >(enumValueConst))
  62. {
  63. AZStd::string consted = enumValueConst.second;
  64. guiEnumValue = AZStd::make_pair(enumValueConst.first, consted);
  65. GUI->addEnumValue(guiEnumValue);
  66. }
  67. else
  68. {
  69. AZ_WarningOnce("AzToolsFramework", false, "Failed to read 'EnumValue' attribute from property '%s' into enum combo box. Expected pair<IntegerType, char*> or pair<IntegerType, AZStd::string>, where IntegerType is int or u32 ", debugName);
  70. }
  71. }
  72. }
  73. }
  74. else if (attrib == AZ::Edit::Attributes::EnumValues)
  75. {
  76. AZStd::vector<AZStd::pair<AZ::EntityId, AZStd::string>> guiEnumValues;
  77. AZStd::vector<AZStd::pair<AZ::EntityId, AZStd::string> > enumValues;
  78. AZStd::vector<AZ::Edit::EnumConstant<AZ::u64>> enumConstantValues;
  79. if (attrValue->Read<AZStd::vector<AZ::Edit::EnumConstant<AZ::u64>>>(enumConstantValues))
  80. {
  81. for (const AZ::Edit::EnumConstant<AZ::u64>& constantValue : enumConstantValues)
  82. {
  83. auto& enumValue = guiEnumValues.emplace_back();
  84. enumValue.first = AZ::EntityId(constantValue.m_value);
  85. enumValue.second = constantValue.m_description;
  86. }
  87. GUI->addEnumValues(guiEnumValues);
  88. }
  89. else
  90. {
  91. // Legacy path. Support temporarily for compatibility.
  92. if (attrValue->Read< AZStd::vector<AZStd::pair<AZ::EntityId, AZStd::string> > >(enumValues))
  93. {
  94. for (auto it = enumValues.begin(); it != enumValues.end(); ++it)
  95. guiEnumValues.push_back(static_cast<AZStd::pair<AZ::EntityId, AZStd::string>>(*it));
  96. GUI->addEnumValues(guiEnumValues);
  97. }
  98. else
  99. {
  100. AZStd::vector<AZStd::pair<AZ::EntityId, const char*> > attempt2;
  101. if (attrValue->Read<AZStd::vector<AZStd::pair<AZ::EntityId, const char*> > >(attempt2))
  102. {
  103. for (auto it = attempt2.begin(); it != attempt2.end(); ++it)
  104. guiEnumValues.push_back(AZStd::pair<AZ::EntityId, AZStd::string>(it->first, it->second));
  105. GUI->addEnumValues(guiEnumValues);
  106. }
  107. else
  108. {
  109. // emit a warning!
  110. AZ_WarningOnce("AzToolsFramework", false, "Failed to read 'EnumValue' attribute from property '%s' into enum combo box", debugName);
  111. }
  112. }
  113. }
  114. }
  115. }
  116. void PropertyHandlerEntityIdComboBox::Register()
  117. {
  118. AzToolsFramework::PropertyTypeRegistrationMessages::Bus::Broadcast(
  119. &AzToolsFramework::PropertyTypeRegistrationMessages::Bus::Events::RegisterPropertyType, aznew PropertyHandlerEntityIdComboBox());
  120. }
  121. PropertyEntityIdComboBoxCtrl::PropertyEntityIdComboBoxCtrl(QWidget* pParent)
  122. : QWidget(pParent)
  123. {
  124. // create the gui, it consists of a layout, and in that layout, a text field for the value
  125. // and then a slider for the value.
  126. QHBoxLayout* pLayout = new QHBoxLayout(this);
  127. m_pComboBox = aznew AzToolsFramework::DHQComboBox(this);
  128. // many UI elements hide 1 pixel of their size in a border area that only shows up when they are selected.
  129. // The combo box used in this layout does not do this, so adding 1 to the left and right margins will make
  130. // sure that it has the same dimensions as the other UI elements when they are unselected.
  131. pLayout->setSpacing(4);
  132. pLayout->setContentsMargins(1, 0, 1, 0);
  133. pLayout->addWidget(m_pComboBox);
  134. m_pComboBox->setMinimumWidth(AzToolsFramework::PropertyQTConstant_MinimumWidth);
  135. m_pComboBox->setFixedHeight(AzToolsFramework::PropertyQTConstant_DefaultHeight);
  136. m_pComboBox->setFocusPolicy(Qt::StrongFocus);
  137. setLayout(pLayout);
  138. setFocusProxy(m_pComboBox);
  139. setFocusPolicy(m_pComboBox->focusPolicy());
  140. connect(m_pComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onChildComboBoxValueChange(int)));
  141. };
  142. void PropertyEntityIdComboBoxCtrl::setValue(AZ::EntityId value)
  143. {
  144. m_pComboBox->blockSignals(true);
  145. [[maybe_unused]] bool indexWasFound = false;
  146. for (size_t enumValIndex = 0; enumValIndex < m_enumValues.size(); enumValIndex++)
  147. {
  148. if (m_enumValues[enumValIndex].first == value)
  149. {
  150. m_pComboBox->setCurrentIndex(static_cast<int>(enumValIndex));
  151. indexWasFound = true;
  152. break;
  153. }
  154. }
  155. AZ_Warning("AzToolsFramework", indexWasFound == true, "No index in property enum for value %d", value);
  156. m_pComboBox->blockSignals(false);
  157. }
  158. void PropertyEntityIdComboBoxCtrl::addEnumValue(AZStd::pair<AZ::EntityId, AZStd::string>& val)
  159. {
  160. m_pComboBox->blockSignals(true);
  161. m_enumValues.push_back(val);
  162. m_pComboBox->addItem(val.second.c_str());
  163. m_pComboBox->blockSignals(false);
  164. }
  165. void PropertyEntityIdComboBoxCtrl::addEnumValues(AZStd::vector< AZStd::pair<AZ::EntityId, AZStd::string> >& vals)
  166. {
  167. m_pComboBox->blockSignals(true);
  168. for (size_t valIndex = 0; valIndex < vals.size(); valIndex++)
  169. {
  170. m_enumValues.push_back(vals[valIndex]);
  171. m_pComboBox->addItem(vals[valIndex].second.c_str());
  172. }
  173. m_pComboBox->blockSignals(false);
  174. }
  175. AZ::EntityId PropertyEntityIdComboBoxCtrl::value() const
  176. {
  177. AZ_Assert(m_pComboBox->currentIndex() >= 0 &&
  178. m_pComboBox->currentIndex() < static_cast<int>(m_enumValues.size()), "Out of range combo box index %d", m_pComboBox->currentIndex());
  179. return m_enumValues[m_pComboBox->currentIndex()].first;
  180. }
  181. void PropertyEntityIdComboBoxCtrl::onChildComboBoxValueChange(int comboBoxIndex)
  182. {
  183. AZ_Assert(comboBoxIndex >= 0 &&
  184. comboBoxIndex < static_cast<int>(m_enumValues.size()), "Out of range combo box index %d", comboBoxIndex);
  185. emit valueChanged(m_enumValues[comboBoxIndex].first);
  186. }
  187. QWidget* PropertyEntityIdComboBoxCtrl::GetFirstInTabOrder()
  188. {
  189. return m_pComboBox;
  190. }
  191. QWidget* PropertyEntityIdComboBoxCtrl::GetLastInTabOrder()
  192. {
  193. return m_pComboBox;
  194. }
  195. void PropertyEntityIdComboBoxCtrl::UpdateTabOrder()
  196. {
  197. // There's only one QT widget on this property.
  198. }
  199. #include <moc_PropertyHandlerEntityIdComboBox.cpp>