From 22f5aeab07cb1c67561b9e348e2c944740233607 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Fri, 8 Jan 2021 22:15:06 +0100 Subject: Feature: Automatic UI and font zoom levels when supported by the OS. --- src/gfx.cpp | 24 ++++++++++++++++++++++++ src/gfx_func.h | 1 + src/lang/english.txt | 2 ++ src/openttd.cpp | 1 + src/settings_gui.cpp | 18 +++++++++++------- src/table/misc_settings.ini | 16 ++++++++-------- src/video/video_driver.hpp | 21 ++++++++++++++++++++- src/zoom_type.h | 5 +++++ 8 files changed, 72 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/gfx.cpp b/src/gfx.cpp index 54851d375..786bbb25b 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -59,6 +59,10 @@ static ReusableBuffer _cursor_backup; ZoomLevel _gui_zoom; ///< GUI Zoom level ZoomLevel _font_zoom; ///< Font Zoom level +int8 _gui_zoom_cfg; ///< GUI zoom level in config. +int8 _font_zoom_cfg; ///< Font zoom level in config. + + /** * The rect for repaint. * @@ -1876,3 +1880,23 @@ void SortResolutions() { std::sort(_resolutions.begin(), _resolutions.end()); } + +/** + * Resolve GUI zoom level, if auto-suggestion is requested. + */ +void UpdateGUIZoom() +{ + /* Determine real GUI zoom to use. */ + if (_gui_zoom_cfg == ZOOM_LVL_CFG_AUTO) { + _gui_zoom = static_cast(Clamp(VideoDriver::GetInstance()->GetSuggestedUIZoom(), _settings_client.gui.zoom_min, _settings_client.gui.zoom_max)); + } else { + _gui_zoom = static_cast(_gui_zoom_cfg); + } + + /* Determine real font zoom to use. */ + if (_font_zoom_cfg == ZOOM_LVL_CFG_AUTO) { + _font_zoom = static_cast(VideoDriver::GetInstance()->GetSuggestedUIZoom()); + } else { + _font_zoom = static_cast(_font_zoom_cfg); + } +} diff --git a/src/gfx_func.h b/src/gfx_func.h index 7ac26f29b..8695fa0e2 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.h @@ -77,6 +77,7 @@ void UpdateWindows(); void DrawMouseCursor(); void ScreenSizeChanged(); void GameSizeChanged(); +void UpdateGUIZoom(); void UndrawMouseCursor(); /** Size of the buffer used for drawing strings. */ diff --git a/src/lang/english.txt b/src/lang/english.txt index 567d23820..88ef18702 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1004,6 +1004,7 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :other STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Interface size STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Select the interface element size to use +STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(auto-detect) STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Double size STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Quad size @@ -1011,6 +1012,7 @@ STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Quad size STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Font size STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Select the interface font size to use +STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(auto-detect) STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Double size STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Quad size diff --git a/src/openttd.cpp b/src/openttd.cpp index a631bd852..b68f378cf 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -771,6 +771,7 @@ int openttd_main(int argc, char *argv[]) /* Initialize the zoom level of the screen to normal */ _screen.zoom = ZOOM_LVL_NORMAL; + UpdateGUIZoom(); NetworkStartUp(); // initialize network-core diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index e04c50ac3..8bf118e76 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -58,6 +58,7 @@ static const StringID _autosave_dropdown[] = { }; static const StringID _gui_zoom_dropdown[] = { + STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO, STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL, STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM, STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM, @@ -65,6 +66,7 @@ static const StringID _gui_zoom_dropdown[] = { }; static const StringID _font_zoom_dropdown[] = { + STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO, STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL, STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM, STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM, @@ -291,16 +293,16 @@ struct GameOptionsWindow : Window { break; case WID_GO_GUI_ZOOM_DROPDOWN: { - *selected_index = ZOOM_LVL_OUT_4X - _gui_zoom; + *selected_index = _gui_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _gui_zoom + 1 : 0; const StringID *items = _gui_zoom_dropdown; for (int i = 0; *items != INVALID_STRING_ID; items++, i++) { - list.emplace_back(new DropDownListStringItem(*items, i, _settings_client.gui.zoom_min > ZOOM_LVL_OUT_4X - i)); + list.emplace_back(new DropDownListStringItem(*items, i, i != 0 && _settings_client.gui.zoom_min > ZOOM_LVL_OUT_4X - i + 1)); } break; } case WID_GO_FONT_ZOOM_DROPDOWN: { - *selected_index = ZOOM_LVL_OUT_4X - _font_zoom; + *selected_index = _font_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _font_zoom + 1 : 0; const StringID *items = _font_zoom_dropdown; for (int i = 0; *items != INVALID_STRING_ID; items++, i++) { list.emplace_back(new DropDownListStringItem(*items, i, false)); @@ -333,8 +335,8 @@ struct GameOptionsWindow : Window { case WID_GO_AUTOSAVE_DROPDOWN: SetDParam(0, _autosave_dropdown[_settings_client.gui.autosave]); break; case WID_GO_LANG_DROPDOWN: SetDParamStr(0, _current_language->own_name); break; case WID_GO_RESOLUTION_DROPDOWN: SetDParam(0, GetCurRes() == _resolutions.size() ? STR_GAME_OPTIONS_RESOLUTION_OTHER : SPECSTR_RESOLUTION_START + GetCurRes()); break; - case WID_GO_GUI_ZOOM_DROPDOWN: SetDParam(0, _gui_zoom_dropdown[ZOOM_LVL_OUT_4X - _gui_zoom]); break; - case WID_GO_FONT_ZOOM_DROPDOWN: SetDParam(0, _font_zoom_dropdown[ZOOM_LVL_OUT_4X - _font_zoom]); break; + case WID_GO_GUI_ZOOM_DROPDOWN: SetDParam(0, _gui_zoom_dropdown[_gui_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _gui_zoom_cfg + 1 : 0]); break; + case WID_GO_FONT_ZOOM_DROPDOWN: SetDParam(0, _font_zoom_dropdown[_font_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _font_zoom_cfg + 1 : 0]); break; case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->name.c_str()); break; case WID_GO_BASE_GRF_STATUS: SetDParam(0, BaseGraphics::GetUsedSet()->GetNumInvalid()); break; case WID_GO_BASE_SFX_DROPDOWN: SetDParamStr(0, BaseSounds::GetUsedSet()->name.c_str()); break; @@ -538,7 +540,8 @@ struct GameOptionsWindow : Window { case WID_GO_GUI_ZOOM_DROPDOWN: GfxClearSpriteCache(); - _gui_zoom = (ZoomLevel)(ZOOM_LVL_OUT_4X - index); + _gui_zoom_cfg = index > 0 ? ZOOM_LVL_OUT_4X - index + 1 : ZOOM_LVL_CFG_AUTO; + UpdateGUIZoom(); UpdateCursorSize(); UpdateAllVirtCoords(); FixTitleGameZoom(); @@ -547,7 +550,8 @@ struct GameOptionsWindow : Window { case WID_GO_FONT_ZOOM_DROPDOWN: GfxClearSpriteCache(); - _font_zoom = (ZoomLevel)(ZOOM_LVL_OUT_4X - index); + _font_zoom_cfg = index > 0 ? ZOOM_LVL_OUT_4X - index + 1 : ZOOM_LVL_CFG_AUTO; + UpdateGUIZoom(); ClearFontCache(); LoadStringWidthTable(); UpdateAllVirtCoords(); diff --git a/src/table/misc_settings.ini b/src/table/misc_settings.ini index be5088ec9..8cb6d4211 100644 --- a/src/table/misc_settings.ini +++ b/src/table/misc_settings.ini @@ -334,19 +334,19 @@ proc = ZoomMinMaxChanged [SDTG_VAR] name = ""gui_zoom"" -type = SLE_UINT8 -var = _gui_zoom -def = ZOOM_LVL_OUT_4X -min = ZOOM_LVL_MIN +type = SLE_INT8 +var = _gui_zoom_cfg +def = ZOOM_LVL_CFG_AUTO +min = ZOOM_LVL_CFG_AUTO max = ZOOM_LVL_OUT_4X cat = SC_BASIC [SDTG_VAR] name = ""font_zoom"" -type = SLE_UINT8 -var = _font_zoom -def = ZOOM_LVL_OUT_4X -min = ZOOM_LVL_MIN +type = SLE_INT8 +var = _font_zoom_cfg +def = ZOOM_LVL_CFG_AUTO +min = ZOOM_LVL_CFG_AUTO max = ZOOM_LVL_OUT_4X cat = SC_BASIC diff --git a/src/video/video_driver.hpp b/src/video/video_driver.hpp index d4e750134..bc445d92d 100644 --- a/src/video/video_driver.hpp +++ b/src/video/video_driver.hpp @@ -13,6 +13,7 @@ #include "../driver.h" #include "../core/geometry_type.hpp" #include "../core/math_func.hpp" +#include "../zoom_type.h" #include extern std::string _ini_videodriver; @@ -105,6 +106,18 @@ public: */ virtual void EditBoxGainedFocus() {} + /** + * Get a suggested default GUI zoom taking screen DPI into account. + */ + virtual ZoomLevel GetSuggestedUIZoom() + { + float dpi_scale = this->GetDPIScale(); + + if (dpi_scale >= 3.0f) return ZOOM_LVL_NORMAL; + if (dpi_scale >= 1.5f) return ZOOM_LVL_OUT_2X; + return ZOOM_LVL_OUT_4X; + } + /** * Get the currently active instance of the video driver. */ @@ -113,11 +126,17 @@ public: } protected: - /* + /** * Get the resolution of the main screen. */ virtual Dimension GetScreenSize() const { return { DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT }; } + /** + * Get DPI scaling factor of the screen OTTD is displayed on. + * @return 1.0 for default platform DPI, > 1.0 for higher DPI values, and < 1.0 for smaller DPI values. + */ + virtual float GetDPIScale() { return 1.0f; } + /** * Apply resolution auto-detection and clamp to sensible defaults. */ diff --git a/src/zoom_type.h b/src/zoom_type.h index 2606e0767..0945e1cc0 100644 --- a/src/zoom_type.h +++ b/src/zoom_type.h @@ -15,6 +15,8 @@ static uint const ZOOM_LVL_SHIFT = 2; static uint const ZOOM_LVL_BASE = 1 << ZOOM_LVL_SHIFT; +static const int8 ZOOM_LVL_CFG_AUTO = -1; + /** All zoom levels we know. */ enum ZoomLevel : byte { /* Our possible zoom-levels */ @@ -48,6 +50,9 @@ enum ZoomLevel : byte { }; DECLARE_POSTFIX_INCREMENT(ZoomLevel) +extern int8 _gui_zoom_cfg; +extern int8 _font_zoom_cfg; + extern ZoomLevel _gui_zoom; extern ZoomLevel _font_zoom; #define ZOOM_LVL_GUI (_gui_zoom) -- cgit v1.2.3-70-g09d2