Sun, 15 Jun 2025 21:02:29 +0200
add auto-scaling of UI depending on screen resolution - resolves #682
src/ascension/context.h | file | annotate | diff | comparison | revisions | |
src/ascension/ui.h | file | annotate | diff | comparison | revisions | |
src/ascension/window.h | file | annotate | diff | comparison | revisions | |
src/context.c | file | annotate | diff | comparison | revisions | |
src/font.c | file | annotate | diff | comparison | revisions | |
src/window.c | file | annotate | diff | comparison | revisions | |
test/snake/snake.c | file | annotate | diff | comparison | revisions |
--- a/src/ascension/context.h Sun Jun 15 19:50:51 2025 +0200 +++ b/src/ascension/context.h Sun Jun 15 21:02:29 2025 +0200 @@ -61,7 +61,6 @@ AscFont active_font; unsigned char active_window; asc_col4i ink; - float ui_scale; uint64_t frame_nanos; uint64_t total_nanos; } AscContext;
--- a/src/ascension/ui.h Sun Jun 15 19:50:51 2025 +0200 +++ b/src/ascension/ui.h Sun Jun 15 21:02:29 2025 +0200 @@ -30,12 +30,5 @@ #include "ui/text.h" -/** - * Sets the UI scaling factor. - * // TODO: think about whether this should be a context function which also triggers an update on all UI scenes - * @param factor the scaling factor - */ -#define asc_ui_scale(factor) asc_context.ui_scale = (factor) - #endif /* ASCENSION_UI_H */
--- a/src/ascension/window.h Sun Jun 15 19:50:51 2025 +0200 +++ b/src/ascension/window.h Sun Jun 15 21:02:29 2025 +0200 @@ -58,6 +58,7 @@ SDL_Window *window; asc_vec2u dimensions; AscGLContext glctx; + float ui_scale; AscScene ui; AscScene scenes[ASC_MAX_SCENES]; } AscWindow; @@ -140,6 +141,37 @@ */ AscScene *asc_window_scene(unsigned int index); +/** + * The desktop display resolution related to the active window. + * + * @return the desktop display resolution of the display the active window is associated with + */ +asc_vec2u asc_window_display_resolution(void); + +// TODO: there is a ui.h - better move stuff there? + +/** + * Sets the UI scaling factor for the active window. + * + * @param scale the scaling factor + */ +void asc_ui_scale(float scale); + +/** + * Returns the current UI scaling factor for the active window. + * + * @return the scaling factor + */ +float asc_ui_get_scale(void); + +/** + * Automatically chooses a UI scaling factor depending on display resolution. + * + * @note you need to call this function again when the window changes the display + * // TODO: check if there is an SDL event when the window changes the display and implement a reaction + */ +void asc_ui_scale_auto(void); + void asc_add_ui_node(AscSceneNode *node); #endif /* ASCENSION_WINDOW_H */
--- a/src/context.c Sun Jun 15 19:50:51 2025 +0200 +++ b/src/context.c Sun Jun 15 21:02:29 2025 +0200 @@ -65,9 +65,6 @@ asc_context.active_font.style = ASC_FONT_REGULAR; asc_context.active_font.size = 14; - // default UI scale - asc_context.ui_scale = 1.0f; - // no window, yet asc_context.active_window = ASC_MAX_WINDOWS;
--- a/src/font.c Sun Jun 15 19:50:51 2025 +0200 +++ b/src/font.c Sun Jun 15 21:02:29 2025 +0200 @@ -82,8 +82,9 @@ TTF_Font *asc_font_load(AscFont font) { // apply the UI scaling factor first to get the actual font size - if (asc_context.ui_scale != 1.f) { - font.size = (int) roundf((float) font.size * asc_context.ui_scale); + const float ui_scale = asc_active_window->ui_scale; + if (ui_scale != 1.f) { + font.size = (int) roundf((float) font.size * ui_scale); } CxIterator iter = cxListIterator(asc_font_cache);
--- a/src/window.c Sun Jun 15 19:50:51 2025 +0200 +++ b/src/window.c Sun Jun 15 21:02:29 2025 +0200 @@ -77,6 +77,9 @@ } window->resized = true; // count initial sizing as resize + // default UI scale + window->ui_scale = 1.0f; + if (asc_gl_context_initialize(&window->glctx, window->window, &settings->glsettings)) { asc_scene_init(&window->ui, .type = ASC_CAMERA_ORTHO, @@ -198,3 +201,34 @@ AscScene *asc_window_scene(unsigned int index) { return &asc_active_window->scenes[index]; } + +asc_vec2u asc_window_display_resolution(void) { + const AscWindow *window = asc_active_window; + SDL_DisplayMode dm; + const int display = SDL_GetWindowDisplayIndex(window->window); + if (SDL_GetDesktopDisplayMode(display, &dm)) { + asc_error("Failed to get display mode for window %u on display %d: %s", + window->id, display, SDL_GetError()); + } + return asc_vec2u_new(dm.w, dm.h); +} + +void asc_ui_scale(float scale) { + asc_active_window->ui_scale = scale; +} + +float asc_ui_get_scale(void) { + return asc_active_window->ui_scale; +} + +void asc_ui_scale_auto(void) { + asc_vec2u res = asc_window_display_resolution(); + // TODO: debug why this is wrong under GNOME or just throw GNOME away + if (res.width > 3000) { + asc_ui_scale(1.5f); + } else if (res.width > 2000) { + asc_ui_scale(1.2f); + } else { + return asc_ui_scale(1.f); + } +}