mirror of https://github.com/OpenTTD/OpenTTD
Fix #9056: [interface] missing scrollbar on infrastructure window.
parent
8bf2ab62d9
commit
60f6adfea8
|
@ -1752,32 +1752,11 @@ static constexpr NWidgetPart _nested_company_infrastructure_widgets[] = {
|
|||
NWidget(WWT_SHADEBOX, COLOUR_GREY),
|
||||
NWidget(WWT_STICKYBOX, COLOUR_GREY),
|
||||
EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY),
|
||||
NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.framerect), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_RAIL_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_RAIL_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_ROAD_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_ROAD_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_TRAM_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_TRAM_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_WATER_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_WATER_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_STATION_DESC), SetMinimalTextLines(3, 0), SetFill(1, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_STATION_COUNT), SetMinimalTextLines(3, 0), SetFill(0, 1),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_TOTAL_DESC), SetFill(1, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_TOTAL), SetFill(0, 1),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY, WID_CI_LIST), SetFill(1, 0), SetResize(1, 1), SetScrollbar(WID_CI_SCROLLBAR), EndContainer(),
|
||||
NWidget(NWID_VERTICAL),
|
||||
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_CI_SCROLLBAR),
|
||||
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
};
|
||||
|
@ -1787,16 +1766,52 @@ static constexpr NWidgetPart _nested_company_infrastructure_widgets[] = {
|
|||
*/
|
||||
struct CompanyInfrastructureWindow : Window
|
||||
{
|
||||
/* Company Ifrastructure Window infrastructure cache type. */
|
||||
enum CacheEntryType : int {
|
||||
ENTRY_HEADER, ///< section headers.
|
||||
ENTRY_BLANK_LINE, ///< blank line.
|
||||
ENTRY_LABEL_ONLY, ///< label only entry, no values.
|
||||
ENTRY_LABEL_VALUES, ///< label and values (count, cost).
|
||||
ENTRY_TOTAL_COST, ///< total maintenance cost.
|
||||
};
|
||||
|
||||
/* Infrastructure count and maintenance cost cache container. */
|
||||
struct InfrastructureCache {
|
||||
CacheEntryType type;
|
||||
StringID label;
|
||||
uint count;
|
||||
Money yearly_cost;
|
||||
|
||||
InfrastructureCache(CacheEntryType type, StringID label, uint count = 0, Money monthly_cost = 0) : type(type), label(label), count(count), yearly_cost(monthly_cost * 12)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
RailTypes railtypes; ///< Valid railtypes.
|
||||
RoadTypes roadtypes; ///< Valid roadtypes.
|
||||
|
||||
uint total_width; ///< String width of the total cost line.
|
||||
uint total_y_padding; ///< Infrastructure label size.
|
||||
uint max_label_width; ///< Infrastructure label size.
|
||||
uint max_cost_width; ///< Infratructure maintenance cost text size.
|
||||
uint max_count_width; ///< Infrastructure count text size.
|
||||
|
||||
Scrollbar *vscroll; ///< scroll bar widget.
|
||||
|
||||
mutable std::vector<InfrastructureCache> infrastructurelist; ///< infrastructure and total maintenance cost cache.
|
||||
|
||||
CompanyInfrastructureWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
|
||||
{
|
||||
this->UpdateRailRoadTypes();
|
||||
|
||||
this->InitNested(window_number);
|
||||
this->CreateNestedTree();
|
||||
|
||||
this->vscroll = this->GetScrollbar(WID_CI_SCROLLBAR);
|
||||
this->BuildCompanyInfrastructureCache();
|
||||
|
||||
this->SetWidgetDirty(WID_CI_LIST); // Force repaint of company infrastructure widget.
|
||||
|
||||
this->FinishInitNested(window_number);
|
||||
|
||||
this->owner = (Owner)this->window_number;
|
||||
}
|
||||
|
||||
|
@ -1827,29 +1842,89 @@ struct CompanyInfrastructureWindow : Window
|
|||
this->roadtypes &= ~_roadtypes_hidden_mask;
|
||||
}
|
||||
|
||||
/** Get total infrastructure maintenance cost. */
|
||||
Money GetTotalMaintenanceCost() const
|
||||
/**
|
||||
* Build a vector of infrastructure types(roads, trains, trams, airports, stations, ships) to be displayed.
|
||||
* Total maintenance cost of all infrastructure types is last entry in vector.
|
||||
*/
|
||||
void BuildCompanyInfrastructureCache() const
|
||||
{
|
||||
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||
Money total;
|
||||
|
||||
uint32_t rail_total = c->infrastructure.GetRailTotal();
|
||||
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
|
||||
if (HasBit(this->railtypes, rt)) total += RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total);
|
||||
}
|
||||
total += SignalMaintenanceCost(c->infrastructure.signal);
|
||||
Money monthly_cost = 0;
|
||||
Money total_monthly_cost = 0;
|
||||
|
||||
uint32_t road_total = c->infrastructure.GetRoadTotal();
|
||||
uint32_t tram_total = c->infrastructure.GetTramTotal();
|
||||
for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
|
||||
if (HasBit(this->roadtypes, rt)) total += RoadMaintenanceCost(rt, c->infrastructure.road[rt], RoadTypeIsRoad(rt) ? road_total : tram_total);
|
||||
this->infrastructurelist.clear();
|
||||
|
||||
/* Railtypes and signals. */
|
||||
this->infrastructurelist.emplace_back(ENTRY_HEADER, STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT);
|
||||
|
||||
if (this->railtypes != RAILTYPES_NONE) {
|
||||
for (const auto &rt : _sorted_railtypes) {
|
||||
if (!HasBit(this->railtypes, rt)) continue;
|
||||
monthly_cost = RailMaintenanceCost(rt, c->infrastructure.rail[rt], c->infrastructure.GetRailTotal());
|
||||
total_monthly_cost += monthly_cost;
|
||||
this->infrastructurelist.emplace_back(ENTRY_LABEL_VALUES, GetRailTypeInfo(rt)->strings.name, c->infrastructure.rail[rt], monthly_cost);
|
||||
}
|
||||
|
||||
monthly_cost = SignalMaintenanceCost(c->infrastructure.signal);
|
||||
total_monthly_cost += monthly_cost;
|
||||
this->infrastructurelist.emplace_back(ENTRY_LABEL_VALUES, STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS, c->infrastructure.signal, monthly_cost);
|
||||
} else {
|
||||
/* No valid railtype. */
|
||||
this->infrastructurelist.emplace_back(ENTRY_LABEL_ONLY, STR_COMPANY_VIEW_INFRASTRUCTURE_NONE);
|
||||
}
|
||||
|
||||
total += CanalMaintenanceCost(c->infrastructure.water);
|
||||
total += StationMaintenanceCost(c->infrastructure.station);
|
||||
total += AirportMaintenanceCost(c->index);
|
||||
/* roadtypes. */
|
||||
this->infrastructurelist.emplace_back(ENTRY_HEADER, STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT);
|
||||
|
||||
return total;
|
||||
for (const auto &rt : _sorted_roadtypes) {
|
||||
if (!HasBit(this->roadtypes, rt) || !RoadTypeIsRoad(rt)) continue;
|
||||
|
||||
monthly_cost = RoadMaintenanceCost(rt, c->infrastructure.road[rt], c->infrastructure.GetRoadTotal());
|
||||
total_monthly_cost += monthly_cost;
|
||||
this->infrastructurelist.emplace_back(ENTRY_LABEL_VALUES, GetRoadTypeInfo(rt)->strings.name, c->infrastructure.road[rt], monthly_cost);
|
||||
}
|
||||
|
||||
/* trams. */
|
||||
this->infrastructurelist.emplace_back(ENTRY_HEADER, STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT);
|
||||
|
||||
bool has_trams = false;
|
||||
for (const auto &rt : _sorted_roadtypes) {
|
||||
if (!HasBit(this->roadtypes, rt) || !RoadTypeIsTram(rt)) continue;
|
||||
|
||||
has_trams = true;
|
||||
monthly_cost = RoadMaintenanceCost(rt, c->infrastructure.road[rt], c->infrastructure.GetRoadTotal());
|
||||
total_monthly_cost += monthly_cost;
|
||||
this->infrastructurelist.emplace_back(ENTRY_LABEL_VALUES, GetRoadTypeInfo(rt)->strings.name, c->infrastructure.road[rt], monthly_cost);
|
||||
}
|
||||
/* No valid trams. */
|
||||
if (!has_trams)
|
||||
this->infrastructurelist.emplace_back(ENTRY_BLANK_LINE, STR_COMPANY_VIEW_INFRASTRUCTURE_NONE);
|
||||
|
||||
/* Canals, locks, and ship depots (docks are counted as stations). */
|
||||
this->infrastructurelist.emplace_back(ENTRY_HEADER, STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT);
|
||||
|
||||
monthly_cost = CanalMaintenanceCost(c->infrastructure.water);
|
||||
total_monthly_cost += monthly_cost;
|
||||
this->infrastructurelist.emplace_back(ENTRY_LABEL_VALUES, STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS, c->infrastructure.water, monthly_cost);
|
||||
|
||||
/* Airports. */
|
||||
this->infrastructurelist.emplace_back(ENTRY_HEADER, STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT);
|
||||
|
||||
monthly_cost = StationMaintenanceCost(c->infrastructure.station);
|
||||
total_monthly_cost += monthly_cost;
|
||||
this->infrastructurelist.emplace_back(ENTRY_LABEL_VALUES, STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS, c->infrastructure.station, monthly_cost);
|
||||
|
||||
monthly_cost = AirportMaintenanceCost(c->index);
|
||||
total_monthly_cost += monthly_cost;
|
||||
this->infrastructurelist.emplace_back(ENTRY_LABEL_VALUES, STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS, c->infrastructure.airport, monthly_cost);
|
||||
|
||||
/* Total monthly maintenance cost. */
|
||||
if(_settings_game.economy.infrastructure_maintenance)
|
||||
this->infrastructurelist.emplace_back(ENTRY_TOTAL_COST, STR_COMPANY_VIEW_INFRASTRUCTURE_NONE, 0, total_monthly_cost);
|
||||
|
||||
/* Update scrollbar as well. */
|
||||
this->vscroll->SetCount(this->infrastructurelist.size());
|
||||
}
|
||||
|
||||
void SetStringParameters(WidgetID widget) const override
|
||||
|
@ -1863,231 +1938,110 @@ struct CompanyInfrastructureWindow : Window
|
|||
|
||||
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
|
||||
{
|
||||
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||
if (widget != WID_CI_LIST) return;
|
||||
|
||||
switch (widget) {
|
||||
case WID_CI_RAIL_DESC: {
|
||||
uint lines = 1; // Starts at 1 because a line is also required for the section title
|
||||
uint max_lwidth = 0;
|
||||
uint max_count = 1000; // Some random number to reserve enough space.
|
||||
Money max_cost = 1000000; // Some random number to reserve enough space.
|
||||
|
||||
size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT).width + padding.width);
|
||||
|
||||
for (const auto &rt : _sorted_railtypes) {
|
||||
if (HasBit(this->railtypes, rt)) {
|
||||
lines++;
|
||||
size.width = std::max(size.width, GetStringBoundingBox(GetRailTypeInfo(rt)->strings.name).width + padding.width + WidgetDimensions::scaled.hsep_indent);
|
||||
}
|
||||
}
|
||||
if (this->railtypes != RAILTYPES_NONE) {
|
||||
lines++;
|
||||
size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS).width + padding.width + WidgetDimensions::scaled.hsep_indent);
|
||||
}
|
||||
|
||||
size.height = std::max(size.height, lines * GetCharacterHeight(FS_NORMAL));
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_CI_ROAD_DESC:
|
||||
case WID_CI_TRAM_DESC: {
|
||||
uint lines = 1; // Starts at 1 because a line is also required for the section title
|
||||
|
||||
size.width = std::max(size.width, GetStringBoundingBox(widget == WID_CI_ROAD_DESC ? STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT : STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT).width + padding.width);
|
||||
|
||||
for (const auto &rt : _sorted_roadtypes) {
|
||||
if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_DESC)) {
|
||||
lines++;
|
||||
size.width = std::max(size.width, GetStringBoundingBox(GetRoadTypeInfo(rt)->strings.name).width + padding.width + WidgetDimensions::scaled.hsep_indent);
|
||||
}
|
||||
}
|
||||
|
||||
size.height = std::max(size.height, lines * GetCharacterHeight(FS_NORMAL));
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_CI_WATER_DESC:
|
||||
size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT).width + padding.width);
|
||||
size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS).width + padding.width + WidgetDimensions::scaled.hsep_indent);
|
||||
break;
|
||||
|
||||
case WID_CI_STATION_DESC:
|
||||
size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT).width + padding.width);
|
||||
size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS).width + padding.width + WidgetDimensions::scaled.hsep_indent);
|
||||
size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS).width + padding.width + WidgetDimensions::scaled.hsep_indent);
|
||||
break;
|
||||
|
||||
case WID_CI_RAIL_COUNT:
|
||||
case WID_CI_ROAD_COUNT:
|
||||
case WID_CI_TRAM_COUNT:
|
||||
case WID_CI_WATER_COUNT:
|
||||
case WID_CI_STATION_COUNT:
|
||||
case WID_CI_TOTAL: {
|
||||
/* Find the maximum count that is displayed. */
|
||||
uint32_t max_val = 1000; // Some random number to reserve enough space.
|
||||
Money max_cost = 10000; // Some random number to reserve enough space.
|
||||
uint32_t rail_total = c->infrastructure.GetRailTotal();
|
||||
for (RailType rt = RAILTYPE_BEGIN; rt < RAILTYPE_END; rt++) {
|
||||
max_val = std::max(max_val, c->infrastructure.rail[rt]);
|
||||
max_cost = std::max(max_cost, RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total));
|
||||
}
|
||||
max_val = std::max(max_val, c->infrastructure.signal);
|
||||
max_cost = std::max(max_cost, SignalMaintenanceCost(c->infrastructure.signal));
|
||||
uint32_t road_total = c->infrastructure.GetRoadTotal();
|
||||
uint32_t tram_total = c->infrastructure.GetTramTotal();
|
||||
for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) {
|
||||
max_val = std::max(max_val, c->infrastructure.road[rt]);
|
||||
max_cost = std::max(max_cost, RoadMaintenanceCost(rt, c->infrastructure.road[rt], RoadTypeIsRoad(rt) ? road_total : tram_total));
|
||||
|
||||
}
|
||||
max_val = std::max(max_val, c->infrastructure.water);
|
||||
max_cost = std::max(max_cost, CanalMaintenanceCost(c->infrastructure.water));
|
||||
max_val = std::max(max_val, c->infrastructure.station);
|
||||
max_cost = std::max(max_cost, StationMaintenanceCost(c->infrastructure.station));
|
||||
max_val = std::max(max_val, c->infrastructure.airport);
|
||||
max_cost = std::max(max_cost, AirportMaintenanceCost(c->index));
|
||||
|
||||
SetDParamMaxValue(0, max_val);
|
||||
uint count_width = GetStringBoundingBox(STR_JUST_COMMA).width + WidgetDimensions::scaled.hsep_indent; // Reserve some wiggle room
|
||||
|
||||
if (_settings_game.economy.infrastructure_maintenance) {
|
||||
StringID str_total = TimerGameEconomy::UsingWallclockUnits() ? STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_PERIOD : STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_YEAR;
|
||||
SetDParamMaxValue(0, this->GetTotalMaintenanceCost() * 12); // Convert to per year
|
||||
this->total_width = GetStringBoundingBox(str_total).width + WidgetDimensions::scaled.hsep_indent * 2;
|
||||
size.width = std::max(size.width, this->total_width);
|
||||
|
||||
SetDParamMaxValue(0, max_cost * 12); // Convert to per year
|
||||
count_width += std::max(this->total_width, GetStringBoundingBox(str_total).width);
|
||||
}
|
||||
|
||||
size.width = std::max(size.width, count_width);
|
||||
|
||||
/* Set height of the total line. */
|
||||
if (widget == WID_CI_TOTAL) {
|
||||
size.height = _settings_game.economy.infrastructure_maintenance ? std::max<uint>(size.height, WidgetDimensions::scaled.vsep_normal + GetCharacterHeight(FS_NORMAL)) : 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
for (const auto &ie : this->infrastructurelist) {
|
||||
max_lwidth = std::max(max_lwidth, GetStringBoundingBox(ie.label).width);
|
||||
max_cost = std::max(max_cost, ie.yearly_cost);
|
||||
max_count = std::max(max_count, ie.count);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for drawing the counts line.
|
||||
* @param r The bounds to draw in.
|
||||
* @param y The y position to draw at.
|
||||
* @param count The count to show on this line.
|
||||
* @param monthly_cost The monthly costs.
|
||||
*/
|
||||
void DrawCountLine(const Rect &r, int &y, int count, Money monthly_cost) const
|
||||
{
|
||||
SetDParam(0, count);
|
||||
DrawString(r.left, r.right, y += GetCharacterHeight(FS_NORMAL), STR_JUST_COMMA, TC_WHITE, SA_RIGHT);
|
||||
/* add indent width to label text width. */
|
||||
this->max_label_width = max_lwidth + WidgetDimensions::scaled.hsep_indent;
|
||||
|
||||
SetDParam(0, max_count);
|
||||
this->max_count_width = GetStringBoundingBox(STR_JUST_COMMA).width + padding.width * 2;
|
||||
|
||||
if (_settings_game.economy.infrastructure_maintenance) {
|
||||
SetDParam(0, monthly_cost * 12); // Convert to per year
|
||||
Rect tr = r.WithWidth(this->total_width, _current_text_dir == TD_RTL);
|
||||
DrawString(tr.left, tr.right, y,
|
||||
TimerGameEconomy::UsingWallclockUnits() ? STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_PERIOD : STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_YEAR,
|
||||
TC_FROMSTRING, SA_RIGHT);
|
||||
SetDParam(0, max_cost);
|
||||
this->max_cost_width = GetStringBoundingBox(TimerGameEconomy::UsingWallclockUnits()
|
||||
? STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_PERIOD : STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_YEAR).width;
|
||||
this->total_y_padding = WidgetDimensions::scaled.vsep_normal * 3; // padding before and after horizontal line and after total cost line.
|
||||
} else {
|
||||
this->max_cost_width = 0;
|
||||
this->total_y_padding = WidgetDimensions::scaled.vsep_normal; // padding after last count line.
|
||||
}
|
||||
|
||||
size.width = this->max_label_width + this->max_cost_width + this->max_count_width + WidgetDimensions::scaled.hsep_wide * 2;
|
||||
size.width += WidgetDimensions::scaled.hsep_normal * 2;
|
||||
|
||||
/* Set max auto resize height for widget to 25 text lines. */
|
||||
size.height = static_cast<uint>(this->infrastructurelist.size()) * GetCharacterHeight(FS_NORMAL);
|
||||
size.height = Clamp(size.height, 0, GetCharacterHeight(FS_NORMAL) * 25);
|
||||
size.height += this->total_y_padding;
|
||||
|
||||
resize.height = GetCharacterHeight(FS_NORMAL);
|
||||
}
|
||||
|
||||
void DrawWidget(const Rect &r, WidgetID widget) const override
|
||||
{
|
||||
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||
if (widget != WID_CI_LIST) return;
|
||||
|
||||
int y = r.top;
|
||||
Rect rr = r.Shrink(WidgetDimensions::scaled.hsep_normal);
|
||||
Rect ir = rr.Indent(WidgetDimensions::scaled.hsep_indent, _current_text_dir == TD_RTL);
|
||||
|
||||
Rect ir = r.Indent(WidgetDimensions::scaled.hsep_indent, _current_text_dir == TD_RTL);
|
||||
switch (widget) {
|
||||
case WID_CI_RAIL_DESC:
|
||||
DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT);
|
||||
/* set boundaries for labels, infrastructure count and cost secions to handle text overflows and text direction change */
|
||||
int label_right = rr.left + this->max_label_width;
|
||||
int cost_left = label_right + WidgetDimensions::scaled.hsep_wide;
|
||||
int cost_right = cost_left + this->max_cost_width;
|
||||
int count_left = cost_right + WidgetDimensions::scaled.hsep_wide;
|
||||
|
||||
if (this->railtypes != RAILTYPES_NONE) {
|
||||
/* Draw name of each valid railtype. */
|
||||
for (const auto &rt : _sorted_railtypes) {
|
||||
if (HasBit(this->railtypes, rt)) {
|
||||
DrawString(ir.left, ir.right, y += GetCharacterHeight(FS_NORMAL), GetRailTypeInfo(rt)->strings.name, TC_WHITE);
|
||||
auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->infrastructurelist);
|
||||
|
||||
for (auto it = first; it != last; ++it, y += GetCharacterHeight(FS_NORMAL)) {
|
||||
switch (it->type) {
|
||||
case ENTRY_LABEL_VALUES:
|
||||
|
||||
SetDParam(0, it->count);
|
||||
DrawString(count_left, ir.right, y, STR_JUST_COMMA, TC_WHITE, SA_RIGHT);
|
||||
|
||||
[[fallthrough]];
|
||||
|
||||
case ENTRY_TOTAL_COST:
|
||||
if (_settings_game.economy.infrastructure_maintenance) {
|
||||
|
||||
if (it->type == ENTRY_TOTAL_COST) {
|
||||
y += WidgetDimensions::scaled.vsep_normal;
|
||||
GfxFillRect(cost_left, y, cost_right, y + WidgetDimensions::scaled.bevel.top - 1, PC_WHITE);
|
||||
y += WidgetDimensions::scaled.vsep_normal;
|
||||
}
|
||||
}
|
||||
DrawString(ir.left, ir.right, y += GetCharacterHeight(FS_NORMAL), STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS);
|
||||
} else {
|
||||
/* No valid railtype. */
|
||||
DrawString(ir.left, ir.right, y += GetCharacterHeight(FS_NORMAL), STR_COMPANY_VIEW_INFRASTRUCTURE_NONE);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case WID_CI_RAIL_COUNT: {
|
||||
/* Draw infrastructure count for each valid railtype. */
|
||||
uint32_t rail_total = c->infrastructure.GetRailTotal();
|
||||
for (const auto &rt : _sorted_railtypes) {
|
||||
if (HasBit(this->railtypes, rt)) {
|
||||
this->DrawCountLine(r, y, c->infrastructure.rail[rt], RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total));
|
||||
SetDParam(0, it->yearly_cost);
|
||||
DrawString(cost_left, cost_right, y, TimerGameEconomy::UsingWallclockUnits()
|
||||
? STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_PERIOD : STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_YEAR, TC_FROMSTRING, SA_RIGHT);
|
||||
}
|
||||
}
|
||||
if (this->railtypes != RAILTYPES_NONE) {
|
||||
this->DrawCountLine(r, y, c->infrastructure.signal, SignalMaintenanceCost(c->infrastructure.signal));
|
||||
}
|
||||
break;
|
||||
if (it->type == ENTRY_TOTAL_COST) break;
|
||||
|
||||
[[fallthrough]];
|
||||
|
||||
case ENTRY_LABEL_ONLY:
|
||||
DrawString(ir.left, label_right, y, it->label, TC_WHITE);
|
||||
break;
|
||||
case ENTRY_HEADER:
|
||||
DrawString(rr.left, label_right, y, it->label);
|
||||
break;
|
||||
case ENTRY_BLANK_LINE:
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_CI_ROAD_DESC:
|
||||
case WID_CI_TRAM_DESC: {
|
||||
DrawString(r.left, r.right, y, widget == WID_CI_ROAD_DESC ? STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT : STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT);
|
||||
|
||||
/* Draw name of each valid roadtype. */
|
||||
for (const auto &rt : _sorted_roadtypes) {
|
||||
if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_DESC)) {
|
||||
DrawString(ir.left, ir.right, y += GetCharacterHeight(FS_NORMAL), GetRoadTypeInfo(rt)->strings.name, TC_WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_CI_ROAD_COUNT:
|
||||
case WID_CI_TRAM_COUNT: {
|
||||
uint32_t road_tram_total = widget == WID_CI_ROAD_COUNT ? c->infrastructure.GetRoadTotal() : c->infrastructure.GetTramTotal();
|
||||
for (const auto &rt : _sorted_roadtypes) {
|
||||
if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_COUNT)) {
|
||||
this->DrawCountLine(r, y, c->infrastructure.road[rt], RoadMaintenanceCost(rt, c->infrastructure.road[rt], road_tram_total));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_CI_WATER_DESC:
|
||||
DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT);
|
||||
DrawString(ir.left, ir.right, y += GetCharacterHeight(FS_NORMAL), STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS);
|
||||
break;
|
||||
|
||||
case WID_CI_WATER_COUNT:
|
||||
this->DrawCountLine(r, y, c->infrastructure.water, CanalMaintenanceCost(c->infrastructure.water));
|
||||
break;
|
||||
|
||||
case WID_CI_TOTAL:
|
||||
if (_settings_game.economy.infrastructure_maintenance) {
|
||||
Rect tr = r.WithWidth(this->total_width, _current_text_dir == TD_RTL);
|
||||
GfxFillRect(tr.left, y, tr.right, y + WidgetDimensions::scaled.bevel.top - 1, PC_WHITE);
|
||||
y += WidgetDimensions::scaled.vsep_normal;
|
||||
SetDParam(0, this->GetTotalMaintenanceCost() * 12); // Convert to per year
|
||||
DrawString(tr.left, tr.right, y,
|
||||
TimerGameEconomy::UsingWallclockUnits() ? STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_PERIOD : STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_YEAR,
|
||||
TC_FROMSTRING, SA_RIGHT);
|
||||
}
|
||||
break;
|
||||
|
||||
case WID_CI_STATION_DESC:
|
||||
DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT);
|
||||
DrawString(ir.left, ir.right, y += GetCharacterHeight(FS_NORMAL), STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS);
|
||||
DrawString(ir.left, ir.right, y += GetCharacterHeight(FS_NORMAL), STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS);
|
||||
break;
|
||||
|
||||
case WID_CI_STATION_COUNT:
|
||||
this->DrawCountLine(r, y, c->infrastructure.station, StationMaintenanceCost(c->infrastructure.station));
|
||||
this->DrawCountLine(r, y, c->infrastructure.airport, AirportMaintenanceCost(c->index));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Update cache at regular intervals. */
|
||||
IntervalTimer<TimerWindow> redraw_interval = {std::chrono::seconds(1), [this](auto) {
|
||||
this->BuildCompanyInfrastructureCache();
|
||||
this->SetWidgetDirty(WID_CI_LIST);
|
||||
}};
|
||||
|
||||
void OnResize() override
|
||||
{
|
||||
this->vscroll->SetCapacityFromWidget(this, WID_CI_LIST, this->total_y_padding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Some data on this window has become invalid.
|
||||
* @param data Information about the changed data.
|
||||
|
@ -2098,6 +2052,8 @@ struct CompanyInfrastructureWindow : Window
|
|||
if (!gui_scope) return;
|
||||
|
||||
this->UpdateRailRoadTypes();
|
||||
this->BuildCompanyInfrastructureCache();
|
||||
this->SetWidgetDirty(WID_CI_LIST);
|
||||
this->ReInit();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -170,18 +170,8 @@ enum SelectCompanyManagerFaceWidgets : WidgetID {
|
|||
/** Widgets of the #CompanyInfrastructureWindow class. */
|
||||
enum CompanyInfrastructureWidgets : WidgetID {
|
||||
WID_CI_CAPTION, ///< Caption of window.
|
||||
WID_CI_RAIL_DESC, ///< Description of rail.
|
||||
WID_CI_RAIL_COUNT, ///< Count of rail.
|
||||
WID_CI_ROAD_DESC, ///< Description of road.
|
||||
WID_CI_ROAD_COUNT, ///< Count of road.
|
||||
WID_CI_TRAM_DESC, ///< Description of tram.
|
||||
WID_CI_TRAM_COUNT, ///< Count of tram.
|
||||
WID_CI_WATER_DESC, ///< Description of water.
|
||||
WID_CI_WATER_COUNT, ///< Count of water.
|
||||
WID_CI_STATION_DESC, ///< Description of station.
|
||||
WID_CI_STATION_COUNT, ///< Count of station.
|
||||
WID_CI_TOTAL_DESC, ///< Description of total.
|
||||
WID_CI_TOTAL, ///< Count of total.
|
||||
WID_CI_LIST, ///< Infrastructure list.
|
||||
WID_CI_SCROLLBAR, ///< Infrastructure list scroll bar.
|
||||
};
|
||||
|
||||
/** Widgets of the #BuyCompanyWindow class. */
|
||||
|
|
Loading…
Reference in New Issue