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