OpenTTD Source 20250312-master-gcdcc6b491d
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 <http://www.gnu.org/licenses/>.
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"
37
39
40#include "safeguards.h"
41
42
44static const StringID _station_load_types[][5][5] = {
45 {
46 /* No refitting. */
47 {
50 STR_ORDER_FULL_LOAD,
51 STR_ORDER_FULL_LOAD_ANY,
52 STR_ORDER_NO_LOAD,
53 }, {
54 STR_ORDER_UNLOAD,
56 STR_ORDER_UNLOAD_FULL_LOAD,
57 STR_ORDER_UNLOAD_FULL_LOAD_ANY,
58 STR_ORDER_UNLOAD_NO_LOAD,
59 }, {
60 STR_ORDER_TRANSFER,
62 STR_ORDER_TRANSFER_FULL_LOAD,
63 STR_ORDER_TRANSFER_FULL_LOAD_ANY,
64 STR_ORDER_TRANSFER_NO_LOAD,
65 }, {
66 /* Unload and transfer do not work together. */
72 }, {
73 STR_ORDER_NO_UNLOAD,
75 STR_ORDER_NO_UNLOAD_FULL_LOAD,
76 STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY,
77 STR_ORDER_NO_UNLOAD_NO_LOAD,
78 }
79 }, {
80 /* With auto-refitting. No loading and auto-refitting do not work together. */
81 {
82 STR_ORDER_AUTO_REFIT,
84 STR_ORDER_FULL_LOAD_REFIT,
85 STR_ORDER_FULL_LOAD_ANY_REFIT,
87 }, {
88 STR_ORDER_UNLOAD_REFIT,
90 STR_ORDER_UNLOAD_FULL_LOAD_REFIT,
91 STR_ORDER_UNLOAD_FULL_LOAD_ANY_REFIT,
93 }, {
94 STR_ORDER_TRANSFER_REFIT,
96 STR_ORDER_TRANSFER_FULL_LOAD_REFIT,
97 STR_ORDER_TRANSFER_FULL_LOAD_ANY_REFIT,
99 }, {
100 /* Unload and transfer do not work together. */
106 }, {
107 STR_ORDER_NO_UNLOAD_REFIT,
109 STR_ORDER_NO_UNLOAD_FULL_LOAD_REFIT,
110 STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY_REFIT,
112 }
113 }
114};
115
116static const StringID _order_non_stop_drowdown[] = {
117 STR_ORDER_GO_TO,
118 STR_ORDER_GO_NON_STOP_TO,
119 STR_ORDER_GO_VIA,
120 STR_ORDER_GO_NON_STOP_VIA,
121};
122
123static const StringID _order_full_load_drowdown[] = {
124 STR_ORDER_DROP_LOAD_IF_POSSIBLE,
125 STR_EMPTY,
126 STR_ORDER_DROP_FULL_LOAD_ALL,
127 STR_ORDER_DROP_FULL_LOAD_ANY,
128 STR_ORDER_DROP_NO_LOADING,
129};
130
131static const StringID _order_unload_drowdown[] = {
132 STR_ORDER_DROP_UNLOAD_IF_ACCEPTED,
133 STR_ORDER_DROP_UNLOAD,
134 STR_ORDER_DROP_TRANSFER,
135 STR_EMPTY,
136 STR_ORDER_DROP_NO_UNLOADING,
137};
138
139static const StringID _order_goto_dropdown[] = {
140 STR_ORDER_GO_TO,
141 STR_ORDER_GO_TO_NEAREST_DEPOT,
142 STR_ORDER_CONDITIONAL,
143 STR_ORDER_SHARE,
144};
145
146static const StringID _order_goto_dropdown_aircraft[] = {
147 STR_ORDER_GO_TO,
148 STR_ORDER_GO_TO_NEAREST_HANGAR,
149 STR_ORDER_CONDITIONAL,
150 STR_ORDER_SHARE,
151};
152
164
165static const StringID _order_conditional_condition[] = {
166 STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS,
167 STR_ORDER_CONDITIONAL_COMPARATOR_NOT_EQUALS,
168 STR_ORDER_CONDITIONAL_COMPARATOR_LESS_THAN,
169 STR_ORDER_CONDITIONAL_COMPARATOR_LESS_EQUALS,
170 STR_ORDER_CONDITIONAL_COMPARATOR_MORE_THAN,
171 STR_ORDER_CONDITIONAL_COMPARATOR_MORE_EQUALS,
172 STR_ORDER_CONDITIONAL_COMPARATOR_IS_TRUE,
173 STR_ORDER_CONDITIONAL_COMPARATOR_IS_FALSE,
174};
175
176extern uint ConvertSpeedToDisplaySpeed(uint speed, VehicleType type);
177extern uint ConvertDisplaySpeedToSpeed(uint speed, VehicleType type);
178
179static const StringID _order_depot_action_dropdown[] = {
180 STR_ORDER_DROP_GO_ALWAYS_DEPOT,
181 STR_ORDER_DROP_SERVICE_DEPOT,
182 STR_ORDER_DROP_HALT_DEPOT,
183 STR_ORDER_DROP_UNBUNCH,
184};
185
186static int DepotActionStringIndex(const Order *order)
187{
188 if (order->GetDepotActionType() & ODATFB_HALT) {
189 return DA_STOP;
190 } else if (order->GetDepotOrderType() & ODTFB_SERVICE) {
191 return DA_SERVICE;
192 } else if (order->GetDepotActionType() & ODATFB_UNBUNCH) {
193 return DA_UNBUNCH;
194 } else {
195 return DA_ALWAYS_GO;
196 }
197}
198
199static const StringID _order_refit_action_dropdown[] = {
200 STR_ORDER_DROP_REFIT_AUTO,
201 STR_ORDER_DROP_REFIT_AUTO_ANY,
202};
203
204static StringID GetOrderGoToString(const Order &order)
205{
206 if (order.GetDepotOrderType() & ODTFB_SERVICE) {
207 return (order.GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_SERVICE_NON_STOP_AT : STR_ORDER_SERVICE_AT;
208 } else {
209 return (order.GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_GO_NON_STOP_TO : STR_ORDER_GO_TO;
210 }
211}
212
225void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int y, bool selected, bool timetable, int left, int middle, int right)
226{
227 bool rtl = _current_text_dir == TD_RTL;
228
229 SpriteID sprite = rtl ? SPR_ARROW_LEFT : SPR_ARROW_RIGHT;
230 Dimension sprite_size = GetSpriteSize(sprite);
231 if (v->cur_real_order_index == order_index) {
232 /* Draw two arrows before the next real order. */
233 DrawSprite(sprite, PAL_NONE, rtl ? right - sprite_size.width : left, y + ((int)GetCharacterHeight(FS_NORMAL) - (int)sprite_size.height) / 2);
234 DrawSprite(sprite, PAL_NONE, rtl ? right - 2 * sprite_size.width : left + sprite_size.width, y + ((int)GetCharacterHeight(FS_NORMAL) - (int)sprite_size.height) / 2);
235 } else if (v->cur_implicit_order_index == order_index) {
236 /* Draw one arrow before the next implicit order; the next real order will still get two arrows. */
237 DrawSprite(sprite, PAL_NONE, rtl ? right - sprite_size.width : left, y + ((int)GetCharacterHeight(FS_NORMAL) - (int)sprite_size.height) / 2);
238 }
239
240 TextColour colour = TC_BLACK;
241 if (order->IsType(OT_IMPLICIT)) {
242 colour = (selected ? TC_SILVER : TC_GREY) | TC_NO_SHADE;
243 } else if (selected) {
244 colour = TC_WHITE;
245 }
246
247 DrawString(left, rtl ? right - 2 * sprite_size.width - 3 : middle, y, GetString(STR_ORDER_INDEX, order_index + 1), colour, SA_RIGHT | SA_FORCE);
248
249 std::string line;
250
251 switch (order->GetType()) {
252 case OT_DUMMY:
253 line = GetString(STR_INVALID_ORDER);
254 break;
255
256 case OT_IMPLICIT:
257 line = GetString(STR_ORDER_GO_TO_STATION, STR_ORDER_GO_TO, order->GetDestination());
258 if (!timetable) line += GetString(STR_ORDER_IMPLICIT);
259 break;
260
261 case OT_GOTO_STATION: {
262 OrderLoadFlags load = order->GetLoadType();
263 OrderUnloadFlags unload = order->GetUnloadType();
264 bool valid_station = CanVehicleUseStation(v, Station::Get(order->GetDestination().ToStationID()));
265
266 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() : 0), order->GetDestination());
267 if (timetable) {
268 /* Show only wait time in the timetable window. */
269 if (order->GetWaitTime() > 0) {
270 auto [str, value] = GetTimetableParameters(order->GetWaitTime());
271 line += GetString(order->IsWaitTimetabled() ? STR_TIMETABLE_STAY_FOR : STR_TIMETABLE_STAY_FOR_ESTIMATED, str, value);
272 }
273 } else {
274 /* Show non-stop, refit and stop location only in the order window. */
276 StringID str = _station_load_types[order->IsRefit()][unload][load];
277 if (str != INVALID_STRING_ID) {
278 if (order->IsRefit()) {
279 line += GetString(str, order->IsAutoRefit() ? STR_ORDER_AUTO_REFIT_ANY : CargoSpec::Get(order->GetRefitCargo())->name);
280 } else {
281 line += GetString(str);
282 }
283 }
284 }
285
286 if (v->type == VEH_TRAIN && (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) == 0) {
287 /* Only show the stopping location if other than the default chosen by the player. */
289 line += GetString(STR_ORDER_STOP_LOCATION_NEAR_END + order->GetStopLocation());
290 }
291 }
292 }
293 break;
294 }
295
296 case OT_GOTO_DEPOT:
297 if (!(order->GetDepotActionType() & ODATFB_NEAREST_DEPOT)) {
298 /* Going to a specific depot. */
299 line = GetString(STR_ORDER_GO_TO_DEPOT_FORMAT, GetOrderGoToString(*order), v->type, order->GetDestination());
300 } else if (v->type == VEH_AIRCRAFT) {
301 /* Going to the nearest hangar. */
302 line = GetString(STR_ORDER_GO_TO_NEAREST_HANGAR_FORMAT, GetOrderGoToString(*order));
303 } else {
304 /* Going to the nearest depot. */
305 line = GetString(STR_ORDER_GO_TO_NEAREST_DEPOT_FORMAT, GetOrderGoToString(*order), STR_ORDER_TRAIN_DEPOT + v->type);
306 }
307
308 /* Do not show stopping in the depot in the timetable window. */
309 if (!timetable && (order->GetDepotActionType() & ODATFB_HALT)) {
310 line += GetString(STR_ORDER_STOP_ORDER);
311 }
312
313 /* Do not show refitting in the depot in the timetable window. */
314 if (!timetable && order->IsRefit()) {
315 line += GetString((order->GetDepotActionType() & ODATFB_HALT) ? STR_ORDER_REFIT_STOP_ORDER : STR_ORDER_REFIT_ORDER, CargoSpec::Get(order->GetRefitCargo())->name);
316 }
317
318 /* Show unbunching depot in both order and timetable windows. */
319 if (order->GetDepotActionType() & ODATFB_UNBUNCH) {
320 line += GetString(STR_ORDER_WAIT_TO_UNBUNCH);
321 }
322 break;
323
324 case OT_GOTO_WAYPOINT:
325 line = GetString((order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_GO_NON_STOP_TO_WAYPOINT : STR_ORDER_GO_TO_WAYPOINT, order->GetDestination());
326 break;
327
328 case OT_CONDITIONAL:
330 line = GetString(STR_ORDER_CONDITIONAL_UNCONDITIONAL, order->GetConditionSkipToOrder() + 1);
331 } else {
333
334 uint value = order->GetConditionValue();
335 if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value, v->type);
336
337 line = GetString((occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) ? STR_ORDER_CONDITIONAL_TRUE_FALSE : STR_ORDER_CONDITIONAL_NUM,
338 order->GetConditionSkipToOrder() + 1,
339 STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + order->GetConditionVariable(),
340 STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + occ,
341 value);
342 }
343
344 if (timetable && order->GetWaitTime() > 0) {
345 auto [str, value] = GetTimetableParameters(order->GetWaitTime());
346 line += GetString(order->IsWaitTimetabled() ? STR_TIMETABLE_AND_TRAVEL_FOR : STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED, str, value);
347 }
348 break;
349
350 default: NOT_REACHED();
351 }
352
353 /* Check range for aircraft. */
354 if (v->type == VEH_AIRCRAFT && Aircraft::From(v)->GetRange() > 0 && order->IsGotoOrder()) {
355 const Order *next = order->next != nullptr ? order->next : v->GetFirstOrder();
356 if (GetOrderDistance(order, next, v) > Aircraft::From(v)->acache.cached_max_range_sqr) {
357 line += GetString(STR_ORDER_OUT_OF_RANGE);
358 }
359 }
360
361 DrawString(rtl ? left : middle, rtl ? middle : right, y, line, colour);
362}
363
371{
372 /* Override the index as it is not coming from a pool, so would not be initialised correctly. */
373 Order order;
374 order.index = OrderID::Begin();
375
376 /* check depot first */
377 if (IsDepotTypeTile(tile, (TransportType)(uint)v->type) && IsTileOwner(tile, _local_company)) {
381
382 if (_ctrl_pressed) {
383 /* Check to see if we are allowed to make this an unbunching order. */
384 bool failed = false;
385 if (v->HasFullLoadOrder()) {
386 /* We don't allow unbunching if the vehicle has a full load order. */
387 ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_INSERT_NEW_ORDER), GetEncodedString(STR_ERROR_UNBUNCHING_NO_UNBUNCHING_FULL_LOAD), WL_INFO);
388 failed = true;
389 } else if (v->HasUnbunchingOrder()) {
390 /* Don't allow a new unbunching order if we already have one. */
391 ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_INSERT_NEW_ORDER), GetEncodedString(STR_ERROR_UNBUNCHING_ONLY_ONE_ALLOWED), WL_INFO);
392 failed = true;
393 } else if (v->HasConditionalOrder()) {
394 /* We don't allow unbunching if the vehicle has a conditional order. */
395 ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_INSERT_NEW_ORDER), GetEncodedString(STR_ERROR_UNBUNCHING_NO_UNBUNCHING_CONDITIONAL), WL_INFO);
396 failed = true;
397 }
398
399 /* Return an empty order to bail out. */
400 if (failed) {
401 order.Free();
402 return order;
403 }
404
405 /* Now we are allowed to set the action type. */
407 }
408
409 return order;
410 }
411
412 /* check rail waypoint */
413 if (IsRailWaypointTile(tile) &&
414 v->type == VEH_TRAIN &&
418 return order;
419 }
420
421 /* check road waypoint */
422 if (IsRoadWaypointTile(tile) &&
423 v->type == VEH_ROAD &&
427 return order;
428 }
429
430 /* check buoy (no ownership) */
431 if (IsBuoyTile(tile) && v->type == VEH_SHIP) {
433 return order;
434 }
435
436 /* check for station or industry with neutral station */
437 if (IsTileType(tile, MP_STATION) || IsTileType(tile, MP_INDUSTRY)) {
438 const Station *st = nullptr;
439
440 if (IsTileType(tile, MP_STATION)) {
441 st = Station::GetByTile(tile);
442 } else {
443 const Industry *in = Industry::GetByTile(tile);
444 st = in->neutral_station;
445 }
446 if (st != nullptr && (st->owner == _local_company || st->owner == OWNER_NONE)) {
447 StationFacilities facil;
448 switch (v->type) {
449 case VEH_SHIP: facil = StationFacility::Dock; break;
450 case VEH_TRAIN: facil = StationFacility::Train; break;
451 case VEH_AIRCRAFT: facil = StationFacility::Airport; break;
453 default: NOT_REACHED();
454 }
455 if (st->facilities.Any(facil)) {
456 order.MakeGoToStation(st->index);
460 return order;
461 }
462 }
463 }
464
465 /* not found */
466 order.Free();
467 return order;
468}
469
471enum OrderHotKeys : int32_t {
472 OHK_SKIP,
473 OHK_DELETE,
474 OHK_GOTO,
475 OHK_NONSTOP,
476 OHK_FULLLOAD,
477 OHK_UNLOAD,
478 OHK_NEAREST_DEPOT,
479 OHK_ALWAYS_SERVICE,
480 OHK_TRANSFER,
481 OHK_NO_UNLOAD,
482 OHK_NO_LOAD,
483};
484
525struct OrdersWindow : public Window {
526private:
529 OPOS_NONE,
530 OPOS_GOTO,
531 OPOS_CONDITIONAL,
532 OPOS_SHARE,
533 OPOS_END,
534 };
535
538 /* WID_O_SEL_TOP_ROW_GROUNDVEHICLE */
541
542 /* WID_O_SEL_TOP_LEFT */
545
546 /* WID_O_SEL_TOP_MIDDLE */
549
550 /* WID_O_SEL_TOP_RIGHT */
553
554 /* WID_O_SEL_TOP_ROW */
558
559 /* WID_O_SEL_BOTTOM_MIDDLE */
562 };
563
564 int selected_order = -1;
566 OrderPlaceObjectState goto_type = OPOS_NONE;
567 const Vehicle *vehicle = nullptr;
568 Scrollbar *vscroll = nullptr;
569 bool can_do_refit = false;
570 bool can_do_autorefit = false;
571
578 {
579 int num = this->selected_order;
580 return (num >= 0 && num < vehicle->GetNumOrders()) ? num : vehicle->GetNumOrders();
581 }
582
592 {
593 int32_t sel = this->vscroll->GetScrolledRowFromWidget(y, this, WID_O_ORDER_LIST, WidgetDimensions::scaled.framerect.top);
594 if (sel == INT32_MAX) return INVALID_VEH_ORDER_ID;
595 /* One past the orders is the 'End of Orders' line. */
596 assert(IsInsideBS(sel, 0, vehicle->GetNumOrders() + 1));
597 return sel;
598 }
599
604 {
605 assert(type > OPOS_NONE && type < OPOS_END);
606
607 static const HighLightStyle goto_place_style[OPOS_END - 1] = {
608 HT_RECT | HT_VEHICLE, // OPOS_GOTO
609 HT_NONE, // OPOS_CONDITIONAL
610 HT_VEHICLE, // OPOS_SHARE
611 };
613 this->goto_type = type;
615 }
616
623 {
625 const Order *order = this->vehicle->GetOrder(sel_ord);
626
627 if (order == nullptr) return;
628
629 if (toggle && order->GetLoadType() == load_type) {
630 load_type = OLF_LOAD_IF_POSSIBLE; // reset to 'default'
631 }
632 if (order->GetLoadType() == load_type) return; // If we still match, do nothing
633
635 }
636
641 {
643
644 if (i < 0) {
645 const Order *order = this->vehicle->GetOrder(sel_ord);
646 if (order == nullptr) return;
648 }
650 }
651
656 {
657 Order order;
658 order.next = nullptr;
659 order.index = OrderID::Begin();
660 order.MakeGoToDepot(DepotID::Invalid(), ODTFB_PART_OF_ORDERS,
663
664 Command<CMD_INSERT_ORDER>::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), order);
665 }
666
673 {
675 const Order *order = this->vehicle->GetOrder(sel_ord);
676
677 if (order == nullptr) return;
678
679 if (toggle && order->GetUnloadType() == unload_type) {
681 }
682 if (order->GetUnloadType() == unload_type) return; // If we still match, do nothing
683
685
686 /* Transfer and unload orders with leave empty as default */
688 Command<CMD_MODIFY_ORDER>::Post(this->vehicle->tile, this->vehicle->index, sel_ord, MOF_LOAD, OLFB_NO_LOAD);
690 }
691 }
692
698 {
699 if (!this->vehicle->IsGroundVehicle()) return;
700
702 const Order *order = this->vehicle->GetOrder(sel_ord);
703
704 if (order == nullptr || order->GetNonStopType() == non_stop) return;
705
706 /* Keypress if negative, so 'toggle' to the next */
707 if (non_stop < 0) {
709 }
710
713 }
714
720 {
721 /* Don't skip when there's nothing to skip */
722 if (_ctrl_pressed && this->vehicle->cur_implicit_order_index == this->OrderGetSel()) return;
723 if (this->vehicle->GetNumOrders() <= 1) return;
724
726 this->vehicle->tile, this->vehicle->index, _ctrl_pressed ? this->OrderGetSel() : ((this->vehicle->cur_implicit_order_index + 1) % this->vehicle->GetNumOrders()));
727 }
728
733 {
734 /* When networking, move one order lower */
735 int selected = this->selected_order + (int)_networking;
736
737 if (Command<CMD_DELETE_ORDER>::Post(STR_ERROR_CAN_T_DELETE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel())) {
738 this->selected_order = selected >= this->vehicle->GetNumOrders() ? -1 : selected;
739 this->UpdateButtonState();
740 }
741 }
742
750 {
751 /* Don't try to stop sharing orders if 'End of Shared Orders' isn't selected. */
752 if (!this->vehicle->IsOrderListShared() || this->selected_order != this->vehicle->GetNumOrders()) return;
753 /* If Ctrl is pressed, delete the order list as if we clicked the 'Delete' button. */
754 if (_ctrl_pressed) {
755 this->OrderClick_Delete();
756 return;
757 }
758
759 /* Get another vehicle that share orders with this vehicle. */
760 Vehicle *other_shared = (this->vehicle->FirstShared() == this->vehicle) ? this->vehicle->NextShared() : this->vehicle->PreviousShared();
761 /* Copy the order list of the other vehicle. */
762 if (Command<CMD_CLONE_ORDER>::Post(STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST, this->vehicle->tile, CO_COPY, this->vehicle->index, other_shared->index)) {
763 this->UpdateButtonState();
764 }
765 }
766
773 void OrderClick_Refit(int i, bool auto_refit)
774 {
775 if (_ctrl_pressed) {
776 /* Cancel refitting */
777 Command<CMD_ORDER_REFIT>::Post(this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), CARGO_NO_REFIT);
778 } else {
779 if (i == 1) { // Auto-refit to available cargo type.
780 Command<CMD_ORDER_REFIT>::Post(this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), CARGO_AUTO_REFIT);
781 } else {
782 ShowVehicleRefitWindow(this->vehicle, this->OrderGetSel(), this, auto_refit);
783 }
784 }
785 }
786
789 {
790 this->can_do_refit = false;
791 this->can_do_autorefit = false;
792 for (const Vehicle *w = this->vehicle; w != nullptr; w = w->IsGroundVehicle() ? w->Next() : nullptr) {
793 if (IsEngineRefittable(w->engine_type)) this->can_do_refit = true;
794 if (Engine::Get(w->engine_type)->info.misc_flags.Test(EngineMiscFlag::AutoRefit)) this->can_do_autorefit = true;
795 }
796 }
797
798public:
799 OrdersWindow(WindowDesc &desc, const Vehicle *v) : Window(desc)
800 {
801 this->vehicle = v;
802
803 this->CreateNestedTree();
804 this->vscroll = this->GetScrollbar(WID_O_SCROLLBAR);
807 }
808 this->FinishInitNested(v->index);
809
810 this->owner = v->owner;
811
812 this->UpdateAutoRefitState();
813
815 /* If there are less than 2 station, make Go To active. */
816 int station_orders = 0;
817 for (const Order *order : v->Orders()) {
818 if (order->IsType(OT_GOTO_STATION)) station_orders++;
819 }
820
821 if (station_orders < 2) this->OrderClick_Goto(OPOS_GOTO);
822 }
824 }
825
827 {
828 switch (widget) {
829 case WID_O_ORDER_LIST:
831 size.height = 6 * resize.height + padding.height;
832 break;
833
834 case WID_O_COND_VARIABLE: {
835 Dimension d = {0, 0};
836 for (const auto &ocv : _order_conditional_variable) {
838 }
839 d.width += padding.width;
840 d.height += padding.height;
841 size = maxdim(size, d);
842 break;
843 }
844
846 Dimension d = GetStringListBoundingBox(_order_conditional_condition);
847 d.width += padding.width;
848 d.height += padding.height;
849 size = maxdim(size, d);
850 break;
851 }
852 }
853 }
854
860 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
861 {
864
865 switch (data) {
866 case VIWD_AUTOREPLACE:
867 /* Autoreplace replaced the vehicle */
868 this->vehicle = Vehicle::Get(this->window_number);
869 [[fallthrough]];
870
872 /* Vehicle composition was changed. */
873 this->UpdateAutoRefitState();
874 break;
875
877 /* Removed / replaced all orders (after deleting / sharing) */
878 if (this->selected_order == -1) break;
879
880 this->CloseChildWindows();
881 this->selected_order = -1;
882 break;
883
885 /* Some other order changes */
886 break;
887
888 default:
889 if (data < 0) break;
890
891 if (gui_scope) break; // only do this once; from command scope
892 from = GB(data, 0, 8);
893 to = GB(data, 8, 8);
894 /* Moving an order. If one of these is INVALID_VEH_ORDER_ID, then
895 * the order is being created / removed */
896 if (this->selected_order == -1) break;
897
898 if (from == to) break; // no need to change anything
899
900 if (from != this->selected_order) {
901 /* Moving from preceding order? */
902 this->selected_order -= (int)(from <= this->selected_order);
903 /* Moving to preceding order? */
904 this->selected_order += (int)(to <= this->selected_order);
905 break;
906 }
907
908 /* Now we are modifying the selected order */
909 if (to == INVALID_VEH_ORDER_ID) {
910 /* Deleting selected order */
911 this->CloseChildWindows();
912 this->selected_order = -1;
913 break;
914 }
915
916 /* Moving selected order */
917 this->selected_order = to;
918 break;
919 }
920
921 this->vscroll->SetCount(this->vehicle->GetNumOrders() + 1);
922 if (gui_scope) this->UpdateButtonState();
923
924 /* Scroll to the new order. */
925 if (from == INVALID_VEH_ORDER_ID && to != INVALID_VEH_ORDER_ID && !this->vscroll->IsVisible(to)) {
926 this->vscroll->ScrollTowards(to);
927 }
928 }
929
930 void UpdateButtonState()
931 {
932 if (this->vehicle->owner != _local_company) return; // No buttons are displayed with competitor order windows.
933
934 bool shared_orders = this->vehicle->IsOrderListShared();
935 VehicleOrderID sel = this->OrderGetSel();
936 const Order *order = this->vehicle->GetOrder(sel);
937
938 /* Second row. */
939 /* skip */
940 this->SetWidgetDisabledState(WID_O_SKIP, this->vehicle->GetNumOrders() <= 1);
941
942 /* delete / stop sharing */
944 if (shared_orders && this->selected_order == this->vehicle->GetNumOrders()) {
945 /* The 'End of Shared Orders' order is selected, show the 'stop sharing' button. */
946 delete_sel->SetDisplayedPlane(DP_BOTTOM_MIDDLE_STOP_SHARING);
947 } else {
948 /* The 'End of Shared Orders' order isn't selected, show the 'delete' button. */
949 delete_sel->SetDisplayedPlane(DP_BOTTOM_MIDDLE_DELETE);
951 (uint)this->vehicle->GetNumOrders() + ((shared_orders || this->vehicle->GetNumOrders() != 0) ? 1 : 0) <= (uint)this->selected_order);
952
953 /* Set the tooltip of the 'delete' button depending on whether the
954 * 'End of Orders' order or a regular order is selected. */
956 if (this->selected_order == this->vehicle->GetNumOrders()) {
958 } else {
960 }
961 }
962
963 /* First row. */
966
967 /* Selection widgets. */
968 /* Train or road vehicle. */
973 /* Ship or airplane. */
975 assert(row_sel != nullptr || (train_row_sel != nullptr && left_sel != nullptr && middle_sel != nullptr && right_sel != nullptr));
976
977
978 if (order == nullptr) {
979 if (row_sel != nullptr) {
980 row_sel->SetDisplayedPlane(DP_ROW_LOAD);
981 } else {
982 train_row_sel->SetDisplayedPlane(DP_GROUNDVEHICLE_ROW_NORMAL);
983 left_sel->SetDisplayedPlane(DP_LEFT_LOAD);
984 middle_sel->SetDisplayedPlane(DP_MIDDLE_UNLOAD);
985 right_sel->SetDisplayedPlane(DP_RIGHT_EMPTY);
988 }
992 } else {
995
996 switch (order->GetType()) {
997 case OT_GOTO_STATION:
998 if (row_sel != nullptr) {
999 row_sel->SetDisplayedPlane(DP_ROW_LOAD);
1000 } else {
1001 train_row_sel->SetDisplayedPlane(DP_GROUNDVEHICLE_ROW_NORMAL);
1002 left_sel->SetDisplayedPlane(DP_LEFT_LOAD);
1003 middle_sel->SetDisplayedPlane(DP_MIDDLE_UNLOAD);
1004 right_sel->SetDisplayedPlane(DP_RIGHT_REFIT);
1007 }
1010
1011 /* Can only do refitting when stopping at the destination and loading cargo.
1012 * Also enable the button if a refit is already set to allow clearing it. */
1015 ((!this->can_do_refit || !this->can_do_autorefit) && !order->IsRefit()));
1016
1017 break;
1018
1019 case OT_GOTO_WAYPOINT:
1020 if (row_sel != nullptr) {
1021 row_sel->SetDisplayedPlane(DP_ROW_LOAD);
1022 } else {
1023 train_row_sel->SetDisplayedPlane(DP_GROUNDVEHICLE_ROW_NORMAL);
1024 left_sel->SetDisplayedPlane(DP_LEFT_LOAD);
1025 middle_sel->SetDisplayedPlane(DP_MIDDLE_UNLOAD);
1026 right_sel->SetDisplayedPlane(DP_RIGHT_EMPTY);
1029 }
1033 break;
1034
1035 case OT_GOTO_DEPOT:
1036 if (row_sel != nullptr) {
1037 row_sel->SetDisplayedPlane(DP_ROW_DEPOT);
1038 } else {
1039 train_row_sel->SetDisplayedPlane(DP_GROUNDVEHICLE_ROW_NORMAL);
1040 left_sel->SetDisplayedPlane(DP_LEFT_REFIT);
1041 middle_sel->SetDisplayedPlane(DP_MIDDLE_SERVICE);
1042 right_sel->SetDisplayedPlane(DP_RIGHT_EMPTY);
1045 }
1046 /* Disable refit button if the order is no 'always go' order.
1047 * However, keep the service button enabled for refit-orders to allow clearing refits (without knowing about ctrl). */
1049 (order->GetDepotOrderType() & ODTFB_SERVICE) || (order->GetDepotActionType() & ODATFB_HALT) ||
1050 (!this->can_do_refit && !order->IsRefit()));
1051 break;
1052
1053 case OT_CONDITIONAL: {
1054 if (row_sel != nullptr) {
1055 row_sel->SetDisplayedPlane(DP_ROW_CONDITIONAL);
1056 } else {
1058 }
1060 /* Set the strings for the dropdown boxes. */
1062 this->GetWidget<NWidgetCore>(WID_O_COND_COMPARATOR)->SetString(_order_conditional_condition[order->GetConditionComparator()]);
1065 break;
1066 }
1067
1068 default: // every other order
1069 if (row_sel != nullptr) {
1070 row_sel->SetDisplayedPlane(DP_ROW_LOAD);
1071 } else {
1072 train_row_sel->SetDisplayedPlane(DP_GROUNDVEHICLE_ROW_NORMAL);
1073 left_sel->SetDisplayedPlane(DP_LEFT_LOAD);
1074 middle_sel->SetDisplayedPlane(DP_MIDDLE_UNLOAD);
1075 right_sel->SetDisplayedPlane(DP_RIGHT_EMPTY);
1077 }
1081 break;
1082 }
1083 }
1084
1085 /* Disable list of vehicles with the same shared orders if there is no list */
1086 this->SetWidgetDisabledState(WID_O_SHARED_ORDER_LIST, !shared_orders);
1087
1088 this->SetDirty();
1089 }
1090
1091 void OnPaint() override
1092 {
1093 if (this->vehicle->owner != _local_company) {
1094 this->selected_order = -1; // Disable selection any selected row at a competitor order window.
1095 } else {
1096 this->SetWidgetLoweredState(WID_O_GOTO, this->goto_type != OPOS_NONE);
1097 }
1098 this->DrawWidgets();
1099 }
1100
1101 void DrawWidget(const Rect &r, WidgetID widget) const override
1102 {
1103 if (widget != WID_O_ORDER_LIST) return;
1104
1106 bool rtl = _current_text_dir == TD_RTL;
1107 uint64_t max_value = GetParamMaxValue(this->vehicle->GetNumOrders(), 2);
1108 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;
1109 int middle = rtl ? ir.right - index_column_width : ir.left + index_column_width;
1110
1111 int y = ir.top;
1112 int line_height = this->GetWidget<NWidgetBase>(WID_O_ORDER_LIST)->resize_y;
1113
1114 int i = this->vscroll->GetPosition();
1115 const Order *order = this->vehicle->GetOrder(i);
1116 /* First draw the highlighting underground if it exists. */
1117 if (this->order_over != INVALID_VEH_ORDER_ID) {
1118 while (order != nullptr) {
1119 /* Don't draw anything if it extends past the end of the window. */
1120 if (!this->vscroll->IsVisible(i)) break;
1121
1122 if (i != this->selected_order && i == this->order_over) {
1123 /* Highlight dragged order destination. */
1124 int top = (this->order_over < this->selected_order ? y : y + line_height) - WidgetDimensions::scaled.framerect.top;
1125 int bottom = std::min(top + 2, ir.bottom);
1126 top = std::max(top - 3, ir.top);
1127 GfxFillRect(ir.left, top, ir.right, bottom, GetColourGradient(COLOUR_GREY, SHADE_LIGHTEST));
1128 break;
1129 }
1130 y += line_height;
1131
1132 i++;
1133 order = order->next;
1134 }
1135
1136 /* Reset counters for drawing the orders. */
1137 y = ir.top;
1138 i = this->vscroll->GetPosition();
1139 order = this->vehicle->GetOrder(i);
1140 }
1141
1142 /* Draw the orders. */
1143 while (order != nullptr) {
1144 /* Don't draw anything if it extends past the end of the window. */
1145 if (!this->vscroll->IsVisible(i)) break;
1146
1147 DrawOrderString(this->vehicle, order, i, y, i == this->selected_order, false, ir.left, middle, ir.right);
1148 y += line_height;
1149
1150 i++;
1151 order = order->next;
1152 }
1153
1154 if (this->vscroll->IsVisible(i)) {
1156 DrawString(rtl ? ir.left : middle, rtl ? middle : ir.right, y, str, (i == this->selected_order) ? TC_WHITE : TC_BLACK);
1157 }
1158 }
1159
1160 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
1161 {
1162 switch (widget) {
1163 case WID_O_COND_VALUE: {
1164 VehicleOrderID sel = this->OrderGetSel();
1165 const Order *order = this->vehicle->GetOrder(sel);
1166
1167 if (order != nullptr && order->IsType(OT_CONDITIONAL)) {
1168 uint value = order->GetConditionValue();
1169 if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value, this->vehicle->type);
1170 return GetString(STR_JUST_COMMA, value);
1171 }
1172 return {};
1173 }
1174
1175 case WID_O_CAPTION:
1176 return GetString(STR_ORDERS_CAPTION, this->vehicle->index);
1177
1178 case WID_O_DEPOT_ACTION: {
1179 VehicleOrderID sel = this->OrderGetSel();
1180 const Order *order = this->vehicle->GetOrder(sel);
1181 if (order == nullptr || !order->IsType(OT_GOTO_DEPOT)) return {};
1182
1183 /* Select the current action selected in the dropdown. The flags don't match the dropdown so we can't just use an index. */
1187
1189 }
1190
1191 default:
1192 return this->Window::GetWidgetString(widget, stringid);
1193 }
1194 }
1195
1196 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1197 {
1198 switch (widget) {
1199 case WID_O_ORDER_LIST: {
1200 if (this->goto_type == OPOS_CONDITIONAL) {
1201 VehicleOrderID order_id = this->GetOrderFromPt(_cursor.pos.y - this->top);
1203 Order order;
1204 order.next = nullptr;
1205 order.index = OrderID::Begin();
1207
1208 Command<CMD_INSERT_ORDER>::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), order);
1209 }
1211 break;
1212 }
1213
1214 VehicleOrderID sel = this->GetOrderFromPt(pt.y);
1215
1217 TileIndex xy = this->vehicle->GetOrder(sel)->GetLocation(this->vehicle);
1218 if (xy != INVALID_TILE) ScrollMainWindowToTile(xy);
1219 return;
1220 }
1221
1222 /* This order won't be selected any more, close all child windows and dropdowns */
1223 this->CloseChildWindows();
1224
1225 if (sel == INVALID_VEH_ORDER_ID || this->vehicle->owner != _local_company) {
1226 /* Deselect clicked order */
1227 this->selected_order = -1;
1228 } else if (sel == this->selected_order) {
1229 if (this->vehicle->type == VEH_TRAIN && sel < this->vehicle->GetNumOrders()) {
1231 this->vehicle->tile, this->vehicle->index, sel,
1232 MOF_STOP_LOCATION, (this->vehicle->GetOrder(sel)->GetStopLocation() + 1) % OSL_END);
1233 }
1234 } else {
1235 /* Select clicked order */
1236 this->selected_order = sel;
1237
1238 if (this->vehicle->owner == _local_company) {
1239 /* Activate drag and drop */
1241 }
1242 }
1243
1244 this->UpdateButtonState();
1245 break;
1246 }
1247
1248 case WID_O_SKIP:
1249 this->OrderClick_Skip();
1250 break;
1251
1252 case WID_O_DELETE:
1253 this->OrderClick_Delete();
1254 break;
1255
1256 case WID_O_STOP_SHARING:
1257 this->OrderClick_StopSharing();
1258 break;
1259
1260 case WID_O_NON_STOP:
1261 if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
1262 this->OrderClick_Nonstop(-1);
1263 } else {
1264 const Order *o = this->vehicle->GetOrder(this->OrderGetSel());
1265 assert(o != nullptr);
1266 ShowDropDownMenu(this, _order_non_stop_drowdown, o->GetNonStopType(), WID_O_NON_STOP, 0,
1267 o->IsType(OT_GOTO_STATION) ? 0 : (o->IsType(OT_GOTO_WAYPOINT) ? 3 : 12));
1268 }
1269 break;
1270
1271 case WID_O_GOTO:
1272 if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
1273 if (this->goto_type != OPOS_NONE) {
1275 } else {
1276 this->OrderClick_Goto(OPOS_GOTO);
1277 }
1278 } else {
1279 int sel;
1280 switch (this->goto_type) {
1281 case OPOS_NONE: sel = -1; break;
1282 case OPOS_GOTO: sel = 0; break;
1283 case OPOS_CONDITIONAL: sel = 2; break;
1284 case OPOS_SHARE: sel = 3; break;
1285 default: NOT_REACHED();
1286 }
1287 ShowDropDownMenu(this, this->vehicle->type == VEH_AIRCRAFT ? _order_goto_dropdown_aircraft : _order_goto_dropdown, sel, WID_O_GOTO, 0, 0);
1288 }
1289 break;
1290
1291 case WID_O_FULL_LOAD:
1292 if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
1294 } else {
1295 ShowDropDownMenu(this, _order_full_load_drowdown, this->vehicle->GetOrder(this->OrderGetSel())->GetLoadType(), WID_O_FULL_LOAD, 0, 2);
1296 }
1297 break;
1298
1299 case WID_O_UNLOAD:
1300 if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
1301 this->OrderClick_Unload(OUFB_UNLOAD, true);
1302 } else {
1303 ShowDropDownMenu(this, _order_unload_drowdown, this->vehicle->GetOrder(this->OrderGetSel())->GetUnloadType(), WID_O_UNLOAD, 0, 8);
1304 }
1305 break;
1306
1307 case WID_O_REFIT:
1308 this->OrderClick_Refit(0, false);
1309 break;
1310
1311 case WID_O_DEPOT_ACTION:
1312 ShowDropDownMenu(this, _order_depot_action_dropdown, DepotActionStringIndex(this->vehicle->GetOrder(this->OrderGetSel())), WID_O_DEPOT_ACTION, 0, 0);
1313 break;
1314
1316 if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
1317 this->OrderClick_Refit(0, true);
1318 } else {
1319 ShowDropDownMenu(this, _order_refit_action_dropdown, 0, WID_O_REFIT_DROPDOWN, 0, 0);
1320 }
1321 break;
1322
1324 ShowTimetableWindow(this->vehicle);
1325 break;
1326
1327 case WID_O_COND_VARIABLE: {
1328 DropDownList list;
1329 for (const auto &ocv : _order_conditional_variable) {
1330 list.push_back(MakeDropDownListStringItem(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + ocv, ocv));
1331 }
1332 ShowDropDownList(this, std::move(list), this->vehicle->GetOrder(this->OrderGetSel())->GetConditionVariable(), WID_O_COND_VARIABLE);
1333 break;
1334 }
1335
1336 case WID_O_COND_COMPARATOR: {
1337 const Order *o = this->vehicle->GetOrder(this->OrderGetSel());
1338 assert(o != nullptr);
1339 ShowDropDownMenu(this, _order_conditional_condition, o->GetConditionComparator(), WID_O_COND_COMPARATOR, 0, (o->GetConditionVariable() == OCV_REQUIRES_SERVICE) ? 0x3F : 0xC0);
1340 break;
1341 }
1342
1343 case WID_O_COND_VALUE: {
1344 const Order *order = this->vehicle->GetOrder(this->OrderGetSel());
1345 assert(order != nullptr);
1346 uint value = order->GetConditionValue();
1347 if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value, this->vehicle->type);
1349 break;
1350 }
1351
1353 ShowVehicleListWindow(this->vehicle);
1354 break;
1355 }
1356 }
1357
1358 void OnQueryTextFinished(std::optional<std::string> str) override
1359 {
1360 if (!str.has_value() || str->empty()) return;
1361
1362 VehicleOrderID sel = this->OrderGetSel();
1363 uint value = atoi(str->c_str());
1364
1365 switch (this->vehicle->GetOrder(sel)->GetConditionVariable()) {
1366 case OCV_MAX_SPEED:
1367 value = ConvertDisplaySpeedToSpeed(value, this->vehicle->type);
1368 break;
1369
1370 case OCV_RELIABILITY:
1372 value = Clamp(value, 0, 100);
1373 break;
1374
1375 default:
1376 break;
1377 }
1378 Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel, MOF_COND_VALUE, Clamp(value, 0, 2047));
1379 }
1380
1381 void OnDropdownSelect(WidgetID widget, int index) override
1382 {
1383 switch (widget) {
1384 case WID_O_NON_STOP:
1385 this->OrderClick_Nonstop(index);
1386 break;
1387
1388 case WID_O_FULL_LOAD:
1389 this->OrderClick_FullLoad((OrderLoadFlags)index);
1390 break;
1391
1392 case WID_O_UNLOAD:
1393 this->OrderClick_Unload((OrderUnloadFlags)index);
1394 break;
1395
1396 case WID_O_GOTO:
1397 switch (index) {
1398 case 0: this->OrderClick_Goto(OPOS_GOTO); break;
1399 case 1: this->OrderClick_NearestDepot(); break;
1400 case 2: this->OrderClick_Goto(OPOS_CONDITIONAL); break;
1401 case 3: this->OrderClick_Goto(OPOS_SHARE); break;
1402 default: NOT_REACHED();
1403 }
1404 break;
1405
1406 case WID_O_DEPOT_ACTION:
1407 this->OrderClick_Service(index);
1408 break;
1409
1411 this->OrderClick_Refit(index, true);
1412 break;
1413
1415 Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), MOF_COND_VARIABLE, index);
1416 break;
1417
1419 Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), MOF_COND_COMPARATOR, index);
1420 break;
1421 }
1422 }
1423
1424 void OnDragDrop(Point pt, WidgetID widget) override
1425 {
1426 switch (widget) {
1427 case WID_O_ORDER_LIST: {
1430
1431 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()) &&
1433 this->selected_order = -1;
1434 this->UpdateButtonState();
1435 }
1436 break;
1437 }
1438
1439 case WID_O_DELETE:
1440 this->OrderClick_Delete();
1441 break;
1442
1443 case WID_O_STOP_SHARING:
1444 this->OrderClick_StopSharing();
1445 break;
1446 }
1447
1449
1450 if (this->order_over != INVALID_VEH_ORDER_ID) {
1451 /* End of drag-and-drop, hide dragged order destination highlight. */
1452 this->order_over = INVALID_VEH_ORDER_ID;
1454 }
1455 }
1456
1458 {
1459 if (this->vehicle->owner != _local_company) return ES_NOT_HANDLED;
1460
1461 switch (hotkey) {
1462 case OHK_SKIP: this->OrderClick_Skip(); break;
1463 case OHK_DELETE: this->OrderClick_Delete(); break;
1464 case OHK_GOTO: this->OrderClick_Goto(OPOS_GOTO); break;
1465 case OHK_NONSTOP: this->OrderClick_Nonstop(-1); break;
1466 case OHK_FULLLOAD: this->OrderClick_FullLoad(OLF_FULL_LOAD_ANY, true); break;
1467 case OHK_UNLOAD: this->OrderClick_Unload(OUFB_UNLOAD, true); break;
1468 case OHK_NEAREST_DEPOT: this->OrderClick_NearestDepot(); break;
1469 case OHK_ALWAYS_SERVICE: this->OrderClick_Service(-1); break;
1470 case OHK_TRANSFER: this->OrderClick_Unload(OUFB_TRANSFER, true); break;
1471 case OHK_NO_UNLOAD: this->OrderClick_Unload(OUFB_NO_UNLOAD, true); break;
1472 case OHK_NO_LOAD: this->OrderClick_FullLoad(OLFB_NO_LOAD, true); break;
1473 default: return ES_NOT_HANDLED;
1474 }
1475 return ES_HANDLED;
1476 }
1477
1479 {
1480 if (this->goto_type == OPOS_GOTO) {
1481 const Order cmd = GetOrderCmdFromTile(this->vehicle, tile);
1482 if (cmd.IsType(OT_NOTHING)) return;
1483
1484 if (Command<CMD_INSERT_ORDER>::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), cmd)) {
1485 /* With quick goto the Go To button stays active */
1487 }
1488 }
1489 }
1490
1491 bool OnVehicleSelect(const Vehicle *v) override
1492 {
1493 /* v is vehicle getting orders. Only copy/clone orders if vehicle doesn't have any orders yet.
1494 * We disallow copying orders of other vehicles if we already have at least one order entry
1495 * ourself as it easily copies orders of vehicles within a station when we mean the station.
1496 * Obviously if you press CTRL on a non-empty orders vehicle you know what you are doing
1497 * TODO: give a warning message */
1498 bool share_order = _ctrl_pressed || this->goto_type == OPOS_SHARE;
1499 if (this->vehicle->GetNumOrders() != 0 && !share_order) return false;
1500
1502 this->vehicle->tile, share_order ? CO_SHARE : CO_COPY, this->vehicle->index, v->index)) {
1503 this->selected_order = -1;
1505 }
1506 return true;
1507 }
1508
1515 bool OnVehicleSelect(VehicleList::const_iterator begin, VehicleList::const_iterator end) override
1516 {
1517 bool share_order = _ctrl_pressed || this->goto_type == OPOS_SHARE;
1518 if (this->vehicle->GetNumOrders() != 0 && !share_order) return false;
1519
1520 if (!share_order) {
1521 /* If CTRL is not pressed: If all the vehicles in this list have the same orders, then copy orders */
1522 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
1524 })) {
1525 OnVehicleSelect(*begin);
1526 } else {
1528 }
1529 } else {
1530 /* If CTRL is pressed: If all the vehicles in this list share orders, then copy orders */
1531 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
1532 return v1->FirstShared() == v2->FirstShared();
1533 })) {
1534 OnVehicleSelect(*begin);
1535 } else {
1537 }
1538 }
1539
1540 return true;
1541 }
1542
1543 void OnPlaceObjectAbort() override
1544 {
1545 this->goto_type = OPOS_NONE;
1547
1548 /* Remove drag highlighting if it exists. */
1549 if (this->order_over != INVALID_VEH_ORDER_ID) {
1550 this->order_over = INVALID_VEH_ORDER_ID;
1552 }
1553 }
1554
1555 void OnMouseDrag(Point pt, WidgetID widget) override
1556 {
1557 if (this->selected_order != -1 && widget == WID_O_ORDER_LIST) {
1558 /* An order is dragged.. */
1561 uint num_orders = this->vehicle->GetNumOrders();
1562
1563 if (from_order != INVALID_VEH_ORDER_ID && from_order <= num_orders) {
1564 if (to_order != INVALID_VEH_ORDER_ID && to_order <= num_orders) { // ..over an existing order.
1565 this->order_over = to_order;
1566 this->SetWidgetDirty(widget);
1567 } else if (from_order != to_order && this->order_over != INVALID_VEH_ORDER_ID) { // ..outside of the order list.
1568 this->order_over = INVALID_VEH_ORDER_ID;
1569 this->SetWidgetDirty(widget);
1570 }
1571 }
1572 }
1573 }
1574
1575 void OnResize() override
1576 {
1577 /* Update the scroll bar */
1578 this->vscroll->SetCapacityFromWidget(this, WID_O_ORDER_LIST, WidgetDimensions::scaled.framerect.Vertical());
1579 }
1580
1581 static inline HotkeyList hotkeys{"order", {
1582 Hotkey('D', "skip", OHK_SKIP),
1583 Hotkey('F', "delete", OHK_DELETE),
1584 Hotkey('G', "goto", OHK_GOTO),
1585 Hotkey('H', "nonstop", OHK_NONSTOP),
1586 Hotkey('J', "fullload", OHK_FULLLOAD),
1587 Hotkey('K', "unload", OHK_UNLOAD),
1588 Hotkey(0, "nearest_depot", OHK_NEAREST_DEPOT),
1589 Hotkey(0, "always_service", OHK_ALWAYS_SERVICE),
1590 Hotkey(0, "transfer", OHK_TRANSFER),
1591 Hotkey(0, "no_unload", OHK_NO_UNLOAD),
1592 Hotkey(0, "no_load", OHK_NO_LOAD),
1593 }};
1594};
1595
1599 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1600 NWidget(WWT_CAPTION, COLOUR_GREY, WID_O_CAPTION),
1601 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_TIMETABLE_VIEW), SetMinimalSize(61, 14), SetStringTip(STR_ORDERS_TIMETABLE_VIEW, STR_ORDERS_TIMETABLE_VIEW_TOOLTIP),
1602 NWidget(WWT_SHADEBOX, COLOUR_GREY),
1603 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
1604 NWidget(WWT_STICKYBOX, COLOUR_GREY),
1605 EndContainer(),
1607 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(),
1609 EndContainer(),
1610
1611 /* First button row. */
1615 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_NON_STOP), SetMinimalSize(93, 12), SetFill(1, 0),
1616 SetStringTip(STR_ORDER_NON_STOP, STR_ORDER_TOOLTIP_NON_STOP), SetResize(1, 0),
1617 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_TOP_LEFT),
1618 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_FULL_LOAD), SetMinimalSize(93, 12), SetFill(1, 0),
1619 SetStringTip(STR_ORDER_TOGGLE_FULL_LOAD, STR_ORDER_TOOLTIP_FULL_LOAD), SetResize(1, 0),
1620 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_REFIT), SetMinimalSize(93, 12), SetFill(1, 0),
1621 SetStringTip(STR_ORDER_REFIT, STR_ORDER_REFIT_TOOLTIP), SetResize(1, 0),
1622 EndContainer(),
1624 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_UNLOAD), SetMinimalSize(93, 12), SetFill(1, 0),
1625 SetStringTip(STR_ORDER_TOGGLE_UNLOAD, STR_ORDER_TOOLTIP_UNLOAD), SetResize(1, 0),
1627 SetStringTip(STR_JUST_STRING), SetResize(1, 0),
1628 EndContainer(),
1629 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_TOP_RIGHT),
1630 NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(93, 12), SetFill(1, 0), SetResize(1, 0), EndContainer(),
1632 SetStringTip(STR_ORDER_REFIT_AUTO, STR_ORDER_REFIT_AUTO_TOOLTIP), SetResize(1, 0),
1633 EndContainer(),
1634 EndContainer(),
1636 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_VARIABLE), SetMinimalSize(124, 12), SetFill(1, 0),
1637 SetToolTip(STR_ORDER_CONDITIONAL_VARIABLE_TOOLTIP), SetResize(1, 0),
1638 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_COMPARATOR), SetMinimalSize(124, 12), SetFill(1, 0),
1639 SetToolTip(STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP), SetResize(1, 0),
1640 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_COND_VALUE), SetMinimalSize(124, 12), SetFill(1, 0),
1641 SetToolTip(STR_ORDER_CONDITIONAL_VALUE_TOOLTIP), SetResize(1, 0),
1642 EndContainer(),
1643 EndContainer(),
1644 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),
1645 EndContainer(),
1646
1647 /* Second button row. */
1650 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_SKIP), SetMinimalSize(124, 12), SetFill(1, 0),
1651 SetStringTip(STR_ORDERS_SKIP_BUTTON, STR_ORDERS_SKIP_TOOLTIP), SetResize(1, 0),
1653 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_DELETE), SetMinimalSize(124, 12), SetFill(1, 0),
1654 SetStringTip(STR_ORDERS_DELETE_BUTTON, STR_ORDERS_DELETE_TOOLTIP), SetResize(1, 0),
1655 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_STOP_SHARING), SetMinimalSize(124, 12), SetFill(1, 0),
1656 SetStringTip(STR_ORDERS_STOP_SHARING_BUTTON, STR_ORDERS_STOP_SHARING_TOOLTIP), SetResize(1, 0),
1657 EndContainer(),
1658 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_GOTO), SetMinimalSize(124, 12), SetFill(1, 0),
1659 SetStringTip(STR_ORDERS_GO_TO_BUTTON, STR_ORDERS_GO_TO_TOOLTIP), SetResize(1, 0),
1660 EndContainer(),
1661 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
1662 EndContainer(),
1663};
1664
1665static WindowDesc _orders_train_desc(
1666 WDP_AUTO, "view_vehicle_orders_train", 384, 100,
1670 &OrdersWindow::hotkeys
1671);
1672
1676 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1677 NWidget(WWT_CAPTION, COLOUR_GREY, WID_O_CAPTION), SetStringTip(STR_ORDERS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1678 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_TIMETABLE_VIEW), SetMinimalSize(61, 14), SetStringTip(STR_ORDERS_TIMETABLE_VIEW, STR_ORDERS_TIMETABLE_VIEW_TOOLTIP),
1679 NWidget(WWT_SHADEBOX, COLOUR_GREY),
1680 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
1681 NWidget(WWT_STICKYBOX, COLOUR_GREY),
1682 EndContainer(),
1684 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(),
1686 EndContainer(),
1687
1688 /* First button row. */
1690 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_TOP_ROW),
1691 /* Load + unload + refit buttons. */
1693 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_FULL_LOAD), SetMinimalSize(124, 12), SetFill(1, 0),
1694 SetStringTip(STR_ORDER_TOGGLE_FULL_LOAD, STR_ORDER_TOOLTIP_FULL_LOAD), SetResize(1, 0),
1695 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_UNLOAD), SetMinimalSize(124, 12), SetFill(1, 0),
1696 SetStringTip(STR_ORDER_TOGGLE_UNLOAD, STR_ORDER_TOOLTIP_UNLOAD), SetResize(1, 0),
1698 SetStringTip(STR_ORDER_REFIT_AUTO, STR_ORDER_REFIT_AUTO_TOOLTIP), SetResize(1, 0),
1699 EndContainer(),
1700 /* Refit + service buttons. */
1702 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_REFIT), SetMinimalSize(186, 12), SetFill(1, 0),
1703 SetStringTip(STR_ORDER_REFIT, STR_ORDER_REFIT_TOOLTIP), SetResize(1, 0),
1705 SetResize(1, 0),
1706 EndContainer(),
1707
1708 /* Buttons for setting a condition. */
1710 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_VARIABLE), SetMinimalSize(124, 12), SetFill(1, 0),
1711 SetToolTip(STR_ORDER_CONDITIONAL_VARIABLE_TOOLTIP), SetResize(1, 0),
1712 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_COMPARATOR), SetMinimalSize(124, 12), SetFill(1, 0),
1713 SetToolTip(STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP), SetResize(1, 0),
1714 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_COND_VALUE), SetMinimalSize(124, 12), SetFill(1, 0),
1715 SetStringTip(STR_JUST_COMMA, STR_ORDER_CONDITIONAL_VALUE_TOOLTIP), SetResize(1, 0),
1716 EndContainer(),
1717 EndContainer(),
1718
1719 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),
1720 EndContainer(),
1721
1722 /* Second button row. */
1724 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_SKIP), SetMinimalSize(124, 12), SetFill(1, 0),
1725 SetStringTip(STR_ORDERS_SKIP_BUTTON, STR_ORDERS_SKIP_TOOLTIP), SetResize(1, 0),
1727 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_DELETE), SetMinimalSize(124, 12), SetFill(1, 0),
1728 SetStringTip(STR_ORDERS_DELETE_BUTTON, STR_ORDERS_DELETE_TOOLTIP), SetResize(1, 0),
1729 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_STOP_SHARING), SetMinimalSize(124, 12), SetFill(1, 0),
1730 SetStringTip(STR_ORDERS_STOP_SHARING_BUTTON, STR_ORDERS_STOP_SHARING_TOOLTIP), SetResize(1, 0),
1731 EndContainer(),
1732 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_GOTO), SetMinimalSize(124, 12), SetFill(1, 0),
1733 SetStringTip(STR_ORDERS_GO_TO_BUTTON, STR_ORDERS_GO_TO_TOOLTIP), SetResize(1, 0),
1734 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
1735 EndContainer(),
1736};
1737
1738static WindowDesc _orders_desc(
1739 WDP_AUTO, "view_vehicle_orders", 384, 100,
1743 &OrdersWindow::hotkeys
1744);
1745
1749 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1750 NWidget(WWT_CAPTION, COLOUR_GREY, WID_O_CAPTION), SetStringTip(STR_ORDERS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1751 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_TIMETABLE_VIEW), SetMinimalSize(61, 14), SetStringTip(STR_ORDERS_TIMETABLE_VIEW, STR_ORDERS_TIMETABLE_VIEW_TOOLTIP),
1752 NWidget(WWT_SHADEBOX, COLOUR_GREY),
1753 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
1754 NWidget(WWT_STICKYBOX, COLOUR_GREY),
1755 EndContainer(),
1757 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(),
1760 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
1761 EndContainer(),
1762 EndContainer(),
1763};
1764
1765static WindowDesc _other_orders_desc(
1766 WDP_AUTO, "view_vehicle_orders_competitor", 384, 86,
1770 &OrdersWindow::hotkeys
1771);
1772
1773void ShowOrdersWindow(const Vehicle *v)
1774{
1777 if (BringWindowToFrontById(WC_VEHICLE_ORDERS, v->index) != nullptr) return;
1778
1779 /* Using a different WindowDescs for _local_company causes problems.
1780 * Due to this we have to close order windows in ChangeWindowOwner/CloseCompanyWindows,
1781 * because we cannot change switch the WindowDescs and keeping the old WindowDesc results
1782 * in crashed due to missing widges.
1783 * TODO Rewrite the order GUI to not use different WindowDescs.
1784 */
1785 if (v->owner != _local_company) {
1786 new OrdersWindow(_other_orders_desc, v);
1787 } else {
1788 new OrdersWindow(v->IsGroundVehicle() ? _orders_train_desc : _orders_desc, v);
1789 }
1790}
Base for aircraft.
debug_inline 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:78
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:79
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Base class for a 'real' widget.
Stacked widgets, widgets all occupying the same space in the window.
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:2447
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:2521
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:29
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:441
void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, bool instant_close, bool persist)
Show a drop down list.
Definition dropdown.cpp:404
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:1296
Functions related to engines.
@ AutoRefit
Automatic refitting is allowed.
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, const 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:77
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:923
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:852
Dimension GetStringListBoundingBox(std::span< const StringID > list, FontSize fontsize)
Get maximum dimension of a list of strings.
Definition gfx.cpp:890
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:658
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:38
void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen.
Definition gfx.cpp:115
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:989
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:243
@ SA_RIGHT
Right align the text (must be a single bit).
Definition gfx_type.h:377
@ SA_FORCE
Force the alignment, i.e. don't swap for RTL languages.
Definition gfx_type.h:387
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition gfx_type.h:294
@ TC_NO_SHADE
Do not add shading to this text colour.
Definition gfx_type.h:318
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 NWidget(WidgetType tp, Colours col, WidgetID idx=-1)
Widget part function for starting a new 'real' widget.
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 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:943
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:65
Basic functions/variables used all over the place.
uint GetOrderDistance(const Order *prev, const Order *cur, const Vehicle *v, int conditional_depth)
Get the distance between two orders of a vehicle.
Command definitions related to orders.
uint ConvertSpeedToDisplaySpeed(uint speed, VehicleType type)
Convert the given (internal) speed to the display speed.
Definition strings.cpp:954
static constexpr NWidgetPart _nested_other_orders_widgets[]
Nested widget definition for competitor orders.
static constexpr NWidgetPart _nested_orders_train_widgets[]
Nested widget definition for "your" train orders.
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:44
static constexpr NWidgetPart _nested_orders_widgets[]
Nested widget definition for "your" orders (non-train).
void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int y, bool selected, bool timetable, int left, int middle, int right)
Draws an order in order or timetable GUI.
uint ConvertDisplaySpeedToSpeed(uint speed, VehicleType type)
Convert the given display speed to the (internal) speed.
Definition strings.cpp:967
OrderConditionVariable
Variables (of a vehicle) to 'cause' skipping on.
Definition order_type.h:129
@ OCV_AGE
Skip based on the age.
Definition order_type.h:133
@ OCV_UNCONDITIONALLY
Always skip.
Definition order_type.h:135
@ OCV_MAX_SPEED
Skip based on the maximum speed.
Definition order_type.h:132
@ OCV_LOAD_PERCENTAGE
Skip based on the amount of load.
Definition order_type.h:130
@ OCV_REQUIRES_SERVICE
Skip when the vehicle requires service.
Definition order_type.h:134
@ OCV_RELIABILITY
Skip based on the reliability.
Definition order_type.h:131
@ OCV_REMAINING_LIFETIME
Skip based on the remaining lifetime.
Definition order_type.h:136
@ OCV_MAX_RELIABILITY
Skip based on the maximum reliability.
Definition order_type.h:137
OrderStopLocation
Where to stop the trains.
Definition order_type.h:99
@ OSL_PLATFORM_FAR_END
Stop at the far end of the platform.
Definition order_type.h:102
@ MOF_COND_VARIABLE
A conditional variable changes.
Definition order_type.h:166
@ MOF_LOAD
Passes an OrderLoadType.
Definition order_type.h:164
@ MOF_UNLOAD
Passes an OrderUnloadType.
Definition order_type.h:163
@ MOF_STOP_LOCATION
Passes an OrderStopLocation.
Definition order_type.h:162
@ MOF_COND_COMPARATOR
A comparator changes.
Definition order_type.h:167
@ MOF_COND_VALUE
The value to set the condition to.
Definition order_type.h:168
@ MOF_DEPOT_ACTION
Selects the OrderDepotAction.
Definition order_type.h:165
@ MOF_NON_STOP
Passes an OrderNonStopFlags.
Definition order_type.h:161
OrderUnloadFlags
Flags related to the unloading order.
Definition order_type.h:68
@ OUFB_TRANSFER
Transfer all cargo onto the platform.
Definition order_type.h:71
@ OUFB_NO_UNLOAD
Totally no unloading will be done.
Definition order_type.h:72
@ OUF_UNLOAD_IF_POSSIBLE
Unload all cargo that the station accepts.
Definition order_type.h:69
@ OUFB_UNLOAD
Force unloading all cargo onto the platform, possibly not getting paid.
Definition order_type.h:70
@ DA_SERVICE
Service only if needed.
Definition order_type.h:178
@ DA_STOP
Go to the depot and stop there.
Definition order_type.h:179
@ DA_ALWAYS_GO
Always go to the depot.
Definition order_type.h:177
@ DA_UNBUNCH
Go to the depot and unbunch.
Definition order_type.h:180
@ ODTFB_PART_OF_ORDERS
This depot order is because of a regular order.
Definition order_type.h:112
@ ODTFB_SERVICE
This depot order is because of the servicing limit.
Definition order_type.h:111
uint8_t VehicleOrderID
The index of an order within its current vehicle (not pool related)
Definition order_type.h:18
@ ODATFB_UNBUNCH
Service the vehicle and then unbunch it.
Definition order_type.h:122
@ ODATFB_NEAREST_DEPOT
Send the vehicle to the nearest depot.
Definition order_type.h:121
@ ODATFB_HALT
Service the vehicle and then halt it.
Definition order_type.h:120
OrderLoadFlags
Flags related to the loading order.
Definition order_type.h:78
@ OLFB_NO_LOAD
Do not load anything.
Definition order_type.h:82
@ OLF_LOAD_IF_POSSIBLE
Load as long as there is cargo that fits in the train.
Definition order_type.h:79
@ OLF_FULL_LOAD_ANY
Full load a single cargo of the consist.
Definition order_type.h:81
static const VehicleOrderID INVALID_VEH_ORDER_ID
Invalid vehicle order index (sentinel)
Definition order_type.h:40
OrderConditionComparator
Comparator for the skip reasoning.
Definition order_type.h:144
@ OCC_IS_TRUE
Skip if the variable is true.
Definition order_type.h:151
@ OCC_IS_FALSE
Skip if the variable is false.
Definition order_type.h:152
@ ONSF_NO_STOP_AT_ANY_STATION
The vehicle will not stop at any stations it passes including the destination.
Definition order_type.h:92
@ ONSF_NO_STOP_AT_DESTINATION_STATION
The vehicle will stop at any station it passes except the destination.
Definition order_type.h:91
@ ONSF_STOP_EVERYWHERE
The vehicle will stop at any station it passes and the destination.
Definition order_type.h:89
@ ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS
The vehicle will not stop at any stations it passes except the destination.
Definition order_type.h:90
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.
uint8_t GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition palette.cpp:387
Road vehicle states.
A number of safeguards to prevent using unsafe methods.
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:57
static const CursorID ANIMCURSOR_PICKSTATION
716 - 718 - goto-order icon
Definition sprites.h:1515
static const CursorID SPR_CURSOR_MOUSE
Cursor sprite numbers.
Definition sprites.h:1394
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.
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:248
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:426
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.
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
Point pos
logical mouse position
Definition gfx_type.h:124
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.
uint8_t 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:63
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:235
Station * neutral_station
Associated neutral station.
Definition industry.h:93
Partial widget specification to allow NWidgets to be written nested.
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:93
OrderDepotTypeFlags GetDepotOrderType() const
What caused us going to the depot?
Definition order_base.h:144
OrderConditionVariable GetConditionVariable() const
What variable do we have to compare?
Definition order_base.h:148
void SetLoadType(OrderLoadFlags load_type)
Set how the consist must be loaded.
Definition order_base.h:157
DestinationID GetDestination() const
Gets the destination of this order.
Definition order_base.h:103
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition order_base.h:70
void SetNonStopType(OrderNonStopFlags non_stop_type)
Set whether we must stop at stations or not.
Definition order_base.h:161
VehicleOrderID GetConditionSkipToOrder() const
Get the order to skip to.
Definition order_base.h:152
OrderStopLocation GetStopLocation() const
Where must we stop at the platform?
Definition order_base.h:142
uint16_t GetWaitTime() const
Get the time in ticks a vehicle will probably wait at the destination (timetabled or not).
Definition order_base.h:192
CargoType GetRefitCargo() const
Get the cargo to to refit to.
Definition order_base.h:131
OrderType GetType() const
Get the type of order of this order.
Definition order_base.h:76
void MakeGoToStation(StationID destination)
Makes this order a Go To Station order.
Definition order_cmd.cpp:75
OrderLoadFlags GetLoadType() const
How must the consist be loaded?
Definition order_base.h:136
void SetStopLocation(OrderStopLocation stop_location)
Set where we must stop at the platform.
Definition order_base.h:163
void MakeGoToWaypoint(StationID destination)
Makes this order a Go To Waypoint order.
bool IsWaitTimetabled() const
Does this order have an explicit wait time set?
Definition order_base.h:183
Order * next
Pointer to next order. If nullptr, end of list.
Definition order_base.h:59
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:167
OrderDepotActionFlags GetDepotActionType() const
What are we going to do when in the depot.
Definition order_base.h:146
void Free()
'Free' the order
Definition order_cmd.cpp:63
bool IsAutoRefit() const
Is this order a auto-refit order.
Definition order_base.h:124
OrderUnloadFlags GetUnloadType() const
How must the consist be unloaded?
Definition order_base.h:138
OrderConditionComparator GetConditionComparator() const
What is the comparator to use?
Definition order_base.h:150
OrderNonStopFlags GetNonStopType() const
At which stations must we stop?
Definition order_base.h:140
bool IsRefit() const
Is this order a refit order.
Definition order_base.h:117
uint16_t GetConditionValue() const
Get the value to base the skip on.
Definition order_base.h:154
void MakeGoToDepot(DestinationID destination, OrderDepotTypeFlags order, OrderNonStopFlags non_stop_type=ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS, OrderDepotActionFlags action=ODATF_SERVICE_ONLY, CargoType cargo=CARGO_NO_REFIT)
Makes this order a Go To Depot order.
Definition order_cmd.cpp:90
Order window code for all vehicles.
void OrderClick_Refit(int i, bool auto_refit)
Handle the click on the refit button.
void OrderClick_FullLoad(OrderLoadFlags load_type, bool toggle=false)
Handle the click on the full load button.
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.
const Vehicle * vehicle
Vehicle owning the orders being displayed and manipulated.
void OrderClick_Service(int i)
Handle the click on the service.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
void OrderClick_Nonstop(int non_stop)
Handle the click on the nonstop button.
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 OnDropdownSelect(WidgetID widget, int index) override
A dropdown option associated to this window has been selected.
void OnPlaceObject(Point pt, TileIndex tile) override
The user clicked some place on the map when a tile highlight mode has been set.
void OrderClick_Unload(OrderUnloadFlags unload_type, bool toggle=false)
Handle the click on the unload button.
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.
bool can_do_autorefit
Vehicle chain can be auto-refitted.
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.
Coordinates of a point in 2D.
static Titem * Get(auto index)
Returns Titem with given index.
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.
bool HasUnbunchingOrder() const
Check if the current vehicle has an unbunching order.
Definition vehicle.cpp:2480
VehicleOrderID GetNumOrders() const
Get the number of orders this vehicle has.
Order * GetFirstOrder() const
Get the first order of the vehicles order list.
Vehicle * NextShared() const
Get the next vehicle of the shared vehicle chain.
bool HasFullLoadOrder() const
Check if the current vehicle has a full load order.
Definition vehicle.cpp:2456
Vehicle * PreviousShared() const
Get the previous vehicle of the shared vehicle chain.
Vehicle * FirstShared() const
Get the first vehicle of this vehicle chain.
debug_inline bool IsGroundVehicle() const
Check if the vehicle is a ground vehicle.
TileIndex tile
Current tile index.
bool HasConditionalOrder() const
Check if the current vehicle has a conditional order.
Definition vehicle.cpp:2468
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:1736
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:744
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:554
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:502
void CloseChildWindows(WindowClass wc=WC_INVALID) const
Close all children a window might have in a head-recursive manner.
Definition window.cpp:1038
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:1726
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 NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:973
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:311
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.
bool IsTileOwner(Tile tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition tile_map.h:214
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
@ MP_INDUSTRY
Part of an industry.
Definition tile_type.h:56
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:3278
bool CanVehicleUseStation(EngineID engine_type, const Station *st)
Can this station be used by the given engine type?
Definition vehicle.cpp:3047
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:73
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:65
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:40
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition widget_type.h:56
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition widget_type.h:54
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition widget_type.h:51
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition widget_type.h:75
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:67
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:59
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition widget_type.h:58
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition widget_type.h:55
@ WWT_DROPDOWN
Drop down list.
Definition widget_type.h:60
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:70
@ 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:1143
Window * BringWindowToFrontById(WindowClass cls, WindowNumber number)
Find a window and make it the relative top-window on the screen.
Definition window.cpp:1226
@ 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:936
@ WDP_AUTO
Find a place automatically.
Definition window_gui.h:145
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: