From 4111ce2698fcc82fa0d820ad740840e04792a907 Mon Sep 17 00:00:00 2001 From: frosch Date: Tue, 6 May 2025 16:01:42 +0200 Subject: [PATCH] Add: WWT_IMGTEXTBTN, WWT_PUSHIMGTEXTBTN --- src/widget.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++++ src/widget_type.h | 16 ++++++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/widget.cpp b/src/widget.cpp index 7bb3842059..82236b453d 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -358,6 +358,37 @@ static inline void DrawImageButtons(const Rect &r, WidgetType type, Colours colo DrawSpriteIgnorePadding(img, PAL_NONE, r, align); } +/** + * Draw a button with image and rext. + * @param r Rectangle of the button. + * @param colour Colour of the button. + * @param clicked Button is clicked. + * @param img Image caption. + * @param text_colour Colour of the text. + * @param text Text caption. + * @param align Alignment of the caption. + * @param fs Font size of the text. + */ +static inline void DrawImageTextButtons(const Rect &r, Colours colour, bool clicked, SpriteID img, TextColour text_colour, const std::string &text, StringAlignment align, FontSize fs) +{ + DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FrameFlag::Lowered : FrameFlags{}); + + bool rtl = _current_text_dir == TD_RTL; + int image_width = img != 0 ? GetScaledSpriteSize(img).width : 0; + Rect r_img = r.Shrink(WidgetDimensions::scaled.framerect).WithWidth(image_width, rtl); + Rect r_text = r.Shrink(WidgetDimensions::scaled.framerect).Indent(image_width + WidgetDimensions::scaled.hsep_wide, rtl); + + if (img != 0) { + DrawSpriteIgnorePadding(img, PAL_NONE, r_img, SA_HOR_CENTER | (align & SA_VERT_MASK)); + } + + if (!text.empty()) { + Dimension d = GetStringBoundingBox(text, fs); + Point p = GetAlignedPosition(r_text, d, align); + DrawString(r_text.left, r_text.right, p.y, text, text_colour, align, false, fs); + } +} + /** * Draw the label-part of a widget. * @param r Rectangle of the label background. @@ -2720,6 +2751,8 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, WidgetID index, const Wi case WWT_TEXTBTN: case WWT_PUSHTXTBTN: case WWT_TEXTBTN_2: + case WWT_IMGTEXTBTN: + case WWT_PUSHIMGTEXTBTN: case WWT_BOOLBTN: case WWT_MATRIX: case NWID_BUTTON_DROPDOWN: @@ -2898,6 +2931,20 @@ void NWidgetLeaf::SetupSmallestSize(Window *w) size = maxdim(size, d2); break; } + + case WWT_IMGTEXTBTN: + case WWT_PUSHIMGTEXTBTN: { + padding = {WidgetDimensions::scaled.framerect.Horizontal(), WidgetDimensions::scaled.framerect.Vertical()}; + Dimension di = GetScaledSpriteSize(this->widget_data.sprite); + Dimension dt = GetStringBoundingBox(GetStringForWidget(w, this), this->text_size); + Dimension d2{ + padding.width + di.width + WidgetDimensions::scaled.hsep_wide + dt.width, + padding.height + std::max(di.height, dt.height) + }; + size = maxdim(size, d2); + break; + } + case WWT_ARROWBTN: case WWT_PUSHARROWBTN: { padding = {WidgetDimensions::scaled.imgbtn.Horizontal(), WidgetDimensions::scaled.imgbtn.Vertical()}; @@ -3021,6 +3068,11 @@ void NWidgetLeaf::Draw(const Window *w) DrawLabel(r, this->text_colour, GetStringForWidget(w, this, (type & WWT_MASK) == WWT_TEXTBTN_2 && clicked), this->align, this->text_size); break; + case WWT_IMGTEXTBTN: + case WWT_PUSHIMGTEXTBTN: + DrawImageTextButtons(r, this->colour, clicked, this->widget_data.sprite, this->text_colour, GetStringForWidget(w, this), this->align, this->text_size); + break; + case WWT_ARROWBTN: case WWT_PUSHARROWBTN: { SpriteID sprite; diff --git a/src/widget_type.h b/src/widget_type.h index 4d43c93107..f23b47b2fd 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -45,6 +45,7 @@ enum WidgetType : uint8_t { WWT_TEXTBTN, ///< (Toggle) Button with text WWT_TEXTBTN_2, ///< (Toggle) Button with diff text when clicked WWT_BOOLBTN, ///< Standard boolean toggle button. + WWT_IMGTEXTBTN, ///< (Toggle) Button with image and text WWT_LABEL, ///< Centered label WWT_TEXT, ///< Pure simple text WWT_MATRIX, ///< Grid of rows and columns. @see MatrixWidgetValues @@ -104,6 +105,7 @@ enum WidgetType : uint8_t { WWT_PUSHTXTBTN = WWT_TEXTBTN | WWB_PUSHBUTTON, ///< Normal push-button (no toggle button) with text caption WWT_PUSHIMGBTN = WWT_IMGBTN | WWB_PUSHBUTTON, ///< Normal push-button (no toggle button) with image caption WWT_PUSHARROWBTN = WWT_ARROWBTN | WWB_PUSHBUTTON, ///< Normal push-button (no toggle button) with arrow caption + WWT_PUSHIMGTEXTBTN = WWT_IMGTEXTBTN | WWB_PUSHBUTTON, ///< Normal push-button (no toggle button) with image and text caption NWID_PUSHBUTTON_DROPDOWN = NWID_BUTTON_DROPDOWN | WWB_PUSHBUTTON, }; @@ -1212,7 +1214,7 @@ constexpr NWidgetPart SetStringTip(StringID string, StringID tip = {}) /** * Widget part function for setting the sprite and tooltip. - * @param data Sprite of the widget. + * @param sprite Sprite of the widget. * @param tip Tooltip of the widget. * @ingroup NestedWidgetParts */ @@ -1221,6 +1223,18 @@ constexpr NWidgetPart SetSpriteTip(SpriteID sprite, StringID tip = {}) return NWidgetPart{WPT_DATATIP, NWidgetPartDataTip{{.sprite = sprite}, tip}}; } +/** + * Widget part function for setting the sprite, string and tooltip. + * @param sprite Sprite of the widget. + * @param string String of the widget. + * @param tip Tooltip of the widget. + * @ingroup NestedWidgetParts + */ +constexpr NWidgetPart SetSpriteStringTip(SpriteID sprite, StringID string, StringID tip = {}) +{ + return NWidgetPart{WPT_DATATIP, NWidgetPartDataTip{{.string = string, .sprite = sprite}, tip}}; +} + /** * Widget part function for setting the arrow widget type and tooltip. * @param widget_type Type of the widget to draw.