From 9984f39c96feb6777569a789d6fea3f6ac88c6e1 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Mon, 2 Nov 2020 20:10:44 +0000 Subject: [PATCH] Add feature to reverse the order of an order list See: #120 --- src/command.cpp | 2 ++ src/command_type.h | 1 + src/lang/english.txt | 4 +++ src/order_cmd.cpp | 28 ++++++++++++++++++ src/order_gui.cpp | 59 +++++++++++++++++++++++++++++++++++--- src/widgets/order_widget.h | 2 ++ 6 files changed, 92 insertions(+), 4 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index a5d8cda91a..cf0a48a4ff 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -230,6 +230,7 @@ CommandProc CmdSetGroupReplaceProtection; CommandProc CmdSetGroupLivery; CommandProc CmdMoveOrder; +CommandProc CmdReverseOrderList; CommandProcEx CmdChangeTimetable; CommandProc CmdBulkChangeTimetable; CommandProc CmdSetVehicleOnTime; @@ -458,6 +459,7 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdSetGroupReplaceProtection, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_GROUP_REPLACE_PROTECTION DEF_CMD(CmdSetGroupLivery, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_GROUP_LIVERY DEF_CMD(CmdMoveOrder, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_MOVE_ORDER + DEF_CMD(CmdReverseOrderList, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_REVERSE_ORDER_LIST DEF_CMD(CmdChangeTimetable, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_CHANGE_TIMETABLE DEF_CMD(CmdBulkChangeTimetable, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_BULK_CHANGE_TIMETABLE DEF_CMD(CmdSetVehicleOnTime, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_VEHICLE_ON_TIME diff --git a/src/command_type.h b/src/command_type.h index c84755ef90..afb7618030 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -412,6 +412,7 @@ enum Commands { CMD_SET_GROUP_LIVERY, ///< set the livery for a group CMD_MOVE_ORDER, ///< move an order + CMD_REVERSE_ORDER_LIST, ///< reverse order list CMD_CHANGE_TIMETABLE, ///< change the timetable for a vehicle CMD_BULK_CHANGE_TIMETABLE, ///< change the timetable for all orders of a vehicle CMD_SET_VEHICLE_ON_TIME, ///< set the vehicle on time feature (timetable) diff --git a/src/lang/english.txt b/src/lang/english.txt index 796230e9e8..2c8c5f6d5c 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -4874,6 +4874,10 @@ STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_NOT_IN_ACQUIRE_SLOT :train is not in STR_ORDERS_SKIP_BUTTON :{BLACK}Skip STR_ORDERS_SKIP_TOOLTIP :{BLACK}Skip the current order, and start the next. Ctrl+Click skips to the selected order +STR_ORDERS_MANAGE_LIST :{BLACK}Manage List +STR_ORDERS_MANAGE_LIST_TOOLTIP :{BLACK}Manage this order list +STR_ORDER_REVERSE_ORDER_LIST :Reverse order list + STR_ORDERS_DELETE_BUTTON :{BLACK}Delete STR_ORDERS_DELETE_TOOLTIP :{BLACK}Delete the highlighted order STR_ORDERS_DELETE_ALL_TOOLTIP :{BLACK}Delete all orders diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 0d070a0b98..164b423bbe 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1573,6 +1573,34 @@ CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 return CommandCost(); } +/** + * Reverse an orderlist + * @param tile unused + * @param flags operation to perform + * @param p1 the ID of the vehicle + * @param p2 unused + * @param text unused + * @return the cost of this operation or an error + */ +CommandCost CmdReverseOrderList(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + VehicleID veh = GB(p1, 0, 20); + + Vehicle *v = Vehicle::GetIfValid(veh); + if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; + + uint order_count = v->GetNumOrders(); + if (order_count < 2) return CMD_ERROR; + uint max_order = order_count - 1; + + for (uint i = 0; i < max_order; i++) { + CommandCost cost = DoCommand(tile, p1, max_order | (i << 16), flags, CMD_MOVE_ORDER); + if (cost.Failed()) return cost; + } + + return CommandCost(); +} + /** * Modify an order in the orderlist of a vehicle. * @param tile unused diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 41300e4d18..25f27a2d4c 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -631,6 +631,11 @@ static const StringID _order_goto_dropdown_aircraft[] = { INVALID_STRING_ID }; +static const StringID _order_manage_list_dropdown[] = { + STR_ORDER_REVERSE_ORDER_LIST, + INVALID_STRING_ID +}; + /** Variables for conditional orders; this defines the order of appearance in the dropdown box */ static const OrderConditionVariable _order_conditional_variable[] = { OCV_LOAD_PERCENTAGE, @@ -1211,6 +1216,10 @@ private: DP_ROW_CONDITIONAL = 2, ///< Display the conditional order buttons in the top row of the ship/airplane order window. + /* WID_O_SEL_BOTTOM_LEFT */ + DP_BOTTOM_LEFT_SKIP = 0, ///< Display 'skip' in the left button of the bottom row of the vehicle order window. + DP_BOTTOM_LEFT_MANAGE_LIST = 1, ///< Display 'manage list' in the left button of the bottom row of the vehicle order window. + /* WID_O_SEL_BOTTOM_MIDDLE */ DP_BOTTOM_MIDDLE_DELETE = 0, ///< Display 'delete' in the middle button of the bottom row of the vehicle order window. DP_BOTTOM_MIDDLE_STOP_SHARING = 1, ///< Display 'stop sharing' in the middle button of the bottom row of the vehicle order window. @@ -1515,6 +1524,14 @@ private: } } + /** + * Handle the click on the reverse order list button. + */ + void OrderClick_ReverseOrderList() + { + DoCommandP(this->vehicle->tile, this->vehicle->index, 0, CMD_REVERSE_ORDER_LIST | CMD_MSG(STR_ERROR_CAN_T_MOVE_THIS_ORDER)); + } + /** Cache auto-refittability of the vehicle chain. */ void UpdateAutoRefitState() { @@ -1739,6 +1756,11 @@ public: } } + /* skip / extra menu */ + NWidgetStacked *skip_sel = this->GetWidget(WID_O_SEL_BOTTOM_LEFT); + NWidgetLeaf *manage_list_dropdown = this->GetWidget(WID_O_MANAGE_LIST); + skip_sel->SetDisplayedPlane((manage_list_dropdown->IsLowered() || (_ctrl_pressed && this->selected_order == this->vehicle->GetNumOrders())) ? DP_BOTTOM_LEFT_MANAGE_LIST : DP_BOTTOM_LEFT_SKIP); + /* First row. */ this->RaiseWidget(WID_O_FULL_LOAD); this->RaiseWidget(WID_O_UNLOAD); @@ -2172,6 +2194,12 @@ public: this->OrderClick_Skip(); break; + case WID_O_MANAGE_LIST: { + uint disabled_mask = (this->vehicle->GetNumOrders() < 2 ? 1 : 0); + ShowDropDownMenu(this, _order_manage_list_dropdown, -1, WID_O_MANAGE_LIST, disabled_mask, 0, 0, DDSF_LOST_FOCUS); + break; + } + case WID_O_DELETE: this->OrderClick_Delete(); break; @@ -2481,6 +2509,13 @@ public: case WID_O_COND_COUNTER: this->ModifyOrder(this->OrderGetSel(), MOF_COND_VALUE_2 | index << 4); break; + + case WID_O_MANAGE_LIST: + switch (index) { + case 0: this->OrderClick_ReverseOrderList(); break; + default: NOT_REACHED(); + } + break; } } @@ -2640,6 +2675,14 @@ public: } } + void OnDropdownClose(Point pt, int widget, int index, bool instant_close) override + { + Window::OnDropdownClose(pt, widget, index, instant_close); + if (this->GetWidget(WID_O_SEL_BOTTOM_LEFT)->shown_plane == DP_BOTTOM_LEFT_MANAGE_LIST) { + this->UpdateButtonState(); + } + } + const Vehicle *GetVehicle() { return this->vehicle; @@ -2745,8 +2788,12 @@ static const NWidgetPart _nested_orders_train_widgets[] = { /* Second button row. */ NWidget(NWID_HORIZONTAL), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_SKIP), SetMinimalSize(124, 12), SetFill(1, 0), - SetDataTip(STR_ORDERS_SKIP_BUTTON, STR_ORDERS_SKIP_TOOLTIP), SetResize(1, 0), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_BOTTOM_LEFT), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_SKIP), SetMinimalSize(124, 12), SetFill(1, 0), + SetDataTip(STR_ORDERS_SKIP_BUTTON, STR_ORDERS_SKIP_TOOLTIP), SetResize(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_MANAGE_LIST), SetMinimalSize(124, 12), SetFill(1, 0), + SetDataTip(STR_ORDERS_MANAGE_LIST, STR_ORDERS_MANAGE_LIST_TOOLTIP), SetResize(1, 0), + EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_BOTTOM_MIDDLE), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_DELETE), SetMinimalSize(124, 12), SetFill(1, 0), SetDataTip(STR_ORDERS_DELETE_BUTTON, STR_ORDERS_DELETE_TOOLTIP), SetResize(1, 0), @@ -2841,8 +2888,12 @@ static const NWidgetPart _nested_orders_widgets[] = { /* Second button row. */ NWidget(NWID_HORIZONTAL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_SKIP), SetMinimalSize(124, 12), SetFill(1, 0), - SetDataTip(STR_ORDERS_SKIP_BUTTON, STR_ORDERS_SKIP_TOOLTIP), SetResize(1, 0), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_BOTTOM_LEFT), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_SKIP), SetMinimalSize(124, 12), SetFill(1, 0), + SetDataTip(STR_ORDERS_SKIP_BUTTON, STR_ORDERS_SKIP_TOOLTIP), SetResize(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_MANAGE_LIST), SetMinimalSize(124, 12), SetFill(1, 0), + SetDataTip(STR_ORDERS_MANAGE_LIST, STR_ORDERS_MANAGE_LIST_TOOLTIP), SetResize(1, 0), + EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_BOTTOM_MIDDLE), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_DELETE), SetMinimalSize(124, 12), SetFill(1, 0), SetDataTip(STR_ORDERS_DELETE_BUTTON, STR_ORDERS_DELETE_TOOLTIP), SetResize(1, 0), diff --git a/src/widgets/order_widget.h b/src/widgets/order_widget.h index e82f08d012..eb3564ce28 100644 --- a/src/widgets/order_widget.h +++ b/src/widgets/order_widget.h @@ -19,6 +19,7 @@ enum OrderWidgets { WID_O_ORDER_LIST, ///< Order list panel. WID_O_SCROLLBAR, ///< Order list scrollbar. WID_O_SKIP, ///< Skip current order. + WID_O_MANAGE_LIST, ///< Manage order list. WID_O_DELETE, ///< Delete selected order. WID_O_STOP_SHARING, ///< Stop sharing orders. WID_O_NON_STOP, ///< Goto non-stop to destination. @@ -46,6 +47,7 @@ enum OrderWidgets { WID_O_SEL_TOP_RIGHT, ///< #NWID_SELECTION widget for right part of the top row of the 'your train' order window. WID_O_SEL_TOP_ROW_GROUNDVEHICLE, ///< #NWID_SELECTION widget for the top row of the 'your train' order window. WID_O_SEL_TOP_ROW, ///< #NWID_SELECTION widget for the top row of the 'your non-trains' order window. + WID_O_SEL_BOTTOM_LEFT, ///< #NWID_SELECTION widget for the left part of the bottom row of the 'your train' order window. WID_O_SEL_BOTTOM_MIDDLE, ///< #NWID_SELECTION widget for the middle part of the bottom row of the 'your train' order window. WID_O_SEL_SHARED, ///< #NWID_SELECTION widget for WID_O_SHARED_ORDER_LIST and WID_O_ADD_VEH_GROUP WID_O_SHARED_ORDER_LIST, ///< Open list of shared vehicles.