From a11a8d0b2920f576ba108169a3d7c3b24383d7e2 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 22 Mar 2024 17:22:42 +0000 Subject: [PATCH] Allow removing vehicle from slots using vehicle details window dropdown --- src/lang/extra/english.txt | 1 + src/vehicle_gui.cpp | 43 ++++++++++++++++++++++++++++--------- src/widgets/dropdown_type.h | 13 +++++++++++ 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/lang/extra/english.txt b/src/lang/extra/english.txt index 46da7875bc..f1520258fc 100644 --- a/src/lang/extra/english.txt +++ b/src/lang/extra/english.txt @@ -1622,6 +1622,7 @@ STR_VEHICLE_DETAILS_TRAIN_MAX_SPEED :{BLACK}Max. spe STR_VEHICLE_DETAILS_EXTRA_ACTIONS_TOOLTIP :{BLACK}Extra vehicle actions STR_VEHICLE_DETAILS_REMOVE_SPEED_RESTRICTION :Remove speed restriction STR_VEHICLE_DETAILS_SET_SPEED_RESTRICTION :Set speed restriction +STR_VEHICLE_DETAILS_REMOVE_FROM_SLOT :Remove from slot: STR_ORDER_DROP_CARGO_TYPE_LOAD :Load by cargo type STR_ORDER_DROP_CARGO_TYPE_UNLOAD :Unload by cargo type diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 1b0aa03f3e..696bbeffc9 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -2848,6 +2848,7 @@ struct VehicleDetailsWindow : Window { enum DropDownAction { VDWDDA_CLEAR_SPEED_RESTRICTION, VDWDDA_SET_SPEED_RESTRICTION, + VDWDDA_REMOVE_FROM_SLOT, }; /** Initialize a newly created vehicle details window */ @@ -2955,6 +2956,19 @@ struct VehicleDetailsWindow : Window { return HasBit(Train::From(v)->flags, VRF_SPEED_ADAPTATION_EXEMPT); } + std::vector GetVehicleSlots(const Vehicle *v) const + { + std::vector slots; + TraceRestrictGetVehicleSlots(v->index, slots); + + std::sort(slots.begin(), slots.end(), [&](TraceRestrictSlotID a, TraceRestrictSlotID b) -> bool { + int r = StrNaturalCompare(TraceRestrictSlot::Get(a)->name, TraceRestrictSlot::Get(b)->name); + if (r == 0) return a < b; + return r < 0; + }); + return slots; + } + void UpdateWidgetSize(WidgetID widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { @@ -3230,14 +3244,7 @@ struct VehicleDetailsWindow : Window { bool should_show_slots = this->ShouldShowSlotsLine(v); if (should_show_slots) { - std::vector slots; - TraceRestrictGetVehicleSlots(v->index, slots); - - std::sort(slots.begin(), slots.end(), [&](TraceRestrictSlotID a, TraceRestrictSlotID b) -> bool { - int r = StrNaturalCompare(TraceRestrictSlot::Get(a)->name, TraceRestrictSlot::Get(b)->name); - if (r == 0) return a < b; - return r < 0; - }); + std::vector slots = this->GetVehicleSlots(v); SetDParam(0, slots.size()); std::string buffer = GetString(STR_TRACE_RESTRICT_SLOT_LIST_HEADER); @@ -3338,7 +3345,7 @@ struct VehicleDetailsWindow : Window { WID_VD_INCREASE_SERVICING_INTERVAL, WID_VD_DECREASE_SERVICING_INTERVAL); - this->SetWidgetDisabledState(WID_VD_EXTRA_ACTIONS, v->type != VEH_TRAIN); + this->SetWidgetDisabledState(WID_VD_EXTRA_ACTIONS, v->type != VEH_TRAIN && !HasBit(v->vehicle_flags, VF_HAVE_SLOT)); StringID str = !v->ServiceIntervalIsCustom() ? STR_VEHICLE_DETAILS_DEFAULT : @@ -3400,6 +3407,16 @@ struct VehicleDetailsWindow : Window { list.emplace_back(new DropDownListStringItem(STR_VEHICLE_DETAILS_REMOVE_SPEED_RESTRICTION, VDWDDA_CLEAR_SPEED_RESTRICTION, !change_allowed || Train::From(v)->speed_restriction == 0)); list.emplace_back(new DropDownListStringItem(STR_VEHICLE_DETAILS_SET_SPEED_RESTRICTION, VDWDDA_SET_SPEED_RESTRICTION, !change_allowed)); } + if (HasBit(v->vehicle_flags, VF_HAVE_SLOT)) { + if (!list.empty()) list.push_back(std::make_unique(-1, false)); + list.push_back(std::make_unique>(STR_VEHICLE_DETAILS_REMOVE_FROM_SLOT, -1)); + + std::vector slots = this->GetVehicleSlots(v); + for (TraceRestrictSlotID slot_id : slots) { + SetDParam(0, slot_id); + list.emplace_back(new DropDownListCheckedItem(false, STR_TRACE_RESTRICT_SLOT_NAME, VDWDDA_REMOVE_FROM_SLOT | (slot_id << 8), TraceRestrictSlot::Get(slot_id)->owner != _local_company)); + } + } ShowDropDownList(this, std::move(list), -1, WID_VD_EXTRA_ACTIONS, 140); break; } @@ -3439,7 +3456,7 @@ struct VehicleDetailsWindow : Window { case WID_VD_EXTRA_ACTIONS: { const Vehicle *v = Vehicle::Get(this->window_number); - switch (index) { + switch (GB(index, 0, 8)) { case VDWDDA_CLEAR_SPEED_RESTRICTION: DoCommandP(v->tile, v->index, 0, CMD_SET_TRAIN_SPEED_RESTRICTION | CMD_MSG(STR_ERROR_CAN_T_CHANGE_SPEED_RESTRICTION)); break; @@ -3447,6 +3464,12 @@ struct VehicleDetailsWindow : Window { case VDWDDA_SET_SPEED_RESTRICTION: { SetDParam(0, ConvertKmhishSpeedToDisplaySpeed(Train::From(v)->speed_restriction, VEH_TRAIN)); ShowQueryString(STR_JUST_INT, STR_TIMETABLE_CHANGE_SPEED, 10, this, CS_NUMERAL, QSF_NONE); + break; + } + + case VDWDDA_REMOVE_FROM_SLOT: { + DoCommandP(0, GB(index, 8, 16), v->index, CMD_REMOVE_VEHICLE_TRACERESTRICT_SLOT | CMD_MSG(STR_TRACE_RESTRICT_ERROR_SLOT_CAN_T_REMOVE_VEHICLE)); + break; } } break; diff --git a/src/widgets/dropdown_type.h b/src/widgets/dropdown_type.h index 59fe6a922f..b47ebe62f2 100644 --- a/src/widgets/dropdown_type.h +++ b/src/widgets/dropdown_type.h @@ -211,6 +211,19 @@ public: } }; +/** + * Drop down unselectable component. + * @tparam TBase Base component. + */ +template +class DropDownUnselectable : public TBase { +public: + template + explicit DropDownUnselectable(Args&&... args) : TBase(std::forward(args)...) {} + + bool Selectable() const override { return false; } +}; + /* Commonly used drop down list items. */ using DropDownListDividerItem = DropDownDivider; using DropDownListStringItem = DropDownString;