(svn r17931) -Codechange: Error message window uses pure nested widgets.

replace/41b28d7194a279bdc17475d4fbe2ea6ec885a466
alberth 15 years ago
parent 3a95e115fc
commit 898f20ce56

@ -496,61 +496,43 @@ enum ErrorMessageWidgets {
EMW_MESSAGE, EMW_MESSAGE,
}; };
static const Widget _errmsg_widgets[] = {
{ WWT_CLOSEBOX, RESIZE_NONE, COLOUR_RED, 0, 10, 0, 13, STR_BLACK_CROSS, STR_TOOLTIP_CLOSE_WINDOW},
{ WWT_CAPTION, RESIZE_NONE, COLOUR_RED, 11, 239, 0, 13, STR_ERROR_MESSAGE_CAPTION, STR_NULL},
{ WWT_PANEL, RESIZE_BOTTOM, COLOUR_RED, 0, 239, 14, 45, 0x0, STR_NULL},
{ WWT_EMPTY, RESIZE_NONE, COLOUR_RED, 0, 0, 0, 0, 0x0, STR_NULL},
{ WWT_EMPTY, RESIZE_NONE, COLOUR_RED, 2, 237, 14, 45, 0x0, STR_NULL},
{ WIDGETS_END},
};
static const NWidgetPart _nested_errmsg_widgets[] = { static const NWidgetPart _nested_errmsg_widgets[] = {
NWidget(NWID_LAYERED), NWidget(NWID_HORIZONTAL),
NWidget(NWID_VERTICAL), NWidget(WWT_CLOSEBOX, COLOUR_RED, EMW_CLOSE),
NWidget(NWID_HORIZONTAL), NWidget(WWT_CAPTION, COLOUR_RED, EMW_CAPTION), SetDataTip(STR_ERROR_MESSAGE_CAPTION, STR_NULL),
NWidget(WWT_CLOSEBOX, COLOUR_RED, EMW_CLOSE), EndContainer(),
NWidget(WWT_CAPTION, COLOUR_RED, EMW_CAPTION), SetDataTip(STR_ERROR_MESSAGE_CAPTION, STR_NULL), NWidget(WWT_PANEL, COLOUR_RED, EMW_PANEL),
EndContainer(), NWidget(WWT_EMPTY, COLOUR_RED, EMW_MESSAGE), SetPadding(0, 2, 0, 2), SetMinimalSize(236, 32),
NWidget(WWT_PANEL, COLOUR_RED, EMW_PANEL),
NWidget(WWT_EMPTY, COLOUR_RED, EMW_MESSAGE), SetPadding(0, 2, 0, 2), SetMinimalSize(236, 32),
NWidget(NWID_SPACER), SetResize(0, 1),
EndContainer(),
EndContainer(),
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, COLOUR_RED, EMW_FACE), SetMinimalSize(1, 1), SetFill(false, false),
NWidget(NWID_SPACER), SetFill(true, false),
EndContainer(),
NWidget(NWID_SPACER), SetFill(true, true), SetResize(0, 1),
EndContainer(),
EndContainer(), EndContainer(),
}; };
static const Widget _errmsg_face_widgets[] = { static const WindowDesc _errmsg_desc(
{ WWT_CLOSEBOX, RESIZE_NONE, COLOUR_RED, 0, 10, 0, 13, STR_BLACK_CROSS, STR_TOOLTIP_CLOSE_WINDOW}, 0, 0, 240, 46, 240, 46, // x/y position is not used.
{ WWT_CAPTION, RESIZE_NONE, COLOUR_RED, 11, 333, 0, 13, STR_ERROR_MESSAGE_CAPTION_OTHER_COMPANY, STR_NULL}, WC_ERRMSG, WC_NONE,
{ WWT_PANEL, RESIZE_BOTTOM, COLOUR_RED, 0, 333, 14, 136, 0x0, STR_NULL}, WDF_STD_BTN | WDF_DEF_WIDGET,
{ WWT_EMPTY, RESIZE_NONE, COLOUR_RED, 2, 92, 16, 135, 0x0, STR_NULL}, NULL, _nested_errmsg_widgets, lengthof(_nested_errmsg_widgets)
{ WWT_EMPTY, RESIZE_NONE, COLOUR_RED, 94, 331, 14, 136, 0x0, STR_NULL}, );
{ WIDGETS_END},
};
static const NWidgetPart _nested_errmsg_face_widgets[] = { static const NWidgetPart _nested_errmsg_face_widgets[] = {
NWidget(NWID_HORIZONTAL), NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_RED, EMW_CLOSE), NWidget(WWT_CLOSEBOX, COLOUR_RED, EMW_CLOSE),
NWidget(WWT_CAPTION, COLOUR_RED, EMW_CAPTION), SetDataTip(STR_ERROR_MESSAGE_CAPTION_OTHER_COMPANY, STR_NULL), NWidget(WWT_CAPTION, COLOUR_RED, EMW_CAPTION), SetDataTip(STR_ERROR_MESSAGE_CAPTION_OTHER_COMPANY, STR_NULL),
EndContainer(), EndContainer(),
NWidget(WWT_PANEL, COLOUR_RED, EMW_PANEL), NWidget(WWT_PANEL, COLOUR_RED, EMW_PANEL),
NWidget(NWID_HORIZONTAL), SetPIP(2, 1, 2), NWidget(NWID_HORIZONTAL), SetPIP(2, 1, 2),
NWidget(WWT_EMPTY, COLOUR_RED, EMW_FACE), SetMinimalSize(91, 120), SetPadding(2, 0, 1, 0), NWidget(WWT_EMPTY, COLOUR_RED, EMW_FACE), SetMinimalSize(91, 120), SetFill(false, true), SetPadding(2, 0, 1, 0),
NWidget(WWT_EMPTY, COLOUR_RED, EMW_MESSAGE), SetMinimalSize(238, 123), NWidget(WWT_EMPTY, COLOUR_RED, EMW_MESSAGE), SetFill(false, true), SetMinimalSize(238, 123),
EndContainer(),
NWidget(NWID_SPACER), SetResize(0, 1),
EndContainer(), EndContainer(),
EndContainer(), EndContainer(),
}; };
static const WindowDesc _errmsg_face_desc(
0, 0, 334, 137, 334, 137, // x/y position is not used.
WC_ERRMSG, WC_NONE,
WDF_STD_BTN | WDF_DEF_WIDGET,
NULL, _nested_errmsg_face_widgets, lengthof(_nested_errmsg_face_widgets)
);
/** Window class for displaying an error message window. */ /** Window class for displaying an error message window. */
struct ErrmsgWindow : public Window { struct ErrmsgWindow : public Window {
private: private:
@ -558,77 +540,97 @@ private:
uint64 decode_params[20]; ///< Parameters of the message strings. uint64 decode_params[20]; ///< Parameters of the message strings.
StringID summary_msg; ///< General error message showed in first line. Must be valid. 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 detailed_msg; ///< Detailed error message showed in second line. Can be #INVALID_STRING_ID.
bool show_company_manager_face; ///< Display the face of the manager in the window. uint height_summary; ///< Height of the #summary_msg string in pixels in the #EMW_MESSAGE widget.
uint height_detailed; ///< Height of the #detailed_msg string in pixels in the #EMW_MESSAGE widget.
Rect area_summary; ///< Area available for #summary_msg in the #EMW_MESSAGE widget. Point position; ///< Position of the error message window.
Rect area_detailed; ///< Area available for #detailed_msg in the #EMW_MESSAGE widget.
public: public:
ErrmsgWindow(Point pt, int width, int height, StringID summary_msg, StringID detailed_msg, const Widget *widget, bool show_company_manager_face, bool no_timeout) : ErrmsgWindow(Point pt, const WindowDesc *desc, StringID summary_msg, StringID detailed_msg, bool no_timeout) : Window()
Window(pt.x, pt.y, width, height, WC_ERRMSG, widget),
show_company_manager_face(show_company_manager_face)
{ {
this->position = pt;
this->duration = no_timeout ? 0 : _settings_client.gui.errmsg_duration; this->duration = no_timeout ? 0 : _settings_client.gui.errmsg_duration;
CopyOutDParam(this->decode_params, 0, lengthof(this->decode_params)); CopyOutDParam(this->decode_params, 0, lengthof(this->decode_params));
this->summary_msg = summary_msg; this->summary_msg = summary_msg;
this->detailed_msg = detailed_msg; this->detailed_msg = detailed_msg;
this->desc_flags = WDF_STD_BTN | WDF_DEF_WIDGET;
SwitchToErrorRefStack();
RewindTextRefStack();
assert(summary_msg != INVALID_STRING_ID); assert(summary_msg != INVALID_STRING_ID);
this->area_detailed.left = this->area_summary.left = this->widget[EMW_MESSAGE].left + WD_FRAMETEXT_LEFT; this->InitNested(desc);
this->area_detailed.right = this->area_summary.right = this->widget[EMW_MESSAGE].right - WD_FRAMETEXT_RIGHT; }
int text_width = this->area_detailed.right - this->area_detailed.left + 1;
int height_summary = GetStringHeight(summary_msg, text_width); // summary_msg is printed first virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *resize)
int height_detailed = (detailed_msg == INVALID_STRING_ID) ? 0 : GetStringHeight(detailed_msg, text_width); {
if (widget != EMW_MESSAGE) return;
SwitchToNormalRefStack(); CopyInDParam(0, this->decode_params, lengthof(this->decode_params));
/* If the error message comes from a NewGRF, we must use the text ref. stack reserved for error messages.
* If the message doesn't come from a NewGRF, it won't use the TTDP-style text ref. stack, so we won't hurt anything
*/
SwitchToErrorRefStack();
RewindTextRefStack();
int h = this->widget[EMW_MESSAGE].top + 2 + height_detailed + height_summary; int text_width = max(0, (int)size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT);
height = max<int>(height, h + 4); this->height_summary = GetStringHeight(summary_msg, text_width);
this->height_detailed = (detailed_msg == INVALID_STRING_ID) ? 0 : GetStringHeight(detailed_msg, text_width);
if (detailed_msg == INVALID_STRING_ID) { SwitchToNormalRefStack(); // Switch back to the normal text ref. stack for NewGRF texts.
this->area_summary.top = this->widget[EMW_MESSAGE].top + WD_FRAMERECT_TOP;
this->area_summary.bottom = height - WD_FRAMERECT_BOTTOM;
} else {
int over = (height - h) / 2;
this->area_summary.top = this->widget[EMW_MESSAGE].top + WD_FRAMERECT_TOP;
this->area_summary.bottom = this->area_summary.top + height_summary + over;
this->area_detailed.bottom = height - WD_FRAMERECT_BOTTOM;
this->area_detailed.top = this->area_detailed.bottom - height_detailed - over;
}
this->FindWindowPlacementAndResize(width, height); uint panel_height = WD_FRAMERECT_TOP + this->height_summary + WD_FRAMERECT_BOTTOM;
if (detailed_msg != INVALID_STRING_ID) panel_height += this->height_detailed + WD_PAR_VSEP_WIDE;
size->height = max(size->height, panel_height);
}
virtual Point OnInitialPosition(const WindowDesc *desc, int16 sm_width, int16 sm_height, int window_number)
{
return this->position;
} }
virtual void OnPaint() virtual void OnPaint()
{ {
CopyInDParam(0, this->decode_params, lengthof(this->decode_params));
this->DrawWidgets(); this->DrawWidgets();
CopyInDParam(0, this->decode_params, lengthof(this->decode_params)); }
/* If the error message comes from a NewGRF, we must use the text ref. stack reserved for error messages. virtual void SetStringParameters(int widget) const
* If the message doesn't come from a NewGRF, it won't use the TTDP-style text ref. stack, so we won't hurt anything {
*/ if (widget == EMW_CAPTION) CopyInDParam(0, this->decode_params, lengthof(this->decode_params));
SwitchToErrorRefStack(); }
RewindTextRefStack();
if (this->show_company_manager_face) { virtual void DrawWidget(const Rect &r, int widget) const
const Company *c = Company::Get((CompanyID)GetDParamX(this->decode_params, 2)); {
DrawCompanyManagerFace(c->face, c->colour, this->widget[EMW_FACE].left, this->widget[EMW_FACE].top); switch (widget) {
} case EMW_FACE: {
const Company *c = Company::Get((CompanyID)GetDParamX(this->decode_params, 2));
DrawCompanyManagerFace(c->face, c->colour, r.left, r.top);
break;
}
DrawStringMultiLine(this->area_summary.left, this->area_summary.right, this->area_summary.top, this->area_summary.bottom, this->summary_msg, TC_FROMSTRING, SA_CENTER); case EMW_MESSAGE:
if (this->detailed_msg != INVALID_STRING_ID) { CopyInDParam(0, this->decode_params, lengthof(this->decode_params));
DrawStringMultiLine(this->area_detailed.left, this->area_detailed.right, this->area_detailed.top, this->area_detailed.bottom, this->detailed_msg, TC_FROMSTRING, SA_CENTER); SwitchToErrorRefStack();
} RewindTextRefStack();
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 {
int extra = (r.bottom - r.top + 1 - this->height_summary - this->height_detailed - WD_PAR_VSEP_WIDE) / 2;
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_FROMSTRING, SA_CENTER);
/* Switch back to the normal text ref. stack for NewGRF texts */ bottom = r.bottom - WD_FRAMERECT_BOTTOM;
SwitchToNormalRefStack(); top = bottom - this->height_detailed - extra;
DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, top, bottom, this->detailed_msg, TC_FROMSTRING, SA_CENTER);
}
SwitchToNormalRefStack(); // Switch back to the normal text ref. stack for NewGRF texts.
break;
default:
break;
}
} }
virtual void OnMouseLoop() virtual void OnMouseLoop()
@ -671,9 +673,6 @@ public:
*/ */
void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, int x, int y, bool no_timeout) void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, int x, int y, bool no_timeout)
{ {
static Widget *generated_errmsg_widgets = NULL;
static Widget *generated_errmsg_face_widgets = NULL;
DeleteWindowById(WC_ERRMSG, 0); DeleteWindowById(WC_ERRMSG, 0);
if (_settings_client.gui.errmsg_duration == 0 && !no_timeout) return; if (_settings_client.gui.errmsg_duration == 0 && !no_timeout) return;
@ -701,9 +700,7 @@ void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, int x, int y,
pt.y = (_screen.height - 46) >> 1; pt.y = (_screen.height - 46) >> 1;
} }
const Widget *wid = InitializeWidgetArrayFromNestedWidgets(_nested_errmsg_widgets, lengthof(_nested_errmsg_widgets), new ErrmsgWindow(pt, &_errmsg_desc, summary_msg, detailed_msg, no_timeout);
_errmsg_widgets, &generated_errmsg_widgets);
new ErrmsgWindow(pt, 240, 46, summary_msg, detailed_msg, wid, false, no_timeout);
} else { } else {
if ((x | y) != 0) { if ((x | y) != 0) {
pt = RemapCoords2(x, y); pt = RemapCoords2(x, y);
@ -715,9 +712,7 @@ void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, int x, int y,
pt.y = (_screen.height - 137) >> 1; pt.y = (_screen.height - 137) >> 1;
} }
const Widget *wid = InitializeWidgetArrayFromNestedWidgets(_nested_errmsg_face_widgets, lengthof(_nested_errmsg_face_widgets), new ErrmsgWindow(pt, &_errmsg_face_desc, summary_msg, detailed_msg, no_timeout);
_errmsg_face_widgets, &generated_errmsg_face_widgets);
new ErrmsgWindow(pt, 334, 137, summary_msg, detailed_msg, wid, true, no_timeout);
} }
} }

Loading…
Cancel
Save