ViewportTitleDlg.cpp 12 KB

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