OpenTTD Source 20250924-master-gbec4e71d53
timetable_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 "gui.h"
13#include "window_gui.h"
14#include "window_func.h"
15#include "textbuf_gui.h"
16#include "strings_func.h"
17#include "vehicle_base.h"
18#include "string_func.h"
19#include "gfx_func.h"
20#include "company_func.h"
21#include "timer/timer.h"
24#include "timer/timer_window.h"
25#include "date_gui.h"
26#include "vehicle_gui.h"
27#include "settings_type.h"
28#include "timetable_cmd.h"
29#include "timetable.h"
31
33
34#include "table/sprites.h"
35#include "table/strings.h"
36
37#include "safeguards.h"
38
44
50std::pair<StringParameter, StringParameter> GetTimetableParameters(TimerGameTick::Ticks ticks)
51{
53 case TimetableMode::Days: return {STR_UNITS_DAYS, ticks / Ticks::DAY_TICKS};
54 case TimetableMode::Seconds: return {STR_UNITS_SECONDS, ticks / Ticks::TICKS_PER_SECOND};
55 case TimetableMode::Ticks: return {STR_UNITS_TICKS, ticks};
56 default:
57 NOT_REACHED();
58 }
59}
60
66{
68 case TimetableMode::Days:
69 return Ticks::DAY_TICKS;
70 case TimetableMode::Seconds:
72 case TimetableMode::Ticks:
73 return 1;
74 default:
75 NOT_REACHED();
76 }
77}
78
86{
88 case TimetableMode::Days:
89 return ticks > Ticks::DAY_TICKS;
90 case TimetableMode::Seconds:
91 return ticks > Ticks::TICKS_PER_SECOND;
92 case TimetableMode::Ticks:
93 return ticks > (round_to_day ? Ticks::DAY_TICKS : 0);
94 default:
95 NOT_REACHED();
96 }
97}
98
105static bool CanDetermineTimeTaken(const Order &order, bool travelling)
106{
107 /* Current order is conditional */
108 if (order.IsType(OT_CONDITIONAL) || order.IsType(OT_IMPLICIT)) return false;
109 /* No travel time and we have not already finished travelling */
110 if (travelling && !order.IsTravelTimetabled()) return false;
111 /* No wait time but we are loading at this timetabled station */
112 if (!travelling && !order.IsWaitTimetabled() && order.IsType(OT_GOTO_STATION) &&
114 return false;
115 }
116
117 return true;
118}
119
120
129static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID start, bool travelling, std::vector<TimetableArrivalDeparture> &table, TimerGameTick::Ticks offset)
130{
131 assert(!table.empty());
132 assert(v->GetNumOrders() >= 2);
133 assert(start < v->GetNumOrders());
134
135 /* Pre-initialize with unknown time */
136 for (int i = 0; i < v->GetNumOrders(); ++i) {
137 table[i].arrival = table[i].departure = Ticks::INVALID_TICKS;
138 }
139
140 TimerGameTick::Ticks sum = offset;
141 VehicleOrderID i = start;
142 auto orders = v->Orders();
143
144 /* Cyclically loop over all orders until we reach the current one again.
145 * As we may start at the current order, do a post-checking loop */
146 do {
147 /* Automatic orders don't influence the overall timetable;
148 * they just add some untimetabled entries, but the time till
149 * the next non-implicit order can still be known. */
150 if (!orders[i].IsType(OT_IMPLICIT)) {
151 if (travelling || i != start) {
152 if (!CanDetermineTimeTaken(orders[i], true)) return;
153 sum += orders[i].GetTimetabledTravel();
154 table[i].arrival = sum;
155 }
156
157 if (!CanDetermineTimeTaken(orders[i], false)) return;
158 sum += orders[i].GetTimetabledWait();
159 table[i].departure = sum;
160 }
161
162 i = v->orders->GetNext(i);
163 } while (i != start);
164
165 /* When loading at a scheduled station we still have to treat the
166 * travelling part of the first order. */
167 if (!travelling) {
168 if (!CanDetermineTimeTaken(orders[i], true)) return;
169 sum += orders[i].GetTimetabledTravel();
170 table[i].arrival = sum;
171 }
172}
173
175 int sel_index = -1;
177 const Vehicle *vehicle = nullptr;
178 bool show_expected = true;
179 Scrollbar *vscroll = nullptr;
180 bool set_start_date_all = false;
181 bool change_timetable_all = false;
182
184 Window(desc),
186 {
187 this->CreateNestedTree();
188 this->vscroll = this->GetScrollbar(WID_VT_SCROLLBAR);
189
190 /* When using wallclock units, we must ensure the client displays timetables in seconds. */
192 _settings_client.gui.timetable_mode = TimetableMode::Seconds;
193 }
194
195 this->UpdateSelectionStates();
196 this->FinishInitNested(window_number);
197
198 this->owner = this->vehicle->owner;
199 }
200
207 static bool BuildArrivalDepartureList(const Vehicle *v, std::vector<TimetableArrivalDeparture> &table)
208 {
210
211 bool travelling = (!v->current_order.IsType(OT_LOADING) || v->current_order.GetNonStopType() == ONSF_STOP_EVERYWHERE);
213
214 /* If arrival and departure times are in days, compensate for the current date_fract. */
215 if (_settings_client.gui.timetable_mode != TimetableMode::Seconds) start_time += TimerGameEconomy::date_fract;
216
217 FillTimetableArrivalDepartureTable(v, v->cur_real_order_index % v->GetNumOrders(), travelling, table, start_time);
218
219 return (travelling && v->lateness_counter < 0);
220 }
221
222 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
223 {
224 switch (widget) {
226 /* We handle this differently depending on the timetable mode. */
227 if (_settings_client.gui.timetable_mode == TimetableMode::Seconds) {
228 /* A five-digit number would fit a timetable lasting 2.7 real-world hours, which should be plenty. */
229 uint64_t max_digits = GetParamMaxDigits(4, FS_SMALL);
230 size.width = std::max(
231 GetStringBoundingBox(GetString(STR_TIMETABLE_ARRIVAL_SECONDS_IN_FUTURE, TC_BLACK, max_digits)).width,
232 GetStringBoundingBox(GetString(STR_TIMETABLE_DEPARTURE_SECONDS_IN_FUTURE, TC_BLACK, max_digits)).width)
233 + WidgetDimensions::scaled.hsep_wide + padding.width;
234 } else {
236 size.width = std::max(
237 GetStringBoundingBox(GetString(STR_TIMETABLE_ARRIVAL_DATE, TC_BLACK, max_value)).width,
238 GetStringBoundingBox(GetString(STR_TIMETABLE_DEPARTURE_DATE, TC_BLACK, max_value)).width)
239 + WidgetDimensions::scaled.hsep_wide + padding.width;
240 }
241 [[fallthrough]];
242
245 fill.height = resize.height = GetCharacterHeight(FS_NORMAL);
246 size.height = 8 * resize.height + padding.height;
247 break;
248
250 size.height = 2 * GetCharacterHeight(FS_NORMAL) + padding.height;
251 break;
252 }
253 }
254
255 int GetOrderFromTimetableWndPt(int y, [[maybe_unused]] const Vehicle *v)
256 {
257 int32_t sel = this->vscroll->GetScrolledRowFromWidget(y, this, WID_VT_TIMETABLE_PANEL, WidgetDimensions::scaled.framerect.top);
258 if (sel == INT32_MAX) return sel;
259 assert(IsInsideBS(sel, 0, v->GetNumOrders() * 2));
260 return sel;
261 }
262
268 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
269 {
270 switch (data) {
271 case VIWD_AUTOREPLACE:
272 /* Autoreplace replaced the vehicle */
273 this->vehicle = Vehicle::Get(this->window_number);
274 break;
275
277 /* Removed / replaced all orders (after deleting / sharing) */
278 if (this->sel_index == -1) break;
279
280 this->CloseChildWindows();
281 this->sel_index = -1;
282 break;
283
285 if (!gui_scope) break;
286 this->UpdateSelectionStates();
287 this->ReInit();
288 break;
289
290 default: {
291 if (gui_scope) break; // only do this once; from command scope
292
293 /* Moving an order. If one of these is INVALID_VEH_ORDER_ID, then
294 * the order is being created / removed */
295 if (this->sel_index == -1) break;
296
297 VehicleOrderID from = GB(data, 0, 8);
298 VehicleOrderID to = GB(data, 8, 8);
299
300 if (from == to) break; // no need to change anything
301
302 /* if from == INVALID_VEH_ORDER_ID, one order was added; if to == INVALID_VEH_ORDER_ID, one order was removed */
303 uint old_num_orders = this->vehicle->GetNumOrders() - (uint)(from == INVALID_VEH_ORDER_ID) + (uint)(to == INVALID_VEH_ORDER_ID);
304
305 VehicleOrderID selected_order = (this->sel_index + 1) / 2;
306 if (selected_order == old_num_orders) selected_order = 0; // when last travel time is selected, it belongs to order 0
307
308 bool travel = HasBit(this->sel_index, 0);
309
310 if (from != selected_order) {
311 /* Moving from preceding order? */
312 selected_order -= (int)(from <= selected_order);
313 /* Moving to preceding order? */
314 selected_order += (int)(to <= selected_order);
315 } else {
316 /* Now we are modifying the selected order */
317 if (to == INVALID_VEH_ORDER_ID) {
318 /* Deleting selected order */
319 this->CloseChildWindows();
320 this->sel_index = -1;
321 break;
322 } else {
323 /* Moving selected order */
324 selected_order = to;
325 }
326 }
327
328 /* recompute new sel_index */
329 this->sel_index = 2 * selected_order - (int)travel;
330 /* travel time of first order needs special handling */
331 if (this->sel_index == -1) this->sel_index = this->vehicle->GetNumOrders() * 2 - 1;
332 break;
333 }
334 }
335 }
336
337
338 void OnPaint() override
339 {
340 const Vehicle *v = this->vehicle;
341 int selected = this->sel_index;
342
343 this->vscroll->SetCount(v->GetNumOrders() * 2);
344
345 if (v->owner == _local_company) {
346 bool disable = true;
347 if (selected != -1) {
348 const Order *order = v->GetOrder(((selected + 1) / 2) % v->GetNumOrders());
349 if (selected % 2 != 0) {
350 disable = order != nullptr && (order->IsType(OT_CONDITIONAL) || order->IsType(OT_IMPLICIT));
351 } else {
352 disable = order == nullptr || ((!order->IsType(OT_GOTO_STATION) || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) && !order->IsType(OT_CONDITIONAL));
353 }
354 }
355 bool disable_speed = disable || selected % 2 == 0 || v->type == VEH_AIRCRAFT;
356
359 this->SetWidgetDisabledState(WID_VT_CHANGE_SPEED, disable_speed);
360 this->SetWidgetDisabledState(WID_VT_CLEAR_SPEED, disable_speed);
362
363 this->SetWidgetDisabledState(WID_VT_START_DATE, v->orders == nullptr);
365 this->SetWidgetDisabledState(WID_VT_AUTOFILL, v->orders == nullptr);
366 } else {
375 }
376
378
379 this->DrawWidgets();
380 }
381
382 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
383 {
384 switch (widget) {
385 case WID_VT_CAPTION: return GetString(STR_TIMETABLE_TITLE, this->vehicle->index);
386 case WID_VT_EXPECTED: return GetString(this->show_expected ? STR_TIMETABLE_EXPECTED : STR_TIMETABLE_SCHEDULED);
387 default: return this->Window::GetWidgetString(widget, stringid);
388 }
389 }
390
391 std::string GetTimetableTravelString(const Order &order, int i, TextColour &colour) const
392 {
393 colour = (i == this->sel_index) ? TC_WHITE : TC_BLACK;
394
395 if (order.IsType(OT_CONDITIONAL)) {
396 return GetString(STR_TIMETABLE_NO_TRAVEL);
397 }
398
399 if (order.IsType(OT_IMPLICIT)) {
400 colour = ((i == this->sel_index) ? TC_SILVER : TC_GREY) | TC_NO_SHADE;
401 return GetString(STR_TIMETABLE_NOT_TIMETABLEABLE);
402 }
403
404 if (order.IsTravelTimetabled()) {
405 auto [str, value] = GetTimetableParameters(order.GetTimetabledTravel());
406 return order.GetMaxSpeed() != UINT16_MAX
407 ? GetString(STR_TIMETABLE_TRAVEL_FOR_SPEED, str, value, PackVelocity(order.GetMaxSpeed(), this->vehicle->type))
408 : GetString(STR_TIMETABLE_TRAVEL_FOR, str, value);
409 }
410
411 if (order.GetTravelTime() > 0) {
412 auto [str, value] = GetTimetableParameters(order.GetTravelTime());
413 return order.GetMaxSpeed() != UINT16_MAX
414 ? GetString(STR_TIMETABLE_TRAVEL_FOR_SPEED_ESTIMATED, str, value, PackVelocity(order.GetMaxSpeed(), this->vehicle->type))
415 : GetString(STR_TIMETABLE_TRAVEL_FOR_ESTIMATED, str, value);
416 }
417
418 return order.GetMaxSpeed() != UINT16_MAX
419 ? GetString(STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED, PackVelocity(order.GetMaxSpeed(), this->vehicle->type))
420 : GetString(STR_TIMETABLE_TRAVEL_NOT_TIMETABLED);
421 }
422
427 void DrawTimetablePanel(const Rect &r) const
428 {
429 const Vehicle *v = this->vehicle;
430 if (v->GetNumOrders() == 0) return;
431 Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
432 int i = this->vscroll->GetPosition();
433 VehicleOrderID order_id = (i + 1) / 2;
434 bool final_order = false;
435 int selected = this->sel_index;
436
437 bool rtl = _current_text_dir == TD_RTL;
438 int index_column_width = GetStringBoundingBox(GetString(STR_ORDER_INDEX, GetParamMaxValue(v->GetNumOrders(), 2))).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + WidgetDimensions::scaled.hsep_normal;
439 int middle = rtl ? tr.right - index_column_width : tr.left + index_column_width;
440
441 auto orders = v->Orders();
442 while (true) {
443 /* Don't draw anything if it extends past the end of the window. */
444 if (!this->vscroll->IsVisible(i)) break;
445
446 if (i % 2 == 0) {
447 DrawOrderString(v, &orders[order_id], order_id, tr.top, i == selected, true, tr.left, middle, tr.right);
448 if (v->orders->GetNext(order_id) == 0) final_order = true;
449 order_id = v->orders->GetNext(order_id);
450 } else {
451 TextColour colour;
452 std::string string = GetTimetableTravelString(orders[order_id], i, colour);
453
454 DrawString(rtl ? tr.left : middle, rtl ? middle : tr.right, tr.top, string, colour);
455
456 if (final_order) break;
457 }
458
459 i++;
460 tr.top += GetCharacterHeight(FS_NORMAL);
461 }
462 }
463
468 void DrawArrivalDeparturePanel(const Rect &r) const
469 {
470 const Vehicle *v = this->vehicle;
471
472 /* Arrival and departure times are handled in an all-or-nothing approach,
473 * i.e. are only shown if we can calculate all times.
474 * Excluding order lists with only one order makes some things easier. */
475 TimerGameTick::Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0;
476 if (total_time <= 0 || v->GetNumOrders() <= 1 || !v->vehicle_flags.Test(VehicleFlag::TimetableStarted)) return;
477
478 std::vector<TimetableArrivalDeparture> arr_dep(v->GetNumOrders());
479 const VehicleOrderID cur_order = v->cur_real_order_index % v->GetNumOrders();
480
482 int selected = this->sel_index;
483
484 Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
485 bool show_late = this->show_expected && VehicleIsAboveLatenessThreshold(v->lateness_counter, true);
486 TimerGameTick::Ticks offset = show_late ? 0 : -v->lateness_counter;
487
488 for (int i = this->vscroll->GetPosition(); i / 2 < v->GetNumOrders(); ++i) { // note: i is also incremented in the loop
489 /* Don't draw anything if it extends past the end of the window. */
490 if (!this->vscroll->IsVisible(i)) break;
491
492 /* TC_INVALID will skip the colour change. */
493 TextColour tc = show_late ? TC_RED : TC_INVALID;
494 if (i % 2 == 0) {
495 /* Draw an arrival time. */
496 if (arr_dep[i / 2].arrival != Ticks::INVALID_TICKS) {
497 /* First set the offset and text colour based on the expected/scheduled mode and some other things. */
498 TimerGameTick::Ticks this_offset;
499 if (this->show_expected && i / 2 == early_id) {
500 /* Show expected arrival. */
501 this_offset = 0;
502 tc = TC_GREEN;
503 } else {
504 /* Show scheduled arrival. */
505 this_offset = offset;
506 }
507
508 /* Now actually draw the arrival time. */
509 if (_settings_client.gui.timetable_mode == TimetableMode::Seconds) {
510 /* Display seconds from now. */
511 DrawString(tr,
512 GetString(STR_TIMETABLE_ARRIVAL_SECONDS_IN_FUTURE, tc, (arr_dep[i / 2].arrival + offset) / Ticks::TICKS_PER_SECOND),
513 i == selected ? TC_WHITE : TC_BLACK);
514 } else {
515 /* Show a date. */
516 DrawString(tr,
517 GetString(STR_TIMETABLE_ARRIVAL_DATE, tc, TimerGameEconomy::date + (arr_dep[i / 2].arrival + this_offset) / Ticks::DAY_TICKS),
518 i == selected ? TC_WHITE : TC_BLACK);
519 }
520 }
521 } else {
522 /* Draw a departure time. */
523 if (arr_dep[i / 2].departure != Ticks::INVALID_TICKS) {
524 if (_settings_client.gui.timetable_mode == TimetableMode::Seconds) {
525 /* Display seconds from now. */
526 DrawString(tr,
527 GetString(STR_TIMETABLE_DEPARTURE_SECONDS_IN_FUTURE, tc, (arr_dep[i / 2].departure + offset) / Ticks::TICKS_PER_SECOND),
528 i == selected ? TC_WHITE : TC_BLACK);
529 } else {
530 /* Show a date. */
531 DrawString(tr,
532 GetString(STR_TIMETABLE_DEPARTURE_DATE, tc, TimerGameEconomy::date + (arr_dep[i / 2].departure + offset) / Ticks::DAY_TICKS),
533 i == selected ? TC_WHITE : TC_BLACK);
534 }
535 }
536 }
537 tr.top += GetCharacterHeight(FS_NORMAL);
538 }
539 }
540
541 std::string GetTimetableTotalTimeString(TimerGameTick::Ticks total_time) const
542 {
543 auto [str, value] = GetTimetableParameters(total_time);
544 if (!this->vehicle->orders->IsCompleteTimetable()) return GetString(STR_TIMETABLE_TOTAL_TIME_INCOMPLETE, str, value);
545 if (total_time % TicksPerTimetableUnit() == 0) return GetString(STR_TIMETABLE_TOTAL_TIME, str, value);
546 return GetString(STR_TIMETABLE_APPROX_TIME, str, value);
547 }
548
553 void DrawSummaryPanel(const Rect &r) const
554 {
555 const Vehicle *v = this->vehicle;
556 Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
557
558 TimerGameTick::Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0;
559 if (total_time != 0) {
560 DrawString(tr, GetTimetableTotalTimeString(total_time));
561 }
562 tr.top += GetCharacterHeight(FS_NORMAL);
563
564 /* Draw the lateness display, or indicate that the timetable has not started yet. */
565 if (v->timetable_start != 0) {
566 /* We are running towards the first station so we can start the
567 * timetable at the given time. */
568 if (_settings_client.gui.timetable_mode == TimetableMode::Seconds) {
569 /* Real time units use seconds relative to now. */
570 DrawString(tr, GetString(STR_TIMETABLE_STATUS_START_IN_SECONDS, static_cast<TimerGameTick::Ticks>(v->timetable_start - TimerGameTick::counter) / Ticks::TICKS_PER_SECOND));
571 } else {
572 /* Other units use dates. */
573 DrawString(tr, GetString(STR_TIMETABLE_STATUS_START_AT_DATE, STR_JUST_DATE_TINY, GetDateFromStartTick(v->timetable_start)));
574 }
576 /* We aren't running on a timetable yet. */
577 DrawString(tr, STR_TIMETABLE_STATUS_NOT_STARTED);
578 } else if (!VehicleIsAboveLatenessThreshold(abs(v->lateness_counter), false)) {
579 /* We are on time. */
580 DrawString(tr, STR_TIMETABLE_STATUS_ON_TIME);
581 } else {
582 /* We are late. */
583 auto [str, value] = GetTimetableParameters(abs(v->lateness_counter));
584 DrawString(tr, GetString(v->lateness_counter < 0 ? STR_TIMETABLE_STATUS_EARLY : STR_TIMETABLE_STATUS_LATE, str, value));
585 }
586 }
587
588 void DrawWidget(const Rect &r, WidgetID widget) const override
589 {
590 switch (widget) {
592 this->DrawTimetablePanel(r);
593 break;
594 }
595
598 break;
599 }
600
602 this->DrawSummaryPanel(r);
603 break;
604 }
605 }
606 }
607
608 static inline std::tuple<VehicleOrderID, ModifyTimetableFlags> PackTimetableArgs(const Vehicle *v, uint selected, bool speed)
609 {
610 uint order_number = (selected + 1) / 2;
611 ModifyTimetableFlags mtf = (selected % 2 != 0) ? (speed ? MTF_TRAVEL_SPEED : MTF_TRAVEL_TIME) : MTF_WAIT_TIME;
612
613 if (order_number >= v->GetNumOrders()) order_number = 0;
614
615 return { order_number, mtf };
616 }
617
618 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
619 {
620 const Vehicle *v = this->vehicle;
621
622 switch (widget) {
623 case WID_VT_ORDER_VIEW: // Order view button
624 ShowOrdersWindow(v);
625 break;
626
627 case WID_VT_TIMETABLE_PANEL: { // Main panel.
628 int selected = GetOrderFromTimetableWndPt(pt.y, v);
629
630 this->CloseChildWindows();
631 this->sel_index = (selected == INT32_MAX || selected == this->sel_index) ? -1 : selected;
632 break;
633 }
634
635 case WID_VT_START_DATE: // Change the date that the timetable starts.
636 if (_settings_client.gui.timetable_mode == TimetableMode::Seconds) {
638 this->change_timetable_all = _ctrl_pressed;
639 ShowQueryString({}, STR_TIMETABLE_START_SECONDS_QUERY, 6, this, CS_NUMERAL, QueryStringFlag::AcceptUnchanged);
640 } else {
642 [ctrl=_ctrl_pressed](const Window *w, TimerGameEconomy::Date date) {
643 Command<CMD_SET_TIMETABLE_START>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, w->window_number, ctrl, GetStartTickFromDate(date));
644 }
645 );
646 }
647 break;
648
649 case WID_VT_CHANGE_TIME: { // "Wait For" button.
651 int selected = this->sel_index;
652 VehicleOrderID real = (selected + 1) / 2;
653
654 if (real >= v->GetNumOrders()) real = 0;
655
656 const Order *order = v->GetOrder(real);
657 std::string current;
658
659 if (order != nullptr) {
660 uint time = (selected % 2 != 0) ? order->GetTravelTime() : order->GetWaitTime();
661 time /= TicksPerTimetableUnit();
662
663 if (time != 0) {
664 current = GetString(STR_JUST_INT, time);
665 }
666 }
667
668 this->change_timetable_all = _ctrl_pressed && (order != nullptr);
669 ShowQueryString(current, STR_TIMETABLE_CHANGE_TIME_QUERY, 31, this, CS_NUMERAL, QueryStringFlag::AcceptUnchanged);
670 break;
671 }
672
673 case WID_VT_CHANGE_SPEED: { // Change max speed button.
675 int selected = this->sel_index;
676 VehicleOrderID real = (selected + 1) / 2;
677
678 if (real >= v->GetNumOrders()) real = 0;
679
680 std::string current;
681 const Order *order = v->GetOrder(real);
682 if (order != nullptr) {
683 if (order->GetMaxSpeed() != UINT16_MAX) {
684 current = GetString(STR_JUST_INT, ConvertKmhishSpeedToDisplaySpeed(order->GetMaxSpeed(), v->type));
685 }
686 }
687
688 this->change_timetable_all = _ctrl_pressed && (order != nullptr);
689 ShowQueryString(current, STR_TIMETABLE_CHANGE_SPEED_QUERY, 31, this, CS_NUMERAL, {});
690 break;
691 }
692
693 case WID_VT_CLEAR_TIME: { // Clear waiting time.
694 auto [order_id, mtf] = PackTimetableArgs(v, this->sel_index, false);
695 if (_ctrl_pressed) {
696 Command<CMD_BULK_CHANGE_TIMETABLE>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, mtf, 0);
697 } else {
698 Command<CMD_CHANGE_TIMETABLE>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, 0);
699 }
700 break;
701 }
702
703 case WID_VT_CLEAR_SPEED: { // Clear max speed button.
704 auto [order_id, mtf] = PackTimetableArgs(v, this->sel_index, true);
705 if (_ctrl_pressed) {
706 Command<CMD_BULK_CHANGE_TIMETABLE>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, mtf, UINT16_MAX);
707 } else {
708 Command<CMD_CHANGE_TIMETABLE>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, UINT16_MAX);
709 }
710 break;
711 }
712
713 case WID_VT_RESET_LATENESS: // Reset the vehicle's late counter.
714 Command<CMD_SET_VEHICLE_ON_TIME>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, _ctrl_pressed);
715 break;
716
717 case WID_VT_AUTOFILL: { // Autofill the timetable.
719 break;
720 }
721
722 case WID_VT_EXPECTED:
723 this->show_expected = !this->show_expected;
724 break;
725
727 ShowVehicleListWindow(v);
728 break;
729 }
730
731 this->SetDirty();
732 }
733
734 void OnQueryTextFinished(std::optional<std::string> str) override
735 {
736 if (!str.has_value()) return;
737
738 const Vehicle *v = this->vehicle;
739 uint64_t val = ParseInteger<uint64_t>(*str, 10, true).value_or(0);
740 auto [order_id, mtf] = PackTimetableArgs(v, this->sel_index, query_widget == WID_VT_CHANGE_SPEED);
741
742 switch (query_widget) {
743 case WID_VT_CHANGE_SPEED: {
745
746 if (this->change_timetable_all) {
747 Command<CMD_BULK_CHANGE_TIMETABLE>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, mtf, ClampTo<uint16_t>(val));
748 } else {
749 Command<CMD_CHANGE_TIMETABLE>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, ClampTo<uint16_t>(val));
750 }
751 break;
752 }
753
755 val *= TicksPerTimetableUnit();
756
757 if (this->change_timetable_all) {
758 Command<CMD_BULK_CHANGE_TIMETABLE>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, mtf, ClampTo<uint16_t>(val));
759 } else {
760 Command<CMD_CHANGE_TIMETABLE>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, ClampTo<uint16_t>(val));
761 }
762 break;
763
764 case WID_VT_START_DATE: {
766 Command<CMD_SET_TIMETABLE_START>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, this->change_timetable_all, start_tick);
767 break;
768 }
769
770 default:
771 NOT_REACHED();
772 }
773 }
774
775 void OnResize() override
776 {
777 /* Update the scroll bar */
778 this->vscroll->SetCapacityFromWidget(this, WID_VT_TIMETABLE_PANEL, WidgetDimensions::scaled.framerect.Vertical());
779 }
780
785 {
786 this->GetWidget<NWidgetStacked>(WID_VT_ARRIVAL_DEPARTURE_SELECTION)->SetDisplayedPlane(_settings_client.gui.timetable_arrival_departure ? 0 : SZSP_NONE);
787 this->GetWidget<NWidgetStacked>(WID_VT_EXPECTED_SELECTION)->SetDisplayedPlane(_settings_client.gui.timetable_arrival_departure ? 0 : 1);
788 }
789
794 if (_settings_client.gui.timetable_mode == TimetableMode::Seconds) {
795 this->SetDirty();
796 }
797 }};
798};
799
800static constexpr NWidgetPart _nested_timetable_widgets[] = {
802 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
803 NWidget(WWT_CAPTION, COLOUR_GREY, WID_VT_CAPTION),
804 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_ORDER_VIEW), SetMinimalSize(61, 14), SetStringTip(STR_TIMETABLE_ORDER_VIEW, STR_TIMETABLE_ORDER_VIEW_TOOLTIP),
805 NWidget(WWT_SHADEBOX, COLOUR_GREY),
806 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
807 NWidget(WWT_STICKYBOX, COLOUR_GREY),
808 EndContainer(),
810 NWidget(WWT_PANEL, COLOUR_GREY, WID_VT_TIMETABLE_PANEL), SetMinimalSize(388, 82), SetResize(1, 10), SetToolTip(STR_TIMETABLE_TOOLTIP), SetScrollbar(WID_VT_SCROLLBAR), EndContainer(),
813 EndContainer(),
815 EndContainer(),
820 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_CHANGE_TIME), SetResize(1, 0), SetFill(1, 1), SetStringTip(STR_TIMETABLE_CHANGE_TIME, STR_TIMETABLE_WAIT_TIME_TOOLTIP),
821 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_CLEAR_TIME), SetResize(1, 0), SetFill(1, 1), SetStringTip(STR_TIMETABLE_CLEAR_TIME, STR_TIMETABLE_CLEAR_TIME_TOOLTIP),
822 EndContainer(),
824 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_CHANGE_SPEED), SetResize(1, 0), SetFill(1, 1), SetStringTip(STR_TIMETABLE_CHANGE_SPEED, STR_TIMETABLE_CHANGE_SPEED_TOOLTIP),
825 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_CLEAR_SPEED), SetResize(1, 0), SetFill(1, 1), SetStringTip(STR_TIMETABLE_CLEAR_SPEED, STR_TIMETABLE_CLEAR_SPEED_TOOLTIP),
826 EndContainer(),
828 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_START_DATE), SetResize(1, 0), SetFill(1, 1), SetStringTip(STR_TIMETABLE_START, STR_TIMETABLE_START_TOOLTIP),
829 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_RESET_LATENESS), SetResize(1, 0), SetFill(1, 1), SetStringTip(STR_TIMETABLE_RESET_LATENESS, STR_TIMETABLE_RESET_LATENESS_TOOLTIP),
830 EndContainer(),
832 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_AUTOFILL), SetResize(1, 0), SetFill(1, 1), SetStringTip(STR_TIMETABLE_AUTOFILL, STR_TIMETABLE_AUTOFILL_TOOLTIP),
834 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_EXPECTED), SetResize(1, 0), SetFill(1, 1), SetToolTip(STR_TIMETABLE_EXPECTED_TOOLTIP),
835 NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(),
836 EndContainer(),
837 EndContainer(),
838 EndContainer(),
840 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VT_SHARED_ORDER_LIST), SetFill(0, 1), SetSpriteTip(SPR_SHARED_ORDERS_ICON, STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP),
841 NWidget(WWT_RESIZEBOX, COLOUR_GREY), SetFill(0, 1),
842 EndContainer(),
843 EndContainer(),
844};
845
846static WindowDesc _timetable_desc(
847 WDP_AUTO, "view_vehicle_timetable", 400, 130,
850 _nested_timetable_widgets
851);
852
858{
861 AllocateWindowDescFront<TimetableWindow>(_timetable_desc, v->index);
862}
@ AutofillTimetable
Whether the vehicle should fill in the timetable automatically.
@ TimetableStarted
Whether the vehicle has started running on the timetable yet.
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
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.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
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:2423
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:2497
size_type GetPosition() const
Gets the position of the first visible element in the list.
static constexpr TimerGameTick::Ticks DAY_TICKS
1 day is 74 ticks; TimerGameCalendar::date_fract used to be uint16_t and incremented by 885.
static constexpr TimerGameTick::Ticks INVALID_TICKS
Representation of an invalid number of ticks.
static constexpr TimerGameTick::Ticks TICKS_PER_SECOND
Estimation of how many ticks fit in a single second.
static constexpr TimerGame< struct Economy >::Year MAX_YEAR
MAX_YEAR, nicely rounded value of the number of years that can be encoded in a single 32 bits date,...
static Date date
Current date in days (day counter).
static Year year
Current year, starting at 0.
static bool UsingWallclockUnits(bool newgame=false)
Check if we are using wallclock units.
static DateFract date_fract
Fractional part of the day.
uint64_t TickCounter
The type that the tick counter is stored in.
static TickCounter counter
Monotonic counter, in ticks, since start of game.
int32_t Ticks
The type to store ticks in.
@ NONE
These timers can be executed in any order; the order is not relevant.
static constexpr Date DateAtStartOfYear(Year year)
Calculate the date of the first day of a given year.
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:30
int hsep_wide
Wide horizontal spacing.
Definition window_gui.h:62
Functions related to commands.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Functions related to companies.
void ShowSetDateWindow(Window *parent, int window_number, TimerGameEconomy::Date initial_date, TimerGameEconomy::Year min_year, TimerGameEconomy::Year max_year, SetDateCallback &&callback)
Create the new 'set date' window.
Definition date_gui.cpp:214
Functions related to the graphical selection of a date.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:87
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition gfx.cpp:966
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:895
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:666
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:39
Functions related to the gfx engine.
@ FS_SMALL
Index of the small font in the font tables.
Definition gfx_type.h:250
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:249
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 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:966
GUI functions that shouldn't be here.
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 abs(const T a)
Returns the absolute value of (scalar) variable.
Definition math_func.hpp:23
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.
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.
uint8_t VehicleOrderID
The index of an order within its current vehicle (not pool related)
Definition order_type.h:18
static const VehicleOrderID INVALID_VEH_ORDER_ID
Invalid vehicle order index (sentinel)
Definition order_type.h:39
@ ONSF_NO_STOP_AT_DESTINATION_STATION
The vehicle will stop at any station it passes except the destination.
Definition order_type.h:90
@ ONSF_STOP_EVERYWHERE
The vehicle will stop at any station it passes and the destination.
Definition order_type.h:88
ModifyTimetableFlags
Enumeration for the data to set in CmdChangeTimetable.
Definition order_type.h:186
@ MTF_TRAVEL_TIME
Set travel time.
Definition order_type.h:188
@ MTF_WAIT_TIME
Set wait time.
Definition order_type.h:187
@ MTF_TRAVEL_SPEED
Set max travel speed.
Definition order_type.h:189
A number of safeguards to prevent using unsafe methods.
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
Types related to global configuration settings.
This file contains all sprite-related enums and defines.
Definition of base types and functions in a cross-platform compatible way.
Parse strings.
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
uint ConvertDisplaySpeedToKmhishSpeed(uint speed, VehicleType type)
Convert the given display speed to the km/h-ish speed.
Definition strings.cpp:1000
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:424
uint ConvertKmhishSpeedToDisplaySpeed(uint speed, VehicleType type)
Convert the given km/h-ish speed to the display speed.
Definition strings.cpp:990
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:56
uint64_t GetParamMaxDigits(uint count, FontSize size)
Get some number that is suitable for string size computations.
Definition strings.cpp:218
Functions related to OTTD's strings.
int64_t PackVelocity(uint speed, VehicleType type)
Pack velocity and vehicle type for use with SCC_VELOCITY string parameter.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
@ TD_RTL
Text is written right-to-left by default.
TimerGameTick::Ticks current_order_time
How many ticks have passed since this order started.
VehicleOrderID cur_real_order_index
The index to the current real (non-implicit) order.
VehicleFlags vehicle_flags
Used for gradual loading and other miscellaneous things (.
TimerGameTick::TickCounter timetable_start
At what tick of TimerGameTick::counter the vehicle should start its timetable.
TimerGameTick::Ticks lateness_counter
How many ticks late (or early if negative) this vehicle is.
VehicleType type
Type of vehicle.
GUISettings gui
settings related to the GUI
Dimensions (a width and height) of a rectangle in 2D.
bool timetable_arrival_departure
show arrivals and departures in vehicle timetables
TimetableMode timetable_mode
Time units for timetables: days, seconds, or ticks.
Partial widget specification to allow NWidgets to be written nested.
TimerGameTick::Ticks GetTimetableDurationIncomplete() const
Gets the known duration of the vehicles timetable even if the timetable is not complete.
Definition order_base.h:417
bool IsCompleteTimetable() const
Checks whether all orders of the list have a filled timetable.
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:352
uint16_t GetTimetabledTravel() const
Get the time in ticks a vehicle should take to reach the destination or 0 if it's not timetabled.
Definition order_base.h:186
uint16_t GetMaxSpeed() const
Get the maxmimum speed in km-ish/h a vehicle is allowed to reach on the way to the destination.
Definition order_base.h:197
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition order_base.h:66
uint16_t GetWaitTime() const
Get the time in ticks a vehicle will probably wait at the destination (timetabled or not).
Definition order_base.h:188
bool IsWaitTimetabled() const
Does this order have an explicit wait time set?
Definition order_base.h:179
bool IsTravelTimetabled() const
Does this order have an explicit travel time set?
Definition order_base.h:181
uint16_t GetTravelTime() const
Get the time in ticks a vehicle will probably take to reach the destination (timetabled or not).
Definition order_base.h:190
OrderNonStopFlags GetNonStopType() const
At which stations must we stop?
Definition order_base.h:136
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.
Templated helper to make a type-safe 'typedef' representing a single POD value.
Container for the arrival/departure dates of a vehicle.
TimerGameTick::Ticks arrival
The arrival time.
TimerGameTick::Ticks departure
The departure time.
void OnResize() override
Called after the window got resized.
void DrawTimetablePanel(const Rect &r) const
Helper function to draw the timetable panel.
bool set_start_date_all
Set start date using minutes text entry for all timetable entries (ctrl-click) action.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
void DrawSummaryPanel(const Rect &r) const
Helper function to draw the summary panel.
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
void OnQueryTextFinished(std::optional< std::string > str) override
The query window opened from this window has closed.
const Vehicle * vehicle
Vehicle monitored by the window.
void UpdateSelectionStates()
Update the selection state of the arrival/departure data.
Scrollbar * vscroll
The scrollbar.
bool show_expected
Whether we show expected arrival or scheduled.
const IntervalTimer< TimerGameTick > redraw_interval
In real-time mode, the timetable GUI shows relative times and needs to be redrawn every second.
void OnPaint() override
The window must be repainted.
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.
void DrawArrivalDeparturePanel(const Rect &r) const
Helper function to draw the arrival and departure panel.
VehicleTimetableWidgets query_widget
Which button was clicked to open the query text input?
bool change_timetable_all
Set wait time or speed for all timetable entries (ctrl-click) action.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
static bool BuildArrivalDepartureList(const Vehicle *v, std::vector< TimetableArrivalDeparture > &table)
Build the arrival-departure list for a given vehicle.
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.
Order current_order
The current order (+ status, like: loading)
OrderList * orders
Pointer to the order list for this vehicle.
Owner owner
Which company owns the vehicle?
High level window description.
Definition window_gui.h:167
Number to differentiate different windows of the same class.
Data structure for an opened window.
Definition window_gui.h:273
void ReInit(int rx=0, int ry=0, bool reposition=false)
Re-initialize a window, and optionally change its size.
Definition window.cpp:978
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1789
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:764
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:504
void CloseChildWindows(WindowClass wc=WC_INVALID) const
Close all children a window might have in a head-recursive manner.
Definition window.cpp:1075
ResizeInfo resize
Resize information.
Definition window_gui.h:314
void DisableWidget(WidgetID widget_index)
Sets a widget to disabled.
Definition window_gui.h:391
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1779
Owner owner
The owner of the content shown in this window. Company colour is acquired from this variable.
Definition window_gui.h:316
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition window_gui.h:441
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:313
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:381
int width
width of the window (number of pixels to the right in x direction)
Definition window_gui.h:311
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:302
Stuff related to the text buffer GUI.
@ AcceptUnchanged
return success even when the text didn't change
Definition of Interval and OneShot timers.
Definition of the game-economy-timer.
Definition of the tick-based game-timer.
Definition of the Window system.
Functions related to time tabling.
static const TimerGameEconomy::Year MAX_TIMETABLE_START_YEARS
The maximum start date offset, in economy years.
Definition timetable.h:18
TimerGameEconomy::Date GetDateFromStartTick(TimerGameTick::TickCounter start_tick)
Get a date from a given start tick of timetable.
Command definitions related to timetables.
static TimerGameTick::Ticks TicksPerTimetableUnit()
Get the number of ticks in the current timetable display unit.
void ShowTimetableWindow(const Vehicle *v)
Show the timetable for a given vehicle.
static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID start, bool travelling, std::vector< TimetableArrivalDeparture > &table, TimerGameTick::Ticks offset)
Fill the table with arrivals and departures.
std::pair< StringParameter, StringParameter > GetTimetableParameters(TimerGameTick::Ticks ticks)
Get parameters to format timetable time.
bool VehicleIsAboveLatenessThreshold(TimerGameTick::Ticks ticks, bool round_to_day)
Determine if a vehicle should be shown as late or early, using a threshold depending on the timetable...
static bool CanDetermineTimeTaken(const Order &order, bool travelling)
Check whether it is possible to determine how long the order takes.
Types related to the timetable widgets.
VehicleTimetableWidgets
Widgets of the TimetableWindow class.
@ WID_VT_CHANGE_TIME
Change time button.
@ WID_VT_ARRIVAL_DEPARTURE_PANEL
Panel with the expected/scheduled arrivals.
@ WID_VT_ARRIVAL_DEPARTURE_SELECTION
Disable/hide the arrival departure panel.
@ WID_VT_CLEAR_SPEED
Clear speed limit button.
@ WID_VT_EXPECTED
Toggle between expected and scheduled arrivals.
@ WID_VT_CHANGE_SPEED
Change speed limit button.
@ WID_VT_TIMETABLE_PANEL
Timetable panel.
@ WID_VT_AUTOFILL
Autofill button.
@ WID_VT_SCROLLBAR
Scrollbar for the panel.
@ WID_VT_RESET_LATENESS
Reset lateness button.
@ WID_VT_SHARED_ORDER_LIST
Show the shared order list.
@ WID_VT_SUMMARY_PANEL
Summary panel.
@ WID_VT_CAPTION
Caption of the window.
@ WID_VT_START_DATE
Start date button.
@ WID_VT_EXPECTED_SELECTION
Disable/hide the expected selection button.
@ WID_VT_ORDER_VIEW
Order view.
@ WID_VT_CLEAR_TIME
Clear time button.
Base class for all vehicles.
Functions related to the vehicle's GUIs.
@ 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
@ VEH_AIRCRAFT
Aircraft vehicle type.
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:67
@ 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:58
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition widget_type.h:56
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition widget_type.h:53
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition widget_type.h:77
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:69
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:61
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition widget_type.h:60
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition widget_type.h:57
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:72
@ SZSP_NONE
Display plane with zero size in both directions (none filling and resizing).
@ 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:1193
Window functions not directly related to making/drawing windows.
Functions, definitions and such used only by the GUI.
@ Construction
This window is used for construction; close it whenever changing company.
@ WDP_AUTO
Find a place automatically.
Definition window_gui.h:144
int WidgetID
Widget ID.
Definition window_type.h:20
@ 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: