1
0
Fork 0

Compare commits

...

10 Commits

Author SHA1 Message Date
Peter Nelson fd2dd4397f Codechange: Use range-for and iterator to populate default cargo table. 2023-09-17 21:26:01 +01:00
Peter Nelson 280dce9543 Codechange: Reorder CargoSpec to reduce alignment padding. 2023-09-17 21:26:01 +01:00
Peter Nelson e8cbc3c2c7 Codechange: Simplify initialization of default cargoes. 2023-09-17 21:26:01 +01:00
Patric Stout c6864637fb
Add: [GitHub] also test if release builds without asserts are warning-free (#11309) 2023-09-17 19:47:55 +02:00
Rubidium 3a2509198f Codechange: use better location for the "invalid" action sentinel value
It used to be a random sentinel for end-of-(widget-)list that was used to tell
that no action has taken place yet. Since the last action is practically the
widget that was pressed, add the sentinel to that enumeration.
2023-09-17 19:44:20 +02:00
Rubidium 09a7902d36 Fix 8ab0936: missed WIDGET_LIST_END removals 2023-09-17 19:44:20 +02:00
Jonathan G Rennison 3afb732c37 Fix #11307: Incorrect GroupStatistics after selling leading wagon
When this results in a countable consist
2023-09-17 18:42:37 +01:00
Peter Nelson 14bcfff6f5 Codechange: Rename INVALID_CARGO to INVALID_CARGO_BITNUM
... to avoid future ambiguity.
2023-09-17 16:56:07 +01:00
Peter Nelson 9d1b131c44 Codechange: Use correct constant for invalid cargo type. 2023-09-17 16:56:07 +01:00
Rubidium 7ef22af2bb Codechange: introduce and use function to raise and dirty a set of widgets when they are lowered 2023-09-17 16:03:01 +02:00
22 changed files with 125 additions and 125 deletions

View File

@ -73,10 +73,15 @@ jobs:
fail-fast: false
matrix:
include:
- name: Clang
- name: Clang - Debug
compiler: clang
cxxcompiler: clang++
libraries: libsdl2-dev
- name: Clang - Release
compiler: clang
cxxcompiler: clang++
libraries: libsdl2-dev
extra-cmake-parameters: -DCMAKE_BUILD_TYPE=RelWithDebInfo -DOPTION_USE_ASSERTS=OFF
- name: GCC - SDL2
compiler: gcc
cxxcompiler: g++

View File

@ -87,7 +87,7 @@ struct BuildAirToolbarWindow : Window {
this->InitNested(window_number);
this->OnInvalidateData();
if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
this->last_user_action = WIDGET_LIST_END;
this->last_user_action = INVALID_WID_AT;
}
void Close() override

View File

@ -41,41 +41,33 @@ void SetupCargoForClimate(LandscapeID l)
{
assert(l < lengthof(_default_climate_cargo));
/* Reset and disable all cargo types */
for (CargoID i = 0; i < lengthof(CargoSpec::array); i++) {
*CargoSpec::Get(i) = {};
CargoSpec::Get(i)->bitnum = INVALID_CARGO;
/* Set defaults for newer properties, which old GRFs do not know */
CargoSpec::Get(i)->multiplier = 0x100;
}
_cargo_mask = 0;
for (CargoID i = 0; i < lengthof(_default_climate_cargo[l]); i++) {
CargoLabel cl = _default_climate_cargo[l][i];
/* Copy from default cargo by label or index. */
auto insert = std::begin(CargoSpec::array);
for (const CargoLabel &cl : _default_climate_cargo[l]) {
/* Bzzt: check if cl is just an index into the cargo table */
/* Check if value is an index into the cargo table */
if (cl < lengthof(_default_cargo)) {
/* Copy the indexed cargo */
CargoSpec *cargo = CargoSpec::Get(i);
*cargo = _default_cargo[cl];
if (cargo->bitnum != INVALID_CARGO) SetBit(_cargo_mask, i);
continue;
}
/* Loop through each of the default cargo types to see if
* the label matches */
for (uint j = 0; j < lengthof(_default_cargo); j++) {
if (_default_cargo[j].label == cl) {
*CargoSpec::Get(i) = _default_cargo[j];
/* Populate the available cargo mask */
SetBit(_cargo_mask, i);
break;
/* Copy the default cargo by index. */
*insert = _default_cargo[cl];
} else {
/* Search for label in default cargo types and copy if found. */
auto found = std::find_if(std::begin(_default_cargo), std::end(_default_cargo), [&cl](const CargoSpec &cs) { return cs.label == cl; });
if (found != std::end(_default_cargo)) {
*insert = *found;
} else {
/* Index or label is invalid, this should not happen. */
NOT_REACHED();
}
}
if (insert->IsValid()) SetBit(_cargo_mask, insert->Index());
++insert;
}
/* Reset and disable remaining cargo types. */
std::fill(insert, std::end(CargoSpec::array), CargoSpec{});
}
/**
@ -123,7 +115,7 @@ CargoID GetCargoIDByLabel(CargoLabel cl)
*/
CargoID GetCargoIDByBitnum(uint8_t bitnum)
{
if (bitnum == INVALID_CARGO) return CT_INVALID;
if (bitnum == INVALID_CARGO_BITNUM) return CT_INVALID;
for (const CargoSpec *cs : CargoSpec::Iterate()) {
if (cs->bitnum == bitnum) return cs->Index();

View File

@ -50,16 +50,17 @@ enum CargoClass {
CC_SPECIAL = 1 << 15, ///< Special bit used for livery refit tricks instead of normal cargoes.
};
static const byte INVALID_CARGO = 0xFF; ///< Constant representing invalid cargo
static const byte INVALID_CARGO_BITNUM = 0xFF; ///< Constant representing invalid cargo
/** Specification of a cargo type. */
struct CargoSpec {
uint8_t bitnum; ///< Cargo bit number, is #INVALID_CARGO for a non-used spec.
CargoLabel label; ///< Unique label of the cargo type.
uint8_t bitnum{INVALID_CARGO_BITNUM}; ///< Cargo bit number, is #INVALID_CARGO_BITNUM for a non-used spec.
uint8_t legend_colour;
uint8_t rating_colour;
uint8_t weight; ///< Weight of a single unit of this cargo type in 1/16 ton (62.5 kg).
uint16_t multiplier; ///< Capacity multiplier for vehicles. (8 fractional bits)
uint16_t multiplier{0x100}; ///< Capacity multiplier for vehicles. (8 fractional bits)
uint16_t classes; ///< Classes of this cargo type. @see CargoClass
int32_t initial_payment; ///< Initial payment rate before inflation is applied.
uint8_t transit_periods[2];
@ -75,7 +76,6 @@ struct CargoSpec {
SpriteID sprite; ///< Icon to display this cargo type, may be \c 0xFFF (which means to resolve an action123 chain).
uint16_t classes; ///< Classes of this cargo type. @see CargoClass
const struct GRFFile *grffile; ///< NewGRF where #group belongs to.
const struct SpriteGroup *group;
@ -97,7 +97,7 @@ struct CargoSpec {
*/
inline bool IsValid() const
{
return this->bitnum != INVALID_CARGO;
return this->bitnum != INVALID_CARGO_BITNUM;
}
/**

View File

@ -884,16 +884,10 @@ struct GenerateLandscapeWindow : public Window {
void OnTimeout() override
{
static const int newgame_raise_widgets[] = {WID_GL_START_DATE_DOWN, WID_GL_START_DATE_UP, WID_GL_SNOW_COVERAGE_UP, WID_GL_SNOW_COVERAGE_DOWN, WID_GL_DESERT_COVERAGE_UP, WID_GL_DESERT_COVERAGE_DOWN, WIDGET_LIST_END};
static const int heightmap_raise_widgets[] = {WID_GL_HEIGHTMAP_HEIGHT_DOWN, WID_GL_HEIGHTMAP_HEIGHT_UP, WID_GL_START_DATE_DOWN, WID_GL_START_DATE_UP, WID_GL_SNOW_COVERAGE_UP, WID_GL_SNOW_COVERAGE_DOWN, WID_GL_DESERT_COVERAGE_UP, WID_GL_DESERT_COVERAGE_DOWN, WIDGET_LIST_END};
const int *widget = (mode == GLWM_HEIGHTMAP) ? heightmap_raise_widgets : newgame_raise_widgets;
for (; *widget != WIDGET_LIST_END; widget++) {
if (this->IsWidgetLowered(*widget)) {
this->RaiseWidget(*widget);
this->SetWidgetDirty(*widget);
}
if (mode == GLWM_HEIGHTMAP) {
this->RaiseWidgetsWhenLowered(WID_GL_HEIGHTMAP_HEIGHT_DOWN, WID_GL_HEIGHTMAP_HEIGHT_UP, WID_GL_START_DATE_DOWN, WID_GL_START_DATE_UP, WID_GL_SNOW_COVERAGE_UP, WID_GL_SNOW_COVERAGE_DOWN, WID_GL_DESERT_COVERAGE_UP, WID_GL_DESERT_COVERAGE_DOWN);
} else {
this->RaiseWidgetsWhenLowered(WID_GL_START_DATE_DOWN, WID_GL_START_DATE_UP, WID_GL_SNOW_COVERAGE_UP, WID_GL_SNOW_COVERAGE_DOWN, WID_GL_DESERT_COVERAGE_UP, WID_GL_DESERT_COVERAGE_DOWN);
}
}
@ -1232,13 +1226,7 @@ struct CreateScenarioWindow : public Window
void OnTimeout() override
{
static const int raise_widgets[] = {WID_CS_START_DATE_DOWN, WID_CS_START_DATE_UP, WID_CS_FLAT_LAND_HEIGHT_DOWN, WID_CS_FLAT_LAND_HEIGHT_UP, WIDGET_LIST_END};
for (const int *widget = raise_widgets; *widget != WIDGET_LIST_END; widget++) {
if (this->IsWidgetLowered(*widget)) {
this->RaiseWidget(*widget);
this->SetWidgetDirty(*widget);
}
}
this->RaiseWidgetsWhenLowered(WID_CS_START_DATE_DOWN, WID_CS_START_DATE_UP, WID_CS_FLAT_LAND_HEIGHT_DOWN, WID_CS_FLAT_LAND_HEIGHT_UP);
}
void OnDropdownSelect(int widget, int index) override

View File

@ -1947,15 +1947,15 @@ struct CargoesField {
CargoID other_accepted[MAX_CARGOES]; ///< Cargoes accepted but not used in this figure.
} industry; ///< Industry data (for #CFT_INDUSTRY).
struct {
CargoID vertical_cargoes[MAX_CARGOES]; ///< Cargoes running from top to bottom (cargo ID or #INVALID_CARGO).
CargoID vertical_cargoes[MAX_CARGOES]; ///< Cargoes running from top to bottom (cargo ID or #CT_INVALID).
byte num_cargoes; ///< Number of cargoes.
CargoID supp_cargoes[MAX_CARGOES]; ///< Cargoes entering from the left (index in #vertical_cargoes, or #INVALID_CARGO).
CargoID supp_cargoes[MAX_CARGOES]; ///< Cargoes entering from the left (index in #vertical_cargoes, or #CT_INVALID).
byte top_end; ///< Stop at the top of the vertical cargoes.
CargoID cust_cargoes[MAX_CARGOES]; ///< Cargoes leaving to the right (index in #vertical_cargoes, or #INVALID_CARGO).
CargoID cust_cargoes[MAX_CARGOES]; ///< Cargoes leaving to the right (index in #vertical_cargoes, or #CT_INVALID).
byte bottom_end; ///< Stop at the bottom of the vertical cargoes.
} cargo; ///< Cargo data (for #CFT_CARGO).
struct {
CargoID cargoes[MAX_CARGOES]; ///< Cargoes to display (or #INVALID_CARGO).
CargoID cargoes[MAX_CARGOES]; ///< Cargoes to display (or #CT_INVALID).
bool left_align; ///< Align all cargo texts to the left (else align to the right).
} cargo_label; ///< Label data (for #CFT_CARGO_LABEL).
StringID header; ///< Header text (for #CFT_HEADER).
@ -1979,8 +1979,8 @@ struct CargoesField {
{
this->type = CFT_INDUSTRY;
this->u.industry.ind_type = ind_type;
MemSetT(this->u.industry.other_accepted, INVALID_CARGO, MAX_CARGOES);
MemSetT(this->u.industry.other_produced, INVALID_CARGO, MAX_CARGOES);
MemSetT(this->u.industry.other_accepted, CT_INVALID, MAX_CARGOES);
MemSetT(this->u.industry.other_produced, CT_INVALID, MAX_CARGOES);
}
/**
@ -2031,7 +2031,7 @@ struct CargoesField {
/**
* Make a piece of cargo column.
* @param cargoes Array of #CargoID (may contain #INVALID_CARGO).
* @param cargoes Array of #CargoID (may contain #CT_INVALID).
* @param length Number of cargoes in \a cargoes.
* @param count Number of cargoes to display (should be at least the number of valid cargoes, or \c -1 to let the method compute it).
* @param top_end This is the first cargo field of this column.
@ -2050,16 +2050,16 @@ struct CargoesField {
}
}
this->u.cargo.num_cargoes = (count < 0) ? num : count;
for (; num < MAX_CARGOES; num++) this->u.cargo.vertical_cargoes[num] = INVALID_CARGO;
for (; num < MAX_CARGOES; num++) this->u.cargo.vertical_cargoes[num] = CT_INVALID;
this->u.cargo.top_end = top_end;
this->u.cargo.bottom_end = bottom_end;
MemSetT(this->u.cargo.supp_cargoes, INVALID_CARGO, MAX_CARGOES);
MemSetT(this->u.cargo.cust_cargoes, INVALID_CARGO, MAX_CARGOES);
MemSetT(this->u.cargo.supp_cargoes, CT_INVALID, MAX_CARGOES);
MemSetT(this->u.cargo.cust_cargoes, CT_INVALID, MAX_CARGOES);
}
/**
* Make a field displaying cargo type names.
* @param cargoes Array of #CargoID (may contain #INVALID_CARGO).
* @param cargoes Array of #CargoID (may contain #CT_INVALID).
* @param length Number of cargoes in \a cargoes.
* @param left_align ALign texts to the left (else to the right).
*/
@ -2068,7 +2068,7 @@ struct CargoesField {
this->type = CFT_CARGO_LABEL;
uint i;
for (i = 0; i < MAX_CARGOES && i < length; i++) this->u.cargo_label.cargoes[i] = cargoes[i];
for (; i < MAX_CARGOES; i++) this->u.cargo_label.cargoes[i] = INVALID_CARGO;
for (; i < MAX_CARGOES; i++) this->u.cargo_label.cargoes[i] = CT_INVALID;
this->u.cargo_label.left_align = left_align;
}
@ -2244,7 +2244,7 @@ struct CargoesField {
* @param left Left industry neighbour if available (else \c nullptr should be supplied).
* @param right Right industry neighbour if available (else \c nullptr should be supplied).
* @param pt Click position in the cargo field.
* @return Cargo clicked at, or #INVALID_CARGO if none.
* @return Cargo clicked at, or #CT_INVALID if none.
*/
CargoID CargoClickedAt(const CargoesField *left, const CargoesField *right, Point pt) const
{
@ -2263,11 +2263,11 @@ struct CargoesField {
int vpos = vert_inter_industry_space / 2 + CargoesField::cargo_border.width;
uint row;
for (row = 0; row < MAX_CARGOES; row++) {
if (pt.y < vpos) return INVALID_CARGO;
if (pt.y < vpos) return CT_INVALID;
if (pt.y < vpos + FONT_HEIGHT_NORMAL) break;
vpos += FONT_HEIGHT_NORMAL + CargoesField::cargo_space.width;
}
if (row == MAX_CARGOES) return INVALID_CARGO;
if (row == MAX_CARGOES) return CT_INVALID;
/* row = 0 -> at first horizontal row, row = 1 -> second horizontal row, 2 = 3rd horizontal row. */
if (col == 0) {
@ -2276,7 +2276,7 @@ struct CargoesField {
if (left->type == CFT_INDUSTRY) return left->u.industry.other_produced[row];
if (left->type == CFT_CARGO_LABEL && !left->u.cargo_label.left_align) return left->u.cargo_label.cargoes[row];
}
return INVALID_CARGO;
return CT_INVALID;
}
if (col == this->u.cargo.num_cargoes) {
if (IsValidCargoID(this->u.cargo.cust_cargoes[row])) return this->u.cargo.vertical_cargoes[this->u.cargo.cust_cargoes[row]];
@ -2284,24 +2284,25 @@ struct CargoesField {
if (right->type == CFT_INDUSTRY) return right->u.industry.other_accepted[row];
if (right->type == CFT_CARGO_LABEL && right->u.cargo_label.left_align) return right->u.cargo_label.cargoes[row];
}
return INVALID_CARGO;
return CT_INVALID;
}
if (row >= col) {
/* Clicked somewhere in-between vertical cargo connection.
* Since the horizontal connection is made in the same order as the vertical list, the above condition
* ensures we are left-below the main diagonal, thus at the supplying side.
*/
return (IsValidCargoID(this->u.cargo.supp_cargoes[row])) ? this->u.cargo.vertical_cargoes[this->u.cargo.supp_cargoes[row]] : INVALID_CARGO;
} else {
/* Clicked at a customer connection. */
return (IsValidCargoID(this->u.cargo.cust_cargoes[row])) ? this->u.cargo.vertical_cargoes[this->u.cargo.cust_cargoes[row]] : INVALID_CARGO;
if (IsValidCargoID(this->u.cargo.supp_cargoes[row])) return this->u.cargo.vertical_cargoes[this->u.cargo.supp_cargoes[row]];
return CT_INVALID;
}
/* Clicked at a customer connection. */
if (IsValidCargoID(this->u.cargo.cust_cargoes[row])) return this->u.cargo.vertical_cargoes[this->u.cargo.cust_cargoes[row]];
return CT_INVALID;
}
/**
* Decide what cargo the user clicked in the cargo label field.
* @param pt Click position in the cargo label field.
* @return Cargo clicked at, or #INVALID_CARGO if none.
* @return Cargo clicked at, or #CT_INVALID if none.
*/
CargoID CargoLabelClickedAt(Point pt) const
{
@ -2310,11 +2311,11 @@ struct CargoesField {
int vpos = vert_inter_industry_space / 2 + CargoesField::cargo_border.height;
uint row;
for (row = 0; row < MAX_CARGOES; row++) {
if (pt.y < vpos) return INVALID_CARGO;
if (pt.y < vpos) return CT_INVALID;
if (pt.y < vpos + FONT_HEIGHT_NORMAL) break;
vpos += FONT_HEIGHT_NORMAL + CargoesField::cargo_space.height;
}
if (row == MAX_CARGOES) return INVALID_CARGO;
if (row == MAX_CARGOES) return CT_INVALID;
return this->u.cargo_label.cargoes[row];
}
@ -2369,7 +2370,7 @@ struct CargoesRow {
CargoesField *cargo_fld = this->columns + column + 1;
assert(ind_fld->type == CFT_INDUSTRY && cargo_fld->type == CFT_CARGO);
MemSetT(ind_fld->u.industry.other_produced, INVALID_CARGO, MAX_CARGOES);
MemSetT(ind_fld->u.industry.other_produced, CT_INVALID, MAX_CARGOES);
if (ind_fld->u.industry.ind_type < NUM_INDUSTRYTYPES) {
CargoID others[MAX_CARGOES]; // Produced cargoes not carried in the cargo column.
@ -2403,7 +2404,7 @@ struct CargoesRow {
void MakeCargoLabel(int column, bool accepting)
{
CargoID cargoes[MAX_CARGOES];
MemSetT(cargoes, INVALID_CARGO, lengthof(cargoes));
MemSetT(cargoes, CT_INVALID, lengthof(cargoes));
CargoesField *label_fld = this->columns + column;
CargoesField *cargo_fld = this->columns + (accepting ? column - 1 : column + 1);
@ -2427,7 +2428,7 @@ struct CargoesRow {
CargoesField *cargo_fld = this->columns + column - 1;
assert(ind_fld->type == CFT_INDUSTRY && cargo_fld->type == CFT_CARGO);
MemSetT(ind_fld->u.industry.other_accepted, INVALID_CARGO, MAX_CARGOES);
MemSetT(ind_fld->u.industry.other_accepted, CT_INVALID, MAX_CARGOES);
if (ind_fld->u.industry.ind_type < NUM_INDUSTRYTYPES) {
CargoID others[MAX_CARGOES]; // Accepted cargoes not carried in the cargo column.
@ -2922,10 +2923,7 @@ struct IndustryCargoesWindow : public Window {
{
if (!gui_scope) return;
if (data == NUM_INDUSTRYTYPES) {
if (this->IsWidgetLowered(WID_IC_NOTIFY)) {
this->RaiseWidget(WID_IC_NOTIFY);
this->SetWidgetDirty(WID_IC_NOTIFY);
}
this->RaiseWidgetWhenLowered(WID_IC_NOTIFY);
return;
}
@ -3113,7 +3111,7 @@ struct IndustryCargoesWindow : public Window {
if (!CalculatePositionInWidget(pt, &fieldxy, &xy)) return false;
const CargoesField *fld = this->fields[fieldxy.y].columns + fieldxy.x;
CargoID cid = INVALID_CARGO;
CargoID cid = CT_INVALID;
switch (fld->type) {
case CFT_CARGO: {
CargoesField *lft = (fieldxy.x > 0) ? this->fields[fieldxy.y].columns + fieldxy.x - 1 : nullptr;

View File

@ -189,7 +189,7 @@ public:
}
/** Bare constructor, only for save/load. */
LinkGraph() : cargo(INVALID_CARGO), last_compression(0) {}
LinkGraph() : cargo(CT_INVALID), last_compression(0) {}
/**
* Real constructor.
* @param cargo Cargo the link graph is about.

View File

@ -1180,13 +1180,7 @@ struct NetworkStartServerWindow : public Window {
void OnTimeout() override
{
static const int raise_widgets[] = {WID_NSS_CLIENTS_BTND, WID_NSS_CLIENTS_BTNU, WID_NSS_COMPANIES_BTND, WID_NSS_COMPANIES_BTNU, WIDGET_LIST_END};
for (const int *widget = raise_widgets; *widget != WIDGET_LIST_END; widget++) {
if (this->IsWidgetLowered(*widget)) {
this->RaiseWidget(*widget);
this->SetWidgetDirty(*widget);
}
}
this->RaiseWidgetsWhenLowered(WID_NSS_CLIENTS_BTND, WID_NSS_CLIENTS_BTNU, WID_NSS_COMPANIES_BTND, WID_NSS_COMPANIES_BTNU);
}
void OnQueryTextFinished(char *str) override

View File

@ -414,7 +414,7 @@ struct BuildRailToolbarWindow : Window {
this->InitNested(TRANSPORT_RAIL);
this->SetupRailToolbar(railtype);
this->DisableWidget(WID_RAT_REMOVE);
this->last_user_action = WIDGET_LIST_END;
this->last_user_action = INVALID_WID_RAT;
if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
}

View File

@ -324,7 +324,7 @@ struct BuildRoadToolbarWindow : Window {
}
this->OnInvalidateData();
this->last_started_action = WIDGET_LIST_END;
this->last_started_action = INVALID_WID_ROT;
if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
}

View File

@ -27,7 +27,7 @@
* And the following sprite:
* - SPR_CARGO_<str_plural>
*
* @param bt Cargo bit number, is #INVALID_CARGO for a non-used spec.
* @param bt Cargo bit number, is #INVALID_CARGO_BITNUM for a non-used spec.
* @param label Unique label of the cargo type.
* @param colour CargoSpec->legend_colour and CargoSpec->rating_colour.
* @param weight Weight of a single unit of this cargo type in 1/16 ton (62.5 kg).
@ -44,9 +44,9 @@
* @param classes Classes of this cargo type. @see CargoClass
*/
#define MK(bt, label, colour, weight, mult, ip, td1, td2, freight, te, str_plural, str_singular, str_volume, classes) \
{bt, label, colour, colour, weight, mult, ip, {td1, td2}, freight, te, 0, \
{label, bt, colour, colour, weight, mult, classes, ip, {td1, td2}, freight, te, 0, \
MK_STR_CARGO_PLURAL(str_plural), MK_STR_CARGO_SINGULAR(str_singular), str_volume, MK_STR_QUANTITY(str_plural), MK_STR_ABBREV(str_plural), \
MK_SPRITE(str_plural), classes, nullptr, nullptr, 0}
MK_SPRITE(str_plural), nullptr, nullptr, 0}
/** Cargo types available by default. */
static const CargoSpec _default_cargo[] = {

View File

@ -161,7 +161,7 @@ struct TerraformToolbarWindow : Window {
/* This is needed as we like to have the tree available on OnInit. */
this->CreateNestedTree();
this->FinishInitNested(window_number);
this->last_user_action = WIDGET_LIST_END;
this->last_user_action = INVALID_WID_TT;
}
~TerraformToolbarWindow()
@ -542,7 +542,7 @@ struct ScenarioEditorLandscapeGenerationWindow : Window {
NWidgetStacked *show_desert = this->GetWidget<NWidgetStacked>(WID_ETT_SHOW_PLACE_DESERT);
show_desert->SetDisplayedPlane(_settings_game.game_creation.landscape == LT_TROPIC ? 0 : SZSP_NONE);
this->FinishInitNested(window_number);
this->last_user_action = WIDGET_LIST_END;
this->last_user_action = INVALID_WID_ETT;
}
void OnPaint() override
@ -649,10 +649,7 @@ struct ScenarioEditorLandscapeGenerationWindow : Window {
{
for (uint i = WID_ETT_START; i < this->nested_array_size; i++) {
if (i == WID_ETT_BUTTONS_START) i = WID_ETT_BUTTONS_END; // skip the buttons
if (this->IsWidgetLowered(i)) {
this->RaiseWidget(i);
this->SetWidgetDirty(i);
}
this->RaiseWidgetWhenLowered(i);
}
}

View File

@ -2128,10 +2128,7 @@ struct MainToolbarWindow : Window {
/* We do not want to automatically raise the pause, fast forward and
* switchbar buttons; they have to stay down when pressed etc. */
for (uint i = WID_TN_SETTINGS; i < WID_TN_SWITCH_BAR; i++) {
if (this->IsWidgetLowered(i)) {
this->RaiseWidget(i);
this->SetWidgetDirty(i);
}
this->RaiseWidgetWhenLowered(i);
}
}

View File

@ -1421,16 +1421,18 @@ CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, bool sell_chain, b
/* First normalise the sub types of the chain. */
NormaliseSubtypes(new_head);
if (v == first && v->IsEngine() && !sell_chain && new_head != nullptr && new_head->IsFrontEngine()) {
/* We are selling the front engine. In this case we want to
* 'give' the order, unit number and such to the new head. */
new_head->orders = first->orders;
new_head->AddToShared(first);
DeleteVehicleOrders(first);
if (v == first && !sell_chain && new_head != nullptr && new_head->IsFrontEngine()) {
if (v->IsEngine()) {
/* We are selling the front engine. In this case we want to
* 'give' the order, unit number and such to the new head. */
new_head->orders = first->orders;
new_head->AddToShared(first);
DeleteVehicleOrders(first);
/* Copy other important data from the front engine */
new_head->CopyVehicleConfigAndStatistics(first);
GroupStatistics::CountVehicle(new_head, 1); // after copying over the profit
/* Copy other important data from the front engine */
new_head->CopyVehicleConfigAndStatistics(first);
}
GroupStatistics::CountVehicle(new_head, 1); // after copying over the profit, if required
} else if (v->IsPrimaryVehicle() && backup_order) {
OrderBackup::Backup(v, user);
}

View File

@ -274,7 +274,7 @@ static void GetCargoSummaryOfArticulatedVehicle(const Train *v, CargoSummary &su
if (!v->GetEngine()->CanCarryCargo()) continue;
CargoSummaryItem new_item;
new_item.cargo = v->cargo_cap > 0 ? v->cargo_type : INVALID_CARGO;
new_item.cargo = v->cargo_cap > 0 ? v->cargo_type : (CargoID)CT_INVALID;
new_item.subtype = GetCargoSubtypeText(v);
if (!IsValidCargoID(new_item.cargo) && new_item.subtype == STR_EMPTY) continue;

View File

@ -2616,8 +2616,7 @@ struct VehicleDetailsWindow : Window {
/* Disable service-scroller when interval is set to disabled */
this->SetWidgetsDisabledState(!IsVehicleServiceIntervalEnabled(v->type, v->owner),
WID_VD_INCREASE_SERVICING_INTERVAL,
WID_VD_DECREASE_SERVICING_INTERVAL,
WIDGET_LIST_END);
WID_VD_DECREASE_SERVICING_INTERVAL);
StringID str = v->ServiceIntervalIsCustom() ?
(v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_PERCENT : STR_VEHICLE_DETAILS_DAYS) :
@ -2657,9 +2656,7 @@ struct VehicleDetailsWindow : Window {
WID_VD_DETAILS_CARGO_CARRIED,
WID_VD_DETAILS_TRAIN_VEHICLES,
WID_VD_DETAILS_CAPACITY_OF_EACH,
WID_VD_DETAILS_TOTAL_CARGO,
widget,
WIDGET_LIST_END);
WID_VD_DETAILS_TOTAL_CARGO);
this->tab = (TrainDetailsWindowTabs)(widget - WID_VD_DETAILS_CARGO_CARRIED);
this->SetDirty();

View File

@ -17,8 +17,6 @@
#include "gfx_type.h"
#include "window_type.h"
static const int WIDGET_LIST_END = -1; ///< indicate the end of widgets' list for vararg functions
/** Bits of the #WWT_MATRIX widget data. */
enum MatrixWidgetValues {
/* Number of column bits of the WWT_MATRIX widget data. */

View File

@ -14,6 +14,8 @@
enum AirportToolbarWidgets {
WID_AT_AIRPORT, ///< Build airport button.
WID_AT_DEMOLISH, ///< Demolish button.
INVALID_WID_AT = -1,
};
/** Widgets of the #BuildAirportWindow class. */

View File

@ -28,6 +28,8 @@ enum RailToolbarWidgets {
WID_RAT_BUILD_TUNNEL, ///< Build a tunnel.
WID_RAT_REMOVE, ///< Bulldozer to remove rail.
WID_RAT_CONVERT_RAIL, ///< Convert other rail to this type.
INVALID_WID_RAT = -1,
};
/** Widgets of the #BuildRailStationWindow class. */

View File

@ -26,6 +26,8 @@ enum RoadToolbarWidgets {
WID_ROT_BUILD_TUNNEL, ///< Build tunnel.
WID_ROT_REMOVE, ///< Remove road.
WID_ROT_CONVERT_ROAD, ///< Convert road.
INVALID_WID_ROT = -1,
};
/** Widgets of the #BuildRoadDepotWindow class. */

View File

@ -22,6 +22,8 @@ enum TerraformToolbarWidgets {
WID_TT_PLANT_TREES, ///< Plant trees button (note: opens separate window, no place-push-button).
WID_TT_PLACE_SIGN, ///< Place sign button.
WID_TT_PLACE_OBJECT, ///< Place object button.
INVALID_WID_TT = -1,
};
/** Widgets of the #ScenarioEditorLandscapeGenerationWindow class. */
@ -42,6 +44,8 @@ enum EditorTerraformToolbarWidgets {
WID_ETT_DECREASE_SIZE, ///< Downwards arrow button to decrease terraforming size.
WID_ETT_NEW_SCENARIO, ///< Button for generating a new scenario.
WID_ETT_RESET_LANDSCAPE, ///< Button for removing all company-owned property.
INVALID_WID_ETT = -1,
};
#endif /* WIDGETS_TERRAFORM_WIDGET_H */

View File

@ -413,6 +413,18 @@ public:
SetWidgetLoweredState(widget_index, false);
}
/**
* Marks a widget as raised and dirty (redraw), when it is marked as lowered.
* @param widget_index index of this widget in the window
*/
inline void RaiseWidgetWhenLowered(byte widget_index)
{
if (this->IsWidgetLowered(widget_index)) {
this->RaiseWidget(widget_index);
this->SetWidgetDirty(widget_index);
}
}
/**
* Gets the lowered state of a widget.
* @param widget_index index of this widget in the window
@ -458,6 +470,16 @@ public:
{
(SetWidgetLoweredState(widgets, lowered_stat), ...);
}
/**
* Raises the widgets and sets widgets dirty that are lowered.
* @param widgets list of widgets
*/
template<typename... Args>
void RaiseWidgetsWhenLowered(Args... widgets) {
(this->RaiseWidgetWhenLowered(widgets), ...);
}
void SetWidgetDirty(byte widget_index) const;
void DrawWidgets() const;