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_SHADEBOX, COLOUR_GREY),
|
||||||
NWidget(WWT_STICKYBOX, COLOUR_GREY),
|
NWidget(WWT_STICKYBOX, COLOUR_GREY),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
NWidget(WWT_PANEL, COLOUR_GREY),
|
NWidget(NWID_HORIZONTAL),
|
||||||
NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.framerect), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
|
NWidget(WWT_PANEL, COLOUR_GREY, WID_CI_LIST), SetFill(1, 0), SetResize(1, 1), SetScrollbar(WID_CI_SCROLLBAR), EndContainer(),
|
||||||
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
|
NWidget(NWID_VERTICAL),
|
||||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_RAIL_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0),
|
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_CI_SCROLLBAR),
|
||||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_RAIL_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1),
|
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
|
||||||
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(),
|
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
};
|
};
|
||||||
|
@ -1787,16 +1766,52 @@ static constexpr NWidgetPart _nested_company_infrastructure_widgets[] = {
|
||||||
*/
|
*/
|
||||||
struct CompanyInfrastructureWindow : Window
|
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.
|
RailTypes railtypes; ///< Valid railtypes.
|
||||||
RoadTypes roadtypes; ///< Valid roadtypes.
|
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)
|
CompanyInfrastructureWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
|
||||||
{
|
{
|
||||||
this->UpdateRailRoadTypes();
|
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;
|
this->owner = (Owner)this->window_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1827,29 +1842,89 @@ struct CompanyInfrastructureWindow : Window
|
||||||
this->roadtypes &= ~_roadtypes_hidden_mask;
|
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);
|
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||||
Money total;
|
|
||||||
|
|
||||||
uint32_t rail_total = c->infrastructure.GetRailTotal();
|
Money monthly_cost = 0;
|
||||||
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
|
Money total_monthly_cost = 0;
|
||||||
if (HasBit(this->railtypes, rt)) total += RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total);
|
|
||||||
}
|
|
||||||
total += SignalMaintenanceCost(c->infrastructure.signal);
|
|
||||||
|
|
||||||
uint32_t road_total = c->infrastructure.GetRoadTotal();
|
this->infrastructurelist.clear();
|
||||||
uint32_t tram_total = c->infrastructure.GetTramTotal();
|
|
||||||
for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
|
/* Railtypes and signals. */
|
||||||
if (HasBit(this->roadtypes, rt)) total += RoadMaintenanceCost(rt, c->infrastructure.road[rt], RoadTypeIsRoad(rt) ? road_total : tram_total);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
total += CanalMaintenanceCost(c->infrastructure.water);
|
monthly_cost = SignalMaintenanceCost(c->infrastructure.signal);
|
||||||
total += StationMaintenanceCost(c->infrastructure.station);
|
total_monthly_cost += monthly_cost;
|
||||||
total += AirportMaintenanceCost(c->index);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
return total;
|
/* roadtypes. */
|
||||||
|
this->infrastructurelist.emplace_back(ENTRY_HEADER, STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT);
|
||||||
|
|
||||||
|
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
|
void SetStringParameters(WidgetID widget) const override
|
||||||
|
@ -1863,230 +1938,109 @@ struct CompanyInfrastructureWindow : Window
|
||||||
|
|
||||||
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
|
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) {
|
uint max_lwidth = 0;
|
||||||
case WID_CI_RAIL_DESC: {
|
uint max_count = 1000; // Some random number to reserve enough space.
|
||||||
uint lines = 1; // Starts at 1 because a line is also required for the section title
|
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 &ie : this->infrastructurelist) {
|
||||||
|
max_lwidth = std::max(max_lwidth, GetStringBoundingBox(ie.label).width);
|
||||||
for (const auto &rt : _sorted_railtypes) {
|
max_cost = std::max(max_cost, ie.yearly_cost);
|
||||||
if (HasBit(this->railtypes, rt)) {
|
max_count = std::max(max_count, ie.count);
|
||||||
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));
|
/* add indent width to label text width. */
|
||||||
break;
|
this->max_label_width = max_lwidth + WidgetDimensions::scaled.hsep_indent;
|
||||||
}
|
|
||||||
|
|
||||||
case WID_CI_ROAD_DESC:
|
SetDParam(0, max_count);
|
||||||
case WID_CI_TRAM_DESC: {
|
this->max_count_width = GetStringBoundingBox(STR_JUST_COMMA).width + padding.width * 2;
|
||||||
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) {
|
if (_settings_game.economy.infrastructure_maintenance) {
|
||||||
StringID str_total = TimerGameEconomy::UsingWallclockUnits() ? STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_PERIOD : STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_YEAR;
|
SetDParam(0, max_cost);
|
||||||
SetDParamMaxValue(0, this->GetTotalMaintenanceCost() * 12); // Convert to per year
|
this->max_cost_width = GetStringBoundingBox(TimerGameEconomy::UsingWallclockUnits()
|
||||||
this->total_width = GetStringBoundingBox(str_total).width + WidgetDimensions::scaled.hsep_indent * 2;
|
? STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_PERIOD : STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_YEAR).width;
|
||||||
size.width = std::max(size.width, this->total_width);
|
this->total_y_padding = WidgetDimensions::scaled.vsep_normal * 3; // padding before and after horizontal line and after total cost line.
|
||||||
|
} else {
|
||||||
SetDParamMaxValue(0, max_cost * 12); // Convert to per year
|
this->max_cost_width = 0;
|
||||||
count_width += std::max(this->total_width, GetStringBoundingBox(str_total).width);
|
this->total_y_padding = WidgetDimensions::scaled.vsep_normal; // padding after last count line.
|
||||||
}
|
}
|
||||||
|
|
||||||
size.width = std::max(size.width, count_width);
|
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 height of the total line. */
|
/* Set max auto resize height for widget to 25 text lines. */
|
||||||
if (widget == WID_CI_TOTAL) {
|
size.height = static_cast<uint>(this->infrastructurelist.size()) * GetCharacterHeight(FS_NORMAL);
|
||||||
size.height = _settings_game.economy.infrastructure_maintenance ? std::max<uint>(size.height, WidgetDimensions::scaled.vsep_normal + GetCharacterHeight(FS_NORMAL)) : 0;
|
size.height = Clamp(size.height, 0, GetCharacterHeight(FS_NORMAL) * 25);
|
||||||
}
|
size.height += this->total_y_padding;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
resize.height = GetCharacterHeight(FS_NORMAL);
|
||||||
* 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);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawWidget(const Rect &r, WidgetID widget) const override
|
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;
|
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);
|
/* set boundaries for labels, infrastructure count and cost secions to handle text overflows and text direction change */
|
||||||
switch (widget) {
|
int label_right = rr.left + this->max_label_width;
|
||||||
case WID_CI_RAIL_DESC:
|
int cost_left = label_right + WidgetDimensions::scaled.hsep_wide;
|
||||||
DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT);
|
int cost_right = cost_left + this->max_cost_width;
|
||||||
|
int count_left = cost_right + WidgetDimensions::scaled.hsep_wide;
|
||||||
|
|
||||||
if (this->railtypes != RAILTYPES_NONE) {
|
auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->infrastructurelist);
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
for (auto it = first; it != last; ++it, y += GetCharacterHeight(FS_NORMAL)) {
|
||||||
|
switch (it->type) {
|
||||||
|
case ENTRY_LABEL_VALUES:
|
||||||
|
|
||||||
case WID_CI_RAIL_COUNT: {
|
SetDParam(0, it->count);
|
||||||
/* Draw infrastructure count for each valid railtype. */
|
DrawString(count_left, ir.right, y, STR_JUST_COMMA, TC_WHITE, SA_RIGHT);
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this->railtypes != RAILTYPES_NONE) {
|
|
||||||
this->DrawCountLine(r, y, c->infrastructure.signal, SignalMaintenanceCost(c->infrastructure.signal));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case WID_CI_ROAD_DESC:
|
[[fallthrough]];
|
||||||
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. */
|
case ENTRY_TOTAL_COST:
|
||||||
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) {
|
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);
|
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;
|
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:
|
SetDParam(0, it->yearly_cost);
|
||||||
DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT);
|
DrawString(cost_left, cost_right, y, TimerGameEconomy::UsingWallclockUnits()
|
||||||
DrawString(ir.left, ir.right, y += GetCharacterHeight(FS_NORMAL), STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS);
|
? STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_PERIOD : STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL_YEAR, TC_FROMSTRING, SA_RIGHT);
|
||||||
DrawString(ir.left, ir.right, y += GetCharacterHeight(FS_NORMAL), STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS);
|
}
|
||||||
break;
|
if (it->type == ENTRY_TOTAL_COST) break;
|
||||||
|
|
||||||
case WID_CI_STATION_COUNT:
|
[[fallthrough]];
|
||||||
this->DrawCountLine(r, y, c->infrastructure.station, StationMaintenanceCost(c->infrastructure.station));
|
|
||||||
this->DrawCountLine(r, y, c->infrastructure.airport, AirportMaintenanceCost(c->index));
|
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;
|
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.
|
* Some data on this window has become invalid.
|
||||||
|
@ -2098,6 +2052,8 @@ struct CompanyInfrastructureWindow : Window
|
||||||
if (!gui_scope) return;
|
if (!gui_scope) return;
|
||||||
|
|
||||||
this->UpdateRailRoadTypes();
|
this->UpdateRailRoadTypes();
|
||||||
|
this->BuildCompanyInfrastructureCache();
|
||||||
|
this->SetWidgetDirty(WID_CI_LIST);
|
||||||
this->ReInit();
|
this->ReInit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -170,18 +170,8 @@ enum SelectCompanyManagerFaceWidgets : WidgetID {
|
||||||
/** Widgets of the #CompanyInfrastructureWindow class. */
|
/** Widgets of the #CompanyInfrastructureWindow class. */
|
||||||
enum CompanyInfrastructureWidgets : WidgetID {
|
enum CompanyInfrastructureWidgets : WidgetID {
|
||||||
WID_CI_CAPTION, ///< Caption of window.
|
WID_CI_CAPTION, ///< Caption of window.
|
||||||
WID_CI_RAIL_DESC, ///< Description of rail.
|
WID_CI_LIST, ///< Infrastructure list.
|
||||||
WID_CI_RAIL_COUNT, ///< Count of rail.
|
WID_CI_SCROLLBAR, ///< Infrastructure list scroll bar.
|
||||||
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.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Widgets of the #BuyCompanyWindow class. */
|
/** Widgets of the #BuyCompanyWindow class. */
|
||||||
|
|
Loading…
Reference in New Issue