Depot lists internal layout was not handled well. This is improved by throwing more Rects at it: - Vehicle images are now be vertically centred in the rect. - Image clipping is relaxed to cover the rect, improving larger sprites. - Outline highlight is now aware of bevel thickness.
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
#include "depot_cmd.h"
|
||||
#include "train_cmd.h"
|
||||
#include "vehicle_cmd.h"
|
||||
#include "core/geometry_func.hpp"
|
||||
|
||||
#include "widgets/depot_widget.h"
|
||||
|
||||
@@ -303,18 +304,15 @@ struct DepotWindow : Window {
|
||||
/**
|
||||
* Draw a vehicle in the depot window in the box with the top left corner at x,y.
|
||||
* @param v Vehicle to draw.
|
||||
* @param left Left side of the box to draw in.
|
||||
* @param right Right side of the box to draw in.
|
||||
* @param y Top of the box to draw in.
|
||||
* @param r Rect to draw in.
|
||||
*/
|
||||
void DrawVehicleInDepot(const Vehicle *v, int left, int right, int y) const
|
||||
void DrawVehicleInDepot(const Vehicle *v, const Rect &r) const
|
||||
{
|
||||
bool free_wagon = false;
|
||||
int sprite_y = y + (this->resize.step_height - ScaleSpriteTrad(GetVehicleHeight(v->type))) / 2;
|
||||
|
||||
bool rtl = _current_text_dir == TD_RTL;
|
||||
int image_left = rtl ? left + this->count_width : left + this->header_width;
|
||||
int image_right = rtl ? right - this->header_width : right - this->count_width;
|
||||
Rect text = r.Shrink(RectPadding::zero, WidgetDimensions::scaled.matrix); /* Ract for text elements, horizontal is already applied. */
|
||||
Rect image = r.Indent(this->header_width, rtl).Indent(this->count_width, !rtl); /* Rect for vehicle images */
|
||||
|
||||
switch (v->type) {
|
||||
case VEH_TRAIN: {
|
||||
@@ -325,42 +323,42 @@ struct DepotWindow : Window {
|
||||
ScaleSpriteTrad(_consistent_train_width != 0 ? _consistent_train_width : TRAININFO_DEFAULT_VEHICLE_WIDTH) :
|
||||
0;
|
||||
|
||||
DrawTrainImage(u, image_left + (rtl ? 0 : x_space), image_right - (rtl ? x_space : 0), sprite_y,
|
||||
this->sel, EIT_IN_DEPOT, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over);
|
||||
DrawTrainImage(u, image.Indent(x_space, rtl), this->sel, EIT_IN_DEPOT, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over);
|
||||
|
||||
/* Length of consist in tiles with 1 fractional digit (rounded up) */
|
||||
SetDParam(0, CeilDiv(u->gcache.cached_total_length * 10, TILE_SIZE));
|
||||
SetDParam(1, 1);
|
||||
DrawString(rtl ? left : right - this->count_width, rtl ? left + this->count_width : right, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter
|
||||
Rect count = text.WithWidth(this->count_width - WidgetDimensions::scaled.hsep_normal, !rtl);
|
||||
DrawString(count.left, count.right, count.bottom - FONT_HEIGHT_SMALL + 1, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter
|
||||
break;
|
||||
}
|
||||
|
||||
case VEH_ROAD: DrawRoadVehImage( v, image_left, image_right, sprite_y, this->sel, EIT_IN_DEPOT); break;
|
||||
case VEH_SHIP: DrawShipImage( v, image_left, image_right, sprite_y, this->sel, EIT_IN_DEPOT); break;
|
||||
case VEH_AIRCRAFT: DrawAircraftImage(v, image_left, image_right, sprite_y, this->sel, EIT_IN_DEPOT); break;
|
||||
case VEH_ROAD: DrawRoadVehImage( v, image, this->sel, EIT_IN_DEPOT); break;
|
||||
case VEH_SHIP: DrawShipImage( v, image, this->sel, EIT_IN_DEPOT); break;
|
||||
case VEH_AIRCRAFT: DrawAircraftImage(v, image, this->sel, EIT_IN_DEPOT); break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
uint diff_x, diff_y;
|
||||
if (v->IsGroundVehicle()) {
|
||||
/* Arrange unitnumber and flag horizontally */
|
||||
diff_x = this->flag_width;
|
||||
diff_y = (this->resize.step_height - this->flag_height) / 2;
|
||||
diff_x = this->flag_size.width + WidgetDimensions::scaled.hsep_normal;
|
||||
diff_y = WidgetDimensions::scaled.matrix.top;
|
||||
} else {
|
||||
/* Arrange unitnumber and flag vertically */
|
||||
diff_x = 0;
|
||||
diff_y = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal;
|
||||
diff_y = WidgetDimensions::scaled.matrix.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal;
|
||||
}
|
||||
int text_left = rtl ? right - this->header_width - 1 : left + diff_x;
|
||||
int text_right = rtl ? right - diff_x : left + this->header_width - 1;
|
||||
|
||||
text = text.WithWidth(this->header_width - WidgetDimensions::scaled.hsep_normal, rtl).WithHeight(FONT_HEIGHT_NORMAL).Indent(diff_x, rtl);
|
||||
if (free_wagon) {
|
||||
DrawString(text_left, text_right, y + WidgetDimensions::scaled.framerect.top, STR_DEPOT_NO_ENGINE);
|
||||
DrawString(text, STR_DEPOT_NO_ENGINE);
|
||||
} else {
|
||||
DrawSprite((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, rtl ? right - this->flag_width : left + WidgetDimensions::scaled.framerect.left, y + diff_y);
|
||||
Rect flag = r.WithWidth(this->flag_size.width, rtl).WithHeight(this->flag_size.height).Translate(0, diff_y);
|
||||
DrawSpriteIgnorePadding((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, flag, false, SA_CENTER);
|
||||
|
||||
SetDParam(0, v->unitnumber);
|
||||
DrawString(text_left, text_right, y + WidgetDimensions::scaled.framerect.top, (uint16)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? STR_BLACK_COMMA : STR_RED_COMMA);
|
||||
DrawString(text, (uint16)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? STR_BLACK_COMMA : STR_RED_COMMA);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,7 +371,10 @@ struct DepotWindow : Window {
|
||||
/* Set the row and number of boxes in each row based on the number of boxes drawn in the matrix */
|
||||
const NWidgetCore *wid = this->GetWidget<NWidgetCore>(WID_D_MATRIX);
|
||||
|
||||
Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
|
||||
/* Set up rect for each cell */
|
||||
Rect ir = r.WithHeight(this->resize.step_height);
|
||||
if (this->num_columns != 1) ir = ir.WithWidth(this->resize.step_width, rtl);
|
||||
ir = ir.Shrink(WidgetDimensions::scaled.framerect, RectPadding::zero);
|
||||
|
||||
/* Draw vertical separators at whole tiles.
|
||||
* This only works in two cases:
|
||||
@@ -383,15 +384,14 @@ struct DepotWindow : Window {
|
||||
if (this->type == VEH_TRAIN && _consistent_train_width != 0) {
|
||||
int w = ScaleSpriteTrad(2 * _consistent_train_width);
|
||||
int col = _colour_gradient[wid->colour][4];
|
||||
int image_left = rtl ? ir.left + this->count_width : ir.left + this->header_width;
|
||||
int image_right = rtl ? ir.right - this->header_width : ir.right - this->count_width;
|
||||
Rect image = ir.Indent(this->header_width, rtl).Indent(this->count_width, !rtl);
|
||||
int first_line = w + (-this->hscroll->GetPosition()) % w;
|
||||
if (rtl) {
|
||||
for (int x = image_right - first_line; x >= image_left; x -= w) {
|
||||
for (int x = image.right - first_line; x >= image.left; x -= w) {
|
||||
GfxDrawLine(x, r.top, x, r.bottom, col, ScaleGUITrad(1), ScaleGUITrad(3));
|
||||
}
|
||||
} else {
|
||||
for (int x = image_left + first_line; x <= image_right; x += w) {
|
||||
for (int x = image.left + first_line; x <= image.right; x += w) {
|
||||
GfxDrawLine(x, r.top, x, r.bottom, col, ScaleGUITrad(1), ScaleGUITrad(3));
|
||||
}
|
||||
}
|
||||
@@ -401,26 +401,22 @@ struct DepotWindow : Window {
|
||||
|
||||
uint num = this->vscroll->GetPosition() * this->num_columns;
|
||||
uint maxval = static_cast<uint>(std::min<size_t>(this->vehicle_list.size(), num + (rows_in_display * this->num_columns)));
|
||||
int y;
|
||||
for (y = r.top; num < maxval; y += this->resize.step_height) { // Draw the rows
|
||||
for (; num < maxval; ir = ir.Translate(0, this->resize.step_height)) { // Draw the rows
|
||||
Rect cell = ir; /* Keep track of horizontal cells */
|
||||
for (uint i = 0; i < this->num_columns && num < maxval; i++, num++) {
|
||||
/* Draw all vehicles in the current row */
|
||||
const Vehicle *v = this->vehicle_list[num];
|
||||
if (this->num_columns == 1) {
|
||||
this->DrawVehicleInDepot(v, ir.left, ir.right, y);
|
||||
} else {
|
||||
int x = ir.left + (rtl ? (this->num_columns - i - 1) : i) * this->resize.step_width;
|
||||
this->DrawVehicleInDepot(v, x, x + this->resize.step_width - 1 - WidgetDimensions::scaled.framerect.Horizontal(), y);
|
||||
}
|
||||
this->DrawVehicleInDepot(v, cell);
|
||||
cell = cell.Translate(rtl ? -(int)this->resize.step_width : (int)this->resize.step_width, 0);
|
||||
}
|
||||
}
|
||||
|
||||
maxval = static_cast<uint>(std::min<size_t>(this->vehicle_list.size() + this->wagon_list.size(), (this->vscroll->GetPosition() * this->num_columns) + (rows_in_display * this->num_columns)));
|
||||
|
||||
/* Draw the train wagons without an engine in front. */
|
||||
for (; num < maxval; num++, y += this->resize.step_height) {
|
||||
for (; num < maxval; num++, ir = ir.Translate(0, this->resize.step_height)) {
|
||||
const Vehicle *v = this->wagon_list[num - this->vehicle_list.size()];
|
||||
this->DrawVehicleInDepot(v, ir.left, ir.right, y);
|
||||
this->DrawVehicleInDepot(v, ir);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -503,12 +499,12 @@ struct DepotWindow : Window {
|
||||
FALLTHROUGH;
|
||||
|
||||
case VEH_ROAD:
|
||||
if (xm <= this->flag_width) return MODE_START_STOP;
|
||||
if (xm <= this->flag_size.width) return MODE_START_STOP;
|
||||
break;
|
||||
|
||||
case VEH_SHIP:
|
||||
case VEH_AIRCRAFT:
|
||||
if (xm <= this->flag_width && ym >= (uint)(FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal)) return MODE_START_STOP;
|
||||
if (xm <= this->flag_size.width && ym >= (uint)(FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal)) return MODE_START_STOP;
|
||||
break;
|
||||
|
||||
default: NOT_REACHED();
|
||||
@@ -645,10 +641,16 @@ struct DepotWindow : Window {
|
||||
}
|
||||
}
|
||||
|
||||
uint count_width;
|
||||
uint header_width;
|
||||
uint flag_width;
|
||||
uint flag_height;
|
||||
uint count_width; ///< Width of length count, including separator.
|
||||
uint header_width; ///< Width of unit number and flag, including separator.
|
||||
Dimension flag_size; ///< Size of start/stop flag.
|
||||
VehicleCellSize cell_size; ///< Vehicle sprite cell size.
|
||||
|
||||
void OnInit() override
|
||||
{
|
||||
this->cell_size = GetVehicleImageCellSize(this->type, EIT_IN_DEPOT);
|
||||
this->flag_size = maxdim(GetScaledSpriteSize(SPR_FLAG_VEH_STOPPED), GetScaledSpriteSize(SPR_FLAG_VEH_RUNNING));
|
||||
}
|
||||
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
@@ -659,33 +661,30 @@ struct DepotWindow : Window {
|
||||
if (this->type == VEH_TRAIN) {
|
||||
SetDParamMaxValue(0, 1000, 0, FS_SMALL);
|
||||
SetDParam(1, 1);
|
||||
this->count_width = GetStringBoundingBox(STR_TINY_BLACK_DECIMAL).width + WidgetDimensions::scaled.framerect.Horizontal();
|
||||
this->count_width = GetStringBoundingBox(STR_TINY_BLACK_DECIMAL).width + WidgetDimensions::scaled.hsep_normal;
|
||||
} else {
|
||||
this->count_width = 0;
|
||||
}
|
||||
|
||||
SetDParamMaxDigits(0, this->unitnumber_digits);
|
||||
Dimension unumber = GetStringBoundingBox(STR_BLACK_COMMA);
|
||||
const Sprite *spr = GetSprite(SPR_FLAG_VEH_STOPPED, ST_NORMAL);
|
||||
this->flag_width = UnScaleGUI(spr->width) + WidgetDimensions::scaled.framerect.right;
|
||||
this->flag_height = UnScaleGUI(spr->height);
|
||||
|
||||
if (this->type == VEH_TRAIN || this->type == VEH_ROAD) {
|
||||
min_height = std::max<uint>(unumber.height + WidgetDimensions::scaled.matrix.top, UnScaleGUI(spr->height));
|
||||
this->header_width = unumber.width + this->flag_width + WidgetDimensions::scaled.framerect.left;
|
||||
min_height = std::max<uint>(unumber.height, this->flag_size.height);
|
||||
this->header_width = unumber.width + WidgetDimensions::scaled.hsep_normal + this->flag_size.width + WidgetDimensions::scaled.hsep_normal;
|
||||
} else {
|
||||
min_height = unumber.height + UnScaleGUI(spr->height) + padding.height + WidgetDimensions::scaled.vsep_normal;
|
||||
this->header_width = std::max<uint>(unumber.width, this->flag_width) + WidgetDimensions::scaled.framerect.right;
|
||||
min_height = unumber.height + WidgetDimensions::scaled.vsep_normal + this->flag_size.height;
|
||||
this->header_width = std::max<uint>(unumber.width, this->flag_size.width) + WidgetDimensions::scaled.hsep_normal;
|
||||
}
|
||||
int base_width = this->count_width + this->header_width;
|
||||
int base_width = this->count_width + this->header_width + padding.width;
|
||||
|
||||
resize->height = std::max<uint>(GetVehicleImageCellSize(this->type, EIT_IN_DEPOT).height, min_height);
|
||||
resize->height = std::max<uint>(this->cell_size.height, min_height + padding.height);
|
||||
if (this->type == VEH_TRAIN) {
|
||||
resize->width = 1;
|
||||
size->width = base_width + 2 * ScaleSpriteTrad(29); // about 2 parts
|
||||
size->height = resize->height * 6;
|
||||
} else {
|
||||
resize->width = base_width + GetVehicleImageCellSize(this->type, EIT_IN_DEPOT).extend_left + GetVehicleImageCellSize(this->type, EIT_IN_DEPOT).extend_right;
|
||||
resize->width = base_width + this->cell_size.extend_left + this->cell_size.extend_right;
|
||||
size->width = resize->width * (this->type == VEH_ROAD ? 5 : 3);
|
||||
size->height = resize->height * (this->type == VEH_ROAD ? 5 : 3);
|
||||
}
|
||||
|
Reference in New Issue
Block a user