diff --git a/src/error_gui.cpp b/src/error_gui.cpp index 5e8f52432d..1914826b7e 100644 --- a/src/error_gui.cpp +++ b/src/error_gui.cpp @@ -185,6 +185,7 @@ public: CopyInDParam(0, this->decode_params, lengthof(this->decode_params)); if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_grffile, this->textref_stack_size, this->textref_stack); + size->width = GetMinSizing(NWST_WINDOW_LENGTH, size->width); int text_width = max(0, (int)size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT); this->height_summary = GetStringHeight(this->summary_msg, text_width); this->height_detailed = (this->detailed_msg == INVALID_STRING_ID) ? 0 : GetStringHeight(this->detailed_msg, text_width); diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 1746573c90..62838285a2 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -1101,6 +1101,7 @@ struct QueryWindow : public Window { { if (widget != WID_Q_TEXT) return; + size->width = GetMinSizing(NWST_WINDOW_LENGTH, size->width); Dimension d = GetStringMultiLineBoundingBox(this->message, *size); d.width += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT; d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; diff --git a/src/misc_gui.cpp.orig b/src/misc_gui.cpp.orig index 71af9c33ae..1746573c90 100644 --- a/src/misc_gui.cpp.orig +++ b/src/misc_gui.cpp.orig @@ -786,11 +786,12 @@ void QueryString::DrawEditBox(const Window *w, int wid) const /* If we have a marked area, draw a background highlight. */ if (tb->marklength != 0) GfxFillRect(delta + tb->markxoffs, 0, delta + tb->markxoffs + tb->marklength - 1, bottom - top, PC_GREY); - DrawString(delta, tb->pixels, 0, tb->buf, TC_YELLOW); + DrawString(delta, tb->pixels, Center(0, bottom - top), tb->buf, TC_YELLOW); + bool focussed = w->IsWidgetGloballyFocused(wid) || IsOSKOpenedFor(w, wid); if (focussed && tb->caret) { int caret_width = GetStringBoundingBox("_").width; - DrawString(tb->caretxoffs + delta, tb->caretxoffs + delta + caret_width, 0, "_", TC_WHITE); + DrawString(tb->caretxoffs + delta, tb->caretxoffs + delta + caret_width, Center(0, bottom - top), "_", TC_WHITE); } _cur_dpi = old_dpi; diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 97d4f795ea..ba4b557db3 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -315,6 +315,7 @@ struct NewsWindow : Window { StringID str = STR_NULL; switch (widget) { case WID_N_MESSAGE: + size->width = GetMinSizing(NWST_WINDOW_LENGTH, size->width); CopyInDParam(0, this->ni->params, lengthof(this->ni->params)); str = this->ni->string_id; break; diff --git a/src/widget.cpp b/src/widget.cpp index 1acdcf74d7..437d2fdf3f 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -2925,6 +2925,9 @@ uint GetMinSizing(NWidSizingType type, uint min_1) case NWST_KEYBOARD: min_sizing = 2 * _settings_client.gui.min_button; break; + case NWST_WINDOW_LENGTH: + min_sizing = 8 * _settings_client.gui.min_button; + break; default: NOT_REACHED(); } diff --git a/src/widget.cpp.orig b/src/widget.cpp.orig index 534909066a..1acdcf74d7 100644 --- a/src/widget.cpp.orig +++ b/src/widget.cpp.orig @@ -523,7 +523,7 @@ static inline void DrawButtonDropdown(const Rect &r, Colours colour, bool clicke { int text_offset = max(0, ((int)(r.bottom - r.top + 1) - FONT_HEIGHT_NORMAL) / 2); // Offset for rendering the text vertically centered - int dd_width = NWidgetLeaf::dropdown_dimension.width; + int dd_width = GetMinSizing(NWST_STEP, NWidgetLeaf::dropdown_dimension.width); if (_current_text_dir == TD_LTR) { DrawFrameRect(r.left, r.top, r.right - dd_width, r.bottom, colour, clicked_button ? FR_LOWERED : FR_NONE); @@ -746,6 +746,7 @@ NWidgetBase *NWidgetBase::GetWidgetOfType(WidgetType tp) */ NWidgetResizeBase::NWidgetResizeBase(WidgetType tp, uint fill_x, uint fill_y) : NWidgetBase(tp) { + this->sizing_type = NWST_NONE; this->fill_x = fill_x; this->fill_y = fill_y; } @@ -757,8 +758,23 @@ NWidgetResizeBase::NWidgetResizeBase(WidgetType tp, uint fill_x, uint fill_y) : */ void NWidgetResizeBase::SetMinimalSize(uint min_x, uint min_y) { - this->min_x = min_x; - this->min_y = min_y; + uint min_size = 0; + switch (this->sizing_type) { + case NWST_NONE: + case NWST_OVERRIDE: + min_size = 0; + break; + case NWST_BUTTON: + min_size = _settings_client.gui.min_button; + break; + case NWST_STEP: + min_size = _settings_client.gui.min_step; + break; + default: NOT_REACHED(); + } + + this->min_x = max(min_x, min_size); + this->min_y = max(min_y, min_size); } /** @@ -810,6 +826,7 @@ void NWidgetResizeBase::AssignSizePosition(SizingType sizing, uint x, uint y, ui */ NWidgetCore::NWidgetCore(WidgetType tp, Colours colour, uint fill_x, uint fill_y, uint32 widget_data, StringID tool_tip) : NWidgetResizeBase(tp, fill_x, fill_y) { + this->sizing_type = NWST_NONE; this->colour = colour; this->index = -1; this->widget_data = widget_data; @@ -1930,6 +1947,7 @@ void Scrollbar::SetCapacityFromWidget(Window *w, int widget, int padding) NWidgetScrollbar::NWidgetScrollbar(WidgetType tp, Colours colour, int index) : NWidgetCore(tp, colour, 1, 1, 0x0, STR_NULL), Scrollbar(tp != NWID_HSCROLLBAR) { assert(tp == NWID_HSCROLLBAR || tp == NWID_VSCROLLBAR); + this->sizing_type = NWST_STEP; this->SetIndex(index); switch (this->type) { @@ -2001,7 +2019,9 @@ void NWidgetScrollbar::Draw(const Window *w) if (vertical_dimension.width == 0) { vertical_dimension = maxdim(GetSpriteSize(SPR_ARROW_UP), GetSpriteSize(SPR_ARROW_DOWN)); vertical_dimension.width += extra.width; + vertical_dimension.width = GetMinSizing(NWST_STEP, vertical_dimension.width); vertical_dimension.height += extra.height; + vertical_dimension.height = GetMinSizing(NWST_STEP, vertical_dimension.height); } return vertical_dimension; } @@ -2012,7 +2032,9 @@ void NWidgetScrollbar::Draw(const Window *w) if (horizontal_dimension.width == 0) { horizontal_dimension = maxdim(GetSpriteSize(SPR_ARROW_LEFT), GetSpriteSize(SPR_ARROW_RIGHT)); horizontal_dimension.width += extra.width; + horizontal_dimension.width = GetMinSizing(NWST_STEP, horizontal_dimension.width); horizontal_dimension.height += extra.height; + horizontal_dimension.height = GetMinSizing(NWST_STEP, horizontal_dimension.height); } return horizontal_dimension; } @@ -2050,8 +2072,40 @@ Dimension NWidgetLeaf::dropdown_dimension = {0, 0}; */ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data, StringID tip) : NWidgetCore(tp, colour, 1, 1, data, tip) { + assert(this->sizing_type < NWST_END); assert(index >= 0 || tp == WWT_LABEL || tp == WWT_TEXT || tp == WWT_CAPTION || tp == WWT_RESIZEBOX || tp == WWT_SHADEBOX || tp == WWT_DEFSIZEBOX || tp == WWT_DEBUGBOX || tp == WWT_STICKYBOX || tp == WWT_CLOSEBOX); if (index >= 0) this->SetIndex(index); + + if (this->sizing_type == NWST_NONE) { + switch (tp) { + case WWT_PUSHBTN: + case WWT_IMGBTN: + case WWT_PUSHIMGBTN: + case WWT_IMGBTN_2: + case WWT_TEXTBTN: + case WWT_PUSHTXTBTN: + case WWT_TEXTBTN_2: + case WWT_PUSHARROWBTN: + case WWT_EDITBOX: + case WWT_CAPTION: + case WWT_STICKYBOX: + case WWT_SHADEBOX: + case WWT_DEBUGBOX: + case WWT_DEFSIZEBOX: + case WWT_RESIZEBOX: + case WWT_CLOSEBOX: + this->sizing_type = NWST_BUTTON; + break; + case NWID_PUSHBUTTON_DROPDOWN: + case NWID_BUTTON_DROPDOWN: + case WWT_DROPDOWN: + this->sizing_type = NWST_STEP; + break; + default: + this->sizing_type = NWST_OVERRIDE; + } + } + this->SetMinimalSize(0, 0); this->SetResize(0, 0); @@ -2463,11 +2517,12 @@ void NWidgetLeaf::Draw(const Window *w) */ bool NWidgetLeaf::ButtonHit(const Point &pt) { + uint button_size = GetMinSizing(NWST_STEP, 12); if (_current_text_dir == TD_LTR) { - int button_width = this->pos_x + this->current_x - 12; + int button_width = this->pos_x + this->current_x - button_size; return pt.x < button_width; } else { - int button_left = this->pos_x + 12; + int button_left = this->pos_x + button_size; return pt.x >= button_left; } } @@ -2560,6 +2615,16 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, break; } + case WPT_SIZINGTYPE: { + NWidgetResizeBase *nwrb = dynamic_cast(*dest); + if (nwrb != NULL) { + assert(parts->u.sizing_type < NWST_END); + nwrb->sizing_type = parts->u.sizing_type; + nwrb->SetMinimalSize(0, 0); + } + break; + } + case WPT_MINSIZE: { NWidgetResizeBase *nwrb = dynamic_cast(*dest); if (nwrb != NULL) { @@ -2816,6 +2881,7 @@ NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int wid } NWidgetBackground *panel = new NWidgetBackground(WWT_PANEL, COLOUR_GREY, widnum); + panel->sizing_type = NWST_STEP; panel->SetMinimalSize(sprite_size.width, sprite_size.height); panel->SetFill(1, 1); panel->SetResize(1, 0); @@ -2836,3 +2902,31 @@ NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int wid if (hor != NULL) vert->Add(hor); return vert; } + +/** + * Return the minimal automatic size for a widget. + * @param type The automatic sizing type to use. + * @param min_1 Minimal passed value. + * @return At least the passed value, or the minimal size for the associated sizing type. + */ +uint GetMinSizing(NWidSizingType type, uint min_1) +{ + uint min_sizing; + switch (type) { + case NWST_NONE: + case NWST_OVERRIDE: + return min_1; + case NWST_BUTTON: + min_sizing = _settings_client.gui.min_button; + break; + case NWST_STEP: + min_sizing = _settings_client.gui.min_step; + break; + case NWST_KEYBOARD: + min_sizing = 2 * _settings_client.gui.min_button; + break; + default: NOT_REACHED(); + } + + return max(min_sizing, min_1); +} diff --git a/src/widget_type.h b/src/widget_type.h index f2e015c957..6d95a2ce27 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -42,13 +42,14 @@ enum ArrowWidgetValues { /** Values for different minimal sizing of widgets. */ enum NWidSizingType { - NWST_NONE, ///< No sizing type is yet defined. - ///< Most buttons and scrollbars are initialized with this value. - ///< Later, they are automatically set to NWST_BUTTON or NWST_STEP. - NWST_BUTTON, ///< Size will be set at least _settings_client.gui.min_button. - NWST_STEP, ///< Size will be set at least _settings_client.gui.min_step (scrollbars and dropdowns). - NWST_KEYBOARD, ///< Size for keyboard keys. - NWST_OVERRIDE, ///< Avoid widgets to use automatic minimal sizing. + NWST_NONE, ///< No sizing type is yet defined. + ///< Most buttons and scrollbars are initialized with this value. + ///< Later, they are automatically set to NWST_BUTTON or NWST_STEP. + NWST_BUTTON, ///< Size will be set at least _settings_client.gui.min_button. + NWST_STEP, ///< Size will be set at least _settings_client.gui.min_step (scrollbars and dropdowns). + NWST_KEYBOARD, ///< Size for keyboard keys. + NWST_WINDOW_LENGTH, ///< Width for command errors, message windows and statusbar middle part. + NWST_OVERRIDE, ///< Avoid widgets to use automatic minimal sizing. NWST_END };