diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index e312160b2f..9b8cd466a9 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3682,18 +3682,17 @@ STR_6576 :Adds special colours to colour dropdown STR_6577 :Block brake speed STR_6578 :Set speed limit for block brakes. In block section mode, adjacent brakes with a slower speed are linked to the block brake. STR_6579 :Block brakes will be set to default speed when saved as track design - STR_6580 :Reset STR_6581 :Are you sure you want to reset all shortcut keys on this tab? STR_6582 :Open keyboard shortcuts window - STR_6583 :{WINDOW_COLOUR_2}Reversed Trains STR_6584 :Select to run trains backwards STR_6585 :Can’t make changes… - STR_6586 :OpenRCT2 STR_6587 :The OpenRCT2 Title Theme is a work of Allister Brimble,{NEWLINE}licensed CC BY-SA 4.0. STR_6588 :Thanks to Herman Riddering for allowing us to record the 35er Voigt. +STR_6589 :Show window buttons on the left +STR_6590 :Show the window buttons (e.g. to close the window) on the left of the title bar instead of on the right. ############# # Scenarios # diff --git a/distribution/changelog.txt b/distribution/changelog.txt index e90371d755..6e2a072adc 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,5 +1,6 @@ 0.4.6 (in development) ------------------------------------------------------------------------ +- Feature: [#15660] Ability to show window buttons on the left. - Feature: [OpenMusic#41] Official Title Theme by Allister Brimble. - Improved: [#20200] Allow audio files to play to up to 44100hz sample rate (from 22050hz). - Change: [#20110] Fix a few RCT1 build height parity discrepancies. diff --git a/src/openrct2-ui/interface/Widget.cpp b/src/openrct2-ui/interface/Widget.cpp index b86d3e1293..ac979cd5a5 100644 --- a/src/openrct2-ui/interface/Widget.cpp +++ b/src/openrct2-ui/interface/Widget.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -565,11 +566,14 @@ static void WidgetCaptionDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid int32_t width = widget->width() - 4; if ((widget + 1)->type == WindowWidgetType::CloseBox) { - width -= 10; + width -= CloseButtonWidth; if ((widget + 2)->type == WindowWidgetType::CloseBox) - width -= 10; + width -= CloseButtonWidth; } topLeft.x += width / 2; + if (gConfigInterface.WindowButtonsOnTheLeft) + topLeft.x += CloseButtonWidth; + DrawTextEllipsised( dpi, topLeft, width, widget->text, Formatter::Common(), { COLOUR_WHITE | static_cast(COLOUR_FLAG_OUTLINE), TextAlignment::CENTRE }); diff --git a/src/openrct2-ui/interface/Window.cpp b/src/openrct2-ui/interface/Window.cpp index 62a83d94a6..d80699c7a6 100644 --- a/src/openrct2-ui/interface/Window.cpp +++ b/src/openrct2-ui/interface/Window.cpp @@ -828,3 +828,9 @@ void WindowAlignTabs(WindowBase* w, WidgetIndex start_tab_id, WidgetIndex end_ta } } } + +ScreenCoordsXY WindowGetViewportSoundIconPos(WindowBase& w) +{ + const uint8_t buttonOffset = (gConfigInterface.WindowButtonsOnTheLeft) ? CloseButtonWidth + 2 : 0; + return w.windowPos + ScreenCoordsXY{ 2 + buttonOffset, 2 }; +} diff --git a/src/openrct2-ui/interface/Window.h b/src/openrct2-ui/interface/Window.h index 576e194ebe..31a3f60ad0 100644 --- a/src/openrct2-ui/interface/Window.h +++ b/src/openrct2-ui/interface/Window.h @@ -39,3 +39,4 @@ struct Window : WindowBase void WindowAllWheelInput(); void ApplyScreenSaverLockSetting(); void WindowAlignTabs(WindowBase* w, WidgetIndex start_tab_id, WidgetIndex end_tab_id); +ScreenCoordsXY WindowGetViewportSoundIconPos(WindowBase& w); diff --git a/src/openrct2-ui/scripting/CustomWindow.cpp b/src/openrct2-ui/scripting/CustomWindow.cpp index 92220060da..926e93dd69 100644 --- a/src/openrct2-ui/scripting/CustomWindow.cpp +++ b/src/openrct2-ui/scripting/CustomWindow.cpp @@ -49,7 +49,7 @@ namespace OpenRCT2::Ui::Windows static Widget CustomDefaultWidgets[] = { { WindowWidgetType::Frame, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE }, // panel / background - { WindowWidgetType::Caption, 0, 1, 0, 1, 14, STR_STRING, STR_WINDOW_TITLE_TIP }, // title bar + { WindowWidgetType::Caption, 0, 0, 0, 1, 14, STR_STRING, STR_WINDOW_TITLE_TIP }, // title bar { WindowWidgetType::CloseBox, 0, 0, 0, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, // close x button { WindowWidgetType::Resize, 1, 0, 0, 14, 0, 0xFFFFFFFF, STR_NONE }, // content panel }; @@ -476,13 +476,9 @@ namespace OpenRCT2::Ui::Windows void OnPrepareDraw() override { - widgets[WIDX_BACKGROUND].right = width - 1; - widgets[WIDX_BACKGROUND].bottom = height - 1; - widgets[WIDX_TITLE].right = width - 2; - widgets[WIDX_CLOSE].left = width - 13; - widgets[WIDX_CLOSE].right = width - 3; - widgets[WIDX_CONTENT_PANEL].right = width - 1; - widgets[WIDX_CONTENT_PANEL].bottom = height - 1; + // This has to be called to ensure the window frame is correctly initialised - not doing this will + // cause an assertion to be hit. + ResizeFrameWithPage(); widgets[WIDX_CLOSE].text = (colours[0] & COLOUR_FLAG_TRANSLUCENT) ? STR_CLOSE_X_WHITE : STR_CLOSE_X; // Having the content panel visible for transparent windows makes the borders darker than they should be diff --git a/src/openrct2-ui/windows/About.cpp b/src/openrct2-ui/windows/About.cpp index 1230ea7c35..46b746181b 100644 --- a/src/openrct2-ui/windows/About.cpp +++ b/src/openrct2-ui/windows/About.cpp @@ -261,6 +261,11 @@ private: // Licence } + + void OnResize() override + { + ResizeFrameWithPage(); + } }; /** diff --git a/src/openrct2-ui/windows/Banner.cpp b/src/openrct2-ui/windows/Banner.cpp index f61ef7e7c6..9c020c6fc2 100644 --- a/src/openrct2-ui/windows/Banner.cpp +++ b/src/openrct2-ui/windows/Banner.cpp @@ -295,6 +295,11 @@ public: Widget* dropDownWidget = &window_banner_widgets[WIDX_TEXT_COLOUR_DROPDOWN]; dropDownWidget->text = BannerColouredTextFormats[banner->text_colour]; } + + void OnResize() override + { + ResizeFrame(); + } }; /** diff --git a/src/openrct2-ui/windows/Cheats.cpp b/src/openrct2-ui/windows/Cheats.cpp index 83cbbdca7a..5bd005a65e 100644 --- a/src/openrct2-ui/windows/Cheats.cpp +++ b/src/openrct2-ui/windows/Cheats.cpp @@ -1121,6 +1121,11 @@ private: break; } } + + void OnResize() override + { + ResizeFrameWithPage(); + } }; WindowBase* WindowCheatsOpen() diff --git a/src/openrct2-ui/windows/ClearScenery.cpp b/src/openrct2-ui/windows/ClearScenery.cpp index 6685b3c356..968558f8ed 100644 --- a/src/openrct2-ui/windows/ClearScenery.cpp +++ b/src/openrct2-ui/windows/ClearScenery.cpp @@ -195,6 +195,11 @@ public: DrawTextBasic(dpi, screenCoords, STR_COST_AMOUNT, ft, { TextAlignment::CENTRE }); } } + + void OnResize() override + { + ResizeFrame(); + } }; WindowBase* WindowClearSceneryOpen() diff --git a/src/openrct2-ui/windows/CustomCurrency.cpp b/src/openrct2-ui/windows/CustomCurrency.cpp index c6c79d6317..b5be3ab9ce 100644 --- a/src/openrct2-ui/windows/CustomCurrency.cpp +++ b/src/openrct2-ui/windows/CustomCurrency.cpp @@ -218,6 +218,11 @@ public: : STR_SUFFIX; DrawTextBasic(dpi, drawPos, stringId, {}, { colours[1] }); } + + void OnResize() override + { + ResizeFrame(); + } }; WindowBase* CustomCurrencyWindowOpen() diff --git a/src/openrct2-ui/windows/DemolishRidePrompt.cpp b/src/openrct2-ui/windows/DemolishRidePrompt.cpp index 63f25b2a98..0e60317cdf 100644 --- a/src/openrct2-ui/windows/DemolishRidePrompt.cpp +++ b/src/openrct2-ui/windows/DemolishRidePrompt.cpp @@ -90,6 +90,11 @@ public: DrawTextWrapped(dpi, stringCoords, WW - 4, stringId, ft, { TextAlignment::CENTRE }); } } + + void OnResize() override + { + ResizeFrame(); + } }; WindowBase* WindowRideDemolishPromptOpen(const Ride& ride) diff --git a/src/openrct2-ui/windows/Finances.cpp b/src/openrct2-ui/windows/Finances.cpp index 0c548da76b..da854e1100 100644 --- a/src/openrct2-ui/windows/Finances.cpp +++ b/src/openrct2-ui/windows/Finances.cpp @@ -937,6 +937,11 @@ public: DrawTabImage(dpi, WINDOW_FINANCES_PAGE_MARKETING, SPR_TAB_FINANCES_MARKETING_0); DrawTabImage(dpi, WINDOW_FINANCES_PAGE_RESEARCH, SPR_TAB_FINANCES_RESEARCH_0); } + + void OnResize() override + { + ResizeFrameWithPage(); + } }; static FinancesWindow* FinancesWindowOpen(uint8_t page) diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index 31010db170..42e6a99c4e 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -1399,6 +1399,11 @@ public: OnMouseUp(WIDX_CONSTRUCT); } + void OnResize() override + { + ResizeFrame(); + } + #pragma endregion }; diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 8876064635..1bf8d56dd2 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -755,7 +755,7 @@ private: WindowDrawViewport(dpi, *this); if (viewport->flags & VIEWPORT_FLAG_SOUND_ON) { - GfxDrawSprite(dpi, ImageId(SPR_HEARING_VIEWPORT), windowPos + ScreenCoordsXY{ 2, 2 }); + GfxDrawSprite(dpi, ImageId(SPR_HEARING_VIEWPORT), WindowGetViewportSoundIconPos(*this)); } } diff --git a/src/openrct2-ui/windows/InstallTrack.cpp b/src/openrct2-ui/windows/InstallTrack.cpp index 9b91ae2141..d194251f71 100644 --- a/src/openrct2-ui/windows/InstallTrack.cpp +++ b/src/openrct2-ui/windows/InstallTrack.cpp @@ -359,6 +359,11 @@ public: } } + void OnResize() override + { + ResizeFrame(); + } + private: void UpdatePreview() { diff --git a/src/openrct2-ui/windows/Land.cpp b/src/openrct2-ui/windows/Land.cpp index ae9984e9ff..6484b96aec 100644 --- a/src/openrct2-ui/windows/Land.cpp +++ b/src/openrct2-ui/windows/Land.cpp @@ -307,6 +307,11 @@ public: } } + void OnResize() override + { + ResizeFrame(); + } + private: void DrawDropdownButtons(DrawPixelInfo& dpi) { diff --git a/src/openrct2-ui/windows/LandRights.cpp b/src/openrct2-ui/windows/LandRights.cpp index 708f3d13ed..dd9d91f4fb 100644 --- a/src/openrct2-ui/windows/LandRights.cpp +++ b/src/openrct2-ui/windows/LandRights.cpp @@ -377,6 +377,11 @@ public: } } + void OnResize() override + { + ResizeFrame(); + } + private: uint8_t _landRightsMode; money64 _landRightsCost; diff --git a/src/openrct2-ui/windows/MapGen.cpp b/src/openrct2-ui/windows/MapGen.cpp index 52be1db3d9..9308fd3610 100644 --- a/src/openrct2-ui/windows/MapGen.cpp +++ b/src/openrct2-ui/windows/MapGen.cpp @@ -1371,6 +1371,11 @@ public: HeightmapGenerateMap(); } } + + void OnResize() override + { + ResizeFrameWithPage(); + } }; WindowBase* WindowMapgenOpen() diff --git a/src/openrct2-ui/windows/MazeConstruction.cpp b/src/openrct2-ui/windows/MazeConstruction.cpp index 334f612696..317d4742ab 100644 --- a/src/openrct2-ui/windows/MazeConstruction.cpp +++ b/src/openrct2-ui/windows/MazeConstruction.cpp @@ -162,6 +162,7 @@ public: void OnResize() override { + ResizeFrameWithPage(); uint64_t disabledWidgets = 0; if (_rideConstructionState == RideConstructionState::Place) { diff --git a/src/openrct2-ui/windows/NewCampaign.cpp b/src/openrct2-ui/windows/NewCampaign.cpp index a5295b8558..3fbb32cc17 100644 --- a/src/openrct2-ui/windows/NewCampaign.cpp +++ b/src/openrct2-ui/windows/NewCampaign.cpp @@ -369,6 +369,11 @@ public: ft.Add(AdvertisingCampaignPricePerWeek[campaign.campaign_type] * campaign.no_weeks); DrawTextBasic(dpi, screenCoords, STR_MARKETING_TOTAL_COST, ft); } + + void OnResize() override + { + ResizeFrame(); + } }; WindowBase* WindowNewCampaignOpen(int16_t campaignType) diff --git a/src/openrct2-ui/windows/News.cpp b/src/openrct2-ui/windows/News.cpp index 99bc5b691b..9273fb389e 100644 --- a/src/openrct2-ui/windows/News.cpp +++ b/src/openrct2-ui/windows/News.cpp @@ -306,6 +306,11 @@ public: i++; } } + + void OnResize() override + { + ResizeFrame(); + } }; WindowBase* WindowNewsOpen() diff --git a/src/openrct2-ui/windows/NewsOptions.cpp b/src/openrct2-ui/windows/NewsOptions.cpp index 10913b5c17..c0a9a6de56 100644 --- a/src/openrct2-ui/windows/NewsOptions.cpp +++ b/src/openrct2-ui/windows/NewsOptions.cpp @@ -259,6 +259,11 @@ private: return configValue; } + void OnResize() override + { + ResizeFrameWithPage(); + } + static constexpr int32_t TabAnimationDivisor[3] = { 1, // Park 4, // Ride diff --git a/src/openrct2-ui/windows/ObjectLoadError.cpp b/src/openrct2-ui/windows/ObjectLoadError.cpp index 0848748d3e..131f2c9b94 100644 --- a/src/openrct2-ui/windows/ObjectLoadError.cpp +++ b/src/openrct2-ui/windows/ObjectLoadError.cpp @@ -551,6 +551,11 @@ public: } } + void OnResize() override + { + ResizeFrame(); + } + void Initialise(utf8* path, const size_t numMissingObjects, const ObjectEntryDescriptor* missingObjects) { _invalidEntries = std::vector(missingObjects, missingObjects + numMissingObjects); diff --git a/src/openrct2-ui/windows/Options.cpp b/src/openrct2-ui/windows/Options.cpp index 2c395aa061..3096d7c126 100644 --- a/src/openrct2-ui/windows/Options.cpp +++ b/src/openrct2-ui/windows/Options.cpp @@ -159,6 +159,7 @@ enum WindowOptionsWidgetIdx { WIDX_TRAP_CURSOR, WIDX_INVERT_DRAG, WIDX_ZOOM_TO_CURSOR, + WIDX_WINDOW_BUTTONS_ON_THE_LEFT, WIDX_HOTKEY_DROPDOWN, WIDX_THEMES_GROUP, WIDX_THEMES_LABEL, @@ -318,21 +319,22 @@ static Widget window_options_audio_widgets[] = { static Widget window_options_controls_and_interface_widgets[] = { MAIN_OPTIONS_WIDGETS, #define CONTROLS_GROUP_START 53 - MakeWidget({ 5, CONTROLS_GROUP_START + 0}, {300, 92}, WindowWidgetType::Groupbox, WindowColour::Secondary, STR_CONTROLS_GROUP ), // Controls group - MakeWidget({ 10, CONTROLS_GROUP_START + 13}, {290, 14}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_SCREEN_EDGE_SCROLLING, STR_SCREEN_EDGE_SCROLLING_TIP ), // Edge scrolling - MakeWidget({ 10, CONTROLS_GROUP_START + 30}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_TRAP_MOUSE, STR_TRAP_MOUSE_TIP ), // Trap mouse - MakeWidget({ 10, CONTROLS_GROUP_START + 45}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_INVERT_RIGHT_MOUSE_DRAG, STR_INVERT_RIGHT_MOUSE_DRAG_TIP), // Invert right mouse dragging - MakeWidget({ 10, CONTROLS_GROUP_START + 60}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_ZOOM_TO_CURSOR, STR_ZOOM_TO_CURSOR_TIP ), // Zoom to cursor - MakeWidget({155, CONTROLS_GROUP_START + 75}, {145, 13}, WindowWidgetType::Button, WindowColour::Secondary, STR_HOTKEY, STR_HOTKEY_TIP ), // Set hotkeys buttons + MakeWidget({ 5, CONTROLS_GROUP_START + 0}, {300,107}, WindowWidgetType::Groupbox, WindowColour::Secondary, STR_CONTROLS_GROUP ), // Controls group + MakeWidget({ 10, CONTROLS_GROUP_START + 13}, {290, 14}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_SCREEN_EDGE_SCROLLING, STR_SCREEN_EDGE_SCROLLING_TIP ), // Edge scrolling + MakeWidget({ 10, CONTROLS_GROUP_START + 30}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_TRAP_MOUSE, STR_TRAP_MOUSE_TIP ), // Trap mouse + MakeWidget({ 10, CONTROLS_GROUP_START + 45}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_INVERT_RIGHT_MOUSE_DRAG, STR_INVERT_RIGHT_MOUSE_DRAG_TIP ), // Invert right mouse dragging + MakeWidget({ 10, CONTROLS_GROUP_START + 60}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_ZOOM_TO_CURSOR, STR_ZOOM_TO_CURSOR_TIP ), // Zoom to cursor + MakeWidget({ 10, CONTROLS_GROUP_START + 75}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary, STR_WINDOW_BUTTONS_ON_THE_LEFT, STR_WINDOW_BUTTONS_ON_THE_LEFT_TIP), // Window buttons on the left + MakeWidget({155, CONTROLS_GROUP_START + 90}, {145, 13}, WindowWidgetType::Button, WindowColour::Secondary, STR_HOTKEY, STR_HOTKEY_TIP ), // Set hotkeys buttons #undef CONTROLS_GROUP_START -#define THEMES_GROUP_START 148 +#define THEMES_GROUP_START 163 MakeWidget({ 5, THEMES_GROUP_START + 0}, {300, 48}, WindowWidgetType::Groupbox, WindowColour::Secondary, STR_THEMES_GROUP ), // Themes group MakeWidget({ 10, THEMES_GROUP_START + 14}, {145, 12}, WindowWidgetType::Label, WindowColour::Secondary, STR_THEMES_LABEL_CURRENT_THEME, STR_CURRENT_THEME_TIP ), // Themes MakeWidget({155, THEMES_GROUP_START + 14}, {145, 12}, WindowWidgetType::DropdownMenu, WindowColour::Secondary, STR_STRING ), MakeWidget({288, THEMES_GROUP_START + 15}, { 11, 10}, WindowWidgetType::Button, WindowColour::Secondary, STR_DROPDOWN_GLYPH, STR_CURRENT_THEME_TIP ), MakeWidget({155, THEMES_GROUP_START + 30}, {145, 13}, WindowWidgetType::Button, WindowColour::Secondary, STR_EDIT_THEMES_BUTTON, STR_EDIT_THEMES_BUTTON_TIP), // Themes button #undef THEMES_GROUP_START -#define TOOLBAR_GROUP_START 200 +#define TOOLBAR_GROUP_START 215 MakeWidget({ 5, TOOLBAR_GROUP_START + 0}, {300, 92}, WindowWidgetType::Groupbox, WindowColour::Secondary, STR_TOOLBAR_BUTTONS_GROUP ), // Toolbar buttons group MakeWidget({ 10, TOOLBAR_GROUP_START + 14}, {280, 12}, WindowWidgetType::Label, WindowColour::Secondary, STR_SHOW_TOOLBAR_BUTTONS_FOR ), MakeWidget({ 24, TOOLBAR_GROUP_START + 31}, {122, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_FINANCES_BUTTON_ON_TOOLBAR, STR_FINANCES_BUTTON_ON_TOOLBAR_TIP ), // Finances @@ -663,8 +665,11 @@ private: y = std::max(y, widget->bottom); } height = y + 6; - widgets[WIDX_BACKGROUND].bottom = height - 1; - widgets[WIDX_PAGE_BACKGROUND].bottom = height - 1; + } + + void OnResize() override + { + ResizeFrameWithPage(); } void CommonUpdate() @@ -1582,6 +1587,12 @@ private: Invalidate(); WindowInvalidateByClass(WindowClass::TopToolbar); break; + case WIDX_WINDOW_BUTTONS_ON_THE_LEFT: + gConfigInterface.WindowButtonsOnTheLeft ^= 1; + ConfigSaveDefault(); + Invalidate(); + WindowInvalidateAll(); + break; case WIDX_INVERT_DRAG: gConfigGeneral.InvertViewportDrag ^= 1; ConfigSaveDefault(); @@ -1646,6 +1657,7 @@ private: SetCheckboxValue(WIDX_TOOLBAR_SHOW_MUTE, gConfigInterface.ToolbarShowMute); SetCheckboxValue(WIDX_TOOLBAR_SHOW_CHAT, gConfigInterface.ToolbarShowChat); SetCheckboxValue(WIDX_TOOLBAR_SHOW_ZOOM, gConfigInterface.ToolbarShowZoom); + SetCheckboxValue(WIDX_WINDOW_BUTTONS_ON_THE_LEFT, gConfigInterface.WindowButtonsOnTheLeft); size_t activeAvailableThemeIndex = ThemeManagerGetAvailableThemeIndex(); const utf8* activeThemeName = ThemeManagerGetAvailableThemeName(activeAvailableThemeIndex); diff --git a/src/openrct2-ui/windows/Park.cpp b/src/openrct2-ui/windows/Park.cpp index e020545f4f..717fbc1ee8 100644 --- a/src/openrct2-ui/windows/Park.cpp +++ b/src/openrct2-ui/windows/Park.cpp @@ -595,7 +595,7 @@ private: { WindowDrawViewport(dpi, *this); if (viewport->flags & VIEWPORT_FLAG_SOUND_ON) - GfxDrawSprite(dpi, ImageId(SPR_HEARING_VIEWPORT), windowPos + ScreenCoordsXY{ 2, 2 }); + GfxDrawSprite(dpi, ImageId(SPR_HEARING_VIEWPORT), WindowGetViewportSoundIconPos(*this)); } // Draw park closed / open label diff --git a/src/openrct2-ui/windows/PatrolArea.cpp b/src/openrct2-ui/windows/PatrolArea.cpp index 5c5a775a38..b741820291 100644 --- a/src/openrct2-ui/windows/PatrolArea.cpp +++ b/src/openrct2-ui/windows/PatrolArea.cpp @@ -283,6 +283,11 @@ private: auto coords = FootpathGetCoordinatesFromPos(pos, nullptr, nullptr); return coords.IsNull() ? std::nullopt : std::make_optional(coords); } + + void OnResize() override + { + ResizeFrame(); + } }; WindowBase* WindowPatrolAreaOpen(EntityId staffId) diff --git a/src/openrct2-ui/windows/RefurbishRidePrompt.cpp b/src/openrct2-ui/windows/RefurbishRidePrompt.cpp index b830e2fe12..f5ca03a5be 100644 --- a/src/openrct2-ui/windows/RefurbishRidePrompt.cpp +++ b/src/openrct2-ui/windows/RefurbishRidePrompt.cpp @@ -89,6 +89,11 @@ public: DrawTextWrapped(dpi, stringCoords, WW - 4, stringId, ft, { TextAlignment::CENTRE }); } } + + void OnResize() override + { + ResizeFrame(); + } }; WindowBase* WindowRideRefurbishPromptOpen(const Ride& ride) diff --git a/src/openrct2-ui/windows/Research.cpp b/src/openrct2-ui/windows/Research.cpp index dbed33e9aa..d8e78ac129 100644 --- a/src/openrct2-ui/windows/Research.cpp +++ b/src/openrct2-ui/windows/Research.cpp @@ -280,6 +280,11 @@ private: } } + void OnResize() override + { + ResizeFrameWithPage(); + } + void DrawTabImage(DrawPixelInfo& dpi, int32_t tabPage, int32_t spriteIndex) { WidgetIndex widgetIndex = WIDX_TAB_1 + tabPage; diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 9ab4efa397..39287c80b3 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -2595,7 +2595,7 @@ static void WindowRideMainPaint(WindowBase* w, DrawPixelInfo& dpi) { WindowDrawViewport(dpi, *w); if (w->viewport->flags & VIEWPORT_FLAG_SOUND_ON) - GfxDrawSprite(dpi, ImageId(SPR_HEARING_VIEWPORT), w->windowPos + ScreenCoordsXY{ 2, 2 }); + GfxDrawSprite(dpi, ImageId(SPR_HEARING_VIEWPORT), WindowGetViewportSoundIconPos(*w)); } // View dropdown diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index bdc3492960..886b585e11 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -304,6 +304,7 @@ public: void OnResize() override { + ResizeFrame(); WindowRideConstructionUpdateEnabledTrackPieces(); auto currentRide = GetRide(_currentRideIndex); diff --git a/src/openrct2-ui/windows/SavePrompt.cpp b/src/openrct2-ui/windows/SavePrompt.cpp index 61797f8cfc..2439e9fd0b 100644 --- a/src/openrct2-ui/windows/SavePrompt.cpp +++ b/src/openrct2-ui/windows/SavePrompt.cpp @@ -185,6 +185,11 @@ public: { DrawWidgets(dpi); } + + void OnResize() override + { + ResizeFrame(); + } }; WindowBase* WindowSavePromptOpen() diff --git a/src/openrct2-ui/windows/Scenery.cpp b/src/openrct2-ui/windows/Scenery.cpp index adde85b1e8..73837de353 100644 --- a/src/openrct2-ui/windows/Scenery.cpp +++ b/src/openrct2-ui/windows/Scenery.cpp @@ -317,6 +317,8 @@ public: WindowEventInvalidateCall(this); ContentUpdateScroll(); } + + ResizeFrameWithPage(); } void OnMouseDown(WidgetIndex widgetIndex) override @@ -739,13 +741,6 @@ public: } } - widgets[WIDX_SCENERY_BACKGROUND].right = windowWidth - 1; - widgets[WIDX_SCENERY_BACKGROUND].bottom = height - 1; - widgets[WIDX_SCENERY_TAB_CONTENT_PANEL].right = windowWidth - 1; - widgets[WIDX_SCENERY_TAB_CONTENT_PANEL].bottom = height - 1; - widgets[WIDX_SCENERY_TITLE].right = windowWidth - 2; - widgets[WIDX_SCENERY_CLOSE].left = windowWidth - 13; - widgets[WIDX_SCENERY_CLOSE].right = widgets[WIDX_SCENERY_CLOSE].left + 10; widgets[WIDX_SCENERY_LIST].right = windowWidth - 26; widgets[WIDX_SCENERY_LIST].bottom = height - 14; diff --git a/src/openrct2-ui/windows/SceneryScatter.cpp b/src/openrct2-ui/windows/SceneryScatter.cpp index c2a8ac206d..c3357ae77d 100644 --- a/src/openrct2-ui/windows/SceneryScatter.cpp +++ b/src/openrct2-ui/windows/SceneryScatter.cpp @@ -190,6 +190,11 @@ public: DrawTextBasic(dpi, screenCoords - ScreenCoordsXY{ 0, 2 }, STR_LAND_TOOL_SIZE_VALUE, ft, { TextAlignment::CENTRE }); } } + + void OnResize() override + { + ResizeFrame(); + } }; WindowBase* WindowSceneryScatterOpen() diff --git a/src/openrct2-ui/windows/ServerStart.cpp b/src/openrct2-ui/windows/ServerStart.cpp index bf9d4f934d..706f7ef279 100644 --- a/src/openrct2-ui/windows/ServerStart.cpp +++ b/src/openrct2-ui/windows/ServerStart.cpp @@ -248,6 +248,11 @@ public: DrawTextBasic(dpi, windowPos + ScreenCoordsXY{ 6, widgets[WIDX_MAXPLAYERS].top }, STR_MAX_PLAYERS, {}, { colours[1] }); } + void OnResize() override + { + ResizeFrame(); + } + private: char _port[7]; char _name[65]; diff --git a/src/openrct2-ui/windows/Sign.cpp b/src/openrct2-ui/windows/Sign.cpp index 1676732317..ddaaa78c4c 100644 --- a/src/openrct2-ui/windows/Sign.cpp +++ b/src/openrct2-ui/windows/Sign.cpp @@ -318,6 +318,11 @@ public: viewport->flags = gConfigGeneral.AlwaysShowGridlines ? VIEWPORT_FLAG_GRIDLINES : 0; Invalidate(); } + + void OnResize() override + { + ResizeFrame(); + } }; /** diff --git a/src/openrct2-ui/windows/Staff.cpp b/src/openrct2-ui/windows/Staff.cpp index 652313e13c..92bbd998ba 100644 --- a/src/openrct2-ui/windows/Staff.cpp +++ b/src/openrct2-ui/windows/Staff.cpp @@ -522,7 +522,7 @@ private: if (viewport->flags & VIEWPORT_FLAG_SOUND_ON) { - GfxDrawSprite(dpi, ImageId(SPR_HEARING_VIEWPORT), windowPos + ScreenCoordsXY{ 2, 2 }); + GfxDrawSprite(dpi, ImageId(SPR_HEARING_VIEWPORT), WindowGetViewportSoundIconPos(*this)); } } diff --git a/src/openrct2-ui/windows/StaffFirePrompt.cpp b/src/openrct2-ui/windows/StaffFirePrompt.cpp index ae6157f776..2d9654c62d 100644 --- a/src/openrct2-ui/windows/StaffFirePrompt.cpp +++ b/src/openrct2-ui/windows/StaffFirePrompt.cpp @@ -83,6 +83,11 @@ public: ScreenCoordsXY textCoords(windowPos + ScreenCoordsXY{ WW / 2, (WH / 2) - 3 }); DrawTextWrapped(dpi, textCoords, WW - 4, STR_FIRE_STAFF_ID, ft, { TextAlignment::CENTRE }); } + + void OnResize() override + { + ResizeFrame(); + } }; WindowBase* WindowStaffFirePromptOpen(Peep* peep) diff --git a/src/openrct2-ui/windows/StaffList.cpp b/src/openrct2-ui/windows/StaffList.cpp index de9d280e9a..d7ff745021 100644 --- a/src/openrct2-ui/windows/StaffList.cpp +++ b/src/openrct2-ui/windows/StaffList.cpp @@ -177,6 +177,7 @@ public: height = min_height; Invalidate(); } + ResizeFrameWithPage(); } void OnUpdate() override @@ -263,13 +264,6 @@ public: } SetWidgetPressed(WIDX_STAFF_LIST_QUICK_FIRE, _quickFireMode); - widgets[WIDX_STAFF_LIST_BACKGROUND].right = width - 1; - widgets[WIDX_STAFF_LIST_BACKGROUND].bottom = height - 1; - widgets[WIDX_STAFF_LIST_TAB_CONTENT_PANEL].right = width - 1; - widgets[WIDX_STAFF_LIST_TAB_CONTENT_PANEL].bottom = height - 1; - widgets[WIDX_STAFF_LIST_TITLE].right = width - 2; - widgets[WIDX_STAFF_LIST_CLOSE].left = width - 2 - 11; - widgets[WIDX_STAFF_LIST_CLOSE].right = width - 2 - 11 + 10; widgets[WIDX_STAFF_LIST_LIST].right = width - 4; widgets[WIDX_STAFF_LIST_LIST].bottom = height - 15; widgets[WIDX_STAFF_LIST_QUICK_FIRE].left = width - 77; diff --git a/src/openrct2-ui/windows/TextInput.cpp b/src/openrct2-ui/windows/TextInput.cpp index c7b39945d0..d98b2ffade 100644 --- a/src/openrct2-ui/windows/TextInput.cpp +++ b/src/openrct2-ui/windows/TextInput.cpp @@ -313,6 +313,11 @@ public: return numLines * 10 + WH; } + void OnResize() override + { + ResizeFrame(); + } + private: static void DrawIMEComposition(DrawPixelInfo& dpi, int32_t cursorX, int32_t cursorY) { diff --git a/src/openrct2-ui/windows/Themes.cpp b/src/openrct2-ui/windows/Themes.cpp index d24f80b4ce..7871e964b4 100644 --- a/src/openrct2-ui/windows/Themes.cpp +++ b/src/openrct2-ui/windows/Themes.cpp @@ -350,6 +350,8 @@ public: Invalidate(); } } + + ResizeFrameWithPage(); } void OnUpdate() override @@ -377,13 +379,6 @@ public: _colour_index_2 = -1; } - window_themes_widgets[WIDX_THEMES_BACKGROUND].right = width - 1; - window_themes_widgets[WIDX_THEMES_BACKGROUND].bottom = height - 1; - window_themes_widgets[WIDX_THEMES_TAB_CONTENT_PANEL].right = width - 1; - window_themes_widgets[WIDX_THEMES_TAB_CONTENT_PANEL].bottom = height - 1; - window_themes_widgets[WIDX_THEMES_TITLE].right = width - 2; - window_themes_widgets[WIDX_THEMES_CLOSE].left = width - 2 - 0x0B; - window_themes_widgets[WIDX_THEMES_CLOSE].right = width - 2 - 0x0B + 0x0A; window_themes_widgets[WIDX_THEMES_LIST].right = width - 4; window_themes_widgets[WIDX_THEMES_LIST].bottom = height - 0x0F; diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index 0cb5aac216..277dac2306 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -727,6 +727,7 @@ public: Invalidate(); height = min_height; } + ResizeFrame(); } void OnMouseDown(WidgetIndex widgetIndex) override diff --git a/src/openrct2-ui/windows/TrackDesignManage.cpp b/src/openrct2-ui/windows/TrackDesignManage.cpp index aecab10a40..88084988c6 100644 --- a/src/openrct2-ui/windows/TrackDesignManage.cpp +++ b/src/openrct2-ui/windows/TrackDesignManage.cpp @@ -67,6 +67,11 @@ class TrackDesignManageWindow final : public Window void OnMouseUp(WidgetIndex widgetIndex) override; void OnTextInput(WidgetIndex widgetIndex, std::string_view text) override; void OnDraw(DrawPixelInfo& dpi) override; + + void OnResize() override + { + ResizeFrame(); + } }; class TrackDeletePromptWindow final : public Window @@ -80,6 +85,11 @@ class TrackDeletePromptWindow final : public Window void OnOpen() override; void OnMouseUp(WidgetIndex widgetIndex) override; void OnDraw(DrawPixelInfo& dpi) override; + + void OnResize() override + { + ResizeFrame(); + } }; static void WindowTrackDeletePromptOpen(TrackDesignFileRef* tdFileRef); diff --git a/src/openrct2-ui/windows/TrackDesignPlace.cpp b/src/openrct2-ui/windows/TrackDesignPlace.cpp index 32d38e5540..3d8dca0886 100644 --- a/src/openrct2-ui/windows/TrackDesignPlace.cpp +++ b/src/openrct2-ui/windows/TrackDesignPlace.cpp @@ -312,6 +312,11 @@ public: } } + void OnResize() override + { + ResizeFrame(); + } + void ClearProvisionalTemporarily() { if (_hasPlacementGhost) diff --git a/src/openrct2-ui/windows/TrackList.cpp b/src/openrct2-ui/windows/TrackList.cpp index 74fa898b11..007b5bfd63 100644 --- a/src/openrct2-ui/windows/TrackList.cpp +++ b/src/openrct2-ui/windows/TrackList.cpp @@ -741,6 +741,11 @@ public: LoadDesignsList(item); return true; } + + void OnResize() override + { + ResizeFrame(); + } }; WindowBase* WindowTrackListOpen(const RideSelection item) diff --git a/src/openrct2-ui/windows/Transparency.cpp b/src/openrct2-ui/windows/Transparency.cpp index 1db37999b4..ffa83a7613 100644 --- a/src/openrct2-ui/windows/Transparency.cpp +++ b/src/openrct2-ui/windows/Transparency.cpp @@ -242,6 +242,11 @@ private: gConfigGeneral.InvisibleSupports = wflags & VIEWPORT_FLAG_INVISIBLE_SUPPORTS; ConfigSaveDefault(); } + + void OnResize() override + { + ResizeFrame(); + } }; WindowBase* WindowTransparencyOpen() diff --git a/src/openrct2-ui/windows/ViewClipping.cpp b/src/openrct2-ui/windows/ViewClipping.cpp index 8c6b9fd1c9..e28ae5bce9 100644 --- a/src/openrct2-ui/windows/ViewClipping.cpp +++ b/src/openrct2-ui/windows/ViewClipping.cpp @@ -365,6 +365,11 @@ public: } } + void OnResize() override + { + ResizeFrame(); + } + private: void OnClose() override { diff --git a/src/openrct2-ui/windows/Water.cpp b/src/openrct2-ui/windows/Water.cpp index 1fce7975c0..89a43b98c5 100644 --- a/src/openrct2-ui/windows/Water.cpp +++ b/src/openrct2-ui/windows/Water.cpp @@ -175,6 +175,11 @@ public: } } + void OnResize() override + { + ResizeFrame(); + } + private: void InputSize() { diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index 1e75cff005..3848f859dd 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -38,6 +38,12 @@ using namespace OpenRCT2; using namespace OpenRCT2::Ui; +#ifdef __APPLE__ +static constexpr const bool WindowButtonsOnTheLeftDefault = true; +#else +static constexpr const bool WindowButtonsOnTheLeftDefault = false; +#endif + namespace Config { #pragma region Enums @@ -331,6 +337,7 @@ namespace Config model->ObjectSelectionFilterFlags = reader->GetInt32("object_selection_filter_flags", 0x3FFF); model->ScenarioselectLastTab = reader->GetInt32("scenarioselect_last_tab", 0); model->ListRideVehiclesSeparately = reader->GetBoolean("list_ride_vehicles_separately", false); + model->WindowButtonsOnTheLeft = reader->GetBoolean("window_buttons_on_the_left", WindowButtonsOnTheLeftDefault); } } @@ -352,6 +359,7 @@ namespace Config writer->WriteInt32("object_selection_filter_flags", model->ObjectSelectionFilterFlags); writer->WriteInt32("scenarioselect_last_tab", model->ScenarioselectLastTab); writer->WriteBoolean("list_ride_vehicles_separately", model->ListRideVehiclesSeparately); + writer->WriteBoolean("window_buttons_on_the_left", model->WindowButtonsOnTheLeft); } static void ReadSound(IIniReader* reader) diff --git a/src/openrct2/config/Config.h b/src/openrct2/config/Config.h index 5dd801bfba..c3555fd8ad 100644 --- a/src/openrct2/config/Config.h +++ b/src/openrct2/config/Config.h @@ -135,6 +135,7 @@ struct InterfaceConfiguration int32_t ObjectSelectionFilterFlags; int32_t ScenarioselectLastTab; bool ListRideVehiclesSeparately; + bool WindowButtonsOnTheLeft; }; struct SoundConfiguration diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index 06e447366b..238c6ad0a7 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -2262,8 +2262,16 @@ void WindowBase::ResizeFrame() // Title widgets[1].right = width - 2; // Close button - widgets[2].left = width - 13; - widgets[2].right = width - 3; + if (gConfigInterface.WindowButtonsOnTheLeft) + { + widgets[2].left = 2; + widgets[2].right = 2 + CloseButtonWidth; + } + else + { + widgets[2].left = width - 3 - CloseButtonWidth; + widgets[2].right = width - 3; + } } void WindowBase::ResizeFrameWithPage() diff --git a/src/openrct2/interface/Window.h b/src/openrct2/interface/Window.h index f274acbf35..06e366958a 100644 --- a/src/openrct2/interface/Window.h +++ b/src/openrct2/interface/Window.h @@ -38,6 +38,8 @@ enum class CursorID : uint8_t; enum class RideConstructionState : uint8_t; enum class CloseWindowModifier : uint8_t; +constexpr const uint8_t CloseButtonWidth = 10; + #define SCROLLABLE_ROW_HEIGHT 12 #define LIST_ROW_HEIGHT 12 #define TABLE_CELL_HEIGHT 12 diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 36054623c9..bf533667f9 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3994,6 +3994,9 @@ enum : uint16_t STR_ABOUT_OPENRCT2_TITLE = 6587, STR_ABOUT_FAIRGROUND_ORGAN = 6588, + STR_WINDOW_BUTTONS_ON_THE_LEFT = 6589, + STR_WINDOW_BUTTONS_ON_THE_LEFT_TIP = 6590, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working /* MAX_STR_COUNT = 32768 */ // MAX_STR_COUNT - upper limit for number of strings, not the current count strings };