Changeset - r13750:4428487b0600
[Not reviewed]
master
0 6 0
rubidium - 15 years ago 2009-11-25 16:17:06
rubidium@openttd.org
(svn r18285) -Feature: show the expected arrival/departure dates in the timetable window. Based on work by PhilSophus.
6 files changed with 242 insertions and 11 deletions:
0 comments (0 inline, 0 general)
src/lang/english.txt
Show inline comments
 
@@ -1177,6 +1177,7 @@ STR_CONFIG_SETTING_LOADING_INDICATORS_OW
 
STR_CONFIG_SETTING_LOADING_INDICATORS_ALL                       :All companies
 
STR_CONFIG_SETTING_TIMETABLE_ALLOW                              :{LTBLUE}Enable timetabling for vehicles: {ORANGE}{STRING1}
 
STR_CONFIG_SETTING_TIMETABLE_IN_TICKS                           :{LTBLUE}Show timetable in ticks rather than days: {ORANGE}{STRING1}
 
STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE             :{LTBLUE}Show arrival and departure in timetables: {ORANGE}{STRING1}
 
STR_CONFIG_SETTING_QUICKGOTO                                    :{LTBLUE}Quick creation of vehicle orders: {ORANGE}{STRING1}
 
STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE                            :{LTBLUE}Default rail type (after new game/game load): {ORANGE}{STRING1}
 
STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_RAIL                       :Normal Rail
 
@@ -3151,6 +3152,22 @@ STR_TIMETABLE_RESET_LATENESS_TOOLTIP    
 
STR_TIMETABLE_AUTOFILL                                          :{BLACK}Autofill
 
STR_TIMETABLE_AUTOFILL_TOOLTIP                                  :{BLACK}Fill the timetable automatically with the values from the next journey (Ctrl+Click to try to keep waiting times)
 

	
 
STR_TIMETABLE_EXPECTED                                          :{BLACK}Expected
 
STR_TIMETABLE_SCHEDULED                                         :{BLACK}Scheduled
 
STR_TIMETABLE_EXPECTED_TOOLTIP                                  :{BLACK}Switch between expected and schedule
 

	
 
### Do not separate or reorder ###
 
STR_TIMETABLE_ARRIVAL                                           :A:{SETX 30}{STRING1}
 
STR_TIMETABLE_ARRIVAL_EARLY                                     :A:{SETX 30}{GREEN}{STRING1}
 
STR_TIMETABLE_ARRIVAL_LATE                                      :A:{SETX 30}{RED}{STRING1}
 
#####
 

	
 
### Do not separate or reorder ###
 
STR_TIMETABLE_DEPARTURE                                         :D:{SETX 30}{STRING1}
 
STR_TIMETABLE_DEPARTURE_EARLY                                   :D:{SETX 30}{GREEN}{STRING1}
 
STR_TIMETABLE_DEPARTURE_LATE                                    :D:{SETX 30}{RED}{STRING1}
 
#####
 

	
 
# AI debug window
 
STR_AI_DEBUG                                                    :{WHITE}AI Debug
 
STR_AI_DEBUG_NAME_TOOLTIP                                       :{BLACK}Name of the AI
src/settings.cpp
Show inline comments
 
@@ -763,6 +763,11 @@ static bool TownFoundingChanged(int32 p1
 
	return true;
 
}
 

	
 
static bool InvalidateVehTimetableWindow(int32 p1)
 
{
 
	InvalidateWindowClassesData(WC_VEHICLE_TIMETABLE, -2);
 
	return true;
 
}
 

	
 
/*
 
 * A: competitors
src/settings_gui.cpp
Show inline comments
 
@@ -1238,6 +1238,7 @@ static SettingEntry _settings_ui[] = {
 
	SettingEntry("gui.pause_on_newgame"),
 
	SettingEntry("gui.advanced_vehicle_list"),
 
	SettingEntry("gui.timetable_in_ticks"),
 
	SettingEntry("gui.timetable_arrival_departure"),
 
	SettingEntry("gui.quick_goto"),
 
	SettingEntry("gui.default_rail_type"),
 
	SettingEntry("gui.always_build_infrastructure"),
src/settings_type.h
Show inline comments
 
@@ -76,6 +76,7 @@ struct GUISettings {
 
	uint8  right_mouse_btn_emulation;        ///< should we emulate right mouse clicking?
 
	uint8  scrollwheel_scrolling;            ///< scrolling using the scroll wheel?
 
	uint8  scrollwheel_multiplier;           ///< how much 'wheel' per incoming event from the OS?
 
	bool   timetable_arrival_departure;      ///< show arrivals and departures in vehicle timetables
 
	bool   left_mouse_btn_scrolling;         ///< left mouse button scroll
 
	bool   pause_on_newgame;                 ///< whether to start new games paused or not
 
	bool   enable_signal_gui;                ///< show the signal GUI when the signal button is pressed
src/table/settings.h
Show inline comments
 
@@ -33,6 +33,7 @@ static int32 CheckNoiseToleranceLevel(co
 
static bool CheckFreeformEdges(int32 p1);
 
static bool ChangeDynamicEngines(int32 p1);
 
static bool StationCatchmentChanged(int32 p1);
 
static bool InvalidateVehTimetableWindow(int32 p1);
 

	
 
#ifdef ENABLE_NETWORK
 
static bool UpdateClientName(int32 p1);
 
@@ -549,7 +550,8 @@ const SettingDesc _settings[] = {
 
	  SDTC_VAR(gui.scrollwheel_multiplier,    SLE_UINT8, S,  0,     5,        1,       15, 1, STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER,      NULL),
 
	 SDTC_BOOL(gui.pause_on_newgame,                     S,  0, false,                        STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME,           NULL),
 
	  SDTC_VAR(gui.advanced_vehicle_list,     SLE_UINT8, S, MS,     1,        0,        2, 0, STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS,      NULL),
 
	 SDTC_BOOL(gui.timetable_in_ticks,                   S,  0, false,                        STR_CONFIG_SETTING_TIMETABLE_IN_TICKS,          NULL),
 
	 SDTC_BOOL(gui.timetable_in_ticks,                   S,  0, false,                        STR_CONFIG_SETTING_TIMETABLE_IN_TICKS,          InvalidateVehTimetableWindow),
 
	 SDTC_BOOL(gui.timetable_arrival_departure,          S,  0,  true,                        STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE, InvalidateVehTimetableWindow),
 
	 SDTC_BOOL(gui.quick_goto,                           S,  0, false,                        STR_CONFIG_SETTING_QUICKGOTO,                   NULL),
 
	  SDTC_VAR(gui.loading_indicators,        SLE_UINT8, S, MS,     1,        0,        2, 0, STR_CONFIG_SETTING_LOADING_INDICATORS,          RedrawScreen),
 
	  SDTC_VAR(gui.default_rail_type,         SLE_UINT8, S, MS,     4,        0,        6, 0, STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE,           NULL),
src/timetable_gui.cpp
Show inline comments
 
@@ -20,6 +20,7 @@
 
#include "string_func.h"
 
#include "gfx_func.h"
 
#include "company_func.h"
 
#include "date_func.h"
 

	
 
#include "table/strings.h"
 

	
 
@@ -27,12 +28,23 @@ enum TimetableViewWindowWidgets {
 
	TTV_CAPTION,
 
	TTV_ORDER_VIEW,
 
	TTV_TIMETABLE_PANEL,
 
	TTV_FAKE_SCROLLBAR,               ///< So the timetable panel 'sees' the scrollbar too
 
	TTV_ARRIVAL_DEPARTURE_PANEL,      ///< Panel with the expected/scheduled arrivals
 
	TTV_SCROLLBAR,
 
	TTV_SUMMARY_PANEL,
 
	TTV_CHANGE_TIME,
 
	TTV_CLEAR_TIME,
 
	TTV_RESET_LATENESS,
 
	TTV_AUTOFILL,
 
	TTV_EXPECTED,                    ///< Toggle between expected and scheduled arrivals
 
	TTV_ARRIVAL_DEPARTURE_SELECTION, ///< Disable/hide the arrival departure panel
 
	TTV_EXPECTED_SELECTION,          ///< Disable/hide the expected selection button
 
};
 

	
 
/** Container for the arrival/departure dates of a vehicle */
 
struct TimetableArrivalDeparture {
 
	Ticks arrival;   ///< The arrival time
 
	Ticks departure; ///< The departure time
 
};
 

	
 
/**
 
@@ -52,21 +64,137 @@ void SetTimetableParams(int param1, int 
 
	}
 
}
 

	
 
/**
 
 * Sets the arrival or departure string and parameters.
 
 * @param param1 the first DParam to fill
 
 * @param param2 the second DParam to fill
 
 * @param ticks  the number of ticks to 'draw'
 
 */
 
static void SetArrivalDepartParams(int param1, int param2, Ticks ticks)
 
{
 
	SetDParam(param1, STR_JUST_DATE_TINY);
 
	SetDParam(param2, _date + (ticks / DAY_TICKS));
 
}
 

	
 
/**
 
 * Check whether it is possible to determine how long the order takes.
 
 * @param order the order to check.
 
 * @param travelling whether we are interested in the travel or the wait part.
 
 * @return true if the travel/wait time can be used.
 
 */
 
static bool CanDetermineTimeTaken(const Order *order, bool travelling)
 
{
 
	/* Current order is conditional */
 
	if (order->IsType(OT_CONDITIONAL)) return false;
 
	/* No travel time and we have not already finished travelling */
 
	if (travelling && order->travel_time == 0) return false;
 
	/* No wait time but we are loading at this timetabled station */
 
	if (!travelling && order->wait_time == 0 && order->IsType(OT_GOTO_STATION) && !(order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) return false;
 

	
 
	return true;
 
}
 

	
 

	
 
/**
 
 * Fill the table with arrivals and departures
 
 * @param v Vehicle which must have at least 2 orders.
 
 * @param start order index to start at
 
 * @param travelling Are we still in the travelling part of the start order
 
 * @param table Fill in arrival and departures including intermediate orders
 
 * @param offset Add this value to result and all arrivals and departures
 
 */
 
static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID start, bool travelling, TimetableArrivalDeparture *table, Ticks offset)
 
{
 
	assert(table != NULL);
 
	assert(v->GetNumOrders() >= 2);
 
	assert(start < v->GetNumOrders());
 

	
 
	Ticks sum = offset;
 
	VehicleOrderID i = start;
 
	const Order *order = v->GetOrder(i);
 

	
 
	/* Pre-initialize with unknown time */
 
	for (int i = 0; i < v->GetNumOrders(); ++i) {
 
		table[i].arrival = table[i].departure = INVALID_TICKS;
 
	}
 

	
 
	/* Cyclically loop over all orders until we reach the current one again.
 
	 * As we may start at the current order, do a post-checking loop */
 
	do {
 
		if (travelling || i != start) {
 
			if (!CanDetermineTimeTaken(order, true)) return;
 
			sum += order->travel_time;
 
			table[i].arrival = sum;
 
		}
 

	
 
		if (!CanDetermineTimeTaken(order, false)) return;
 
		sum += order->wait_time;
 
		table[i].departure = sum;
 

	
 
		++i;
 
		order = order->next;
 
		if (i >= v->GetNumOrders()) {
 
			i = 0;
 
			assert(order == NULL);
 
			order = v->orders.list->GetFirstOrder();
 
		}
 
	} while (i != start);
 

	
 
	/* When loading at a scheduled station we still have to treat the
 
	 * travelling part of the first order. */
 
	if (!travelling) {
 
		if (!CanDetermineTimeTaken(order, true)) return;
 
		sum += order->travel_time;
 
		table[i].arrival = sum;
 
	}
 
}
 

	
 

	
 
struct TimetableWindow : Window {
 
	int sel_index;
 
	const Vehicle *vehicle; ///< Vehicle monitored by the window.
 
	bool show_expected;     ///< Whether we show expected arrival or scheduled
 

	
 
	TimetableWindow(const WindowDesc *desc, WindowNumber window_number) : Window()
 
	TimetableWindow(const WindowDesc *desc, WindowNumber window_number) :
 
			Window(),
 
			sel_index(-1),
 
			vehicle(Vehicle::Get(window_number)),
 
			show_expected(true)
 
	{
 
		this->vehicle = Vehicle::Get(window_number);
 
		this->InitNested(desc, window_number);
 
		this->CreateNestedTree(desc);
 
		this->UpdateSelectionStates();
 
		this->FinishInitNested(desc, window_number);
 

	
 
		this->owner = this->vehicle->owner;
 
		this->sel_index = -1;
 
	}
 

	
 
	/**
 
	 * Build the arrival-departure list for a given vehicle
 
	 * @param v the vehicle to make the list for
 
	 * @param table the table to fill
 
	 * @return if next arrival will be early
 
	 */
 
	static bool BuildArrivalDepartureList(const Vehicle *v, TimetableArrivalDeparture *table)
 
	{
 
		assert(HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED));
 

	
 
		bool travelling = (!v->current_order.IsType(OT_LOADING) || v->current_order.GetNonStopType() == ONSF_STOP_EVERYWHERE);
 
		Ticks start_time = _date_fract - v->current_order_time;
 

	
 
		FillTimetableArrivalDepartureTable(v, v->cur_order_index % v->GetNumOrders(), travelling, table, start_time);
 

	
 
		return (travelling && v->lateness_counter < 0);
 
	}
 

	
 
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
 
	{
 
		switch (widget) {
 
			case TTV_ARRIVAL_DEPARTURE_PANEL:
 
				SetDParam(0, STR_JUST_DATE_TINY);
 
				SetDParam(1, MAX_YEAR * DAYS_IN_YEAR);
 
				size->width = GetStringBoundingBox(STR_TIMETABLE_ARRIVAL).width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
 
				/* fall through */
 
			case TTV_ARRIVAL_DEPARTURE_SELECTION:
 
			case TTV_TIMETABLE_PANEL:
 
				resize->height = FONT_HEIGHT_NORMAL;
 
				size->height = WD_FRAMERECT_TOP + 8 * resize->height + WD_FRAMERECT_BOTTOM;
 
@@ -105,6 +233,11 @@ struct TimetableWindow : Window {
 
				this->sel_index = -1;
 
				break;
 

	
 
			case -2:
 
				this->UpdateSelectionStates();
 
				this->ReInit();
 
				break;
 

	
 
			default: {
 
				/* Moving an order. If one of these is INVALID_VEH_ORDER_ID, then
 
				 * the order is being created / removed */
 
@@ -187,7 +320,10 @@ struct TimetableWindow : Window {
 

	
 
	virtual void SetStringParameters(int widget) const
 
	{
 
		if (widget == TTV_CAPTION) SetDParam(0, this->vehicle->index);
 
		switch (widget) {
 
			case TTV_CAPTION: SetDParam(0, this->vehicle->index); break;
 
			case TTV_EXPECTED: SetDParam(0, this->show_expected ? STR_TIMETABLE_EXPECTED : STR_TIMETABLE_SCHEDULED); break;
 
		}
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
@@ -241,6 +377,55 @@ struct TimetableWindow : Window {
 
				break;
 
			}
 

	
 
			case TTV_ARRIVAL_DEPARTURE_PANEL: {
 
				/* Arrival and departure times are handled in an all-or-nothing approach,
 
				 * i.e. are only shown if we can calculate all times.
 
				 * Excluding order lists with only one order makes some things easier.
 
				 */
 
				Ticks total_time = v->orders.list != NULL ? v->orders.list->GetTimetableDurationIncomplete() : 0;
 
				if (total_time <= 0 || v->GetNumOrders() <= 1 || !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) break;
 

	
 
				TimetableArrivalDeparture *arr_dep = AllocaM(TimetableArrivalDeparture, v->GetNumOrders());
 
				const VehicleOrderID cur_order = v->cur_order_index % v->GetNumOrders();
 

	
 
				VehicleOrderID earlyID = BuildArrivalDepartureList(v, arr_dep) ? cur_order : (VehicleOrderID)INVALID_VEH_ORDER_ID;
 

	
 
				int y = r.top + WD_FRAMERECT_TOP;
 

	
 
				Ticks offset;
 
				StringID str_offset;
 
				if (this->show_expected && v->lateness_counter > DAY_TICKS) {
 
					offset = 0;
 
					str_offset = STR_TIMETABLE_ARRIVAL_LATE - STR_TIMETABLE_ARRIVAL;
 
				} else {
 
					offset = -v->lateness_counter;
 
					str_offset = 0;
 
				}
 

	
 
				for (int i = this->vscroll.GetPosition(); i / 2 < v->GetNumOrders(); ++i) { // note: i is also incremented in the loop
 
					/* Don't draw anything if it extends past the end of the window. */
 
					if (!this->vscroll.IsVisible(i)) break;
 

	
 
					if (i % 2 == 0) {
 
						if (arr_dep[i / 2].arrival != INVALID_TICKS) {
 
							if (this->show_expected && i / 2 == earlyID) {
 
								SetArrivalDepartParams(0, 1, arr_dep[i / 2].arrival);
 
								DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_TIMETABLE_ARRIVAL_EARLY, i == selected ? TC_WHITE : TC_BLACK);
 
							} else {
 
								SetArrivalDepartParams(0, 1, arr_dep[i / 2].arrival + offset);
 
								DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_TIMETABLE_ARRIVAL + str_offset, i == selected ? TC_WHITE : TC_BLACK);
 
							}
 
						}
 
					} else {
 
						if (arr_dep[i / 2].departure != INVALID_TICKS) {
 
							SetArrivalDepartParams(0, 1, arr_dep[i/2].departure + offset);
 
							DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_TIMETABLE_DEPARTURE + str_offset, i == selected ? TC_WHITE : TC_BLACK);
 
						}
 
					}
 
					y += FONT_HEIGHT_NORMAL;
 
				}
 
			} break;
 

	
 
			case TTV_SUMMARY_PANEL: {
 
				int y = r.top + WD_FRAMERECT_TOP;
 

	
 
@@ -325,6 +510,10 @@ struct TimetableWindow : Window {
 
				if (_ctrl_pressed) SetBit(p2, 1);
 
				DoCommandP(0, v->index, p2, CMD_AUTOFILL_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
 
			} break;
 

	
 
			case TTV_EXPECTED:
 
				this->show_expected = !this->show_expected;
 
				break;
 
		}
 

	
 
		this->SetDirty();
 
@@ -351,6 +540,16 @@ struct TimetableWindow : Window {
 
		/* Update the scroll bar */
 
		this->vscroll.SetCapacity((this->GetWidget<NWidgetBase>(TTV_TIMETABLE_PANEL)->current_y - WD_FRAMERECT_TOP - WD_FRAMERECT_BOTTOM) / this->resize.step_height);
 
	}
 

	
 
	/**
 
	 * Update the selection state of the arrival/departure data
 
	 */
 
	void UpdateSelectionStates()
 
	{
 
		int plane = _settings_client.gui.timetable_arrival_departure ? 0 : STACKED_SELECTION_ZERO_SIZE;
 
		this->GetWidget<NWidgetStacked>(TTV_ARRIVAL_DEPARTURE_SELECTION)->SetDisplayedPlane(plane);
 
		this->GetWidget<NWidgetStacked>(TTV_EXPECTED_SELECTION)->SetDisplayedPlane(plane);
 
	}
 
};
 

	
 
static const NWidgetPart _nested_timetable_widgets[] = {
 
@@ -362,15 +561,21 @@ static const NWidgetPart _nested_timetab
 
	EndContainer(),
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_PANEL, COLOUR_GREY, TTV_TIMETABLE_PANEL), SetMinimalSize(388, 82), SetResize(1, 10), SetDataTip(STR_NULL, STR_TIMETABLE_TOOLTIP), EndContainer(),
 
		NWidget(WWT_SCROLLBAR, COLOUR_GREY, TTV_FAKE_SCROLLBAR), SetMinimalSize(0, 0), // Hack so the timetable panel can 'use' the scrollbar too
 
		NWidget(NWID_SELECTION, INVALID_COLOUR, TTV_ARRIVAL_DEPARTURE_SELECTION),
 
			NWidget(WWT_PANEL, COLOUR_GREY, TTV_ARRIVAL_DEPARTURE_PANEL), SetMinimalSize(110, 0), SetFill(0, 1), SetDataTip(STR_NULL, STR_TIMETABLE_TOOLTIP), EndContainer(),
 
		EndContainer(),
 
		NWidget(WWT_SCROLLBAR, COLOUR_GREY, TTV_SCROLLBAR),
 
	EndContainer(),
 
	NWidget(WWT_PANEL, COLOUR_GREY, TTV_SUMMARY_PANEL), SetMinimalSize(400, 22), SetResize(1, 0), EndContainer(),
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, TTV_CHANGE_TIME), SetMinimalSize(110, 12), SetDataTip(STR_TIMETABLE_CHANGE_TIME, STR_TIMETABLE_WAIT_TIME_TOOLTIP),
 
		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, TTV_CLEAR_TIME), SetMinimalSize(110, 12), SetDataTip(STR_TIMETABLE_CLEAR_TIME, STR_TIMETABLE_CLEAR_TIME_TOOLTIP),
 
		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, TTV_RESET_LATENESS), SetMinimalSize(118, 12), SetDataTip(STR_TIMETABLE_RESET_LATENESS, STR_TIMETABLE_RESET_LATENESS_TOOLTIP),
 
		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, TTV_AUTOFILL), SetMinimalSize(50, 12), SetDataTip(STR_TIMETABLE_AUTOFILL, STR_TIMETABLE_AUTOFILL_TOOLTIP),
 
		NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetResize(1, 0), EndContainer(),
 
		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, TTV_CHANGE_TIME), SetMinimalSize(110, 12), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_TIMETABLE_CHANGE_TIME, STR_TIMETABLE_WAIT_TIME_TOOLTIP),
 
		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, TTV_CLEAR_TIME), SetMinimalSize(110, 12), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_TIMETABLE_CLEAR_TIME, STR_TIMETABLE_CLEAR_TIME_TOOLTIP),
 
		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, TTV_RESET_LATENESS), SetMinimalSize(118, 12), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_TIMETABLE_RESET_LATENESS, STR_TIMETABLE_RESET_LATENESS_TOOLTIP),
 
		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, TTV_AUTOFILL), SetMinimalSize(50, 12), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_TIMETABLE_AUTOFILL, STR_TIMETABLE_AUTOFILL_TOOLTIP),
 
		NWidget(NWID_SELECTION, INVALID_COLOUR, TTV_EXPECTED_SELECTION),
 
			NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, TTV_EXPECTED), SetMinimalSize(50, 12), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_TIMETABLE_EXPECTED_TOOLTIP),
 
		EndContainer(),
 
		NWidget(WWT_RESIZEBOX,COLOUR_GREY),
 
	EndContainer(),
 
};
0 comments (0 inline, 0 general)