ViewportTitleDlg.cpp 12 KB

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