From 16188c7305a667b48a6b3ab8a37a3d31bb40a1e4 Mon Sep 17 00:00:00 2001 From: Ralph Sennhauser Date: Fri, 10 Jul 2026 11:16:46 +0200 Subject: [PATCH] Add birds eye view toggle to View menu On request by @nifa add a checked menu item to View menu to set birds eye view. When game view is focused, the focus which it hogs almost always, then 'B' doesn't propagate properly so use Ctrl+B instead in line with other main menu shortcuts. Signed-off-by: Ralph Sennhauser --- .../AtlasUI/ScenarioEditor/ScenarioEditor.cpp | 14 ++++++++------ .../AtlasUI/ScenarioEditor/ScenarioEditor.h | 6 ++++-- .../Handlers/CameraCtrlHandlers.cpp | 17 ++++++++++------- source/tools/atlas/GameInterface/Messages.h | 4 +++- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp index 40dae8038f..b8a62dc97c 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp @@ -173,12 +173,6 @@ private: if (KeyScroll(evt, true)) return; - if (evt.GetKeyCode() == 'B') - { - POST_MESSAGE(ToggleBirdsEyeView, ()); - return; - } - POST_MESSAGE(GuiKeyEvent, (GetSDLKeyFromWxKeyCode(evt.GetKeyCode()), evt.GetUnicodeKey(), true)); evt.Skip(); @@ -372,6 +366,7 @@ enum ID_Wireframe, ID_SmoothFramerate, + ID_BirdsEyeView, ID_CameraReset, ID_MessageTrace, @@ -406,6 +401,7 @@ BEGIN_EVENT_TABLE(ScenarioEditor, wxFrame) EVT_MENU(ID_Wireframe, ScenarioEditor::OnWireframe) EVT_MENU(ID_SmoothFramerate, ScenarioEditor::OnSmoothFramerate) + EVT_MENU(ID_BirdsEyeView, ScenarioEditor::OnBirdsEyeView) EVT_MENU(ID_CameraReset, ScenarioEditor::OnCameraReset) EVT_MENU(ID_MessageTrace, ScenarioEditor::OnMessageTrace) @@ -523,6 +519,7 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent) { menuView->AppendCheckItem(ID_Wireframe, _("&Wireframe")); menuView->AppendCheckItem(ID_SmoothFramerate, _("Smooth framerate")); + menuView->AppendCheckItem(ID_BirdsEyeView, _("&Birds Eye View\tCtrl+B")); menuView->Append(ID_CameraReset, _("&Reset camera")); } @@ -1001,6 +998,11 @@ void ScenarioEditor::OnSmoothFramerate(wxCommandEvent& event) POST_MESSAGE(SetSmoothFramerate, (event.IsChecked())); } +void ScenarioEditor::OnBirdsEyeView(wxCommandEvent& event) +{ + POST_MESSAGE(SetBirdsEyeView, (event.IsChecked())); +} + void ScenarioEditor::OnDumpState(wxCommandEvent& event) { wxDateTime time = wxDateTime::Now(); diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h index ae9670c65d..98856f9c43 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h @@ -60,12 +60,14 @@ public: void OnPaste(wxCommandEvent& event); void OnWireframe(wxCommandEvent& event); + void OnSmoothFramerate(wxCommandEvent& event); + void OnBirdsEyeView(wxCommandEvent& event); + void OnCameraReset(wxCommandEvent& event); + void OnMessageTrace(wxCommandEvent& event); void OnScreenshot(wxCommandEvent& event); void OnMediaPlayer(wxCommandEvent& event); void OnJavaScript(wxCommandEvent& event); - void OnCameraReset(wxCommandEvent& event); - void OnSmoothFramerate(wxCommandEvent& event); void OnDumpState(wxCommandEvent& event); void OnSelectedObjectsChange(const std::vector& selectedObjects); diff --git a/source/tools/atlas/GameInterface/Handlers/CameraCtrlHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/CameraCtrlHandlers.cpp index c0044c54f4..47da436fc1 100644 --- a/source/tools/atlas/GameInterface/Handlers/CameraCtrlHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/CameraCtrlHandlers.cpp @@ -39,7 +39,7 @@ namespace { -bool g_BirdEyeView{false}; +bool g_BirdsEyeView{false}; } // namespace namespace AtlasMessage { @@ -66,7 +66,7 @@ MESSAGEHANDLER(CameraReset) g_Game->GetView()->ResetCameraTarget(target); - g_BirdEyeView = false; + g_BirdsEyeView = false; } MESSAGEHANDLER(ScrollConstant) @@ -147,7 +147,7 @@ MESSAGEHANDLER(SmoothZoom) MESSAGEHANDLER(RotateAround) { - if (!g_Game || g_Game->GetView()->GetCinema()->IsPlaying() || g_BirdEyeView) + if (!g_Game || g_Game->GetView()->GetCinema()->IsPlaying() || g_BirdsEyeView) return; static CVector3D focusPos; @@ -269,8 +269,11 @@ MESSAGEHANDLER(SetView) // TODO: Rotation } -MESSAGEHANDLER(ToggleBirdsEyeView) +MESSAGEHANDLER(SetBirdsEyeView) { + if (g_BirdsEyeView == msg->enabled) + return; + if (!g_Game || g_Game->GetView()->GetCinema()->IsPlaying()) return; @@ -280,7 +283,7 @@ MESSAGEHANDLER(ToggleBirdsEyeView) CMatrix3D& orientation{camera.GetOrientation()}; const CVector3D focus{camera.GetFocus()}; - if (!g_BirdEyeView) + if (!g_BirdsEyeView) { CVector3D in = orientation.GetIn(); declination = atan2(sqrt(in.X*in.X + in.Z*in.Z), in.Y) - std::numbers::pi_v / 2.f; @@ -289,7 +292,7 @@ MESSAGEHANDLER(ToggleBirdsEyeView) CQuaternion q; // If really 90° then the camera movement bugs out as it has no clear // forward anymore, so stick with 89°. - q.FromAxisAngle(orientation.GetLeft(), g_BirdEyeView ? + q.FromAxisAngle(orientation.GetLeft(), g_BirdsEyeView ? DEGTORAD(89.f) - declination : DEGTORAD(-89.f) + declination); CVector3D origin = orientation.GetTranslation(); @@ -304,7 +307,7 @@ MESSAGEHANDLER(ToggleBirdsEyeView) camera.UpdateFrustum(); g_Game->GetView()->SetCamera(camera); - g_BirdEyeView = !g_BirdEyeView; + g_BirdsEyeView = msg->enabled; } } diff --git a/source/tools/atlas/GameInterface/Messages.h b/source/tools/atlas/GameInterface/Messages.h index 73cf3fcd99..9e381d7b38 100644 --- a/source/tools/atlas/GameInterface/Messages.h +++ b/source/tools/atlas/GameInterface/Messages.h @@ -473,7 +473,9 @@ MESSAGE(SetView, ((sCameraInfo, info)) ); -MESSAGE(ToggleBirdsEyeView, ); +MESSAGE(SetBirdsEyeView, + ((bool, enabled)) + ); //////////////////////////////////////////////////////////////////////////