From 274b7a0195d3378a490709c269f82b2965cdcdc5 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 6 Mar 2025 00:00:57 +0000 Subject: [PATCH] Fix #13645: "Follow vehicle" button not raised when following stopped. (#13746) --- src/vehicle_gui.cpp | 2 +- src/viewport.cpp | 22 +++++++++++++++++++++- src/window.cpp | 11 ++++++----- src/window_gui.h | 2 ++ 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index f1b275e328..9bfa5ecfb0 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -3479,7 +3479,7 @@ void StopGlobalFollowVehicle(const Vehicle *v) Window *w = GetMainWindow(); if (w->viewport->follow_vehicle == v->index) { ScrollMainWindowTo(v->x_pos, v->y_pos, v->z_pos, true); // lock the main view on the vehicle's last position - w->viewport->follow_vehicle = VehicleID::Invalid(); + w->viewport->CancelFollow(*w); } } diff --git a/src/viewport.cpp b/src/viewport.cpp index 7405fce2d9..34b6245a05 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -94,6 +94,8 @@ #include #include +#include "widgets/vehicle_widget.h" + #include "table/strings.h" #include "table/string_colours.h" @@ -2530,7 +2532,7 @@ bool ScrollWindowTo(int x, int y, int z, Window *w, bool instant) } Point pt = MapXYZToViewport(w->viewport, x, y, z); - w->viewport->follow_vehicle = VehicleID::Invalid(); + w->viewport->CancelFollow(*w); if (w->viewport->dest_scrollpos_x == pt.x && w->viewport->dest_scrollpos_y == pt.y) return false; @@ -3717,3 +3719,21 @@ void SetViewportCatchmentTown(const Town *t, bool sel) } if (_viewport_highlight_town != nullptr) SetWindowDirty(WC_TOWN_VIEW, _viewport_highlight_town->index); } + +/** + * Cancel viewport vehicle following, and raise follow location widget if needed. + * @param viewport_window Window of this viewport. + */ +void ViewportData::CancelFollow(const Window &viewport_window) +{ + if (this->follow_vehicle == VehicleID::Invalid()) return; + + if (viewport_window.window_class == WC_MAIN_WINDOW) { + /* We're cancelling follow in the main viewport, so we need to check for a vehicle view window + * to raise the location follow widget. */ + Window *vehicle_window = FindWindowById(WC_VEHICLE_VIEW, this->follow_vehicle); + if (vehicle_window != nullptr) vehicle_window->RaiseWidgetWhenLowered(WID_VV_LOCATION); + } + + this->follow_vehicle = VehicleID::Invalid(); +} diff --git a/src/window.cpp b/src/window.cpp index eb540dfe8a..4faa23342e 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -2697,17 +2697,17 @@ static void HandleAutoscroll() /* If we succeed at scrolling in any direction, stop following a vehicle. */ static const int SCROLLSPEED = 3; if (x - 15 < 0) { - w->viewport->follow_vehicle = VehicleID::Invalid(); + w->viewport->CancelFollow(*w); w->viewport->dest_scrollpos_x += ScaleByZoom((x - 15) * SCROLLSPEED, vp->zoom); } else if (15 - (vp->width - x) > 0) { - w->viewport->follow_vehicle = VehicleID::Invalid(); + w->viewport->CancelFollow(*w); w->viewport->dest_scrollpos_x += ScaleByZoom((15 - (vp->width - x)) * SCROLLSPEED, vp->zoom); } if (y - 15 < 0) { - w->viewport->follow_vehicle = VehicleID::Invalid(); + w->viewport->CancelFollow(*w); w->viewport->dest_scrollpos_y += ScaleByZoom((y - 15) * SCROLLSPEED, vp->zoom); } else if (15 - (vp->height - y) > 0) { - w->viewport->follow_vehicle = VehicleID::Invalid(); + w->viewport->CancelFollow(*w); w->viewport->dest_scrollpos_y += ScaleByZoom((15 - (vp->height - y)) * SCROLLSPEED, vp->zoom); } } @@ -2775,7 +2775,8 @@ static void HandleKeyScrolling() if (_game_mode != GM_MENU && _game_mode != GM_BOOTSTRAP) { /* Key scrolling stops following a vehicle. */ - GetMainWindow()->viewport->follow_vehicle = VehicleID::Invalid(); + Window *main_window = GetMainWindow(); + main_window->viewport->CancelFollow(*main_window); } ScrollMainViewport(scrollamt[_dirkeys][0] * factor, scrollamt[_dirkeys][1] * factor); diff --git a/src/window_gui.h b/src/window_gui.h index 8d1718717b..9b27432192 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -254,6 +254,8 @@ struct ViewportData : Viewport { int32_t scrollpos_y; ///< Currently shown y coordinate (virtual screen coordinate of topleft corner of the viewport). int32_t dest_scrollpos_x; ///< Current destination x coordinate to display (virtual screen coordinate of topleft corner of the viewport). int32_t dest_scrollpos_y; ///< Current destination y coordinate to display (virtual screen coordinate of topleft corner of the viewport). + + void CancelFollow(const Window &viewport_window); }; struct QueryString;