From 123983743ff4a4f7da44c18b71fbd903eccd1b83 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 23 Oct 2022 15:45:47 +0100 Subject: [PATCH] Change: Add optional text labels to slider widget. --- src/gfx.cpp | 4 ++-- src/gfx_func.h | 2 +- src/music_gui.cpp | 4 ++-- src/settings_gui.cpp | 4 ++-- src/widgets/slider.cpp | 23 ++++++++++++++++++++--- src/widgets/slider_func.h | 3 ++- 6 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/gfx.cpp b/src/gfx.cpp index d96b2bdac4..67165fadc1 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -915,12 +915,12 @@ Dimension GetStringBoundingBox(const std::string &str, FontSize start_fontsize) * @param strid String to examine. * @return Width and height of the bounding box for the string in pixels. */ -Dimension GetStringBoundingBox(StringID strid) +Dimension GetStringBoundingBox(StringID strid, FontSize start_fontsize) { char buffer[DRAW_STRING_BUFFER]; GetString(buffer, strid, lastof(buffer)); - return GetStringBoundingBox(buffer); + return GetStringBoundingBox(buffer, start_fontsize); } /** diff --git a/src/gfx_func.h b/src/gfx_func.h index f6018c8a59..4ed6a81461 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.h @@ -147,7 +147,7 @@ static inline void GfxFillRect(const Rect &r, int colour, FillRectMode mode = FI Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize = FS_NORMAL); Dimension GetStringBoundingBox(const std::string &str, FontSize start_fontsize = FS_NORMAL); -Dimension GetStringBoundingBox(StringID strid); +Dimension GetStringBoundingBox(StringID strid, FontSize start_fontsize = FS_NORMAL); int GetStringHeight(const char *str, int maxw, FontSize fontsize = FS_NORMAL); int GetStringHeight(StringID str, int maxw); int GetStringLineCount(StringID str, int maxw); diff --git a/src/music_gui.cpp b/src/music_gui.cpp index 71068aeac8..8d4b9a019a 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -741,11 +741,11 @@ struct MusicWindow : public Window { } case WID_M_MUSIC_VOL: - DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.music_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.music_vol, {}); break; case WID_M_EFFECT_VOL: - DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.effect_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.effect_vol, {}); break; } } diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 8b9d8b3514..8e401edc22 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -347,11 +347,11 @@ struct GameOptionsWindow : Window { break; case WID_GO_BASE_SFX_VOLUME: - DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.effect_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.effect_vol, {}); break; case WID_GO_BASE_MUSIC_VOLUME: - DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.music_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.music_vol, {}); break; } } diff --git a/src/widgets/slider.cpp b/src/widgets/slider.cpp index b30aba848a..023101e73b 100644 --- a/src/widgets/slider.cpp +++ b/src/widgets/slider.cpp @@ -24,13 +24,18 @@ static const int SLIDER_WIDTH = 3; * @param min_value Minimum value of slider * @param max_value Maximum value of slider * @param value Value to put the slider at + * @param labels List of positions and labels to draw along the slider. */ -void DrawSliderWidget(Rect r, int min_value, int max_value, int value) +void DrawSliderWidget(Rect r, int min_value, int max_value, int value, const std::map &labels) { + /* Allow space for labels. We assume they are in the small font. */ + if (labels.size() > 0) r.bottom -= FONT_HEIGHT_SMALL + WidgetDimensions::scaled.hsep_normal; + max_value -= min_value; /* Draw a wedge indicating low to high value. */ const int ha = (r.bottom - r.top) / 5; + const int sw = ScaleGUITrad(SLIDER_WIDTH); const int t = WidgetDimensions::scaled.bevel.top; /* Thickness of lines */ int wx1 = r.left + sw / 2; int wx2 = r.right - sw / 2; @@ -44,10 +49,22 @@ void DrawSliderWidget(Rect r, int min_value, int max_value, int value) GfxDrawLine(wedge[1].x, wedge[1].y, wedge[2].x, wedge[2].y, _current_text_dir == TD_RTL ? shadow : light, t); GfxDrawLine(wedge[0].x, wedge[0].y, wedge[1].x, wedge[1].y, shadow, t); + int x; + for (auto label : labels) { + x = label.first - min_value; + if (_current_text_dir == TD_RTL) x = max_value - x; + x = r.left + (x * (r.right - r.left - sw) / max_value) + sw / 2; + GfxDrawLine(x, r.bottom - ha + 1, x, r.bottom + (label.second == STR_NULL ? 0 : WidgetDimensions::scaled.hsep_normal), shadow, t); + if (label.second != STR_NULL) { + Dimension d = GetStringBoundingBox(label.second, FS_SMALL); + x = Clamp(x - d.width / 2, r.left, r.right - d.width); + DrawString(x, x + d.width, r.bottom + 1 + WidgetDimensions::scaled.hsep_normal, label.second, TC_BLACK, SA_CENTER, false, FS_SMALL); + } + } + /* Draw a slider handle indicating current value. */ - const int sw = ScaleGUITrad(SLIDER_WIDTH); if (_current_text_dir == TD_RTL) value = max_value - value; - const int x = r.left + ((value - min_value) * (r.right - r.left - sw) / max_value); + x = r.left + ((value - min_value) * (r.right - r.left - sw) / max_value); DrawFrameRect(x, r.top, x + sw, r.bottom, COLOUR_GREY, FR_NONE); } diff --git a/src/widgets/slider_func.h b/src/widgets/slider_func.h index 35b7737f3d..7de929512c 100644 --- a/src/widgets/slider_func.h +++ b/src/widgets/slider_func.h @@ -13,8 +13,9 @@ #include "../window_type.h" #include "../gfx_func.h" +#include -void DrawSliderWidget(Rect r, int min_value, int max_value, int value); +void DrawSliderWidget(Rect r, int min_value, int max_value, int value, const std::map &labels); bool ClickSliderWidget(Rect r, Point pt, int min_value, int max_value, int &value); inline bool ClickSliderWidget(Rect r, Point pt, int min_value, int max_value, byte &value)