Changeset - r16431:ec558deca9d7
[Not reviewed]
src/ai/ai_gui.cpp
Show inline comments
 
@@ -281,25 +281,25 @@ struct AISettingsWindow : public Window 
 
		this->DrawWidgets();
 
	}
 

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

	
 
		AIConfig *config = this->ai_config;
 
		AIConfigItemList::const_iterator it = config->GetConfigList()->begin();
 
		int i = 0;
 
		for (; !this->vscroll->IsVisible(i); i++) it++;
 

	
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		uint buttons_left = rtl ? r.right - 23 : r.left + 4;
 
		uint text_left    = r.left + (rtl ? WD_FRAMERECT_LEFT : 28);
 
		uint text_right   = r.right - (rtl ? 28 : WD_FRAMERECT_RIGHT);
 

	
 

	
 
		int y = r.top;
 
		for (; this->vscroll->IsVisible(i) && it != config->GetConfigList()->end(); i++, it++) {
 
			int current_value = config->GetSetting((*it).name);
 
			bool editable = (_game_mode == GM_MENU) || ((it->flags & AICONFIG_INGAME) != 0);
 

	
 
			StringID str;
 
			TextColour colour;
 
@@ -351,25 +351,25 @@ struct AISettingsWindow : public Window 
 
				const NWidgetBase *wid = this->GetWidget<NWidgetBase>(AIS_WIDGET_BACKGROUND);
 
				int num = (pt.y - wid->pos_y) / this->line_height + this->vscroll->GetPosition();
 
				if (num >= (int)this->ai_config->GetConfigList()->size()) break;
 

	
 
				AIConfigItemList::const_iterator it = this->ai_config->GetConfigList()->begin();
 
				for (int i = 0; i < num; i++) it++;
 
				AIConfigItem config_item = *it;
 
				if (_game_mode != GM_MENU && (config_item.flags & AICONFIG_INGAME) == 0) return;
 

	
 
				bool bool_item = (config_item.flags & AICONFIG_BOOLEAN) != 0;
 

	
 
				int x = pt.x - wid->pos_x;
 
				if (_dynlang.text_dir == TD_RTL) x = wid->current_x - x;
 
				if (_current_text_dir == TD_RTL) x = wid->current_x - x;
 
				x -= 4;
 
				/* One of the arrows is clicked (or green/red rect in case of bool value) */
 
				if (IsInsideMM(x, 0, 21)) {
 
					int new_val = this->ai_config->GetSetting(config_item.name);
 
					if (bool_item) {
 
						new_val = !new_val;
 
					} else if (x >= 10) {
 
						/* Increase button clicked */
 
						new_val += config_item.step_size;
 
						if (new_val > config_item.max_value) new_val = config_item.max_value;
 
						this->clicked_increase = true;
 
					} else {
src/aircraft_gui.cpp
Show inline comments
 
@@ -69,25 +69,25 @@ void DrawAircraftDetails(const Aircraft 
 

	
 

	
 
/**
 
 * Draws an image of an aircraft
 
 * @param v         Front vehicle
 
 * @param left      The minimum horizontal position
 
 * @param right     The maximum horizontal position
 
 * @param y         Vertical position to draw at
 
 * @param selection Selected vehicle to draw a frame around
 
 */
 
void DrawAircraftImage(const Vehicle *v, int left, int right, int y, VehicleID selection)
 
{
 
	bool rtl = _dynlang.text_dir == TD_RTL;
 
	bool rtl = _current_text_dir == TD_RTL;
 

	
 
	SpriteID sprite = v->GetImage(rtl ? DIR_E : DIR_W);
 
	const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
 

	
 
	int x = rtl ? right - real_sprite->width - real_sprite->x_offs : left - real_sprite->x_offs;
 
	bool helicopter = v->subtype == AIR_HELICOPTER;
 

	
 
	PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
 
	DrawSprite(sprite, pal, x, y + 10);
 
	if (helicopter) {
 
		const Aircraft *a = Aircraft::From(v);
 
		SpriteID rotor_sprite = GetCustomRotorSprite(a, true);
src/build_vehicle_gui.cpp
Show inline comments
 
@@ -833,25 +833,25 @@ int DrawVehiclePurchaseInfo(int left, in
 
 * @param selected_group the group to list the engines of
 
 */
 
void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group)
 
{
 
	static const int sprite_widths[]  = { 60, 60, 76, 67 };
 
	static const int sprite_y_offsets[] = { -1, -1, -2, -2 };
 

	
 
	/* Obligatory sanity checks! */
 
	assert((uint)type < lengthof(sprite_widths));
 
	assert_compile(lengthof(sprite_y_offsets) == lengthof(sprite_widths));
 
	assert(max <= eng_list->Length());
 

	
 
	bool rtl = _dynlang.text_dir == TD_RTL;
 
	bool rtl = _current_text_dir == TD_RTL;
 
	int step_size = GetEngineListHeight(type);
 
	int sprite_width = sprite_widths[type];
 

	
 
	int sprite_x        = (rtl ? r - sprite_width / 2 : l + sprite_width / 2) - 1;
 
	int sprite_y_offset = sprite_y_offsets[type] + step_size / 2;
 

	
 
	int text_left  = l + (rtl ? WD_FRAMERECT_LEFT : sprite_width);
 
	int text_right = r - (rtl ? sprite_width : WD_FRAMERECT_RIGHT);
 

	
 
	int normal_text_y_offset = (step_size - FONT_HEIGHT_NORMAL) / 2;
 
	int small_text_y_offset  = step_size - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1;
 

	
src/cheat_gui.cpp
Show inline comments
 
@@ -154,25 +154,25 @@ struct CheatWindow : Window {
 
	CheatWindow(const WindowDesc *desc) : Window()
 
	{
 
		this->InitNested(desc);
 
	}
 

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

	
 
		int y = r.top + WD_FRAMERECT_TOP + this->header_height;
 
		DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP, y, STR_CHEATS_WARNING, TC_FROMSTRING, SA_CENTER);
 

	
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		uint box_left    = rtl ? r.right - 12 : r.left + 5;
 
		uint button_left = rtl ? r.right - 40 : r.left + 20;
 
		uint text_left   = r.left + (rtl ? WD_FRAMERECT_LEFT: 50);
 
		uint text_right  = r.right - (rtl ? 50 : WD_FRAMERECT_RIGHT);
 

	
 
		for (int i = 0; i != lengthof(_cheats_ui); i++) {
 
			const CheatEntry *ce = &_cheats_ui[i];
 

	
 
			DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, box_left, y + 2);
 

	
 
			switch (ce->type) {
 
				case SLE_BOOL: {
 
@@ -271,25 +271,25 @@ struct CheatWindow : Window {
 
	}
 

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

	
 
	virtual void OnClick(Point pt, int widget, int click_count)
 
	{
 
		const NWidgetBase *wid = this->GetWidget<NWidgetBase>(CW_PANEL);
 
		uint btn = (pt.y - wid->pos_y - WD_FRAMERECT_TOP - this->header_height) / (FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL);
 
		uint x = pt.x - wid->pos_x;
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		if (rtl) x = wid->current_x - x;
 

	
 
		/* Not clicking a button? */
 
		if (!IsInsideMM(x, 20, 40) || btn >= lengthof(_cheats_ui)) return;
 

	
 
		const CheatEntry *ce = &_cheats_ui[btn];
 
		int value = (int32)ReadValue(ce->variable, ce->type);
 
		int oldvalue = value;
 

	
 
		*ce->been_used = true;
 

	
 
		switch (ce->type) {
src/company_gui.cpp
Show inline comments
 
@@ -538,25 +538,25 @@ public:
 
	uint Height(uint width) const
 
	{
 
		return max(FONT_HEIGHT_NORMAL, (byte)14);
 
	}
 

	
 
	bool Selectable() const
 
	{
 
		return true;
 
	}
 

	
 
	void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
 
	{
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		DrawSprite(SPR_VEH_BUS_SIDE_VIEW, PALETTE_RECOLOUR_START + this->result, rtl ? right - 16 : left + 16, top + 7);
 
		DrawString(rtl ? left + 2 : left + 32, rtl ? right - 32 : right - 2, top + max(0, 13 - FONT_HEIGHT_NORMAL), this->String(), sel ? TC_WHITE : TC_BLACK);
 
	}
 
};
 

	
 
/** Widgets of the select company livery window. */
 
enum SelectCompanyLiveryWindowWidgets {
 
	SCLW_WIDGET_CAPTION,
 
	SCLW_WIDGET_CLASS_GENERAL,
 
	SCLW_WIDGET_CLASS_RAIL,
 
	SCLW_WIDGET_CLASS_ROAD,
 
	SCLW_WIDGET_CLASS_SHIP,
 
@@ -678,25 +678,25 @@ public:
 
					if (scheme == LS_END) scheme = LS_DEFAULT;
 
				}
 
				SetDParam(0, STR_COLOUR_DARK_BLUE + ((widget == SCLW_WIDGET_PRI_COL_DROPDOWN) ? c->livery[scheme].colour1 : c->livery[scheme].colour2));
 
				break;
 
			}
 
		}
 
	}
 

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

	
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 

	
 
		/* Horizontal coordinates of scheme name column. */
 
		const NWidgetBase *nwi = this->GetWidget<NWidgetBase>(SCLW_WIDGET_SPACER_DROPDOWN);
 
		int sch_left = nwi->pos_x;
 
		int sch_right = sch_left + nwi->current_x - 1;
 
		/* Horizontal coordinates of first dropdown. */
 
		nwi = this->GetWidget<NWidgetBase>(SCLW_WIDGET_PRI_COL_DROPDOWN);
 
		int pri_left = nwi->pos_x;
 
		int pri_right = pri_left + nwi->current_x - 1;
 
		/* Horizontal coordinates of second dropdown. */
 
		nwi = this->GetWidget<NWidgetBase>(SCLW_WIDGET_SEC_COL_DROPDOWN);
 
		int sec_left = nwi->pos_x;
 
@@ -767,25 +767,25 @@ public:
 

	
 
			case SCLW_WIDGET_MATRIX: {
 
				const NWidgetBase *wid = this->GetWidget<NWidgetBase>(SCLW_WIDGET_MATRIX);
 
				LiveryScheme j = (LiveryScheme)((pt.y - wid->pos_y) / (4 + FONT_HEIGHT_NORMAL));
 

	
 
				for (LiveryScheme scheme = LS_BEGIN; scheme <= j; scheme++) {
 
					if (_livery_class[scheme] != this->livery_class || !HasBit(_loaded_newgrf_features.used_liveries, scheme)) j++;
 
					if (scheme >= LS_END) return;
 
				}
 
				if (j >= LS_END) return;
 

	
 
				/* If clicking on the left edge, toggle using the livery */
 
				if (_dynlang.text_dir == TD_RTL ? pt.x - wid->pos_x > wid->current_x - TEXT_INDENT : pt.x - wid->pos_x < TEXT_INDENT) {
 
				if (_current_text_dir == TD_RTL ? pt.x - wid->pos_x > wid->current_x - TEXT_INDENT : pt.x - wid->pos_x < TEXT_INDENT) {
 
					DoCommandP(0, j | (2 << 8), !Company::Get((CompanyID)this->window_number)->livery[j].in_use, CMD_SET_COMPANY_COLOUR);
 
				}
 

	
 
				if (_ctrl_pressed) {
 
					ToggleBit(this->sel, j);
 
				} else {
 
					this->sel = 1 << j;
 
				}
 
				this->SetDirty();
 
				break;
 
			}
 
		}
src/depot_gui.cpp
Show inline comments
 
@@ -264,25 +264,25 @@ struct DepotWindow : Window {
 
	/**
 
	 * Draw a vehicle in the depot window in the box with the top left corner at x,y.
 
	 * @param v     Vehicle to draw.
 
	 * @param left  Left side of the box to draw in.
 
	 * @param right Right side of the box to draw in.
 
	 * @param y     Top of the box to draw in.
 
	 */
 
	void DrawVehicleInDepot(const Vehicle *v, int left, int right, int y) const
 
	{
 
		bool free_wagon = false;
 
		int sprite_y = y + (this->resize.step_height - GetVehicleHeight(v->type)) / 2;
 

	
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		int image_left  = rtl ? left  + this->count_width  : left  + this->header_width;
 
		int image_right = rtl ? right - this->header_width : right - this->count_width;
 

	
 
		switch (v->type) {
 
			case VEH_TRAIN: {
 
				const Train *u = Train::From(v);
 
				free_wagon = u->IsFreeWagon();
 

	
 
				uint x_space = free_wagon ? TRAININFO_DEFAULT_VEHICLE_WIDTH : 0;
 
				DrawTrainImage(u, image_left + (rtl ? 0 : x_space), image_right - (rtl ? x_space : 0), sprite_y - 1,
 
						this->sel, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over);
 

	
 
@@ -322,25 +322,25 @@ struct DepotWindow : Window {
 
		} else {
 
			DrawSprite((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, rtl ? right - this->flag_width : left + WD_FRAMERECT_LEFT, y + diff_y);
 

	
 
			SetDParam(0, v->unitnumber);
 
			DrawString(text_left, text_right, y + 2, (uint16)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? STR_BLACK_COMMA : STR_RED_COMMA);
 
		}
 
	}
 

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

	
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 

	
 
		/* Set the row and number of boxes in each row based on the number of boxes drawn in the matrix */
 
		uint16 mat_data = this->GetWidget<NWidgetCore>(DEPOT_WIDGET_MATRIX)->widget_data;
 
		uint16 rows_in_display   = GB(mat_data, MAT_ROW_START, MAT_ROW_BITS);
 
		uint16 boxes_in_each_row = GB(mat_data, MAT_COL_START, MAT_COL_BITS);
 

	
 
		uint16 num = this->vscroll->GetPosition() * boxes_in_each_row;
 
		int maxval = min(this->vehicle_list.Length(), num + (rows_in_display * boxes_in_each_row));
 
		int y;
 
		for (y = r.top + 1; num < maxval; y += this->resize.step_height) { // Draw the rows
 
			for (byte i = 0; i < boxes_in_each_row && num < maxval; i++, num++) {
 
				/* Draw all vehicles in the current row */
 
@@ -380,25 +380,25 @@ struct DepotWindow : Window {
 

	
 
	enum DepotGUIAction {
 
		MODE_ERROR,
 
		MODE_DRAG_VEHICLE,
 
		MODE_SHOW_VEHICLE,
 
		MODE_START_STOP,
 
	};
 

	
 
	DepotGUIAction GetVehicleFromDepotWndPt(int x, int y, const Vehicle **veh, GetDepotVehiclePtData *d) const
 
	{
 
		const NWidgetCore *matrix_widget = this->GetWidget<NWidgetCore>(DEPOT_WIDGET_MATRIX);
 
		/* In case of RTL the widgets are swapped as a whole */
 
		if (_dynlang.text_dir == TD_RTL) x = matrix_widget->current_x - x;
 
		if (_current_text_dir == TD_RTL) x = matrix_widget->current_x - x;
 

	
 
		uint xt = 0, xm = 0, ym = 0;
 
		if (this->type == VEH_TRAIN) {
 
			xm = x;
 
		} else {
 
			xt = x / this->resize.step_width;
 
			xm = x % this->resize.step_width;
 
			if (xt >= this->num_columns) return MODE_ERROR;
 
		}
 
		ym = y % this->resize.step_height;
 

	
 
		uint row = y / this->resize.step_height;
src/gfx.cpp
Show inline comments
 
@@ -337,25 +337,25 @@ static UChar *HandleBiDiAndArabicShapes(
 

	
 
	UChar *t = buffer;
 
	size_t length = 0;
 
	while (*t != '\0' && length < lengthof(input_output) - 1) {
 
		input_output[length++] = *t++;
 
	}
 
	input_output[length] = 0;
 

	
 
	UErrorCode err = U_ZERO_ERROR;
 
	UBiDi *para = ubidi_openSized((int32_t)length, 0, &err);
 
	if (para == NULL) return buffer;
 

	
 
	ubidi_setPara(para, input_output, (int32_t)length, _dynlang.text_dir == TD_RTL ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR, NULL, &err);
 
	ubidi_setPara(para, input_output, (int32_t)length, _current_text_dir == TD_RTL ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR, NULL, &err);
 
	ubidi_writeReordered(para, intermediate, (int32_t)length, UBIDI_REMOVE_BIDI_CONTROLS, &err);
 
	length = u_shapeArabic(intermediate, (int32_t)length, input_output, lengthof(input_output), U_SHAPE_TEXT_DIRECTION_VISUAL_LTR | U_SHAPE_LETTERS_SHAPE, &err);
 
	ubidi_close(para);
 

	
 
	if (U_FAILURE(err)) return buffer;
 

	
 
	input_output[length] = '\0';
 
	return input_output;
 
}
 
#endif /* WITH_ICU */
 

	
 

	
 
@@ -546,25 +546,25 @@ 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_STRIP) && (align & SA_HOR_MASK) != SA_HOR_CENTER) align ^= SA_RIGHT;
 
	if (!(align & SA_FORCE) && _current_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++;
 
		}
 

	
src/graph_gui.cpp
Show inline comments
 
@@ -65,25 +65,25 @@ struct GraphLegendWindow : Window {
 
	{
 
		this->DrawWidgets();
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		if (!IsInsideMM(widget, GLW_FIRST_COMPANY, MAX_COMPANIES + GLW_FIRST_COMPANY)) return;
 

	
 
		CompanyID cid = (CompanyID)(widget - GLW_FIRST_COMPANY);
 

	
 
		if (!Company::IsValidID(cid)) return;
 

	
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 

	
 
		DrawCompanyIcon(cid, rtl ? r.right - 16 : r.left + 2, r.top + 2 + (FONT_HEIGHT_NORMAL - 10) / 2);
 

	
 
		SetDParam(0, cid);
 
		SetDParam(1, cid);
 
		DrawString(r.left + (rtl ? WD_FRAMERECT_LEFT : 19), r.right - (rtl ? 19 : WD_FRAMERECT_RIGHT), r.top + WD_FRAMERECT_TOP, STR_COMPANY_NAME_COMPANY_NUM, HasBit(_legend_excluded_companies, cid) ? TC_BLACK : TC_WHITE);
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget, int click_count)
 
	{
 
		if (!IsInsideMM(widget, GLW_FIRST_COMPANY, MAX_COMPANIES + GLW_FIRST_COMPANY)) return;
 

	
 
@@ -955,25 +955,25 @@ struct PaymentRatesGraphWindow : BaseGra
 
		d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
 
		*size = maxdim(d, *size);
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		if (widget < CPW_CARGO_FIRST) {
 
			BaseGraphWindow::DrawWidget(r, widget);
 
			return;
 
		}
 

	
 
		const CargoSpec *cs = _sorted_cargo_specs[widget - CPW_CARGO_FIRST];
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 

	
 
		/* Since the buttons have no text, no images,
 
		 * both the text and the coloured box have to be manually painted.
 
		 * clk_dif will move one pixel down and one pixel to the right
 
		 * when the button is clicked */
 
		byte clk_dif = this->IsWidgetLowered(widget) ? 1 : 0;
 
		int x = r.left + WD_FRAMERECT_LEFT;
 
		int y = r.top;
 

	
 
		int rect_x = clk_dif + (rtl ? r.right - 12 : r.left + WD_FRAMERECT_LEFT);
 

	
 
		GfxFillRect(rect_x, y + clk_dif, rect_x + 8, y + 5 + clk_dif, 0);
 
@@ -1187,25 +1187,25 @@ public:
 
		this->companies.Sort(&PerformanceSorter);
 

	
 
		this->DrawWidgets();
 
	}
 

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

	
 
		uint y = r.top + WD_FRAMERECT_TOP;
 
		int icon_y_offset = 1 + (FONT_HEIGHT_NORMAL - 10) / 2;
 

	
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		uint ordinal_left  = rtl ? r.right - WD_FRAMERECT_LEFT - this->ordinal_width : r.left + WD_FRAMERECT_LEFT;
 
		uint ordinal_right = rtl ? r.right - WD_FRAMERECT_LEFT : r.left + WD_FRAMERECT_LEFT + this->ordinal_width;
 
		uint icon_left     = r.left + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT + (rtl ? this->text_width : this->ordinal_width);
 
		uint text_left     = rtl ? r.left + WD_FRAMERECT_LEFT : r.right - WD_FRAMERECT_LEFT - this->text_width;
 
		uint text_right    = rtl ? r.left + WD_FRAMERECT_LEFT + this->text_width : r.right - WD_FRAMERECT_LEFT;
 

	
 
		for (uint i = 0; i != this->companies.Length(); i++) {
 
			const Company *c = this->companies[i];
 
			DrawString(ordinal_left, ordinal_right, y, i + STR_ORDINAL_NUMBER_1ST, i == 0 ? TC_WHITE : TC_YELLOW);
 

	
 
			DrawCompanyIcon(c->index, icon_left, y + icon_y_offset);
 

	
 
@@ -1372,25 +1372,25 @@ struct PerformanceRatingDetailWindow : W
 
				 * least 999 999 M which roughly is equally long. Furthermore if the
 
				 * exchange rate is that high, 999 999 k is usually not enough anymore
 
				 * to show the different currency numbers. */
 
				if (_currency->rate < 1000) max /= _currency->rate;
 
				SetDParam(0, max);
 
				SetDParam(1, max);
 
				uint score_detail_width = GetStringBoundingBox(STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY).width;
 

	
 
				size->width = 7 + score_info_width + 5 + this->bar_width + 5 + score_detail_width + 7;
 
				uint left  = 7;
 
				uint right = size->width - 7;
 

	
 
				bool rtl = _dynlang.text_dir == TD_RTL;
 
				bool rtl = _current_text_dir == TD_RTL;
 
				this->score_info_left  = rtl ? right - score_info_width : left;
 
				this->score_info_right = rtl ? right : left + score_info_width;
 

	
 
				this->score_detail_left  = rtl ? left : right - score_detail_width;
 
				this->score_detail_right = rtl ? left + score_detail_width : right;
 

	
 
				this->bar_left  = left + (rtl ? score_detail_width : score_info_width) + 5;
 
				this->bar_right = this->bar_left + this->bar_width;
 
				break;
 
		}
 
	}
 

	
 
@@ -1435,25 +1435,25 @@ struct PerformanceRatingDetailWindow : W
 

	
 
		uint bar_top  = r.top + WD_MATRIX_TOP;
 
		uint text_top = bar_top + 2;
 

	
 
		DrawString(this->score_info_left, this->score_info_right, text_top, STR_PERFORMANCE_DETAIL_VEHICLES + score_type);
 

	
 
		/* Draw the score */
 
		SetDParam(0, score);
 
		DrawString(this->score_info_left, this->score_info_right, text_top, STR_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT);
 

	
 
		/* Calculate the %-bar */
 
		uint x = Clamp(val, 0, needed) * this->bar_width / needed;
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		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);
src/industry_gui.cpp
Show inline comments
 
@@ -1645,40 +1645,40 @@ struct CargoesField {
 
				GfxDrawLine(xpos,  ypos1, xpos2, ypos1, INDUSTRY_LINE_COLOUR);
 
				GfxDrawLine(xpos,  ypos1, xpos,  ypos2, INDUSTRY_LINE_COLOUR);
 
				GfxDrawLine(xpos,  ypos2, xpos2, ypos2, INDUSTRY_LINE_COLOUR);
 
				GfxDrawLine(xpos2, ypos1, xpos2, ypos2, INDUSTRY_LINE_COLOUR);
 
				ypos += (normal_height - FONT_HEIGHT_NORMAL) / 2;
 
				if (this->u.industry.ind_type < NUM_INDUSTRYTYPES) {
 
					const IndustrySpec *indsp = GetIndustrySpec(this->u.industry.ind_type);
 
					SetDParam(0, indsp->name);
 
					DrawString(xpos, xpos2, ypos, STR_JUST_STRING, TC_WHITE, SA_HOR_CENTER);
 

	
 
					/* Draw the industry legend. */
 
					int blob_left, blob_right;
 
					if (_dynlang.text_dir == TD_RTL) {
 
					if (_current_text_dir == TD_RTL) {
 
						blob_right = xpos2 - BLOB_DISTANCE;
 
						blob_left  = blob_right - BLOB_WIDTH;
 
					} else {
 
						blob_left  = xpos + BLOB_DISTANCE;
 
						blob_right = blob_left + BLOB_WIDTH;
 
					}
 
					GfxFillRect(blob_left,     ypos2 - BLOB_DISTANCE - BLOB_HEIGHT,     blob_right,     ypos2 - BLOB_DISTANCE,     0); // Border
 
					GfxFillRect(blob_left + 1, ypos2 - BLOB_DISTANCE - BLOB_HEIGHT + 1, blob_right - 1, ypos2 - BLOB_DISTANCE - 1, indsp->map_colour);
 
				} else {
 
					DrawString(xpos, xpos2, ypos, STR_INDUSTRY_CARGOES_HOUSES, TC_FROMSTRING, SA_HOR_CENTER);
 
				}
 

	
 
				/* Draw the other_produced/other_accepted cargoes. */
 
				const CargoID *other_right, *other_left;
 
				if (_dynlang.text_dir == TD_RTL) {
 
				if (_current_text_dir == TD_RTL) {
 
					other_right = this->u.industry.other_accepted;
 
					other_left  = this->u.industry.other_produced;
 
				} else {
 
					other_right = this->u.industry.other_produced;
 
					other_left  = this->u.industry.other_accepted;
 
				}
 
				ypos1 += VERT_CARGO_EDGE;
 
				for (uint i = 0; i < MAX_CARGOES; i++) {
 
					if (other_right[i] != INVALID_CARGO) {
 
						const CargoSpec *csp = CargoSpec::Get(other_right[i]);
 
						int xp = xpos + industry_width + CARGO_STUB_WIDTH;
 
						DrawHorConnection(xpos + industry_width, xp - 1, ypos1, csp);
 
@@ -1704,25 +1704,25 @@ struct CargoesField {
 
					if (this->u.cargo.top_end) GfxDrawLine(colpos, top - 1, colpos + HOR_CARGO_WIDTH - 1, top - 1, CARGO_LINE_COLOUR);
 
					if (this->u.cargo.bottom_end) GfxDrawLine(colpos, bot + 1, colpos + HOR_CARGO_WIDTH - 1, bot + 1, CARGO_LINE_COLOUR);
 
					GfxDrawLine(colpos, top, colpos, bot, CARGO_LINE_COLOUR);
 
					colpos++;
 
					const CargoSpec *csp = CargoSpec::Get(this->u.cargo.vertical_cargoes[i]);
 
					GfxFillRect(colpos, top, colpos + HOR_CARGO_WIDTH - 2, bot, csp->legend_colour, FILLRECT_OPAQUE);
 
					colpos += HOR_CARGO_WIDTH - 2;
 
					GfxDrawLine(colpos, top, colpos, bot, CARGO_LINE_COLOUR);
 
					colpos += 1 + HOR_CARGO_SPACE;
 
				}
 

	
 
				const CargoID *hor_left, *hor_right;
 
				if (_dynlang.text_dir == TD_RTL) {
 
				if (_current_text_dir == TD_RTL) {
 
					hor_left  = this->u.cargo.cust_cargoes;
 
					hor_right = this->u.cargo.supp_cargoes;
 
				} else {
 
					hor_left  = this->u.cargo.supp_cargoes;
 
					hor_right = this->u.cargo.cust_cargoes;
 
				}
 
				ypos += VERT_CARGO_EDGE + VERT_INTER_INDUSTRY_SPACE / 2;
 
				for (uint i = 0; i < MAX_CARGOES; i++) {
 
					if (hor_left[i] != INVALID_CARGO) {
 
						int col = hor_left[i];
 
						int dx = 0;
 
						const CargoSpec *csp = CargoSpec::Get(this->u.cargo.vertical_cargoes[col]);
 
@@ -2425,25 +2425,25 @@ struct IndustryCargoesWindow : public Wi
 

	
 
		int left_pos = WD_FRAMERECT_LEFT;
 
		if (this->ind_cargo >= NUM_INDUSTRYTYPES) left_pos += (CargoesField::industry_width + CargoesField::CARGO_FIELD_WIDTH) / 2;
 
		int last_column = (this->ind_cargo < NUM_INDUSTRYTYPES) ? 4 : 2;
 

	
 
		const NWidgetBase *nwp = this->GetWidget<NWidgetBase>(ICW_PANEL);
 
		int vpos = -this->vscroll->GetPosition() * nwp->resize_y;
 
		for (uint i = 0; i < this->fields.Length(); i++) {
 
			int row_height = (i == 0) ? CargoesField::small_height : CargoesField::normal_height;
 
			if (vpos + row_height >= 0) {
 
				int xpos = left_pos;
 
				int col, dir;
 
				if (_dynlang.text_dir == TD_RTL) {
 
				if (_current_text_dir == TD_RTL) {
 
					col = last_column;
 
					dir = -1;
 
				} else {
 
					col = 0;
 
					dir = 1;
 
				}
 
				while (col >= 0 && col <= last_column) {
 
					this->fields[i].columns[col].Draw(xpos, vpos);
 
					xpos += (col & 1) ? CargoesField::CARGO_FIELD_WIDTH : CargoesField::industry_width;
 
					col += dir;
 
				}
 
			}
 
@@ -2481,25 +2481,25 @@ struct IndustryCargoesWindow : public Wi
 
		for (column = 0; column <= 5; column++) {
 
			int width = (column & 1) ? CargoesField::CARGO_FIELD_WIDTH : CargoesField::industry_width;
 
			if (pt.x < xpos + width) break;
 
			xpos += width;
 
		}
 
		int num_columns = (this->ind_cargo < NUM_INDUSTRYTYPES) ? 4 : 2;
 
		if (column > num_columns) return false;
 
		xpos = pt.x - xpos;
 

	
 
		/* Return both positions, compensating for RTL languages (which works due to the equal symmetry in both displays). */
 
		fieldxy->y = row;
 
		xy->y = vpos;
 
		if (_dynlang.text_dir == TD_RTL) {
 
		if (_current_text_dir == TD_RTL) {
 
			fieldxy->x = num_columns - column;
 
			xy->x = ((column & 1) ? CargoesField::CARGO_FIELD_WIDTH : CargoesField::industry_width) - xpos;
 
		} else {
 
			fieldxy->x = column;
 
			xy->x = xpos;
 
		}
 
		return true;
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget, int click_count)
 
	{
 
		switch (widget) {
src/music_gui.cpp
Show inline comments
 
@@ -571,27 +571,27 @@ struct MusicWindow : public Window {
 
				for (uint i = 0; i < NUM_SONGS_AVAILABLE; i++) {
 
					SetDParamStr(0, GetSongName(i));
 
					d = maxdim(d, GetStringBoundingBox(STR_MUSIC_TITLE_NAME));
 
				}
 
				d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
 
				d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
 
				*size = maxdim(*size, d);
 
				break;
 
			}
 

	
 
			/* Hack-ish: set the proper widget data; only needs to be done once
 
			 * per (Re)Init as that's the only time the language changes. */
 
			case MW_PREV: this->GetWidget<NWidgetCore>(MW_PREV)->widget_data = _dynlang.text_dir == TD_RTL ? SPR_IMG_SKIP_TO_NEXT : SPR_IMG_SKIP_TO_PREV; break;
 
			case MW_NEXT: this->GetWidget<NWidgetCore>(MW_NEXT)->widget_data = _dynlang.text_dir == TD_RTL ? SPR_IMG_SKIP_TO_PREV : SPR_IMG_SKIP_TO_NEXT; break;
 
			case MW_PLAY: this->GetWidget<NWidgetCore>(MW_PLAY)->widget_data = _dynlang.text_dir == TD_RTL ? SPR_IMG_PLAY_MUSIC_RTL : SPR_IMG_PLAY_MUSIC; break;
 
			case MW_PREV: this->GetWidget<NWidgetCore>(MW_PREV)->widget_data = _current_text_dir == TD_RTL ? SPR_IMG_SKIP_TO_NEXT : SPR_IMG_SKIP_TO_PREV; break;
 
			case MW_NEXT: this->GetWidget<NWidgetCore>(MW_NEXT)->widget_data = _current_text_dir == TD_RTL ? SPR_IMG_SKIP_TO_PREV : SPR_IMG_SKIP_TO_NEXT; break;
 
			case MW_PLAY: this->GetWidget<NWidgetCore>(MW_PLAY)->widget_data = _current_text_dir == TD_RTL ? SPR_IMG_PLAY_MUSIC_RTL : SPR_IMG_PLAY_MUSIC; break;
 
		}
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		switch (widget) {
 
			case MW_GAUGE:
 
				GfxFillRect(r.left, r.top, r.right, r.bottom, 0);
 

	
 
				for (uint i = 0; i != 8; i++) {
 
					int colour = 0xD0;
 
					if (i > 4) {
 
@@ -622,25 +622,25 @@ struct MusicWindow : public Window {
 
				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_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) {
 
				if (_current_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);
 
				break;
 
			}
 
		}
 
	}
 

	
 
	virtual void OnPaint()
 
	{
 
@@ -675,25 +675,25 @@ struct MusicWindow : public Window {
 
				break;
 

	
 
			case MW_PLAY: // start playing
 
				msf.playing = true;
 
				break;
 

	
 
			case MW_MUSIC_VOL: case MW_EFFECT_VOL: { // volume sliders
 
				int x = pt.x - this->GetWidget<NWidgetBase>(widget)->pos_x;
 

	
 
				byte *vol = (widget == MW_MUSIC_VOL) ? &msf.music_vol : &msf.effect_vol;
 

	
 
				byte new_vol = x * 127 / this->GetWidget<NWidgetBase>(widget)->current_x;
 
				if (_dynlang.text_dir == TD_RTL) new_vol = 127 - new_vol;
 
				if (_current_text_dir == TD_RTL) new_vol = 127 - new_vol;
 
				if (new_vol != *vol) {
 
					*vol = new_vol;
 
					if (widget == MW_MUSIC_VOL) MusicVolumeChanged(new_vol);
 
					this->SetDirty();
 
				}
 

	
 
				_left_button_clicked = false;
 
				break;
 
			}
 

	
 
			case MW_SHUFFLE: // toggle shuffle
 
				msf.shuffle ^= 1;
src/network/network.cpp
Show inline comments
 
@@ -198,25 +198,25 @@ void NetworkTextMessage(NetworkAction ac
 
		default:                            strid = STR_NETWORK_CHAT_ALL; break;
 
	}
 

	
 
	char message[1024];
 
	SetDParamStr(0, name);
 
	SetDParamStr(1, str);
 
	SetDParam(2, data);
 

	
 
	/* All of these strings start with "***". These characters are interpreted as both left-to-right and
 
	 * right-to-left characters depending on the context. As the next text might be an user's name, the
 
	 * user name's characters will influence the direction of the "***" instead of the language setting
 
	 * of the game. Manually set the direction of the "***" by inserting a text-direction marker. */
 
	char *msg_ptr = message + Utf8Encode(message, _dynlang.text_dir == TD_LTR ? CHAR_TD_LRM : CHAR_TD_RLM);
 
	char *msg_ptr = message + Utf8Encode(message, _current_text_dir == TD_LTR ? CHAR_TD_LRM : CHAR_TD_RLM);
 
	GetString(msg_ptr, strid, lastof(message));
 

	
 
	DEBUG(desync, 1, "msg: %08x; %02x; %s", _date, _date_fract, message);
 
	IConsolePrintF(colour, "%s", message);
 
	NetworkAddChatMessage((TextColour)colour, duration, "%s", message);
 
}
 

	
 
/* Calculate the frame-lag of a client */
 
uint NetworkCalculateLag(const NetworkClientSocket *cs)
 
{
 
	int lag = cs->last_frame_server - cs->last_frame;
 
	/* This client has missed his ACK packet after 1 DAY_TICKS..
src/network/network_gui.cpp
Show inline comments
 
@@ -1534,25 +1534,25 @@ struct NetworkLobbyWindow : public Windo
 
		this->SetWidgetDisabledState(NLWW_NEW, gi->companies_on >= gi->companies_max);
 
		/* Cannot spectate if there are too many spectators */
 
		this->SetWidgetDisabledState(NLWW_SPECTATE, gi->spectators_on >= gi->spectators_max);
 

	
 
		this->vscroll->SetCount(gi->companies_on);
 

	
 
		/* Draw window widgets */
 
		this->DrawWidgets();
 
	}
 

	
 
	void DrawMatrix(const Rect &r) const
 
	{
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		uint left = r.left + WD_FRAMERECT_LEFT;
 
		uint right = r.right - WD_FRAMERECT_RIGHT;
 

	
 
		Dimension lock_size = GetSpriteSize(SPR_LOCK);
 
		int lock_width      = lock_size.width;
 
		int lock_y_offset   = (this->resize.step_height - WD_MATRIX_TOP - WD_MATRIX_BOTTOM - lock_size.height) / 2;
 

	
 
		Dimension profit_size = GetSpriteSize(SPR_PROFIT_LOT);
 
		int profit_width      = lock_size.width;
 
		int profit_y_offset   = (this->resize.step_height - WD_MATRIX_TOP - WD_MATRIX_BOTTOM - profit_size.height) / 2;
 

	
 
		uint text_left   = left  + (rtl ? lock_width + profit_width + 4 : 0);
 
@@ -2055,25 +2055,25 @@ struct NetworkClientListWindow : Window 
 
	virtual void OnPaint()
 
	{
 
		/* Check if we need to reset the height */
 
		if (!this->CheckClientListHeight()) return;
 

	
 
		this->DrawWidgets();
 
	}
 

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

	
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		int icon_y_offset = 1 + (FONT_HEIGHT_NORMAL - 10) / 2;
 
		uint y = r.top + WD_FRAMERECT_TOP;
 
		uint left = r.left + WD_FRAMERECT_LEFT;
 
		uint right = r.right - WD_FRAMERECT_RIGHT;
 
		uint type_icon_width = this->server_client_width + this->company_icon_width;
 

	
 

	
 
		uint type_left  = rtl ? right - this->server_client_width : left;
 
		uint type_right = rtl ? right : left + this->server_client_width - 1;
 
		uint icon_left  = rtl ? right - type_icon_width + WD_FRAMERECT_LEFT : left + this->server_client_width;
 
		uint name_left  = rtl ? left : left + type_icon_width;
 
		uint name_right = rtl ? right - type_icon_width : right;
src/newgrf_gui.cpp
Show inline comments
 
@@ -234,25 +234,25 @@ struct NewGRFParametersWindow : public W
 
	{
 
		if (widget == GRFPAR_WIDGET_DESCRIPTION) {
 
			const GRFParameterInfo *par_info = (this->clicked_row < this->grf_config->param_info.Length()) ? this->grf_config->param_info[this->clicked_row] : NULL;
 
			if (par_info == NULL) return;
 
			const char *desc = GetGRFStringFromGRFText(par_info->desc);
 
			if (desc == NULL) return;
 
			DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_TEXTPANEL_TOP, r.bottom - WD_TEXTPANEL_BOTTOM, desc, TC_BLACK);
 
			return;
 
		} else if (widget != GRFPAR_WIDGET_BACKGROUND) {
 
			return;
 
		}
 

	
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		uint buttons_left = rtl ? r.right - 23 : r.left + 4;
 
		uint text_left    = r.left + (rtl ? WD_FRAMERECT_LEFT : 28);
 
		uint text_right   = r.right - (rtl ? 28 : WD_FRAMERECT_RIGHT);
 

	
 
		int y = r.top;
 
		for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) {
 
			GRFParameterInfo *par_info = (i < this->grf_config->param_info.Length()) ? this->grf_config->param_info[i] : NULL;
 
			if (par_info == NULL) par_info = GetDummyParameterInfo(i);
 
			uint32 current_value = par_info->GetValue(this->grf_config);
 
			bool selected = (i == this->clicked_row);
 

	
 
			if (par_info->type == PTYPE_BOOL) {
 
@@ -307,25 +307,25 @@ struct NewGRFParametersWindow : public W
 
			}
 

	
 
			case GRFPAR_WIDGET_BACKGROUND: {
 
				uint num = this->vscroll->GetScrolledRowFromWidget(pt.y, this, GRFPAR_WIDGET_BACKGROUND);
 
				if (num >= this->vscroll->GetCount()) break;
 
				if (this->clicked_row != num) {
 
					DeleteChildWindows(WC_QUERY_STRING);
 
					this->clicked_row = num;
 
				}
 

	
 
				const NWidgetBase *wid = this->GetWidget<NWidgetBase>(GRFPAR_WIDGET_BACKGROUND);
 
				int x = pt.x - wid->pos_x;
 
				if (_dynlang.text_dir == TD_RTL) x = wid->current_x - x;
 
				if (_current_text_dir == TD_RTL) x = wid->current_x - x;
 
				x -= 4;
 

	
 
				GRFParameterInfo *par_info = (num < this->grf_config->param_info.Length()) ? this->grf_config->param_info[num] : NULL;
 
				if (par_info == NULL) par_info = GetDummyParameterInfo(num);
 

	
 
				/* One of the arrows is clicked */
 
				if (IsInsideMM(x, 0, 21)) {
 
					uint32 val = par_info->GetValue(this->grf_config);
 
					if (par_info->type == PTYPE_BOOL) {
 
						val = !val;
 
					} else {
 
						if (x >= 10) {
 
@@ -691,25 +691,25 @@ struct NewGRFWindow : public QueryString
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		switch (widget) {
 
			case SNGRFS_FILE_LIST: {
 
				GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, 0xD7);
 

	
 
				uint step_height = this->GetWidget<NWidgetBase>(SNGRFS_FILE_LIST)->resize_y;
 
				uint y = r.top + WD_FRAMERECT_TOP;
 
				int sprite_offset_y = (step_height - 10) / 2;
 
				int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2;
 

	
 
				bool rtl = _dynlang.text_dir == TD_RTL;
 
				bool rtl = _current_text_dir == TD_RTL;
 
				uint text_left    = rtl ? r.left + WD_FRAMERECT_LEFT : r.left + 25;
 
				uint text_right   = rtl ? r.right - 25 : r.right - WD_FRAMERECT_RIGHT;
 
				uint square_left  = rtl ? r.right - 15 : r.left + 5;
 
				uint warning_left = rtl ? r.right - 30 : r.left + 20;
 

	
 
				int i = 0;
 
				for (const GRFConfig *c = this->actives; c != NULL; c = c->next, i++) {
 
					if (this->vscroll->IsVisible(i)) {
 
						const char *text = c->GetName();
 
						bool h = (this->active_sel == c);
 
						PaletteID pal = this->GetPalette(c);
 

	
src/news_gui.cpp
Show inline comments
 
@@ -985,25 +985,25 @@ struct MessageHistoryWindow : Window {
 
	{
 
		if (widget != MHW_BACKGROUND || _total_news == 0) return;
 

	
 
		/* Find the first news item to display. */
 
		NewsItem *ni = _latest_news;
 
		for (int n = this->vscroll->GetPosition(); n > 0; n--) {
 
			ni = ni->prev;
 
			if (ni == NULL) return;
 
		}
 

	
 
		/* Fill the widget with news items. */
 
		int y = r.top + this->top_spacing;
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		uint date_left  = rtl ? r.right - WD_FRAMERECT_RIGHT - this->date_width : r.left + WD_FRAMERECT_LEFT;
 
		uint date_right = rtl ? r.right - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT + this->date_width;
 
		uint news_left  = rtl ? r.left + WD_FRAMERECT_LEFT : r.left + WD_FRAMERECT_LEFT + this->date_width + WD_FRAMERECT_RIGHT;
 
		uint news_right = rtl ? r.right - WD_FRAMERECT_RIGHT - this->date_width - WD_FRAMERECT_RIGHT : r.right - WD_FRAMERECT_RIGHT;
 
		for (int n = this->vscroll->GetCapacity(); n > 0; n--) {
 
			SetDParam(0, ni->date);
 
			DrawString(date_left, date_right, y, STR_SHORT_DATE);
 

	
 
			DrawNewsString(news_left, news_right, y, TC_WHITE, ni);
 
			y += this->line_height;
 

	
 
			ni = ni->prev;
src/order_gui.cpp
Show inline comments
 
@@ -179,25 +179,25 @@ static int DepotActionStringIndex(const 
 
 * @param v Vehicle the order belongs to
 
 * @param order The order to draw
 
 * @param order_index Index of the order in the orders of the vehicle
 
 * @param y Y position for drawing
 
 * @param selected True, if the order is selected
 
 * @param timetable True, when drawing in the timetable GUI
 
 * @param left Left border for text drawing
 
 * @param middle X position between order index and order text
 
 * @param right Right border for text drawing
 
 */
 
void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int y, bool selected, bool timetable, int left, int middle, int right)
 
{
 
	bool rtl = _dynlang.text_dir == TD_RTL;
 
	bool rtl = _current_text_dir == TD_RTL;
 

	
 
	SpriteID sprite = rtl ? SPR_ARROW_LEFT : SPR_ARROW_RIGHT;
 
	Dimension sprite_size = GetSpriteSize(sprite);
 
	if (v->cur_order_index == order_index) {
 
		DrawSprite(sprite, PAL_NONE, rtl ? right - sprite_size.width : left, y + ((int)FONT_HEIGHT_NORMAL - (int)sprite_size.height) / 2);
 
	}
 

	
 
	SetDParam(0, order_index + 1);
 
	DrawString(left, rtl ? right - sprite_size.width - 3 : middle, y, STR_ORDER_INDEX, selected ? TC_WHITE : TC_BLACK, SA_RIGHT | SA_FORCE);
 

	
 
	SetDParam(5, STR_EMPTY);
 

	
 
@@ -935,25 +935,25 @@ public:
 
	}
 

	
 
	virtual void OnPaint()
 
	{
 
		if (this->vehicle->owner != _local_company) this->selected_order = -1; // Disable selection any selected row at a competitor order window.
 
		this->DrawWidgets();
 
	}
 

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

	
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		SetDParam(0, 99);
 
		int index_column_width = GetStringBoundingBox(STR_ORDER_INDEX).width + GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + 3;
 
		int middle = rtl ? r.right - WD_FRAMETEXT_RIGHT - index_column_width : r.left + WD_FRAMETEXT_LEFT + index_column_width;
 

	
 
		int y = r.top + WD_FRAMERECT_TOP;
 
		int line_height = this->GetWidget<NWidgetBase>(ORDER_WIDGET_ORDER_LIST)->resize_y;
 

	
 
		int i = this->vscroll->GetPosition();
 
		const Order *order = this->vehicle->GetOrder(i);
 
		/* First draw the highlighting underground if it exists. */
 
		if (this->order_over != INVALID_ORDER) {
 
			while (order != NULL) {
src/roadveh_gui.cpp
Show inline comments
 
@@ -122,25 +122,25 @@ void DrawRoadVehDetails(const Vehicle *v
 
}
 

	
 
/**
 
 * Draws an image of a road vehicle chain
 
 * @param v         Front vehicle
 
 * @param left      The minimum horizontal position
 
 * @param right     The maximum horizontal position
 
 * @param y         Vertical position to draw at
 
 * @param selection Selected vehicle to draw a frame around
 
 */
 
void DrawRoadVehImage(const Vehicle *v, int left, int right, int y, VehicleID selection)
 
{
 
	bool rtl = _dynlang.text_dir == TD_RTL;
 
	bool rtl = _current_text_dir == TD_RTL;
 
	Direction dir = rtl ? DIR_E : DIR_W;
 
	const RoadVehicle *u = RoadVehicle::From(v);
 

	
 
	int max_width = right - left + 1;
 
	int spent_width = 0;
 
	int pos = rtl ? right : left;
 

	
 
	for (; u != NULL && spent_width < max_width; u = u->Next()) {
 
		Point offset;
 
		int width = u->GetDisplayImageWidth(&offset);
 

	
 
		PaletteID pal = (u->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(u);
src/settings_gui.cpp
Show inline comments
 
@@ -1037,25 +1037,25 @@ SettingEntry *SettingEntry::FindEntry(ui
 
 * @param right        Right-most x position to draw strings at.
 
 * @param base_y       Upper-most position in window/panel to start drawing \a first_row
 
 * @param first_row    First row number to draw
 
 * @param max_row      Row-number to stop drawing (the row-number of the row below the last row to draw)
 
 * @param cur_row      Current row number (internal variable)
 
 * @param parent_last  Last-field booleans of parent page level (page level \e i sets bit \e i to 1 if it is its last field)
 
 * @return Row number of the next row to draw
 
 */
 
uint SettingEntry::Draw(GameSettings *settings_ptr, int left, int right, int base_y, uint first_row, uint max_row, uint cur_row, uint parent_last)
 
{
 
	if (cur_row >= max_row) return cur_row;
 

	
 
	bool rtl = _dynlang.text_dir == TD_RTL;
 
	bool rtl = _current_text_dir == TD_RTL;
 
	int offset = rtl ? -4 : 4;
 
	int level_width = rtl ? -LEVEL_WIDTH : LEVEL_WIDTH;
 

	
 
	int x = rtl ? right : left;
 
	int y = base_y;
 
	if (cur_row >= first_row) {
 
		int colour = _colour_gradient[COLOUR_ORANGE][4];
 
		y = base_y + (cur_row - first_row) * SETTING_HEIGHT; // Compute correct y start position
 

	
 
		/* Draw vertical for parent nesting levels */
 
		for (uint lvl = 0; lvl < this->level; lvl++) {
 
			if (!HasBit(parent_last, lvl)) GfxDrawLine(x + offset, y, x + offset, y + SETTING_HEIGHT - 1, colour);
 
@@ -1117,25 +1117,25 @@ static const void *ResolveVariableAddres
 
 * @param left         Left-most position in window/panel to start drawing
 
 * @param right        Right-most position in window/panel to draw
 
 * @param y            Upper-most position in window/panel to start drawing
 
 * @param state        State of the left + right arrow buttons to draw for the setting
 
 */
 
void SettingEntry::DrawSetting(GameSettings *settings_ptr, const SettingDesc *sd, int left, int right, int y, int state)
 
{
 
	const SettingDescBase *sdb = &sd->desc;
 
	const void *var = ResolveVariableAddress(settings_ptr, sd);
 
	bool editable = true;
 
	bool disabled = false;
 

	
 
	bool rtl = _dynlang.text_dir == TD_RTL;
 
	bool rtl = _current_text_dir == TD_RTL;
 
	uint buttons_left = rtl ? right - 19 : left;
 
	uint text_left  = left + (rtl ? 0 : 25);
 
	uint text_right = right - (rtl ? 25 : 0);
 
	uint button_y = y + (SETTING_HEIGHT - 11) / 2;
 

	
 
	/* We do not allow changes of some items when we are a client in a networkgame */
 
	if (!(sd->save.conv & SLF_NETWORK_NO) && _networking && !_network_server && !(sdb->flags & SGF_PER_COMPANY)) editable = false;
 
	if ((sdb->flags & SGF_NETWORK_ONLY) && !_networking) editable = false;
 
	if ((sdb->flags & SGF_NO_NETWORK) && _networking) editable = false;
 

	
 
	if (sdb->cmd == SDT_BOOLX) {
 
		static const Colours _bool_ctabs[2][2] = {{COLOUR_CREAM, COLOUR_RED}, {COLOUR_DARK_GREEN, COLOUR_GREEN}};
 
@@ -1557,25 +1557,25 @@ struct GameSettingsWindow : Window {
 
	virtual void OnClick(Point pt, int widget, int click_count)
 
	{
 
		if (widget != SETTINGSEL_OPTIONSPANEL) return;
 

	
 
		uint btn = this->vscroll->GetScrolledRowFromWidget(pt.y, this, SETTINGSEL_OPTIONSPANEL, SETTINGTREE_TOP_OFFSET - 1);
 
		if (btn == INT_MAX) return;
 

	
 
		uint cur_row = 0;
 
		SettingEntry *pe = _settings_main_page.FindEntry(btn, &cur_row);
 

	
 
		if (pe == NULL) return;  // Clicked below the last setting of the page
 

	
 
		int x = (_dynlang.text_dir == TD_RTL ? this->width - pt.x : pt.x) - SETTINGTREE_LEFT_OFFSET - (pe->level + 1) * LEVEL_WIDTH;  // Shift x coordinate
 
		int x = (_current_text_dir == TD_RTL ? this->width - pt.x : pt.x) - SETTINGTREE_LEFT_OFFSET - (pe->level + 1) * LEVEL_WIDTH;  // Shift x coordinate
 
		if (x < 0) return;  // Clicked left of the entry
 

	
 
		if ((pe->flags & SEF_KIND_MASK) == SEF_SUBTREE_KIND) {
 
			pe->d.sub.folded = !pe->d.sub.folded; // Flip 'folded'-ness of the sub-page
 

	
 
			this->vscroll->SetCount(_settings_main_page.Length());
 
			this->SetDirty();
 
			return;
 
		}
 

	
 
		assert((pe->flags & SEF_KIND_MASK) == SEF_SETTING_KIND);
 
		const SettingDesc *sd = pe->d.entry.setting;
 
@@ -1622,25 +1622,25 @@ struct GameSettingsWindow : Window {
 
						if (value < sdb->min) value = sdb->min; // skip between "disabled" and minimum
 
					} else {
 
						value -= step;
 
						if (value < sdb->min) value = (sdb->flags & SGF_0ISDISABLED) ? 0 : sdb->min;
 
					}
 

	
 
					/* Set up scroller timeout for numeric values */
 
					if (value != oldvalue && !(sd->desc.flags & SGF_MULTISTRING)) {
 
						if (this->clicked_entry != NULL) { // Release previous buttons if any
 
							this->clicked_entry->SetButtons(0);
 
						}
 
						this->clicked_entry = pe;
 
						this->clicked_entry->SetButtons((x >= 10) != (_dynlang.text_dir == TD_RTL) ? SEF_RIGHT_DEPRESSED : SEF_LEFT_DEPRESSED);
 
						this->clicked_entry->SetButtons((x >= 10) != (_current_text_dir == TD_RTL) ? SEF_RIGHT_DEPRESSED : SEF_LEFT_DEPRESSED);
 
						this->flags4 |= WF_TIMEOUT_BEGIN;
 
						_left_button_clicked = false;
 
					}
 
					break;
 
				}
 

	
 
				default: NOT_REACHED();
 
			}
 

	
 
			if (value != oldvalue) {
 
				if ((sd->desc.flags & SGF_PER_COMPANY) != 0) {
 
					SetCompanySetting(pe->d.entry.index, value);
 
@@ -1744,25 +1744,25 @@ void ShowGameSettings()
 
 * @param clickable_right is the right button clickable?
 
 */
 
void DrawArrowButtons(int x, int y, Colours button_colour, byte state, bool clickable_left, bool clickable_right)
 
{
 
	int colour = _colour_gradient[button_colour][2];
 

	
 
	DrawFrameRect(x,      y + 1, x +  9, y + 9, button_colour, (state == 1) ? FR_LOWERED : FR_NONE);
 
	DrawFrameRect(x + 10, y + 1, x + 19, y + 9, button_colour, (state == 2) ? FR_LOWERED : FR_NONE);
 
	DrawSprite(SPR_ARROW_LEFT, PAL_NONE, x + WD_IMGBTN_LEFT, y + WD_IMGBTN_TOP);
 
	DrawSprite(SPR_ARROW_RIGHT, PAL_NONE, x + WD_IMGBTN_LEFT + 10, y + WD_IMGBTN_TOP);
 

	
 
	/* Grey out the buttons that aren't clickable */
 
	bool rtl = _dynlang.text_dir == TD_RTL;
 
	bool rtl = _current_text_dir == TD_RTL;
 
	if (rtl ? !clickable_right : !clickable_left) {
 
		GfxFillRect(x +  1, y + 1, x +  1 + 8, y + 8, colour, FILLRECT_CHECKER);
 
	}
 
	if (rtl ? !clickable_left : !clickable_right) {
 
		GfxFillRect(x + 11, y + 1, x + 11 + 8, y + 8, colour, FILLRECT_CHECKER);
 
	}
 
}
 

	
 
/** Widget numbers of the custom currency window. */
 
enum CustomCurrencyWidgets {
 
	CUSTCURR_RATE_DOWN,
 
	CUSTCURR_RATE_UP,
src/ship_gui.cpp
Show inline comments
 
@@ -21,25 +21,25 @@
 
#include "table/strings.h"
 

	
 
/**
 
 * Draws an image of a ship
 
 * @param v         Front vehicle
 
 * @param left      The minimum horizontal position
 
 * @param right     The maximum horizontal position
 
 * @param y         Vertical position to draw at
 
 * @param selection Selected vehicle to draw a frame around
 
 */
 
void DrawShipImage(const Vehicle *v, int left, int right, int y, VehicleID selection)
 
{
 
	bool rtl = _dynlang.text_dir == TD_RTL;
 
	bool rtl = _current_text_dir == TD_RTL;
 

	
 
	SpriteID sprite = v->GetImage(rtl ? DIR_E : DIR_W);
 
	const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
 

	
 
	int x = rtl ? right - real_sprite->width - real_sprite->x_offs : left - real_sprite->x_offs;
 

	
 
	DrawSprite(sprite, GetVehiclePalette(v), x, y + 10);
 

	
 
	if (v->index == selection) {
 
		x += real_sprite->x_offs;
 
		y += real_sprite->y_offs + 10;
 
		DrawFrameRect(x - 1, y - 1, x + real_sprite->width + 1, y + real_sprite->height + 1, COLOUR_WHITE, FR_BORDERONLY);
src/signs_gui.cpp
Show inline comments
 
@@ -220,25 +220,25 @@ struct SignListWindow : QueryStringBaseW
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		switch (widget) {
 
			case SLW_LIST: {
 
				uint y = r.top + WD_FRAMERECT_TOP; // Offset from top of widget.
 
				/* No signs? */
 
				if (this->vscroll->GetCount() == 0) {
 
					DrawString(r.left + WD_FRAMETEXT_LEFT, r.right, y, STR_STATION_LIST_NONE);
 
					return;
 
				}
 

	
 
				bool rtl = _dynlang.text_dir == TD_RTL;
 
				bool rtl = _current_text_dir == TD_RTL;
 
				int sprite_offset_y = (FONT_HEIGHT_NORMAL - 10) / 2 + 1;
 
				uint icon_left  = 4 + (rtl ? r.right - this->text_offset : r.left);
 
				uint text_left  = r.left + (rtl ? WD_FRAMERECT_LEFT : this->text_offset);
 
				uint text_right = r.right - (rtl ? this->text_offset : WD_FRAMERECT_RIGHT);
 

	
 
				/* At least one sign available. */
 
				for (uint16 i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) {
 
					const Sign *si = this->signs[i];
 

	
 
					if (si->owner != OWNER_NONE) DrawCompanyIcon(si->owner, icon_left, y + sprite_offset_y);
 

	
 
					SetDParam(0, si->index);
src/smallmap_gui.cpp
Show inline comments
 
@@ -1072,25 +1072,25 @@ public:
 
	{
 
		switch (widget) {
 
			case SM_WIDGET_MAP: {
 
				DrawPixelInfo new_dpi;
 
				if (!FillDrawPixelInfo(&new_dpi, r.left + 1, r.top + 1, r.right - r.left - 1, r.bottom - r.top - 1)) return;
 
				this->DrawSmallMap(&new_dpi);
 
				break;
 
			}
 

	
 
			case SM_WIDGET_LEGEND: {
 
				uint columns = this->GetNumberColumnsLegend(r.right - r.left + 1);
 
				uint number_of_rows = max(this->map_type == SMT_INDUSTRY ? CeilDiv(_smallmap_industry_count, columns) : 0, this->min_number_of_fixed_rows);
 
				bool rtl = _dynlang.text_dir == TD_RTL;
 
				bool rtl = _current_text_dir == TD_RTL;
 
				uint y_org = r.top + WD_FRAMERECT_TOP;
 
				uint x = rtl ? r.right - this->column_width - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT;
 
				uint y = y_org;
 
				uint i = 0; // Row counter for industry legend.
 
				uint row_height = FONT_HEIGHT_SMALL;
 

	
 
				uint text_left  = rtl ? 0 : LEGEND_BLOB_WIDTH + WD_FRAMERECT_LEFT;
 
				uint text_right = this->column_width - 1 - (rtl ? LEGEND_BLOB_WIDTH + WD_FRAMERECT_RIGHT : 0);
 
				uint blob_left  = rtl ? this->column_width - 1 - LEGEND_BLOB_WIDTH : 0;
 
				uint blob_right = rtl ? this->column_width - 1 : LEGEND_BLOB_WIDTH;
 

	
 
				for (const LegendAndColour *tbl = _legend_table[this->map_type]; !tbl->end; ++tbl) {
 
@@ -1217,25 +1217,25 @@ public:
 
				break;
 

	
 
			case SM_WIDGET_LEGEND: // Legend
 
				/* If industry type small map*/
 
				if (this->map_type == SMT_INDUSTRY) {
 
					/* If click on industries label, find right industry type and enable/disable it */
 
					const NWidgetBase *wi = this->GetWidget<NWidgetBase>(SM_WIDGET_LEGEND); // Label panel
 
					uint line = (pt.y - wi->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_SMALL;
 
					uint columns = this->GetNumberColumnsLegend(wi->current_x);
 
					uint number_of_rows = max(CeilDiv(_smallmap_industry_count, columns), this->min_number_of_fixed_rows);
 
					if (line >= number_of_rows) break;
 

	
 
					bool rtl = _dynlang.text_dir == TD_RTL;
 
					bool rtl = _current_text_dir == TD_RTL;
 
					int x = pt.x - wi->pos_x;
 
					if (rtl) x = wi->current_x - x;
 
					uint column = (x - WD_FRAMERECT_LEFT) / this->column_width;
 

	
 
					/* Check if click is on industry label*/
 
					int industry_pos = (column * number_of_rows) + line;
 
					if (industry_pos < _smallmap_industry_count) {
 
						if (_ctrl_pressed) {
 
							/* Disable all, except the clicked one */
 
							bool changes = false;
 
							for (int i = 0; i != _smallmap_industry_count; i++) {
 
								bool new_state = i == industry_pos;
src/station_gui.cpp
Show inline comments
 
@@ -441,25 +441,25 @@ public:
 
		this->DrawWidgets();
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		switch (widget) {
 
			case SLW_SORTBY:
 
				/* draw arrow pointing up/down for ascending/descending sorting */
 
				this->DrawSortButtonState(SLW_SORTBY, this->stations.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
 
				break;
 

	
 
			case SLW_LIST: {
 
				bool rtl = _dynlang.text_dir == TD_RTL;
 
				bool rtl = _current_text_dir == TD_RTL;
 
				int max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->stations.Length());
 
				int y = r.top + WD_FRAMERECT_TOP;
 
				for (int i = this->vscroll->GetPosition(); i < max; ++i) { // do until max number of stations of owner
 
					const Station *st = this->stations[i];
 
					assert(st->xy != INVALID_TILE);
 

	
 
					/* Do not do the complex check HasStationInUse here, it may be even false
 
					 * when the order had been removed and the station list hasn't been removed yet */
 
					assert(st->owner == owner || st->owner == OWNER_NONE);
 

	
 
					SetDParam(0, st->index);
 
					SetDParam(1, st->facilities);
 
@@ -841,25 +841,25 @@ static const NWidgetPart _nested_station
 
 * @param left  left most coordinate to draw on
 
 * @param right right most coordinate to draw on
 
 * @param y y coordinate
 
 * @param width the width of the view
 
 */
 
static void DrawCargoIcons(CargoID i, uint waiting, int left, int right, int y)
 
{
 
	uint num = min((waiting + 5) / 10, (right - left) / 10); // maximum is width / 10 icons so it won't overflow
 
	if (num == 0) return;
 

	
 
	SpriteID sprite = CargoSpec::Get(i)->GetCargoIcon();
 

	
 
	int x = _dynlang.text_dir == TD_RTL ? right - num * 10 : left;
 
	int x = _current_text_dir == TD_RTL ? right - num * 10 : left;
 
	do {
 
		DrawSprite(sprite, PAL_NONE, x, y);
 
		x += 10;
 
	} while (--num);
 
}
 

	
 
struct CargoData {
 
	CargoID cargo;
 
	StationID source;
 
	uint count;
 

	
 
	CargoData(CargoID cargo, StationID source, uint count) :
 
@@ -1050,25 +1050,25 @@ struct StationViewWindow : public Window
 

	
 
		const Station *st = Station::Get(this->window_number);
 
		if (--pos < 0) {
 
			StringID str = STR_JUST_NOTHING;
 
			for (CargoID i = 0; i < NUM_CARGO; i++) {
 
				if (!st->goods[i].cargo.Empty()) str = STR_EMPTY;
 
			}
 
			SetDParam(0, str);
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_STATION_VIEW_WAITING_TITLE);
 
			y += FONT_HEIGHT_NORMAL;
 
		}
 

	
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		int text_left    = rtl ? r.left + this->expand_shrink_width : r.left + WD_FRAMERECT_LEFT;
 
		int text_right   = rtl ? r.right - WD_FRAMERECT_LEFT : r.right - this->expand_shrink_width;
 
		int shrink_left  = rtl ? r.left + WD_FRAMERECT_LEFT : r.right - this->expand_shrink_width + WD_FRAMERECT_LEFT;
 
		int shrink_right = rtl ? r.left + this->expand_shrink_width - WD_FRAMERECT_RIGHT : r.right - WD_FRAMERECT_RIGHT;
 

	
 

	
 
		int maxrows = this->vscroll->GetCapacity();
 
		for (CargoDataList::const_iterator it = cargolist.begin(); it != cargolist.end() && pos > -maxrows; ++it) {
 
			if (--pos < 0) {
 
				const CargoData *cd = &(*it);
 
				if (cd->source == INVALID_STATION) {
 
					/* Heading */
src/statusbar_gui.cpp
Show inline comments
 
@@ -53,32 +53,32 @@ static bool DrawScrollingStatusText(cons
 
			d += 4;
 
		} else if (IsPrintable(c)) {
 
			if (d + Utf8CharLen(c) >= last) break;
 
			d += Utf8Encode(d, c);
 
		}
 
	}
 
	*d = '\0';
 

	
 
	DrawPixelInfo tmp_dpi;
 
	if (!FillDrawPixelInfo(&tmp_dpi, left, top, right - left, bottom)) return true;
 

	
 
	int width = GetStringBoundingBox(buffer).width;
 
	int pos = (_dynlang.text_dir == TD_RTL) ? (scroll_pos - width) : (right - scroll_pos - left);
 
	int pos = (_current_text_dir == TD_RTL) ? (scroll_pos - width) : (right - scroll_pos - left);
 

	
 
	DrawPixelInfo *old_dpi = _cur_dpi;
 
	_cur_dpi = &tmp_dpi;
 
	DrawString(pos, INT16_MAX, 0, buffer, TC_LIGHT_BLUE, SA_LEFT | SA_FORCE);
 
	_cur_dpi = old_dpi;
 

	
 
	return (_dynlang.text_dir == TD_RTL) ? (pos < right - left) : (pos + width > 0);
 
	return (_current_text_dir == TD_RTL) ? (pos < right - left) : (pos + width > 0);
 
}
 

	
 
enum StatusbarWidget {
 
	SBW_LEFT,   ///< left part of the statusbar; date is shown there
 
	SBW_MIDDLE, ///< middle part; current news or company name or *** SAVING *** or *** PAUSED ***
 
	SBW_RIGHT,  ///< right part; bank balance
 
};
 

	
 
struct StatusBarWindow : Window {
 
	bool saving;
 
	int ticker_scroll;
 
	int reminder_timeout;
src/strings.cpp
Show inline comments
 
@@ -31,26 +31,27 @@
 
#include "vehicle_base.h"
 
#include "engine_base.h"
 
#include "strgen/strgen.h"
 
#include "townname_func.h"
 
#include "string_func.h"
 
#include "company_base.h"
 
#include "smallmap_gui.h"
 
#include "debug.h"
 

	
 
#include "table/strings.h"
 
#include "table/control_codes.h"
 

	
 
DynamicLanguages _dynlang;     ///< Language information of the program.
 
uint64 _decode_parameters[20]; ///< Global array of string parameters. To access, use #SetDParam.
 
DynamicLanguages _dynlang;       ///< Language information of the program.
 
TextDirection _current_text_dir; ///< Text direction of the currently selected language
 
uint64 _decode_parameters[20];   ///< Global array of string parameters. To access, use #SetDParam.
 

	
 
static char *StationGetSpecialString(char *buff, int x, const char *last);
 
static char *GetSpecialTownNameString(char *buff, int ind, uint32 seed, const char *last);
 
static char *GetSpecialNameString(char *buff, int ind, int64 *argv, const char *last);
 

	
 
static char *FormatString(char *buff, const char *str, int64 *argv, uint casei, const char *last);
 

	
 
struct LanguagePack : public LanguagePackHeader {
 
	char data[]; // list of strings
 
};
 

	
 
static char **_langpack_offs;
 
@@ -1376,25 +1377,25 @@ bool ReadLanguagePack(int lang_index)
 
	}
 

	
 
	free(_langpack);
 
	_langpack = lang_pack;
 

	
 
	free(_langpack_offs);
 
	_langpack_offs = langpack_offs;
 

	
 
	const char *c_file = strrchr(_dynlang.ent[lang_index].file, PATHSEPCHAR) + 1;
 
	strecpy(_dynlang.curr_file, c_file, lastof(_dynlang.curr_file));
 

	
 
	_dynlang.curr = lang_index;
 
	_dynlang.text_dir = (TextDirection)lang_pack->text_dir;
 
	_current_text_dir = (TextDirection)lang_pack->text_dir;
 
	SetCurrentGrfLangID(_langpack->newgrflangid);
 
	InitializeSortedCargoSpecs();
 
	SortIndustryTypes();
 
	BuildIndustriesLegend();
 
	SortNetworkLanguages();
 
	return true;
 
}
 

	
 
/* Win32 implementation in win32.cpp.
 
 * OS X implementation in os/macosx/macos.mm. */
 
#if !(defined(WIN32) || defined(__APPLE__))
 
/**
 
@@ -1692,20 +1693,20 @@ void CheckForMissingGlyphsInLoadedLangua
 
	 * For right-to-left languages we need the ICU library. If
 
	 * we do not have support for that library we warn the user
 
	 * about it with a message. As we do not want the string to
 
	 * be translated by the translators, we 'force' it into the
 
	 * binary and 'load' it via a BindCString. To do this
 
	 * properly we have to set the colour of the string,
 
	 * otherwise we end up with a lot of artefacts. The colour
 
	 * 'character' might change in the future, so for safety
 
	 * we just Utf8 Encode it into the string, which takes
 
	 * exactly three characters, so it replaces the "XXX" with
 
	 * the colour marker.
 
	 */
 
	if (_dynlang.text_dir != TD_LTR) {
 
	if (_current_text_dir != TD_LTR) {
 
		static char *err_str = strdup("XXXThis version of OpenTTD does not support right-to-left languages. Recompile with icu enabled.");
 
		Utf8Encode(err_str, SCC_YELLOW);
 
		SetDParamStr(0, err_str);
 
		ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR);
 
	}
 
#endif
 
}
src/strings_func.h
Show inline comments
 
@@ -87,24 +87,25 @@ static inline void CopyInDParam(int offs
 
 * Copy \a num string parameters from the global string parameter array to the \a dst array.
 
 * @param dst  Destination array of string parameters.
 
 * @param offs Index in the global array to copy the first string parameter from.
 
 * @param num  Number of string parameters to copy.
 
 */
 
static inline void CopyOutDParam(uint64 *dst, int offs, int num)
 
{
 
	extern uint64 _decode_parameters[20];
 
	memcpy(dst, _decode_parameters + offs, sizeof(uint64) * (num));
 
}
 

	
 
extern DynamicLanguages _dynlang; // defined in strings.cpp
 
extern TextDirection _current_text_dir; ///< Text direction of the currently selected language
 

	
 
bool ReadLanguagePack(int index);
 
void InitializeLanguagePacks();
 
const char *GetCurrentLanguageIsoCode();
 

	
 
int CDECL StringIDSorter(const StringID *a, const StringID *b);
 

	
 
/** Key comparison function for std::map */
 
struct StringIDCompare
 
{
 
	bool operator()(StringID s1, StringID s2) const { return StringIDSorter(&s1, &s2) < 0; }
 
};
src/strings_type.h
Show inline comments
 
@@ -28,25 +28,24 @@ enum TextDirection {
 

	
 
/** Information about a language */
 
struct Language {
 
	char *name; ///< The internal name of the language
 
	char *file; ///< The name of the language as it appears on disk
 
};
 

	
 
/** Used for dynamic language support */
 
struct DynamicLanguages {
 
	int num;                  ///< Number of languages
 
	int curr;                 ///< Currently selected language index
 
	char curr_file[MAX_PATH]; ///< Currently selected language file name without path (needed for saving the filename of the loaded language).
 
	TextDirection text_dir;   ///< Text direction of the currently selected language
 
	Language ent[MAX_LANG];   ///< Information about the languages
 
};
 

	
 
/** Special string constants */
 
enum SpecialStrings {
 

	
 
	/* special strings for town names. the town name is generated dynamically on request. */
 
	SPECSTR_TOWNNAME_START     = 0x20C0,
 
	SPECSTR_TOWNNAME_ENGLISH   = SPECSTR_TOWNNAME_START,
 
	SPECSTR_TOWNNAME_FRENCH,
 
	SPECSTR_TOWNNAME_GERMAN,
 
	SPECSTR_TOWNNAME_AMERICAN,
src/terraform_gui.cpp
Show inline comments
 
@@ -364,25 +364,25 @@ Window *ShowTerraformToolbar(Window *lin
 
	if (link == NULL) {
 
		w = AllocateWindowDescFront<TerraformToolbarWindow>(&_terraform_desc, 0);
 
		return w;
 
	}
 

	
 
	/* Delete the terraform toolbar to place it again. */
 
	DeleteWindowById(WC_SCEN_LAND_GEN, 0, true);
 
	w = AllocateWindowDescFront<TerraformToolbarWindow>(&_terraform_desc, 0);
 
	/* Align the terraform toolbar under the main toolbar. */
 
	w->top -= w->height;
 
	w->SetDirty();
 
	/* Put the linked toolbar to the left / right of it. */
 
	link->left = w->left + (_dynlang.text_dir == TD_RTL ? w->width : -link->width);
 
	link->left = w->left + (_current_text_dir == TD_RTL ? w->width : -link->width);
 
	link->top  = w->top;
 
	link->SetDirty();
 

	
 
	return w;
 
}
 

	
 
EventState TerraformToolbarGlobalHotkeys(uint16 key, uint16 keycode)
 
{
 
	int num = CheckHotkeyMatch<TerraformToolbarWindow>(_terraform_hotkeys, keycode, NULL, true);
 
	if (num == -1) return ES_NOT_HANDLED;
 
	Window *w = ShowTerraformToolbar(NULL);
 
	if (w == NULL) return ES_NOT_HANDLED;
src/timetable_gui.cpp
Show inline comments
 
@@ -355,25 +355,25 @@ struct TimetableWindow : Window {
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		const Vehicle *v = this->vehicle;
 
		int selected = this->sel_index;
 

	
 
		switch (widget) {
 
			case TTV_TIMETABLE_PANEL: {
 
				int y = r.top + WD_FRAMERECT_TOP;
 
				int i = this->vscroll->GetPosition();
 
				VehicleOrderID order_id = (i + 1) / 2;
 
				bool final_order = false;
 

	
 
				bool rtl = _dynlang.text_dir == TD_RTL;
 
				bool rtl = _current_text_dir == TD_RTL;
 
				SetDParam(0, 99);
 
				int index_column_width = GetStringBoundingBox(STR_ORDER_INDEX).width + GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + 3;
 
				int middle = rtl ? r.right - WD_FRAMERECT_RIGHT - index_column_width : r.left + WD_FRAMERECT_LEFT + index_column_width;
 

	
 
				const Order *order = v->GetOrder(order_id);
 
				while (order != NULL) {
 
					/* Don't draw anything if it extends past the end of the window. */
 
					if (!this->vscroll->IsVisible(i)) break;
 

	
 
					if (i % 2 == 0) {
 
						DrawOrderString(v, order, order_id, y, i == selected, true, r.left + WD_FRAMERECT_LEFT, middle, r.right - WD_FRAMERECT_RIGHT);
 

	
 
@@ -417,25 +417,25 @@ struct TimetableWindow : Window {
 
				if (total_time <= 0 || v->GetNumOrders() <= 1 || !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) break;
 

	
 
				TimetableArrivalDeparture *arr_dep = AllocaM(TimetableArrivalDeparture, v->GetNumOrders());
 
				const VehicleOrderID cur_order = v->cur_order_index % v->GetNumOrders();
 

	
 
				VehicleOrderID earlyID = BuildArrivalDepartureList(v, arr_dep) ? cur_order : (VehicleOrderID)INVALID_VEH_ORDER_ID;
 

	
 
				int y = r.top + WD_FRAMERECT_TOP;
 

	
 
				bool show_late = this->show_expected && v->lateness_counter > DAY_TICKS;
 
				Ticks offset = show_late ? 0 : -v->lateness_counter;
 

	
 
				bool rtl = _dynlang.text_dir == TD_RTL;
 
				bool rtl = _current_text_dir == TD_RTL;
 
				int abbr_left  = rtl ? r.right - WD_FRAMERECT_RIGHT - this->deparr_abbr_width : r.left + WD_FRAMERECT_LEFT;
 
				int abbr_right = rtl ? r.right - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT + this->deparr_abbr_width;
 
				int time_left  = rtl ? r.left + WD_FRAMERECT_LEFT : r.right - WD_FRAMERECT_RIGHT - this->deparr_time_width;
 
				int time_right = rtl ? r.left + WD_FRAMERECT_LEFT + this->deparr_time_width : r.right - WD_FRAMERECT_RIGHT;
 

	
 
				for (int i = this->vscroll->GetPosition(); i / 2 < v->GetNumOrders(); ++i) { // note: i is also incremented in the loop
 
					/* Don't draw anything if it extends past the end of the window. */
 
					if (!this->vscroll->IsVisible(i)) break;
 

	
 
					if (i % 2 == 0) {
 
						if (arr_dep[i / 2].arrival != INVALID_TICKS) {
 
							DrawString(abbr_left, abbr_right, y, STR_TIMETABLE_ARRIVAL_ABBREVIATION, i == selected ? TC_WHITE : TC_BLACK);
src/toolbar_gui.cpp
Show inline comments
 
@@ -129,25 +129,25 @@ public:
 
		this->checkmark_width = GetStringBoundingBox(STR_JUST_CHECKMARK).width + 3;
 
	}
 

	
 
	virtual ~DropDownListCheckedItem() {}
 

	
 
	uint Width() const
 
	{
 
		return DropDownListStringItem::Width() + this->checkmark_width;
 
	}
 

	
 
	void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
 
	{
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		if (this->checked) {
 
			DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, STR_JUST_CHECKMARK, sel ? TC_WHITE : TC_BLACK);
 
		}
 
		DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : this->checkmark_width), right - WD_FRAMERECT_RIGHT - (rtl ? this->checkmark_width : 0), top, this->String(), sel ? TC_WHITE : TC_BLACK);
 
	}
 
};
 

	
 
/**
 
 * Drop down list entry for showing a company entry, with companies 'blob'.
 
 */
 
class DropDownListCompanyItem : public DropDownListItem {
 
	uint icon_width;
 
@@ -168,25 +168,25 @@ public:
 

	
 
	uint Width() const
 
	{
 
		CompanyID company = (CompanyID)this->result;
 
		SetDParam(0, company);
 
		SetDParam(1, company);
 
		return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_width + 3;
 
	}
 

	
 
	void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
 
	{
 
		CompanyID company = (CompanyID)this->result;
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 

	
 
		/* It's possible the company is deleted while the dropdown is open */
 
		if (!Company::IsValidID(company)) return;
 

	
 
		DrawCompanyIcon(company, rtl ? right - this->icon_width - WD_FRAMERECT_RIGHT : left + WD_FRAMERECT_LEFT, top + 1 + (FONT_HEIGHT_NORMAL - 10) / 2);
 

	
 
		SetDParam(0, company);
 
		SetDParam(1, company);
 
		TextColour col;
 
		if (this->greyed) {
 
			col = TC_GREY;
 
		} else {
 
@@ -1045,25 +1045,25 @@ public:
 
			} else {
 
				cur_wid++;
 
			}
 
		}
 
	}
 

	
 
	/* virtual */ void Draw(const Window *w)
 
	{
 
		/* Draw brown-red toolbar bg. */
 
		GfxFillRect(this->pos_x, this->pos_y, this->pos_x + this->current_x - 1, this->pos_y + this->current_y - 1, 0xB2);
 
		GfxFillRect(this->pos_x, this->pos_y, this->pos_x + this->current_x - 1, this->pos_y + this->current_y - 1, 0xB4, FILLRECT_CHECKER);
 

	
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		for (NWidgetBase *child_wid = rtl ? this->tail : this->head; child_wid != NULL; child_wid = rtl ? child_wid->prev : child_wid->next) {
 
			if (child_wid->type == NWID_SPACER) continue;
 
			if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
 

	
 
			child_wid->Draw(w);
 
		}
 
	}
 

	
 
	/* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y)
 
	{
 
		if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL;
 

	
src/town_gui.cpp
Show inline comments
 
@@ -135,25 +135,25 @@ public:
 

	
 
		DrawString(left, right, y, STR_LOCAL_AUTHORITY_COMPANY_RATINGS);
 
		y += FONT_HEIGHT_NORMAL;
 

	
 
		Dimension icon_size = GetSpriteSize(SPR_COMPANY_ICON);
 
		int icon_width      = icon_size.width;
 
		int icon_y_offset   = (FONT_HEIGHT_NORMAL - icon_size.height) / 2;
 

	
 
		Dimension exclusive_size = GetSpriteSize(SPR_EXCLUSIVE_TRANSPORT);
 
		int exclusive_width      = exclusive_size.width;
 
		int exclusive_y_offset   = (FONT_HEIGHT_NORMAL - exclusive_size.height) / 2;
 

	
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		uint text_left      = left  + (rtl ? 0 : icon_width + exclusive_width + 4);
 
		uint text_right     = right - (rtl ? icon_width + exclusive_width + 4 : 0);
 
		uint icon_left      = rtl ? right - icon_width : left;
 
		uint exclusive_left = rtl ? right - icon_width - exclusive_width - 2 : left + icon_width + 2;
 

	
 
		/* Draw list of companies */
 
		const Company *c;
 
		FOR_ALL_COMPANIES(c) {
 
			if ((HasBit(this->town->have_ratings, c->index) || this->town->exclusivity == c->index)) {
 
				DrawCompanyIcon(c->index, icon_left, y + icon_y_offset);
 

	
 
				SetDParam(0, c->index);
 
@@ -389,25 +389,25 @@ public:
 
				break;
 

	
 
			case LT_TROPIC:
 
				if (GetTropicZone(this->town->xy) == TROPICZONE_DESERT) cargo_needed_for_growth = 2;
 
				break;
 

	
 
			default: break;
 
		}
 

	
 
		if (cargo_needed_for_growth > 0) {
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH);
 

	
 
			bool rtl = _dynlang.text_dir == TD_RTL;
 
			bool rtl = _current_text_dir == TD_RTL;
 
			uint cargo_text_left = r.left + WD_FRAMERECT_LEFT + (rtl ? 0 : 20);
 
			uint cargo_text_right = r.right - WD_FRAMERECT_RIGHT - (rtl ? 20 : 0);
 

	
 
			const CargoSpec *food = FindFirstCargoWithTownEffect(TE_FOOD);
 
			CargoID first_food_cargo = (food != NULL) ? food->Index() : (CargoID)CT_INVALID;
 
			StringID food_name       = (food != NULL) ? food->name    : STR_CARGO_PLURAL_FOOD;
 

	
 
			const CargoSpec *water = FindFirstCargoWithTownEffect(TE_WATER);
 
			CargoID first_water_cargo = (water != NULL) ? water->Index() : (CargoID)CT_INVALID;
 
			StringID water_name       = (water != NULL) ? water->name    : STR_CARGO_PLURAL_WATER;
 

	
 
			if (first_food_cargo != CT_INVALID && this->town->act_food > 0) {
src/train_gui.cpp
Show inline comments
 
@@ -46,25 +46,25 @@ void CcBuildWagon(const CommandCost &res
 
	}
 
}
 

	
 
/**
 
 * Highlight the position where a rail vehicle is dragged over by drawing a light gray background.
 
 * @param px        The current x position to draw from.
 
 * @param max_width The maximum space available to draw.
 
 * @param selection Selected vehicle that is dragged.
 
 * @return The width of the highlight mark.
 
 */
 
static int HighlightDragPosition(int px, int max_width, VehicleID selection)
 
{
 
	bool rtl = _dynlang.text_dir == TD_RTL;
 
	bool rtl = _current_text_dir == TD_RTL;
 

	
 
	assert(selection != INVALID_VEHICLE);
 
	Point offset;
 
	int dragged_width = Train::Get(selection)->GetDisplayImageWidth(&offset) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
 

	
 
	int drag_hlight_left = rtl ? max(px -dragged_width, 0) : px;
 
	int drag_hlight_right = rtl ? px : min(px + dragged_width, max_width);
 
	int drag_hlight_width = max(drag_hlight_right - drag_hlight_left, 0);
 

	
 
	if (drag_hlight_width > 0) {
 
		GfxFillRect(drag_hlight_left + WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP + 1,
 
				drag_hlight_right - WD_FRAMERECT_RIGHT, 13 - WD_FRAMERECT_BOTTOM, _colour_gradient[COLOUR_GREY][7]);
 
@@ -76,25 +76,25 @@ static int HighlightDragPosition(int px,
 
/**
 
 * Draws an image of a whole train
 
 * @param v         Front vehicle
 
 * @param left      The minimum horizontal position
 
 * @param right     The maximum horizontal position
 
 * @param y         Vertical position to draw at
 
 * @param selection Selected vehicle to draw a frame around
 
 * @param skip      Number of pixels to skip at the front (for scrolling)
 
 * @param drag_dest The vehicle another one is dragged over, \c INVALID_VEHICLE if none.
 
 */
 
void DrawTrainImage(const Train *v, int left, int right, int y, VehicleID selection, int skip, VehicleID drag_dest)
 
{
 
	bool rtl = _dynlang.text_dir == TD_RTL;
 
	bool rtl = _current_text_dir == TD_RTL;
 
	Direction dir = rtl ? DIR_E : DIR_W;
 

	
 
	DrawPixelInfo tmp_dpi, *old_dpi;
 
	/* Position of highlight box */
 
	int highlight_l = 0;
 
	int highlight_r = 0;
 
	int max_width = right - left + 1;
 

	
 
	if (!FillDrawPixelInfo(&tmp_dpi, left, y, max_width, 14)) return;
 

	
 
	old_dpi = _cur_dpi;
 
	_cur_dpi = &tmp_dpi;
 
@@ -326,25 +326,25 @@ int GetTrainDetailsWndVScroll(VehicleID 
 
 * @param v     current vehicle
 
 * @param left  The left most coordinate to draw
 
 * @param right The right most coordinate to draw
 
 * @param y     The y coordinate
 
 * @param vscroll_pos Position of scrollbar
 
 * @param vscroll_cap Number of lines currently displayed
 
 * @param det_tab Selected details tab
 
 */
 
void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab)
 
{
 
	/* draw the first 3 details tabs */
 
	if (det_tab != TDW_TAB_TOTALS) {
 
		bool rtl = _dynlang.text_dir == TD_RTL;
 
		bool rtl = _current_text_dir == TD_RTL;
 
		Direction dir = rtl ? DIR_E : DIR_W;
 
		int x = rtl ? right : left;
 
		int sprite_y_offset = 4 + (FONT_HEIGHT_NORMAL - 10) / 2;
 
		int line_height = WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM;
 
		for (; v != NULL && vscroll_pos > -vscroll_cap; v = v->GetNextVehicle()) {
 
			GetCargoSummaryOfArticulatedVehicle(v, &_cargo_summary);
 

	
 
			/* Draw sprites */
 
			uint dx = 0;
 
			int px = x;
 
			const Train *u = v;
 
			do {
src/vehicle_gui.cpp
Show inline comments
 
@@ -1023,25 +1023,25 @@ uint GetVehicleListHeight(VehicleType ty
 

	
 
/**
 
 * Draw all the vehicle list items.
 
 * @param selected_vehicle The vehicle that is to be highlighted.
 
 * @param line_height      Height of a single item line.
 
 * @param r                Rectangle with edge positions of the matrix widget.
 
 */
 
void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int line_height, const Rect &r) const
 
{
 
	int left = r.left + WD_MATRIX_LEFT;
 
	int right = r.right - WD_MATRIX_RIGHT;
 
	int width = right - left;
 
	bool rtl = _dynlang.text_dir == TD_RTL;
 
	bool rtl = _current_text_dir == TD_RTL;
 

	
 
	int text_offset = GetDigitWidth() * this->unitnumber_digits + WD_FRAMERECT_RIGHT;
 
	int text_left  = left  + (rtl ?           0 : text_offset);
 
	int text_right = right - (rtl ? text_offset :           0);
 

	
 
	bool show_orderlist = this->vli.vtype >= VEH_SHIP;
 
	int orderlist_left  = left  + (rtl ? 0 : max(100 + text_offset, width / 2));
 
	int orderlist_right = right - (rtl ? max(100 + text_offset, width / 2) : 0);
 

	
 
	int image_left  = (rtl && show_orderlist) ? orderlist_right : text_left;
 
	int image_right = (!rtl && show_orderlist) ? orderlist_left : text_right;
 

	
 
@@ -1730,25 +1730,25 @@ struct VehicleDetailsWindow : Window {
 
				SetDParam(1, v->breakdowns_since_last_service);
 
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS);
 
				break;
 
			}
 

	
 
			case VLD_WIDGET_MATRIX:
 
				/* For trains only. */
 
				DrawVehicleDetails(v, r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, r.top + WD_MATRIX_TOP, this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->tab);
 
				break;
 

	
 
			case VLD_WIDGET_MIDDLE_DETAILS: {
 
				/* For other vehicles, at the place of the matrix. */
 
				bool rtl = _dynlang.text_dir == TD_RTL;
 
				bool rtl = _current_text_dir == TD_RTL;
 
				uint sprite_width = max<uint>(GetSprite(v->GetImage(rtl ? DIR_E : DIR_W), ST_NORMAL)->width, 70U) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
 

	
 
				uint text_left  = r.left  + (rtl ? 0 : sprite_width);
 
				uint text_right = r.right - (rtl ? sprite_width : 0);
 

	
 
				/* Articulated road vehicles use a complete line. */
 
				if (v->type == VEH_ROAD && RoadVehicle::From(v)->HasArticulatedPart()) {
 
					DrawVehicleImage(v, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, INVALID_VEHICLE, 0);
 
				} else {
 
					uint sprite_left  = rtl ? text_right : r.left;
 
					uint sprite_right = rtl ? r.right : text_left;
 

	
src/widget.cpp
Show inline comments
 
@@ -43,25 +43,25 @@ static Point HandleScrollbarHittest(cons
 

	
 
	int height = (bottom - top);
 
	int pos = sb->GetPosition();
 
	int count = sb->GetCount();
 
	int cap = sb->GetCapacity();
 

	
 
	if (count != 0) top += height * pos / count;
 

	
 
	if (cap > count) cap = count;
 
	if (count != 0) bottom -= (count - pos - cap) * height / count;
 

	
 
	Point pt;
 
	if (horizontal && _dynlang.text_dir == TD_RTL) {
 
	if (horizontal && _current_text_dir == TD_RTL) {
 
		pt.x = rev_base - (bottom - 1);
 
		pt.y = rev_base - top;
 
	} else {
 
		pt.x = top;
 
		pt.y = bottom - 1;
 
	}
 
	return pt;
 
}
 

	
 
/**
 
 * Compute new position of the scrollbar after a click and updates the window flags.
 
 * @param w   Window on which a scroll was performed.
 
@@ -69,25 +69,25 @@ static Point HandleScrollbarHittest(cons
 
 * @param mi  Minimum coordinate of the scroll bar.
 
 * @param ma  Maximum coordinate of the scroll bar.
 
 * @param x   The X coordinate of the mouse click.
 
 * @param y   The Y coordinate of the mouse click.
 
 */
 
static void ScrollbarClickPositioning(Window *w, NWidgetScrollbar *sb, int x, int y, int mi, int ma)
 
{
 
	int pos;
 
	bool rtl = false;
 

	
 
	if (sb->type == NWID_HSCROLLBAR) {
 
		pos = x;
 
		rtl = _dynlang.text_dir == TD_RTL;
 
		rtl = _current_text_dir == TD_RTL;
 
	} else {
 
		pos = y;
 
	}
 
	if (pos <= mi + 9) {
 
		/* Pressing the upper button? */
 
		SetBit(sb->disp_flags, NDB_SCROLLBAR_UP);
 
		if (_scroller_click_timeout <= 1) {
 
			_scroller_click_timeout = 3;
 
			sb->UpdatePosition(rtl ? 1 : -1);
 
		}
 
		w->scrolling_scrollbar = sb->index;
 
	} else if (pos >= ma - 10) {
 
@@ -378,25 +378,25 @@ static inline void DrawFrame(const Rect 
 
	int x2 = r.left; // by default the left side is the left side of the widget
 

	
 
	if (str != STR_NULL) x2 = DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top, str);
 

	
 
	int c1 = _colour_gradient[colour][3];
 
	int c2 = _colour_gradient[colour][7];
 

	
 
	/* If the frame has text, adjust the top bar to fit half-way through */
 
	int dy1 = 4;
 
	if (str != STR_NULL) dy1 = FONT_HEIGHT_NORMAL / 2 - 1;
 
	int dy2 = dy1 + 1;
 

	
 
	if (_dynlang.text_dir == TD_LTR) {
 
	if (_current_text_dir == TD_LTR) {
 
		/* Line from upper left corner to start of text */
 
		GfxFillRect(r.left, r.top + dy1, r.left + 4, r.top + dy1, c1);
 
		GfxFillRect(r.left + 1, r.top + dy2, r.left + 4, r.top + dy2, c2);
 

	
 
		/* Line from end of text to upper right corner */
 
		GfxFillRect(x2, r.top + dy1, r.right - 1, r.top + dy1, c1);
 
		GfxFillRect(x2, r.top + dy2, r.right - 2, r.top + dy2, c2);
 
	} else {
 
		/* Line from upper left corner to start of text */
 
		GfxFillRect(r.left, r.top + dy1, x2 - 2, r.top + dy1, c1);
 
		GfxFillRect(r.left + 1, r.top + dy2, x2 - 2, r.top + dy2, c2);
 

	
 
@@ -505,25 +505,25 @@ void DrawCaption(const Rect &r, Colours 
 
/**
 
 * 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) {
 
	if (_current_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_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_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);
 
	}
 
}
 

	
 
@@ -555,25 +555,25 @@ void Window::DrawWidgets() const
 
 * Draw a sort button's up or down arrow symbol.
 
 * @param widget Sort button widget
 
 * @param state State of sort button
 
 */
 
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 base = offset + nwid->pos_x + (_current_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_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
 
@@ -2005,26 +2005,26 @@ void NWidgetLeaf::Draw(const Window *w)
 
		case WWT_TEXTBTN:
 
		case WWT_PUSHTXTBTN:
 
		case WWT_TEXTBTN_2:
 
			if (this->index >= 0) w->SetStringParameters(this->index);
 
			DrawFrameRect(r.left, r.top, r.right, r.bottom, this->colour, (clicked) ? FR_LOWERED : FR_NONE);
 
			DrawLabel(r, this->type, clicked, this->widget_data);
 
			break;
 

	
 
		case WWT_ARROWBTN:
 
		case WWT_PUSHARROWBTN: {
 
			SpriteID sprite;
 
			switch (this->widget_data) {
 
				case AWV_DECREASE: sprite = _dynlang.text_dir != TD_RTL ? SPR_ARROW_LEFT : SPR_ARROW_RIGHT; break;
 
				case AWV_INCREASE: sprite = _dynlang.text_dir == TD_RTL ? SPR_ARROW_LEFT : SPR_ARROW_RIGHT; break;
 
				case AWV_DECREASE: sprite = _current_text_dir != TD_RTL ? SPR_ARROW_LEFT : SPR_ARROW_RIGHT; break;
 
				case AWV_INCREASE: sprite = _current_text_dir == TD_RTL ? SPR_ARROW_LEFT : SPR_ARROW_RIGHT; break;
 
				case AWV_LEFT:     sprite = SPR_ARROW_LEFT;  break;
 
				case AWV_RIGHT:    sprite = SPR_ARROW_RIGHT; break;
 
				default: NOT_REACHED();
 
			}
 
			DrawImageButtons(r, WWT_PUSHIMGBTN, this->colour, clicked, sprite);
 
		}
 

	
 
		case WWT_LABEL:
 
			if (this->index >= 0) w->SetStringParameters(this->index);
 
			DrawLabel(r, this->type, clicked, this->widget_data);
 
			break;
 

	
 
@@ -2089,25 +2089,25 @@ void NWidgetLeaf::Draw(const Window *w)
 
	}
 
}
 

	
 
/**
 
 * For a #NWID_BUTTON_DROPDOWN, test whether \a pt refers to the button or to the drop-down.
 
 * @param pt Point in the widget.
 
 * @return The point refers to the button.
 
 *
 
 * @note The magic constants are also used at #DrawButtonDropdown.
 
 */
 
bool NWidgetLeaf::ButtonHit(const Point &pt)
 
{
 
	if (_dynlang.text_dir == TD_LTR) {
 
	if (_current_text_dir == TD_LTR) {
 
		int button_width = this->pos_x + this->current_x - 12;
 
		return pt.x < button_width;
 
	} else {
 
		int button_left = this->pos_x + 12;
 
		return pt.x >= button_left;
 
	}
 
}
 

	
 
/* == Conversion code from NWidgetPart array to NWidgetBase* tree == */
 

	
 
/**
 
 * Construct a single nested widget in \a *dest from its parts.
src/widgets/dropdown.cpp
Show inline comments
 
@@ -404,25 +404,25 @@ void ShowDropDownList(Window *w, DropDow
 
			int avg_height = list_height / (int)list->size();
 
			int rows = (screen_bottom - 4 - top) / avg_height;
 
			height = rows * avg_height;
 
			scroll = true;
 
			/* Add space for the scroll bar if we automatically determined
 
			 * the width of the list. */
 
			max_item_width += WD_VSCROLLBAR_WIDTH;
 
		}
 
	}
 

	
 
	if (auto_width) width = max(width, max_item_width);
 

	
 
	Point dw_pos = { w->left + (_dynlang.text_dir == TD_RTL ? wi_rect.right + 1 - width : wi_rect.left), top};
 
	Point dw_pos = { w->left + (_current_text_dir == TD_RTL ? wi_rect.right + 1 - width : wi_rect.left), top};
 
	Dimension dw_size = {width, height};
 
	new DropdownWindow(w, list, selected, button, instant_close, dw_pos, dw_size, wi_colour, scroll);
 
}
 

	
 
/**
 
 * Show a dropdown menu window near a widget of the parent window.
 
 * The result code of the items is their index in the #strings list.
 
 * @param w             Parent window that wants the dropdown menu.
 
 * @param strings       Menu list, end with #INVALID_STRING_ID
 
 * @param selected      Index of initial selected item.
 
 * @param button        Button widget number of the parent window #w that wants the dropdown menu.
 
 * @param disabled_mask Bitmask for diabled items (items with their bit set are not copied to the dropdown list).
src/window.cpp
Show inline comments
 
@@ -564,25 +564,25 @@ void Window::SetDirty() const
 
 */
 
void Window::ReInit(int rx, int ry)
 
{
 
	this->SetDirty(); // Mark whole current window as dirty.
 

	
 
	/* Save current size. */
 
	int window_width  = this->width;
 
	int window_height = this->height;
 

	
 
	this->OnInit();
 
	/* Re-initialize the window from the ground up. No need to change the nested_array, as all widgets stay where they are. */
 
	this->nested_root->SetupSmallestSize(this, false);
 
	this->nested_root->AssignSizePosition(ST_SMALLEST, 0, 0, this->nested_root->smallest_x, this->nested_root->smallest_y, _dynlang.text_dir == TD_RTL);
 
	this->nested_root->AssignSizePosition(ST_SMALLEST, 0, 0, this->nested_root->smallest_x, this->nested_root->smallest_y, _current_text_dir == TD_RTL);
 
	this->width  = this->nested_root->smallest_x;
 
	this->height = this->nested_root->smallest_y;
 
	this->resize.step_width  = this->nested_root->resize_x;
 
	this->resize.step_height = this->nested_root->resize_y;
 

	
 
	/* Resize as close to the original size + requested resize as possible. */
 
	window_width  = max(window_width  + rx, this->width);
 
	window_height = max(window_height + ry, this->height);
 
	int dx = (this->resize.step_width  == 0) ? 0 : window_width  - this->width;
 
	int dy = (this->resize.step_height == 0) ? 0 : window_height - this->height;
 
	/* dx and dy has to go by step.. calculate it.
 
	 * The cast to int is necessary else dx/dy are implicitly casted to unsigned int, which won't work. */
 
@@ -898,25 +898,25 @@ void Window::InitializeData(const Window
 
	this->window_number = window_number;
 
	this->desc_flags = desc->flags;
 

	
 
	this->OnInit();
 
	/* Initialize nested widget tree. */
 
	if (this->nested_array == NULL) {
 
		this->nested_array = CallocT<NWidgetBase *>(this->nested_array_size);
 
		this->nested_root->SetupSmallestSize(this, true);
 
	} else {
 
		this->nested_root->SetupSmallestSize(this, false);
 
	}
 
	/* Initialize to smallest size. */
 
	this->nested_root->AssignSizePosition(ST_SMALLEST, 0, 0, this->nested_root->smallest_x, this->nested_root->smallest_y, _dynlang.text_dir == TD_RTL);
 
	this->nested_root->AssignSizePosition(ST_SMALLEST, 0, 0, this->nested_root->smallest_x, this->nested_root->smallest_y, _current_text_dir == TD_RTL);
 

	
 
	/* Further set up window properties,
 
	 * this->left, this->top, this->width, this->height, this->resize.width, and this->resize.height are initialized later. */
 
	this->resize.step_width  = this->nested_root->resize_x;
 
	this->resize.step_height = this->nested_root->resize_y;
 

	
 
	/* Give focus to the opened window unless it is the OSK window or a text box
 
	 * of focused window has focus (so we don't interrupt typing). But if the new
 
	 * window has a text box, then take focus anyway. */
 
	if (this->window_class != WC_OSK && (!EditBoxInGlobalFocus() || this->nested_root->GetWidgetOfType(WWT_EDITBOX) != NULL)) SetFocusedWindow(this);
 

	
 
	/* Hacky way of specifying always-on-top windows. These windows are
 
@@ -1177,25 +1177,25 @@ restart:
 
}
 

	
 
/**
 
 * Computer the position of the top-left corner of a window to be opened right
 
 * under the toolbar.
 
 * @param window_width the width of the window to get the position for
 
 * @return Coordinate of the top-left corner of the new window.
 
 */
 
Point GetToolbarAlignedWindowPosition(int window_width)
 
{
 
	const Window *w = FindWindowById(WC_MAIN_TOOLBAR, 0);
 
	assert(w != NULL);
 
	Point pt = { _dynlang.text_dir == TD_RTL ? w->left : (w->left + w->width) - window_width, w->top + w->height };
 
	Point pt = { _current_text_dir == TD_RTL ? w->left : (w->left + w->width) - window_width, w->top + w->height };
 
	return pt;
 
}
 

	
 
/**
 
 * Compute the position of the top-left corner of a new window that is opened.
 
 *
 
 * By default position a child window at an offset of 10/10 of its parent.
 
 * With the exception of WC_BUILD_TOOLBAR (build railway/roads/ship docks/airports)
 
 * and WC_SCEN_LAND_GEN (landscaping). Whose child window has an offset of 0/toolbar-height of
 
 * its parent. So it's exactly under the parent toolbar and no buttons will be covered.
 
 * However if it falls too extremely outside window positions, reposition
 
 * it to an automatic place.
 
@@ -1585,25 +1585,25 @@ static void EnsureVisibleCaption(Window 
 
 * @param delta_y Delta y-size of changed window
 
 */
 
void ResizeWindow(Window *w, int delta_x, int delta_y)
 
{
 
	if (delta_x != 0 || delta_y != 0) {
 
		w->SetDirty();
 

	
 
		uint new_xinc = max(0, (w->nested_root->resize_x == 0) ? 0 : (int)(w->nested_root->current_x - w->nested_root->smallest_x) + delta_x);
 
		uint new_yinc = max(0, (w->nested_root->resize_y == 0) ? 0 : (int)(w->nested_root->current_y - w->nested_root->smallest_y) + delta_y);
 
		assert(w->nested_root->resize_x == 0 || new_xinc % w->nested_root->resize_x == 0);
 
		assert(w->nested_root->resize_y == 0 || new_yinc % w->nested_root->resize_y == 0);
 

	
 
		w->nested_root->AssignSizePosition(ST_RESIZE, 0, 0, w->nested_root->smallest_x + new_xinc, w->nested_root->smallest_y + new_yinc, _dynlang.text_dir == TD_RTL);
 
		w->nested_root->AssignSizePosition(ST_RESIZE, 0, 0, w->nested_root->smallest_x + new_xinc, w->nested_root->smallest_y + new_yinc, _current_text_dir == TD_RTL);
 
		w->width  = w->nested_root->current_x;
 
		w->height = w->nested_root->current_y;
 
	}
 

	
 
	EnsureVisibleCaption(w, w->left, w->top);
 

	
 
	/* Always call OnResize to make sure everything is initialised correctly if it needs to be. */
 
	w->OnResize();
 
	w->SetDirty();
 
}
 

	
 
/**
 
@@ -1852,25 +1852,25 @@ static EventState HandleScrollbarScrolli
 
			if (!_left_button_down) {
 
				w->scrolling_scrollbar = -1;
 
				w->SetDirty();
 
				return ES_HANDLED;
 
			}
 

	
 
			int i;
 
			NWidgetScrollbar *sb = w->GetWidget<NWidgetScrollbar>(w->scrolling_scrollbar);
 
			bool rtl = false;
 

	
 
			if (sb->type == NWID_HSCROLLBAR) {
 
				i = _cursor.pos.x - _cursorpos_drag_start.x;
 
				rtl = _dynlang.text_dir == TD_RTL;
 
				rtl = _current_text_dir == TD_RTL;
 
			} else {
 
				i = _cursor.pos.y - _cursorpos_drag_start.y;
 
			}
 

	
 
			if (sb->disp_flags & ND_SCROLLBAR_BTN) {
 
				if (_scroller_click_timeout == 1) {
 
					_scroller_click_timeout = 3;
 
					sb->UpdatePosition(rtl == HasBit(sb->disp_flags, NDB_SCROLLBAR_UP) ? 1 : -1);
 
					w->SetDirty();
 
				}
 
				return ES_HANDLED;
 
			}
0 comments (0 inline, 0 general)