Changeset - r15390:44d506cb3529
[Not reviewed]
master
0 20 0
alberth - 14 years ago 2010-07-02 13:53:05
alberth@openttd.org
(svn r20043) -Codechange: Introduce vertical alignment for DrawStringMultiLine().
20 files changed with 80 insertions and 74 deletions:
0 comments (0 inline, 0 general)
src/autoreplace_gui.cpp
Show inline comments
 
@@ -318,25 +318,25 @@ public:
 
				const Company *c = Company::Get(_local_company);
 
				if (this->sel_engine[0] != INVALID_ENGINE) {
 
					if (!EngineHasReplacementForCompany(c, this->sel_engine[0], this->sel_group)) {
 
						SetDParam(0, STR_REPLACE_NOT_REPLACING);
 
					} else {
 
						SetDParam(0, STR_ENGINE_NAME);
 
						SetDParam(1, EngineReplacementForCompany(c, this->sel_engine[0], this->sel_group));
 
					}
 
				} else {
 
					SetDParam(0, STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED);
 
				}
 

	
 
				DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_BLACK_STRING, TC_FROMSTRING, SA_CENTER);
 
				DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_BLACK_STRING, TC_FROMSTRING, SA_HOR_CENTER);
 
				break;
 
			}
 

	
 
			case RVW_WIDGET_LEFT_MATRIX:
 
			case RVW_WIDGET_RIGHT_MATRIX: {
 
				int side = (widget == RVW_WIDGET_LEFT_MATRIX) ? 0 : 1;
 
				EngineID start  = side == 0 ? this->vscroll.GetPosition() : this->vscroll2.GetPosition(); // what is the offset for the start (scrolling)
 
				EngineID end    = min((side == 0 ? this->vscroll.GetCapacity() : this->vscroll2.GetCapacity()) + start, this->engines[side].Length());
 

	
 
				/* Do the actual drawing */
 
				DrawEngineList((VehicleType)this->window_number, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP,
 
						&this->engines[side], start, end, this->sel_engine[side], side == 0, this->sel_group);
src/company_gui.cpp
Show inline comments
 
@@ -140,25 +140,25 @@ enum CompanyFinancesWindowWidgets {
 
	CFW_INCREASE_LOAN, ///< Increase loan
 
	CFW_REPAY_LOAN,    ///< Decrease loan
 
};
 

	
 
/** Draw the expenses categories.
 
 * @param r Available space for drawing.
 
 * @note The environment must provide padding at the left and right of \a r.
 
 */
 
static void DrawCategories(const Rect &r)
 
{
 
	int y = r.top;
 

	
 
	DrawString(r.left, r.right, y, STR_FINANCES_EXPENDITURE_INCOME_TITLE, TC_FROMSTRING, SA_CENTER, true);
 
	DrawString(r.left, r.right, y, STR_FINANCES_EXPENDITURE_INCOME_TITLE, TC_FROMSTRING, SA_HOR_CENTER, true);
 
	y += FONT_HEIGHT_NORMAL + EXP_LINESPACE;
 

	
 
	int type = _settings_client.gui.expenses_layout;
 
	for (uint i = 0; i < _expenses_list_types[type].length; i++) {
 
		const ExpensesType et = _expenses_list_types[type].et[i];
 
		if (et == INVALID_EXPENSES) {
 
			y += EXP_LINESPACE;
 
			DrawString(r.left, r.right, y, STR_FINANCES_TOTAL_CAPTION, TC_FROMSTRING, SA_RIGHT);
 
			y += FONT_HEIGHT_NORMAL + EXP_BLOCKSPACE;
 
		} else {
 
			DrawString(r.left, r.right, y, STR_FINANCES_SECTION_CONSTRUCTION + et);
 
			y += FONT_HEIGHT_NORMAL;
 
@@ -1110,25 +1110,25 @@ class SelectCompanyManagerFaceWindow : p
 
		if (!nwi_widget->IsDisabled()) {
 
			if (is_bool_widget) {
 
				/* if it a bool button write yes or no */
 
				str = (val != 0) ? STR_FACE_YES : STR_FACE_NO;
 
			} else {
 
				/* else write the value + 1 */
 
				SetDParam(0, val + 1);
 
				str = STR_JUST_INT;
 
			}
 

	
 
			/* Draw the value/bool in white (0xC). If the button clicked adds 1px to x and y text coordinates (IsWindowWidgetLowered()). */
 
			DrawString(nwi_widget->pos_x + nwi_widget->IsLowered(), nwi_widget->pos_x + nwi_widget->current_x - 1 - nwi_widget->IsLowered(),
 
					nwi_widget->pos_y + 1 + nwi_widget->IsLowered(), str, TC_WHITE, SA_CENTER);
 
					nwi_widget->pos_y + 1 + nwi_widget->IsLowered(), str, TC_WHITE, SA_HOR_CENTER);
 
		}
 
	}
 

	
 
	void UpdateData()
 
	{
 
		this->ge = (GenderEthnicity)GB(this->face, _cmf_info[CMFV_GEN_ETHN].offset, _cmf_info[CMFV_GEN_ETHN].length); // get the gender and ethnicity
 
		this->is_female = HasBit(this->ge, GENDER_FEMALE); // get the gender: 0 == male and 1 == female
 
		this->is_moust_male = !is_female && GetCompanyManagerFaceBits(this->face, CMFV_HAS_MOUSTACHE, this->ge) != 0; // is a male face with moustache
 
	}
 

	
 
public:
 
	SelectCompanyManagerFaceWindow(const WindowDesc *desc, Window *parent) : Window()
src/engine_gui.cpp
Show inline comments
 
@@ -88,25 +88,25 @@ struct EnginePreviewWindow : Window {
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		if (widget != EPW_QUESTION) return;
 

	
 
		EngineID engine = this->window_number;
 
		SetDParam(0, GetEngineCategoryName(engine));
 
		int y = r.top + GetStringHeight(STR_ENGINE_PREVIEW_MESSAGE, r.right - r.top + 1);
 
		y = DrawStringMultiLine(r.left, r.right, r.top, y, STR_ENGINE_PREVIEW_MESSAGE, TC_FROMSTRING, SA_CENTER) + WD_PAR_VSEP_WIDE;
 

	
 
		SetDParam(0, engine);
 
		DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_ENGINE_NAME, TC_BLACK, SA_CENTER);
 
		DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_ENGINE_NAME, TC_BLACK, SA_HOR_CENTER);
 
		y += FONT_HEIGHT_NORMAL;
 

	
 
		DrawVehicleEngine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, this->width >> 1, y + VEHICLE_SPACE / 2, engine, GetEnginePalette(engine, _local_company));
 

	
 
		y += VEHICLE_SPACE;
 
		DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, r.bottom, GetEngineInfoString(engine), TC_FROMSTRING, SA_CENTER);
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget, int click_count)
 
	{
 
		switch (widget) {
 
			case EPW_YES:
src/fios_gui.cpp
Show inline comments
 
@@ -358,25 +358,25 @@ public:
 
					if (item == this->selected) {
 
						GfxFillRect(r.left + 1, y, r.right, y + this->resize.step_height, 156);
 
					}
 
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, item->title, _fios_colours[item->type]);
 
					y += this->resize.step_height;
 
					if (y >= this->vscroll.GetCapacity() * this->resize.step_height + r.top + WD_FRAMERECT_TOP) break;
 
				}
 
			} break;
 

	
 
			case SLWW_DETAILS: {
 
				GfxFillRect(r.left + WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP,
 
						r.right - WD_FRAMERECT_RIGHT, r.top + FONT_HEIGHT_NORMAL * 2 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM, 0x0A);
 
				DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL / 2 + WD_FRAMERECT_TOP, STR_SAVELOAD_DETAIL_CAPTION, TC_FROMSTRING, SA_CENTER);
 
				DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL / 2 + WD_FRAMERECT_TOP, STR_SAVELOAD_DETAIL_CAPTION, TC_FROMSTRING, SA_HOR_CENTER);
 

	
 
				if (this->selected == NULL) break;
 

	
 
				uint y = r.top + FONT_HEIGHT_NORMAL * 2 + WD_PAR_VSEP_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
 
				uint y_max = r.bottom - FONT_HEIGHT_NORMAL - WD_FRAMERECT_BOTTOM;
 

	
 
				if (y > y_max) break;
 
				if (!_load_check_data.checkable) {
 
					/* Old savegame, no information available */
 
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_NOT_AVAILABLE);
 
					y += FONT_HEIGHT_NORMAL;
 
				} else if (_load_check_data.error != INVALID_STRING_ID) {
src/genworld_gui.cpp
Show inline comments
 
@@ -1211,35 +1211,35 @@ struct GenerateProgressWindow : public W
 
				break;
 
		}
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		switch (widget) {
 
			case GPWW_PROGRESS_BAR:
 
				/* Draw the % complete with a bar and a text */
 
				DrawFrameRect(r.left, r.top, r.right, r.bottom, COLOUR_GREY, FR_BORDERONLY);
 
				DrawFrameRect(r.left + 1, r.top + 1, (int)((r.right - r.left - 2) * _gws.percent / 100) + r.left + 1, r.bottom - 1, COLOUR_MAUVE, FR_NONE);
 
				SetDParam(0, _gws.percent);
 
				DrawString(r.left, r.right, r.top + 5, STR_GENERATION_PROGRESS, TC_FROMSTRING, SA_CENTER);
 
				DrawString(r.left, r.right, r.top + 5, STR_GENERATION_PROGRESS, TC_FROMSTRING, SA_HOR_CENTER);
 
				break;
 

	
 
			case GPWW_PROGRESS_TEXT:
 
				/* Tell which class we are generating */
 
				DrawString(r.left, r.right, r.top, _gws.cls, TC_FROMSTRING, SA_CENTER);
 
				DrawString(r.left, r.right, r.top, _gws.cls, TC_FROMSTRING, SA_HOR_CENTER);
 

	
 
				/* And say where we are in that class */
 
				SetDParam(0, _gws.current);
 
				SetDParam(1, _gws.total);
 
				DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL, STR_GENERATION_PROGRESS_NUM, TC_FROMSTRING, SA_CENTER);
 
				DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL, STR_GENERATION_PROGRESS_NUM, TC_FROMSTRING, SA_HOR_CENTER);
 
		}
 
	}
 
};
 

	
 
/**
 
 * Initializes the progress counters to the starting point.
 
 */
 
void PrepareGenerateWorldProgress()
 
{
 
	_gws.cls     = STR_GENERATION_WORLD_GENERATION;
 
	_gws.current = 0;
 
	_gws.total   = 0;
src/gfx.cpp
Show inline comments
 
@@ -518,25 +518,25 @@ static int DrawString(int left, int righ
 
			loc += len;
 
			continue;
 
		}
 

	
 
		if (align & SA_STRIP) {
 
			/* We do not want to keep the SETX(Y)!. It was already copied, so
 
			 * remove it and undo the incrementing of the pointer! */
 
			*p-- = '\0';
 
			loc += len + (c == SCC_SETXY ? 2 : 1);
 
			continue;
 
		}
 

	
 
		if ((align & SA_MASK) != SA_LEFT) {
 
		if ((align & SA_HOR_MASK) != SA_LEFT) {
 
			DEBUG(grf, 1, "Using SETX and/or SETXY when not aligned to the left. Fixing alignment...");
 

	
 
			/* For left alignment and change the left so it will roughly be in the
 
			 * middle. This will never cause the string to be completely centered,
 
			 * but once SETX is used you cannot be sure the actual content of the
 
			 * string is centered, so it doesn't really matter. */
 
			align = SA_LEFT | SA_FORCE;
 
			initial_left = left = max(left, (left + right - (int)GetStringBoundingBox(str).width) / 2);
 
		}
 

	
 
		/* We add the begin of the string, but don't add it twice */
 
		if (p != draw_buffer) {
 
@@ -545,76 +545,76 @@ static int DrawString(int left, int righ
 
			*p++ = c;
 
		}
 

	
 
		/* Skip the SCC_SETX(Y) ... */
 
		loc += len;
 
		/* ... copy the x coordinate ... */
 
		*p++ = *loc++;
 
		/* ... and finally copy the y coordinate if it exists */
 
		if (c == SCC_SETXY) *p++ = *loc++;
 
	}
 

	
 
	/* In case we have a RTL language we swap the alignment. */
 
	if (!(align & SA_FORCE) && _dynlang.text_dir == TD_RTL && align != SA_CENTER) align ^= SA_RIGHT;
 
	if (!(align & SA_FORCE) && _dynlang.text_dir == TD_RTL && !(align & SA_STRIP) && (align & SA_HOR_MASK) != SA_HOR_CENTER) align ^= SA_RIGHT;
 

	
 
	for (UChar **iter = setx_offsets.Begin(); iter != setx_offsets.End(); iter++) {
 
		UChar *to_draw = *iter;
 
		int offset = 0;
 

	
 
		/* Skip the SETX(Y) and set the appropriate offsets. */
 
		if (*to_draw == SCC_SETX || *to_draw == SCC_SETXY) {
 
			to_draw++;
 
			offset = *to_draw++;
 
			if (*to_draw == SCC_SETXY) top = initial_top + *to_draw++;
 
		}
 

	
 
		to_draw = HandleBiDiAndArabicShapes(to_draw);
 
		int w = GetStringWidth(to_draw, params.fontsize);
 

	
 
		/* right is the right most position to draw on. In this case we want to do
 
		 * calculations with the width of the string. In comparison right can be
 
		 * seen as lastof(todraw) and width as lengthof(todraw). They differ by 1.
 
		 * So most +1/-1 additions are to move from lengthof to 'indices'.
 
		 */
 
		switch (align & SA_MASK) {
 
		switch (align & SA_HOR_MASK) {
 
			case SA_LEFT:
 
				/* right + 1 = left + w */
 
				left = initial_left + offset;
 
				right = left + w - 1;
 
				break;
 

	
 
			case SA_CENTER:
 
			case SA_HOR_CENTER:
 
				left  = RoundDivSU(initial_right + 1 + initial_left - w, 2);
 
				/* right + 1 = left + w */
 
				right = left + w - 1;
 
				break;
 

	
 
			case SA_RIGHT:
 
				left = initial_right + 1 - w - offset;
 
				break;
 

	
 
			default:
 
				NOT_REACHED();
 
		}
 

	
 
		min_left  = min(left, min_left);
 
		max_right = max(right, max_right);
 

	
 
		ReallyDoDrawString(to_draw, left, top, params, !truncate);
 
		if (underline) {
 
			GfxFillRect(left, top + FONT_HEIGHT_NORMAL, right, top + FONT_HEIGHT_NORMAL, _string_colourremap[1]);
 
		}
 
	}
 

	
 
	return align == SA_RIGHT ? min_left : max_right;
 
	return (align & SA_HOR_MASK) == SA_RIGHT ? min_left : max_right;
 
}
 

	
 
/**
 
 * Draw string, possibly truncated to make it fit in its allocated space
 
 *
 
 * @param left   The left most position to draw on.
 
 * @param right  The right most position to draw on.
 
 * @param top    The top most position to draw on.
 
 * @param str    String to draw.
 
 * @param colour Colour used for drawing the string, see DoDrawString() for details
 
 * @param align  The alignment of the string when drawing left-to-right. In the
 
 *               case a right-to-left language is chosen this is inverted so it
 
@@ -815,27 +815,25 @@ Dimension GetStringMultiLineBoundingBox(
 
	return box;
 
}
 

	
 
/**
 
 * Draw string, possibly over multiple lines.
 
 *
 
 * @param left   The left most position to draw on.
 
 * @param right  The right most position to draw on.
 
 * @param top    The top most position to draw on.
 
 * @param bottom The bottom most position to draw on.
 
 * @param str    String to draw.
 
 * @param colour Colour used for drawing the string, see DoDrawString() for details
 
 * @param align  The alignment of the string when drawing left-to-right. In the
 
 *               case a right-to-left language is chosen this is inverted so it
 
 *               will be drawn in the right direction.
 
 * @param align  The horizontal and vertical alignment of the string.
 
 * @param underline Whether to underline all strings
 
 *
 
 * @return The bottom to where we have written.
 
 */
 
int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str, TextColour colour, StringAlignment align, bool underline)
 
{
 
	int maxw = right - left + 1;
 
	int maxh = bottom - top + 1;
 

	
 
	/* It makes no sense to even try if it can't be drawn anyway, or
 
	 * do we really want to support fonts of 0 or less pixels high? */
 
	if (maxh <= 0) return top;
 
@@ -848,25 +846,25 @@ int DrawStringMultiLine(int left, int ri
 

	
 
	int mt = GetCharacterHeight((FontSize)GB(tmp, 16, 16));
 
	int total_height = (num + 1) * mt;
 

	
 
	if (total_height > maxh) {
 
		/* Check there's room enough for at least one line. */
 
		if (maxh < mt) return top;
 

	
 
		num = maxh / mt - 1;
 
		total_height = (num + 1) * mt;
 
	}
 

	
 
	int y = (align == SA_CENTER) ? RoundDivSU(bottom + top - total_height, 2) : top;
 
	int y = ((align & SA_VERT_MASK) == SA_VERT_CENTER) ? RoundDivSU(bottom + top - total_height, 2) : top;
 
	const char *src = buffer;
 

	
 
	DrawStringParams params(colour);
 

	
 
	for (;;) {
 
		char buf2[DRAW_STRING_BUFFER];
 
		strecpy(buf2, src, lastof(buf2));
 
		DrawString(left, right, y, buf2, lastof(buf2), params, align, underline, false);
 

	
 
		for (;;) {
 
			WChar c = Utf8Consume(&src);
 
			if (c == 0) {
src/gfx_func.h
Show inline comments
 
@@ -84,36 +84,44 @@ void UndrawMouseCursor();
 

	
 
/** Size of the buffer used for drawing strings. */
 
static const int DRAW_STRING_BUFFER = 2048;
 

	
 
void RedrawScreenRect(int left, int top, int right, int bottom);
 
void GfxScroll(int left, int top, int width, int height, int xo, int yo);
 

	
 
Dimension GetSpriteSize(SpriteID sprid);
 
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = NULL);
 

	
 
/** How to align the to-be drawn text. */
 
enum StringAlignment {
 
	SA_LEFT,      ///< Left align the text
 
	SA_CENTER,    ///< Center the text
 
	SA_RIGHT,     ///< Right align the text
 
	SA_MASK  = 3, ///< Mask for base alignment
 
	SA_FORCE = 4, ///< Force the alignment, i.e. don't swap for RTL languages.
 
	SA_STRIP = 8, ///< Strip the SETX/SETXY commands from the string
 
	SA_LEFT        = 0 << 0, ///< Left align the text.
 
	SA_HOR_CENTER  = 1 << 0, ///< Horizontally center the text.
 
	SA_RIGHT       = 2 << 0, ///< Right align the text (must be a single bit).
 
	SA_HOR_MASK    = 3 << 0, ///< Mask for horizontal alignment.
 

	
 
	SA_TOP         = 0 << 2, ///< Top align the text.
 
	SA_VERT_CENTER = 1 << 2, ///< Vertically center the text.
 
	SA_BOTTOM      = 2 << 2, ///< Bottom align the text.
 
	SA_VERT_MASK   = 3 << 2, ///< Mask for vertical alignment.
 

	
 
	SA_CENTER      = SA_HOR_CENTER | SA_VERT_CENTER, ///< Center both horizontally and vertically.
 

	
 
	SA_FORCE       = 1 << 4, ///< Force the alignment, i.e. don't swap for RTL languages.
 
	SA_STRIP       = 1 << 5, ///< Strip the SETX/SETXY commands from the string
 
};
 
DECLARE_ENUM_AS_BIT_SET(StringAlignment)
 

	
 
int DrawString(int left, int right, int top, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false);
 
int DrawString(int left, int right, int top, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false);
 
int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false);
 
int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false);
 

	
 
void DrawCharCentered(uint32 c, int x, int y, TextColour colour);
 

	
 
void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode = FILLRECT_OPAQUE);
 
void GfxDrawLine(int left, int top, int right, int bottom, int colour);
 
void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3);
 

	
 
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize = FS_NORMAL);
 
Dimension GetStringBoundingBox(StringID strid);
 
uint32 FormatStringLinebreaks(char *str, const char *last, int maxw, FontSize start_fontsize = FS_NORMAL);
 
int GetStringHeight(StringID str, int maxw);
 
Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestion);
src/graph_gui.cpp
Show inline comments
 
@@ -399,25 +399,25 @@ protected:
 
					year++;
 
				}
 
				x += x_sep;
 
			}
 
		} else {
 
			/* Draw the label under the data point rather than on the grid line. */
 
			x = r.left;
 
			y = r.bottom + 2;
 
			uint16 label = this->x_values_start;
 

	
 
			for (int i = 0; i < this->num_on_x_axis; i++) {
 
				SetDParam(0, label);
 
				DrawString(x + 1, x + x_sep - 1, y, STR_GRAPH_Y_LABEL_NUMBER, graph_axis_label_colour, SA_CENTER);
 
				DrawString(x + 1, x + x_sep - 1, y, STR_GRAPH_Y_LABEL_NUMBER, graph_axis_label_colour, SA_HOR_CENTER);
 

	
 
				label += this->x_values_increment;
 
				x += x_sep;
 
			}
 
		}
 

	
 
		/* draw lines and dots */
 
		for (int i = 0; i < this->num_dataset; i++) {
 
			if (!HasBit(this->excluded_data, i)) {
 
				/* Centre the dot between the grid lines. */
 
				x = r.left + (x_sep / 2);
 

	
 
@@ -1430,25 +1430,25 @@ struct PerformanceRatingDetailWindow : W
 
		if (rtl) {
 
			x = this->bar_right - x;
 
		} else {
 
			x = this->bar_left + x;
 
		}
 

	
 
		/* Draw the bar */
 
		if (x != this->bar_left)  GfxFillRect(this->bar_left, bar_top, x, bar_top + this->bar_height, rtl ? colour_notdone : colour_done);
 
		if (x != this->bar_right) GfxFillRect(x, bar_top, this->bar_right, bar_top + this->bar_height, rtl ? colour_done : colour_notdone);
 

	
 
		/* Draw it */
 
		SetDParam(0, Clamp(val, 0, needed) * 100 / needed);
 
		DrawString(this->bar_left, this->bar_right, text_top, STR_PERFORMANCE_DETAIL_PERCENT, TC_FROMSTRING, SA_CENTER);
 
		DrawString(this->bar_left, this->bar_right, text_top, STR_PERFORMANCE_DETAIL_PERCENT, TC_FROMSTRING, SA_HOR_CENTER);
 

	
 
		/* SCORE_LOAN is inversed */
 
		if (score_type == SCORE_LOAN) val = needed - val;
 

	
 
		/* Draw the amount we have against what is needed
 
		 * For some of them it is in currency format */
 
		SetDParam(0, val);
 
		SetDParam(1, needed);
 
		switch (score_type) {
 
			case SCORE_MIN_PROFIT:
 
			case SCORE_MIN_INCOME:
 
			case SCORE_MAX_INCOME:
src/misc_gui.cpp
Show inline comments
 
@@ -84,25 +84,25 @@ public:
 
	{
 
		this->DrawWidgets();
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		if (widget != LIW_BACKGROUND) return;
 

	
 
		uint y = r.top + WD_TEXTPANEL_TOP;
 
		for (uint i = 0; i < LAND_INFO_CENTERED_LINES; i++) {
 
			if (StrEmpty(this->landinfo_data[i])) break;
 

	
 
			DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, this->landinfo_data[i], i == 0 ? TC_LIGHT_BLUE : TC_FROMSTRING, SA_CENTER);
 
			DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, this->landinfo_data[i], i == 0 ? TC_LIGHT_BLUE : TC_FROMSTRING, SA_HOR_CENTER);
 
			y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
 
			if (i == 0) y += 4;
 
		}
 

	
 
		if (!StrEmpty(this->landinfo_data[LAND_INFO_MULTICENTER_LINE])) {
 
			SetDParamStr(0, this->landinfo_data[LAND_INFO_MULTICENTER_LINE]);
 
			DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, r.bottom - WD_TEXTPANEL_BOTTOM, STR_JUST_RAW_STRING, TC_FROMSTRING, SA_CENTER);
 
		}
 
	}
 

	
 
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
 
	{
src/music_gui.cpp
Show inline comments
 
@@ -604,25 +604,25 @@ struct MusicWindow : public Window {
 
					str = STR_MUSIC_TRACK_DIGIT;
 
				}
 
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str);
 
			} break;
 

	
 
			case MW_TRACK_NAME: {
 
				GfxFillRect(r.left, r.top + 1, r.right - 1, r.bottom, 0);
 
				StringID str = STR_MUSIC_TITLE_NONE;
 
				if (_song_is_active != 0 && _music_wnd_cursong != 0) {
 
					str = STR_MUSIC_TITLE_NAME;
 
					SetDParamStr(0, GetSongName(_music_wnd_cursong - 1));
 
				}
 
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_FROMSTRING, SA_CENTER);
 
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_FROMSTRING, SA_HOR_CENTER);
 
			} break;
 

	
 
			case MW_MUSIC_VOL: case MW_EFFECT_VOL: {
 
				DrawFrameRect(r.left, r.top + 2, r.right, r.bottom - 2, COLOUR_GREY, FR_LOWERED);
 
				byte volume = (widget == MW_MUSIC_VOL) ? msf.music_vol : msf.effect_vol;
 
				int x = (volume * (r.right - r.left) / 127);
 
				if (_dynlang.text_dir == TD_RTL) {
 
					x = r.right - x;
 
				} else {
 
					x += r.left;
 
				}
 
				DrawFrameRect(x, r.top, x + slider_width, r.bottom, COLOUR_GREY, FR_NONE);
src/network/network_content_gui.cpp
Show inline comments
 
@@ -142,25 +142,25 @@ public:
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		if (widget != NCDSWW_BACKGROUND) return;
 

	
 
		/* Draw nice progress bar :) */
 
		DrawFrameRect(r.left + 20, r.top + 4, r.left + 20 + (int)((this->width - 40LL) * this->downloaded_bytes / this->total_bytes), r.top + 14, COLOUR_MAUVE, FR_NONE);
 

	
 
		int y = r.top + 20;
 
		SetDParam(0, this->downloaded_bytes);
 
		SetDParam(1, this->total_bytes);
 
		SetDParam(2, this->downloaded_bytes * 100LL / this->total_bytes);
 
		DrawString(r.left + 2, r.right - 2, y, STR_CONTENT_DOWNLOAD_PROGRESS_SIZE, TC_FROMSTRING, SA_CENTER);
 
		DrawString(r.left + 2, r.right - 2, y, STR_CONTENT_DOWNLOAD_PROGRESS_SIZE, TC_FROMSTRING, SA_HOR_CENTER);
 

	
 
		StringID str;
 
		if (this->downloaded_bytes == this->total_bytes) {
 
			str = STR_CONTENT_DOWNLOAD_COMPLETE;
 
		} else if (!StrEmpty(this->name)) {
 
			SetDParamStr(0, this->name);
 
			SetDParam(1, this->downloaded_files);
 
			SetDParam(2, this->total_files);
 
			str = STR_CONTENT_DOWNLOAD_FILE;
 
		} else {
 
			str = STR_CONTENT_DOWNLOAD_INITIALISE;
 
		}
 
@@ -457,47 +457,47 @@ public:
 
			SpriteID pal = PAL_NONE;
 
			switch (ci->state) {
 
				case ContentInfo::UNSELECTED:     sprite = SPR_BOX_EMPTY;   break;
 
				case ContentInfo::SELECTED:       sprite = SPR_BOX_CHECKED; break;
 
				case ContentInfo::AUTOSELECTED:   sprite = SPR_BOX_CHECKED; break;
 
				case ContentInfo::ALREADY_HERE:   sprite = SPR_BLOT; pal = PALETTE_TO_GREEN; break;
 
				case ContentInfo::DOES_NOT_EXIST: sprite = SPR_BLOT; pal = PALETTE_TO_RED;   break;
 
				default: NOT_REACHED();
 
			}
 
			DrawSprite(sprite, pal, nwi_checkbox->pos_x + (pal == PAL_NONE ? 2 : 3), y + sprite_y_offset + (pal == PAL_NONE ? 1 : 0));
 

	
 
			StringID str = STR_CONTENT_TYPE_BASE_GRAPHICS + ci->type - CONTENT_TYPE_BASE_GRAPHICS;
 
			DrawString(nwi_type->pos_x, nwi_type->pos_x + nwi_type->current_x - 1, y + WD_MATRIX_TOP, str, TC_BLACK, SA_CENTER);
 
			DrawString(nwi_type->pos_x, nwi_type->pos_x + nwi_type->current_x - 1, y + WD_MATRIX_TOP, str, TC_BLACK, SA_HOR_CENTER);
 

	
 
			DrawString(nwi_name->pos_x + WD_FRAMERECT_LEFT, nwi_name->pos_x + nwi_name->current_x - WD_FRAMERECT_RIGHT, y + WD_MATRIX_TOP, ci->name, TC_BLACK);
 
			y += this->resize.step_height;
 
		}
 
	}
 

	
 
	/**
 
	 * Helper function to draw the details part of this window.
 
	 * @param r the rectangle to stay within while drawing
 
	 */
 
	void DrawDetails(const Rect &r) const
 
	{
 
		static const int DETAIL_LEFT         =  5; ///< Number of pixels at the left
 
		static const int DETAIL_RIGHT        =  5; ///< Number of pixels at the right
 
		static const int DETAIL_TOP          =  5; ///< Number of pixels at the top
 

	
 
		/* Height for the title banner */
 
		int DETAIL_TITLE_HEIGHT = 5 * FONT_HEIGHT_NORMAL;
 

	
 
		/* Create the nice grayish rectangle at the details top */
 
		GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + DETAIL_TITLE_HEIGHT, 157);
 
		DrawString(r.left + WD_INSET_LEFT, r.right - WD_INSET_RIGHT, r.top + FONT_HEIGHT_NORMAL + WD_INSET_TOP, STR_CONTENT_DETAIL_TITLE, TC_FROMSTRING, SA_CENTER);
 
		DrawString(r.left + WD_INSET_LEFT, r.right - WD_INSET_RIGHT, r.top + FONT_HEIGHT_NORMAL + WD_INSET_TOP, STR_CONTENT_DETAIL_TITLE, TC_FROMSTRING, SA_HOR_CENTER);
 

	
 
		/* Draw the total download size */
 
		SetDParam(0, this->filesize_sum);
 
		DrawString(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, r.bottom - FONT_HEIGHT_NORMAL - WD_PAR_VSEP_NORMAL, STR_CONTENT_TOTAL_DOWNLOAD_SIZE);
 

	
 
		if (this->selected == NULL) return;
 

	
 
		/* And fill the rest of the details when there's information to place there */
 
		DrawStringMultiLine(r.left + WD_INSET_LEFT, r.right - WD_INSET_RIGHT, r.top + DETAIL_TITLE_HEIGHT / 2, r.top + DETAIL_TITLE_HEIGHT, STR_CONTENT_DETAIL_SUBTITLE_UNSELECTED + this->selected->state, TC_FROMSTRING, SA_CENTER);
 

	
 
		/* Also show the total download size, so keep some space from the bottom */
 
		const uint max_y = r.bottom - FONT_HEIGHT_NORMAL - WD_PAR_VSEP_WIDE;
src/network/network_gui.cpp
Show inline comments
 
@@ -374,52 +374,52 @@ protected:
 
		DrawString(nwi_name->pos_x + WD_FRAMERECT_LEFT, nwi_name->pos_x + nwi_name->current_x - WD_FRAMERECT_RIGHT, y, cur_item->info.server_name, TC_BLACK);
 

	
 
		/* only draw details if the server is online */
 
		if (cur_item->online) {
 
			const NWidgetServerListHeader *nwi_header = this->GetWidget<NWidgetServerListHeader>(NGWW_HEADER);
 

	
 
			if (nwi_header->IsWidgetVisible(NGWW_CLIENTS)) {
 
				const NWidgetBase *nwi_clients = this->GetWidget<NWidgetBase>(NGWW_CLIENTS);
 
				SetDParam(0, cur_item->info.clients_on);
 
				SetDParam(1, cur_item->info.clients_max);
 
				SetDParam(2, cur_item->info.companies_on);
 
				SetDParam(3, cur_item->info.companies_max);
 
				DrawString(nwi_clients->pos_x, nwi_clients->pos_x + nwi_clients->current_x - 1, y, STR_NETWORK_SERVER_LIST_GENERAL_ONLINE, TC_FROMSTRING, SA_CENTER);
 
				DrawString(nwi_clients->pos_x, nwi_clients->pos_x + nwi_clients->current_x - 1, y, STR_NETWORK_SERVER_LIST_GENERAL_ONLINE, TC_FROMSTRING, SA_HOR_CENTER);
 
			}
 

	
 
			if (nwi_header->IsWidgetVisible(NGWW_MAPSIZE)) {
 
				/* map size */
 
				const NWidgetBase *nwi_mapsize = this->GetWidget<NWidgetBase>(NGWW_MAPSIZE);
 
				SetDParam(0, cur_item->info.map_width);
 
				SetDParam(1, cur_item->info.map_height);
 
				DrawString(nwi_mapsize->pos_x, nwi_mapsize->pos_x + nwi_mapsize->current_x - 1, y, STR_NETWORK_SERVER_LIST_MAP_SIZE_SHORT, TC_FROMSTRING, SA_CENTER);
 
				DrawString(nwi_mapsize->pos_x, nwi_mapsize->pos_x + nwi_mapsize->current_x - 1, y, STR_NETWORK_SERVER_LIST_MAP_SIZE_SHORT, TC_FROMSTRING, SA_HOR_CENTER);
 
			}
 

	
 
			if (nwi_header->IsWidgetVisible(NGWW_DATE)) {
 
				/* current date */
 
				const NWidgetBase *nwi_date = this->GetWidget<NWidgetBase>(NGWW_DATE);
 
				YearMonthDay ymd;
 
				ConvertDateToYMD(cur_item->info.game_date, &ymd);
 
				SetDParam(0, ymd.year);
 
				DrawString(nwi_date->pos_x, nwi_date->pos_x + nwi_date->current_x - 1, y, STR_JUST_INT, TC_BLACK, SA_CENTER);
 
				DrawString(nwi_date->pos_x, nwi_date->pos_x + nwi_date->current_x - 1, y, STR_JUST_INT, TC_BLACK, SA_HOR_CENTER);
 
			}
 

	
 
			if (nwi_header->IsWidgetVisible(NGWW_YEARS)) {
 
				/* number of years the game is running */
 
				const NWidgetBase *nwi_years = this->GetWidget<NWidgetBase>(NGWW_YEARS);
 
				YearMonthDay ymd_cur, ymd_start;
 
				ConvertDateToYMD(cur_item->info.game_date, &ymd_cur);
 
				ConvertDateToYMD(cur_item->info.start_date, &ymd_start);
 
				SetDParam(0, ymd_cur.year - ymd_start.year);
 
				DrawString(nwi_years->pos_x, nwi_years->pos_x + nwi_years->current_x - 1, y, STR_JUST_INT, TC_BLACK, SA_CENTER);
 
				DrawString(nwi_years->pos_x, nwi_years->pos_x + nwi_years->current_x - 1, y, STR_JUST_INT, TC_BLACK, SA_HOR_CENTER);
 
			}
 

	
 
			/* Align the sprites */
 
			y += (FONT_HEIGHT_NORMAL - 10) / 2;
 

	
 
			/* draw a lock if the server is password protected */
 
			if (cur_item->info.use_password) DrawSprite(SPR_LOCK, PAL_NONE, nwi_info->pos_x + 5, y - 1);
 

	
 
			/* draw red or green icon, depending on compatibility with server */
 
			DrawSprite(SPR_BLOT, (cur_item->info.compatible ? PALETTE_TO_GREEN : (cur_item->info.version_compatible ? PALETTE_TO_YELLOW : PALETTE_TO_RED)), nwi_info->pos_x + 15, y);
 

	
 
			/* draw flag according to server language */
 
@@ -587,34 +587,34 @@ public:
 
		this->DrawEditBox(NGWW_CLIENT);
 
	}
 

	
 
	void DrawDetails(const Rect &r) const
 
	{
 
		NetworkGameList *sel = this->server;
 

	
 
		const int detail_height = 6 + 8 + 6 + 3 * FONT_HEIGHT_NORMAL;
 

	
 
		/* Draw the right menu */
 
		GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + detail_height - 1, 157);
 
		if (sel == NULL) {
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_CENTER);
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_HOR_CENTER);
 
		} else if (!sel->online) {
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, sel->info.server_name, TC_ORANGE, SA_CENTER); // game name
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, sel->info.server_name, TC_ORANGE, SA_HOR_CENTER); // game name
 

	
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + detail_height + 4, STR_NETWORK_SERVER_LIST_SERVER_OFFLINE, TC_FROMSTRING, SA_CENTER); // server offline
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + detail_height + 4, STR_NETWORK_SERVER_LIST_SERVER_OFFLINE, TC_FROMSTRING, SA_HOR_CENTER); // server offline
 
		} else { // show game info
 

	
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_CENTER);
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, sel->info.server_name, TC_ORANGE, SA_CENTER); // game name
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 8 + 2 * FONT_HEIGHT_NORMAL, sel->info.map_name, TC_BLACK, SA_CENTER); // map name
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_HOR_CENTER);
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, sel->info.server_name, TC_ORANGE, SA_HOR_CENTER); // game name
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 8 + 2 * FONT_HEIGHT_NORMAL, sel->info.map_name, TC_BLACK, SA_HOR_CENTER); // map name
 

	
 
			uint16 y = r.top + detail_height + 4;
 

	
 
			SetDParam(0, sel->info.clients_on);
 
			SetDParam(1, sel->info.clients_max);
 
			SetDParam(2, sel->info.companies_on);
 
			SetDParam(3, sel->info.companies_max);
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CLIENTS);
 
			y += FONT_HEIGHT_NORMAL;
 

	
 
			SetDParam(0, STR_NETWORK_LANG_ANY + sel->info.server_lang);
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_LANGUAGE); // server language
 
@@ -639,30 +639,30 @@ public:
 

	
 
			SetDParam(0, sel->info.start_date);
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_START_DATE); // start date
 
			y += FONT_HEIGHT_NORMAL;
 

	
 
			SetDParam(0, sel->info.game_date);
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CURRENT_DATE); // current date
 
			y += FONT_HEIGHT_NORMAL;
 

	
 
			y += WD_PAR_VSEP_NORMAL;
 

	
 
			if (!sel->info.compatible) {
 
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, sel->info.version_compatible ? STR_NETWORK_SERVER_LIST_GRF_MISMATCH : STR_NETWORK_SERVER_LIST_VERSION_MISMATCH, TC_FROMSTRING, SA_CENTER); // server mismatch
 
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, sel->info.version_compatible ? STR_NETWORK_SERVER_LIST_GRF_MISMATCH : STR_NETWORK_SERVER_LIST_VERSION_MISMATCH, TC_FROMSTRING, SA_HOR_CENTER); // server mismatch
 
			} else if (sel->info.clients_on == sel->info.clients_max) {
 
				/* Show: server full, when clients_on == max_clients */
 
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_FULL, TC_FROMSTRING, SA_CENTER); // server full
 
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_FULL, TC_FROMSTRING, SA_HOR_CENTER); // server full
 
			} else if (sel->info.use_password) {
 
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_PASSWORD, TC_FROMSTRING, SA_CENTER); // password warning
 
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_PASSWORD, TC_FROMSTRING, SA_HOR_CENTER); // password warning
 
			}
 
		}
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget, int click_count)
 
	{
 
		this->field = widget;
 
		switch (widget) {
 
			case NGWW_CANCEL: // Cancel button
 
				DeleteWindowById(WC_NETWORK_WINDOW, 0);
 
				break;
 

	
 
@@ -1556,25 +1556,25 @@ struct NetworkLobbyWindow : public Windo
 

	
 
			pos++;
 
			y += this->resize.step_height;
 
			if (pos >= this->vscroll.GetPosition() + this->vscroll.GetCapacity()) break;
 
		}
 
	}
 

	
 
	void DrawDetails(const Rect &r) const
 
	{
 
		const int detail_height = 12 + FONT_HEIGHT_NORMAL + 12;
 
		/* Draw info about selected company when it is selected in the left window */
 
		GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + detail_height - 1, 157);
 
		DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 12, STR_NETWORK_GAME_LOBBY_COMPANY_INFO, TC_FROMSTRING, SA_CENTER);
 
		DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 12, STR_NETWORK_GAME_LOBBY_COMPANY_INFO, TC_FROMSTRING, SA_HOR_CENTER);
 

	
 
		if (this->company == INVALID_COMPANY || StrEmpty(this->company_info[this->company].company_name)) return;
 

	
 
		int y = r.top + detail_height + 4;
 
		const NetworkGameInfo *gi = &this->server->info;
 

	
 
		SetDParam(0, gi->clients_on);
 
		SetDParam(1, gi->clients_max);
 
		SetDParam(2, gi->companies_on);
 
		SetDParam(3, gi->companies_max);
 
		DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CLIENTS);
 
		y += FONT_HEIGHT_NORMAL;
 
@@ -2144,39 +2144,39 @@ struct NetworkJoinStatusWindow : Window 
 
	}
 

	
 
	virtual void OnPaint()
 
	{
 
		this->DrawWidgets();
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		if (widget != NJSW_BACKGROUND) return;
 

	
 
		uint8 progress; // used for progress bar
 
		DrawString(r.left + 2, r.right - 2, r.top + 20, STR_NETWORK_CONNECTING_1 + _network_join_status, TC_FROMSTRING, SA_CENTER);
 
		DrawString(r.left + 2, r.right - 2, r.top + 20, STR_NETWORK_CONNECTING_1 + _network_join_status, TC_FROMSTRING, SA_HOR_CENTER);
 
		switch (_network_join_status) {
 
			case NETWORK_JOIN_STATUS_CONNECTING: case NETWORK_JOIN_STATUS_AUTHORIZING:
 
			case NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO:
 
				progress = 10; // first two stages 10%
 
				break;
 
			case NETWORK_JOIN_STATUS_WAITING:
 
				SetDParam(0, _network_join_waiting);
 
				DrawString(r.left + 2, r.right - 2, r.top + 20 + FONT_HEIGHT_NORMAL, STR_NETWORK_CONNECTING_WAITING, TC_FROMSTRING, SA_CENTER);
 
				DrawString(r.left + 2, r.right - 2, r.top + 20 + FONT_HEIGHT_NORMAL, STR_NETWORK_CONNECTING_WAITING, TC_FROMSTRING, SA_HOR_CENTER);
 
				progress = 15; // third stage is 15%
 
				break;
 
			case NETWORK_JOIN_STATUS_DOWNLOADING:
 
				SetDParam(0, _network_join_bytes);
 
				SetDParam(1, _network_join_bytes_total);
 
				DrawString(r.left + 2, r.right - 2, r.top + 20 + FONT_HEIGHT_NORMAL, STR_NETWORK_CONNECTING_DOWNLOADING, TC_FROMSTRING, SA_CENTER);
 
				DrawString(r.left + 2, r.right - 2, r.top + 20 + FONT_HEIGHT_NORMAL, STR_NETWORK_CONNECTING_DOWNLOADING, TC_FROMSTRING, SA_HOR_CENTER);
 
				/* Fallthrough */
 
			default: // Waiting is 15%, so the resting receivement of map is maximum 70%
 
				progress = 15 + _network_join_bytes * (100 - 15) / _network_join_bytes_total;
 
		}
 

	
 
		/* Draw nice progress bar :) */
 
		DrawFrameRect(r.left + 20, r.top + 5, (int)((this->width - 20) * progress / 100), r.top + 15, COLOUR_MAUVE, FR_NONE);
 
	}
 

	
 
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
 
	{
 
		if (widget != NJSW_BACKGROUND) return;
src/newgrf_gui.cpp
Show inline comments
 
@@ -385,25 +385,25 @@ struct NewGRFWindow : public QueryString
 
					const char *text = c->GetName();
 

	
 
					if (h) GfxFillRect(r.left + 1, y, r.right - 1, y + step_height - 1, 156);
 
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y + offset_y, text, h ? TC_WHITE : TC_SILVER);
 
					y += step_height;
 
				}
 
				break;
 
			}
 

	
 
			case SNGRFS_NEWGRF_INFO_TITLE:
 
				/* Create the nice grayish rectangle at the details top. */
 
				GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, 157);
 
				DrawString(r.left, r.right, (r.top + r.bottom - FONT_HEIGHT_NORMAL) / 2, STR_NEWGRF_SETTINGS_INFO_TITLE, TC_FROMSTRING, SA_CENTER);
 
				DrawString(r.left, r.right, (r.top + r.bottom - FONT_HEIGHT_NORMAL) / 2, STR_NEWGRF_SETTINGS_INFO_TITLE, TC_FROMSTRING, SA_HOR_CENTER);
 
				break;
 

	
 
			case SNGRFS_NEWGRF_INFO: {
 
				const GRFConfig *selected = this->active_sel;
 
				if (selected == NULL) selected = this->avail_sel;
 
				if (selected != NULL) {
 
					ShowNewGRFInfo(selected, r.left + WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP, r.right - WD_FRAMERECT_RIGHT, r.bottom - WD_FRAMERECT_BOTTOM, this->show_params);
 
				}
 
				break;
 
			}
 
		}
 
	}
src/news_gui.cpp
Show inline comments
 
@@ -1127,25 +1127,25 @@ struct MessageOptionsWindow : Window {
 
	}
 

	
 
	virtual void OnPaint()
 
	{
 
		this->DrawWidgets();
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		if (widget >= WIDGET_NEWSOPT_START_OPTION && widget < WIDGET_NEWSOPT_END_OPTION && (widget -  WIDGET_NEWSOPT_START_OPTION) % MOS_WIDG_PER_SETTING == 1) {
 
			/* Draw the string of each setting on each button. */
 
			int i = (widget -  WIDGET_NEWSOPT_START_OPTION) / MOS_WIDG_PER_SETTING;
 
			DrawString(r.left, r.right, r.top + 2, this->message_opt[_news_type_data[i].display], TC_BLACK, SA_CENTER);
 
			DrawString(r.left, r.right, r.top + 2, this->message_opt[_news_type_data[i].display], TC_BLACK, SA_HOR_CENTER);
 
		}
 
	}
 

	
 
	virtual void OnInit()
 
	{
 
		this->dim_message_opt.width  = 0;
 
		this->dim_message_opt.height = 0;
 
		for (const StringID *str = message_opt; *str != INVALID_STRING_ID; str++) this->dim_message_opt = maxdim(this->dim_message_opt, GetStringBoundingBox(*str));
 
	}
 

	
 
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
 
	{
src/station_gui.cpp
Show inline comments
 
@@ -485,47 +485,47 @@ public:
 
					y += FONT_HEIGHT_NORMAL;
 
				}
 

	
 
				if (this->vscroll.GetCount() == 0) { // company has no stations
 
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_STATION_LIST_NONE);
 
					return;
 
				}
 
				break;
 
			}
 

	
 
			case SLW_NOCARGOWAITING: {
 
				int cg_ofst = this->IsWidgetLowered(widget) ? 2 : 1;
 
				DrawString(r.left + cg_ofst, r.right + cg_ofst, r.top + cg_ofst, STR_ABBREV_NONE, TC_BLACK, SA_CENTER);
 
				DrawString(r.left + cg_ofst, r.right + cg_ofst, r.top + cg_ofst, STR_ABBREV_NONE, TC_BLACK, SA_HOR_CENTER);
 
				break;
 
			}
 

	
 
			case SLW_CARGOALL: {
 
				int cg_ofst = this->IsWidgetLowered(widget) ? 2 : 1;
 
				DrawString(r.left + cg_ofst, r.right + cg_ofst, r.top + cg_ofst, STR_ABBREV_ALL, TC_BLACK, SA_CENTER);
 
				DrawString(r.left + cg_ofst, r.right + cg_ofst, r.top + cg_ofst, STR_ABBREV_ALL, TC_BLACK, SA_HOR_CENTER);
 
				break;
 
			}
 

	
 
			case SLW_FACILALL: {
 
				int cg_ofst = this->IsWidgetLowered(widget) ? 2 : 1;
 
				DrawString(r.left + cg_ofst, r.right + cg_ofst, r.top + cg_ofst, STR_ABBREV_ALL, TC_BLACK);
 
				break;
 
			}
 

	
 
			default:
 
				if (widget >= SLW_CARGOSTART) {
 
					const CargoSpec *cs = CargoSpec::Get(widget - SLW_CARGOSTART);
 
					if (cs->IsValid()) {
 
						int cg_ofst = HasBit(this->cargo_filter, cs->Index()) ? 2 : 1;
 
						GfxFillRect(r.left + cg_ofst, r.top + cg_ofst, r.right - 2 + cg_ofst, r.bottom - 2 + cg_ofst, cs->rating_colour);
 
						DrawString(r.left + cg_ofst, r.right + cg_ofst, r.top + cg_ofst, cs->abbrev, TC_BLACK, SA_CENTER);
 
						DrawString(r.left + cg_ofst, r.right + cg_ofst, r.top + cg_ofst, cs->abbrev, TC_BLACK, SA_HOR_CENTER);
 
					}
 
				}
 
				break;
 
		}
 
	}
 

	
 
	virtual void SetStringParameters(int widget) const
 
	{
 
		if (widget == SLW_CAPTION) {
 
			SetDParam(0, this->window_number);
 
			SetDParam(1, this->vscroll.GetCount());
 
		}
src/statusbar_gui.cpp
Show inline comments
 
@@ -131,59 +131,59 @@ struct StatusBarWindow : Window {
 

	
 
		d.width += padding.width;
 
		d.height += padding.height;
 
		*size = maxdim(d, *size);
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		switch (widget) {
 
			case SBW_LEFT:
 
				/* Draw the date */
 
				SetDParam(0, _date);
 
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, (_pause_mode || _settings_client.gui.status_long_date) ? STR_WHITE_DATE_LONG : STR_WHITE_DATE_SHORT, TC_FROMSTRING, SA_CENTER);
 
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, (_pause_mode || _settings_client.gui.status_long_date) ? STR_WHITE_DATE_LONG : STR_WHITE_DATE_SHORT, TC_FROMSTRING, SA_HOR_CENTER);
 
				break;
 

	
 
			case SBW_RIGHT: {
 
				/* Draw company money, if any */
 
				const Company *c = Company::GetIfValid(_local_company);
 
				if (c != NULL) {
 
					SetDParam(0, c->money);
 
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_COMPANY_MONEY, TC_FROMSTRING, SA_CENTER);
 
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_COMPANY_MONEY, TC_FROMSTRING, SA_HOR_CENTER);
 
				}
 
			} break;
 

	
 
			case SBW_MIDDLE:
 
				/* Draw status bar */
 
				if (this->saving) { // true when saving is active
 
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_SAVING_GAME, TC_FROMSTRING, SA_CENTER);
 
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_SAVING_GAME, TC_FROMSTRING, SA_HOR_CENTER);
 
				} else if (_do_autosave) {
 
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_AUTOSAVE, TC_FROMSTRING, SA_CENTER);
 
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_AUTOSAVE, TC_FROMSTRING, SA_HOR_CENTER);
 
				} else if (_pause_mode != PM_UNPAUSED) {
 
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_PAUSED, TC_FROMSTRING, SA_CENTER);
 
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_PAUSED, TC_FROMSTRING, SA_HOR_CENTER);
 
				} else if (this->ticker_scroll < TICKER_STOP && FindWindowById(WC_NEWS_WINDOW, 0) == NULL && _statusbar_news_item != NULL && _statusbar_news_item->string_id != 0) {
 
					/* Draw the scrolling news text */
 
					if (!DrawScrollingStatusText(_statusbar_news_item, this->ticker_scroll, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom)) {
 
						InvalidateWindowData(WC_STATUS_BAR, 0, SBI_NEWS_DELETED);
 
						if (Company::IsValidID(_local_company)) {
 
							/* This is the default text */
 
							SetDParam(0, _local_company);
 
							DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_CENTER);
 
							DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER);
 
						}
 
					}
 
				} else {
 
					if (Company::IsValidID(_local_company)) {
 
						/* This is the default text */
 
						SetDParam(0, _local_company);
 
						DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_CENTER);
 
						DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER);
 
					}
 
				}
 

	
 
				if (this->reminder_timeout > 0) DrawSprite(SPR_BLOT, PALETTE_TO_RED, r.right - WD_FRAMERECT_RIGHT - 10, r.top + WD_FRAMERECT_TOP + 1);
 
				break;
 
		}
 
	}
 

	
 
	virtual void OnInvalidateData(int data)
 
	{
 
		switch (data) {
 
			default: NOT_REACHED();
src/toolbar_gui.cpp
Show inline comments
 
@@ -1449,34 +1449,34 @@ public:
 
	{
 
		this->SetWidgetDisabledState(TBSE_DATEBACKWARD, _settings_game.game_creation.starting_year <= MIN_YEAR);
 
		this->SetWidgetDisabledState(TBSE_DATEFORWARD, _settings_game.game_creation.starting_year >= MAX_YEAR);
 

	
 
		this->DrawWidgets();
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		switch (widget) {
 
			case TBSE_DATEPANEL:
 
				SetDParam(0, ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
 
				DrawString(r.left, r.right, (this->height - FONT_HEIGHT_NORMAL) / 2, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_CENTER);
 
				DrawString(r.left, r.right, (this->height - FONT_HEIGHT_NORMAL) / 2, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_HOR_CENTER);
 
				break;
 

	
 
			case TBSE_SPACERPANEL: {
 
				int height = r.bottom - r.top;
 
				if (height > 2 * FONT_HEIGHT_NORMAL) {
 
					DrawString(r.left, r.right, (height + 1) / 2 - FONT_HEIGHT_NORMAL, STR_SCENEDIT_TOOLBAR_OPENTTD, TC_FROMSTRING, SA_CENTER);
 
					DrawString(r.left, r.right, (height + 1) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_CENTER);
 
					DrawString(r.left, r.right, (height + 1) / 2 - FONT_HEIGHT_NORMAL, STR_SCENEDIT_TOOLBAR_OPENTTD, TC_FROMSTRING, SA_HOR_CENTER);
 
					DrawString(r.left, r.right, (height + 1) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
 
				} else {
 
					DrawString(r.left, r.right, (height - FONT_HEIGHT_NORMAL) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_CENTER);
 
					DrawString(r.left, r.right, (height - FONT_HEIGHT_NORMAL) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
 
				}
 
			} break;
 
		}
 
	}
 

	
 
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
 
	{
 
		switch (widget) {
 
			case TBSE_SPACERPANEL:
 
				size->width = max(GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_OPENTTD).width, GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR).width) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
 
				break;
 

	
src/vehicle_gui.cpp
Show inline comments
 
@@ -2116,25 +2116,25 @@ public:
 
					if (v->GetNumOrders() == 0) {
 
						str = STR_VEHICLE_STATUS_NO_ORDERS + _settings_client.gui.vehicle_speed;
 
						SetDParam(0, v->GetDisplaySpeed());
 
					} else {
 
						str = STR_EMPTY;
 
					}
 
					break;
 
			}
 
		}
 

	
 
		/* draw the flag plus orders */
 
		DrawSprite(v->vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP);
 
		DrawString(r.left + WD_FRAMERECT_LEFT + 6, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_FROMSTRING, SA_CENTER);
 
		DrawString(r.left + WD_FRAMERECT_LEFT + 6, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_FROMSTRING, SA_HOR_CENTER);
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget, int click_count)
 
	{
 
		const Vehicle *v = Vehicle::Get(this->window_number);
 

	
 
		switch (widget) {
 
			case VVW_WIDGET_START_STOP_VEH: // start stop
 
				if (_ctrl_pressed) {
 
					/* Scroll to current order destination */
 
					TileIndex tile = v->current_order.GetLocation(v);
 
					if (tile != INVALID_TILE) ScrollMainWindowToTile(tile);
src/viewport.cpp
Show inline comments
 
@@ -1354,25 +1354,25 @@ static void ViewportDrawStrings(DrawPixe
 
			}
 

	
 
			/* Draw the rectangle if 'tranparent station signs' is off,
 
			 * or if we are drawing a general text sign (STR_WHITE_SIGN) */
 
			if (!IsTransparencySet(TO_SIGNS) || ss->string == STR_WHITE_SIGN) {
 
				DrawFrameRect(
 
					x, y, x + w, y + h, ss->colour,
 
					IsTransparencySet(TO_SIGNS) ? FR_TRANSPARENT : FR_NONE
 
				);
 
			}
 
		}
 

	
 
		DrawString(x + VPSM_LEFT, x + w - 1 - VPSM_RIGHT, y + VPSM_TOP, ss->string, colour, SA_CENTER);
 
		DrawString(x + VPSM_LEFT, x + w - 1 - VPSM_RIGHT, y + VPSM_TOP, ss->string, colour, SA_HOR_CENTER);
 
	}
 
}
 

	
 
void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom)
 
{
 
	DrawPixelInfo *old_dpi = _cur_dpi;
 
	_cur_dpi = &_vd.dpi;
 

	
 
	_vd.dpi.zoom = vp->zoom;
 
	int mask = ScaleByZoom(-1, vp->zoom);
 

	
 
	_vd.combine_sprites = SPRITE_COMBINE_NONE;
src/widget.cpp
Show inline comments
 
@@ -250,25 +250,25 @@ static inline void DrawImageButtons(cons
 
 * Draw the label-part of a widget.
 
 * @param r       Rectangle of the label background.
 
 * @param type    Widget type (#WWT_TEXTBTN, #WWT_TEXTBTN_2, or #WWT_LABEL).
 
 * @param clicked Label is rendered lowered.
 
 * @param str     Text to draw.
 
 */
 
static inline void DrawLabel(const Rect &r, WidgetType type, bool clicked, StringID str)
 
{
 
	if (str == STR_NULL) return;
 
	if ((type & WWT_MASK) == WWT_TEXTBTN_2 && clicked) str++;
 
	Dimension d = GetStringBoundingBox(str);
 
	int offset = max(0, ((int)(r.bottom - r.top + 1) - (int)d.height) / 2); // Offset for rendering the text vertically centered
 
	DrawString(r.left + clicked, r.right + clicked, r.top + offset + clicked, str, TC_FROMSTRING, SA_CENTER);
 
	DrawString(r.left + clicked, r.right + clicked, r.top + offset + clicked, str, TC_FROMSTRING, SA_HOR_CENTER);
 
}
 

	
 
/**
 
 * Draw text.
 
 * @param r      Rectangle of the background.
 
 * @param colour Colour of the text.
 
 * @param str    Text to draw.
 
 */
 
static inline void DrawText(const Rect &r, TextColour colour, StringID str)
 
{
 
	Dimension d = GetStringBoundingBox(str);
 
	int offset = max(0, ((int)(r.bottom - r.top + 1) - (int)d.height) / 2); // Offset for rendering the text vertically centered
 
@@ -337,28 +337,28 @@ static inline void DrawMatrix(const Rect
 
 * Draw a vertical scrollbar.
 
 * @param r            Rectangle of the scrollbar widget.
 
 * @param colour       Colour of the scrollbar widget.
 
 * @param up_clicked   Up-arrow is clicked.
 
 * @param bar_dragged  Bar is dragged.
 
 * @param down_clicked Down-arrow is clicked.
 
 * @param scrollbar    Scrollbar size, offset, and capacity information.
 
 */
 
static inline void DrawVerticalScrollbar(const Rect &r, Colours colour, bool up_clicked, bool bar_dragged, bool down_clicked, const Scrollbar *scrollbar)
 
{
 
	/* draw up/down buttons */
 
	DrawFrameRect(r.left, r.top, r.right, r.top + 9, colour, (up_clicked) ? FR_LOWERED : FR_NONE);
 
	DrawString(r.left + up_clicked, r.right + up_clicked, r.top + up_clicked, UPARROW, TC_BLACK, SA_CENTER);
 
	DrawString(r.left + up_clicked, r.right + up_clicked, r.top + up_clicked, UPARROW, TC_BLACK, SA_HOR_CENTER);
 

	
 
	DrawFrameRect(r.left, r.bottom - 9, r.right, r.bottom, colour, (down_clicked) ? FR_LOWERED : FR_NONE);
 
	DrawString(r.left + down_clicked, r.right + down_clicked, r.bottom - 9 + down_clicked, DOWNARROW, TC_BLACK, SA_CENTER);
 
	DrawString(r.left + down_clicked, r.right + down_clicked, r.bottom - 9 + down_clicked, DOWNARROW, TC_BLACK, SA_HOR_CENTER);
 

	
 
	int c1 = _colour_gradient[colour & 0xF][3];
 
	int c2 = _colour_gradient[colour & 0xF][7];
 

	
 
	/* draw "shaded" background */
 
	GfxFillRect(r.left, r.top + 10, r.right, r.bottom - 10, c2);
 
	GfxFillRect(r.left, r.top + 10, r.right, r.bottom - 10, c1, FILLRECT_CHECKER);
 

	
 
	/* draw shaded lines */
 
	GfxFillRect(r.left + 2, r.top + 10, r.left + 2, r.bottom - 10, c1);
 
	GfxFillRect(r.left + 3, r.top + 10, r.left + 3, r.bottom - 10, c2);
 
	GfxFillRect(r.left + 7, r.top + 10, r.left + 7, r.bottom - 10, c1);
 
@@ -507,67 +507,67 @@ static inline void DrawResizeBox(const R
 
}
 

	
 
/**
 
 * Draw a close box.
 
 * @param r      Rectangle of the box.
 
 * @param colour Colour of the close box.
 
 * @param str    Cross to draw (#STR_BLACK_CROSS or #STR_SILVER_CROSS).
 
 */
 
static inline void DrawCloseBox(const Rect &r, Colours colour, StringID str)
 
{
 
	assert(str == STR_BLACK_CROSS || str == STR_SILVER_CROSS); // black or silver cross
 
	DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, FR_NONE);
 
	DrawString(r.left + WD_CLOSEBOX_LEFT, r.right - WD_CLOSEBOX_RIGHT, r.top + WD_CLOSEBOX_TOP, str, TC_FROMSTRING, SA_CENTER);
 
	DrawString(r.left + WD_CLOSEBOX_LEFT, r.right - WD_CLOSEBOX_RIGHT, r.top + WD_CLOSEBOX_TOP, str, TC_FROMSTRING, SA_HOR_CENTER);
 
}
 

	
 
/**
 
 * Draw a caption bar.
 
 * @param r      Rectangle of the bar.
 
 * @param colour Colour of the window.
 
 * @param owner  'Owner' of the window.
 
 * @param str    Text to draw in the bar.
 
 */
 
void DrawCaption(const Rect &r, Colours colour, Owner owner, StringID str)
 
{
 
	DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, FR_BORDERONLY);
 
	DrawFrameRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, colour, (owner == INVALID_OWNER) ? FR_LOWERED | FR_DARKENED : FR_LOWERED | FR_DARKENED | FR_BORDERONLY);
 

	
 
	if (owner != INVALID_OWNER) {
 
		GfxFillRect(r.left + 2, r.top + 2, r.right - 2, r.bottom - 2, _colour_gradient[_company_colours[owner]][4]);
 
	}
 

	
 
	if (str != STR_NULL) DrawString(r.left + WD_CAPTIONTEXT_LEFT, r.right - WD_CAPTIONTEXT_RIGHT, r.top + WD_CAPTIONTEXT_TOP, str, TC_FROMSTRING, SA_CENTER);
 
	if (str != STR_NULL) DrawString(r.left + WD_CAPTIONTEXT_LEFT, r.right - WD_CAPTIONTEXT_RIGHT, r.top + WD_CAPTIONTEXT_TOP, str, TC_FROMSTRING, SA_HOR_CENTER);
 
}
 

	
 
/**
 
 * Draw a button with a dropdown (#WWT_DROPDOWN and #NWID_BUTTON_DROPDOWN).
 
 * @param r                Rectangle containing the widget.
 
 * @param colour           Background colour of the widget.
 
 * @param clicked_button   The button-part is lowered.
 
 * @param clicked_dropdown The drop-down part is lowered.
 
 * @param str              Text of the button.
 
 *
 
 * @note Magic constants are also used in #NWidgetLeaf::ButtonHit.
 
 */
 
static inline void DrawButtonDropdown(const Rect &r, Colours colour, bool clicked_button, bool clicked_dropdown, StringID str)
 
{
 
	if (_dynlang.text_dir == TD_LTR) {
 
		DrawFrameRect(r.left, r.top, r.right - 12, r.bottom, colour, clicked_button ? FR_LOWERED : FR_NONE);
 
		DrawFrameRect(r.right - 11, r.top, r.right, r.bottom, colour, clicked_dropdown ? FR_LOWERED : FR_NONE);
 
		DrawString(r.right - (clicked_dropdown ? 10 : 11), r.right, r.top + (clicked_dropdown ? 2 : 1), DOWNARROW, TC_BLACK, SA_CENTER);
 
		DrawString(r.right - (clicked_dropdown ? 10 : 11), r.right, r.top + (clicked_dropdown ? 2 : 1), DOWNARROW, TC_BLACK, SA_HOR_CENTER);
 
		if (str != STR_NULL) DrawString(r.left + WD_DROPDOWNTEXT_LEFT + clicked_button, r.right - WD_DROPDOWNTEXT_RIGHT + clicked_button, r.top + WD_DROPDOWNTEXT_TOP + clicked_button, str, TC_BLACK);
 
	} else {
 
		DrawFrameRect(r.left + 12, r.top, r.right, r.bottom, colour, clicked_button ? FR_LOWERED : FR_NONE);
 
		DrawFrameRect(r.left, r.top, r.left + 11, r.bottom, colour, clicked_dropdown ? FR_LOWERED : FR_NONE);
 
		DrawString(r.left + clicked_dropdown, r.left + 11, r.top + (clicked_dropdown ? 2 : 1), DOWNARROW, TC_BLACK, SA_CENTER);
 
		DrawString(r.left + clicked_dropdown, r.left + 11, r.top + (clicked_dropdown ? 2 : 1), DOWNARROW, TC_BLACK, SA_HOR_CENTER);
 
		if (str != STR_NULL) DrawString(r.left + WD_DROPDOWNTEXT_RIGHT + clicked_button, r.right - WD_DROPDOWNTEXT_LEFT + clicked_button, r.top + WD_DROPDOWNTEXT_TOP + clicked_button, str, TC_BLACK);
 
	}
 
}
 

	
 
/**
 
 * Draw a dropdown #WWT_DROPDOWN widget.
 
 * @param r       Rectangle containing the widget.
 
 * @param colour  Background colour of the widget.
 
 * @param clicked The widget is lowered.
 
 * @param str     Text of the button.
 
 */
 
static inline void DrawDropdown(const Rect &r, Colours colour, bool clicked, StringID str)
 
@@ -594,25 +594,25 @@ void Window::DrawWidgets() const
 
 */
 
void Window::DrawSortButtonState(int widget, SortButtonState state) const
 
{
 
	if (state == SBS_OFF) return;
 

	
 
	assert(this->nested_array != NULL);
 
	const NWidgetBase *nwid = this->GetWidget<NWidgetBase>(widget);
 

	
 
	int offset = this->IsWidgetLowered(widget) ? 1 : 0;
 
	int base = offset + nwid->pos_x + (_dynlang.text_dir == TD_LTR ? nwid->current_x - WD_SORTBUTTON_ARROW_WIDTH : 0);
 
	int top = nwid->pos_y;
 

	
 
	DrawString(base, base + WD_SORTBUTTON_ARROW_WIDTH, top + 1 + offset, state == SBS_DOWN ? DOWNARROW : UPARROW, TC_BLACK, SA_CENTER);
 
	DrawString(base, base + WD_SORTBUTTON_ARROW_WIDTH, top + 1 + offset, state == SBS_DOWN ? DOWNARROW : UPARROW, TC_BLACK, SA_HOR_CENTER);
 
}
 

	
 

	
 
/**
 
 * @defgroup NestedWidgets Hierarchical widgets
 
 * Hierarchical widgets, also known as nested widgets, are widgets stored in a tree. At the leafs of the tree are (mostly) the 'real' widgets
 
 * visible to the user. At higher levels, widgets get organized in container widgets, until all widgets of the window are merged.
 
 *
 
 * \section nestedwidgetkinds Hierarchical widget kinds
 
 * A leaf widget is one of
 
 * <ul>
 
 * <li> #NWidgetLeaf for widgets visible for the user, or
0 comments (0 inline, 0 general)