From 06a52be95c3295db2efb3b68afa657d28e05e44e Mon Sep 17 00:00:00 2001 From: smatz Date: Tue, 22 Jul 2008 19:25:47 +0000 Subject: (svn r13787) -Codechange: resize the red error message box if needed --- src/gfx.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/gfx_func.h | 1 + src/misc_gui.cpp | 42 ++++++++++++++++++++++++++++++------------ 3 files changed, 77 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/gfx.cpp b/src/gfx.cpp index e57327446..3b9b042eb 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -452,6 +452,52 @@ end_of_inner_loop: } } + +/** Calculates height of string (in pixels). Accepts multiline string with '\0' as separators. + * @param src string to check + * @param num number of extra lines (output of FormatStringLinebreaks()) + * @note assumes text won't be truncated. FormatStringLinebreaks() is a good way to ensure that. + * @return height of pixels of string when it is drawn + */ +static int GetMultilineStringHeight(const char *src, int num) +{ + int maxy = 0; + int y = 0; + int fh = GetCharacterHeight(_cur_fontsize); + + for (;;) { + WChar c = Utf8Consume(&src); + + switch (c) { + case 0: y += fh; if (--num < 0) return maxy; break; + case '\n': y += fh; break; + case SCC_SETX: src++; break; + case SCC_SETXY: src++; y = (int)*src++; break; + case SCC_TINYFONT: fh = GetCharacterHeight(FS_SMALL); break; + case SCC_BIGFONT: fh = GetCharacterHeight(FS_LARGE); break; + default: maxy = max(maxy, y + fh); break; + } + } +} + + +/** Calculates height of string (in pixels). The string is changed to a multiline string if needed. + * @param str string to check + * @param maxw maximum string width + * @return height of pixels of string when it is drawn + */ +int GetStringHeight(StringID str, int maxw) +{ + char buffer[512]; + + GetString(buffer, str, lastof(buffer)); + + uint32 tmp = FormatStringLinebreaks(buffer, maxw); + + return GetMultilineStringHeight(buffer, GB(tmp, 0, 16)); +} + + /** Draw a given string with the centre around the given (x,y) coordinates * @param x Centre the string around this pixel width * @param y Centre the string around this pixel height diff --git a/src/gfx_func.h b/src/gfx_func.h index 371645c5f..51986a71f 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.h @@ -105,6 +105,7 @@ void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3) Dimension GetStringBoundingBox(const char *str); uint32 FormatStringLinebreaks(char *str, int maxw); +int GetStringHeight(StringID str, int maxw); void LoadStringWidthTable(); void DrawStringMultiCenter(int x, int y, StringID str, int maxw); uint DrawStringMultiLine(int x, int y, StringID str, int maxw, int maxh = -1); diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index f9d45e265..732efebd8 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -378,14 +378,14 @@ void ShowAboutWindow() static const Widget _errmsg_widgets[] = { { WWT_CLOSEBOX, RESIZE_NONE, 4, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, { WWT_CAPTION, RESIZE_NONE, 4, 11, 239, 0, 13, STR_00B2_MESSAGE, STR_NULL}, -{ WWT_PANEL, RESIZE_NONE, 4, 0, 239, 14, 45, 0x0, STR_NULL}, +{ WWT_PANEL, RESIZE_BOTTOM, 4, 0, 239, 14, 45, 0x0, STR_NULL}, { WIDGETS_END}, }; static const Widget _errmsg_face_widgets[] = { { WWT_CLOSEBOX, RESIZE_NONE, 4, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, { WWT_CAPTION, RESIZE_NONE, 4, 11, 333, 0, 13, STR_00B3_MESSAGE_FROM, STR_NULL}, -{ WWT_PANEL, RESIZE_NONE, 4, 0, 333, 14, 136, 0x0, STR_NULL}, +{ WWT_PANEL, RESIZE_BOTTOM, 4, 0, 333, 14, 136, 0x0, STR_NULL}, { WIDGETS_END}, }; @@ -397,6 +397,8 @@ private: StringID message_2; bool show_player_face; + int y[2]; + public: ErrmsgWindow(Point pt, int width, int height, StringID msg1, StringID msg2, const Widget *widget, bool show_player_face) : Window(pt.x, pt.y, width, height, WC_ERRMSG, widget), @@ -407,16 +409,35 @@ public: this->message_1 = msg1; this->message_2 = msg2; this->desc_flags = WDF_STD_BTN | WDF_DEF_WIDGET; + + SwitchToErrorRefStack(); + RewindTextRefStack(); + + assert(msg2 != INVALID_STRING_ID); + + int h2 = 3 + GetStringHeight(msg2, width - 2); // msg2 is printed first + int h1 = (msg1 == INVALID_STRING_ID) ? 0 : 3 + GetStringHeight(msg1, width - 2); + + SwitchToNormalRefStack(); + + int h = 15 + h1 + h2; + height = max(height, h); + + if (msg1 == INVALID_STRING_ID) { + // only 1 line will be printed + y[1] = (height - 15) / 2 + 15 - 5; + } else { + int over = (height - h) / 4; + + y[1] = 15 + h2 / 2 + 1 - 5 + over; + y[0] = height - 3 - h1 / 2 - 5 - over; + } + this->FindWindowPlacementAndResize(width, height); } virtual void OnPaint() { - static int y[][3] = { - {15, 25, 30}, // _errmsg_widgets - {45, 65, 90}, // _errmsg_face_widgets - }; - CopyInDParam(0, this->decode_params, lengthof(this->decode_params)); this->DrawWidgets(); CopyInDParam(0, this->decode_params, lengthof(this->decode_params)); @@ -432,11 +453,8 @@ public: DrawPlayerFace(p->face, p->player_color, 2, 16); } - byte j = (this->message_1 == INVALID_STRING_ID) ? 1 : 0; - DrawStringMultiCenter(this->width - 120, y[this->show_player_face][j], this->message_2, this->width - 2); - if (j == 0) { - DrawStringMultiCenter(this->width - 120, y[this->show_player_face][2], this->message_1, this->width - 2); - } + DrawStringMultiCenter(this->width - 120, y[1], this->message_2, this->width - 2); + if (this->message_1 != INVALID_STRING_ID) DrawStringMultiCenter(this->width - 120, y[0], this->message_1, this->width - 2); /* Switch back to the normal text ref. stack for NewGRF texts */ SwitchToNormalRefStack(); -- cgit v1.2.3-54-g00ecf