From 989577d40cbd7584620618a20dd862de4f9d9768 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Mon, 19 Nov 2018 18:59:25 +0000 Subject: [PATCH] Add support for adding a third error line to the error GUI Add support for a second error string ID to CommandCost --- src/command.cpp | 2 +- src/command_type.h | 24 +++++++++++++++++++++++- src/error.h | 5 +++-- src/error_gui.cpp | 33 +++++++++++++++++++++++++++++---- 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index 979b43aad1..23500fefe5 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -785,7 +785,7 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac /* Only show the error when it's for us. */ StringID error_part1 = GB(cmd, 16, 16); if (estimate_only || (IsLocalCompany() && error_part1 != 0 && my_cmd)) { - ShowErrorMessage(error_part1, res.GetErrorMessage(), WL_INFO, x, y, res.GetTextRefStackGRF(), res.GetTextRefStackSize(), res.GetTextRefStack()); + ShowErrorMessage(error_part1, res.GetErrorMessage(), WL_INFO, x, y, res.GetTextRefStackGRF(), res.GetTextRefStackSize(), res.GetTextRefStack(), res.GetExtraErrorMessage()); } } else if (estimate_only) { ShowEstimatedCostOrIncome(res.GetCost(), x, y); diff --git a/src/command_type.h b/src/command_type.h index badfa229cb..c130633963 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -30,6 +30,7 @@ class CommandCost { bool success; ///< Whether the comment went fine up to this moment const GRFFile *textref_stack_grffile; ///< NewGRF providing the #TextRefStack content. uint textref_stack_size; ///< Number of uint32 values to put on the #TextRefStack for the error message. + StringID extra_message = INVALID_STRING_ID; ///< Additional warning message for when success is unset static uint32 textref_stack[16]; @@ -44,6 +45,16 @@ public: */ explicit CommandCost(StringID msg) : expense_type(INVALID_EXPENSES), cost(0), message(msg), success(false), textref_stack_grffile(NULL), textref_stack_size(0) {} + /** + * Creates a command return value the is failed with the given message + */ + static CommandCost DualErrorMessage(StringID msg, StringID extra_msg) + { + CommandCost cc(msg); + cc.extra_message = extra_msg; + return cc; + } + /** * Creates a command cost with given expense type and start cost of 0 * @param ex_t the expense type @@ -100,11 +111,12 @@ public: * Makes this #CommandCost behave like an error command. * @param message The error message. */ - void MakeError(StringID message) + void MakeError(StringID message, StringID extra_message = INVALID_STRING_ID) { assert(message != INVALID_STRING_ID); this->success = false; this->message = message; + this->extra_message = extra_message; } void UseTextRefStack(const GRFFile *grffile, uint num_registers); @@ -146,6 +158,16 @@ public: return this->message; } + /** + * Returns the extra error message of a command + * @return the extra error message, if succeeded #INVALID_STRING_ID + */ + StringID GetExtraErrorMessage() const + { + if (this->success) return INVALID_STRING_ID; + return this->extra_message; + } + /** * Did this command succeed? * @return true if and only if it succeeded diff --git a/src/error.h b/src/error.h index 597b62efbe..191fdfd6a9 100644 --- a/src/error.h +++ b/src/error.h @@ -37,13 +37,14 @@ protected: uint32 textref_stack[16]; ///< Values to put on the #TextRefStack for the error message. StringID summary_msg; ///< General error message showed in first line. Must be valid. StringID detailed_msg; ///< Detailed error message showed in second line. Can be #INVALID_STRING_ID. + StringID extra_msg; ///< Extra error message shown in third line. Can be #INVALID_STRING_ID. Point position; ///< Position of the error message window. CompanyID face; ///< Company belonging to the face being shown. #INVALID_COMPANY if no face present. public: ErrorMessageData(const ErrorMessageData &data); ~ErrorMessageData(); - ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration = 0, int x = 0, int y = 0, const GRFFile *textref_stack_grffile = NULL, uint textref_stack_size = 0, const uint32 *textref_stack = NULL); + ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration = 0, int x = 0, int y = 0, const GRFFile *textref_stack_grffile = NULL, uint textref_stack_size = 0, const uint32 *textref_stack = NULL, StringID extra_msg = INVALID_STRING_ID); /** Check whether error window shall display a company manager face */ bool HasFace() const { return face != INVALID_COMPANY; } @@ -56,7 +57,7 @@ public: void ScheduleErrorMessage(const ErrorMessageData &data); -void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x = 0, int y = 0, const GRFFile *textref_stack_grffile = NULL, uint textref_stack_size = 0, const uint32 *textref_stack = NULL); +void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x = 0, int y = 0, const GRFFile *textref_stack_grffile = NULL, uint textref_stack_size = 0, const uint32 *textref_stack = NULL, StringID extra_msg = INVALID_STRING_ID); void ClearErrorMessages(); void ShowFirstError(); void UnshowCriticalError(); diff --git a/src/error_gui.cpp b/src/error_gui.cpp index 1c59b7e8d0..7a62f2af09 100644 --- a/src/error_gui.cpp +++ b/src/error_gui.cpp @@ -99,13 +99,15 @@ ErrorMessageData::~ErrorMessageData() * @param textref_stack_grffile NewGRF that provides the #TextRefStack for the error message. * @param textref_stack_size Number of uint32 values to put on the #TextRefStack for the error message; 0 if the #TextRefStack shall not be used. * @param textref_stack Values to put on the #TextRefStack. + * @param extra_msg Extra error message showed in third line. Can be INVALID_STRING_ID. */ -ErrorMessageData::ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration, int x, int y, const GRFFile *textref_stack_grffile, uint textref_stack_size, const uint32 *textref_stack) : +ErrorMessageData::ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration, int x, int y, const GRFFile *textref_stack_grffile, uint textref_stack_size, const uint32 *textref_stack, StringID extra_msg) : duration(duration), textref_stack_grffile(textref_stack_grffile), textref_stack_size(textref_stack_size), summary_msg(summary_msg), detailed_msg(detailed_msg), + extra_msg(extra_msg), face(INVALID_COMPANY) { this->position.x = x; @@ -173,6 +175,7 @@ struct ErrmsgWindow : public Window, ErrorMessageData { private: uint height_summary; ///< Height of the #summary_msg string in pixels in the #WID_EM_MESSAGE widget. uint height_detailed; ///< Height of the #detailed_msg string in pixels in the #WID_EM_MESSAGE widget. + uint height_extra; ///< Height of the #extra_msg string in pixels in the #WID_EM_MESSAGE widget. public: ErrmsgWindow(const ErrorMessageData &data) : Window(data.HasFace() ? &_errmsg_face_desc : &_errmsg_desc), ErrorMessageData(data) @@ -190,11 +193,13 @@ public: 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); + this->height_extra = (this->extra_msg == INVALID_STRING_ID) ? 0 : GetStringHeight(this->extra_msg, text_width); if (this->textref_stack_size > 0) StopTextRefStackUsage(); uint panel_height = WD_FRAMERECT_TOP + this->height_summary + WD_FRAMERECT_BOTTOM; if (this->detailed_msg != INVALID_STRING_ID) panel_height += this->height_detailed + WD_PAR_VSEP_WIDE; + if (this->extra_msg != INVALID_STRING_ID) panel_height += this->height_extra + WD_PAR_VSEP_WIDE; size->height = max(size->height, panel_height); break; @@ -271,7 +276,7 @@ public: if (this->detailed_msg == INVALID_STRING_ID) { DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, this->summary_msg, TC_FROMSTRING, SA_CENTER); - } else { + } else if (this->extra_msg == INVALID_STRING_ID) { int extra = (r.bottom - r.top + 1 - this->height_summary - this->height_detailed - WD_PAR_VSEP_WIDE) / 2; /* Note: NewGRF supplied error message often do not start with a colour code, so default to white. */ @@ -282,6 +287,21 @@ public: bottom = r.bottom - WD_FRAMERECT_BOTTOM; top = bottom - this->height_detailed - extra; DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, top, bottom, this->detailed_msg, TC_WHITE, SA_CENTER); + } else { + int extra = (r.bottom - r.top + 1 - this->height_summary - this->height_detailed - this->height_extra - (WD_PAR_VSEP_WIDE * 2)) / 3; + + /* Note: NewGRF supplied error message often do not start with a colour code, so default to white. */ + int top = r.top + WD_FRAMERECT_TOP; + int bottom = top + this->height_summary + extra; + DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, top, bottom, this->summary_msg, TC_WHITE, SA_CENTER); + + top = bottom + WD_PAR_VSEP_WIDE; + bottom = top + this->height_detailed + extra; + DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, top, bottom, this->detailed_msg, TC_WHITE, SA_CENTER); + + bottom = r.bottom - WD_FRAMERECT_BOTTOM; + top = bottom - this->height_extra - extra; + DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, top, bottom, this->extra_msg, TC_WHITE, SA_CENTER); } if (this->textref_stack_size > 0) StopTextRefStackUsage(); @@ -374,8 +394,9 @@ void UnshowCriticalError() * @param textref_stack_grffile NewGRF providing the #TextRefStack for the error message. * @param textref_stack_size Number of uint32 values to put on the #TextRefStack for the error message; 0 if the #TextRefStack shall not be used. * @param textref_stack Values to put on the #TextRefStack. + * @param extra_msg Extra error message showed in third line. Can be INVALID_STRING_ID. */ -void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x, int y, const GRFFile *textref_stack_grffile, uint textref_stack_size, const uint32 *textref_stack) +void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x, int y, const GRFFile *textref_stack_grffile, uint textref_stack_size, const uint32 *textref_stack, StringID extra_msg) { assert(textref_stack_size == 0 || (textref_stack_grffile != NULL && textref_stack != NULL)); if (summary_msg == STR_NULL) summary_msg = STR_EMPTY; @@ -391,6 +412,10 @@ void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel b += seprintf(b, lastof(buf), " "); GetString(b, detailed_msg, lastof(buf)); } + if (extra_msg != INVALID_STRING_ID) { + b += seprintf(b, lastof(buf), " "); + GetString(b, extra_msg, lastof(buf)); + } if (textref_stack_size > 0) StopTextRefStackUsage(); @@ -404,7 +429,7 @@ void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel if (_settings_client.gui.errmsg_duration == 0 && !no_timeout) return; - ErrorMessageData data(summary_msg, detailed_msg, no_timeout ? 0 : _settings_client.gui.errmsg_duration, x, y, textref_stack_grffile, textref_stack_size, textref_stack); + ErrorMessageData data(summary_msg, detailed_msg, no_timeout ? 0 : _settings_client.gui.errmsg_duration, x, y, textref_stack_grffile, textref_stack_size, textref_stack, extra_msg); data.CopyOutDParams(); ErrmsgWindow *w = (ErrmsgWindow*)FindWindowById(WC_ERRMSG, 0);