ViewportTitleDlg.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  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. // Description : CViewportTitleDlg implementation file
  9. #if !defined(Q_MOC_RUN)
  10. #include "EditorDefs.h"
  11. #include "ViewportTitleDlg.h"
  12. // Qt
  13. #include <QCheckBox>
  14. #include <QLabel>
  15. #include <QInputDialog>
  16. #include <AtomLyIntegration/AtomViewportDisplayInfo/AtomViewportInfoDisplayBus.h>
  17. // Editor
  18. #include "CustomAspectRatioDlg.h"
  19. #include "CustomResolutionDlg.h"
  20. #include "DisplaySettings.h"
  21. #include "EditorViewportSettings.h"
  22. #include "GameEngine.h"
  23. #include "Include/IObjectManager.h"
  24. #include "MainWindow.h"
  25. #include "MathConversion.h"
  26. #include "Objects/SelectionGroup.h"
  27. #include "Settings.h"
  28. #include "UsedResources.h"
  29. #include "ViewPane.h"
  30. #include <AzCore/Asset/AssetSerializer.h>
  31. #include <AzCore/Casting/numeric_cast.h>
  32. #include <AzCore/std/algorithm.h>
  33. #include <AzFramework/API/ApplicationAPI.h>
  34. #include <AzToolsFramework/ActionManager/Menu/MenuManagerInterface.h>
  35. #include <AzToolsFramework/ActionManager/Menu/MenuManagerInternalInterface.h>
  36. #include <AzToolsFramework/Editor/ActionManagerUtils.h>
  37. #include <AzToolsFramework/Viewport/ViewportMessages.h>
  38. #include <AzToolsFramework/Viewport/ViewportSettings.h>
  39. #include <AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.h>
  40. #include <AzQtComponents/Components/Widgets/CheckBox.h>
  41. #include <Editor/EditorSettingsAPIBus.h>
  42. #include <EditorModeFeedback/EditorStateRequestsBus.h>
  43. #include <LmbrCentral/Audio/AudioSystemComponentBus.h>
  44. AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
  45. #include "ui_ViewportTitleDlg.h"
  46. AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
  47. #endif //! defined(Q_MOC_RUN)
  48. // CViewportTitleDlg dialog
  49. namespace
  50. {
  51. class CViewportTitleDlgDisplayInfoHelper
  52. : public QObject
  53. , public AZ::AtomBridge::AtomViewportInfoDisplayNotificationBus::Handler
  54. {
  55. Q_OBJECT
  56. public:
  57. CViewportTitleDlgDisplayInfoHelper(CViewportTitleDlg* parent)
  58. : QObject(parent)
  59. {
  60. AZ::AtomBridge::AtomViewportInfoDisplayNotificationBus::Handler::BusConnect();
  61. }
  62. signals:
  63. void ViewportInfoStatusUpdated(int newIndex);
  64. private:
  65. void OnViewportInfoDisplayStateChanged(AZ::AtomBridge::ViewportInfoDisplayState state) override
  66. {
  67. emit ViewportInfoStatusUpdated(aznumeric_cast<int>(state));
  68. }
  69. };
  70. } // end anonymous namespace
  71. CViewportTitleDlg::CViewportTitleDlg(QWidget* pParent)
  72. : QWidget(pParent)
  73. , m_ui(new Ui::ViewportTitleDlg)
  74. {
  75. m_prevMoveSpeedScale = 0;
  76. m_pViewPane = nullptr;
  77. if (gSettings.bMuteAudio)
  78. {
  79. LmbrCentral::AudioSystemComponentRequestBus::Broadcast(&LmbrCentral::AudioSystemComponentRequestBus::Events::GlobalMuteAudio);
  80. }
  81. else
  82. {
  83. LmbrCentral::AudioSystemComponentRequestBus::Broadcast(&LmbrCentral::AudioSystemComponentRequestBus::Events::GlobalUnmuteAudio);
  84. }
  85. OnInitDialog();
  86. }
  87. CViewportTitleDlg::~CViewportTitleDlg()
  88. {
  89. }
  90. //////////////////////////////////////////////////////////////////////////
  91. void CViewportTitleDlg::SetViewPane(CLayoutViewPane* pViewPane)
  92. {
  93. if (m_pViewPane)
  94. {
  95. m_pViewPane->disconnect(this);
  96. }
  97. m_pViewPane = pViewPane;
  98. if (m_pViewPane)
  99. {
  100. connect(this, &QWidget::customContextMenuRequested, m_pViewPane, &CLayoutViewPane::ShowTitleMenu);
  101. }
  102. }
  103. //////////////////////////////////////////////////////////////////////////
  104. void CViewportTitleDlg::OnInitDialog()
  105. {
  106. }
  107. //////////////////////////////////////////////////////////////////////////
  108. void CViewportTitleDlg::SetTitle(const QString& title)
  109. {
  110. m_title = title;
  111. }
  112. //////////////////////////////////////////////////////////////////////////
  113. void CViewportTitleDlg::OnMaximize()
  114. {
  115. if (m_pViewPane)
  116. {
  117. m_pViewPane->ToggleMaximize();
  118. }
  119. }
  120. void CViewportTitleDlg::SetNoViewportInfo()
  121. {
  122. AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Broadcast(
  123. &AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::SetDisplayState, AZ::AtomBridge::ViewportInfoDisplayState::NoInfo);
  124. }
  125. void CViewportTitleDlg::SetNormalViewportInfo()
  126. {
  127. AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Broadcast(
  128. &AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::SetDisplayState, AZ::AtomBridge::ViewportInfoDisplayState::NormalInfo);
  129. }
  130. void CViewportTitleDlg::SetFullViewportInfo()
  131. {
  132. AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Broadcast(
  133. &AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::SetDisplayState, AZ::AtomBridge::ViewportInfoDisplayState::FullInfo);
  134. }
  135. void CViewportTitleDlg::SetCompactViewportInfo()
  136. {
  137. AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Broadcast(
  138. &AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::SetDisplayState, AZ::AtomBridge::ViewportInfoDisplayState::CompactInfo);
  139. }
  140. //////////////////////////////////////////////////////////////////////////
  141. void CViewportTitleDlg::OnToggleDisplayInfo()
  142. {
  143. AZ::AtomBridge::ViewportInfoDisplayState state = AZ::AtomBridge::ViewportInfoDisplayState::NoInfo;
  144. AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::BroadcastResult(
  145. state, &AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::GetDisplayState);
  146. state = aznumeric_cast<AZ::AtomBridge::ViewportInfoDisplayState>(
  147. (aznumeric_cast<int>(state) + 1) % aznumeric_cast<int>(AZ::AtomBridge::ViewportInfoDisplayState::Invalid));
  148. // SetDisplayState will fire OnViewportInfoDisplayStateChanged and notify us, no need to call UpdateDisplayInfo.
  149. AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Broadcast(
  150. &AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::SetDisplayState, state);
  151. }
  152. //////////////////////////////////////////////////////////////////////////
  153. void CViewportTitleDlg::OnMenuFOVCustom()
  154. {
  155. bool ok;
  156. int fovDegrees = QInputDialog::getInt(this, tr("Custom FOV"), QString(), 60, 1, 120, 1, &ok);
  157. if (ok)
  158. {
  159. m_pViewPane->SetViewportFOV(aznumeric_cast<float>(fovDegrees));
  160. // Update the custom presets.
  161. const QString text = QString::number(fovDegrees);
  162. UpdateCustomPresets(text, m_customFOVPresets);
  163. SaveCustomPresets("FOVPresets", "FOVPreset", m_customFOVPresets);
  164. }
  165. }
  166. //////////////////////////////////////////////////////////////////////////
  167. void CViewportTitleDlg::OnMenuAspectRatioCustom()
  168. {
  169. const QRect viewportRect = m_pViewPane->GetViewport()->rect();
  170. const unsigned int width = viewportRect.width();
  171. const unsigned int height = viewportRect.height();
  172. int whGCD = gcd(width, height);
  173. CCustomAspectRatioDlg aspectRatioInputDialog(width / whGCD, height / whGCD, this);
  174. if (aspectRatioInputDialog.exec() == QDialog::Accepted)
  175. {
  176. const unsigned int aspectX = aspectRatioInputDialog.GetX();
  177. const unsigned int aspectY = aspectRatioInputDialog.GetY();
  178. m_pViewPane->SetAspectRatio(aspectX, aspectY);
  179. // Update the custom presets.
  180. UpdateCustomPresets(QString::fromLatin1("%1:%2").arg(aspectX).arg(aspectY), m_customAspectRatioPresets);
  181. SaveCustomPresets("AspectRatioPresets", "AspectRatioPreset", m_customAspectRatioPresets);
  182. }
  183. }
  184. //////////////////////////////////////////////////////////////////////////
  185. void CViewportTitleDlg::OnMenuResolutionCustom()
  186. {
  187. const QRect rectViewport = m_pViewPane->GetViewport()->rect();
  188. CCustomResolutionDlg resDlg(rectViewport.width(), rectViewport.height(), parentWidget());
  189. if (resDlg.exec() == QDialog::Accepted)
  190. {
  191. m_pViewPane->ResizeViewport(resDlg.GetWidth(), resDlg.GetHeight());
  192. // Update the custom presets.
  193. const QString text = QString::fromLatin1("%1 x %2").arg(resDlg.GetWidth()).arg(resDlg.GetHeight());
  194. UpdateCustomPresets(text, m_customResPresets);
  195. SaveCustomPresets("ResPresets", "ResPreset", m_customResPresets);
  196. }
  197. }
  198. void CViewportTitleDlg::LoadCustomPresets(const QString& section, const QString& keyName, QStringList& outCustompresets)
  199. {
  200. QSettings settings("O3DE", "O3DE"); // Temporary solution until we have the global Settings class.
  201. settings.beginGroup(section);
  202. outCustompresets = settings.value(keyName).toStringList();
  203. settings.endGroup();
  204. }
  205. void CViewportTitleDlg::SaveCustomPresets(const QString& section, const QString& keyName, const QStringList& custompresets)
  206. {
  207. QSettings settings("O3DE", "O3DE"); // Temporary solution until we have the global Settings class.
  208. settings.beginGroup(section);
  209. settings.setValue(keyName, custompresets);
  210. settings.endGroup();
  211. }
  212. void CViewportTitleDlg::UpdateCustomPresets(const QString& text, QStringList& custompresets)
  213. {
  214. custompresets.removeAll(text);
  215. custompresets.push_front(text);
  216. if (custompresets.size() > MAX_NUM_CUSTOM_PRESETS)
  217. {
  218. custompresets.erase(custompresets.begin() + MAX_NUM_CUSTOM_PRESETS, custompresets.end()); // QList doesn't have resize()
  219. }
  220. }
  221. bool CViewportTitleDlg::eventFilter(QObject* object, QEvent* event)
  222. {
  223. bool consumeEvent = false;
  224. // These events are forwarded from the toolbar that took ownership of our widgets
  225. if (event->type() == QEvent::MouseButtonDblClick)
  226. {
  227. QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
  228. if (mouseEvent->button() == Qt::LeftButton)
  229. {
  230. OnMaximize();
  231. consumeEvent = true;
  232. }
  233. }
  234. else if (event->type() == QEvent::FocusIn)
  235. {
  236. parentWidget()->setFocus();
  237. }
  238. return QWidget::eventFilter(object, event) || consumeEvent;
  239. }
  240. void CViewportTitleDlg::OnBnClickedGotoPosition()
  241. {
  242. emit ActionTriggered(ID_DISPLAY_GOTOPOSITION);
  243. }
  244. void CViewportTitleDlg::OnBnClickedMuteAudio()
  245. {
  246. gSettings.bMuteAudio = !gSettings.bMuteAudio;
  247. if (gSettings.bMuteAudio)
  248. {
  249. LmbrCentral::AudioSystemComponentRequestBus::Broadcast(&LmbrCentral::AudioSystemComponentRequestBus::Events::GlobalMuteAudio);
  250. }
  251. else
  252. {
  253. LmbrCentral::AudioSystemComponentRequestBus::Broadcast(&LmbrCentral::AudioSystemComponentRequestBus::Events::GlobalUnmuteAudio);
  254. }
  255. }
  256. inline double Round(double fVal, double fStep)
  257. {
  258. if (fStep > 0.f)
  259. {
  260. fVal = int_round(fVal / fStep) * fStep;
  261. }
  262. return fVal;
  263. }
  264. namespace
  265. {
  266. void PyToggleHelpers()
  267. {
  268. AzToolsFramework::SetHelpersVisible(!AzToolsFramework::HelpersVisible());
  269. AzToolsFramework::EditorSettingsAPIBus::Broadcast(&AzToolsFramework::EditorSettingsAPIBus::Events::SaveSettingsRegistryFile);
  270. }
  271. bool PyIsHelpersShown()
  272. {
  273. return AzToolsFramework::HelpersVisible();
  274. }
  275. } // namespace
  276. namespace AzToolsFramework
  277. {
  278. void ViewportTitleDlgPythonFuncsHandler::Reflect(AZ::ReflectContext* context)
  279. {
  280. if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  281. {
  282. // this will put these methods into the 'azlmbr.legacy.general' module
  283. auto addLegacyGeneral = [](AZ::BehaviorContext::GlobalMethodBuilder methodBuilder)
  284. {
  285. methodBuilder->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
  286. ->Attribute(AZ::Script::Attributes::Category, "Legacy/Editor")
  287. ->Attribute(AZ::Script::Attributes::Module, "legacy.general");
  288. };
  289. addLegacyGeneral(behaviorContext->Method("toggle_helpers", PyToggleHelpers, nullptr, "Toggles the display of helpers."));
  290. addLegacyGeneral(behaviorContext->Method("is_helpers_shown", PyIsHelpersShown, nullptr, "Gets the display state of helpers."));
  291. }
  292. }
  293. } // namespace AzToolsFramework
  294. #include "ViewportTitleDlg.moc"
  295. #include <moc_ViewportTitleDlg.cpp>