changeset 4442:a2a4fc0887ab draft

(svn r6215) -Codechange: [vehicle list windows] unified Player(vehicle)WndProc into PlayerVehWndProc Those 4 unified functions were really much alike, so there was no reason to have so much dublicated code
author bjarni <bjarni@openttd.org>
date Tue, 29 Aug 2006 17:41:13 +0000
parents 614ec0ebc3ea
children 917acff8e545
files aircraft_gui.c roadveh_gui.c ship_gui.c train_gui.c vehicle_gui.c vehicle_gui.h
diffstat 6 files changed, 327 insertions(+), 731 deletions(-) [+]
line wrap: on
line diff
--- a/aircraft_gui.c
+++ b/aircraft_gui.c
@@ -81,7 +81,7 @@
 	y += ShowAdditionalText(x, y, 227, engine_number);
 }
 
-static void DrawAircraftImage(const Vehicle *v, int x, int y, VehicleID selection)
+void DrawAircraftImage(const Vehicle *v, int x, int y, VehicleID selection)
 {
 	PalSpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
 	DrawSprite(GetAircraftImage(v, DIR_W) | pal, x + 25, y + 10);
@@ -243,7 +243,7 @@
 	NewAircraftWndProc
 };
 
-static void ShowBuildAircraftWindow(TileIndex tile)
+void ShowBuildAircraftWindow(TileIndex tile)
 {
 	Window *w;
 
@@ -953,7 +953,7 @@
 	}
 }
 
-static void DrawSmallOrderList(const Vehicle *v, int x, int y)
+void DrawSmallOrderListAircraft(const Vehicle *v, int x, int y)
 {
 	const Order *order;
 	int sel, i = 0;
@@ -975,7 +975,7 @@
 }
 
 
-static const Widget _player_aircraft_widgets[] = {
+const Widget _player_aircraft_widgets[] = {
 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,              STR_018B_CLOSE_WINDOW },
 {    WWT_CAPTION,  RESIZE_RIGHT,    14,    11,   247,     0,    13, STR_A009_AIRCRAFT,     STR_018C_WINDOW_TITLE_DRAG_THIS },
 {  WWT_STICKYBOX,     RESIZE_LR,    14,   248,   259,     0,    13, 0x0,                   STR_STICKY_BUTTON },
@@ -1007,187 +1007,12 @@
 {   WIDGETS_END},
 };
 
-static void PlayerAircraftWndProc(Window *w, WindowEvent *e)
-{
-	OrderID order = INVALID_ORDER;
-	StationID station = INVALID_STATION;
-	PlayerID owner = GB(w->window_number, 0, 8);
-	vehiclelist_d *vl = &WP(w, vehiclelist_d);
-
-	if (w->window_number & SHARE_FLAG) {
-		order = GB(w->window_number, 16, 16);
-	} else {
-		station = GB(w->window_number, 16, 16);
-	}
-
-	switch (e->event) {
-	case WE_PAINT: {
-		int x = 2;
-		int y = PLY_WND_PRC__OFFSET_TOP_WIDGET;
-		int max;
-		int i;
-
-		BuildVehicleList(vl, VEH_Aircraft, owner, station, order);
-		SortVehicleList(vl);
-		SetVScrollCount(w, vl->list_length);
-
-		// disable 'Sort By' tooltip on Unsorted sorting criteria
-		if (vl->sort_type == SORT_BY_UNSORTED) w->disabled_state |= (1 << 3);
-
-		/* draw the widgets */
-		{
-			const Player *p = GetPlayer(owner);
-			if (order != INVALID_ORDER) {
-				/* Shared Orders -- (###) Aircraft */
-				SetDParam(0, w->vscroll.count);
-				w->widget[1].unkA  = STR_VEH_WITH_SHARED_ORDERS_LIST;
-				w->widget[9].unkA  = STR_EMPTY;
-				w->widget[10].unkA = STR_EMPTY;
-				SETBIT(w->disabled_state, 9);
-				SETBIT(w->disabled_state, 10);
-			} else if (station == INVALID_STATION) {
-				/* Company Name -- (###) Aircraft */
-				SetDParam(0, p->name_1);
-				SetDParam(1, p->name_2);
-				SetDParam(2, w->vscroll.count);
-				w->widget[1].unkA = STR_A009_AIRCRAFT;
-			} else {
-				/* Station Name -- (###) Aircraft */
-				SetDParam(0, station);
-				SetDParam(1, w->vscroll.count);
-				w->widget[1].unkA = STR_SCHEDULED_AIRCRAFT;
-			}
-			DrawWindowWidgets(w);
-		}
-		/* draw sorting criteria string */
-		DrawString(85, 15, _vehicle_sort_listing[vl->sort_type], 0x10);
-		/* draw arrow pointing up/down for ascending/descending sorting */
-		DoDrawString(vl->flags & VL_DESC ? DOWNARROW : UPARROW, 69, 15, 0x10);
-
-		max = min(w->vscroll.pos + w->vscroll.cap, vl->list_length);
-		for (i = w->vscroll.pos; i < max; ++i) {
-			const Vehicle* v = vl->sort_list[i];
-			StringID str;
-
-			assert(v->type == VEH_Aircraft && v->subtype <= 2);
-
-			DrawAircraftImage(v, x + 19, y + 6, INVALID_VEHICLE);
-			DrawVehicleProfitButton(v, x, y + 13);
-
-			SetDParam(0, v->unitnumber);
-			if (IsAircraftInHangar(v)) {
-				str = STR_021F;
-			} else {
-				str = v->age > v->max_age - 366 ? STR_00E3 : STR_00E2;
-			}
-			DrawString(x, y + 2, str, 0);
-
-			SetDParam(0, v->profit_this_year);
-			SetDParam(1, v->profit_last_year);
-			DrawString(x + 19, y + 28, STR_0198_PROFIT_THIS_YEAR_LAST_YEAR, 0);
-
-			if (v->string_id != STR_SV_AIRCRAFT_NAME) {
-				SetDParam(0, v->string_id);
-				DrawString(x + 19, y, STR_01AB, 0);
-			}
-
-			DrawSmallOrderList(v, x + 136, y);
-
-			y += PLY_WND_PRC__SIZE_OF_ROW_BIG;
-		}
-		}	break;
-
-	case WE_CLICK: {
-		switch (e->click.widget) {
-		case 3: /* Flip sorting method ascending/descending */
-			vl->flags ^= VL_DESC;
-			vl->flags |= VL_RESORT;
-			_sorting.aircraft.order = !!(vl->flags & VL_DESC);
-			SetWindowDirty(w);
-			break;
-
-		case 4: case 5:/* Select sorting criteria dropdown menu */
-			ShowDropDownMenu(w, _vehicle_sort_listing, vl->sort_type, 5, 0, 0);
-			return;
-
-		case 7: { /* Matrix to show vehicles */
-			uint32 id_v = (e->click.pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / PLY_WND_PRC__SIZE_OF_ROW_BIG;
-			const Vehicle *v;
-
-			if (id_v >= w->vscroll.cap) return; // click out of bounds
-
-			id_v += w->vscroll.pos;
-
-			if (id_v >= vl->list_length) return; // click out of list bound
-
-			v = vl->sort_list[id_v];
-
-			assert(v->type == VEH_Aircraft && v->subtype <= 2);
-
-			ShowAircraftViewWindow(v);
-		} break;
-
-		case 9: /* Build new Vehicle */
-			if (!IsWindowOfPrototype(w, _player_aircraft_widgets)) break;
-			ShowBuildAircraftWindow(0);
-			break;
-
-		case 10:
-			if (!IsWindowOfPrototype(w, _player_aircraft_widgets)) break;
-			ShowReplaceVehicleWindow(VEH_Aircraft);
-			break;
-
-		}
-	}	break;
-
-	case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
-		if (vl->sort_type != e->dropdown.index) {
-			// value has changed -> resort
-			vl->flags |= VL_RESORT;
-			vl->sort_type = e->dropdown.index;
-			_sorting.aircraft.criteria = vl->sort_type;
-
-			// enable 'Sort By' if a sorter criteria is chosen
-			if (vl->sort_type != SORT_BY_UNSORTED) CLRBIT(w->disabled_state, 3);
-		}
-		SetWindowDirty(w);
-		break;
-
-	case WE_CREATE: /* set up resort timer */
-		vl->sort_list = NULL;
-		vl->flags = VL_REBUILD | (_sorting.aircraft.order << (VL_DESC - 1));
-		vl->sort_type = _sorting.aircraft.criteria;
-		vl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
-		break;
-
-	case WE_DESTROY:
-		free((void*)vl->sort_list);
-		break;
-
-	case WE_TICK: /* resort the list every 20 seconds orso (10 days) */
-		if (--vl->resort_timer == 0) {
-			DEBUG(misc, 1) ("Periodic resort aircraft list player %d station %d",
-				owner, station);
-			vl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
-			vl->flags |= VL_RESORT;
-			SetWindowDirty(w);
-		}
-		break;
-
-	case WE_RESIZE:
-		/* Update the scroll + matrix */
-		w->vscroll.cap += e->sizing.diff.y / PLY_WND_PRC__SIZE_OF_ROW_BIG;
-		w->widget[7].unkA = (w->vscroll.cap << 8) + 1;
-		break;
-	}
-}
-
 static const WindowDesc _player_aircraft_desc = {
 	-1, -1, 260, 182,
 	WC_AIRCRAFT_LIST,0,
 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
 	_player_aircraft_widgets,
-	PlayerAircraftWndProc
+	PlayerVehWndProc
 };
 
 static const WindowDesc _other_player_aircraft_desc = {
@@ -1195,7 +1020,7 @@
 	WC_AIRCRAFT_LIST,0,
 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
 	_other_player_aircraft_widgets,
-	PlayerAircraftWndProc
+	PlayerVehWndProc
 };
 
 void ShowPlayerAircraftLocal(PlayerID player, StationID station, OrderID order, bool show_shared)
@@ -1203,16 +1028,20 @@
 	Window *w;
 
 	if (show_shared) {
-		w = AllocateWindowDescFront(&_player_aircraft_desc, (order << 16) | SHARE_FLAG);
+		w = AllocateWindowDescFront(&_player_aircraft_desc, (order << 16) | (VEH_Aircraft << 11) | SHARE_FLAG);
 	} else {
 		if (player == _local_player) {
-			w = AllocateWindowDescFront(&_player_aircraft_desc, (station << 16) | player);
+			w = AllocateWindowDescFront(&_player_aircraft_desc, (station << 16) | (VEH_Aircraft << 11) | player);
 		} else  {
-			w = AllocateWindowDescFront(&_other_player_aircraft_desc, (station << 16) | player);
+			w = AllocateWindowDescFront(&_other_player_aircraft_desc, (station << 16) | (VEH_Aircraft << 11) | player);
 		}
 	}
 
 	if (w != NULL) {
+		vehiclelist_d *vl = &WP(w, vehiclelist_d);
+		vl->flags = VL_REBUILD | (_sorting.aircraft.order << (VL_DESC - 1));
+		vl->sort_type = _sorting.aircraft.criteria;
+
 		w->caption_color = player;
 		w->vscroll.cap = 4;
 		w->widget[7].unkA = (w->vscroll.cap << 8) + 1;
--- a/roadveh_gui.c
+++ b/roadveh_gui.c
@@ -69,7 +69,7 @@
 	y += ShowAdditionalText(x, y, 227, engine_number);
 }
 
-static void DrawRoadVehImage(const Vehicle *v, int x, int y, VehicleID selection)
+void DrawRoadVehImage(const Vehicle *v, int x, int y, VehicleID selection)
 {
 	PalSpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
 	DrawSprite(GetRoadVehImage(v, DIR_W) | pal, x + 14, y + 6);
@@ -602,7 +602,7 @@
 	NewRoadVehWndProc
 };
 
-static void ShowBuildRoadVehWindow(TileIndex tile)
+void ShowBuildRoadVehWindow(TileIndex tile)
 {
 	Window *w;
 
@@ -912,7 +912,7 @@
 	}
 }
 
-static const Widget _player_roadveh_widgets[] = {
+const Widget _player_roadveh_widgets[] = {
 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,               STR_018B_CLOSE_WINDOW},
 {    WWT_CAPTION,  RESIZE_RIGHT,    14,    11,   247,     0,    13, STR_9001_ROAD_VEHICLES, STR_018C_WINDOW_TITLE_DRAG_THIS},
 {  WWT_STICKYBOX,     RESIZE_LR,    14,   248,   259,     0,    13, 0x0,                    STR_STICKY_BUTTON},
@@ -945,182 +945,12 @@
 {   WIDGETS_END},
 };
 
-static void PlayerRoadVehWndProc(Window *w, WindowEvent *e)
-{
-	OrderID order = INVALID_ORDER;
-	StationID station = INVALID_STATION;
-	PlayerID owner = GB(w->window_number, 0, 8);
-	vehiclelist_d *vl = &WP(w, vehiclelist_d);
-
-	if (w->window_number & SHARE_FLAG) {
-		order = GB(w->window_number, 16, 16);
-	} else {
-		station = GB(w->window_number, 16, 16);
-	}
-
-	switch (e->event) {
-	case WE_PAINT: {
-		int x = 2;
-		int y = PLY_WND_PRC__OFFSET_TOP_WIDGET;
-		int max;
-		int i;
-
-		BuildVehicleList(vl, VEH_Road, owner, station, order);
-		SortVehicleList(vl);
-		SetVScrollCount(w, vl->list_length);
-
-		// disable 'Sort By' tooltip on Unsorted sorting criteria
-		if (vl->sort_type == SORT_BY_UNSORTED) w->disabled_state |= (1 << 3);
-
-		/* draw the widgets */
-		if (order != INVALID_ORDER) {
-			/* Shared Orders -- (##) Road vehicles */
-			SetDParam(0, w->vscroll.count);
-			w->widget[1].unkA  = STR_VEH_WITH_SHARED_ORDERS_LIST;
-			w->widget[9].unkA  = STR_EMPTY;
-			w->widget[10].unkA = STR_EMPTY;
-			SETBIT(w->disabled_state, 9);
-			SETBIT(w->disabled_state, 10);
-		} else if (station == INVALID_STATION) {
-			const Player *p = GetPlayer(owner);
-			/* Company Name -- (###) Road vehicles */
-			SetDParam(0, p->name_1);
-			SetDParam(1, p->name_2);
-			SetDParam(2, w->vscroll.count);
-			w->widget[1].unkA = STR_9001_ROAD_VEHICLES;
-		} else {
-			/* Station Name -- (###) Road vehicles */
-			SetDParam(0, station);
-			SetDParam(1, w->vscroll.count);
-			w->widget[1].unkA = STR_SCHEDULED_ROAD_VEHICLES;
-		}
-		DrawWindowWidgets(w);
-		/* draw sorting criteria string */
-		DrawString(85, 15, _vehicle_sort_listing[vl->sort_type], 0x10);
-		/* draw arrow pointing up/down for ascending/descending sorting */
-		DoDrawString(vl->flags & VL_DESC ? DOWNARROW : UPARROW, 69, 15, 0x10);
-
-		max = min(w->vscroll.pos + w->vscroll.cap, vl->list_length);
-		for (i = w->vscroll.pos; i < max; ++i) {
-			const Vehicle* v = vl->sort_list[i];
-			StringID str;
-
-			assert(v->type == VEH_Road && v->owner == owner);
-
-			DrawRoadVehImage(v, x + 22, y + 6, INVALID_VEHICLE);
-			DrawVehicleProfitButton(v, x, y + 13);
-
-			SetDParam(0, v->unitnumber);
-			if (IsRoadVehInDepot(v)) {
-				str = STR_021F;
-			} else {
-				str = v->age > v->max_age - 366 ? STR_00E3 : STR_00E2;
-			}
-			DrawString(x, y + 2, str, 0);
-
-			SetDParam(0, v->profit_this_year);
-			SetDParam(1, v->profit_last_year);
-			DrawString(x + 24, y + 18, STR_0198_PROFIT_THIS_YEAR_LAST_YEAR, 0);
-
-			if (v->string_id != STR_SV_ROADVEH_NAME) {
-				SetDParam(0, v->string_id);
-				DrawString(x + 24, y, STR_01AB, 0);
-			}
-
-			y += PLY_WND_PRC__SIZE_OF_ROW_SMALL;
-		}
-		}	break;
-
-	case WE_CLICK: {
-		switch (e->click.widget) {
-		case 3: /* Flip sorting method ascending/descending */
-			vl->flags ^= VL_DESC;
-			vl->flags |= VL_RESORT;
-			_sorting.roadveh.order = !!(vl->flags & VL_DESC);
-			SetWindowDirty(w);
-			break;
-
-		case 4: case 5:/* Select sorting criteria dropdown menu */
-			ShowDropDownMenu(w, _vehicle_sort_listing, vl->sort_type, 5, 0, 0);
-			return;
-		case 7: { /* Matrix to show vehicles */
-			uint32 id_v = (e->click.pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / PLY_WND_PRC__SIZE_OF_ROW_SMALL;
-			const Vehicle *v;
-
-			if (id_v >= w->vscroll.cap) return; // click out of bounds
-
-			id_v += w->vscroll.pos;
-
-			if (id_v >= vl->list_length) return; // click out of list bound
-
-			v = vl->sort_list[id_v];
-
-			assert(v->type == VEH_Road && v->owner == owner);
-
-			ShowRoadVehViewWindow(v);
-		} break;
-
-		case 9: /* Build new Vehicle */
-			if (!IsWindowOfPrototype(w, _player_roadveh_widgets)) break;
-			ShowBuildRoadVehWindow(0);
-			break;
-
-		case 10: {
-			if (!IsWindowOfPrototype(w, _player_roadveh_widgets)) break;
-			ShowReplaceVehicleWindow(VEH_Road);
-			break;
-		}
-		}
-	}	break;
-
-	case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
-		if (vl->sort_type != e->dropdown.index) {
-			// value has changed -> resort
-			vl->flags |= VL_RESORT;
-			vl->sort_type = e->dropdown.index;
-			_sorting.roadveh.criteria = vl->sort_type;
-
-			// enable 'Sort By' if a sorter criteria is chosen
-			if (vl->sort_type != SORT_BY_UNSORTED) CLRBIT(w->disabled_state, 3);
-		}
-		SetWindowDirty(w);
-		break;
-
-	case WE_CREATE: /* set up resort timer */
-		vl->sort_list = NULL;
-		vl->flags = VL_REBUILD | (_sorting.roadveh.order << (VL_DESC - 1));
-		vl->sort_type = _sorting.roadveh.criteria;
-		vl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
-		break;
-
-	case WE_DESTROY:
-		free((void*)vl->sort_list);
-		break;
-
-	case WE_TICK: /* resort the list every 20 seconds orso (10 days) */
-		if (--vl->resort_timer == 0) {
-			DEBUG(misc, 1) ("Periodic resort road vehicles list player %d station %d",
-				owner, station);
-			vl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
-			vl->flags |= VL_RESORT;
-			SetWindowDirty(w);
-		}
-		break;
-
-	case WE_RESIZE:
-		/* Update the scroll + matrix */
-		w->vscroll.cap += e->sizing.diff.y / PLY_WND_PRC__SIZE_OF_ROW_SMALL;
-		w->widget[7].unkA = (w->vscroll.cap << 8) + 1;
-		break;
-	}
-}
-
 static const WindowDesc _player_roadveh_desc = {
 	-1, -1, 260, 220,
 	WC_ROADVEH_LIST,0,
 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
 	_player_roadveh_widgets,
-	PlayerRoadVehWndProc
+	PlayerVehWndProc
 };
 
 static const WindowDesc _other_player_roadveh_desc = {
@@ -1128,7 +958,7 @@
 	WC_ROADVEH_LIST,0,
 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
 	_other_player_roadveh_widgets,
-	PlayerRoadVehWndProc
+	PlayerVehWndProc
 };
 
 
@@ -1137,15 +967,19 @@
 	Window *w;
 
 	if (show_shared) {
-		w = AllocateWindowDescFront(&_player_roadveh_desc, (order << 16) | SHARE_FLAG);
+		w = AllocateWindowDescFront(&_player_roadveh_desc, (order << 16) | (VEH_Road << 11) | SHARE_FLAG);
 	} else {
 		if ( player == _local_player) {
-			w = AllocateWindowDescFront(&_player_roadveh_desc, (station << 16) | player);
+			w = AllocateWindowDescFront(&_player_roadveh_desc, (station << 16) | (VEH_Road << 11) | player);
 		} else  {
-			w = AllocateWindowDescFront(&_other_player_roadveh_desc, (station << 16) | player);
+			w = AllocateWindowDescFront(&_other_player_roadveh_desc, (station << 16) | (VEH_Road << 11) | player);
 		}
 	}
 	if (w != NULL) {
+		vehiclelist_d *vl = &WP(w, vehiclelist_d);
+		vl->flags = VL_REBUILD | (_sorting.roadveh.order << (VL_DESC - 1));
+		vl->sort_type = _sorting.roadveh.criteria;
+
 		w->caption_color = player;
 		w->vscroll.cap = 7; // maximum number of vehicles shown
 		w->widget[7].unkA = (w->vscroll.cap << 8) + 1;
--- a/ship_gui.c
+++ b/ship_gui.c
@@ -69,7 +69,7 @@
 	y += ShowAdditionalText(x, y, 227, engine_number);
 }
 
-static void DrawShipImage(const Vehicle *v, int x, int y, VehicleID selection)
+void DrawShipImage(const Vehicle *v, int x, int y, VehicleID selection)
 {
 	DrawSprite(GetShipImage(v, DIR_W) | GetVehiclePalette(v), x + 32, y + 10);
 
@@ -425,7 +425,7 @@
 };
 
 
-static void ShowBuildShipWindow(TileIndex tile)
+void ShowBuildShipWindow(TileIndex tile)
 {
 	Window *w;
 
@@ -620,7 +620,7 @@
 	/* determine amount of items for scroller */
 	num = 0;
 	FOR_ALL_VEHICLES(v) {
-		if (v->type == VEH_Ship && IsShipInDepot(v) && v->tile == tile) num++;
+		if (v->type == VEH_Ship && (v) && v->tile == tile) num++;
 	}
 	SetVScrollCount(w, (num + w->hscroll.cap - 1) / w->hscroll.cap);
 
@@ -636,7 +636,7 @@
 	num = w->vscroll.pos * w->hscroll.cap;
 
 	FOR_ALL_VEHICLES(v) {
-		if (v->type == VEH_Ship && IsShipInDepot(v) && v->tile == tile &&
+		if (v->type == VEH_Ship && (v) && v->tile == tile &&
 				--num < 0 && num >= -w->vscroll.cap * w->hscroll.cap) {
 			DrawShipImage(v, x+19, y, WP(w,traindepot_d).sel);
 
@@ -892,7 +892,7 @@
 }
 
 
-static void DrawSmallOrderList(const Vehicle *v, int x, int y)
+void DrawSmallOrderListShip(const Vehicle *v, int x, int y)
 {
 	const Order *order;
 	int sel, i = 0;
@@ -916,7 +916,7 @@
 }
 
 
-static const Widget _player_ships_widgets[] = {
+const Widget _player_ships_widgets[] = {
 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,             STR_018B_CLOSE_WINDOW},
 {    WWT_CAPTION,  RESIZE_RIGHT,    14,    11,   247,     0,    13, STR_9805_SHIPS,       STR_018C_WINDOW_TITLE_DRAG_THIS},
 {  WWT_STICKYBOX,     RESIZE_LR,    14,   248,   259,     0,    13, 0x0,                  STR_STICKY_BUTTON},
@@ -948,187 +948,12 @@
 {   WIDGETS_END},
 };
 
-static void PlayerShipsWndProc(Window *w, WindowEvent *e)
-{
-	OrderID order = INVALID_ORDER;
-	StationID station = INVALID_STATION;
-	PlayerID owner = GB(w->window_number, 0, 8);
-	vehiclelist_d *vl = &WP(w, vehiclelist_d);
-
-	if (w->window_number & SHARE_FLAG) {
-		order = GB(w->window_number, 16, 16);
-	} else {
-		station = GB(w->window_number, 16, 16);
-	}
-
-	switch (e->event) {
-	case WE_PAINT: {
-		int x = 2;
-		int y = PLY_WND_PRC__OFFSET_TOP_WIDGET;
-		int max;
-		int i;
-
-		BuildVehicleList(vl, VEH_Ship, owner, station, order);
-		SortVehicleList(vl);
-		SetVScrollCount(w, vl->list_length);
-
-		// disable 'Sort By' tooltip on Unsorted sorting criteria
-		if (vl->sort_type == SORT_BY_UNSORTED)
-			w->disabled_state |= (1 << 3);
-
-		/* draw the widgets */
-		{
-			const Player *p = GetPlayer(owner);
-			if (order != INVALID_ORDER) {
-				/* Shared Orders -- (###) Ships */
-				SetDParam(0, w->vscroll.count);
-				w->widget[1].unkA  = STR_VEH_WITH_SHARED_ORDERS_LIST;
-				w->widget[9].unkA  = STR_EMPTY;
-				w->widget[10].unkA = STR_EMPTY;
-				SETBIT(w->disabled_state, 9);
-				SETBIT(w->disabled_state, 10);
-			} else if (station == INVALID_STATION) {
-				/* Company Name -- (###) Ships */
-				SetDParam(0, p->name_1);
-				SetDParam(1, p->name_2);
-				SetDParam(2, w->vscroll.count);
-				w->widget[1].unkA = STR_9805_SHIPS;
-			} else {
-				/* Station Name -- (###) Ships */
-				SetDParam(0, station);
-				SetDParam(1, w->vscroll.count);
-				w->widget[1].unkA = STR_SCHEDULED_SHIPS;
-			}
-			DrawWindowWidgets(w);
-		}
-		/* draw sorting criteria string */
-		DrawString(85, 15, _vehicle_sort_listing[vl->sort_type], 0x10);
-		/* draw arrow pointing up/down for ascending/descending sorting */
-		DoDrawString(vl->flags & VL_DESC ? DOWNARROW : UPARROW, 69, 15, 0x10);
-
-		max = min(w->vscroll.pos + w->vscroll.cap, vl->list_length);
-		for (i = w->vscroll.pos; i < max; ++i) {
-			const Vehicle* v = vl->sort_list[i];
-			StringID str;
-
-			assert(v->type == VEH_Ship);
-
-			DrawShipImage(v, x + 19, y + 6, INVALID_VEHICLE);
-			DrawVehicleProfitButton(v, x, y + 13);
-
-			SetDParam(0, v->unitnumber);
-			if (IsShipInDepot(v)) {
-				str = STR_021F;
-			} else {
-				str = v->age > v->max_age - 366 ? STR_00E3 : STR_00E2;
-			}
-			DrawString(x, y + 2, str, 0);
-
-			SetDParam(0, v->profit_this_year);
-			SetDParam(1, v->profit_last_year);
-			DrawString(x + 12, y + 28, STR_0198_PROFIT_THIS_YEAR_LAST_YEAR, 0);
-
-			if (v->string_id != STR_SV_SHIP_NAME) {
-				SetDParam(0, v->string_id);
-				DrawString(x + 12, y, STR_01AB, 0);
-			}
-
-			DrawSmallOrderList(v, x + 138, y);
-
-			y += PLY_WND_PRC__SIZE_OF_ROW_BIG;
-		}
-		}	break;
-
-	case WE_CLICK: {
-		switch (e->click.widget) {
-		case 3: /* Flip sorting method ascending/descending */
-			vl->flags ^= VL_DESC;
-			vl->flags |= VL_RESORT;
-			_sorting.ship.order = !!(vl->flags & VL_DESC);
-			SetWindowDirty(w);
-			break;
-		case 4: case 5:/* Select sorting criteria dropdown menu */
-			ShowDropDownMenu(w, _vehicle_sort_listing, vl->sort_type, 5, 0, 0);
-			return;
-		case 7: { /* Matrix to show vehicles */
-			uint32 id_v = (e->click.pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / PLY_WND_PRC__SIZE_OF_ROW_BIG;
-			const Vehicle *v;
-
-			if (id_v >= w->vscroll.cap) return; // click out of bounds
-
-			id_v += w->vscroll.pos;
-
-			if (id_v >= vl->list_length) return; // click out of list bound
-
-			v = vl->sort_list[id_v];
-
-			assert(v->type == VEH_Ship);
-
-			ShowShipViewWindow(v);
-		} break;
-
-		case 9: /* Build new Vehicle */
-			if (!IsWindowOfPrototype(w, _player_ships_widgets)) break;
-			ShowBuildShipWindow(0);
-			break;
-
-		case 10: {
-			if (!IsWindowOfPrototype(w, _player_ships_widgets)) break;
-
-			ShowReplaceVehicleWindow(VEH_Ship);
-			break;
-		}
-	}
-	}	break;
-
-	case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
-		if (vl->sort_type != e->dropdown.index) {
-			// value has changed -> resort
-			vl->flags |= VL_RESORT;
-			vl->sort_type = e->dropdown.index;
-			_sorting.ship.criteria = vl->sort_type;
-
-			// enable 'Sort By' if a sorter criteria is chosen
-			if (vl->sort_type != SORT_BY_UNSORTED) CLRBIT(w->disabled_state, 3);
-		}
-		SetWindowDirty(w);
-		break;
-
-	case WE_CREATE: /* set up resort timer */
-		vl->sort_list = NULL;
-		vl->flags = VL_REBUILD | (_sorting.ship.order << (VL_DESC - 1));
-		vl->sort_type = _sorting.ship.criteria;
-		vl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
-		break;
-
-	case WE_DESTROY:
-		free((void*)vl->sort_list);
-		break;
-
-	case WE_TICK: /* resort the list every 20 seconds orso (10 days) */
-		if (--vl->resort_timer == 0) {
-			DEBUG(misc, 1) ("Periodic resort ships list player %d station %d",
-				owner, station);
-			vl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
-			vl->flags |= VL_RESORT;
-			SetWindowDirty(w);
-		}
-		break;
-
-	case WE_RESIZE:
-		/* Update the scroll + matrix */
-		w->vscroll.cap += e->sizing.diff.y / PLY_WND_PRC__SIZE_OF_ROW_BIG;
-		w->widget[7].unkA = (w->vscroll.cap << 8) + 1;
-		break;
-	}
-}
-
 static const WindowDesc _player_ships_desc = {
 	-1, -1, 260, 182,
 	WC_SHIPS_LIST,0,
 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
 	_player_ships_widgets,
-	PlayerShipsWndProc
+	PlayerVehWndProc
 };
 
 static const WindowDesc _other_player_ships_desc = {
@@ -1136,7 +961,7 @@
 	WC_SHIPS_LIST,0,
 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
 	_other_player_ships_widgets,
-	PlayerShipsWndProc
+	PlayerVehWndProc
 };
 
 
@@ -1145,16 +970,20 @@
 	Window *w;
 
 	if (show_shared) {
-		w = AllocateWindowDescFront(&_player_ships_desc, (order << 16) | SHARE_FLAG);
+		w = AllocateWindowDescFront(&_player_ships_desc, (order << 16) | VEH_Ship << 11 | SHARE_FLAG);
 	} else {
 		if (player == _local_player) {
-			w = AllocateWindowDescFront(&_player_ships_desc, (station << 16) | player);
+			w = AllocateWindowDescFront(&_player_ships_desc, (station << 16) | VEH_Ship << 11 | player);
 		} else  {
-			w = AllocateWindowDescFront(&_other_player_ships_desc, (station << 16) | player);
+			w = AllocateWindowDescFront(&_other_player_ships_desc, (station << 16) | VEH_Ship << 11 | player);
 		}
 	}
 
 	if (w != NULL) {
+		vehiclelist_d *vl = &WP(w, vehiclelist_d);
+		vl->flags = VL_REBUILD | (_sorting.ship.order << (VL_DESC - 1));
+		vl->sort_type = _sorting.ship.criteria;
+
 		w->caption_color = player;
 		w->vscroll.cap = 4;
 		w->widget[7].unkA = (w->vscroll.cap << 8) + 1;
--- a/train_gui.c
+++ b/train_gui.c
@@ -321,7 +321,7 @@
 	NewRailVehicleWndProc
 };
 
-static void ShowBuildTrainWindow(TileIndex tile)
+void ShowBuildTrainWindow(TileIndex tile)
 {
 	Window *w;
 
@@ -353,7 +353,7 @@
 	return (len * _traininfo_vehicle_width) / 8;
 }
 
-static void DrawTrainImage(const Vehicle *v, int x, int y, int count, int skip, VehicleID selection)
+void DrawTrainImage(const Vehicle *v, int x, int y, int count, int skip, VehicleID selection)
 {
 	DrawPixelInfo tmp_dpi, *old_dpi;
 	int dx = -(skip * 8) / _traininfo_vehicle_width;
@@ -1372,7 +1372,7 @@
 	WP(w,traindetails_d).tab = 0;
 }
 
-static const Widget _player_trains_widgets[] = {
+const Widget _player_trains_widgets[] = {
 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,              STR_018B_CLOSE_WINDOW},
 {    WWT_CAPTION,  RESIZE_RIGHT,    14,    11,   312,     0,    13, STR_881B_TRAINS,       STR_018C_WINDOW_TITLE_DRAG_THIS},
 {  WWT_STICKYBOX,     RESIZE_LR,    14,   313,   324,     0,    13, 0x0,                   STR_STICKY_BUTTON},
@@ -1404,187 +1404,12 @@
 {   WIDGETS_END},
 };
 
-static void PlayerTrainsWndProc(Window *w, WindowEvent *e)
-{
-	OrderID order = INVALID_ORDER;
-	StationID station = INVALID_STATION;
-	PlayerID owner = GB(w->window_number, 0, 8);
-	vehiclelist_d *vl = &WP(w, vehiclelist_d);
-
-	if (w->window_number & SHARE_FLAG) {
-		order = GB(w->window_number, 16, 16);
-	} else {
-		station = GB(w->window_number, 16, 16);
-	}
-
-	switch (e->event) {
-	case WE_PAINT: {
-		int x = 2;
-		int y = PLY_WND_PRC__OFFSET_TOP_WIDGET;
-		int max;
-		int i;
-
-		BuildVehicleList(vl, VEH_Train, owner, station, order);
-		SortVehicleList(vl);
-		SetVScrollCount(w, vl->list_length);
-
-		// disable 'Sort By' tooltip on Unsorted sorting criteria
-		if (vl->sort_type == SORT_BY_UNSORTED) w->disabled_state |= (1 << 3);
-
-		/* draw the widgets */
-		{
-			if (order != INVALID_ORDER) {
-				/* Shared Orders -- (###) Trains */
-				SetDParam(0, w->vscroll.count);
-				w->widget[1].unkA  = STR_VEH_WITH_SHARED_ORDERS_LIST;
-				w->widget[9].unkA  = STR_EMPTY;
-				w->widget[10].unkA = STR_EMPTY;
-				SETBIT(w->disabled_state, 9);
-				SETBIT(w->disabled_state, 10);
-			} else if (station == INVALID_STATION) {
-				const Player *p = GetPlayer(owner);
-				/* Company Name -- (###) Trains */
-				SetDParam(0, p->name_1);
-				SetDParam(1, p->name_2);
-				SetDParam(2, w->vscroll.count);
-				w->widget[1].unkA = STR_881B_TRAINS;
-			} else {
-				/* Station Name -- (###) Trains */
-				SetDParam(0, station);
-				SetDParam(1, w->vscroll.count);
-				w->widget[1].unkA = STR_SCHEDULED_TRAINS;
-			}
-			DrawWindowWidgets(w);
-		}
-		/* draw sorting criteria string */
-		DrawString(85, 15, _vehicle_sort_listing[vl->sort_type], 0x10);
-		/* draw arrow pointing up/down for ascending/descending sorting */
-		DoDrawString(vl->flags & VL_DESC ? DOWNARROW : UPARROW, 69, 15, 0x10);
-
-		max = min(w->vscroll.pos + w->vscroll.cap, vl->list_length);
-		for (i = w->vscroll.pos; i < max; ++i) {
-			const Vehicle* v = vl->sort_list[i];
-			StringID str;
-
-			assert(v->type == VEH_Train && v->owner == owner);
-
-			DrawTrainImage(v, x + 21, y + 6, w->hscroll.cap, 0, INVALID_VEHICLE);
-			DrawVehicleProfitButton(v, x, y + 13);
-
-			SetDParam(0, v->unitnumber);
-			if (IsTileDepotType(v->tile, TRANSPORT_RAIL) && (v->vehstatus & VS_HIDDEN)) {
-				str = STR_021F;
-			} else {
-				str = v->age > v->max_age - 366 ? STR_00E3 : STR_00E2;
-			}
-			DrawString(x, y + 2, str, 0);
-
-			SetDParam(0, v->profit_this_year);
-			SetDParam(1, v->profit_last_year);
-			DrawString(x + 21, y + 18, STR_0198_PROFIT_THIS_YEAR_LAST_YEAR, 0);
-
-			if (v->string_id != STR_SV_TRAIN_NAME) {
-				SetDParam(0, v->string_id);
-				DrawString(x + 21, y, STR_01AB, 0);
-			}
-
-			y += PLY_WND_PRC__SIZE_OF_ROW_SMALL;
-		}
-		break;
-	}
-
-	case WE_CLICK: {
-		switch (e->click.widget) {
-		case 3: /* Flip sorting method ascending/descending */
-			vl->flags ^= VL_DESC;
-			vl->flags |= VL_RESORT;
-			_sorting.train.order = !!(vl->flags & VL_DESC);
-			SetWindowDirty(w);
-			break;
-
-		case 4: case 5:/* Select sorting criteria dropdown menu */
-			ShowDropDownMenu(w, _vehicle_sort_listing, vl->sort_type, 5, 0, 0);
-			return;
-
-		case 7: { /* Matrix to show vehicles */
-			uint32 id_v = (e->click.pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / PLY_WND_PRC__SIZE_OF_ROW_SMALL;
-			const Vehicle *v;
-
-			if (id_v >= w->vscroll.cap) return; // click out of bounds
-
-			id_v += w->vscroll.pos;
-
-			if (id_v >= vl->list_length) return; // click out of list bound
-
-			v = vl->sort_list[id_v];
-
-			assert(v->type == VEH_Train && IsFrontEngine(v) && v->owner == owner);
-
-			ShowTrainViewWindow(v);
-		} break;
-
-		case 9: /* Build new Vehicle */
-			if (!IsWindowOfPrototype(w, _player_trains_widgets)) break;
-			ShowBuildTrainWindow(0);
-			break;
-
-		case 10:
-			if (!IsWindowOfPrototype(w, _player_trains_widgets)) break;
-			ShowReplaceVehicleWindow(VEH_Train);
-			break;
-
-		}
-	}	break;
-
-	case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
-		if (vl->sort_type != e->dropdown.index) {
-			// value has changed -> resort
-			vl->flags |= VL_RESORT;
-			vl->sort_type = e->dropdown.index;
-			_sorting.train.criteria = vl->sort_type;
-
-			// enable 'Sort By' if a sorter criteria is chosen
-			if (vl->sort_type != SORT_BY_UNSORTED) CLRBIT(w->disabled_state, 3);
-		}
-		SetWindowDirty(w);
-		break;
-
-	case WE_CREATE: /* set up resort timer */
-		vl->sort_list = NULL;
-		vl->flags = VL_REBUILD | (_sorting.train.order << (VL_DESC - 1));
-		vl->sort_type = _sorting.train.criteria;
-		vl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
-		break;
-
-	case WE_DESTROY:
-		free((void*)vl->sort_list);
-		break;
-
-	case WE_TICK: /* resort the list every 20 seconds orso (10 days) */
-		if (--vl->resort_timer == 0) {
-			DEBUG(misc, 1) ("Periodic resort trains list player %d station %d",
-				owner, station);
-			vl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
-			vl->flags |= VL_RESORT;
-			SetWindowDirty(w);
-		}
-		break;
-
-	case WE_RESIZE:
-		/* Update the scroll + matrix */
-		w->hscroll.cap += e->sizing.diff.x;
-		w->vscroll.cap += e->sizing.diff.y / PLY_WND_PRC__SIZE_OF_ROW_SMALL;
-		w->widget[7].unkA = (w->vscroll.cap << 8) + 1;
-		break;
-	}
-}
-
 static const WindowDesc _player_trains_desc = {
 	-1, -1, 325, 220,
 	WC_TRAINS_LIST,0,
 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
 	_player_trains_widgets,
-	PlayerTrainsWndProc
+	PlayerVehWndProc
 };
 
 static const WindowDesc _other_player_trains_desc = {
@@ -1592,7 +1417,7 @@
 	WC_TRAINS_LIST,0,
 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
 	_other_player_trains_widgets,
-	PlayerTrainsWndProc
+	PlayerVehWndProc
 };
 
 static void ShowPlayerTrainsLocal(PlayerID player, StationID station, OrderID order, bool show_shared)
@@ -1600,15 +1425,19 @@
 	Window *w;
 
 	if (show_shared) {
-		w = AllocateWindowDescFront(&_player_trains_desc, (order << 16) | SHARE_FLAG);
+		w = AllocateWindowDescFront(&_player_trains_desc, (order << 16) | (VEH_Train << 11) | SHARE_FLAG);
 	} else {
 		if (player == _local_player) {
-			w = AllocateWindowDescFront(&_player_trains_desc, (station << 16) | player);
+			w = AllocateWindowDescFront(&_player_trains_desc, (station << 16) | (VEH_Train << 11) | player);
 		} else {
-			w = AllocateWindowDescFront(&_other_player_trains_desc, (station << 16) | player);
+			w = AllocateWindowDescFront(&_other_player_trains_desc, (station << 16) | (VEH_Train << 11) | player);
 		}
 	}
 	if (w != NULL) {
+		vehiclelist_d *vl = &WP(w, vehiclelist_d);
+		vl->flags = VL_REBUILD | (_sorting.train.order << (VL_DESC - 1));
+		vl->sort_type = _sorting.train.criteria;
+
 		w->caption_color = player;
 		w->hscroll.cap = 10 * 29;
 		w->vscroll.cap = 7; // maximum number of vehicles shown
--- a/vehicle_gui.c
+++ b/vehicle_gui.c
@@ -23,6 +23,10 @@
 #include "newgrf_engine.h"
 #include "newgrf_text.h"
 #include "date.h"
+#include "ship.h"
+#include "aircraft.h"
+#include "roadveh.h"
+#include "depot.h"
 
 Sorting _sorting;
 
@@ -1197,3 +1201,258 @@
 		}
 	}
 }
+
+extern const Widget _player_ships_widgets[];
+extern const Widget _player_aircraft_widgets[];
+extern const Widget _player_roadveh_widgets[];
+extern const Widget _player_trains_widgets[];
+
+void PlayerVehWndProc(Window *w, WindowEvent *e)
+{
+	vehiclelist_d *vl = &WP(w, vehiclelist_d);
+	const byte vehicle_type = GB(w->window_number, 11, 5);
+	const byte size_of_row = (vehicle_type == VEH_Aircraft || vehicle_type == VEH_Ship) ? PLY_WND_PRC__SIZE_OF_ROW_BIG : PLY_WND_PRC__SIZE_OF_ROW_SMALL;
+
+	switch (e->event) {
+		case WE_PAINT: {
+			int x = 2;
+			int y = PLY_WND_PRC__OFFSET_TOP_WIDGET;
+			int max;
+			int i;
+			const PlayerID owner = GB(w->window_number, 0, 8);
+			const Player *p = GetPlayer(owner);
+			OrderID order     = INVALID_ORDER;
+			StationID station = INVALID_STATION;
+
+			if (w->window_number & SHARE_FLAG) {
+				order = GB(w->window_number, 16, 16);
+			} else {
+				station = GB(w->window_number, 16, 16);
+			}
+
+			BuildVehicleList(vl, vehicle_type, owner, station, order);
+			SortVehicleList(vl);
+			SetVScrollCount(w, vl->list_length);
+
+			// disable 'Sort By' tooltip on Unsorted sorting criteria
+			if (vl->sort_type == SORT_BY_UNSORTED) SETBIT(w->disabled_state, 3);
+
+			/* draw the widgets */
+			if (order != INVALID_ORDER) {
+				/* Shared Orders */
+				SetDParam(0, w->vscroll.count);
+				w->widget[1].unkA  = STR_VEH_WITH_SHARED_ORDERS_LIST;
+				w->widget[9].unkA  = STR_EMPTY;
+				w->widget[10].unkA = STR_EMPTY;
+				SETBIT(w->disabled_state, 9);
+				SETBIT(w->disabled_state, 10);
+			} else if (station == INVALID_STATION) {
+				/* Company Name */
+				SetDParam(0, p->name_1);
+				SetDParam(1, p->name_2);
+				SetDParam(2, w->vscroll.count);
+				switch (vehicle_type) {
+					case VEH_Train:    w->widget[1].unkA = STR_881B_TRAINS;        break;
+					case VEH_Road:     w->widget[1].unkA = STR_9001_ROAD_VEHICLES; break;
+					case VEH_Ship:     w->widget[1].unkA = STR_9805_SHIPS;         break;
+					case VEH_Aircraft: w->widget[1].unkA = STR_A009_AIRCRAFT;      break;
+					default: NOT_REACHED(); break;
+				}
+			} else {
+				/* Station Name */
+				SetDParam(0, station);
+				SetDParam(1, w->vscroll.count);
+				switch (vehicle_type) {
+					case VEH_Train:    w->widget[1].unkA = STR_SCHEDULED_TRAINS;        break;
+					case VEH_Road:     w->widget[1].unkA = STR_SCHEDULED_ROAD_VEHICLES; break;
+					case VEH_Ship:     w->widget[1].unkA = STR_SCHEDULED_SHIPS;         break;
+					case VEH_Aircraft: w->widget[1].unkA = STR_SCHEDULED_AIRCRAFT;      break;
+					default: NOT_REACHED(); break;
+				}
+			}
+			DrawWindowWidgets(w);
+
+			/* draw sorting criteria string */
+			DrawString(85, 15, _vehicle_sort_listing[vl->sort_type], 0x10);
+			/* draw arrow pointing up/down for ascending/descending sorting */
+			DoDrawString(vl->flags & VL_DESC ? DOWNARROW : UPARROW, 69, 15, 0x10);
+
+			max = min(w->vscroll.pos + w->vscroll.cap, vl->list_length);
+			for (i = w->vscroll.pos; i < max; ++i) {
+				const Vehicle* v = vl->sort_list[i];
+				StringID str;
+
+				str = v->age > v->max_age - 366 ? STR_00E3 : STR_00E2;
+				SetDParam(0, v->profit_this_year);
+				SetDParam(1, v->profit_last_year);
+				switch (vehicle_type) {
+					case VEH_Train:
+						DrawTrainImage(v, x + 21, y + 6, w->hscroll.cap, 0, INVALID_VEHICLE);
+						DrawString(x + 21, y + 18, STR_0198_PROFIT_THIS_YEAR_LAST_YEAR, 0);
+						if (IsTileDepotType(v->tile, TRANSPORT_RAIL) && (v->vehstatus & VS_HIDDEN)) str = STR_021F;
+						if (v->string_id != STR_SV_TRAIN_NAME) {
+							SetDParam(0, v->string_id);
+							DrawString(x + 21, y, STR_01AB, 0);
+						}
+						break;
+					case VEH_Road:
+						DrawRoadVehImage(v, x + 22, y + 6, INVALID_VEHICLE);
+						DrawString(x + 24, y + 18, STR_0198_PROFIT_THIS_YEAR_LAST_YEAR, 0);
+						if (IsRoadVehInDepot(v)) str = STR_021F;
+						if (v->string_id != STR_SV_ROADVEH_NAME) {
+							SetDParam(0, v->string_id);
+							DrawString(x + 24, y, STR_01AB, 0);
+						}
+						break;
+					case VEH_Ship:
+						DrawShipImage(v, x + 19, y + 6, INVALID_VEHICLE);
+						DrawString(x + 12, y + 28, STR_0198_PROFIT_THIS_YEAR_LAST_YEAR, 0);
+						if (IsShipInDepot(v)) str = STR_021F;
+							if (v->string_id != STR_SV_SHIP_NAME) {
+								SetDParam(0, v->string_id);
+								DrawString(x + 12, y, STR_01AB, 0);
+							}
+								DrawSmallOrderListShip(v, x + 138, y);
+						break;
+					case VEH_Aircraft:
+						DrawAircraftImage(v, x + 19, y + 6, INVALID_VEHICLE);
+						DrawString(x + 19, y + 28, STR_0198_PROFIT_THIS_YEAR_LAST_YEAR, 0);
+						if (IsAircraftInHangar(v)) str = STR_021F;
+							if (v->string_id != STR_SV_AIRCRAFT_NAME) {
+								SetDParam(0, v->string_id);
+								DrawString(x + 19, y, STR_01AB, 0);
+							}
+								DrawSmallOrderListAircraft(v, x + 136, y);
+						break;
+					default: NOT_REACHED(); break;
+				}
+				SetDParam(0, v->unitnumber);
+				DrawString(x, y + 2, str, 0);
+
+				DrawVehicleProfitButton(v, x, y + 13);
+
+				y += size_of_row;
+			}
+		}	break;
+
+		case WE_CLICK: {
+			switch (e->click.widget) {
+				case 3: /* Flip sorting method ascending/descending */
+					vl->flags ^= VL_DESC;
+					vl->flags |= VL_RESORT;
+
+					switch (vehicle_type) {
+						case VEH_Train:    _sorting.train.order    = !!(vl->flags & VL_DESC); break;
+						case VEH_Road:     _sorting.roadveh.order  = !!(vl->flags & VL_DESC); break;
+						case VEH_Ship:     _sorting.ship.order     = !!(vl->flags & VL_DESC); break;
+						case VEH_Aircraft: _sorting.aircraft.order = !!(vl->flags & VL_DESC); break;
+						default: NOT_REACHED(); break;
+					}
+					SetWindowDirty(w);
+					break;
+				case 4: case 5:/* Select sorting criteria dropdown menu */
+					ShowDropDownMenu(w, _vehicle_sort_listing, vl->sort_type, 5, 0, 0);
+					return;
+				case 7: { /* Matrix to show vehicles */
+					uint32 id_v = (e->click.pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / size_of_row;
+					const Vehicle *v;
+
+					if (id_v >= w->vscroll.cap) return; // click out of bounds
+
+					id_v += w->vscroll.pos;
+
+					if (id_v >= vl->list_length) return; // click out of list bound
+
+					v = vl->sort_list[id_v];
+
+					switch (vehicle_type) {
+						case VEH_Train: ShowTrainViewWindow(v); break;
+						case VEH_Road: ShowRoadVehViewWindow(v); break;
+						case VEH_Ship: ShowShipViewWindow(v); break;
+						case VEH_Aircraft: ShowAircraftViewWindow(v); break;
+						default: NOT_REACHED(); break;
+					}
+				} break;
+
+				case 9: /* Build new Vehicle */
+					switch (vehicle_type) {
+						case VEH_Train:
+							assert(IsWindowOfPrototype(w, _player_trains_widgets));
+							ShowBuildTrainWindow(0);
+							break;
+						case VEH_Road:
+							assert(IsWindowOfPrototype(w, _player_roadveh_widgets));
+							ShowBuildRoadVehWindow(0);
+							break;
+						case VEH_Ship:
+							assert(IsWindowOfPrototype(w, _player_ships_widgets));
+							ShowBuildShipWindow(0);
+							break;
+						case VEH_Aircraft:
+							assert(IsWindowOfPrototype(w, _player_aircraft_widgets));
+							ShowBuildAircraftWindow(0);
+							break;
+						default: NOT_REACHED(); break;
+					}
+					break;
+
+				case 10: {
+					if (vehicle_type == VEH_Train    && !IsWindowOfPrototype(w, _player_trains_widgets))   break;
+					if (vehicle_type == VEH_Road     && !IsWindowOfPrototype(w, _player_roadveh_widgets))  break;
+					if (vehicle_type == VEH_Ship     && !IsWindowOfPrototype(w, _player_ships_widgets))    break;
+					if (vehicle_type == VEH_Aircraft && !IsWindowOfPrototype(w, _player_aircraft_widgets)) break;
+
+					ShowReplaceVehicleWindow(vehicle_type);
+					break;
+				}
+			}
+		}	break;
+
+		case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
+			if (vl->sort_type != e->dropdown.index) {
+				// value has changed -> resort
+				vl->flags |= VL_RESORT;
+				vl->sort_type = e->dropdown.index;
+				switch (vehicle_type) {
+					case VEH_Train:    _sorting.train.criteria    = vl->sort_type; break;
+					case VEH_Road:     _sorting.roadveh.criteria  = vl->sort_type; break;
+					case VEH_Ship:     _sorting.ship.criteria     = vl->sort_type; break;
+					case VEH_Aircraft: _sorting.aircraft.criteria = vl->sort_type; break;
+					default: NOT_REACHED(); break;
+				}
+				// enable 'Sort By' if a sorter criteria is chosen
+				if (vl->sort_type != SORT_BY_UNSORTED) CLRBIT(w->disabled_state, 3);
+			}
+			SetWindowDirty(w);
+			break;
+
+		case WE_CREATE:
+			/* IMPORTANT: order and criteria needs to be set after the window is created, but before it's used */
+			/* w->window_number is not yet set at this point, so we lack info on what kind of vehicle we are dealing with */
+			vl->sort_list = NULL;
+			vl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;	// Set up resort timer
+			break;
+
+		case WE_DESTROY:
+			free((void*)vl->sort_list);
+			break;
+
+		case WE_TICK: /* resort the list every 20 seconds orso (10 days) */
+			if (--vl->resort_timer == 0) {
+				StationID station = (w->window_number & SHARE_FLAG) ? INVALID_STATION : GB(w->window_number, 16, 16);
+				PlayerID owner = GB(w->window_number, 0, 8);
+				DEBUG(misc, 1) ("Periodic resort ships list player %d station %d", 	owner, station);
+				vl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
+				vl->flags |= VL_RESORT;
+				SetWindowDirty(w);
+			}
+			break;
+
+		case WE_RESIZE:
+			/* Update the scroll + matrix */
+			if (vehicle_type == VEH_Train) w->hscroll.cap += e->sizing.diff.x;
+			w->vscroll.cap += e->sizing.diff.y / size_of_row;
+			w->widget[7].unkA = (w->vscroll.cap << 8) + 1;
+			break;
+	}
+}
--- a/vehicle_gui.h
+++ b/vehicle_gui.h
@@ -5,6 +5,7 @@
 
 #include "station.h"
 #include "vehicle.h"
+#include "window.h"
 
 struct vehiclelist_d;
 
@@ -43,6 +44,8 @@
 	PLY_WND_PRC__SIZE_OF_ROW_BIG   = 36,
 };
 
+void PlayerVehWndProc(Window *w, WindowEvent *e);
+
 void ShowReplaceVehicleWindow(byte vehicletype);
 
 void DrawTrainEnginePurchaseInfo(int x, int y, EngineID engine_number);
@@ -51,6 +54,19 @@
 void DrawAircraftPurchaseInfo(int x, int y, EngineID engine_number);
 void DrawShipPurchaseInfo(int x, int y, EngineID engine_number);
 
+void DrawTrainImage(const Vehicle *v, int x, int y, int count, int skip, VehicleID selection);
+void DrawRoadVehImage(const Vehicle *v, int x, int y, VehicleID selection);
+void DrawShipImage(const Vehicle *v, int x, int y, VehicleID selection);
+void DrawSmallOrderListShip(const Vehicle *v, int x, int y);
+
+void ShowBuildTrainWindow(TileIndex tile);
+void ShowBuildRoadVehWindow(TileIndex tile);
+void ShowBuildShipWindow(TileIndex tile);
+void ShowBuildAircraftWindow(TileIndex tile);
+
+void DrawAircraftImage(const Vehicle *v, int x, int y, VehicleID selection);
+void DrawSmallOrderListAircraft(const Vehicle *v, int x, int y);
+
 void ChangeVehicleViewWindow(const Vehicle *from_v, const Vehicle *to_v);
 
 int ShowAdditionalText(int x, int y, int w, EngineID engine_number);