mirror of https://github.com/OpenTTD/OpenTTD
Add: Overlay cargo icon in vehicle/depot list when holding shift+ctrl. (#12938)
parent
9404a03663
commit
e45e8a39c8
|
@ -97,6 +97,17 @@ void DrawAircraftImage(const Vehicle *v, const Rect &r, VehicleID selection, Eng
|
||||||
|
|
||||||
PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
|
PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
|
||||||
seq.Draw(x, y, pal, (v->vehstatus & VS_CRASHED) != 0);
|
seq.Draw(x, y, pal, (v->vehstatus & VS_CRASHED) != 0);
|
||||||
|
|
||||||
|
/* Aircraft can store cargo in their shadow, show this if present. */
|
||||||
|
const Vehicle *u = v->Next();
|
||||||
|
assert(u != nullptr);
|
||||||
|
int dx = 0;
|
||||||
|
if (u->cargo_cap > 0 && u->cargo_type != v->cargo_type) {
|
||||||
|
dx = GetLargestCargoIconSize().width / 2;
|
||||||
|
DrawCargoIconOverlay(x + dx, y, u->cargo_type);
|
||||||
|
}
|
||||||
|
if (v->cargo_cap > 0) DrawCargoIconOverlay(x - dx, y, v->cargo_type);
|
||||||
|
|
||||||
if (helicopter) {
|
if (helicopter) {
|
||||||
const Aircraft *a = Aircraft::From(v);
|
const Aircraft *a = Aircraft::From(v);
|
||||||
VehicleSpriteSeq rotor_seq;
|
VehicleSpriteSeq rotor_seq;
|
||||||
|
|
|
@ -974,6 +974,15 @@ struct DepotWindow : Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool last_overlay_state;
|
||||||
|
void OnMouseLoop() override
|
||||||
|
{
|
||||||
|
if (last_overlay_state != ShowCargoIconOverlay()) {
|
||||||
|
last_overlay_state = ShowCargoIconOverlay();
|
||||||
|
this->SetDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OnMouseDrag(Point pt, WidgetID widget) override
|
void OnMouseDrag(Point pt, WidgetID widget) override
|
||||||
{
|
{
|
||||||
if (this->sel == INVALID_VEHICLE) return;
|
if (this->sel == INVALID_VEHICLE) return;
|
||||||
|
|
|
@ -692,6 +692,15 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool last_overlay_state;
|
||||||
|
void OnMouseLoop() override
|
||||||
|
{
|
||||||
|
if (last_overlay_state != ShowCargoIconOverlay()) {
|
||||||
|
last_overlay_state = ShowCargoIconOverlay();
|
||||||
|
this->SetDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
|
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
|
||||||
{
|
{
|
||||||
switch (widget) {
|
switch (widget) {
|
||||||
|
|
|
@ -4009,10 +4009,10 @@ STR_VEHICLE_LIST_SHIP_CAPTION :{WHITE}{STRING2
|
||||||
STR_VEHICLE_LIST_AIRCRAFT_CAPTION :{WHITE}{STRING2} - {COMMA} Aircraft
|
STR_VEHICLE_LIST_AIRCRAFT_CAPTION :{WHITE}{STRING2} - {COMMA} Aircraft
|
||||||
|
|
||||||
###length VEHICLE_TYPES
|
###length VEHICLE_TYPES
|
||||||
STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP :{BLACK}Trains - click on train for information
|
STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP :{BLACK}Trains - click on train for information. Hold Ctrl+Shift to overlay cargo type
|
||||||
STR_VEHICLE_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}Road vehicles - click on vehicle for information
|
STR_VEHICLE_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}Road vehicles - click on vehicle for information. Hold Ctrl+Shift to overlay cargo type
|
||||||
STR_VEHICLE_LIST_SHIP_TOOLTIP :{BLACK}Ships - click on ship for information
|
STR_VEHICLE_LIST_SHIP_TOOLTIP :{BLACK}Ships - click on ship for information. Hold Ctrl+Shift to overlay cargo type
|
||||||
STR_VEHICLE_LIST_AIRCRAFT_TOOLTIP :{BLACK}Aircraft - click on aircraft for information
|
STR_VEHICLE_LIST_AIRCRAFT_TOOLTIP :{BLACK}Aircraft - click on aircraft for information. Hold Ctrl+Shift to overlay cargo type
|
||||||
|
|
||||||
###length VEHICLE_TYPES
|
###length VEHICLE_TYPES
|
||||||
STR_VEHICLE_LIST_AVAILABLE_TRAINS :Available Trains
|
STR_VEHICLE_LIST_AVAILABLE_TRAINS :Available Trains
|
||||||
|
|
|
@ -132,6 +132,10 @@ void DrawRoadVehImage(const Vehicle *v, const Rect &r, VehicleID selection, Engi
|
||||||
|
|
||||||
AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
|
AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
|
||||||
|
|
||||||
|
bool do_overlays = ShowCargoIconOverlay();
|
||||||
|
/* List of overlays, only used if cargo icon overlays are enabled. */
|
||||||
|
static std::vector<CargoIconOverlay> overlays;
|
||||||
|
|
||||||
int px = rtl ? max_width + skip : -skip;
|
int px = rtl ? max_width + skip : -skip;
|
||||||
int y = r.Height() / 2;
|
int y = r.Height() / 2;
|
||||||
for (; u != nullptr && (rtl ? px > 0 : px < max_width); u = u->Next())
|
for (; u != nullptr && (rtl ? px > 0 : px < max_width); u = u->Next())
|
||||||
|
@ -146,9 +150,15 @@ void DrawRoadVehImage(const Vehicle *v, const Rect &r, VehicleID selection, Engi
|
||||||
seq.Draw(px + (rtl ? -offset.x : offset.x), y + offset.y, pal, (u->vehstatus & VS_CRASHED) != 0);
|
seq.Draw(px + (rtl ? -offset.x : offset.x), y + offset.y, pal, (u->vehstatus & VS_CRASHED) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (do_overlays) AddCargoIconOverlay(overlays, px, width, u);
|
||||||
px += rtl ? -width : width;
|
px += rtl ? -width : width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (do_overlays) {
|
||||||
|
DrawCargoIconOverlays(overlays, y);
|
||||||
|
overlays.clear();
|
||||||
|
}
|
||||||
|
|
||||||
if (v->index == selection) {
|
if (v->index == selection) {
|
||||||
int height = ScaleSpriteTrad(12);
|
int height = ScaleSpriteTrad(12);
|
||||||
Rect hr = {(rtl ? px : 0), 0, (rtl ? max_width : px) - 1, height - 1};
|
Rect hr = {(rtl ? px : 0), 0, (rtl ? max_width : px) - 1, height - 1};
|
||||||
|
|
|
@ -44,6 +44,7 @@ void DrawShipImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineI
|
||||||
int y = ScaleSpriteTrad(-1) + CenterBounds(r.top, r.bottom, 0);
|
int y = ScaleSpriteTrad(-1) + CenterBounds(r.top, r.bottom, 0);
|
||||||
|
|
||||||
seq.Draw(x, y, GetVehiclePalette(v), false);
|
seq.Draw(x, y, GetVehiclePalette(v), false);
|
||||||
|
if (v->cargo_cap > 0) DrawCargoIconOverlay(x, y, v->cargo_type);
|
||||||
|
|
||||||
if (v->index == selection) {
|
if (v->index == selection) {
|
||||||
x += x_offs;
|
x += x_offs;
|
||||||
|
|
|
@ -106,6 +106,10 @@ void DrawTrainImage(const Train *v, const Rect &r, VehicleID selection, EngineIm
|
||||||
{
|
{
|
||||||
AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
|
AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
|
||||||
|
|
||||||
|
bool do_overlays = ShowCargoIconOverlay();
|
||||||
|
/* List of overlays, only used if cargo icon overlays are enabled. */
|
||||||
|
static std::vector<CargoIconOverlay> overlays;
|
||||||
|
|
||||||
int px = rtl ? max_width + skip : -skip;
|
int px = rtl ? max_width + skip : -skip;
|
||||||
int y = r.Height() / 2;
|
int y = r.Height() / 2;
|
||||||
bool sel_articulated = false;
|
bool sel_articulated = false;
|
||||||
|
@ -143,9 +147,15 @@ void DrawTrainImage(const Train *v, const Rect &r, VehicleID selection, EngineIm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (do_overlays) AddCargoIconOverlay(overlays, px, width, v);
|
||||||
px += rtl ? -width : width;
|
px += rtl ? -width : width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (do_overlays) {
|
||||||
|
DrawCargoIconOverlays(overlays, y);
|
||||||
|
overlays.clear();
|
||||||
|
}
|
||||||
|
|
||||||
if (dragging && drag_at_end_of_train) {
|
if (dragging && drag_at_end_of_train) {
|
||||||
/* Highlight the drag-and-drop destination at the end of the train. */
|
/* Highlight the drag-and-drop destination at the end of the train. */
|
||||||
HighlightDragPosition(px, max_width, y, selection, _cursor.vehchain);
|
HighlightDragPosition(px, max_width, y, selection, _cursor.vehchain);
|
||||||
|
|
|
@ -329,6 +329,82 @@ static bool CargoFilter(const GUIVehicleGroup *vehgroup, const CargoID cid)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if cargo icon overlays should be drawn.
|
||||||
|
* @returns true iff cargo icon overlays should be drawn.
|
||||||
|
*/
|
||||||
|
bool ShowCargoIconOverlay()
|
||||||
|
{
|
||||||
|
return _shift_pressed && _ctrl_pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a cargo icon to the list of overlays.
|
||||||
|
* @param overlays List of overlays.
|
||||||
|
* @param x Horizontal position.
|
||||||
|
* @param width Width available.
|
||||||
|
* @param v Vehicle to add.
|
||||||
|
*/
|
||||||
|
void AddCargoIconOverlay(std::vector<CargoIconOverlay> &overlays, int x, int width, const Vehicle *v)
|
||||||
|
{
|
||||||
|
bool rtl = _current_text_dir == TD_RTL;
|
||||||
|
if (!v->IsArticulatedPart() || v->cargo_type != v->Previous()->cargo_type) {
|
||||||
|
/* Add new overlay slot. */
|
||||||
|
overlays.emplace_back(rtl ? x - width : x, rtl ? x : x + width, v->cargo_type, v->cargo_cap);
|
||||||
|
} else {
|
||||||
|
/* This is an articulated part with the same cargo type, adjust left or right of last overlay slot. */
|
||||||
|
if (rtl) {
|
||||||
|
overlays.back().left -= width;
|
||||||
|
} else {
|
||||||
|
overlays.back().right += width;
|
||||||
|
}
|
||||||
|
overlays.back().cargo_cap += v->cargo_cap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw a cargo icon overlaying an existing sprite, with a black contrast outline.
|
||||||
|
* @param x Horizontal position from left.
|
||||||
|
* @param y Vertical position from top.
|
||||||
|
* @param cid Cargo ID to draw icon for.
|
||||||
|
*/
|
||||||
|
void DrawCargoIconOverlay(int x, int y, CargoID cid)
|
||||||
|
{
|
||||||
|
if (!ShowCargoIconOverlay()) return;
|
||||||
|
if (!IsValidCargoID(cid)) return;
|
||||||
|
|
||||||
|
const CargoSpec *cs = CargoSpec::Get(cid);
|
||||||
|
|
||||||
|
SpriteID spr = cs->GetCargoIcon();
|
||||||
|
if (spr == 0) return;
|
||||||
|
|
||||||
|
Dimension d = GetSpriteSize(spr);
|
||||||
|
d.width /= 2;
|
||||||
|
d.height /= 2;
|
||||||
|
int one = ScaleGUITrad(1);
|
||||||
|
|
||||||
|
/* Draw the cargo icon in black shifted 4 times to create the outline. */
|
||||||
|
DrawSprite(spr, PALETTE_ALL_BLACK, x - d.width - one, y - d.height);
|
||||||
|
DrawSprite(spr, PALETTE_ALL_BLACK, x - d.width + one, y - d.height);
|
||||||
|
DrawSprite(spr, PALETTE_ALL_BLACK, x - d.width, y - d.height - one);
|
||||||
|
DrawSprite(spr, PALETTE_ALL_BLACK, x - d.width, y - d.height + one);
|
||||||
|
/* Draw the cargo icon normally. */
|
||||||
|
DrawSprite(spr, PAL_NONE, x - d.width, y - d.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw a list of cargo icon overlays.
|
||||||
|
* @param overlays List of overlays.
|
||||||
|
* @param y Vertical position.
|
||||||
|
*/
|
||||||
|
void DrawCargoIconOverlays(std::span<const CargoIconOverlay> overlays, int y)
|
||||||
|
{
|
||||||
|
for (const auto &cio : overlays) {
|
||||||
|
if (cio.cargo_cap == 0) continue;
|
||||||
|
DrawCargoIconOverlay((cio.left + cio.right) / 2, y, cio.cargo_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GUIVehicleGroupList::FilterFunction * const _vehicle_group_filter_funcs[] = {
|
static GUIVehicleGroupList::FilterFunction * const _vehicle_group_filter_funcs[] = {
|
||||||
&CargoFilter,
|
&CargoFilter,
|
||||||
};
|
};
|
||||||
|
@ -2053,6 +2129,15 @@ public:
|
||||||
this->DrawWidgets();
|
this->DrawWidgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool last_overlay_state;
|
||||||
|
void OnMouseLoop() override
|
||||||
|
{
|
||||||
|
if (last_overlay_state != ShowCargoIconOverlay()) {
|
||||||
|
last_overlay_state = ShowCargoIconOverlay();
|
||||||
|
this->SetDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
|
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
|
||||||
{
|
{
|
||||||
switch (widget) {
|
switch (widget) {
|
||||||
|
|
|
@ -139,6 +139,22 @@ struct BaseVehicleListWindow : public Window {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CargoIconOverlay {
|
||||||
|
int left;
|
||||||
|
int right;
|
||||||
|
CargoID cargo_type;
|
||||||
|
uint cargo_cap;
|
||||||
|
|
||||||
|
constexpr CargoIconOverlay(int left, int right, CargoID cargo_type, uint cargo_cap)
|
||||||
|
: left(left), right(right), cargo_type(cargo_type), cargo_cap(cargo_cap)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
bool ShowCargoIconOverlay();
|
||||||
|
void AddCargoIconOverlay(std::vector<CargoIconOverlay> &overlays, int x, int width, const Vehicle *v);
|
||||||
|
void DrawCargoIconOverlay(int x, int y, CargoID cid);
|
||||||
|
void DrawCargoIconOverlays(std::span<const CargoIconOverlay> overlays, int y);
|
||||||
|
|
||||||
uint GetVehicleListHeight(VehicleType type, uint divisor = 1);
|
uint GetVehicleListHeight(VehicleType type, uint divisor = 1);
|
||||||
|
|
||||||
struct Sorting {
|
struct Sorting {
|
||||||
|
|
Loading…
Reference in New Issue