Changeset - r9682:4ecd68d88958
[Not reviewed]
master
0 3 0
smatz - 16 years ago 2008-07-22 19:25:47
smatz@openttd.org
(svn r13787) -Codechange: resize the red error message box if needed
3 files changed with 77 insertions and 12 deletions:
0 comments (0 inline, 0 general)
src/gfx.cpp
Show inline comments
 
@@ -443,24 +443,70 @@ end_of_inner_loop:
 
		 * whitespace seperators are supported */
 
		num++;
 
		char *s = Utf8PrevChar(str);
 
		*s++ = '\0';
 

	
 
		/* In which case (see above) we will shift remainder to left and close the gap */
 
		if (str - s >= 1) {
 
			for (; str[-1] != '\0';) *s++ = *str++;
 
		}
 
	}
 
}
 

	
 

	
 
/** 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<int>(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
 
 * @param str String to draw
 
 * @param maxw Maximum width the string can have before it is wrapped */
 
void DrawStringMultiCenter(int x, int y, StringID str, int maxw)
 
{
 
	char buffer[512];
 
	uint32 tmp;
 
	int num, w, mt;
 
	const char *src;
 
	WChar c;
src/gfx_func.h
Show inline comments
 
@@ -96,24 +96,25 @@ void DrawStringCenterUnderlineTruncated(
 
int DrawStringRightAligned(int x, int y, StringID str, uint16 color);
 
void DrawStringRightAlignedTruncated(int x, int y, StringID str, uint16 color, uint maxw);
 
void DrawStringRightAlignedUnderline(int x, int y, StringID str, uint16 color);
 

	
 
void DrawCharCentered(uint32 c, int x, int y, uint16 color);
 

	
 
void GfxFillRect(int left, int top, int right, int bottom, int color, FillRectMode mode = FILLRECT_OPAQUE);
 
void GfxDrawLine(int left, int top, int right, int bottom, int color);
 
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);
 

	
 
/**
 
 * Let the dirty blocks repainting by the video driver.
 
 *
 
 * @ingroup dirty
 
 */
 
void DrawDirtyBlocks();
 

	
 
/**
src/misc_gui.cpp
Show inline comments
 
@@ -369,83 +369,101 @@ struct AboutWindow : public Window {
 
	}
 
};
 

	
 
void ShowAboutWindow()
 
{
 
	DeleteWindowById(WC_GAME_OPTIONS, 0);
 
	new AboutWindow();
 
}
 

	
 
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},
 
};
 

	
 
struct ErrmsgWindow : public Window {
 
private:
 
	uint duration;
 
	uint64 decode_params[20];
 
	StringID message_1;
 
	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),
 
			show_player_face(show_player_face)
 
	{
 
		this->duration = _settings_client.gui.errmsg_duration;
 
		CopyOutDParam(this->decode_params, 0, lengthof(this->decode_params));
 
		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<int>(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));
 

	
 
		/* 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();
 

	
 
		if (this->show_player_face) {
 
			const Player *p = GetPlayer((PlayerID)GetDParamX(this->decode_params, 2));
 
			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();
 
	}
 

	
 
	virtual void OnMouseLoop()
 
	{
 
		if (_right_button_down) delete this;
 
	}
 

	
 
	virtual void OnHundredthTick()
 
	{
0 comments (0 inline, 0 general)