* Draw the details for the given vehicle at the given position * * @param v current vehicle * @param r the Rect to draw within * @param vscroll_pos Position of scrollbar * @param vscroll_cap Number of lines currently displayed * @param det_tab Selected details tab */
| 352 | * @param det_tab Selected details tab |
| 353 | */ |
| 354 | void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16_t vscroll_cap, TrainDetailsWindowTabs det_tab) |
| 355 | { |
| 356 | bool rtl = _current_text_dir == TD_RTL; |
| 357 | int line_height = r.Height(); |
| 358 | int sprite_y_offset = line_height / 2; |
| 359 | int text_y_offset = (line_height - GetCharacterHeight(FS_NORMAL)) / 2; |
| 360 | |
| 361 | /* draw the first 3 details tabs */ |
| 362 | if (det_tab != TDW_TAB_TOTALS) { |
| 363 | Direction dir = rtl ? DIR_E : DIR_W; |
| 364 | int x = rtl ? r.right : r.left; |
| 365 | for (; v != nullptr && vscroll_pos > -vscroll_cap; v = v->GetNextVehicle()) { |
| 366 | GetCargoSummaryOfArticulatedVehicle(v, _cargo_summary); |
| 367 | |
| 368 | /* Draw sprites */ |
| 369 | uint dx = 0; |
| 370 | int px = x; |
| 371 | const Train *u = v; |
| 372 | do { |
| 373 | Point offset; |
| 374 | int width = u->GetDisplayImageWidth(&offset); |
| 375 | if (vscroll_pos <= 0 && vscroll_pos > -vscroll_cap) { |
| 376 | int pitch = 0; |
| 377 | const Engine *e = Engine::Get(v->engine_type); |
| 378 | if (e->GetGRF() != nullptr) { |
| 379 | pitch = ScaleSpriteTrad(e->GetGRF()->traininfo_vehicle_pitch); |
| 380 | } |
| 381 | PaletteID pal = v->vehstatus.Test(VehState::Crashed) ? PALETTE_CRASH : GetVehiclePalette(u); |
| 382 | VehicleSpriteSeq seq; |
| 383 | u->GetImage(dir, EIT_IN_DETAILS, &seq); |
| 384 | seq.Draw(px + (rtl ? -offset.x : offset.x), r.top - line_height * vscroll_pos + sprite_y_offset + pitch, pal, v->vehstatus.Test(VehState::Crashed)); |
| 385 | } |
| 386 | px += rtl ? -width : width; |
| 387 | dx += width; |
| 388 | u = u->Next(); |
| 389 | } while (u != nullptr && u->IsArticulatedPart()); |
| 390 | |
| 391 | bool separate_sprite_row = (dx > (uint)ScaleSpriteTrad(TRAIN_DETAILS_MAX_INDENT)); |
| 392 | if (separate_sprite_row) { |
| 393 | vscroll_pos--; |
| 394 | dx = 0; |
| 395 | } |
| 396 | |
| 397 | int sprite_width = std::max<int>(dx, ScaleSpriteTrad(TRAIN_DETAILS_MIN_INDENT)) + WidgetDimensions::scaled.hsep_normal; |
| 398 | Rect dr = r.Indent(sprite_width, rtl); |
| 399 | uint num_lines = std::max(1u, (unsigned)_cargo_summary.size()); |
| 400 | for (uint i = 0; i < num_lines; i++) { |
| 401 | if (vscroll_pos <= 0 && vscroll_pos > -vscroll_cap) { |
| 402 | int py = r.top - line_height * vscroll_pos + text_y_offset; |
| 403 | if (i > 0 || separate_sprite_row) { |
| 404 | if (vscroll_pos != 0) GfxFillRect(r.WithY(py - WidgetDimensions::scaled.matrix.top - 1, py - WidgetDimensions::scaled.matrix.top), GetColourGradient(COLOUR_GREY, SHADE_LIGHT)); |
| 405 | } |
| 406 | switch (det_tab) { |
| 407 | case TDW_TAB_CARGO: |
| 408 | if (i < _cargo_summary.size()) { |
| 409 | TrainDetailsCargoTab(&_cargo_summary[i], dr.left, dr.right, py); |
| 410 | } else { |
| 411 | DrawString(dr.left, dr.right, py, STR_QUANTITY_N_A, TC_LIGHT_BLUE); |
no test coverage detected