OpenTTD Source 20260129-master-g2bb01bd0e4
order_gui.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#include "stdafx.h"
11#include "command_func.h"
12#include "viewport_func.h"
13#include "depot_map.h"
14#include "roadveh.h"
15#include "timetable.h"
16#include "strings_func.h"
17#include "company_func.h"
18#include "dropdown_type.h"
19#include "dropdown_func.h"
20#include "textbuf_gui.h"
21#include "string_func.h"
22#include "tilehighlight_func.h"
23#include "network/network.h"
24#include "station_base.h"
25#include "industry.h"
26#include "waypoint_base.h"
28#include "hotkeys.h"
29#include "aircraft.h"
30#include "engine_func.h"
31#include "vehicle_func.h"
32#include "vehiclelist.h"
33#include "vehicle_func.h"
34#include "error.h"
35#include "order_cmd.h"
36#include "company_cmd.h"
38
40
41#include "table/strings.h"
42
43#include "safeguards.h"
44
45
47static const StringID _station_load_types[][5][5] = {
48 {
49 /* No refitting. */
50 {
53 STR_ORDER_FULL_LOAD,
54 STR_ORDER_FULL_LOAD_ANY,
55 STR_ORDER_NO_LOAD,
56 }, {
57 STR_ORDER_UNLOAD,
59 STR_ORDER_UNLOAD_FULL_LOAD,
60 STR_ORDER_UNLOAD_FULL_LOAD_ANY,
61 STR_ORDER_UNLOAD_NO_LOAD,
62 }, {
63 STR_ORDER_TRANSFER,
65 STR_ORDER_TRANSFER_FULL_LOAD,
66 STR_ORDER_TRANSFER_FULL_LOAD_ANY,
67 STR_ORDER_TRANSFER_NO_LOAD,
68 }, {
69 /* Unload and transfer do not work together. */
75 }, {
76 STR_ORDER_NO_UNLOAD,
78 STR_ORDER_NO_UNLOAD_FULL_LOAD,
79 STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY,
80 STR_ORDER_NO_UNLOAD_NO_LOAD,
81 }
82 }, {
83 /* With auto-refitting. No loading and auto-refitting do not work together. */
84 {
85 STR_ORDER_AUTO_REFIT,
87 STR_ORDER_FULL_LOAD_REFIT,
88 STR_ORDER_FULL_LOAD_ANY_REFIT,
90 }, {
91 STR_ORDER_UNLOAD_REFIT,
93 STR_ORDER_UNLOAD_FULL_LOAD_REFIT,
94 STR_ORDER_UNLOAD_FULL_LOAD_ANY_REFIT,
96 }, {
97 STR_ORDER_TRANSFER_REFIT,
99 STR_ORDER_TRANSFER_FULL_LOAD_REFIT,
100 STR_ORDER_TRANSFER_FULL_LOAD_ANY_REFIT,
102 }, {
103 /* Unload and transfer do not work together. */
109 }, {
110 STR_ORDER_NO_UNLOAD_REFIT,
112 STR_ORDER_NO_UNLOAD_FULL_LOAD_REFIT,
113 STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY_REFIT,
115 }
116 }
117};
118
119static const StringID _order_non_stop_dropdown[] = {
120 STR_ORDER_GO_TO,
121 STR_ORDER_GO_NON_STOP_TO,
122 STR_ORDER_GO_VIA,
123 STR_ORDER_GO_NON_STOP_VIA,
124};
125
126static const StringID _order_full_load_dropdown[] = {
127 STR_ORDER_DROP_LOAD_IF_POSSIBLE,
128 STR_EMPTY,
129 STR_ORDER_DROP_FULL_LOAD_ALL,
130 STR_ORDER_DROP_FULL_LOAD_ANY,
131 STR_ORDER_DROP_NO_LOADING,
132};
133
134static const StringID _order_unload_dropdown[] = {
135 STR_ORDER_DROP_UNLOAD_IF_ACCEPTED,
136 STR_ORDER_DROP_UNLOAD,
137 STR_ORDER_DROP_TRANSFER,
138 STR_EMPTY,
139 STR_ORDER_DROP_NO_UNLOADING,
140};
141
142static const StringID _order_goto_dropdown[] = {
143 STR_ORDER_GO_TO,
144 STR_ORDER_GO_TO_NEAREST_DEPOT,
145 STR_ORDER_CONDITIONAL,
146 STR_ORDER_SHARE,
147};
148
149static const StringID _order_goto_dropdown_aircraft[] = {
150 STR_ORDER_GO_TO,
151 STR_ORDER_GO_TO_NEAREST_HANGAR,
152 STR_ORDER_CONDITIONAL,
153 STR_ORDER_SHARE,
154};
155
167
168static const StringID _order_conditional_condition[] = {
169 STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS,
170 STR_ORDER_CONDITIONAL_COMPARATOR_NOT_EQUALS,
171 STR_ORDER_CONDITIONAL_COMPARATOR_LESS_THAN,
172 STR_ORDER_CONDITIONAL_COMPARATOR_LESS_EQUALS,
173 STR_ORDER_CONDITIONAL_COMPARATOR_MORE_THAN,
174 STR_ORDER_CONDITIONAL_COMPARATOR_MORE_EQUALS,
175 STR_ORDER_CONDITIONAL_COMPARATOR_IS_TRUE,
176 STR_ORDER_CONDITIONAL_COMPARATOR_IS_FALSE,
177};
178
179extern uint ConvertSpeedToDisplaySpeed(uint speed, VehicleType type);
180extern uint ConvertDisplaySpeedToSpeed(uint speed, VehicleType type);
181
182static const StringID _order_depot_action_dropdown[] = {
183 STR_ORDER_DROP_GO_ALWAYS_DEPOT,
184 STR_ORDER_DROP_SERVICE_DEPOT,
185 STR_ORDER_DROP_HALT_DEPOT,
186 STR_ORDER_DROP_UNBUNCH,
187};
188
189static OrderDepotAction DepotActionStringIndex(const Order *order)
190{
195}
196
197static const StringID _order_refit_action_dropdown[] = {
198 STR_ORDER_DROP_REFIT_AUTO,
199 STR_ORDER_DROP_REFIT_AUTO_ANY,
200};
201
202static StringID GetOrderGoToString(const Order &order)
203{
205 return order.GetNonStopType().Test(OrderNonStopFlag::NoIntermediate) ? STR_ORDER_SERVICE_NON_STOP_AT : STR_ORDER_SERVICE_AT;
206 } else {
207 return order.GetNonStopType().Test(OrderNonStopFlag::NoIntermediate) ? STR_ORDER_GO_NON_STOP_TO : STR_ORDER_GO_TO;
208 }
209}
210
223void DrawOrderString(const Vehicle *v, const Order *order, VehicleOrderID order_index, int y, bool selected, bool timetable, int left, int middle, int right)
224{
225 bool rtl = _current_text_dir == TD_RTL;
226
227 SpriteID sprite = rtl ? SPR_ARROW_LEFT : SPR_ARROW_RIGHT;
228 Dimension sprite_size = GetSpriteSize(sprite);
229 if (v->cur_real_order_index == order_index) {
230 /* Draw two arrows before the next real order. */
231 DrawSprite(sprite, PAL_NONE, rtl ? right - sprite_size.width : left, y + ((int)GetCharacterHeight(FS_NORMAL) - (int)sprite_size.height) / 2);
232 DrawSprite(sprite, PAL_NONE, rtl ? right - 2 * sprite_size.width : left + sprite_size.width, y + ((int)GetCharacterHeight(FS_NORMAL) - (int)sprite_size.height) / 2);
233 } else if (v->cur_implicit_order_index == order_index) {
234 /* Draw one arrow before the next implicit order; the next real order will still get two arrows. */
235 DrawSprite(sprite, PAL_NONE, rtl ? right - sprite_size.width : left, y + ((int)GetCharacterHeight(FS_NORMAL) - (int)sprite_size.height) / 2);
236 }
237
238 TextColour colour = TC_BLACK;
239 if (order->IsType(OT_IMPLICIT)) {
240 colour = (selected ? TC_SILVER : TC_GREY) | TC_NO_SHADE;
241 } else if (selected) {
242 colour = TC_WHITE;
243 }
244
245 DrawString(left, rtl ? right - 2 * sprite_size.width - 3 : middle, y, GetString(STR_ORDER_INDEX, order_index + 1), colour, SA_RIGHT | SA_FORCE);
246
247 std::string line;
248
249 switch (order->GetType()) {
250 case OT_DUMMY:
251 line = GetString(STR_INVALID_ORDER);
252 break;
253
254 case OT_IMPLICIT:
255 line = GetString(STR_ORDER_GO_TO_STATION, STR_ORDER_GO_TO, order->GetDestination());
256 if (!timetable) line += GetString(STR_ORDER_IMPLICIT);
257 break;
258
259 case OT_GOTO_STATION: {
260 OrderLoadType load = order->GetLoadType();
261 OrderUnloadType unload = order->GetUnloadType();
262 bool valid_station = CanVehicleUseStation(v, Station::Get(order->GetDestination().ToStationID()));
263
264 line = GetString(valid_station ? STR_ORDER_GO_TO_STATION : STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION, STR_ORDER_GO_TO + (v->IsGroundVehicle() ? order->GetNonStopType() : OrderNonStopFlags{}).base(), order->GetDestination());
265 if (timetable) {
266 /* Show only wait time in the timetable window. */
267 if (order->GetWaitTime() > 0) {
268 auto [str, value] = GetTimetableParameters(order->GetWaitTime());
269 line += GetString(order->IsWaitTimetabled() ? STR_TIMETABLE_STAY_FOR : STR_TIMETABLE_STAY_FOR_ESTIMATED, str, value);
270 }
271 } else {
272 /* Show non-stop, refit and stop location only in the order window. */
274 StringID str = _station_load_types[order->IsRefit()][to_underlying(unload)][to_underlying(load)];
275 if (str != INVALID_STRING_ID) {
276 if (order->IsRefit()) {
277 line += GetString(str, order->IsAutoRefit() ? STR_ORDER_AUTO_REFIT_ANY : CargoSpec::Get(order->GetRefitCargo())->name);
278 } else {
279 line += GetString(str);
280 }
281 }
282 }
283
285 /* Only show the stopping location if other than the default chosen by the player. */
287 line += GetString(STR_ORDER_STOP_LOCATION_NEAR_END + to_underlying(order->GetStopLocation()));
288 }
289 }
290 }
291 break;
292 }
293
294 case OT_GOTO_DEPOT:
296 /* Going to a specific depot. */
297 line = GetString(STR_ORDER_GO_TO_DEPOT_FORMAT, GetOrderGoToString(*order), v->type, order->GetDestination());
298 } else if (v->type == VEH_AIRCRAFT) {
299 /* Going to the nearest hangar. */
300 line = GetString(STR_ORDER_GO_TO_NEAREST_HANGAR_FORMAT, GetOrderGoToString(*order));
301 } else {
302 /* Going to the nearest depot. */
303 line = GetString(STR_ORDER_GO_TO_NEAREST_DEPOT_FORMAT, GetOrderGoToString(*order), STR_ORDER_TRAIN_DEPOT + v->type);
304 }
305
306 /* Do not show stopping in the depot in the timetable window. */
307 if (!timetable && order->GetDepotActionType().Test(OrderDepotActionFlag::Halt)) {
308 line += GetString(STR_ORDER_STOP_ORDER);
309 }
310
311 /* Do not show refitting in the depot in the timetable window. */
312 if (!timetable && order->IsRefit()) {
313 line += GetString(order->GetDepotActionType().Test(OrderDepotActionFlag::Halt) ? STR_ORDER_REFIT_STOP_ORDER : STR_ORDER_REFIT_ORDER, CargoSpec::Get(order->GetRefitCargo())->name);
314 }
315
316 /* Show unbunching depot in both order and timetable windows. */
318 line += GetString(STR_ORDER_WAIT_TO_UNBUNCH);
319 }
320 break;
321
322 case OT_GOTO_WAYPOINT:
323 line = GetString(order->GetNonStopType().Test(OrderNonStopFlag::NoIntermediate) ? STR_ORDER_GO_NON_STOP_TO_WAYPOINT : STR_ORDER_GO_TO_WAYPOINT, order->GetDestination());
324 break;
325
326 case OT_CONDITIONAL:
328 line = GetString(STR_ORDER_CONDITIONAL_UNCONDITIONAL, order->GetConditionSkipToOrder() + 1);
329 } else {
331
332 uint value = order->GetConditionValue();
334
335 line = GetString((occ == OrderConditionComparator::IsTrue || occ == OrderConditionComparator::IsFalse) ? STR_ORDER_CONDITIONAL_TRUE_FALSE : STR_ORDER_CONDITIONAL_NUM,
336 order->GetConditionSkipToOrder() + 1,
337 STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + to_underlying(order->GetConditionVariable()),
338 STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + to_underlying(occ),
339 value);
340 }
341
342 if (timetable && order->GetWaitTime() > 0) {
343 auto [str, value] = GetTimetableParameters(order->GetWaitTime());
344 line += GetString(order->IsWaitTimetabled() ? STR_TIMETABLE_AND_TRAVEL_FOR : STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED, str, value);
345 }
346 break;
347
348 default: NOT_REACHED();
349 }
350
351 /* Check range for aircraft. */
352 if (v->type == VEH_AIRCRAFT && Aircraft::From(v)->GetRange() > 0 && order->IsGotoOrder()) {
353 if (GetOrderDistance(order_index, v->orders->GetNext(order_index), v) > Aircraft::From(v)->acache.cached_max_range_sqr) {
354 line += GetString(STR_ORDER_OUT_OF_RANGE);
355 }
356 }
357
358 DrawString(rtl ? left : middle, rtl ? middle : right, y, line, colour);
359}
360
368{
369 Order order{};
370
371 /* check depot first */
372 if (IsDepotTypeTile(tile, (TransportType)(uint)v->type) && IsTileOwner(tile, _local_company)) {
376
377 if (_ctrl_pressed) {
378 /* Now we are allowed to set the action type. */
380 }
381
382 return order;
383 }
384
385 /* check rail waypoint */
386 if (IsRailWaypointTile(tile) &&
387 v->type == VEH_TRAIN &&
391 return order;
392 }
393
394 /* check road waypoint */
395 if (IsRoadWaypointTile(tile) &&
396 v->type == VEH_ROAD &&
400 return order;
401 }
402
403 /* check buoy (no ownership) */
404 if (IsBuoyTile(tile) && v->type == VEH_SHIP) {
406 return order;
407 }
408
409 /* check for station or industry with neutral station */
411 const Station *st = nullptr;
412
413 if (IsTileType(tile, TileType::Station)) {
414 st = Station::GetByTile(tile);
415 } else {
416 const Industry *in = Industry::GetByTile(tile);
417 st = in->neutral_station;
418 }
419 if (st != nullptr && (st->owner == _local_company || st->owner == OWNER_NONE)) {
420 StationFacilities facil;
421 switch (v->type) {
422 case VEH_SHIP: facil = StationFacility::Dock; break;
423 case VEH_TRAIN: facil = StationFacility::Train; break;
424 case VEH_AIRCRAFT: facil = StationFacility::Airport; break;
426 default: NOT_REACHED();
427 }
428 if (st->facilities.Any(facil)) {
429 order.MakeGoToStation(st->index);
433 return order;
434 }
435 }
436 }
437
438 /* not found */
439 order.Free();
440 return order;
441}
442
444enum OrderHotKeys : int32_t {
445 OHK_SKIP,
446 OHK_DELETE,
447 OHK_GOTO,
448 OHK_NONSTOP,
449 OHK_FULLLOAD,
450 OHK_UNLOAD,
451 OHK_NEAREST_DEPOT,
452 OHK_ALWAYS_SERVICE,
453 OHK_TRANSFER,
454 OHK_NO_UNLOAD,
455 OHK_NO_LOAD,
456};
457
498struct OrdersWindow : public Window {
499private:
501 enum OrderPlaceObjectState : uint8_t {
502 OPOS_NONE,
503 OPOS_GOTO,
504 OPOS_CONDITIONAL,
505 OPOS_SHARE,
506 OPOS_END,
507 };
508
510 enum DisplayPane : uint8_t {
511 /* WID_O_SEL_TOP_ROW_GROUNDVEHICLE */
514
515 /* WID_O_SEL_TOP_LEFT */
518
519 /* WID_O_SEL_TOP_MIDDLE */
522
523 /* WID_O_SEL_TOP_RIGHT */
526
527 /* WID_O_SEL_TOP_ROW */
531
532 /* WID_O_SEL_BOTTOM_MIDDLE */
535 };
536
537 int selected_order = -1;
539 OrderPlaceObjectState goto_type = OPOS_NONE;
540 const Vehicle *vehicle = nullptr;
541 Scrollbar *vscroll = nullptr;
542 bool can_do_refit = false;
543 bool can_do_autorefit = false;
544
551 {
552 int num = this->selected_order;
553 return (num >= 0 && num < vehicle->GetNumOrders()) ? num : vehicle->GetNumOrders();
554 }
555
565 {
566 int32_t sel = this->vscroll->GetScrolledRowFromWidget(y, this, WID_O_ORDER_LIST, WidgetDimensions::scaled.framerect.top);
567 if (sel == INT32_MAX) return INVALID_VEH_ORDER_ID;
568 /* One past the orders is the 'End of Orders' line. */
569 assert(IsInsideBS(sel, 0, vehicle->GetNumOrders() + 1));
570 return sel;
571 }
572
577 {
578 assert(type > OPOS_NONE && type < OPOS_END);
579
580 static const HighLightStyle goto_place_style[OPOS_END - 1] = {
581 HT_RECT | HT_VEHICLE, // OPOS_GOTO
582 HT_NONE, // OPOS_CONDITIONAL
583 HT_VEHICLE, // OPOS_SHARE
584 };
585 SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, goto_place_style[type - 1], this);
586 this->goto_type = type;
588 }
589
595 void OrderClick_FullLoad(OrderLoadType load_type, bool toggle = false)
596 {
597 VehicleOrderID sel_ord = this->OrderGetSel();
598 const Order *order = this->vehicle->GetOrder(sel_ord);
599
600 if (order == nullptr) return;
601
602 if (toggle && order->GetLoadType() == load_type) {
603 load_type = OrderLoadType::LoadIfPossible; // reset to 'default'
604 }
605 if (order->GetLoadType() == load_type) return; // If we still match, do nothing
606
607 Command<Commands::ModifyOrder>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel_ord, MOF_LOAD, to_underlying(load_type));
608 }
609
613 void OrderClick_Service(std::optional<OrderDepotAction> i)
614 {
615 VehicleOrderID sel_ord = this->OrderGetSel();
616
617 if (!i.has_value()) {
618 const Order *order = this->vehicle->GetOrder(sel_ord);
619 if (order == nullptr) return;
621 }
622 Command<Commands::ModifyOrder>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel_ord, MOF_DEPOT_ACTION, to_underlying(i.value()));
623 }
624
629 {
630 Order order{};
631 order.MakeGoToDepot(DepotID::Invalid(), OrderDepotTypeFlag::PartOfOrders,
632 _settings_client.gui.new_nonstop && this->vehicle->IsGroundVehicle() ? OrderNonStopFlag::NoIntermediate : OrderNonStopFlags{});
634
635 Command<Commands::InsertOrder>::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), order);
636 }
637
643 void OrderClick_Unload(OrderUnloadType unload_type, bool toggle = false)
644 {
645 VehicleOrderID sel_ord = this->OrderGetSel();
646 const Order *order = this->vehicle->GetOrder(sel_ord);
647
648 if (order == nullptr) return;
649
650 if (toggle && order->GetUnloadType() == unload_type) {
652 }
653 if (order->GetUnloadType() == unload_type) return; // If we still match, do nothing
654
655 Command<Commands::ModifyOrder>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel_ord, MOF_UNLOAD, to_underlying(unload_type));
656
657 /* Transfer and unload orders with leave empty as default */
658 if (unload_type == OrderUnloadType::Transfer || unload_type == OrderUnloadType::Unload) {
659 Command<Commands::ModifyOrder>::Post(this->vehicle->tile, this->vehicle->index, sel_ord, MOF_LOAD, to_underlying(OrderLoadType::NoLoad));
661 }
662 }
663
668 void OrderClick_Nonstop(std::optional<OrderNonStopFlags> non_stop)
669 {
670 if (!this->vehicle->IsGroundVehicle()) return;
671
672 VehicleOrderID sel_ord = this->OrderGetSel();
673 const Order *order = this->vehicle->GetOrder(sel_ord);
674
675 if (order == nullptr || order->GetNonStopType() == non_stop) return;
676
677 /* Keypress if no value, so 'toggle' to the next */
678 if (!non_stop.has_value()) {
680 }
681
683 Command<Commands::ModifyOrder>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel_ord, MOF_NON_STOP, non_stop.value().base());
684 }
685
691 {
692 /* Don't skip when there's nothing to skip */
693 if (_ctrl_pressed && this->vehicle->cur_implicit_order_index == this->OrderGetSel()) return;
694 if (this->vehicle->GetNumOrders() <= 1) return;
695
696 Command<Commands::SkipToOrder>::Post(_ctrl_pressed ? STR_ERROR_CAN_T_SKIP_TO_ORDER : STR_ERROR_CAN_T_SKIP_ORDER,
697 this->vehicle->tile, this->vehicle->index, _ctrl_pressed ? this->OrderGetSel() : ((this->vehicle->cur_implicit_order_index + 1) % this->vehicle->GetNumOrders()));
698 }
699
704 {
705 /* When networking, move one order lower */
706 int selected = this->selected_order + (int)_networking;
707
708 if (Command<Commands::DeleteOrder>::Post(STR_ERROR_CAN_T_DELETE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel())) {
709 this->selected_order = selected >= this->vehicle->GetNumOrders() ? -1 : selected;
710 this->UpdateButtonState();
711 }
712 }
713
721 {
722 /* Don't try to stop sharing orders if 'End of Shared Orders' isn't selected. */
723 if (!this->vehicle->IsOrderListShared() || this->selected_order != this->vehicle->GetNumOrders()) return;
724 /* If Ctrl is pressed, delete the order list as if we clicked the 'Delete' button. */
725 if (_ctrl_pressed) {
726 this->OrderClick_Delete();
727 return;
728 }
729
730 /* Get another vehicle that share orders with this vehicle. */
731 Vehicle *other_shared = (this->vehicle->FirstShared() == this->vehicle) ? this->vehicle->NextShared() : this->vehicle->PreviousShared();
732 /* Copy the order list of the other vehicle. */
733 if (Command<Commands::CloneOrder>::Post(STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST, this->vehicle->tile, CO_COPY, this->vehicle->index, other_shared->index)) {
734 this->UpdateButtonState();
735 }
736 }
737
744 void OrderClick_Refit(int i, bool auto_refit)
745 {
746 if (_ctrl_pressed) {
747 /* Cancel refitting */
748 Command<Commands::OrderRefit>::Post(this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), CARGO_NO_REFIT);
749 } else {
750 if (i == 1) { // Auto-refit to available cargo type.
751 Command<Commands::OrderRefit>::Post(this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), CARGO_AUTO_REFIT);
752 } else {
753 ShowVehicleRefitWindow(this->vehicle, this->OrderGetSel(), this, auto_refit);
754 }
755 }
756 }
757
760 {
761 this->can_do_refit = false;
762 this->can_do_autorefit = false;
763 for (const Vehicle *w = this->vehicle; w != nullptr; w = w->IsGroundVehicle() ? w->Next() : nullptr) {
764 if (IsEngineRefittable(w->engine_type)) this->can_do_refit = true;
765 if (Engine::Get(w->engine_type)->info.misc_flags.Test(EngineMiscFlag::AutoRefit)) this->can_do_autorefit = true;
766 }
767 }
768
769public:
770 OrdersWindow(WindowDesc &desc, const Vehicle *v) : Window(desc)
771 {
772 this->vehicle = v;
773
774 this->CreateNestedTree();
775 this->vscroll = this->GetScrollbar(WID_O_SCROLLBAR);
776 if (NWidgetCore *nwid = this->GetWidget<NWidgetCore>(WID_O_DEPOT_ACTION); nwid != nullptr) {
777 nwid->SetToolTip(STR_ORDER_TRAIN_DEPOT_ACTION_TOOLTIP + v->type);
778 }
779 this->FinishInitNested(v->index);
780
781 this->owner = v->owner;
782
783 this->UpdateAutoRefitState();
784
786 /* If there are less than 2 station, make Go To active. */
787 int station_orders = std::ranges::count_if(v->Orders(), [](const Order &order) { return order.IsType(OT_GOTO_STATION); });
788
789 if (station_orders < 2) this->OrderClick_Goto(OPOS_GOTO);
790 }
792 }
793
794 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
795 {
796 switch (widget) {
797 case WID_O_ORDER_LIST:
798 fill.height = resize.height = GetCharacterHeight(FS_NORMAL);
799 size.height = 6 * resize.height + padding.height;
800 break;
801
802 case WID_O_COND_VARIABLE: {
803 Dimension d = {0, 0};
804 for (const auto &ocv : _order_conditional_variable) {
805 d = maxdim(d, GetStringBoundingBox(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + to_underlying(ocv)));
806 }
807 d.width += padding.width;
808 d.height += padding.height;
809 size = maxdim(size, d);
810 break;
811 }
812
814 Dimension d = GetStringListBoundingBox(_order_conditional_condition);
815 d.width += padding.width;
816 d.height += padding.height;
817 size = maxdim(size, d);
818 break;
819 }
820 }
821 }
822
828 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
829 {
832
833 switch (data) {
834 case VIWD_AUTOREPLACE:
835 /* Autoreplace replaced the vehicle */
836 this->vehicle = Vehicle::Get(this->window_number);
837 [[fallthrough]];
838
840 /* Vehicle composition was changed. */
841 this->UpdateAutoRefitState();
842 break;
843
845 /* Removed / replaced all orders (after deleting / sharing) */
846 if (this->selected_order == -1) break;
847
848 this->CloseChildWindows();
849 this->selected_order = -1;
850 break;
851
853 /* Some other order changes */
854 break;
855
856 default:
857 if (data < 0) break;
858
859 if (gui_scope) break; // only do this once; from command scope
860 from = GB(data, 0, 8);
861 to = GB(data, 8, 8);
862 /* Moving an order. If one of these is INVALID_VEH_ORDER_ID, then
863 * the order is being created / removed */
864 if (this->selected_order == -1) break;
865
866 if (from == to) break; // no need to change anything
867
868 if (from != this->selected_order) {
869 /* Moving from preceding order? */
870 this->selected_order -= (int)(from <= this->selected_order);
871 /* Moving to preceding order? */
872 this->selected_order += (int)(to <= this->selected_order);
873 break;
874 }
875
876 /* Now we are modifying the selected order */
877 if (to == INVALID_VEH_ORDER_ID) {
878 /* Deleting selected order */
879 this->CloseChildWindows();
880 this->selected_order = -1;
881 break;
882 }
883
884 /* Moving selected order */
885 this->selected_order = to;
886 break;
887 }
888
889 this->vscroll->SetCount(this->vehicle->GetNumOrders() + 1);
890 if (gui_scope) this->UpdateButtonState();
891
892 /* Scroll to the new order. */
893 if (from == INVALID_VEH_ORDER_ID && to != INVALID_VEH_ORDER_ID && !this->vscroll->IsVisible(to)) {
894 this->vscroll->ScrollTowards(to);
895 }
896 }
897
898 void UpdateButtonState()
899 {
900 if (this->vehicle->owner != _local_company) return; // No buttons are displayed with competitor order windows.
901
902 bool shared_orders = this->vehicle->IsOrderListShared();
903 VehicleOrderID sel = this->OrderGetSel();
904 const Order *order = this->vehicle->GetOrder(sel);
905
906 /* Second row. */
907 /* skip */
908 this->SetWidgetDisabledState(WID_O_SKIP, this->vehicle->GetNumOrders() <= 1);
909
910 /* delete / stop sharing */
911 NWidgetStacked *delete_sel = this->GetWidget<NWidgetStacked>(WID_O_SEL_BOTTOM_MIDDLE);
912 if (shared_orders && this->selected_order == this->vehicle->GetNumOrders()) {
913 /* The 'End of Shared Orders' order is selected, show the 'stop sharing' button. */
915 } else {
916 /* The 'End of Shared Orders' order isn't selected, show the 'delete' button. */
919 (uint)this->vehicle->GetNumOrders() + ((shared_orders || this->vehicle->GetNumOrders() != 0) ? 1 : 0) <= (uint)this->selected_order);
920
921 /* Set the tooltip of the 'delete' button depending on whether the
922 * 'End of Orders' order or a regular order is selected. */
923 NWidgetCore *nwi = this->GetWidget<NWidgetCore>(WID_O_DELETE);
924 if (this->selected_order == this->vehicle->GetNumOrders()) {
925 nwi->SetStringTip(STR_ORDERS_DELETE_BUTTON, STR_ORDERS_DELETE_ALL_TOOLTIP);
926 } else {
927 nwi->SetStringTip(STR_ORDERS_DELETE_BUTTON, STR_ORDERS_DELETE_TOOLTIP);
928 }
929 }
930
931 /* First row. */
934
935 /* Selection widgets. */
936 /* Train or road vehicle. */
937 NWidgetStacked *train_row_sel = this->GetWidget<NWidgetStacked>(WID_O_SEL_TOP_ROW_GROUNDVEHICLE);
938 NWidgetStacked *left_sel = this->GetWidget<NWidgetStacked>(WID_O_SEL_TOP_LEFT);
939 NWidgetStacked *middle_sel = this->GetWidget<NWidgetStacked>(WID_O_SEL_TOP_MIDDLE);
940 NWidgetStacked *right_sel = this->GetWidget<NWidgetStacked>(WID_O_SEL_TOP_RIGHT);
941 /* Ship or airplane. */
942 NWidgetStacked *row_sel = this->GetWidget<NWidgetStacked>(WID_O_SEL_TOP_ROW);
943 assert(row_sel != nullptr || (train_row_sel != nullptr && left_sel != nullptr && middle_sel != nullptr && right_sel != nullptr));
944
945
946 if (order == nullptr) {
947 if (row_sel != nullptr) {
949 } else {
956 }
960 } else {
963
964 switch (order->GetType()) {
965 case OT_GOTO_STATION:
966 if (row_sel != nullptr) {
968 } else {
975 }
978
979 /* Can only do refitting when stopping at the destination and loading cargo.
980 * Also enable the button if a refit is already set to allow clearing it. */
983 ((!this->can_do_refit || !this->can_do_autorefit) && !order->IsRefit()));
984
985 break;
986
987 case OT_GOTO_WAYPOINT:
988 if (row_sel != nullptr) {
990 } else {
997 }
1001 break;
1002
1003 case OT_GOTO_DEPOT:
1004 if (row_sel != nullptr) {
1006 } else {
1013 }
1014 /* Disable refit button if the order is no 'always go' order.
1015 * However, keep the service button enabled for refit-orders to allow clearing refits (without knowing about ctrl). */
1018 (!this->can_do_refit && !order->IsRefit()));
1019 break;
1020
1021 case OT_CONDITIONAL: {
1022 if (row_sel != nullptr) {
1024 } else {
1026 }
1028 /* Set the strings for the dropdown boxes. */
1029 this->GetWidget<NWidgetCore>(WID_O_COND_VARIABLE)->SetString(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + to_underlying(ocv));
1030 this->GetWidget<NWidgetCore>(WID_O_COND_COMPARATOR)->SetString(_order_conditional_condition[to_underlying(order->GetConditionComparator())]);
1033 break;
1034 }
1035
1036 default: // every other order
1037 if (row_sel != nullptr) {
1039 } else {
1045 }
1049 break;
1050 }
1051 }
1052
1053 /* Disable list of vehicles with the same shared orders if there is no list */
1054 this->SetWidgetDisabledState(WID_O_SHARED_ORDER_LIST, !shared_orders);
1055
1056 this->SetDirty();
1057 }
1058
1059 void OnPaint() override
1060 {
1061 if (this->vehicle->owner != _local_company) {
1062 this->selected_order = -1; // Disable selection any selected row at a competitor order window.
1063 } else {
1064 this->SetWidgetLoweredState(WID_O_GOTO, this->goto_type != OPOS_NONE);
1065 }
1066 this->DrawWidgets();
1067 }
1068
1069 void DrawWidget(const Rect &r, WidgetID widget) const override
1070 {
1071 if (widget != WID_O_ORDER_LIST) return;
1072
1073 Rect ir = r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect);
1074 bool rtl = _current_text_dir == TD_RTL;
1075 uint64_t max_value = GetParamMaxValue(this->vehicle->GetNumOrders(), 2);
1076 int index_column_width = GetStringBoundingBox(GetString(STR_ORDER_INDEX, max_value)).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + WidgetDimensions::scaled.hsep_normal;
1077 int middle = rtl ? ir.right - index_column_width : ir.left + index_column_width;
1078
1079 int y = ir.top;
1080 int line_height = this->GetWidget<NWidgetBase>(WID_O_ORDER_LIST)->resize_y;
1081
1082 VehicleOrderID i = this->vscroll->GetPosition();
1083 VehicleOrderID num_orders = this->vehicle->GetNumOrders();
1084
1085 /* First draw the highlighting underground if it exists. */
1086 if (this->order_over != INVALID_VEH_ORDER_ID) {
1087 while (i < num_orders) {
1088 /* Don't draw anything if it extends past the end of the window. */
1089 if (!this->vscroll->IsVisible(i)) break;
1090
1091 if (i != this->selected_order && i == this->order_over) {
1092 /* Highlight dragged order destination. */
1093 int top = (this->order_over < this->selected_order ? y : y + line_height) - WidgetDimensions::scaled.framerect.top;
1094 int bottom = std::min(top + 2, ir.bottom);
1095 top = std::max(top - 3, ir.top);
1096 GfxFillRect(ir.left, top, ir.right, bottom, GetColourGradient(COLOUR_GREY, SHADE_LIGHTEST));
1097 break;
1098 }
1099 y += line_height;
1100
1101 i++;
1102 }
1103
1104 /* Reset counters for drawing the orders. */
1105 y = ir.top;
1106 i = this->vscroll->GetPosition();
1107 }
1108
1109 /* Draw the orders. */
1110 while (i < num_orders) {
1111 /* Don't draw anything if it extends past the end of the window. */
1112 if (!this->vscroll->IsVisible(i)) break;
1113
1114 DrawOrderString(this->vehicle, this->vehicle->GetOrder(i), i, y, i == this->selected_order, false, ir.left, middle, ir.right);
1115 y += line_height;
1116
1117 i++;
1118 }
1119
1120 if (this->vscroll->IsVisible(i)) {
1121 StringID str = this->vehicle->IsOrderListShared() ? STR_ORDERS_END_OF_SHARED_ORDERS : STR_ORDERS_END_OF_ORDERS;
1122 DrawString(rtl ? ir.left : middle, rtl ? middle : ir.right, y, str, (i == this->selected_order) ? TC_WHITE : TC_BLACK);
1123 }
1124 }
1125
1126 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
1127 {
1128 switch (widget) {
1129 case WID_O_COND_VALUE: {
1130 VehicleOrderID sel = this->OrderGetSel();
1131 const Order *order = this->vehicle->GetOrder(sel);
1132
1133 if (order != nullptr && order->IsType(OT_CONDITIONAL)) {
1134 uint value = order->GetConditionValue();
1135 if (order->GetConditionVariable() == OrderConditionVariable::MaxSpeed) value = ConvertSpeedToDisplaySpeed(value, this->vehicle->type);
1136 return GetString(STR_JUST_COMMA, value);
1137 }
1138 return {};
1139 }
1140
1141 case WID_O_CAPTION:
1142 return GetString(STR_ORDERS_CAPTION, this->vehicle->index);
1143
1144 case WID_O_DEPOT_ACTION: {
1145 VehicleOrderID sel = this->OrderGetSel();
1146 const Order *order = this->vehicle->GetOrder(sel);
1147 if (order == nullptr || !order->IsType(OT_GOTO_DEPOT)) return {};
1148
1149 /* Select the current action selected in the dropdown. The flags don't match the dropdown so we can't just use an index. */
1150 if (order->GetDepotOrderType().Test(OrderDepotTypeFlag::Service)) return GetString(STR_ORDER_DROP_SERVICE_DEPOT);
1151 if (order->GetDepotActionType().Test(OrderDepotActionFlag::Halt)) return GetString(STR_ORDER_DROP_HALT_DEPOT);
1152 if (order->GetDepotActionType().Test(OrderDepotActionFlag::Unbunch)) return GetString(STR_ORDER_DROP_UNBUNCH);
1153
1154 return GetString(STR_ORDER_DROP_GO_ALWAYS_DEPOT);
1155 }
1156
1157 default:
1158 return this->Window::GetWidgetString(widget, stringid);
1159 }
1160 }
1161
1162 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1163 {
1164 switch (widget) {
1165 case WID_O_ORDER_LIST: {
1166 if (this->goto_type == OPOS_CONDITIONAL) {
1167 VehicleOrderID order_id = this->GetOrderFromPt(_cursor.pos.y - this->top);
1168 if (order_id != INVALID_VEH_ORDER_ID) {
1169 Order order{};
1170 order.MakeConditional(order_id);
1171
1172 Command<Commands::InsertOrder>::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), order);
1173 }
1175 break;
1176 }
1177
1178 VehicleOrderID sel = this->GetOrderFromPt(pt.y);
1179
1180 if (_ctrl_pressed && sel < this->vehicle->GetNumOrders()) {
1181 TileIndex xy = this->vehicle->GetOrder(sel)->GetLocation(this->vehicle);
1182 if (xy != INVALID_TILE) ScrollMainWindowToTile(xy);
1183 return;
1184 }
1185
1186 /* This order won't be selected any more, close all child windows and dropdowns */
1187 this->CloseChildWindows();
1188
1189 if (sel == INVALID_VEH_ORDER_ID || this->vehicle->owner != _local_company) {
1190 /* Deselect clicked order */
1191 this->selected_order = -1;
1192 } else if (sel == this->selected_order && click_count > 1) {
1193 if (this->vehicle->type == VEH_TRAIN && sel < this->vehicle->GetNumOrders()) {
1194 Command<Commands::ModifyOrder>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER,
1195 this->vehicle->tile, this->vehicle->index, sel,
1197 }
1198 } else {
1199 /* Select clicked order */
1200 this->selected_order = sel;
1201
1202 if (this->vehicle->owner == _local_company) {
1203 /* Activate drag and drop */
1205 }
1206 }
1207
1208 this->UpdateButtonState();
1209 break;
1210 }
1211
1212 case WID_O_SKIP:
1213 this->OrderClick_Skip();
1214 break;
1215
1216 case WID_O_DELETE:
1217 this->OrderClick_Delete();
1218 break;
1219
1220 case WID_O_STOP_SHARING:
1221 this->OrderClick_StopSharing();
1222 break;
1223
1224 case WID_O_NON_STOP:
1225 if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
1226 this->OrderClick_Nonstop(std::nullopt);
1227 } else {
1228 const Order *o = this->vehicle->GetOrder(this->OrderGetSel());
1229 assert(o != nullptr);
1230 ShowDropDownMenu(this, _order_non_stop_dropdown, o->GetNonStopType().base(), WID_O_NON_STOP, 0,
1231 o->IsType(OT_GOTO_STATION) ? 0 : (o->IsType(OT_GOTO_WAYPOINT) ? 3 : 12));
1232 }
1233 break;
1234
1235 case WID_O_GOTO:
1236 if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
1237 if (this->goto_type != OPOS_NONE) {
1239 } else {
1240 this->OrderClick_Goto(OPOS_GOTO);
1241 }
1242 } else {
1243 int sel;
1244 switch (this->goto_type) {
1245 case OPOS_NONE: sel = -1; break;
1246 case OPOS_GOTO: sel = 0; break;
1247 case OPOS_CONDITIONAL: sel = 2; break;
1248 case OPOS_SHARE: sel = 3; break;
1249 default: NOT_REACHED();
1250 }
1251 ShowDropDownMenu(this, this->vehicle->type == VEH_AIRCRAFT ? _order_goto_dropdown_aircraft : _order_goto_dropdown, sel, WID_O_GOTO, 0, 0);
1252 }
1253 break;
1254
1255 case WID_O_FULL_LOAD:
1256 if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
1258 } else {
1259 ShowDropDownMenu(this, _order_full_load_dropdown, to_underlying(this->vehicle->GetOrder(this->OrderGetSel())->GetLoadType()), WID_O_FULL_LOAD, 0, 2);
1260 }
1261 break;
1262
1263 case WID_O_UNLOAD:
1264 if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
1266 } else {
1267 ShowDropDownMenu(this, _order_unload_dropdown, to_underlying(this->vehicle->GetOrder(this->OrderGetSel())->GetUnloadType()), WID_O_UNLOAD, 0, 8);
1268 }
1269 break;
1270
1271 case WID_O_REFIT:
1272 this->OrderClick_Refit(0, false);
1273 break;
1274
1275 case WID_O_DEPOT_ACTION:
1276 ShowDropDownMenu(this, _order_depot_action_dropdown, to_underlying(DepotActionStringIndex(this->vehicle->GetOrder(this->OrderGetSel()))), WID_O_DEPOT_ACTION, 0, 0);
1277 break;
1278
1280 if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
1281 this->OrderClick_Refit(0, true);
1282 } else {
1283 ShowDropDownMenu(this, _order_refit_action_dropdown, 0, WID_O_REFIT_DROPDOWN, 0, 0);
1284 }
1285 break;
1286
1288 ShowTimetableWindow(this->vehicle);
1289 break;
1290
1291 case WID_O_COND_VARIABLE: {
1292 DropDownList list;
1293 for (const auto &ocv : _order_conditional_variable) {
1294 list.push_back(MakeDropDownListStringItem(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + to_underlying(ocv), to_underlying(ocv)));
1295 }
1296 ShowDropDownList(this, std::move(list), to_underlying(this->vehicle->GetOrder(this->OrderGetSel())->GetConditionVariable()), WID_O_COND_VARIABLE);
1297 break;
1298 }
1299
1300 case WID_O_COND_COMPARATOR: {
1301 const Order *o = this->vehicle->GetOrder(this->OrderGetSel());
1302 assert(o != nullptr);
1304 break;
1305 }
1306
1307 case WID_O_COND_VALUE: {
1308 const Order *order = this->vehicle->GetOrder(this->OrderGetSel());
1309 assert(order != nullptr);
1310 uint value = order->GetConditionValue();
1311 if (order->GetConditionVariable() == OrderConditionVariable::MaxSpeed) value = ConvertSpeedToDisplaySpeed(value, this->vehicle->type);
1312 ShowQueryString(GetString(STR_JUST_INT, value), STR_ORDER_CONDITIONAL_VALUE_CAPT, 5, this, CS_NUMERAL, {});
1313 break;
1314 }
1315
1317 ShowVehicleListWindow(this->vehicle);
1318 break;
1319 }
1320 }
1321
1322 void OnQueryTextFinished(std::optional<std::string> str) override
1323 {
1324 if (!str.has_value() || str->empty()) return;
1325
1326 VehicleOrderID sel = this->OrderGetSel();
1327 auto value = ParseInteger(*str, 10, true);
1328 if (!value.has_value()) return;
1329
1330 switch (this->vehicle->GetOrder(sel)->GetConditionVariable()) {
1332 value = ConvertDisplaySpeedToSpeed(*value, this->vehicle->type);
1333 break;
1334
1337 value = Clamp(*value, 0, 100);
1338 break;
1339
1340 default:
1341 break;
1342 }
1343 Command<Commands::ModifyOrder>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel, MOF_COND_VALUE, Clamp(*value, 0, 2047));
1344 }
1345
1346 void OnDropdownSelect(WidgetID widget, int index, int) override
1347 {
1348 switch (widget) {
1349 case WID_O_NON_STOP:
1350 this->OrderClick_Nonstop(static_cast<OrderNonStopFlags>(index));
1351 break;
1352
1353 case WID_O_FULL_LOAD:
1354 this->OrderClick_FullLoad(static_cast<OrderLoadType>(index));
1355 break;
1356
1357 case WID_O_UNLOAD:
1358 this->OrderClick_Unload(static_cast<OrderUnloadType>(index));
1359 break;
1360
1361 case WID_O_GOTO:
1362 switch (index) {
1363 case 0: this->OrderClick_Goto(OPOS_GOTO); break;
1364 case 1: this->OrderClick_NearestDepot(); break;
1365 case 2: this->OrderClick_Goto(OPOS_CONDITIONAL); break;
1366 case 3: this->OrderClick_Goto(OPOS_SHARE); break;
1367 default: NOT_REACHED();
1368 }
1369 break;
1370
1371 case WID_O_DEPOT_ACTION:
1372 this->OrderClick_Service(static_cast<OrderDepotAction>(index));
1373 break;
1374
1376 this->OrderClick_Refit(index, true);
1377 break;
1378
1380 Command<Commands::ModifyOrder>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), MOF_COND_VARIABLE, index);
1381 break;
1382
1384 Command<Commands::ModifyOrder>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), MOF_COND_COMPARATOR, index);
1385 break;
1386 }
1387 }
1388
1389 void OnDragDrop(Point pt, WidgetID widget) override
1390 {
1391 switch (widget) {
1392 case WID_O_ORDER_LIST: {
1393 VehicleOrderID from_order = this->OrderGetSel();
1394 VehicleOrderID to_order = this->GetOrderFromPt(pt.y);
1395
1396 if (!(from_order == to_order || from_order == INVALID_VEH_ORDER_ID || from_order > this->vehicle->GetNumOrders() || to_order == INVALID_VEH_ORDER_ID || to_order > this->vehicle->GetNumOrders()) &&
1397 Command<Commands::MoveOrder>::Post(STR_ERROR_CAN_T_MOVE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, from_order, to_order)) {
1398 this->selected_order = -1;
1399 this->UpdateButtonState();
1400 }
1401 break;
1402 }
1403
1404 case WID_O_DELETE:
1405 this->OrderClick_Delete();
1406 break;
1407
1408 case WID_O_STOP_SHARING:
1409 this->OrderClick_StopSharing();
1410 break;
1411 }
1412
1414
1415 if (this->order_over != INVALID_VEH_ORDER_ID) {
1416 /* End of drag-and-drop, hide dragged order destination highlight. */
1417 this->order_over = INVALID_VEH_ORDER_ID;
1419 }
1420 }
1421
1422 EventState OnHotkey(int hotkey) override
1423 {
1424 if (this->vehicle->owner != _local_company) return ES_NOT_HANDLED;
1425
1426 switch (hotkey) {
1427 case OHK_SKIP: this->OrderClick_Skip(); break;
1428 case OHK_DELETE: this->OrderClick_Delete(); break;
1429 case OHK_GOTO: this->OrderClick_Goto(OPOS_GOTO); break;
1430 case OHK_NONSTOP: this->OrderClick_Nonstop(std::nullopt); break;
1431 case OHK_FULLLOAD: this->OrderClick_FullLoad(OrderLoadType::FullLoadAny, true); break;
1432 case OHK_UNLOAD: this->OrderClick_Unload(OrderUnloadType::Unload, true); break;
1433 case OHK_NEAREST_DEPOT: this->OrderClick_NearestDepot(); break;
1434 case OHK_ALWAYS_SERVICE: this->OrderClick_Service(std::nullopt); break;
1435 case OHK_TRANSFER: this->OrderClick_Unload(OrderUnloadType::Transfer, true); break;
1436 case OHK_NO_UNLOAD: this->OrderClick_Unload(OrderUnloadType::NoUnload, true); break;
1437 case OHK_NO_LOAD: this->OrderClick_FullLoad(OrderLoadType::NoLoad, true); break;
1438 default: return ES_NOT_HANDLED;
1439 }
1440 return ES_HANDLED;
1441 }
1442
1443 void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
1444 {
1445 if (this->goto_type == OPOS_GOTO) {
1446 const Order cmd = GetOrderCmdFromTile(this->vehicle, tile);
1447 if (cmd.IsType(OT_NOTHING)) return;
1448
1449 if (Command<Commands::InsertOrder>::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), cmd)) {
1450 /* With quick goto the Go To button stays active */
1452 }
1453 }
1454 }
1455
1456 bool OnVehicleSelect(const Vehicle *v) override
1457 {
1458 /* v is vehicle getting orders. Only copy/clone orders if vehicle doesn't have any orders yet.
1459 * We disallow copying orders of other vehicles if we already have at least one order entry
1460 * ourself as it easily copies orders of vehicles within a station when we mean the station.
1461 * Obviously if you press CTRL on a non-empty orders vehicle you know what you are doing
1462 * TODO: give a warning message */
1463 bool share_order = _ctrl_pressed || this->goto_type == OPOS_SHARE;
1464 if (this->vehicle->GetNumOrders() != 0 && !share_order) return false;
1465
1466 if (Command<Commands::CloneOrder>::Post(share_order ? STR_ERROR_CAN_T_SHARE_ORDER_LIST : STR_ERROR_CAN_T_COPY_ORDER_LIST,
1467 this->vehicle->tile, share_order ? CO_SHARE : CO_COPY, this->vehicle->index, v->index)) {
1468 this->selected_order = -1;
1470 }
1471 return true;
1472 }
1473
1480 bool OnVehicleSelect(VehicleList::const_iterator begin, VehicleList::const_iterator end) override
1481 {
1482 bool share_order = _ctrl_pressed || this->goto_type == OPOS_SHARE;
1483 if (this->vehicle->GetNumOrders() != 0 && !share_order) return false;
1484
1485 if (!share_order) {
1486 /* If CTRL is not pressed: If all the vehicles in this list have the same orders, then copy orders */
1487 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
1488 return VehiclesHaveSameOrderList(v1, v2);
1489 })) {
1490 OnVehicleSelect(*begin);
1491 } else {
1492 ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_COPY_ORDER_LIST), GetEncodedString(STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST), WL_INFO);
1493 }
1494 } else {
1495 /* If CTRL is pressed: If all the vehicles in this list share orders, then copy orders */
1496 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
1497 return v1->FirstShared() == v2->FirstShared();
1498 })) {
1499 OnVehicleSelect(*begin);
1500 } else {
1501 ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_SHARE_ORDER_LIST), GetEncodedString(STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST), WL_INFO);
1502 }
1503 }
1504
1505 return true;
1506 }
1507
1508 void OnPlaceObjectAbort() override
1509 {
1510 this->goto_type = OPOS_NONE;
1512
1513 /* Remove drag highlighting if it exists. */
1514 if (this->order_over != INVALID_VEH_ORDER_ID) {
1515 this->order_over = INVALID_VEH_ORDER_ID;
1517 }
1518 }
1519
1520 void OnMouseDrag(Point pt, WidgetID widget) override
1521 {
1522 if (this->selected_order != -1 && widget == WID_O_ORDER_LIST) {
1523 /* An order is dragged.. */
1524 VehicleOrderID from_order = this->OrderGetSel();
1525 VehicleOrderID to_order = this->GetOrderFromPt(pt.y);
1526 uint num_orders = this->vehicle->GetNumOrders();
1527
1528 if (from_order != INVALID_VEH_ORDER_ID && from_order <= num_orders) {
1529 if (to_order != INVALID_VEH_ORDER_ID && to_order <= num_orders) { // ..over an existing order.
1530 this->order_over = to_order;
1531 this->SetWidgetDirty(widget);
1532 } else if (from_order != to_order && this->order_over != INVALID_VEH_ORDER_ID) { // ..outside of the order list.
1533 this->order_over = INVALID_VEH_ORDER_ID;
1534 this->SetWidgetDirty(widget);
1535 }
1536 }
1537 }
1538 }
1539
1540 void OnResize() override
1541 {
1542 /* Update the scroll bar */
1543 this->vscroll->SetCapacityFromWidget(this, WID_O_ORDER_LIST, WidgetDimensions::scaled.framerect.Vertical());
1544 }
1545
1546 static inline HotkeyList hotkeys{"order", {
1547 Hotkey('D', "skip", OHK_SKIP),
1548 Hotkey('F', "delete", OHK_DELETE),
1549 Hotkey('G', "goto", OHK_GOTO),
1550 Hotkey('H', "nonstop", OHK_NONSTOP),
1551 Hotkey('J', "fullload", OHK_FULLLOAD),
1552 Hotkey('K', "unload", OHK_UNLOAD),
1553 Hotkey(0, "nearest_depot", OHK_NEAREST_DEPOT),
1554 Hotkey(0, "always_service", OHK_ALWAYS_SERVICE),
1555 Hotkey(0, "transfer", OHK_TRANSFER),
1556 Hotkey(0, "no_unload", OHK_NO_UNLOAD),
1557 Hotkey(0, "no_load", OHK_NO_LOAD),
1558 }};
1559};
1560
1562static constexpr std::initializer_list<NWidgetPart> _nested_orders_train_widgets = {
1564 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1565 NWidget(WWT_CAPTION, COLOUR_GREY, WID_O_CAPTION),
1566 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_TIMETABLE_VIEW), SetMinimalSize(61, 14), SetStringTip(STR_ORDERS_TIMETABLE_VIEW, STR_ORDERS_TIMETABLE_VIEW_TOOLTIP),
1567 NWidget(WWT_SHADEBOX, COLOUR_GREY),
1568 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
1569 NWidget(WWT_STICKYBOX, COLOUR_GREY),
1570 EndContainer(),
1572 NWidget(WWT_PANEL, COLOUR_GREY, WID_O_ORDER_LIST), SetMinimalSize(372, 62), SetToolTip(STR_ORDERS_LIST_TOOLTIP), SetResize(1, 1), SetScrollbar(WID_O_SCROLLBAR), EndContainer(),
1574 EndContainer(),
1575
1576 /* First button row. */
1580 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_NON_STOP), SetMinimalSize(93, 12), SetFill(1, 0),
1581 SetStringTip(STR_ORDER_NON_STOP, STR_ORDER_TOOLTIP_NON_STOP), SetResize(1, 0),
1582 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_TOP_LEFT),
1583 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_FULL_LOAD), SetMinimalSize(93, 12), SetFill(1, 0),
1584 SetStringTip(STR_ORDER_TOGGLE_FULL_LOAD, STR_ORDER_TOOLTIP_FULL_LOAD), SetResize(1, 0),
1585 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_REFIT), SetMinimalSize(93, 12), SetFill(1, 0),
1586 SetStringTip(STR_ORDER_REFIT, STR_ORDER_REFIT_TOOLTIP), SetResize(1, 0),
1587 EndContainer(),
1589 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_UNLOAD), SetMinimalSize(93, 12), SetFill(1, 0),
1590 SetStringTip(STR_ORDER_TOGGLE_UNLOAD, STR_ORDER_TOOLTIP_UNLOAD), SetResize(1, 0),
1592 SetStringTip(STR_JUST_STRING), SetResize(1, 0),
1593 EndContainer(),
1594 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_TOP_RIGHT),
1595 NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(93, 12), SetFill(1, 0), SetResize(1, 0), EndContainer(),
1597 SetStringTip(STR_ORDER_REFIT_AUTO, STR_ORDER_REFIT_AUTO_TOOLTIP), SetResize(1, 0),
1598 EndContainer(),
1599 EndContainer(),
1601 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_VARIABLE), SetMinimalSize(124, 12), SetFill(1, 0),
1602 SetToolTip(STR_ORDER_CONDITIONAL_VARIABLE_TOOLTIP), SetResize(1, 0),
1603 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_COMPARATOR), SetMinimalSize(124, 12), SetFill(1, 0),
1604 SetToolTip(STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP), SetResize(1, 0),
1605 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_COND_VALUE), SetMinimalSize(124, 12), SetFill(1, 0),
1606 SetToolTip(STR_ORDER_CONDITIONAL_VALUE_TOOLTIP), SetResize(1, 0),
1607 EndContainer(),
1608 EndContainer(),
1609 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_O_SHARED_ORDER_LIST), SetAspect(1), SetSpriteTip(SPR_SHARED_ORDERS_ICON, STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP),
1610 EndContainer(),
1611
1612 /* Second button row. */
1615 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_SKIP), SetMinimalSize(124, 12), SetFill(1, 0),
1616 SetStringTip(STR_ORDERS_SKIP_BUTTON, STR_ORDERS_SKIP_TOOLTIP), SetResize(1, 0),
1618 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_DELETE), SetMinimalSize(124, 12), SetFill(1, 0),
1619 SetStringTip(STR_ORDERS_DELETE_BUTTON, STR_ORDERS_DELETE_TOOLTIP), SetResize(1, 0),
1620 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_STOP_SHARING), SetMinimalSize(124, 12), SetFill(1, 0),
1621 SetStringTip(STR_ORDERS_STOP_SHARING_BUTTON, STR_ORDERS_STOP_SHARING_TOOLTIP), SetResize(1, 0),
1622 EndContainer(),
1623 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_GOTO), SetMinimalSize(124, 12), SetFill(1, 0),
1624 SetStringTip(STR_ORDERS_GO_TO_BUTTON, STR_ORDERS_GO_TO_TOOLTIP), SetResize(1, 0),
1625 EndContainer(),
1626 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
1627 EndContainer(),
1628};
1629
1630static WindowDesc _orders_train_desc(
1631 WDP_AUTO, "view_vehicle_orders_train", 384, 100,
1635 &OrdersWindow::hotkeys
1636);
1637
1639static constexpr std::initializer_list<NWidgetPart> _nested_orders_widgets = {
1641 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1642 NWidget(WWT_CAPTION, COLOUR_GREY, WID_O_CAPTION), SetStringTip(STR_ORDERS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1643 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_TIMETABLE_VIEW), SetMinimalSize(61, 14), SetStringTip(STR_ORDERS_TIMETABLE_VIEW, STR_ORDERS_TIMETABLE_VIEW_TOOLTIP),
1644 NWidget(WWT_SHADEBOX, COLOUR_GREY),
1645 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
1646 NWidget(WWT_STICKYBOX, COLOUR_GREY),
1647 EndContainer(),
1649 NWidget(WWT_PANEL, COLOUR_GREY, WID_O_ORDER_LIST), SetMinimalSize(372, 62), SetToolTip(STR_ORDERS_LIST_TOOLTIP), SetResize(1, 1), SetScrollbar(WID_O_SCROLLBAR), EndContainer(),
1651 EndContainer(),
1652
1653 /* First button row. */
1655 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_TOP_ROW),
1656 /* Load + unload + refit buttons. */
1658 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_FULL_LOAD), SetMinimalSize(124, 12), SetFill(1, 0),
1659 SetStringTip(STR_ORDER_TOGGLE_FULL_LOAD, STR_ORDER_TOOLTIP_FULL_LOAD), SetResize(1, 0),
1660 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_UNLOAD), SetMinimalSize(124, 12), SetFill(1, 0),
1661 SetStringTip(STR_ORDER_TOGGLE_UNLOAD, STR_ORDER_TOOLTIP_UNLOAD), SetResize(1, 0),
1663 SetStringTip(STR_ORDER_REFIT_AUTO, STR_ORDER_REFIT_AUTO_TOOLTIP), SetResize(1, 0),
1664 EndContainer(),
1665 /* Refit + service buttons. */
1667 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_REFIT), SetMinimalSize(186, 12), SetFill(1, 0),
1668 SetStringTip(STR_ORDER_REFIT, STR_ORDER_REFIT_TOOLTIP), SetResize(1, 0),
1670 SetResize(1, 0),
1671 EndContainer(),
1672
1673 /* Buttons for setting a condition. */
1675 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_VARIABLE), SetMinimalSize(124, 12), SetFill(1, 0),
1676 SetToolTip(STR_ORDER_CONDITIONAL_VARIABLE_TOOLTIP), SetResize(1, 0),
1677 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_COMPARATOR), SetMinimalSize(124, 12), SetFill(1, 0),
1678 SetToolTip(STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP), SetResize(1, 0),
1679 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_COND_VALUE), SetMinimalSize(124, 12), SetFill(1, 0),
1680 SetStringTip(STR_JUST_COMMA, STR_ORDER_CONDITIONAL_VALUE_TOOLTIP), SetResize(1, 0),
1681 EndContainer(),
1682 EndContainer(),
1683
1684 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_O_SHARED_ORDER_LIST), SetAspect(1), SetSpriteTip(SPR_SHARED_ORDERS_ICON, STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP),
1685 EndContainer(),
1686
1687 /* Second button row. */
1689 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_SKIP), SetMinimalSize(124, 12), SetFill(1, 0),
1690 SetStringTip(STR_ORDERS_SKIP_BUTTON, STR_ORDERS_SKIP_TOOLTIP), SetResize(1, 0),
1692 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_DELETE), SetMinimalSize(124, 12), SetFill(1, 0),
1693 SetStringTip(STR_ORDERS_DELETE_BUTTON, STR_ORDERS_DELETE_TOOLTIP), SetResize(1, 0),
1694 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_STOP_SHARING), SetMinimalSize(124, 12), SetFill(1, 0),
1695 SetStringTip(STR_ORDERS_STOP_SHARING_BUTTON, STR_ORDERS_STOP_SHARING_TOOLTIP), SetResize(1, 0),
1696 EndContainer(),
1697 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_GOTO), SetMinimalSize(124, 12), SetFill(1, 0),
1698 SetStringTip(STR_ORDERS_GO_TO_BUTTON, STR_ORDERS_GO_TO_TOOLTIP), SetResize(1, 0),
1699 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
1700 EndContainer(),
1701};
1702
1703static WindowDesc _orders_desc(
1704 WDP_AUTO, "view_vehicle_orders", 384, 100,
1708 &OrdersWindow::hotkeys
1709);
1710
1712static constexpr std::initializer_list<NWidgetPart> _nested_other_orders_widgets = {
1714 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1715 NWidget(WWT_CAPTION, COLOUR_GREY, WID_O_CAPTION), SetStringTip(STR_ORDERS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1716 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_TIMETABLE_VIEW), SetMinimalSize(61, 14), SetStringTip(STR_ORDERS_TIMETABLE_VIEW, STR_ORDERS_TIMETABLE_VIEW_TOOLTIP),
1717 NWidget(WWT_SHADEBOX, COLOUR_GREY),
1718 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
1719 NWidget(WWT_STICKYBOX, COLOUR_GREY),
1720 EndContainer(),
1722 NWidget(WWT_PANEL, COLOUR_GREY, WID_O_ORDER_LIST), SetMinimalSize(372, 72), SetToolTip(STR_ORDERS_LIST_TOOLTIP), SetResize(1, 1), SetScrollbar(WID_O_SCROLLBAR), EndContainer(),
1725 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
1726 EndContainer(),
1727 EndContainer(),
1728};
1729
1730static WindowDesc _other_orders_desc(
1731 WDP_AUTO, "view_vehicle_orders_competitor", 384, 86,
1735 &OrdersWindow::hotkeys
1736);
1737
1738void ShowOrdersWindow(const Vehicle *v)
1739{
1742 if (BringWindowToFrontById(WC_VEHICLE_ORDERS, v->index) != nullptr) return;
1743
1744 /* Using a different WindowDescs for _local_company causes problems.
1745 * Due to this we have to close order windows in ChangeWindowOwner/CloseCompanyWindows,
1746 * because we cannot change switch the WindowDescs and keeping the old WindowDesc results
1747 * in crashed due to missing widget.
1748 * TODO Rewrite the order GUI to not use different WindowDescs.
1749 */
1750 if (v->owner != _local_company) {
1751 new OrdersWindow(_other_orders_desc, v);
1752 } else {
1753 new OrdersWindow(v->IsGroundVehicle() ? _orders_train_desc : _orders_desc, v);
1754 }
1755}
Base for aircraft.
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
static const CargoType CARGO_AUTO_REFIT
Automatically choose cargo type when doing auto refitting.
Definition cargo_type.h:76
static const CargoType CARGO_NO_REFIT
Do not refit cargo of a vehicle (used in vehicle orders and auto-replace/auto-renew).
Definition cargo_type.h:77
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Tstorage base() const noexcept
Retrieve the raw value behind this bit set.
constexpr Timpl & Flip(Tvalue_type value)
Flip the value-th bit.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Enum-as-bit-set wrapper.
Base class for a 'real' widget.
void SetStringTip(StringID string, StringID tool_tip)
Set string and tool tip of the nested widget.
Definition widget.cpp:1164
Stacked widgets, widgets all occupying the same space in the window.
bool SetDisplayedPlane(int plane)
Select which plane to show (for NWID_SELECTION only).
Definition widget.cpp:1422
Scrollbar data structure.
bool IsVisible(size_type item) const
Checks whether given current item is visible in the list.
void SetCount(size_t num)
Sets the number of elements in the list.
size_type GetScrolledRowFromWidget(int clickpos, const Window *const w, WidgetID widget, int padding=0, int line_height=-1) const
Compute the row of a scrolled widget that a user clicked in.
Definition widget.cpp:2425
void SetCapacityFromWidget(Window *w, WidgetID widget, int padding=0)
Set capacity of visible elements from the size and resize properties of a widget.
Definition widget.cpp:2499
void ScrollTowards(size_type position)
Scroll towards the given position; if the item is visible nothing happens, otherwise it will be shown...
size_type GetPosition() const
Gets the position of the first visible element in the list.
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:30
Functions related to commands.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Command definitions related to companies.
Functions related to companies.
static constexpr Owner OWNER_NONE
The tile has no ownership.
Map related accessors for depots.
bool IsDepotTypeTile(Tile tile, TransportType type)
Check if a tile is a depot and it is a depot of the given type.
Definition depot_map.h:19
DestinationID GetDepotDestinationIndex(Tile t)
Get the destination index of a 'depot'.
Definition depot_map.h:66
void ShowDropDownMenu(Window *w, std::span< const StringID > strings, int selected, WidgetID button, uint32_t disabled_mask, uint32_t hidden_mask, uint width)
Show a dropdown menu window near a widget of the parent window.
Definition dropdown.cpp:458
void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, DropDownOptions options)
Show a drop down list.
Definition dropdown.cpp:418
Functions related to the drop down widget.
Types related to the drop down widget.
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
bool IsEngineRefittable(EngineID engine)
Check if an engine is refittable.
Definition engine.cpp:1291
Functions related to engines.
@ AutoRefit
Automatic refitting is allowed.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
Definition enum_type.hpp:17
Functions related to errors.
@ WL_INFO
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
Definition error.h:24
void ShowErrorMessage(EncodedString &&summary_msg, int x, int y, CommandCost &cc)
Display an error message in a window.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:87
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Geometry functions.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition gfx.cpp:968
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:897
Dimension GetStringListBoundingBox(std::span< const StringID > list, FontSize fontsize)
Get maximum dimension of a list of strings.
Definition gfx.cpp:935
int DrawString(int left, int right, int top, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition gfx.cpp:668
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:38
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition gfx.cpp:1034
void GfxFillRect(int left, int top, int right, int bottom, const std::variant< PixelColour, PaletteID > &colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen.
Definition gfx.cpp:115
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:249
@ SA_RIGHT
Right align the text (must be a single bit).
Definition gfx_type.h:390
@ SA_FORCE
Force the alignment, i.e. don't swap for RTL languages.
Definition gfx_type.h:400
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition gfx_type.h:307
@ TC_NO_SHADE
Do not add shading to this text colour.
Definition gfx_type.h:331
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
constexpr NWidgetPart SetSpriteTip(SpriteID sprite, StringID tip={})
Widget part function for setting the sprite and tooltip.
constexpr NWidgetPart SetScrollbar(WidgetID index)
Attach a scrollbar to a widget.
constexpr NWidgetPart SetStringTip(StringID string, StringID tip={})
Widget part function for setting the string and tooltip.
constexpr NWidgetPart SetAspect(float ratio, AspectFlags flags=AspectFlag::ResizeX)
Widget part function for setting the aspect ratio.
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
constexpr NWidgetPart SetToolTip(StringID tip)
Widget part function for setting tooltip and clearing the widget data.
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=INVALID_WIDGET)
Widget part function for starting a new 'real' widget.
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition window.cpp:968
Hotkey related functions.
Base of all industries.
constexpr bool IsInsideBS(const T x, const size_t base, const size_t size)
Checks if a value is between a window started at some base point.
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
void ShowQueryString(std::string_view str, StringID caption, uint maxsize, Window *parent, CharSetFilter afilter, QueryStringFlags flags)
Show a query popup window with a textbox in it.
bool _networking
are we in networking mode?
Definition network.cpp:66
Basic functions/variables used all over the place.
uint GetOrderDistance(VehicleOrderID prev, VehicleOrderID cur, const Vehicle *v, int conditional_depth)
Get the distance between two orders of a vehicle.
Command definitions related to orders.
static constexpr std::initializer_list< NWidgetPart > _nested_orders_widgets
Nested widget definition for "your" orders (non-train).
static constexpr std::initializer_list< NWidgetPart > _nested_other_orders_widgets
Nested widget definition for competitor orders.
uint ConvertSpeedToDisplaySpeed(uint speed, VehicleType type)
Convert the given (internal) speed to the display speed.
Definition strings.cpp:968
static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile)
Get the order command a vehicle can do in a given tile.
static const OrderConditionVariable _order_conditional_variable[]
Variables for conditional orders; this defines the order of appearance in the dropdown box.
OrderHotKeys
Hotkeys for order window.
static const StringID _station_load_types[][5][5]
Order load types that could be given to station orders.
Definition order_gui.cpp:47
static constexpr std::initializer_list< NWidgetPart > _nested_orders_train_widgets
Nested widget definition for "your" train orders.
uint ConvertDisplaySpeedToSpeed(uint speed, VehicleType type)
Convert the given display speed to the (internal) speed.
Definition strings.cpp:981
void DrawOrderString(const Vehicle *v, const Order *order, VehicleOrderID order_index, int y, bool selected, bool timetable, int left, int middle, int right)
Draws an order in order or timetable GUI.
OrderUnloadType
Unloading order types.
Definition order_type.h:67
@ Transfer
Transfer all cargo onto the platform.
@ UnloadIfPossible
Unload all cargo that the station accepts.
@ NoUnload
Totally no unloading will be done.
@ Unload
Force unloading all cargo onto the platform, possibly not getting paid.
OrderConditionVariable
Variables (of a vehicle) to 'cause' skipping on.
Definition order_type.h:128
@ Unconditionally
Always skip.
@ MaxSpeed
Skip based on the maximum speed.
@ Reliability
Skip based on the reliability.
@ MaxReliability
Skip based on the maximum reliability.
@ RequiresService
Skip when the vehicle requires service.
@ LoadPercentage
Skip based on the amount of load.
@ Age
Skip based on the age.
@ RemainingLifetime
Skip based on the remaining lifetime.
OrderStopLocation
Where to stop the trains.
Definition order_type.h:97
@ End
End marker.
@ FarEnd
Stop at the far end of the platform.
@ MOF_COND_VARIABLE
A conditional variable changes.
Definition order_type.h:165
@ MOF_LOAD
Passes an OrderLoadType.
Definition order_type.h:163
@ MOF_UNLOAD
Passes an OrderUnloadType.
Definition order_type.h:162
@ MOF_STOP_LOCATION
Passes an OrderStopLocation.
Definition order_type.h:161
@ MOF_COND_COMPARATOR
A comparator changes.
Definition order_type.h:166
@ MOF_COND_VALUE
The value to set the condition to.
Definition order_type.h:167
@ MOF_DEPOT_ACTION
Selects the OrderDepotAction.
Definition order_type.h:164
@ MOF_NON_STOP
Passes an OrderNonStopFlags.
Definition order_type.h:160
OrderDepotAction
Depot action to switch to when doing a MOF_DEPOT_ACTION.
Definition order_type.h:175
@ Stop
Go to the depot and stop there.
@ AlwaysGo
Always go to the depot.
@ Service
Service only if needed.
@ Unbunch
Go to the depot and unbunch.
@ NoDestination
The vehicle will stop at any station it passes except the destination, aka via.
@ NoIntermediate
The vehicle will not stop at any stations it passes except the destination, aka non-stop.
uint8_t VehicleOrderID
The index of an order within its current vehicle (not pool related)
Definition order_type.h:18
OrderLoadType
Loading order types.
Definition order_type.h:77
@ NoLoad
Do not load anything.
@ FullLoadAny
Full load a single cargo of the consist.
@ LoadIfPossible
Load as long as there is cargo that fits in the train.
@ Halt
Service the vehicle and then halt it.
@ NearestDepot
Send the vehicle to the nearest depot.
@ Unbunch
Service the vehicle and then unbunch it.
@ PartOfOrders
This depot order is because of a regular order.
@ Service
This depot order is because of the servicing limit.
static const VehicleOrderID INVALID_VEH_ORDER_ID
Invalid vehicle order index (sentinel)
Definition order_type.h:39
OrderConditionComparator
Comparator for the skip reasoning.
Definition order_type.h:143
@ IsTrue
Skip if the variable is true.
@ IsFalse
Skip if the variable is false.
Types related to the order widgets.
@ WID_O_TIMETABLE_VIEW
Toggle timetable view.
@ WID_O_SHARED_ORDER_LIST
Open list of shared vehicles.
@ WID_O_SKIP
Skip current order.
@ WID_O_SCROLLBAR
Order list scrollbar.
@ WID_O_SEL_TOP_MIDDLE
NWID_SELECTION widget for middle part of the top 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_REFIT
Select refit.
@ WID_O_ORDER_LIST
Order list panel.
@ WID_O_COND_VARIABLE
Choose condition variable.
@ WID_O_SEL_TOP_ROW
NWID_SELECTION widget for the top row of the 'your non-trains' order window.
@ WID_O_DELETE
Delete selected order.
@ WID_O_STOP_SHARING
Stop sharing orders.
@ WID_O_COND_COMPARATOR
Choose condition type.
@ WID_O_CAPTION
Caption of the window.
@ WID_O_UNLOAD
Select unload.
@ WID_O_SEL_TOP_LEFT
NWID_SELECTION widget for left part of the top row of the 'your train' order window.
@ WID_O_DEPOT_ACTION
Dropdown to select the depot action (stop, service if needed, unbunch).
@ WID_O_REFIT_DROPDOWN
Open refit options.
@ WID_O_SEL_TOP_RIGHT
NWID_SELECTION widget for right part of the top row of the 'your train' order window.
@ WID_O_NON_STOP
Goto non-stop to destination.
@ WID_O_COND_VALUE
Choose condition value.
@ WID_O_FULL_LOAD
Select full load.
@ WID_O_SEL_TOP_ROW_GROUNDVEHICLE
NWID_SELECTION widget for the top row of the 'your train' order window.
@ WID_O_GOTO
Goto destination.
PixelColour GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition palette.cpp:388
Road vehicle states.
A number of safeguards to prevent using unsafe methods.
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
static const CursorID ANIMCURSOR_PICKSTATION
716 - 718 - goto-order icon
Definition sprites.h:1525
static const CursorID SPR_CURSOR_MOUSE
Cursor sprite numbers.
Definition sprites.h:1404
Base classes/functions for stations.
bool IsRailWaypointTile(Tile t)
Is this tile a station tile and a rail waypoint?
StationID GetStationIndex(Tile t)
Get StationID from a tile.
Definition station_map.h:28
bool IsRoadWaypointTile(Tile t)
Is this tile a station tile and a road waypoint?
bool IsBuoyTile(Tile t)
Is tile t a buoy tile?
@ Dock
Station with a dock.
@ TruckStop
Station with truck stops.
@ Train
Station with train station.
@ Airport
Station with an airport.
@ BusStop
Station with bus stops.
Definition of base types and functions in a cross-platform compatible way.
Parse strings.
static std::optional< T > ParseInteger(std::string_view arg, int base=10, bool clamp=false)
Change a string into its number representation.
Functions related to low-level strings.
@ CS_NUMERAL
Only numeric ones.
Definition string_type.h:26
uint64_t GetParamMaxValue(uint64_t max_value, uint min_count, FontSize size)
Get some number that is suitable for string size computations.
Definition strings.cpp:236
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:424
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:56
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
@ TD_RTL
Text is written right-to-left by default.
uint32_t cached_max_range_sqr
Cached squared maximum range.
Definition aircraft.h:66
uint16_t GetRange() const
Get the range of this aircraft.
Definition aircraft.h:133
VehicleOrderID cur_real_order_index
The index to the current real (non-implicit) order.
VehicleOrderID cur_implicit_order_index
The index to the current implicit order.
StationFacilities facilities
The facilities that this station has.
Owner owner
The owner of this station.
static BaseStation * GetByTile(TileIndex tile)
Get the base station belonging to a specific tile.
VehicleType type
Type of vehicle.
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo type.
Definition cargotype.h:137
StringID name
Name of this type of cargo.
Definition cargotype.h:91
GUISettings gui
settings related to the GUI
T y
Y coordinate.
Point pos
logical mouse position
Definition gfx_type.h:125
Dimensions (a width and height) of a rectangle in 2D.
bool new_nonstop
ttdpatch compatible nonstop handling
bool quick_goto
Allow quick access to 'goto button' in vehicle orders window.
OrderStopLocation stop_location
what is the default stop location of trains?
List of hotkeys for a window.
Definition hotkeys.h:37
All data for a single hotkey.
Definition hotkeys.h:21
Defines the internal data of a functional industry.
Definition industry.h:62
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:251
Station * neutral_station
Associated neutral station.
Definition industry.h:108
VehicleOrderID GetNext(VehicleOrderID cur) const
Get the order after the given one or the first one, if the given one is the last one.
Definition order_base.h:363
TileIndex GetLocation(const Vehicle *v, bool airport=false) const
Returns a tile somewhat representing the order destination (not suitable for pathfinding).
bool IsGotoOrder() const
Is this a 'goto' order with a real destination?
Definition order_base.h:89
OrderDepotTypeFlags GetDepotOrderType() const
What caused us going to the depot?
Definition order_base.h:150
OrderConditionVariable GetConditionVariable() const
What variable do we have to compare?
Definition order_base.h:154
DestinationID GetDestination() const
Gets the destination of this order.
Definition order_base.h:99
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition order_base.h:66
void SetNonStopType(OrderNonStopFlags non_stop_type)
Set whether we must stop at stations or not.
Definition order_base.h:167
VehicleOrderID GetConditionSkipToOrder() const
Get the order to skip to.
Definition order_base.h:158
OrderStopLocation GetStopLocation() const
Where must we stop at the platform?
Definition order_base.h:148
uint16_t GetWaitTime() const
Get the time in ticks a vehicle will probably wait at the destination (timetabled or not).
Definition order_base.h:198
CargoType GetRefitCargo() const
Get the cargo to to refit to.
Definition order_base.h:127
OrderType GetType() const
Get the type of order of this order.
Definition order_base.h:72
void MakeGoToStation(StationID destination)
Makes this order a Go To Station order.
Definition order_cmd.cpp:58
void SetStopLocation(OrderStopLocation stop_location)
Set where we must stop at the platform.
Definition order_base.h:169
void MakeGoToWaypoint(StationID destination)
Makes this order a Go To Waypoint order.
Definition order_cmd.cpp:87
OrderUnloadType GetUnloadType() const
How must the consist be unloaded?
Definition order_base.h:144
void MakeGoToDepot(DestinationID destination, OrderDepotTypeFlags order, OrderNonStopFlags non_stop_type=OrderNonStopFlag::NoIntermediate, OrderDepotActionFlags action={}, CargoType cargo=CARGO_NO_REFIT)
Makes this order a Go To Depot order.
Definition order_cmd.cpp:73
bool IsWaitTimetabled() const
Does this order have an explicit wait time set?
Definition order_base.h:189
void MakeConditional(VehicleOrderID order)
Makes this order an conditional order.
void SetDepotActionType(OrderDepotActionFlags depot_service_type)
Set what we are going to do in the depot.
Definition order_base.h:173
OrderLoadType GetLoadType() const
How must the consist be loaded?
Definition order_base.h:142
OrderDepotActionFlags GetDepotActionType() const
What are we going to do when in the depot.
Definition order_base.h:152
void Free()
'Free' the order
Definition order_cmd.cpp:47
void SetLoadType(OrderLoadType load_type)
Set how the consist must be loaded.
Definition order_base.h:163
bool IsAutoRefit() const
Is this order a auto-refit order.
Definition order_base.h:120
OrderConditionComparator GetConditionComparator() const
What is the comparator to use?
Definition order_base.h:156
OrderNonStopFlags GetNonStopType() const
At which stations must we stop?
Definition order_base.h:146
bool IsRefit() const
Is this order a refit order.
Definition order_base.h:113
uint16_t GetConditionValue() const
Get the value to base the skip on.
Definition order_base.h:160
Order window code for all vehicles.
void OrderClick_Refit(int i, bool auto_refit)
Handle the click on the refit button.
void OnDropdownSelect(WidgetID widget, int index, int) override
A dropdown option associated to this window has been selected.
void OrderClick_Delete()
Handle the click on the delete button.
void OnResize() override
Called after the window got resized.
void OrderClick_Skip()
Handle the click on the skip button.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
bool OnVehicleSelect(VehicleList::const_iterator begin, VehicleList::const_iterator end) override
Clones an order list from a vehicle list.
void OrderClick_FullLoad(OrderLoadType load_type, bool toggle=false)
Handle the click on the full load button.
const Vehicle * vehicle
Vehicle owning the orders being displayed and manipulated.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
bool can_do_refit
Vehicle chain can be refitted in depot.
EventState OnHotkey(int hotkey) override
A hotkey has been pressed.
DisplayPane
Displayed planes of the NWID_SELECTION widgets.
@ DP_BOTTOM_MIDDLE_DELETE
Display 'delete' in the middle button of the bottom row of the vehicle order window.
@ DP_ROW_CONDITIONAL
Display the conditional order buttons in the top row of the ship/airplane order window.
@ DP_ROW_DEPOT
Display 'refit' / 'service' buttons in the top row of the ship/airplane order window.
@ DP_BOTTOM_MIDDLE_STOP_SHARING
Display 'stop sharing' in the middle button of the bottom row of the vehicle order window.
@ DP_MIDDLE_UNLOAD
Display 'unload' in the middle button of the top row of the train/rv order window.
@ DP_LEFT_LOAD
Display 'load' in the left button of the top row of the train/rv order window.
@ DP_RIGHT_EMPTY
Display an empty panel in the right button of the top row of the train/rv order window.
@ DP_RIGHT_REFIT
Display 'refit' in the right button of the top row of the train/rv order window.
@ DP_ROW_LOAD
Display 'load' / 'unload' / 'refit' buttons in the top row of the ship/airplane order window.
@ DP_MIDDLE_SERVICE
Display 'service' in the middle button of the top row of the train/rv order window.
@ DP_GROUNDVEHICLE_ROW_CONDITIONAL
Display the row for conditional orders in the top row of the train/rv order window.
@ DP_LEFT_REFIT
Display 'refit' in the left button of the top row of the train/rv order window.
@ DP_GROUNDVEHICLE_ROW_NORMAL
Display the row for normal/depot orders in the top row of the train/rv order window.
void OrderClick_NearestDepot()
Handle the click on the service in nearest depot button.
void OrderClick_StopSharing()
Handle the click on the 'stop sharing' button.
VehicleOrderID OrderGetSel() const
Return the memorised selected order.
void UpdateAutoRefitState()
Cache auto-refittability of the vehicle chain.
void OnPaint() override
The window must be repainted.
void OnDragDrop(Point pt, WidgetID widget) override
A dragged 'object' has been released.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
void OnMouseDrag(Point pt, WidgetID widget) override
An 'object' is being dragged at the provided position, highlight the target if possible.
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
OrderPlaceObjectState
Under what reason are we using the PlaceObject functionality?
void OrderClick_Unload(OrderUnloadType unload_type, bool toggle=false)
Handle the click on the unload button.
void OnPlaceObject(Point pt, TileIndex tile) override
The user clicked some place on the map when a tile highlight mode has been set.
void OnPlaceObjectAbort() override
The user cancelled a tile highlight mode that has been set.
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
VehicleOrderID GetOrderFromPt(int y)
Calculate the selected order.
void OrderClick_Service(std::optional< OrderDepotAction > i)
Handle the click on the service.
bool can_do_autorefit
Vehicle chain can be auto-refitted.
void OrderClick_Nonstop(std::optional< OrderNonStopFlags > non_stop)
Handle the click on the nonstop button.
void OnQueryTextFinished(std::optional< std::string > str) override
The query window opened from this window has closed.
void OrderClick_Goto(OrderPlaceObjectState type)
Handle the click on the goto button.
VehicleOrderID order_over
Order over which another order is dragged, INVALID_VEH_ORDER_ID if none.
static Titem * Get(auto index)
Returns Titem with given index.
const Tindex index
Index of this pool item.
Specification of a rectangle with absolute coordinates of all edges.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
static Station * Get(auto index)
Gets station with given index.
static Aircraft * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
Station data structure.
Vehicle data structure.
bool IsOrderListShared() const
Check if we share our orders with another vehicle.
Order * GetOrder(int index) const
Returns order 'index' of a vehicle or nullptr when it doesn't exists.
VehicleOrderID GetNumOrders() const
Get the number of orders this vehicle has.
bool IsGroundVehicle() const
Check if the vehicle is a ground vehicle.
OrderList * orders
Pointer to the order list for this vehicle.
Vehicle * NextShared() const
Get the next vehicle of the shared vehicle chain.
Vehicle * PreviousShared() const
Get the previous vehicle of the shared vehicle chain.
Vehicle * FirstShared() const
Get the first vehicle of this vehicle chain.
TileIndex tile
Current tile index.
Owner owner
Which company owns the vehicle?
High level window description.
Definition window_gui.h:168
Data structure for an opened window.
Definition window_gui.h:274
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1809
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:766
void RaiseWidget(WidgetID widget_index)
Marks a widget as raised.
Definition window_gui.h:470
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:558
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:506
void CloseChildWindows(WindowClass wc=WC_INVALID) const
Close all children a window might have in a head-recursive manner.
Definition window.cpp:1077
ResizeInfo resize
Resize information.
Definition window_gui.h:315
void DisableWidget(WidgetID widget_index)
Sets a widget to disabled.
Definition window_gui.h:392
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1799
Owner owner
The owner of the content shown in this window. Company colour is acquired from this variable.
Definition window_gui.h:317
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition window_gui.h:442
void EnableWidget(WidgetID widget_index)
Sets a widget to Enabled.
Definition window_gui.h:401
int top
y position of top edge of the window
Definition window_gui.h:311
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:315
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:382
int width
width of the window (number of pixels to the right in x direction)
Definition window_gui.h:312
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:303
Stuff related to the text buffer GUI.
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
bool IsTileOwner(Tile tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition tile_map.h:214
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:100
@ Station
A tile of a station or airport.
@ Industry
Part of an industry.
Functions related to tile highlights.
void ResetObjectToPlace()
Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows).
void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w)
Change the cursor and mouse click/drag handling to a mode for performing special operations like tile...
HighLightStyle
Highlighting draw styles.
@ HT_DRAG
dragging items in the depot windows
@ HT_NONE
default
@ HT_RECT
rectangle (stations, depots, ...)
@ HT_VEHICLE
vehicle is accepted as target as well (bitmask)
Functions related to time tabling.
void ShowTimetableWindow(const Vehicle *v)
Show the timetable for a given vehicle.
std::pair< StringParameter, StringParameter > GetTimetableParameters(TimerGameTick::Ticks ticks)
Get parameters to format timetable time.
TransportType
Available types of transport.
bool VehiclesHaveSameOrderList(const Vehicle *v1, const Vehicle *v2)
Checks if two vehicles have the same list of orders.
Definition vehicle.cpp:3289
bool CanVehicleUseStation(EngineID engine_type, const Station *st)
Can this station be used by the given engine type?
Definition vehicle.cpp:3058
Functions related to vehicles.
void ShowVehicleRefitWindow(const Vehicle *v, VehicleOrderID order, Window *parent, bool auto_refit)
Show the refit window for a vehicle.
@ VIWD_CONSIST_CHANGED
Vehicle composition was changed.
Definition vehicle_gui.h:37
@ VIWD_AUTOREPLACE
Autoreplace replaced the vehicle.
Definition vehicle_gui.h:38
@ VIWD_MODIFY_ORDERS
Other order modifications.
Definition vehicle_gui.h:36
@ VIWD_REMOVE_ALL_ORDERS
Removed / replaced all orders (after deleting / sharing).
Definition vehicle_gui.h:35
VehicleType
Available vehicle types.
@ VEH_ROAD
Road vehicle type.
@ VEH_AIRCRAFT
Aircraft vehicle type.
@ VEH_SHIP
Ship vehicle type.
@ VEH_TRAIN
Train vehicle type.
Functions and type for generating vehicle lists.
bool ScrollMainWindowToTile(TileIndex tile, bool instant)
Scrolls the viewport of the main window to a given location.
Functions related to (drawing on) viewports.
Base of waypoints.
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
@ NWID_BUTTON_DROPDOWN
Button with a drop-down.
Definition widget_type.h:74
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:66
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:39
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition widget_type.h:57
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition widget_type.h:55
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition widget_type.h:52
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition widget_type.h:76
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:68
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:60
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition widget_type.h:59
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition widget_type.h:56
@ WWT_DROPDOWN
Drop down list.
Definition widget_type.h:61
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:71
@ EqualSize
Containers should keep all their (resizing) children equally large.
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition window.cpp:1195
Window * BringWindowToFrontById(WindowClass cls, WindowNumber number)
Find a window and make it the relative top-window on the screen.
Definition window.cpp:1278
@ Construction
This window is used for construction; close it whenever changing company.
bool AllEqual(It begin, It end, Pred pred)
Generic helper function that checks if all elements of the range are equal with respect to the given ...
Definition window_gui.h:947
@ WDP_AUTO
Find a place automatically.
Definition window_gui.h:144
int WidgetID
Widget ID.
Definition window_type.h:20
EventState
State of handling an event.
@ ES_HANDLED
The passed event is handled.
@ ES_NOT_HANDLED
The passed event is not handled.
@ WC_VEHICLE_ORDERS
Vehicle orders; Window numbers:
@ WC_VEHICLE_DETAILS
Vehicle details; Window numbers:
@ WC_VEHICLE_VIEW
Vehicle view; Window numbers:
@ WC_VEHICLE_TIMETABLE
Vehicle timetable; Window numbers: