Ejemplo n.º 1
0
	virtual void DrawWidget(const Rect &r, int widget) const
	{
		if (widget != DDM_ITEMS) return;

		TextColour colour = (TextColour)this->GetWidget<NWidgetCore>(widget)->colour;

		int y = r.top + 2;
		int pos = this->vscroll->GetPosition();
		for (DropDownList::const_iterator it = this->list->begin(); it != this->list->end(); ++it) {
			const DropDownListItem *item = *it;
			int item_height = item->Height(r.right - r.left + 1);

			/* Skip items that are scrolled up */
			if (--pos >= 0) continue;

			if (y + item_height < r.bottom) {
				bool selected = (this->selected_index == item->result);
				if (selected) GfxFillRect(r.left + 2, y, r.right - 1, y + item_height - 1, 0);

				item->Draw(r.left, r.right, y, r.bottom, selected, colour);

				if (item->masked) {
					GfxFillRect(r.left + 1, y, r.right - 1, y + item_height - 1, _colour_gradient[colour][5], FILLRECT_CHECKER);
				}
			}
			y += item_height;
		}
	}
Ejemplo n.º 2
0
	virtual void OnPaint()
	{
		const int right = this->width - 5;

		GfxFillRect(0, 0, this->width - 1, this->height - 1, PC_BLACK);
		int ypos = this->height - this->line_height;
		for (const IConsoleLine *print = IConsoleLine::Get(IConsoleWindow::scroll); print != NULL; print = print->previous) {
			SetDParamStr(0, print->buffer);
			ypos = DrawStringMultiLine(5, right, -this->line_height, ypos, STR_JUST_RAW_STRING, print->colour, SA_LEFT | SA_BOTTOM | SA_FORCE) - ICON_LINE_SPACING;
			if (ypos < 0) break;
		}
		/* If the text is longer than the window, don't show the starting ']' */
		int delta = this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH;
		if (delta > 0) {
			DrawString(5, right, this->height - this->line_height, "]", (TextColour)CC_COMMAND, SA_LEFT | SA_FORCE);
			delta = 0;
		}

		/* If we have a marked area, draw a background highlight. */
		if (_iconsole_cmdline.marklength != 0) GfxFillRect(this->line_offset + delta + _iconsole_cmdline.markxoffs, this->height - this->line_height, this->line_offset + delta + _iconsole_cmdline.markxoffs + _iconsole_cmdline.marklength, this->height - 1, PC_DARK_RED);

		DrawString(this->line_offset + delta, right, this->height - this->line_height, _iconsole_cmdline.buf, (TextColour)CC_COMMAND, SA_LEFT | SA_FORCE);

		if (_focused_window == this && _iconsole_cmdline.caret) {
			DrawString(this->line_offset + delta + _iconsole_cmdline.caretxoffs, right, this->height - this->line_height, "_", TC_WHITE, SA_LEFT | SA_FORCE);
		}
	}
Ejemplo n.º 3
0
	virtual void DrawWidget(const Rect &r, int widget) const
	{
		switch (widget) {
			case WID_MTS_LIST_LEFT: {
				GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK);

				int y = r.top + WD_FRAMERECT_TOP;
				for (MusicSystem::Playlist::const_iterator song = _music.music_set.begin(); song != _music.music_set.end(); ++song) {
					SetDParam(0, song->tracknr);
					SetDParam(1, 2);
					SetDParamStr(2, song->songname);
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME);
					y += FONT_HEIGHT_SMALL;
				}
				break;
			}

			case WID_MTS_LIST_RIGHT: {
				GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK);

				int y = r.top + WD_FRAMERECT_TOP;
				for (MusicSystem::Playlist::const_iterator song = _music.active_playlist.begin(); song != _music.active_playlist.end(); ++song) {
					SetDParam(0, song->tracknr);
					SetDParam(1, 2);
					SetDParamStr(2, song->songname);
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME);
					y += FONT_HEIGHT_SMALL;
				}
				break;
			}
		}
	}
Ejemplo n.º 4
0
	virtual void DrawWidget(const Rect &r, int widget) const
	{
		switch (widget) {
			case ANGRFW_GRF_LIST: {
				GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, 0xD7);

				uint y = r.top + WD_FRAMERECT_TOP;
				uint min_index = this->vscroll.GetPosition();
				uint max_index = min(min_index + this->vscroll.GetCapacity(), this->grfs.Length());

				for (uint i = min_index; i < max_index; i++)
				{
					const GRFConfig *c = this->grfs[i];
					bool h = c == this->sel;
					const char *text = (!StrEmpty(c->name)) ? c->name : c->filename;

					/* Draw selection background */
					if (h) GfxFillRect(r.left + 1, y, r.right - 1, y + this->resize.step_height - 1, 156);
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, text, h ? TC_WHITE : TC_ORANGE);
					y += this->resize.step_height;
				}
				break;
			}

			case ANGRFW_GRF_INFO:
				if (this->sel != NULL) {
					ShowNewGRFInfo(this->sel, r.left + WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP, r.right - WD_FRAMERECT_RIGHT, r.bottom - WD_FRAMERECT_BOTTOM, false);
				}
				break;
		}
	}
Ejemplo n.º 5
0
	void DrawNewsBorder(const Rect &r) const
	{
		GfxFillRect(r.left,  r.top,    r.right, r.bottom, PC_WHITE);

		GfxFillRect(r.left,  r.top,    r.left,  r.bottom, PC_BLACK);
		GfxFillRect(r.right, r.top,    r.right, r.bottom, PC_BLACK);
		GfxFillRect(r.left,  r.top,    r.right, r.top,    PC_BLACK);
		GfxFillRect(r.left,  r.bottom, r.right, r.bottom, PC_BLACK);
	}
Ejemplo n.º 6
0
void DropDownListItem::Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
{
	int c1 = _colour_gradient[bg_colour][3];
	int c2 = _colour_gradient[bg_colour][7];

	int mid = top + this->Height(0) / 2;
	GfxFillRect(left + 1, mid - 2, right - 1, mid - 2, c1);
	GfxFillRect(left + 1, mid - 1, right - 1, mid - 1, c2);
}
Ejemplo n.º 7
0
	void DrawNewsBorder(const Rect &r) const
	{
		GfxFillRect(r.left,  r.top,    r.right, r.bottom, 0xF);

		GfxFillRect(r.left,  r.top,    r.left,  r.bottom, 0xD7);
		GfxFillRect(r.right, r.top,    r.right, r.bottom, 0xD7);
		GfxFillRect(r.left,  r.top,    r.right, r.top,    0xD7);
		GfxFillRect(r.left,  r.bottom, r.right, r.bottom, 0xD7);
	}
Ejemplo n.º 8
0
	virtual void DrawWidget(const Rect &r, int widget) const
	{
		switch (widget) {
			case WID_N_CAPTION:
				DrawCaption(r, COLOUR_LIGHT_BLUE, this->owner, STR_NEWS_MESSAGE_CAPTION);
				break;

			case WID_N_PANEL:
				this->DrawNewsBorder(r);
				break;

			case WID_N_MESSAGE:
				CopyInDParam(0, this->ni->params, lengthof(this->ni->params));
				DrawStringMultiLine(r.left, r.right, r.top, r.bottom, this->ni->string_id, TC_FROMSTRING, SA_CENTER);
				break;

			case WID_N_MGR_FACE: {
				const CompanyNewsInformation *cni = (const CompanyNewsInformation*)this->ni->free_data;
				DrawCompanyManagerFace(cni->face, cni->colour, r.left, r.top);
				GfxFillRect(r.left, r.top, r.right, r.bottom, PALETTE_NEWSPAPER, FILLRECT_RECOLOUR);
				break;
			}
			case WID_N_MGR_NAME: {
				const CompanyNewsInformation *cni = (const CompanyNewsInformation*)this->ni->free_data;
				SetDParamStr(0, cni->president_name);
				DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_JUST_RAW_STRING, TC_FROMSTRING, SA_CENTER);
				break;
			}
			case WID_N_COMPANY_MSG:
				DrawStringMultiLine(r.left, r.right, r.top, r.bottom, this->GetCompanyMessageString(), TC_FROMSTRING, SA_CENTER);
				break;

			case WID_N_VEH_BKGND:
				GfxFillRect(r.left, r.top, r.right, r.bottom, PC_GREY);
				break;

			case WID_N_VEH_NAME:
			case WID_N_VEH_TITLE:
				DrawStringMultiLine(r.left, r.right, r.top, r.bottom, this->GetNewVehicleMessageString(widget), TC_FROMSTRING, SA_CENTER);
				break;

			case WID_N_VEH_SPR: {
				assert(this->ni->reftype1 == NR_ENGINE);
				EngineID engine = this->ni->ref1;
				DrawVehicleEngine(r.left, r.right, (r.left + r.right) / 2, (r.top + r.bottom) / 2, engine, GetEnginePalette(engine, _local_company), EIT_PREVIEW);
				GfxFillRect(r.left, r.top, r.right, r.bottom, PALETTE_NEWSPAPER, FILLRECT_RECOLOUR);
				break;
			}
			case WID_N_VEH_INFO: {
				assert(this->ni->reftype1 == NR_ENGINE);
				EngineID engine = this->ni->ref1;
				DrawStringMultiLine(r.left, r.right, r.top, r.bottom, GetEngineInfoString(engine), TC_FROMSTRING, SA_CENTER);
				break;
			}
		}
	}
Ejemplo n.º 9
0
	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) {
						colour = 0xBF;
						if (i > 6) {
							colour = 0xB8;
						}
					}
					GfxFillRect(r.left, r.bottom - i * 2, r.right, r.bottom - i * 2, colour);
				}
				break;

			case MW_TRACK_NR: {
				GfxFillRect(r.left + 1, r.top + 1, r.right, r.bottom, 0);
				StringID str = STR_MUSIC_TRACK_NONE;
				if (_song_is_active != 0 && _music_wnd_cursong != 0) {
					SetDParam(0, GetTrackNumber(_music_wnd_cursong - 1));
					SetDParam(1, 2);
					str = STR_MUSIC_TRACK_DIGIT;
				}
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str);
				break;
			}

			case MW_TRACK_NAME: {
				GfxFillRect(r.left, r.top + 1, r.right - 1, r.bottom, 0);
				StringID str = STR_MUSIC_TITLE_NONE;
				if (_song_is_active != 0 && _music_wnd_cursong != 0) {
					str = STR_MUSIC_TITLE_NAME;
					SetDParamStr(0, GetSongName(_music_wnd_cursong - 1));
				}
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_FROMSTRING, SA_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 (_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;
			}
		}
	}
Ejemplo n.º 10
0
	virtual void DrawWidget(const Rect &r, int widget) const
	{
		/* There is only one widget. */
		GfxFillRect(r.left, r.top, r.right, r.bottom, PC_BLACK);
		GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_LIGHT_YELLOW);

		for (uint arg = 0; arg < this->paramcount; arg++) {
			SetDParam(arg, this->params[arg]);
		}
		DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, this->string_id, TC_FROMSTRING, SA_CENTER);
	}
	/**
	 * Draw/fill the matrix with the list of content to download.
	 * @param r The boundaries of the matrix.
	 */
	void DrawMatrix(const Rect &r) const
	{
		const NWidgetBase *nwi_checkbox = this->GetWidget<NWidgetBase>(WID_NCL_CHECKBOX);
		const NWidgetBase *nwi_name = this->GetWidget<NWidgetBase>(WID_NCL_NAME);
		const NWidgetBase *nwi_type = this->GetWidget<NWidgetBase>(WID_NCL_TYPE);


		/* Fill the matrix with the information */
		int sprite_y_offset = WD_MATRIX_TOP + (FONT_HEIGHT_NORMAL - 10) / 2;
		uint y = r.top;
		int cnt = 0;
		for (ConstContentIterator iter = this->content.Get(this->vscroll->GetPosition()); iter != this->content.End() && cnt < this->vscroll->GetCapacity(); iter++, cnt++) {
			const ContentInfo *ci = *iter;

			if (ci == this->selected) GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->resize.step_height - 1, PC_GREY);

			SpriteID sprite;
			SpriteID pal = PAL_NONE;
			switch (ci->state) {
				case ContentInfo::UNSELECTED:     sprite = SPR_BOX_EMPTY;   break;
				case ContentInfo::SELECTED:       sprite = SPR_BOX_CHECKED; break;
				case ContentInfo::AUTOSELECTED:   sprite = SPR_BOX_CHECKED; break;
				case ContentInfo::ALREADY_HERE:   sprite = SPR_BLOT; pal = PALETTE_TO_GREEN; break;
				case ContentInfo::DOES_NOT_EXIST: sprite = SPR_BLOT; pal = PALETTE_TO_RED;   break;
				default: NOT_REACHED();
			}
			DrawSprite(sprite, pal, nwi_checkbox->pos_x + (pal == PAL_NONE ? 2 : 3), y + sprite_y_offset + (pal == PAL_NONE ? 1 : 0));

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

			DrawString(nwi_name->pos_x + WD_FRAMERECT_LEFT, nwi_name->pos_x + nwi_name->current_x - WD_FRAMERECT_RIGHT, y + WD_MATRIX_TOP, ci->name, TC_BLACK);
			y += this->resize.step_height;
		}
	}
Ejemplo n.º 12
0
	virtual void DrawWidget(const Rect &r, int widget) const
	{
		switch (widget) {
			case BAIRW_AIRPORT_LIST: {
				int y = r.top;
				for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < AirportClass::GetCount(_selected_airport_class); i++) {
					const AirportSpec *as = AirportClass::Get(_selected_airport_class, i);
					if (!as->IsAvailable()) {
						GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->line_height - 2, PC_BLACK, FILLRECT_CHECKER);
					}
					DrawString(r.left + WD_MATRIX_LEFT, r.right + WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, as->name, ((int)i == _selected_airport_index) ? TC_WHITE : TC_BLACK);
					y += this->line_height;
				}
				break;
			}

			case BAIRW_AIRPORT_SPRITE:
				if (this->preview_sprite != 0) {
					Dimension d = GetSpriteSize(this->preview_sprite);
					DrawSprite(this->preview_sprite, COMPANY_SPRITE_COLOUR(_local_company), (r.left + r.right - d.width) / 2, (r.top + r.bottom - d.height) / 2);
				}
				break;

			case BAIRW_EXTRA_TEXT:
				if (_selected_airport_index != -1) {
					const AirportSpec *as = AirportClass::Get(_selected_airport_class, _selected_airport_index);
					StringID string = GetAirportTextCallback(as, _selected_airport_layout, CBID_AIRPORT_ADDITIONAL_TEXT);
					if (string != STR_UNDEFINED) {
						SetDParam(0, string);
						DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_BLACK_STRING);
					}
				}
				break;
		}
	}
Ejemplo n.º 13
0
	/**
	 * Draw a row in the group list.
	 * @param y Top of the row.
	 * @param left Left of the row.
	 * @param right Right of the row.
	 * @param g_id Group to list.
	 * @param indent Indentation level.
	 * @param protection Whether autoreplace protection is set.
	 */
	void DrawGroupInfo(int y, int left, int right, GroupID g_id, int indent = 0, bool protection = false) const
	{
		/* Highlight the group if a vehicle is dragged over it */
		if (g_id == this->group_over) {
			GfxFillRect(left + WD_FRAMERECT_LEFT, y + WD_FRAMERECT_TOP + WD_MATRIX_TOP, right - WD_FRAMERECT_RIGHT, y + this->tiny_step_height - WD_FRAMERECT_BOTTOM - WD_MATRIX_TOP, _colour_gradient[COLOUR_GREY][7]);
		}

		if (g_id == NEW_GROUP) return;

		/* draw the selected group in white, else we draw it in black */
		TextColour colour = g_id == this->vli.index ? TC_WHITE : TC_BLACK;
		const GroupStatistics &stats = GroupStatistics::Get(this->vli.company, g_id, this->vli.vtype);
		bool rtl = _current_text_dir == TD_RTL;

		/* draw group name */
		int longer_name = 0;
		StringID str;
		if (IsAllGroupID(g_id)) {
			str = STR_GROUP_ALL_TRAINS + this->vli.vtype;
		} else if (IsDefaultGroupID(g_id)) {
			str = STR_GROUP_DEFAULT_TRAINS + this->vli.vtype;
		} else {
			SetDParam(0, g_id);
			str = STR_GROUP_NAME;
			if (!protection) {
				longer_name += this->column_size[VGC_PROTECT].width + 2;
				if (!stats.autoreplace_defined) longer_name += this->column_size[VGC_AUTOREPLACE].width + 2;
			}
		}
		int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this->column_size[VGC_NAME].width - longer_name + 1 : left + WD_FRAMERECT_LEFT + 8;
		DrawString(x + indent * LEVEL_WIDTH, x + this->column_size[VGC_NAME].width + longer_name - 1, y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour);

		/* draw autoreplace protection */
		x = rtl ? x - 2 - this->column_size[VGC_PROTECT].width : x + 2 + this->column_size[VGC_NAME].width;
		if (protection) DrawSprite(SPR_GROUP_REPLACE_PROTECT, PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_PROTECT].height) / 2);

		/* draw autoreplace status */
		x = rtl ? x - 2 - this->column_size[VGC_AUTOREPLACE].width : x + 2 + this->column_size[VGC_PROTECT].width;
		if (stats.autoreplace_defined) DrawSprite(SPR_GROUP_REPLACE_ACTIVE, stats.autoreplace_finished ? PALETTE_CRASH : PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_AUTOREPLACE].height) / 2);

		/* draw the profit icon */
		x = rtl ? x - 2 - this->column_size[VGC_PROFIT].width : x + 2 + this->column_size[VGC_AUTOREPLACE].width;
		SpriteID spr;
		if (stats.num_profit_vehicle == 0) {
			spr = SPR_PROFIT_NA;
		} else if (stats.profit_last_year < 0) {
			spr = SPR_PROFIT_NEGATIVE;
		} else if (stats.profit_last_year < 10000 * stats.num_profit_vehicle) { // TODO magic number
			spr = SPR_PROFIT_SOME;
		} else {
			spr = SPR_PROFIT_LOT;
		}
		DrawSprite(spr, PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_PROFIT].height) / 2);

		/* draw the number of vehicles of the group */
		x = rtl ? x - 2 - this->column_size[VGC_NUMBER].width : x + 2 + this->column_size[VGC_PROFIT].width;
		SetDParam(0, stats.num_vehicle);
		DrawString(x, x + this->column_size[VGC_NUMBER].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NUMBER].height) / 2, STR_TINY_COMMA, colour, SA_RIGHT | SA_FORCE);
	}
Ejemplo n.º 14
0
	virtual void DrawWidget(const Rect &r, int widget) const
	{
		switch (widget) {
			case WID_M_TRACK_NR: {
				GfxFillRect(r.left + 1, r.top + 1, r.right, r.bottom, PC_BLACK);
				if (BaseMusic::GetUsedSet()->num_available == 0) {
					break;
				}
				StringID str = STR_MUSIC_TRACK_NONE;
				if (_music.IsPlaying()) {
					SetDParam(0, _music.GetCurrentSong().tracknr);
					SetDParam(1, 2);
					str = STR_MUSIC_TRACK_DIGIT;
				}
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str);
				break;
			}

			case WID_M_TRACK_NAME: {
				GfxFillRect(r.left, r.top + 1, r.right - 1, r.bottom, PC_BLACK);
				StringID str = STR_MUSIC_TITLE_NONE;
				if (BaseMusic::GetUsedSet()->num_available == 0) {
					str = STR_MUSIC_TITLE_NOMUSIC;
				} else if (_music.IsPlaying()) {
					str = STR_MUSIC_TITLE_NAME;
					SetDParamStr(0, _music.GetCurrentSong().songname);
				}
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_FROMSTRING, SA_HOR_CENTER);
				break;
			}

			case WID_M_MUSIC_VOL: case WID_M_EFFECT_VOL: {
				int sw = ScaleGUITrad(slider_width);
				int hsw = sw / 2;
				DrawFrameRect(r.left + hsw, r.top + 2, r.right - hsw, r.bottom - 2, COLOUR_GREY, FR_LOWERED);
				byte volume = (widget == WID_M_MUSIC_VOL) ? _settings_client.music.music_vol : _settings_client.music.effect_vol;
				if (_current_text_dir == TD_RTL) volume = 127 - volume;
				int x = r.left + (volume * (r.right - r.left - sw) / 127);
				DrawFrameRect(x, r.top, x + sw, r.bottom, COLOUR_GREY, FR_NONE);
				break;
			}
		}
	}
/** Draw the chat message-box */
void NetworkDrawChatMessage()
{
	Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter();
	if (!_chatmessage_dirty) return;

	/* First undraw if needed */
	NetworkUndrawChatMessage();

	if (_iconsole_mode == ICONSOLE_FULL) return;

	/* Check if we have anything to draw at all */
	uint count = GetChatMessageCount();
	if (count == 0) return;

	int x      = _chatmsg_box.x;
	int y      = _screen.height - _chatmsg_box.y - _chatmsg_box.height;
	int width  = _chatmsg_box.width;
	int height = _chatmsg_box.height;
	if (y < 0) {
		height = max(height + y, min(_chatmsg_box.height, _screen.height));
		y = 0;
	}
	if (x + width >= _screen.width) {
		width = _screen.width - x;
	}
	if (width <= 0 || height <= 0) return;

	assert(blitter->BufferSize(width, height) <= (int)(_chatmsg_box.width * _chatmsg_box.height * blitter->GetBytesPerPixel()));

	/* Make a copy of the screen as it is before painting (for undraw) */
	blitter->CopyToBuffer(blitter->MoveTo(_screen.dst_ptr, x, y), _chatmessage_backup, width, height);

	_cur_dpi = &_screen; // switch to _screen painting

	/* Paint a half-transparent box behind the chat messages */
	GfxFillRect(
			_chatmsg_box.x,
			_screen.height - _chatmsg_box.y - count * (FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING) - 2,
			_chatmsg_box.x + _chatmsg_box.width - 1,
			_screen.height - _chatmsg_box.y - 2,
			PALETTE_TO_TRANSPARENT, FILLRECT_RECOLOUR // black, but with some alpha for background
		);

	/* Paint the chat messages starting with the lowest at the bottom */
	for (uint y = FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING; count-- != 0; y += (FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING)) {
		DrawString(_chatmsg_box.x + 3, _chatmsg_box.x + _chatmsg_box.width - 1, _screen.height - _chatmsg_box.y - y + 1, _chatmsg_list[count].message, _chatmsg_list[count].colour);
	}

	/* Make sure the data is updated next flush */
	_video_driver->MakeDirty(x, y, width, height);

	_chatmessage_visible = true;
	_chatmessage_dirty = false;
}
Ejemplo n.º 16
0
	virtual void DrawWidget(const Rect &r, int widget) const
	{
		switch (widget) {
			case WID_MTS_LIST_LEFT: {
				GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK);

				int y = r.top + WD_FRAMERECT_TOP;
				uint vscroll_max = min(this->left_sb->GetPosition() + this->left_sb->GetCapacity(), NUM_SONGS_AVAILABLE);

				for (uint i = this->left_sb->GetPosition(); i < vscroll_max; i++) {
					const char *song_name = GetSongName(i);
					if (StrEmpty(song_name)) continue;

					SetDParam(0, GetTrackNumber(i));
					SetDParam(1, 2);
					SetDParamStr(2, song_name);
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(y, this->resize.step_height, FONT_HEIGHT_SMALL), STR_PLAYLIST_TRACK_NAME);
					y += this->resize.step_height;
				}
				break;
			}

			case WID_MTS_LIST_RIGHT: {
				GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK);

				int y = r.top + WD_FRAMERECT_TOP;
				uint vscroll_max = min(this->right_sb->GetPosition() + this->right_sb->GetCapacity(), this->GetNumberOfTracksOfTracklist());

				for (uint i = this->right_sb->GetPosition(); i < vscroll_max; i++) {
					uint j = _playlists[_settings_client.music.playlist][i] - 1;
					SetDParam(0, GetTrackNumber(j));
					SetDParam(1, 2);
					SetDParamStr(2, GetSongName(j));
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(y, this->resize.step_height, FONT_HEIGHT_SMALL), STR_PLAYLIST_TRACK_NAME);
					y += this->resize.step_height;
				}
				break;
			}
		}
	}
Ejemplo n.º 17
0
	virtual void DrawWidget(const Rect &r, int widget) const
	{
		switch (widget) {
			case WID_M_TRACK_NR: {
				GfxFillRect(r.left + 1, r.top + 1, r.right, r.bottom, PC_BLACK);
				StringID str = STR_MUSIC_TRACK_NONE;
				if (_song_is_active != 0 && _music_wnd_cursong != 0) {
					SetDParam(0, GetTrackNumber(_music_wnd_cursong - 1));
					SetDParam(1, 2);
					str = STR_MUSIC_TRACK_DIGIT;
				}
				DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(r.top, r.bottom - r.top, FONT_HEIGHT_SMALL), str);
				break;
			}

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

			case WID_M_MUSIC_VOL: case WID_M_EFFECT_VOL: {
				DrawFrameRect(r.left, r.top + 2, r.right, r.bottom - 2, COLOUR_GREY, FR_LOWERED);
				byte volume = (widget == WID_M_MUSIC_VOL) ? _settings_client.music.music_vol : _settings_client.music.effect_vol;
				int x = (volume * (r.right - r.left) / 127);
				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;
			}
		}
	}
Ejemplo n.º 18
0
	virtual void DrawWidget(const Rect &r, int widget) const
	{
		switch (widget) {
			case MTSW_LIST_LEFT: {
				GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, 0);

				int y = r.top + WD_FRAMERECT_TOP;
				for (uint i = 0; i < NUM_SONGS_AVAILABLE; i++) {
					const char *song_name = GetSongName(i);
					if (StrEmpty(song_name)) continue;

					SetDParam(0, GetTrackNumber(i));
					SetDParam(1, 2);
					SetDParamStr(2, song_name);
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME);
					y += FONT_HEIGHT_SMALL;
				}
				break;
			}

			case MTSW_LIST_RIGHT: {
				GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, 0);

				int y = r.top + WD_FRAMERECT_TOP;
				for (const byte *p = _playlists[_msf.playlist]; *p != 0; p++) {
					uint i = *p - 1;
					SetDParam(0, GetTrackNumber(i));
					SetDParam(1, 2);
					SetDParamStr(2, GetSongName(i));
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME);
					y += FONT_HEIGHT_SMALL;
				}
				break;
			}
		}
	}
Ejemplo n.º 19
0
/**
 * 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 = _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]);
	}

	return drag_hlight_width;
}
Ejemplo n.º 20
0
/**
 * 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.
 * @param chain     Whether a whole chain is dragged.
 * @return The width of the highlight mark.
 */
static int HighlightDragPosition(int px, int max_width, VehicleID selection, bool chain)
{
	bool rtl = _current_text_dir == TD_RTL;

	assert(selection != INVALID_VEHICLE);
	int dragged_width = WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
	for (Train *t = Train::Get(selection); t != NULL; t = chain ? t->Next() : (t->HasArticulatedPart() ? t->GetNextArticulatedPart() : NULL)) {
		dragged_width += t->GetDisplayImageWidth(NULL);
	}

	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, ScaleGUITrad(13) - WD_FRAMERECT_BOTTOM, _colour_gradient[COLOUR_GREY][7]);
	}

	return drag_hlight_width;
}
Ejemplo n.º 21
0
void DeparturesWindow<Twaypoint>::DrawDeparturesListItems(const Rect &r) const
{
	int left = r.left + WD_MATRIX_LEFT;
	int right = r.right - WD_MATRIX_RIGHT;

	bool rtl = _current_text_dir == TD_RTL;
	bool ltr = !rtl;

	int text_offset = WD_FRAMERECT_RIGHT;
	int text_left  = left  + (rtl ?           0 : text_offset);
	int text_right = right - (rtl ? text_offset :           0);

	int y = r.top + 1;
	uint max_departures = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->departures->Length() + this->arrivals->Length());

	if (max_departures > _settings_client.gui.max_departures) {
		max_departures = _settings_client.gui.max_departures;
	}

	byte small_font_size = _settings_client.gui.departure_larger_font ? FONT_HEIGHT_NORMAL : FONT_HEIGHT_SMALL;

	/* Draw the black background. */
	GfxFillRect(r.left + 1, r.top, r.right - 1, r.bottom, PC_BLACK);

	/* Nothing selected? Then display the information text. */
	bool none_selected[2] = {true, true};
	for (uint i = 0; i < 4; ++i)
	{
		if (this->show_types[i]) {
			none_selected[0] = false;
			break;
		}
	}

	for (uint i = 0; i < 2; ++i)
	{
		if (this->departure_types[i]) {
			none_selected[1] = false;
			break;
		}
	}

	if (none_selected[0] || none_selected[1]) {
		DrawString(text_left, text_right, y + 1, STR_DEPARTURES_NONE_SELECTED);
		return;
	}

	/* No scheduled departures? Then display the information text. */
	if (max_departures == 0) {
		DrawString(text_left, text_right, y + 1, STR_DEPARTURES_EMPTY);
		return;
	}

	/* Find the maximum possible width of the departure time and "Expt <time>" fields. */
	int time_width = cached_date_width;

	if (!_settings_client.gui.departure_show_both) {
		time_width += (departure_types[0] && departure_types[1] ? cached_date_arrow_width : 0);
	}

	/* Vehicle type icon */
	int type_width = _settings_client.gui.departure_show_vehicle_type ? (GetStringBoundingBox(STR_DEPARTURES_TYPE_PLANE)).width : 0;

	/* Find the maximum width of the status field */
	int status_width = cached_status_width;

	/* Find the width of the "Calling at:" field. */
	int calling_at_width = (GetStringBoundingBox(_settings_client.gui.departure_larger_font ? STR_DEPARTURES_CALLING_AT_LARGE : STR_DEPARTURES_CALLING_AT)).width;

	/* Find the maximum company name width. */
	int toc_width = 0;

	/* Find the maximum group name width. */
	int group_width = 0;

	/* Find the maximum vehicle name width. */
	int veh_width = 0;

	if (_settings_client.gui.departure_show_vehicle || _settings_client.gui.departure_show_company || _settings_client.gui.departure_show_group) {
		for (uint i = 0; i < 4; ++i) {
			VehicleList vehicles;

			/* MAX_COMPANIES is probably the wrong thing to put here, but it works. GenerateVehicleSortList doesn't check the company when the type of list is VL_STATION_LIST (r20801). */
			if (!GenerateVehicleSortList(&vehicles, VehicleListIdentifier(VL_STATION_LIST, (VehicleType)(VEH_TRAIN + i), MAX_COMPANIES, station).Pack())) {
				/* Something went wrong: panic! */
				continue;
			}

			for (const Vehicle **v = vehicles.Begin(); v != vehicles.End(); v++) {
				SetDParam(0, (uint64)((*v)->index));
				int width = (GetStringBoundingBox(STR_DEPARTURES_VEH)).width;
				if (_settings_client.gui.departure_show_vehicle && width > veh_width) veh_width = width;

				if ((*v)->group_id != INVALID_GROUP && (*v)->group_id != DEFAULT_GROUP) {
					SetDParam(0, (uint64)((*v)->group_id));
					width = (GetStringBoundingBox(STR_DEPARTURES_GROUP)).width;
					if (_settings_client.gui.departure_show_group && width > group_width) group_width = width;
				}

				SetDParam(0, (uint64)((*v)->owner));
				width = (GetStringBoundingBox(STR_DEPARTURES_TOC)).width;
				if (_settings_client.gui.departure_show_company && width > toc_width) toc_width = width;
			}
		}
	}

	uint departure = 0;
	uint arrival = 0;

	/* Draw each departure. */
	for (uint i = 0; i < max_departures; ++i) {
		const Departure *d;

		if (arrival == this->arrivals->Length()) {
			d = (*(this->departures))[departure++];
		} else if (departure == this->departures->Length()) {
			d = (*(this->arrivals))[arrival++];
		} else {
			d = (*(this->departures))[departure];
			const Departure *a = (*(this->arrivals))[arrival];

			if (a->scheduled_date < d->scheduled_date) {
				d = a;
				arrival++;
			} else {
				departure++;
			}
		}

		if (i < this->vscroll->GetPosition()) {
			continue;
		}

		/* If for some reason the departure is too far in the future or is at a negative time, skip it. */
		if ((d->scheduled_date / DAY_TICKS) > (_date + _settings_client.gui.max_departure_time) ||
			d->scheduled_date < 0) {
			continue;
		}

		if (d->terminus == INVALID_STATION) continue;

		StringID time_str = (departure_types[0] && departure_types[1]) ? (d->type == D_DEPARTURE ? STR_DEPARTURES_TIME_DEP : STR_DEPARTURES_TIME_ARR) : STR_DEPARTURES_TIME;

		if (_settings_client.gui.departure_show_both) time_str = STR_DEPARTURES_TIME_BOTH;

		/* Time */
		SetDParam(0, d->scheduled_date);
		SetDParam(1, d->scheduled_date - d->order->wait_time);
		ltr ? DrawString(              text_left, text_left + time_width, y + 1, time_str)
			: DrawString(text_right - time_width,             text_right, y + 1, time_str);

		/* Vehicle type icon, with thanks to sph */
		if (_settings_client.gui.departure_show_vehicle_type) {
			StringID type = STR_DEPARTURES_TYPE_TRAIN;
			int offset = (_settings_client.gui.departure_show_vehicle_color ? 1 : 0);

			switch (d->vehicle->type) {
				case VEH_TRAIN:
					type = STR_DEPARTURES_TYPE_TRAIN;
					break;
				case VEH_ROAD:
					type = IsCargoInClass(d->vehicle->cargo_type, CC_PASSENGERS) ? STR_DEPARTURES_TYPE_BUS : STR_DEPARTURES_TYPE_LORRY;
					break;
				case VEH_SHIP:
					type = STR_DEPARTURES_TYPE_SHIP;
					break;
				case VEH_AIRCRAFT:
					type = STR_DEPARTURES_TYPE_PLANE;
					break;
				default:
					break;
			}

			type += offset;

			DrawString(text_left + time_width + 3, text_left + time_width + type_width + 3, y, type);
		}

		/* The icons to show with the destination and via stations. */
		StringID icon = STR_DEPARTURES_STATION_NONE;
		StringID icon_via = STR_DEPARTURES_STATION_NONE;

		if (_settings_client.gui.departure_destination_type) {
			Station *t = Station::Get(d->terminus.station);

			if (t->facilities & FACIL_DOCK &&
					t->facilities & FACIL_AIRPORT &&
					d->vehicle->type != VEH_SHIP &&
					d->vehicle->type != VEH_AIRCRAFT) {
				icon = STR_DEPARTURES_STATION_PORTAIRPORT;
			} else if (t->facilities & FACIL_DOCK &&
					d->vehicle->type != VEH_SHIP) {
				icon = STR_DEPARTURES_STATION_PORT;
			} else if (t->facilities & FACIL_AIRPORT &&
					d->vehicle->type != VEH_AIRCRAFT) {
				icon = STR_DEPARTURES_STATION_AIRPORT;
			}
		}

		if (_settings_client.gui.departure_destination_type && d->via != INVALID_STATION) {
			Station *t = Station::Get(d->via);

			if (t->facilities & FACIL_DOCK &&
					t->facilities & FACIL_AIRPORT &&
					d->vehicle->type != VEH_SHIP &&
					d->vehicle->type != VEH_AIRCRAFT) {
				icon_via = STR_DEPARTURES_STATION_PORTAIRPORT;
			} else if (t->facilities & FACIL_DOCK &&
					d->vehicle->type != VEH_SHIP) {
				icon_via = STR_DEPARTURES_STATION_PORT;
			} else if (t->facilities & FACIL_AIRPORT &&
					d->vehicle->type != VEH_AIRCRAFT) {
				icon_via = STR_DEPARTURES_STATION_AIRPORT;
			}
		}

		/* Destination */
		if (d->via == INVALID_STATION) {
			/* Only show the terminus. */
			SetDParam(0, d->terminus.station);
			SetDParam(1, icon);
			ltr ? DrawString(              text_left + time_width + type_width + 6,   text_right - status_width - (toc_width + veh_width + group_width + 2) - 2, y + 1, STR_DEPARTURES_TERMINUS)
				: DrawString(text_left + status_width + (toc_width + veh_width + group_width + 2) + 2,                 text_right - time_width - type_width - 6, y + 1, STR_DEPARTURES_TERMINUS);
		} else {
			/* Show the terminus and the via station. */
			SetDParam(0, d->terminus.station);
			SetDParam(1, icon);
			SetDParam(2, d->via);
			SetDParam(3, icon_via);
			int text_width = (GetStringBoundingBox(STR_DEPARTURES_TERMINUS_VIA_STATION)).width;

			if (text_width < text_right - status_width - (toc_width + veh_width + group_width + 2) - 2 - (text_left + time_width + type_width + 6)) {
				/* They will both fit, so show them both. */
				SetDParam(0, d->terminus.station);
				SetDParam(1, icon);
				SetDParam(2, d->via);
				SetDParam(3, icon_via);
				ltr ? DrawString(              text_left + time_width + type_width + 6, text_right - status_width - (toc_width + veh_width + group_width + 2) - 2, y + 1, STR_DEPARTURES_TERMINUS_VIA_STATION)
					: DrawString(text_left + status_width + (toc_width + veh_width + group_width + 2) + 2,               text_right - time_width - type_width - 6, y + 1, STR_DEPARTURES_TERMINUS_VIA_STATION);
			} else {
				/* They won't both fit, so switch between showing the terminus and the via station approximately every 4 seconds. */
				if (this->tick_count & (1 << 7)) {
					SetDParam(0, d->via);
					SetDParam(1, icon_via);
					ltr ? DrawString(              text_left + time_width + type_width + 6, text_right - status_width - (toc_width + veh_width + group_width + 2) - 2, y + 1, STR_DEPARTURES_VIA)
						: DrawString(text_left + status_width + (toc_width + veh_width + group_width + 2) + 2,               text_right - time_width - type_width - 6, y + 1, STR_DEPARTURES_VIA);
				} else {
					SetDParam(0, d->terminus.station);
					SetDParam(1, icon);
					ltr ? DrawString(              text_left + time_width + type_width + 6, text_right - status_width - (toc_width + veh_width + group_width + 2) - 2, y + 1, STR_DEPARTURES_TERMINUS_VIA)
						: DrawString(text_left + status_width + (toc_width + veh_width + group_width + 2) + 2,               text_right - time_width - type_width - 6, y + 1, STR_DEPARTURES_TERMINUS_VIA);
				}
			}
		}

		/* Status */
		{
			int status_left = ltr ? text_right - status_width - 2 - (toc_width + veh_width + group_width + 2) : text_left + (toc_width + veh_width + group_width + 2) + 7;
			int status_right = ltr ? text_right - (toc_width + veh_width + group_width + 2) + 2 : text_left + status_width + 2 + (toc_width + veh_width + group_width + 7);

			if (d->status == D_ARRIVED) {
				/* The vehicle has arrived. */
				DrawString(status_left, status_right, y + 1, STR_DEPARTURES_ARRIVED);
			} else if(d->status == D_CANCELLED) {
				/* The vehicle has been cancelled. */
				DrawString(status_left, status_right, y + 1, STR_DEPARTURES_CANCELLED);
			} else{
				if (d->lateness <= DAY_TICKS && d->scheduled_date > ((_date * DAY_TICKS) + _date_fract)) {
					/* We have no evidence that the vehicle is late, so assume it is on time. */
					DrawString(status_left, status_right, y + 1, STR_DEPARTURES_ON_TIME);
				} else {
					if ((d->scheduled_date + d->lateness) < ((_date * DAY_TICKS) + _date_fract)) {
						/* The vehicle was expected to have arrived by now, even if we knew it was going to be late. */
						/* We assume that the train stays at least a day at a station so it won't accidentally be marked as delayed for a fraction of a day. */
						DrawString(status_left, status_right, y + 1, STR_DEPARTURES_DELAYED);
					} else {
						/* The vehicle is expected to be late and is not yet due to arrive. */
						SetDParam(0, d->scheduled_date + d->lateness);
						DrawString(status_left, status_right, y + 1, STR_DEPARTURES_EXPECTED);
					}
				}
			}
		}

		/* Vehicle name */

		if (_settings_client.gui.departure_show_vehicle) {
			SetDParam(0, (uint64)(d->vehicle->index));
			ltr ? DrawString(text_right - (toc_width + veh_width + group_width + 2),              text_right - toc_width - group_width - 2, y + 1, STR_DEPARTURES_VEH)
				: DrawString(               text_left + toc_width + group_width + 2, text_left + (toc_width + veh_width + group_width + 2), y + 1, STR_DEPARTURES_VEH);
		}

		/* Group name */

		if (_settings_client.gui.departure_show_group && d->vehicle->group_id != INVALID_GROUP && d->vehicle->group_id != DEFAULT_GROUP) {
			SetDParam(0, (uint64)(d->vehicle->group_id));
			ltr ? DrawString(text_right - (toc_width + group_width + 2),              text_right - toc_width - 2, y + 1, STR_DEPARTURES_GROUP)
				: DrawString(               text_left + toc_width + 2, text_left + (toc_width + group_width + 2), y + 1, STR_DEPARTURES_GROUP);
		}

		/* Operating company */
		if (_settings_client.gui.departure_show_company) {
			SetDParam(0, (uint64)(d->vehicle->owner));
			ltr ? DrawString(text_right - toc_width,            text_right, y + 1, STR_DEPARTURES_TOC, TC_FROMSTRING, SA_RIGHT)
				: DrawString(             text_left, text_left + toc_width, y + 1, STR_DEPARTURES_TOC, TC_FROMSTRING, SA_LEFT);
		}

		int bottom_y = y + this->entry_height - small_font_size - (_settings_client.gui.departure_larger_font ? 1 : 3);

		/* Calling at */
		ltr ? DrawString(                    text_left,  text_left + calling_at_width, bottom_y, _settings_client.gui.departure_larger_font ? STR_DEPARTURES_CALLING_AT_LARGE : STR_DEPARTURES_CALLING_AT)
			: DrawString(text_right - calling_at_width,                    text_right, bottom_y, _settings_client.gui.departure_larger_font ? STR_DEPARTURES_CALLING_AT_LARGE : STR_DEPARTURES_CALLING_AT);

		/* List of stations */
		/* RTL languages can be handled in the language file, e.g. by having the following: */
		/* STR_DEPARTURES_CALLING_AT_STATION      :{STATION}, {RAW_STRING} */
		/* STR_DEPARTURES_CALLING_AT_LAST_STATION :{STATION} & {RAW_STRING}*/
		char buffer[512], scratch[512];

		if (d->calling_at.Length() != 0) {
			SetDParam(0, (uint64)(*d->calling_at.Get(0)).station);
			GetString(scratch, STR_DEPARTURES_CALLING_AT_FIRST_STATION, lastof(scratch));

			StationID continuesTo = INVALID_STATION;

			if (d->calling_at.Get(0)->station == d->terminus.station && d->calling_at.Length() > 1) {
				continuesTo = d->calling_at.Get(d->calling_at.Length() - 1)->station;
			} else if (d->calling_at.Length() > 1) {
				/* There's more than one stop. */

				uint i;
				/* For all but the last station, write out ", <station>". */
				for (i = 1; i < d->calling_at.Length() - 1; ++i) {
					StationID s = d->calling_at.Get(i)->station;
					if (s == d->terminus.station) {
						continuesTo = d->calling_at.Get(d->calling_at.Length() - 1)->station;
						break;
					}
					SetDParam(0, (uint64)scratch);
					SetDParam(1, (uint64)s);
					GetString(buffer, STR_DEPARTURES_CALLING_AT_STATION, lastof(buffer));
					strncpy(scratch, buffer, sizeof(scratch));
				}

				/* Finally, finish off with " and <station>". */
				SetDParam(0, (uint64)scratch);
				SetDParam(1, (uint64)d->calling_at.Get(i)->station);
				GetString(buffer, STR_DEPARTURES_CALLING_AT_LAST_STATION, lastof(buffer));
				strncpy(scratch, buffer, sizeof(scratch));
			}

			SetDParam(0, (uint64)scratch);
			StringID string;
			if (continuesTo == INVALID_STATION) {
				string = _settings_client.gui.departure_larger_font ? STR_DEPARTURES_CALLING_AT_LIST_LARGE : STR_DEPARTURES_CALLING_AT_LIST;
			} else {
				SetDParam(1, continuesTo);
				string = _settings_client.gui.departure_larger_font ? STR_DEPARTURES_CALLING_AT_LIST_SMART_TERMINUS_LARGE : STR_DEPARTURES_CALLING_AT_LIST_SMART_TERMINUS;
			}
			GetString(buffer, string, lastof(buffer));
		} else {
			buffer[0] = 0;
			//SetDParam(0, d->terminus);
			//GetString(scratch, STR_DEPARTURES_CALLING_AT_FIRST_STATION, lastof(scratch));
		}

		int list_width = (GetStringBoundingBox(buffer, _settings_client.gui.departure_larger_font ? FS_NORMAL : FS_SMALL)).width;

		/* Draw the whole list if it will fit. Otherwise scroll it. */
		if (list_width < text_right - (text_left + calling_at_width + 2)) {
			ltr ? DrawString(text_left + calling_at_width + 2,                        text_right, bottom_y, buffer)
				: DrawString(                       text_left, text_right - calling_at_width - 2, bottom_y, buffer);
		} else {
			DrawPixelInfo tmp_dpi;
			if (ltr
				? !FillDrawPixelInfo(&tmp_dpi, text_left + calling_at_width + 2, bottom_y, text_right - (text_left + calling_at_width + 2), small_font_size + 3)
				: !FillDrawPixelInfo(&tmp_dpi, text_left                       , bottom_y, text_right - (text_left + calling_at_width + 2), small_font_size + 3)) {
				y += this->entry_height;
				continue;
			}
			DrawPixelInfo *old_dpi = _cur_dpi;
			_cur_dpi = &tmp_dpi;

			/* The scrolling text starts out of view at the right of the screen and finishes when it is out of view at the left of the screen. */
			int pos = ltr
				? text_right - (this->tick_count % (list_width + text_right - text_left))
				:  text_left + (this->tick_count % (list_width + text_right - text_left));

			ltr ? DrawString(       pos, INT16_MAX, 0, buffer, TC_FROMSTRING,  SA_LEFT | SA_FORCE)
				: DrawString(-INT16_MAX,       pos, 0, buffer, TC_FROMSTRING, SA_RIGHT | SA_FORCE);

			_cur_dpi = old_dpi;
		}

		y += this->entry_height;
	}
}
Ejemplo n.º 22
0
    virtual void DrawWidget(const Rect &r, int widget) const
    {
        switch (widget) {
        case SLWW_SORT_BYNAME:
        case SLWW_SORT_BYDATE:
            if (((_savegame_sort_order & SORT_BY_NAME) != 0) == (widget == SLWW_SORT_BYNAME)) {
                this->DrawSortButtonState(widget, _savegame_sort_order & SORT_DESCENDING ? SBS_DOWN : SBS_UP);
            }
            break;

        case SLWW_BACKGROUND: {
            static const char *path = NULL;
            static StringID str = STR_ERROR_UNABLE_TO_READ_DRIVE;
            static uint64 tot = 0;

            if (_fios_path_changed) {
                str = FiosGetDescText(&path, &tot);
                _fios_path_changed = false;
            }

            if (str != STR_ERROR_UNABLE_TO_READ_DRIVE) SetDParam(0, tot);
            DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP, str);
            DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, path, TC_BLACK);
        }
        break;

        case SLWW_DRIVES_DIRECTORIES_LIST: {
            GfxFillRect(r.left + 1, r.top + 1, r.right, r.bottom, 0xD7);

            uint y = r.top + WD_FRAMERECT_TOP;
            for (uint pos = this->vscroll.GetPosition(); pos < _fios_items.Length(); pos++) {
                const FiosItem *item = _fios_items.Get(pos);

                if (item == this->selected) {
                    GfxFillRect(r.left + 1, y, r.right, y + this->resize.step_height, 156);
                }
                DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, item->title, _fios_colours[item->type]);
                y += this->resize.step_height;
                if (y >= this->vscroll.GetCapacity() * this->resize.step_height + r.top + WD_FRAMERECT_TOP) break;
            }
        }
        break;

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

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

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

            if (y > y_max) break;
            if (!_load_check_data.checkable) {
                /* Old savegame, no information available */
                DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_NOT_AVAILABLE);
                y += FONT_HEIGHT_NORMAL;
            } else if (_load_check_data.error != INVALID_STRING_ID) {
                /* Incompatible / broken savegame */
                SetDParamStr(0, _load_check_data.error_data);
                y = DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT,
                                        y, r.bottom - WD_FRAMERECT_BOTTOM, _load_check_data.error, TC_RED);
            } else {
                /* Mapsize */
                SetDParam(0, _load_check_data.map_size_x);
                SetDParam(1, _load_check_data.map_size_y);
                DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_MAP_SIZE);
                y += FONT_HEIGHT_NORMAL;
                if (y > y_max) break;

                /* Climate */
                byte landscape = _load_check_data.settings.game_creation.landscape;
                if (landscape < NUM_LANDSCAPE) {
                    SetDParam(0, STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE + landscape);
                    DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_LANDSCAPE);
                    y += FONT_HEIGHT_NORMAL;
                }

                y += WD_PAR_VSEP_NORMAL;
                if (y > y_max) break;

                /* Start date (if available) */
                if (_load_check_data.settings.game_creation.starting_year != 0) {
                    SetDParam(0, ConvertYMDToDate(_load_check_data.settings.game_creation.starting_year, 0, 1));
                    DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_START_DATE);
                    y += FONT_HEIGHT_NORMAL;
                }
                if (y > y_max) break;

                /* Hide current date for scenarios */
                if (_saveload_mode != SLD_LOAD_SCENARIO && _saveload_mode != SLD_SAVE_SCENARIO) {
                    /* Current date */
                    SetDParam(0, _load_check_data.current_date);
                    DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CURRENT_DATE);
                    y += FONT_HEIGHT_NORMAL;
                }

                /* Hide the NewGRF stuff when saving. We also hide the button. */
                if (_saveload_mode == SLD_LOAD_GAME || _saveload_mode == SLD_LOAD_SCENARIO) {
                    y += WD_PAR_VSEP_NORMAL;
                    if (y > y_max) break;

                    /* NewGrf compatibility */
                    SetDParam(0, _load_check_data.grfconfig == NULL ? STR_NEWGRF_LIST_NONE :
                              STR_NEWGRF_LIST_ALL_FOUND + _load_check_data.grf_compatibility);
                    DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_GRFSTATUS);
                    y += FONT_HEIGHT_NORMAL;
                }
                if (y > y_max) break;

                /* Hide the company stuff for scenarios */
                if (_saveload_mode != SLD_LOAD_SCENARIO && _saveload_mode != SLD_SAVE_SCENARIO) {
                    y += FONT_HEIGHT_NORMAL;
                    if (y > y_max) break;

                    /* Companies / AIs */
                    CompanyPropertiesMap::const_iterator end = _load_check_data.companies.End();
                    for (CompanyPropertiesMap::const_iterator it = _load_check_data.companies.Begin(); it != end; it++) {
                        SetDParam(0, it->first + 1);
                        const CompanyProperties &c = *it->second;
                        if (c.name != NULL) {
                            SetDParam(1, STR_JUST_RAW_STRING);
                            SetDParamStr(2, c.name);
                        } else {
                            SetDParam(1, c.name_1);
                            SetDParam(2, c.name_2);
                        }
                        DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_COMPANY_INDEX);
                        y += FONT_HEIGHT_NORMAL;
                        if (y > y_max) break;
                    }
                }
            }
        }
        break;
        }
    }
Ejemplo n.º 23
0
	virtual void DrawWidget(const Rect &r, int widget) const
	{
		switch (GB(widget, 0, 16)) {
			case WID_BO_CLASS_LIST: {
				int y = r.top;
				uint pos = 0;
				for (uint i = 0; i < ObjectClass::GetClassCount(); i++) {
					ObjectClass *objclass = ObjectClass::Get((ObjectClassID)i);
					if (objclass->GetUISpecCount() == 0) continue;
					if (!this->vscroll->IsVisible(pos++)) continue;
					DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, objclass->name,
							((int)i == _selected_object_class) ? TC_WHITE : TC_BLACK);
					y += this->line_height;
				}
				break;
			}

			case WID_BO_OBJECT_SPRITE: {
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index);
				if (spec == NULL) break;

				/* Height of the selection matrix.
				 * Depending on the number of views, the matrix has a 1x1, 1x2, 2x1 or 2x2 layout. To make the previews
				 * look nice in all layouts, we use the 4x4 layout (smallest previews) as starting point. For the bigger
				 * previews in the layouts with less views we add space homogeneously on all sides, so the 4x4 preview-rectangle
				 * is centered in the 2x1, 1x2 resp. 1x1 buttons. */
				uint matrix_height = this->GetWidget<NWidgetMatrix>(WID_BO_OBJECT_MATRIX)->current_y;

				DrawPixelInfo tmp_dpi;
				/* Set up a clipping area for the preview. */
				if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left + 1, r.bottom - r.top + 1)) {
					DrawPixelInfo *old_dpi = _cur_dpi;
					_cur_dpi = &tmp_dpi;
					if (spec->grf_prop.grffile == NULL) {
						extern const DrawTileSprites _objects[];
						const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id];
						DrawOrigTileSeqInGUI((r.right - r.left) / 2 - 1, (r.bottom - r.top + matrix_height / 2) / 2 - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), dts, PAL_NONE);
					} else {
						DrawNewObjectTileInGUI((r.right - r.left) / 2 - 1, (r.bottom - r.top + matrix_height / 2) / 2 - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), spec, GB(widget, 16, 16));
					}
					_cur_dpi = old_dpi;
				}
				break;
			}

			case WID_BO_SELECT_IMAGE: {
				ObjectClass *objclass = ObjectClass::Get(_selected_object_class);
				int obj_index = objclass->GetIndexFromUI(GB(widget, 16, 16));
				if (obj_index < 0) break;
				const ObjectSpec *spec = objclass->GetSpec(obj_index);
				if (spec == NULL) break;

				if (!spec->IsAvailable()) {
					GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK, FILLRECT_CHECKER);
				}
				DrawPixelInfo tmp_dpi;
				/* Set up a clipping area for the preview. */
				if (FillDrawPixelInfo(&tmp_dpi, r.left + 1, r.top, (r.right - 1) - (r.left + 1) + 1, r.bottom - r.top + 1)) {
					DrawPixelInfo *old_dpi = _cur_dpi;
					_cur_dpi = &tmp_dpi;
					if (spec->grf_prop.grffile == NULL) {
						extern const DrawTileSprites _objects[];
						const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id];
						DrawOrigTileSeqInGUI((r.right - r.left) / 2 - 1, r.bottom - r.top - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), dts, PAL_NONE);
					} else {
						DrawNewObjectTileInGUI((r.right - r.left) / 2 - 1, r.bottom - r.top - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), spec,
								min(_selected_object_view, spec->views - 1));
					}
					_cur_dpi = old_dpi;
				}
				break;
			}

			case WID_BO_INFO: {
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index);
				if (spec == NULL) break;

				/* Get the extra message for the GUI */
				if (HasBit(spec->callback_mask, CBM_OBJ_FUND_MORE_TEXT)) {
					uint16 callback_res = GetObjectCallback(CBID_OBJECT_FUND_MORE_TEXT, 0, 0, spec, NULL, INVALID_TILE, _selected_object_view);
					if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
						if (callback_res > 0x400) {
							ErrorUnknownCallbackResult(spec->grf_prop.grffile->grfid, CBID_OBJECT_FUND_MORE_TEXT, callback_res);
						} else {
							StringID message = GetGRFStringID(spec->grf_prop.grffile->grfid, 0xD000 + callback_res);
							if (message != STR_NULL && message != STR_UNDEFINED) {
								StartTextRefStackUsage(spec->grf_prop.grffile, 6);
								/* Use all the available space left from where we stand up to the
								 * end of the window. We ALSO enlarge the window if needed, so we
								 * can 'go' wild with the bottom of the window. */
								int y = DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, message, TC_ORANGE) - r.top;
								StopTextRefStackUsage();
								if (y > this->info_height) {
									BuildObjectWindow *bow = const_cast<BuildObjectWindow *>(this);
									bow->info_height = y + 2;
									bow->ReInit();
								}
							}
						}
					}
				}
			}
		}
	}
Ejemplo n.º 24
0
/** Draw the chat message-box */
void NetworkDrawChatMessage()
{
	Blitter *blitter = BlitterFactory::GetCurrentBlitter();
	if (!_chatmessage_dirty) return;

	/* First undraw if needed */
	NetworkUndrawChatMessage();

	if (_iconsole_mode == ICONSOLE_FULL) return;

	/* Check if we have anything to draw at all */
	uint count = GetChatMessageCount();
	if (count == 0) return;

	int x      = _chatmsg_box.x;
	int y      = _screen.height - _chatmsg_box.y - _chatmsg_box.height;
	int width  = _chatmsg_box.width;
	int height = _chatmsg_box.height;
	if (y < 0) {
		height = max(height + y, min(_chatmsg_box.height, _screen.height));
		y = 0;
	}
	if (x + width >= _screen.width) {
		width = _screen.width - x;
	}
	if (width <= 0 || height <= 0) return;

	assert(blitter->BufferSize(width, height) <= (int)(_chatmsg_box.width * _chatmsg_box.height * blitter->GetBytesPerPixel()));

	/* Make a copy of the screen as it is before painting (for undraw) */
	blitter->CopyToBuffer(blitter->MoveTo(_screen.dst_ptr, x, y), _chatmessage_backup, width, height);

	_cur_dpi = &_screen; // switch to _screen painting

	int string_height = 0;
	for (uint i = 0; i < count; i++) {
		SetDParamStr(0, _chatmsg_list[i].message);
		string_height += GetStringLineCount(STR_JUST_RAW_STRING, width - 1) * FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING;
	}

	string_height = min(string_height, MAX_CHAT_MESSAGES * (FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING));

	int top = _screen.height - _chatmsg_box.y - string_height - 2;
	int bottom = _screen.height - _chatmsg_box.y - 2;
	/* Paint a half-transparent box behind the chat messages */
	GfxFillRect(_chatmsg_box.x, top - 2, _chatmsg_box.x + _chatmsg_box.width - 1, bottom,
			PALETTE_TO_TRANSPARENT, FILLRECT_RECOLOUR // black, but with some alpha for background
		);

	/* Paint the chat messages starting with the lowest at the bottom */
	int ypos = bottom - 2;

	for (int i = count - 1; i >= 0; i--) {
		ypos = DrawStringMultiLine(_chatmsg_box.x + 3, _chatmsg_box.x + _chatmsg_box.width - 1, top, ypos, _chatmsg_list[i].message, _chatmsg_list[i].colour, SA_LEFT | SA_BOTTOM | SA_FORCE) - NETWORK_CHAT_LINE_SPACING;
		if (ypos < top) break;
	}

	/* Make sure the data is updated next flush */
	_video_driver->MakeDirty(x, y, width, height);

	_chatmessage_visible = true;
	_chatmessage_dirty = false;
}
Ejemplo n.º 25
0
/**
 * Draw the details for the given vehicle at the given position
 *
 * @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)
{
	/* get rid of awkward offset */
	y -= WD_MATRIX_TOP;

	int sprite_height = ScaleGUITrad(GetVehicleHeight(VEH_TRAIN));
	int line_height = max(sprite_height, WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM);
	int sprite_y_offset = line_height / 2;
	int text_y_offset = (line_height - FONT_HEIGHT_NORMAL) / 2;

	/* draw the first 3 details tabs */
	if (det_tab != TDW_TAB_TOTALS) {
		bool rtl = _current_text_dir == TD_RTL;
		Direction dir = rtl ? DIR_E : DIR_W;
		int x = rtl ? right : left;
		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 {
				Point offset;
				int width = u->GetDisplayImageWidth(&offset);
				if (vscroll_pos <= 0 && vscroll_pos > -vscroll_cap) {
					int pitch = 0;
					const Engine *e = Engine::Get(v->engine_type);
					if (e->GetGRF() != NULL) {
						pitch = ScaleGUITrad(e->GetGRF()->traininfo_vehicle_pitch);
					}
					PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
					VehicleSpriteSeq seq;
					u->GetImage(dir, EIT_IN_DETAILS, &seq);
					seq.Draw(px + (rtl ? -offset.x : offset.x), y - line_height * vscroll_pos + sprite_y_offset + pitch, pal, v->vehstatus & VS_CRASHED);
				}
				px += rtl ? -width : width;
				dx += width;
				u = u->Next();
			} while (u != NULL && u->IsArticulatedPart());

			bool separate_sprite_row = (dx > (uint)ScaleGUITrad(TRAIN_DETAILS_MAX_INDENT));
			if (separate_sprite_row) {
				vscroll_pos--;
				dx = 0;
			}

			uint num_lines = max(1u, _cargo_summary.Length());
			for (uint i = 0; i < num_lines; i++) {
				int sprite_width = max<int>(dx, ScaleGUITrad(TRAIN_DETAILS_MIN_INDENT)) + 3;
				int data_left  = left + (rtl ? 0 : sprite_width);
				int data_right = right - (rtl ? sprite_width : 0);
				if (vscroll_pos <= 0 && vscroll_pos > -vscroll_cap) {
					int py = y - line_height * vscroll_pos + text_y_offset;
					if (i > 0 || separate_sprite_row) {
						if (vscroll_pos != 0) GfxFillRect(left, py - WD_MATRIX_TOP - 1, right, py - WD_MATRIX_TOP, _colour_gradient[COLOUR_GREY][5]);
					}
					switch (det_tab) {
						case TDW_TAB_CARGO:
							if (i < _cargo_summary.Length()) {
								TrainDetailsCargoTab(&_cargo_summary[i], data_left, data_right, py);
							} else {
								DrawString(data_left, data_right, py, STR_QUANTITY_N_A, TC_LIGHT_BLUE);
							}
							break;

						case TDW_TAB_INFO:
							if (i == 0) TrainDetailsInfoTab(v, data_left, data_right, py);
							break;

						case TDW_TAB_CAPACITY:
							if (i < _cargo_summary.Length()) {
								TrainDetailsCapacityTab(&_cargo_summary[i], data_left, data_right, py);
							} else {
								SetDParam(0, STR_EMPTY);
								DrawString(data_left, data_right, py, STR_VEHICLE_INFO_NO_CAPACITY);
							}
							break;

						default: NOT_REACHED();
					}
				}
				vscroll_pos--;
			}
		}
	} else {
		CargoArray act_cargo;
		CargoArray max_cargo;
		Money feeder_share = 0;

		for (const Vehicle *u = v; u != NULL; u = u->Next()) {
			act_cargo[u->cargo_type] += u->cargo.StoredCount();
			max_cargo[u->cargo_type] += u->cargo_cap;
			feeder_share             += u->cargo.FeederShare();
		}

		/* draw total cargo tab */
		DrawString(left, right, y + text_y_offset, STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT);
		y += line_height;

		for (CargoID i = 0; i < NUM_CARGO; i++) {
			if (max_cargo[i] > 0 && --vscroll_pos < 0 && vscroll_pos > -vscroll_cap) {
				SetDParam(0, i);            // {CARGO} #1
				SetDParam(1, act_cargo[i]); // {CARGO} #2
				SetDParam(2, i);            // {SHORTCARGO} #1
				SetDParam(3, max_cargo[i]); // {SHORTCARGO} #2
				SetDParam(4, _settings_game.vehicle.freight_trains);
				DrawString(left, right, y + text_y_offset, FreightWagonMult(i) > 1 ? STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT : STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY);
				y += line_height;
			}
		}
		SetDParam(0, feeder_share);
		DrawString(left, right, y + text_y_offset, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE);
	}
}
	/**
	 * Helper function to draw the details part of this window.
	 * @param r the rectangle to stay within while drawing
	 */
	void DrawDetails(const Rect &r) const
	{
		static const int DETAIL_LEFT         =  5; ///< Number of pixels at the left
		static const int DETAIL_RIGHT        =  5; ///< Number of pixels at the right
		static const int DETAIL_TOP          =  5; ///< Number of pixels at the top

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

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

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

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

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

		/* Also show the total download size, so keep some space from the bottom */
		const uint max_y = r.bottom - FONT_HEIGHT_NORMAL - WD_PAR_VSEP_WIDE;
		int y = r.top + DETAIL_TITLE_HEIGHT + DETAIL_TOP;

		if (this->selected->upgrade) {
			SetDParam(0, STR_CONTENT_TYPE_BASE_GRAPHICS + this->selected->type - CONTENT_TYPE_BASE_GRAPHICS);
			y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_UPDATE);
			y += WD_PAR_VSEP_WIDE;
		}

		SetDParamStr(0, this->selected->name);
		y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_NAME);

		if (!StrEmpty(this->selected->version)) {
			SetDParamStr(0, this->selected->version);
			y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_VERSION);
		}

		if (!StrEmpty(this->selected->description)) {
			SetDParamStr(0, this->selected->description);
			y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_DESCRIPTION);
		}

		if (!StrEmpty(this->selected->url)) {
			SetDParamStr(0, this->selected->url);
			y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_URL);
		}

		SetDParam(0, STR_CONTENT_TYPE_BASE_GRAPHICS + this->selected->type - CONTENT_TYPE_BASE_GRAPHICS);
		y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_TYPE);

		y += WD_PAR_VSEP_WIDE;
		SetDParam(0, this->selected->filesize);
		y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_FILESIZE);

		if (this->selected->dependency_count != 0) {
			/* List dependencies */
			char buf[DRAW_STRING_BUFFER] = "";
			char *p = buf;
			for (uint i = 0; i < this->selected->dependency_count; i++) {
				ContentID cid = this->selected->dependencies[i];

				/* Try to find the dependency */
				ConstContentIterator iter = _network_content_client.Begin();
				for (; iter != _network_content_client.End(); iter++) {
					const ContentInfo *ci = *iter;
					if (ci->id != cid) continue;

					p += seprintf(p, lastof(buf), p == buf ? "%s" : ", %s", (*iter)->name);
					break;
				}
			}
			SetDParamStr(0, buf);
			y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_DEPENDENCIES);
		}

		if (this->selected->tag_count != 0) {
			/* List all tags */
			char buf[DRAW_STRING_BUFFER] = "";
			char *p = buf;
			for (uint i = 0; i < this->selected->tag_count; i++) {
				p += seprintf(p, lastof(buf), i == 0 ? "%s" : ", %s", this->selected->tags[i]);
			}
			SetDParamStr(0, buf);
			y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_TAGS);
		}

		if (this->selected->IsSelected()) {
			/* When selected show all manually selected content that depends on this */
			ConstContentVector tree;
			_network_content_client.ReverseLookupTreeDependency(tree, this->selected);

			char buf[DRAW_STRING_BUFFER] = "";
			char *p = buf;
			for (ConstContentIterator iter = tree.Begin(); iter != tree.End(); iter++) {
				const ContentInfo *ci = *iter;
				if (ci == this->selected || ci->state != ContentInfo::SELECTED) continue;

				p += seprintf(p, lastof(buf), buf == p ? "%s" : ", %s", ci->name);
			}
			if (p != buf) {
				SetDParamStr(0, buf);
				y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_SELECTED_BECAUSE_OF);
			}
		}
	}
Ejemplo n.º 27
0
	virtual void DrawWidget(const Rect &r, int widget) const
	{
		GfxFillRect(r.left, r.top, r.right, r.bottom, 4, FILLRECT_OPAQUE);
		GfxFillRect(r.left, r.top, r.right, r.bottom, 0, FILLRECT_CHECKER);
	}