Merge commit '73bed054b87399484e39f6972d30f91a404daba8'

This commit is contained in:
2024-04-03 19:37:54 +01:00
1355 changed files with 153174 additions and 81531 deletions

View File

@@ -34,7 +34,7 @@
#include "safeguards.h"
void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group);
void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, uint16_t min, uint16_t max, EngineID selected_id, bool show_count, GroupID selected_group);
static bool EngineNumberSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
@@ -149,7 +149,7 @@ class ReplaceVehicleWindow : public Window {
GUIEngineList list;
for (const Engine *e : Engine::IterateType(type)) {
if (!draw_left && !this->show_hidden_engines && e->IsHidden(_local_company)) continue;
if (!draw_left && !this->show_hidden_engines && e->IsVariantHidden(_local_company)) continue;
EngineID eid = e->index;
switch (type) {
case VEH_TRAIN:
@@ -176,11 +176,15 @@ class ReplaceVehicleWindow : public Window {
if (!CheckAutoreplaceValidity(this->sel_engine[0], eid, _local_company)) continue;
}
EngineDisplayFlags flags = (side == 0) ? EngineDisplayFlags::None : e->display_flags;
if (side == 1 && eid == this->sel_engine[0]) flags |= EngineDisplayFlags::Shaded;
list.emplace_back(eid, e->info.variant_id, flags, 0);
list.emplace_back(eid, e->info.variant_id, (side == 0) ? EngineDisplayFlags::None : e->display_flags, 0);
if (side == 1 && e->info.variant_id != INVALID_ENGINE) variants.push_back(e->info.variant_id);
if (side == 1) {
EngineID parent = e->info.variant_id;
while (parent != INVALID_ENGINE) {
variants.push_back(parent);
parent = Engine::Get(parent)->info.variant_id;
}
}
if (eid == this->sel_engine[side]) selected_engine = eid; // The selected engine is still in the list
}
@@ -196,10 +200,10 @@ class ReplaceVehicleWindow : public Window {
this->sel_engine[side] = selected_engine; // update which engine we selected (the same or none, if it's not in the list anymore)
if (draw_left) {
EngList_Sort(&list, &EngineNumberSorter);
EngList_Sort(list, &EngineNumberSorter);
} else {
_engine_sort_direction = this->descending_sort_order;
EngList_Sort(&list, _engine_sort_functions[this->window_number][this->sort_criteria]);
EngList_Sort(list, _engine_sort_functions[this->window_number][this->sort_criteria]);
}
this->engines[side].clear();
@@ -218,8 +222,8 @@ class ReplaceVehicleWindow : public Window {
if (this->engines[0].NeedRebuild()) {
/* We need to rebuild the left engines list */
this->GenerateReplaceVehList(true);
this->vscroll[0]->SetCount((uint)this->engines[0].size());
if (this->reset_sel_engine && this->sel_engine[0] == INVALID_ENGINE && this->engines[0].size() != 0) {
this->vscroll[0]->SetCount(this->engines[0].size());
if (this->reset_sel_engine && this->sel_engine[0] == INVALID_ENGINE && !this->engines[0].empty()) {
this->sel_engine[0] = this->engines[0][0].engine_id;
}
}
@@ -230,6 +234,7 @@ class ReplaceVehicleWindow : public Window {
/* Always empty the right engines list when nothing is selected in the left engines list */
this->engines[1].clear();
this->sel_engine[1] = INVALID_ENGINE;
this->vscroll[1]->SetCount(this->engines[1].size());
} else {
if (this->reset_sel_engine && this->sel_engine[0] != INVALID_ENGINE) {
/* Select the current replacement for sel_engine[0]. */
@@ -238,7 +243,7 @@ class ReplaceVehicleWindow : public Window {
}
/* Regenerate the list on the right. Note: This resets sel_engine[1] to INVALID_ENGINE, if it is no longer available. */
this->GenerateReplaceVehList(false);
this->vscroll[1]->SetCount((uint)this->engines[1].size());
this->vscroll[1]->SetCount(this->engines[1].size());
if (this->reset_sel_engine && this->sel_engine[1] != INVALID_ENGINE) {
int position = 0;
for (const auto &item : this->engines[1]) {
@@ -266,6 +271,21 @@ class ReplaceVehicleWindow : public Window {
Command<CMD_SET_AUTOREPLACE>::Post(this->sel_group, veh_from, veh_to, replace_when_old);
}
/**
* Perform tasks after rail or road type is changed.
*/
void OnRailRoadTypeChange()
{
/* Reset scrollbar positions */
this->vscroll[0]->SetPosition(0);
this->vscroll[1]->SetPosition(0);
/* Rebuild the lists */
this->engines[0].ForceRebuild();
this->engines[1].ForceRebuild();
this->reset_sel_engine = true;
this->SetDirty();
}
public:
ReplaceVehicleWindow(WindowDesc *desc, VehicleType vehicletype, GroupID id_g) : Window(desc)
{
@@ -290,18 +310,13 @@ public:
widget->SetLowered(this->show_hidden_engines);
this->FinishInitNested(vehicletype);
if (vehicletype == VEH_TRAIN || vehicletype == VEH_ROAD) {
widget = this->GetWidget<NWidgetCore>(WID_RV_RAIL_ROAD_TYPE_DROPDOWN);
widget->tool_tip = STR_REPLACE_HELP_RAILTYPE + vehicletype;
}
this->sort_criteria = _engine_sort_last_criteria[vehicletype];
this->descending_sort_order = _engine_sort_last_order[vehicletype];
this->owner = _local_company;
this->sel_group = id_g;
}
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
{
switch (widget) {
case WID_RV_SORT_ASCENDING_DESCENDING: {
@@ -320,7 +335,7 @@ public:
case WID_RV_LEFT_DETAILS:
case WID_RV_RIGHT_DETAILS:
size->height = FONT_HEIGHT_NORMAL * this->details_height + padding.height;
size->height = GetCharacterHeight(FS_NORMAL) * this->details_height + padding.height;
break;
case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: {
@@ -353,28 +368,21 @@ public:
break;
}
case WID_RV_RAIL_ROAD_TYPE_DROPDOWN: {
case WID_RV_RAIL_TYPE_DROPDOWN: {
Dimension d = {0, 0};
switch (this->window_number) {
case VEH_TRAIN:
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
const RailtypeInfo *rti = GetRailTypeInfo(rt);
/* Skip rail type if it has no label */
if (rti->label == 0) continue;
d = maxdim(d, GetStringBoundingBox(rti->strings.replace_text));
}
break;
for (const RailType &rt : _sorted_railtypes) {
d = maxdim(d, GetStringBoundingBox(GetRailTypeInfo(rt)->strings.replace_text));
}
d.width += padding.width;
d.height += padding.height;
*size = maxdim(*size, d);
break;
}
case VEH_ROAD:
for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) {
const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
/* Skip road type if it has no label */
if (rti->label == 0) continue;
d = maxdim(d, GetStringBoundingBox(rti->strings.replace_text));
}
break;
default: NOT_REACHED();
case WID_RV_ROAD_TYPE_DROPDOWN: {
Dimension d = {0, 0};
for (const RoadType &rt : _sorted_roadtypes) {
d = maxdim(d, GetStringBoundingBox(GetRoadTypeInfo(rt)->strings.replace_text));
}
d.width += padding.width;
d.width += SETTING_BUTTON_HEIGHT;
@@ -397,7 +405,7 @@ public:
}
}
void SetStringParameters(int widget) const override
void SetStringParameters(WidgetID widget) const override
{
switch (widget) {
case WID_RV_CAPTION:
@@ -441,10 +449,18 @@ public:
case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN:
SetDParam(0, this->replace_engines ? STR_REPLACE_ENGINES : STR_REPLACE_WAGONS);
break;
case WID_RV_RAIL_TYPE_DROPDOWN:
SetDParam(0, this->sel_railtype == INVALID_RAILTYPE ? STR_REPLACE_ALL_RAILTYPE : GetRailTypeInfo(this->sel_railtype)->strings.replace_text);
break;
case WID_RV_ROAD_TYPE_DROPDOWN:
SetDParam(0, this->sel_roadtype == INVALID_ROADTYPE ? STR_REPLACE_ALL_ROADTYPE : GetRoadTypeInfo(this->sel_roadtype)->strings.replace_text);
break;
}
}
void DrawWidget(const Rect &r, int widget) const override
void DrawWidget(const Rect &r, WidgetID widget) const override
{
switch (widget) {
case WID_RV_SORT_ASCENDING_DESCENDING:
@@ -461,7 +477,7 @@ public:
bool when_old = false;
EngineID e = EngineReplacementForCompany(c, this->sel_engine[0], this->sel_group, &when_old);
str = when_old ? STR_REPLACE_REPLACING_WHEN_OLD : STR_ENGINE_NAME;
SetDParam(0, e);
SetDParam(0, PackEngineNameDParam(e, EngineNameContext::PurchaseList));
}
} else {
str = STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED;
@@ -501,20 +517,6 @@ public:
* or The selected vehicle has no replacement set up */
this->SetWidgetDisabledState(WID_RV_STOP_REPLACE, this->sel_engine[0] == INVALID_ENGINE || !EngineHasReplacementForCompany(c, this->sel_engine[0], this->sel_group));
switch (this->window_number) {
case VEH_TRAIN:
/* Show the selected railtype in the pulldown menu */
this->GetWidget<NWidgetCore>(WID_RV_RAIL_ROAD_TYPE_DROPDOWN)->widget_data = sel_railtype == INVALID_RAILTYPE ? STR_REPLACE_ALL_RAILTYPE : GetRailTypeInfo(sel_railtype)->strings.replace_text;
break;
case VEH_ROAD:
/* Show the selected roadtype in the pulldown menu */
this->GetWidget<NWidgetCore>(WID_RV_RAIL_ROAD_TYPE_DROPDOWN)->widget_data = sel_roadtype == INVALID_ROADTYPE ? STR_REPLACE_ALL_ROADTYPE : GetRoadTypeInfo(sel_roadtype)->strings.replace_text;
break;
default: break;
}
this->DrawWidgets();
if (!this->IsShaded()) {
@@ -531,7 +533,7 @@ public:
const Rect r = this->GetWidget<NWidgetBase>(side == 0 ? WID_RV_LEFT_DETAILS : WID_RV_RIGHT_DETAILS)->GetCurrentRect()
.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect);
int text_end = DrawVehiclePurchaseInfo(r.left, r.right, r.top, this->sel_engine[side], ted);
needed_height = std::max(needed_height, (text_end - r.top) / FONT_HEIGHT_NORMAL);
needed_height = std::max(needed_height, (text_end - r.top) / GetCharacterHeight(FS_NORMAL));
}
}
if (needed_height != this->details_height) { // Details window are not high enough, enlarge them.
@@ -542,7 +544,7 @@ public:
}
}
void OnClick(Point pt, int widget, int click_count) override
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
{
switch (widget) {
case WID_RV_SORT_ASCENDING_DESCENDING:
@@ -566,22 +568,18 @@ public:
case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN: {
DropDownList list;
list.emplace_back(new DropDownListStringItem(STR_REPLACE_ENGINES, 1, false));
list.emplace_back(new DropDownListStringItem(STR_REPLACE_WAGONS, 0, false));
list.push_back(std::make_unique<DropDownListStringItem>(STR_REPLACE_ENGINES, 1, false));
list.push_back(std::make_unique<DropDownListStringItem>(STR_REPLACE_WAGONS, 0, false));
ShowDropDownList(this, std::move(list), this->replace_engines ? 1 : 0, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN);
break;
}
case WID_RV_RAIL_ROAD_TYPE_DROPDOWN: // Rail/roadtype selection dropdown menu
switch (this->window_number) {
case VEH_TRAIN:
ShowDropDownList(this, GetRailTypeDropDownList(true, true), sel_railtype, WID_RV_RAIL_ROAD_TYPE_DROPDOWN);
break;
case WID_RV_RAIL_TYPE_DROPDOWN: // Railtype selection dropdown menu
ShowDropDownList(this, GetRailTypeDropDownList(true, true), this->sel_railtype, widget);
break;
case VEH_ROAD:
ShowDropDownList(this, GetRoadTypeDropDownList(RTTB_ROAD | RTTB_TRAM, true, true), sel_roadtype, WID_RV_RAIL_ROAD_TYPE_DROPDOWN);
break;
}
case WID_RV_ROAD_TYPE_DROPDOWN: // Roadtype selection dropdown menu
ShowDropDownList(this, GetRoadTypeDropDownList(RTTB_ROAD | RTTB_TRAM, true, true), this->sel_roadtype, widget);
break;
case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: {
@@ -620,12 +618,11 @@ public:
} else {
click_side = 1;
}
uint i = this->vscroll[click_side]->GetScrolledRowFromWidget(pt.y, this, widget);
size_t engine_count = this->engines[click_side].size();
EngineID e = INVALID_ENGINE;
if (i < engine_count) {
const auto &item = this->engines[click_side][i];
const auto it = this->vscroll[click_side]->GetScrolledItemFromWidget(this->engines[click_side], pt.y, this, widget);
if (it != this->engines[click_side].end()) {
const auto &item = *it;
const Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.matrix).WithWidth(WidgetDimensions::scaled.hsep_indent * (item.indent + 1), _current_text_dir == TD_RTL);
if ((item.flags & EngineDisplayFlags::HasVariants) != EngineDisplayFlags::None && IsInsideMM(r.left, r.right, pt.x)) {
/* toggle folded flag on engine */
@@ -661,7 +658,7 @@ public:
}
}
void OnDropdownSelect(int widget, int index) override
void OnDropdownSelect(WidgetID widget, int index) override
{
switch (widget) {
case WID_RV_SORT_DROPDOWN:
@@ -673,34 +670,21 @@ public:
}
break;
case WID_RV_RAIL_ROAD_TYPE_DROPDOWN:
switch (this->window_number) {
case VEH_TRAIN: {
RailType temp = (RailType)index;
if (temp == sel_railtype) return; // we didn't select a new one. No need to change anything
sel_railtype = temp;
break;
}
case VEH_ROAD: {
RoadType temp = (RoadType)index;
if (temp == sel_roadtype) return; // we didn't select a new one. No need to change anything
sel_roadtype = temp;
break;
}
default: NOT_REACHED();
}
/* Reset scrollbar positions */
this->vscroll[0]->SetPosition(0);
this->vscroll[1]->SetPosition(0);
/* Rebuild the lists */
this->engines[0].ForceRebuild();
this->engines[1].ForceRebuild();
this->reset_sel_engine = true;
this->SetDirty();
case WID_RV_RAIL_TYPE_DROPDOWN: {
RailType temp = (RailType)index;
if (temp == this->sel_railtype) return; // we didn't select a new one. No need to change anything
this->sel_railtype = temp;
this->OnRailRoadTypeChange();
break;
}
case WID_RV_ROAD_TYPE_DROPDOWN: {
RoadType temp = (RoadType)index;
if (temp == this->sel_roadtype) return; // we didn't select a new one. No need to change anything
this->sel_roadtype = temp;
this->OnRailRoadTypeChange();
break;
}
case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN: {
this->replace_engines = index != 0;
@@ -716,16 +700,15 @@ public:
}
}
bool OnTooltip(Point pt, int widget, TooltipCloseCondition close_cond) override
bool OnTooltip([[maybe_unused]] Point pt, WidgetID widget, TooltipCloseCondition close_cond) override
{
if (widget != WID_RV_TRAIN_WAGONREMOVE_TOGGLE) return false;
if (Group::IsValidID(this->sel_group)) {
uint64 params[1];
params[0] = STR_REPLACE_REMOVE_WAGON_HELP;
GuiShowTooltips(this, STR_REPLACE_REMOVE_WAGON_GROUP_HELP, 1, params, close_cond);
SetDParam(0, STR_REPLACE_REMOVE_WAGON_HELP);
GuiShowTooltips(this, STR_REPLACE_REMOVE_WAGON_GROUP_HELP, close_cond, 1);
} else {
GuiShowTooltips(this, STR_REPLACE_REMOVE_WAGON_HELP, 0, nullptr, close_cond);
GuiShowTooltips(this, STR_REPLACE_REMOVE_WAGON_HELP, close_cond);
}
return true;
}
@@ -741,7 +724,7 @@ public:
* @param data Information about the changed data.
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
*/
void OnInvalidateData(int data = 0, bool gui_scope = true) override
void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
{
if (data != 0) {
/* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */
@@ -752,7 +735,7 @@ public:
}
};
static const NWidgetPart _nested_replace_rail_vehicle_widgets[] = {
static constexpr NWidgetPart _nested_replace_rail_vehicle_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_RV_CAPTION), SetDataTip(STR_REPLACE_VEHICLES_WHITE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
@@ -771,8 +754,8 @@ static const NWidgetPart _nested_replace_rail_vehicle_widgets[] = {
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_RAIL_ROAD_TYPE_DROPDOWN), SetMinimalSize(136, 12), SetDataTip(0x0, STR_REPLACE_HELP_RAILTYPE), SetFill(1, 0), SetResize(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_REPLACE_ENGINE_WAGON_SELECT_HELP),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_RAIL_TYPE_DROPDOWN), SetMinimalSize(136, 12), SetDataTip(STR_JUST_STRING, STR_REPLACE_HELP_RAILTYPE), SetFill(1, 0), SetResize(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN), SetDataTip(STR_JUST_STRING, STR_REPLACE_ENGINE_WAGON_SELECT_HELP),
EndContainer(),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_TRAIN_WAGONREMOVE_TOGGLE), SetMinimalSize(138, 12), SetDataTip(STR_REPLACE_REMOVE_WAGON, STR_REPLACE_REMOVE_WAGON_HELP), SetFill(1, 0), SetResize(1, 0),
NWidget(NWID_HORIZONTAL),
@@ -805,14 +788,14 @@ static const NWidgetPart _nested_replace_rail_vehicle_widgets[] = {
EndContainer(),
};
static WindowDesc _replace_rail_vehicle_desc(
static WindowDesc _replace_rail_vehicle_desc(__FILE__, __LINE__,
WDP_AUTO, "replace_vehicle_train", 500, 140,
WC_REPLACE_VEHICLE, WC_NONE,
WDF_CONSTRUCTION,
_nested_replace_rail_vehicle_widgets, lengthof(_nested_replace_rail_vehicle_widgets)
std::begin(_nested_replace_rail_vehicle_widgets), std::end(_nested_replace_rail_vehicle_widgets)
);
static const NWidgetPart _nested_replace_road_vehicle_widgets[] = {
static constexpr NWidgetPart _nested_replace_road_vehicle_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_RV_CAPTION), SetDataTip(STR_REPLACE_VEHICLES_WHITE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
@@ -830,7 +813,7 @@ static const NWidgetPart _nested_replace_road_vehicle_widgets[] = {
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_VERTICAL),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_RAIL_ROAD_TYPE_DROPDOWN), SetMinimalSize(136, 12), SetDataTip(0x0, STR_REPLACE_HELP_RAILTYPE), SetFill(1, 0), SetResize(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_ROAD_TYPE_DROPDOWN), SetMinimalSize(136, 12), SetDataTip(STR_JUST_STRING, STR_REPLACE_HELP_ROADTYPE), SetFill(1, 0), SetResize(1, 0),
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(),
EndContainer(),
NWidget(NWID_VERTICAL),
@@ -863,14 +846,14 @@ static const NWidgetPart _nested_replace_road_vehicle_widgets[] = {
EndContainer(),
};
static WindowDesc _replace_road_vehicle_desc(
static WindowDesc _replace_road_vehicle_desc(__FILE__, __LINE__,
WDP_AUTO, "replace_vehicle_road", 500, 140,
WC_REPLACE_VEHICLE, WC_NONE,
WDF_CONSTRUCTION,
_nested_replace_road_vehicle_widgets, lengthof(_nested_replace_road_vehicle_widgets)
std::begin(_nested_replace_road_vehicle_widgets), std::end(_nested_replace_road_vehicle_widgets)
);
static const NWidgetPart _nested_replace_vehicle_widgets[] = {
static constexpr NWidgetPart _nested_replace_vehicle_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_RV_CAPTION), SetMinimalSize(433, 14), SetDataTip(STR_REPLACE_VEHICLES_WHITE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
@@ -915,11 +898,11 @@ static const NWidgetPart _nested_replace_vehicle_widgets[] = {
EndContainer(),
};
static WindowDesc _replace_vehicle_desc(
static WindowDesc _replace_vehicle_desc(__FILE__, __LINE__,
WDP_AUTO, "replace_vehicle", 456, 118,
WC_REPLACE_VEHICLE, WC_NONE,
WDF_CONSTRUCTION,
_nested_replace_vehicle_widgets, lengthof(_nested_replace_vehicle_widgets)
std::begin(_nested_replace_vehicle_widgets), std::end(_nested_replace_vehicle_widgets)
);
/**