QConnectionsWidget.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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 <QConnectionsWidget.h>
  9. #include <ACEEnums.h>
  10. #include <AudioControl.h>
  11. #include <AudioControlsEditorPlugin.h>
  12. #include <IAudioSystemControl.h>
  13. #include <IAudioSystemEditor.h>
  14. #include <ImplementationManager.h>
  15. #include <QDropEvent>
  16. #include <QEvent>
  17. #include <QMimeData>
  18. #include <QMessageBox>
  19. #include <QMenu>
  20. namespace AudioControls
  21. {
  22. //-------------------------------------------------------------------------------------------//
  23. QConnectionsWidget::QConnectionsWidget(QWidget* parent)
  24. : QWidget(parent)
  25. , m_control(nullptr)
  26. , m_notFoundColor(QColor(0xf3, 0x81, 0x1d))
  27. , m_localizedColor(QColor(0x42, 0x85, 0xf4))
  28. {
  29. setupUi(this);
  30. m_connectionPropertiesFrame->setHidden(true);
  31. m_connectionList->viewport()->installEventFilter(this);
  32. m_connectionList->installEventFilter(this);
  33. connect(m_connectionList, SIGNAL(customContextMenuRequested(const QPoint&)), SLOT(ShowConnectionContextMenu(const QPoint&)));
  34. connect(m_connectionList, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedConnectionChanged()));
  35. }
  36. //-------------------------------------------------------------------------------------------//
  37. void QConnectionsWidget::CurrentConnectionModified()
  38. {
  39. if (m_control)
  40. {
  41. m_control->SignalControlModified();
  42. }
  43. }
  44. //-------------------------------------------------------------------------------------------//
  45. bool QConnectionsWidget::eventFilter(QObject* object, QEvent* event)
  46. {
  47. IAudioSystemEditor* audioSystemImpl = CAudioControlsEditorPlugin::GetAudioSystemEditorImpl();
  48. if (audioSystemImpl && m_control && event->type() == QEvent::Drop)
  49. {
  50. QDropEvent* dropEvent = static_cast<QDropEvent*>(event);
  51. const QMimeData* mimeData = dropEvent->mimeData();
  52. QString format = "application/x-qabstractitemmodeldatalist";
  53. if (mimeData->hasFormat(format))
  54. {
  55. QByteArray encoded = mimeData->data(format);
  56. QDataStream stream(&encoded, QIODevice::ReadOnly);
  57. while (!stream.atEnd())
  58. {
  59. int row, col;
  60. QMap<int, QVariant> roleDataMap;
  61. stream >> row >> col >> roleDataMap;
  62. if (!roleDataMap.isEmpty())
  63. {
  64. if (IAudioSystemControl* middlewareControl = audioSystemImpl->GetControl(roleDataMap[eMDR_ID].toUInt()))
  65. {
  66. if (audioSystemImpl->GetCompatibleTypes(m_control->GetType()) & middlewareControl->GetType())
  67. {
  68. MakeConnectionTo(middlewareControl);
  69. }
  70. }
  71. }
  72. }
  73. }
  74. return true;
  75. }
  76. else if (event->type() == QEvent::KeyPress)
  77. {
  78. QKeyEvent* dropEvent = static_cast<QKeyEvent*>(event);
  79. if (dropEvent && dropEvent->key() == Qt::Key_Delete && object == m_connectionList)
  80. {
  81. RemoveSelectedConnection();
  82. return true;
  83. }
  84. }
  85. return QWidget::eventFilter(object, event);
  86. }
  87. //-------------------------------------------------------------------------------------------//
  88. void QConnectionsWidget::ShowConnectionContextMenu(const QPoint& pos)
  89. {
  90. QMenu contextMenu(tr("Context menu"), this);
  91. contextMenu.addAction(tr("Remove Connection"), this, SLOT(RemoveSelectedConnection()));
  92. contextMenu.exec(m_connectionList->mapToGlobal(pos));
  93. }
  94. //-------------------------------------------------------------------------------------------//
  95. void QConnectionsWidget::SelectedConnectionChanged()
  96. {
  97. TConnectionPtr connection;
  98. EACEControlType controlType = AudioControls::eACET_NUM_TYPES;
  99. if (m_control)
  100. {
  101. QList<QListWidgetItem*> selected = m_connectionList->selectedItems();
  102. if (selected.length() == 1)
  103. {
  104. QListWidgetItem* currentItem = selected[0];
  105. if (currentItem)
  106. {
  107. const CID externalId = currentItem->data(eMDR_ID).toInt();
  108. connection = m_control->GetConnection(externalId);
  109. controlType = m_control->GetType();
  110. }
  111. }
  112. }
  113. if (m_connectionPropertiesWidget)
  114. {
  115. delete m_connectionPropertiesWidget;
  116. m_connectionPropertiesWidget = nullptr;
  117. }
  118. if (connection && connection->HasProperties())
  119. {
  120. if (IAudioSystemEditor* audioSystemImpl = CAudioControlsEditorPlugin::GetAudioSystemEditorImpl())
  121. {
  122. m_connectionPropertiesWidget = audioSystemImpl->CreateConnectionPropertiesWidget(connection, controlType);
  123. if (m_connectionPropertiesWidget)
  124. {
  125. m_connectionPropertiesWidget->setParent(m_connectionPropertiesFrame);
  126. m_connectionPropertiesLayout->addWidget(m_connectionPropertiesWidget);
  127. bool widgetHasChangedSignal = m_connectionPropertiesWidget->metaObject()->indexOfSignal("PropertiesChanged()") != -1;
  128. AZ_Error(
  129. "Audio", widgetHasChangedSignal,
  130. "The widget created by IAudioSystemEditor::CreateConnectionPropertiesWidget() must have a \"PropertiesChanged()\" "
  131. "signal.");
  132. if (widgetHasChangedSignal)
  133. {
  134. connect(m_connectionPropertiesWidget, SIGNAL(PropertiesChanged()), this, SLOT(CurrentConnectionModified()));
  135. }
  136. }
  137. }
  138. }
  139. }
  140. //-------------------------------------------------------------------------------------------//
  141. void QConnectionsWidget::MakeConnectionTo(IAudioSystemControl* middlewareControl)
  142. {
  143. IAudioSystemEditor* audioSystemImpl = CAudioControlsEditorPlugin::GetAudioSystemEditorImpl();
  144. if (m_control && middlewareControl && audioSystemImpl)
  145. {
  146. CUndo undo("Connected Audio Control to Audio System");
  147. TConnectionPtr connection = m_control->GetConnection(middlewareControl);
  148. if (connection)
  149. {
  150. // connection already exists, select it
  151. const int size = m_connectionList->count();
  152. for (int i = 0; i < size; ++i)
  153. {
  154. QListWidgetItem* listItem = m_connectionList->item(i);
  155. if (listItem && listItem->data(eMDR_ID).toInt() == static_cast<int>(middlewareControl->GetId()))
  156. {
  157. m_connectionList->clearSelection();
  158. listItem->setSelected(true);
  159. m_connectionList->setCurrentItem(listItem);
  160. m_connectionList->scrollToItem(listItem);
  161. break;
  162. }
  163. }
  164. }
  165. else
  166. {
  167. if (m_control->GetType() == EACEControlType::eACET_SWITCH_STATE)
  168. {
  169. if (!m_control->GetParent()->SwitchStateConnectionCheck(middlewareControl))
  170. {
  171. QMessageBox messageBox(this);
  172. messageBox.setStandardButtons(QMessageBox::Ok);
  173. messageBox.setDefaultButton(QMessageBox::Ok);
  174. messageBox.setWindowTitle("Audio Controls Editor");
  175. messageBox.setText("Not in the same switch group, connection failed.");
  176. if (messageBox.exec() == QMessageBox::Ok)
  177. {
  178. return;
  179. }
  180. }
  181. }
  182. connection = audioSystemImpl->CreateConnectionToControl(m_control->GetType(), middlewareControl);
  183. if (connection)
  184. {
  185. m_control->AddConnection(connection);
  186. }
  187. }
  188. }
  189. }
  190. //-------------------------------------------------------------------------------------------//
  191. void QConnectionsWidget::RemoveSelectedConnection()
  192. {
  193. CUndo undo("Disconnected Audio Control from Audio System");
  194. if (m_control)
  195. {
  196. QMessageBox messageBox(this);
  197. messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
  198. messageBox.setDefaultButton(QMessageBox::Yes);
  199. messageBox.setWindowTitle("Audio Controls Editor");
  200. QList<QListWidgetItem*> selected = m_connectionList->selectedItems();
  201. const int size = selected.length();
  202. if (size > 0)
  203. {
  204. if (size == 1)
  205. {
  206. messageBox.setText("Are you sure you want to delete the connection between \"" + QString(m_control->GetName().c_str()) + "\" and \"" + selected[0]->text() + "\"?");
  207. }
  208. else
  209. {
  210. messageBox.setText("Are you sure you want to delete the " + QString::number(size) + " selected connections?");
  211. }
  212. if (messageBox.exec() == QMessageBox::Yes)
  213. {
  214. if (IAudioSystemEditor* audioSystemImpl = CAudioControlsEditorPlugin::GetAudioSystemEditorImpl())
  215. {
  216. AZStd::vector<IAudioSystemControl*> connectedMiddlewareControls;
  217. connectedMiddlewareControls.reserve(selected.size());
  218. for (int i = 0; i < size; ++i)
  219. {
  220. CID middlewareControlId = selected[i]->data(eMDR_ID).toInt();
  221. connectedMiddlewareControls.push_back(audioSystemImpl->GetControl(middlewareControlId));
  222. }
  223. for (int i = 0; i < size; ++i)
  224. {
  225. if (IAudioSystemControl* middlewareControl = connectedMiddlewareControls[i])
  226. {
  227. audioSystemImpl->ConnectionRemoved(middlewareControl);
  228. m_control->RemoveConnection(middlewareControl);
  229. }
  230. }
  231. }
  232. }
  233. }
  234. }
  235. }
  236. //-------------------------------------------------------------------------------------------//
  237. void QConnectionsWidget::UpdateConnections()
  238. {
  239. m_connectionList->clear();
  240. IAudioSystemEditor* audioSystemImpl = CAudioControlsEditorPlugin::GetAudioSystemEditorImpl();
  241. if (audioSystemImpl && m_control)
  242. {
  243. m_connectionList->setEnabled(true);
  244. const size_t size = m_control->ConnectionCount();
  245. for (size_t i = 0; i < size; ++i)
  246. {
  247. TConnectionPtr connection = m_control->GetConnectionAt(i);
  248. if (connection)
  249. {
  250. if (IAudioSystemControl* middlewareControl = audioSystemImpl->GetControl(connection->GetID()))
  251. {
  252. CreateItemFromConnection(middlewareControl);
  253. }
  254. }
  255. }
  256. }
  257. else
  258. {
  259. m_connectionList->setEnabled(false);
  260. }
  261. }
  262. //-------------------------------------------------------------------------------------------//
  263. void QConnectionsWidget::CreateItemFromConnection(IAudioSystemControl* middlewareControl)
  264. {
  265. if (IAudioSystemEditor* audioSystemImpl = CAudioControlsEditorPlugin::GetAudioSystemEditorImpl())
  266. {
  267. const TImplControlType type = middlewareControl->GetType();
  268. QIcon icon = QIcon(QString(audioSystemImpl->GetTypeIcon(type).data()));
  269. icon.addFile(QString(audioSystemImpl->GetTypeIconSelected(type).data()), QSize(), QIcon::Selected);
  270. QListWidgetItem* listItem = new QListWidgetItem(icon, QString(middlewareControl->GetName().c_str()));
  271. listItem->setData(eMDR_ID, middlewareControl->GetId());
  272. listItem->setData(eMDR_LOCALIZED, middlewareControl->IsLocalized());
  273. if (middlewareControl->IsPlaceholder())
  274. {
  275. listItem->setToolTip(tr("Control not found in currently loaded audio system project"));
  276. listItem->setForeground(m_notFoundColor);
  277. }
  278. else if (middlewareControl->IsLocalized())
  279. {
  280. listItem->setForeground(m_localizedColor);
  281. }
  282. m_connectionList->insertItem(0, listItem);
  283. }
  284. }
  285. //-------------------------------------------------------------------------------------------//
  286. void QConnectionsWidget::SetControl(CATLControl* control)
  287. {
  288. if (m_control != control)
  289. {
  290. m_control = control;
  291. m_connectionList->clear();
  292. UpdateConnections();
  293. }
  294. else if (m_control->ConnectionCount() != m_connectionList->count())
  295. {
  296. UpdateConnections();
  297. }
  298. }
  299. } // namespace AudioControls
  300. #include <Source/Editor/moc_QConnectionsWidget.cpp>