1
0
Fork 0

Codechange: Clean up build industry window. (#10779)

* Remove left-over code that treated an invalid list selection as 'fund
many', which is actually implemented as a separate button.
* Manual list management replaced with std::vector.
* Enabled state is only needed for the current selection.
* Selected index is not required only selected type.
pull/10780/head
PeterN 2023-05-07 08:19:09 +01:00 committed by GitHub
parent a836edd5a7
commit 8bf62dac81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 46 additions and 70 deletions

View File

@ -282,25 +282,23 @@ static WindowDesc _build_industry_desc(
/** Build (fund or prospect) a new industry, */ /** Build (fund or prospect) a new industry, */
class BuildIndustryWindow : public Window { class BuildIndustryWindow : public Window {
int selected_index; ///< index of the element in the matrix
IndustryType selected_type; ///< industry corresponding to the above index IndustryType selected_type; ///< industry corresponding to the above index
uint16 count; ///< How many industries are loaded std::vector<IndustryType> list; ///< List of industries.
IndustryType index[NUM_INDUSTRYTYPES + 1]; ///< Type of industry, in the order it was loaded bool enabled; ///< Availability state of the selected industry.
bool enabled[NUM_INDUSTRYTYPES + 1]; ///< availability state, coming from CBID_INDUSTRY_PROBABILITY (if ever)
Scrollbar *vscroll; Scrollbar *vscroll;
Dimension legend; ///< Dimension of the legend 'blob'. Dimension legend; ///< Dimension of the legend 'blob'.
/** The largest allowed minimum-width of the window, given in line heights */ /** The largest allowed minimum-width of the window, given in line heights */
static const int MAX_MINWIDTH_LINEHEIGHTS = 20; static const int MAX_MINWIDTH_LINEHEIGHTS = 20;
void UpdateAvailability()
{
this->enabled = this->selected_type != INVALID_INDUSTRYTYPE && (_game_mode == GM_EDITOR || GetIndustryProbabilityCallback(this->selected_type, IACT_USERCREATION, 1) > 0);
}
void SetupArrays() void SetupArrays()
{ {
this->count = 0; this->list.clear();
for (uint i = 0; i < lengthof(this->index); i++) {
this->index[i] = INVALID_INDUSTRYTYPE;
this->enabled[i] = false;
}
/* Fill the arrays with industries. /* Fill the arrays with industries.
* The tests performed after the enabled allow to load the industries * The tests performed after the enabled allow to load the industries
@ -314,32 +312,27 @@ class BuildIndustryWindow : public Window {
* and raw ones are loaded only when setting allows it */ * and raw ones are loaded only when setting allows it */
if (_game_mode != GM_EDITOR && indsp->IsRawIndustry() && _settings_game.construction.raw_industry_construction == 0) { if (_game_mode != GM_EDITOR && indsp->IsRawIndustry() && _settings_game.construction.raw_industry_construction == 0) {
/* Unselect if the industry is no longer in the list */ /* Unselect if the industry is no longer in the list */
if (this->selected_type == ind) this->selected_index = -1; if (this->selected_type == ind) this->selected_type = INVALID_INDUSTRYTYPE;
continue; continue;
} }
this->index[this->count] = ind;
this->enabled[this->count] = (_game_mode == GM_EDITOR) || GetIndustryProbabilityCallback(ind, IACT_USERCREATION, 1) > 0; this->list.push_back(ind);
/* Keep the selection to the correct line */
if (this->selected_type == ind) this->selected_index = this->count;
this->count++;
} }
} }
/* first industry type is selected if the current selection is invalid. /* First industry type is selected if the current selection is invalid. */
* I'll be damned if there are none available ;) */ if (this->selected_type == INVALID_INDUSTRYTYPE && !this->list.empty()) this->selected_type = this->list[0];
if (this->selected_index == -1) {
this->selected_index = 0;
this->selected_type = this->index[0];
}
this->vscroll->SetCount(this->count); this->UpdateAvailability();
this->vscroll->SetCount((int)this->list.size());
} }
/** Update status of the fund and display-chain widgets. */ /** Update status of the fund and display-chain widgets. */
void SetButtons() void SetButtons()
{ {
this->SetWidgetDisabledState(WID_DPI_FUND_WIDGET, this->selected_type != INVALID_INDUSTRYTYPE && !this->enabled[this->selected_index]); this->SetWidgetDisabledState(WID_DPI_FUND_WIDGET, this->selected_type != INVALID_INDUSTRYTYPE && !this->enabled);
this->SetWidgetDisabledState(WID_DPI_DISPLAY_WIDGET, this->selected_type == INVALID_INDUSTRYTYPE && this->enabled[this->selected_index]); this->SetWidgetDisabledState(WID_DPI_DISPLAY_WIDGET, this->selected_type == INVALID_INDUSTRYTYPE && this->enabled);
} }
/** /**
@ -392,7 +385,6 @@ class BuildIndustryWindow : public Window {
public: public:
BuildIndustryWindow() : Window(&_build_industry_desc) BuildIndustryWindow() : Window(&_build_industry_desc)
{ {
this->selected_index = -1;
this->selected_type = INVALID_INDUSTRYTYPE; this->selected_type = INVALID_INDUSTRYTYPE;
this->CreateNestedTree(); this->CreateNestedTree();
@ -423,9 +415,8 @@ public:
switch (widget) { switch (widget) {
case WID_DPI_MATRIX_WIDGET: { case WID_DPI_MATRIX_WIDGET: {
Dimension d = GetStringBoundingBox(STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES); Dimension d = GetStringBoundingBox(STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES);
for (uint16 i = 0; i < this->count; i++) { for (const auto &indtype : this->list) {
if (this->index[i] == INVALID_INDUSTRYTYPE) continue; d = maxdim(d, GetStringBoundingBox(GetIndustrySpec(indtype)->name));
d = maxdim(d, GetStringBoundingBox(GetIndustrySpec(this->index[i])->name));
} }
resize->height = std::max<uint>(this->legend.height, FONT_HEIGHT_NORMAL) + padding.height; resize->height = std::max<uint>(this->legend.height, FONT_HEIGHT_NORMAL) + padding.height;
d.width += this->legend.width + WidgetDimensions::scaled.hsep_wide + padding.width; d.width += this->legend.width + WidgetDimensions::scaled.hsep_wide + padding.width;
@ -442,14 +433,12 @@ public:
uint extra_lines_newgrf = 0; uint extra_lines_newgrf = 0;
uint max_minwidth = FONT_HEIGHT_NORMAL * MAX_MINWIDTH_LINEHEIGHTS; uint max_minwidth = FONT_HEIGHT_NORMAL * MAX_MINWIDTH_LINEHEIGHTS;
Dimension d = {0, 0}; Dimension d = {0, 0};
for (uint16 i = 0; i < this->count; i++) { for (const auto &indtype : this->list) {
if (this->index[i] == INVALID_INDUSTRYTYPE) continue; const IndustrySpec *indsp = GetIndustrySpec(indtype);
const IndustrySpec *indsp = GetIndustrySpec(this->index[i]);
CargoSuffix cargo_suffix[lengthof(indsp->accepts_cargo)]; CargoSuffix cargo_suffix[lengthof(indsp->accepts_cargo)];
/* Measure the accepted cargoes, if any. */ /* Measure the accepted cargoes, if any. */
GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_FUND, nullptr, this->index[i], indsp, indsp->accepts_cargo, cargo_suffix); GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_FUND, nullptr, indtype, indsp, indsp->accepts_cargo, cargo_suffix);
std::string cargostring = this->MakeCargoListString(indsp->accepts_cargo, cargo_suffix, lengthof(indsp->accepts_cargo), STR_INDUSTRY_VIEW_REQUIRES_N_CARGO); std::string cargostring = this->MakeCargoListString(indsp->accepts_cargo, cargo_suffix, lengthof(indsp->accepts_cargo), STR_INDUSTRY_VIEW_REQUIRES_N_CARGO);
Dimension strdim = GetStringBoundingBox(cargostring.c_str()); Dimension strdim = GetStringBoundingBox(cargostring.c_str());
if (strdim.width > max_minwidth) { if (strdim.width > max_minwidth) {
@ -459,7 +448,7 @@ public:
d = maxdim(d, strdim); d = maxdim(d, strdim);
/* Measure the produced cargoes, if any. */ /* Measure the produced cargoes, if any. */
GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_FUND, nullptr, this->index[i], indsp, indsp->produced_cargo, cargo_suffix); GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_FUND, nullptr, indtype, indsp, indsp->produced_cargo, cargo_suffix);
cargostring = this->MakeCargoListString(indsp->produced_cargo, cargo_suffix, lengthof(indsp->produced_cargo), STR_INDUSTRY_VIEW_PRODUCES_N_CARGO); cargostring = this->MakeCargoListString(indsp->produced_cargo, cargo_suffix, lengthof(indsp->produced_cargo), STR_INDUSTRY_VIEW_PRODUCES_N_CARGO);
strdim = GetStringBoundingBox(cargostring.c_str()); strdim = GetStringBoundingBox(cargostring.c_str());
if (strdim.width > max_minwidth) { if (strdim.width > max_minwidth) {
@ -503,8 +492,8 @@ public:
/* We've chosen many random industries but no industries have been specified */ /* We've chosen many random industries but no industries have been specified */
SetDParam(0, STR_FUND_INDUSTRY_BUILD_NEW_INDUSTRY); SetDParam(0, STR_FUND_INDUSTRY_BUILD_NEW_INDUSTRY);
} else { } else {
if (count > 0) { if (this->selected_type != INVALID_INDUSTRYTYPE) {
const IndustrySpec *indsp = GetIndustrySpec(this->index[this->selected_index]); const IndustrySpec *indsp = GetIndustrySpec(this->selected_type);
SetDParam(0, (_settings_game.construction.raw_industry_construction == 2 && indsp->IsRawIndustry()) ? STR_FUND_INDUSTRY_PROSPECT_NEW_INDUSTRY : STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY); SetDParam(0, (_settings_game.construction.raw_industry_construction == 2 && indsp->IsRawIndustry()) ? STR_FUND_INDUSTRY_PROSPECT_NEW_INDUSTRY : STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY);
} else { } else {
SetDParam(0, STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY); SetDParam(0, STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY);
@ -527,19 +516,15 @@ public:
icon.top = r.top + (this->resize.step_height - this->legend.height + 1) / 2; icon.top = r.top + (this->resize.step_height - this->legend.height + 1) / 2;
icon.bottom = icon.top + this->legend.height - 1; icon.bottom = icon.top + this->legend.height - 1;
for (uint16 i = 0; i < this->vscroll->GetCapacity() && i + this->vscroll->GetPosition() < this->count; i++) { for (uint16 i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) {
bool selected = this->selected_index == i + this->vscroll->GetPosition(); bool selected = this->selected_type == this->list[i];
if (this->index[i + this->vscroll->GetPosition()] == INVALID_INDUSTRYTYPE) { const IndustrySpec *indsp = GetIndustrySpec(this->list[i]);
DrawString(text, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES, selected ? TC_WHITE : TC_ORANGE);
} else {
const IndustrySpec *indsp = GetIndustrySpec(this->index[i + this->vscroll->GetPosition()]);
/* Draw the name of the industry in white is selected, otherwise, in orange */ /* Draw the name of the industry in white is selected, otherwise, in orange */
DrawString(text, indsp->name, selected ? TC_WHITE : TC_ORANGE); DrawString(text, indsp->name, selected ? TC_WHITE : TC_ORANGE);
GfxFillRect(icon, selected ? PC_WHITE : PC_BLACK); GfxFillRect(icon, selected ? PC_WHITE : PC_BLACK);
GfxFillRect(icon.Shrink(WidgetDimensions::scaled.bevel), indsp->map_colour); GfxFillRect(icon.Shrink(WidgetDimensions::scaled.bevel), indsp->map_colour);
}
text = text.Translate(0, this->resize.step_height); text = text.Translate(0, this->resize.step_height);
icon = icon.Translate(0, this->resize.step_height); icon = icon.Translate(0, this->resize.step_height);
@ -646,24 +631,23 @@ public:
case WID_DPI_MATRIX_WIDGET: { case WID_DPI_MATRIX_WIDGET: {
int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_DPI_MATRIX_WIDGET); int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_DPI_MATRIX_WIDGET);
if (y < this->count) { // Is it within the boundaries of available data? if (y != INT_MAX) { // Is it within the boundaries of available data?
this->selected_index = y; this->selected_type = this->list[y];
this->selected_type = this->index[y]; this->UpdateAvailability();
const IndustrySpec *indsp = (this->selected_type == INVALID_INDUSTRYTYPE) ? nullptr : GetIndustrySpec(this->selected_type);
const IndustrySpec *indsp = GetIndustrySpec(this->selected_type);
this->SetDirty(); this->SetDirty();
if (_thd.GetCallbackWnd() == this && if (_thd.GetCallbackWnd() == this &&
((_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && indsp != nullptr && indsp->IsRawIndustry()) || ((_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && indsp != nullptr && indsp->IsRawIndustry()) || !this->enabled)) {
this->selected_type == INVALID_INDUSTRYTYPE ||
!this->enabled[this->selected_index])) {
/* Reset the button state if going to prospecting or "build many industries" */ /* Reset the button state if going to prospecting or "build many industries" */
this->RaiseButtons(); this->RaiseButtons();
ResetObjectToPlace(); ResetObjectToPlace();
} }
this->SetButtons(); this->SetButtons();
if (this->enabled[this->selected_index] && click_count > 1) this->OnClick(pt, WID_DPI_FUND_WIDGET, 1); if (this->enabled && click_count > 1) this->OnClick(pt, WID_DPI_FUND_WIDGET, 1);
} }
break; break;
} }
@ -727,18 +711,13 @@ public:
IntervalTimer<TimerWindow> update_interval = {std::chrono::seconds(3), [this](auto) { IntervalTimer<TimerWindow> update_interval = {std::chrono::seconds(3), [this](auto) {
if (_game_mode == GM_EDITOR) return; if (_game_mode == GM_EDITOR) return;
if (this->count == 0) return; if (this->selected_type == INVALID_INDUSTRYTYPE) return;
const IndustrySpec *indsp = GetIndustrySpec(this->selected_type);
if (indsp->enabled) { bool enabled = this->enabled;
bool call_back_result = GetIndustryProbabilityCallback(this->selected_type, IACT_USERCREATION, 1) > 0; this->UpdateAvailability();
if (enabled != this->enabled) {
/* Only if result does match the previous state would it require a redraw. */ this->SetButtons();
if (call_back_result != this->enabled[this->selected_index]) { this->SetDirty();
this->enabled[this->selected_index] = call_back_result;
this->SetButtons();
this->SetDirty();
}
} }
}}; }};
@ -761,9 +740,6 @@ public:
{ {
if (!gui_scope) return; if (!gui_scope) return;
this->SetupArrays(); this->SetupArrays();
const IndustrySpec *indsp = (this->selected_type == INVALID_INDUSTRYTYPE) ? nullptr : GetIndustrySpec(this->selected_type);
if (indsp == nullptr) this->enabled[this->selected_index] = _settings_game.difficulty.industry_density != ID_FUND_ONLY;
this->SetButtons(); this->SetButtons();
this->SetDirty(); this->SetDirty();
} }