changeset 10122:dff578338ffb draft

(svn r14306) -Codechange: unify the code to draw the vehicle list. -Fix [FS#2292]: inconsistency between drawn vehicle lists in the vehicle list and group windows.
author rubidium <rubidium@openttd.org>
date Sat, 13 Sep 2008 10:04:36 +0000
parents 630bb408b972
children 57aa34285d05
files src/autoreplace_cmd.cpp src/group_gui.cpp src/roadveh_cmd.cpp src/station_gui.cpp src/vehicle_gui.cpp src/vehicle_gui.h src/vehicle_gui_base.h
diffstat 7 files changed, 171 insertions(+), 180 deletions(-) [+]
line wrap: on
line diff
--- a/src/autoreplace_cmd.cpp
+++ b/src/autoreplace_cmd.cpp
@@ -16,6 +16,7 @@
 #include "functions.h"
 #include "autoreplace_func.h"
 #include "articulated_vehicles.h"
+#include "core/alloc_func.hpp"
 
 #include "table/strings.h"
 
--- a/src/group_gui.cpp
+++ b/src/group_gui.cpp
@@ -9,6 +9,7 @@
 #include "textbuf_gui.h"
 #include "command_func.h"
 #include "vehicle_gui.h"
+#include "vehicle_gui_base.h"
 #include "train.h"
 #include "group.h"
 #include "debug.h"
@@ -34,21 +35,11 @@
 	GRP_WIDGET_CLOSEBOX = 0,
 	GRP_WIDGET_CAPTION,
 	GRP_WIDGET_STICKY,
-	GRP_WIDGET_EMPTY_TOP_LEFT,
-	GRP_WIDGET_ALL_VEHICLES,
-	GRP_WIDGET_DEFAULT_VEHICLES,
-	GRP_WIDGET_LIST_GROUP,
-	GRP_WIDGET_LIST_GROUP_SCROLLBAR,
 	GRP_WIDGET_SORT_BY_ORDER,
 	GRP_WIDGET_SORT_BY_DROPDOWN,
 	GRP_WIDGET_EMPTY_TOP_RIGHT,
 	GRP_WIDGET_LIST_VEHICLE,
 	GRP_WIDGET_LIST_VEHICLE_SCROLLBAR,
-	GRP_WIDGET_CREATE_GROUP,
-	GRP_WIDGET_DELETE_GROUP,
-	GRP_WIDGET_RENAME_GROUP,
-	GRP_WIDGET_EMPTY1,
-	GRP_WIDGET_REPLACE_PROTECTION,
 	GRP_WIDGET_EMPTY2,
 	GRP_WIDGET_AVAILABLE_VEHICLES,
 	GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN,
@@ -56,6 +47,17 @@
 	GRP_WIDGET_START_ALL,
 	GRP_WIDGET_EMPTY_BOTTOM_RIGHT,
 	GRP_WIDGET_RESIZE,
+
+	GRP_WIDGET_EMPTY_TOP_LEFT,
+	GRP_WIDGET_ALL_VEHICLES,
+	GRP_WIDGET_DEFAULT_VEHICLES,
+	GRP_WIDGET_LIST_GROUP,
+	GRP_WIDGET_LIST_GROUP_SCROLLBAR,
+	GRP_WIDGET_CREATE_GROUP,
+	GRP_WIDGET_DELETE_GROUP,
+	GRP_WIDGET_RENAME_GROUP,
+	GRP_WIDGET_EMPTY1,
+	GRP_WIDGET_REPLACE_PROTECTION,
 };
 
 enum GroupActionListFunction {
@@ -92,21 +94,11 @@
 {   WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_GREY,     0,    10,     0,    13, STR_00C5,             STR_018B_CLOSE_WINDOW},
 {    WWT_CAPTION,  RESIZE_RIGHT,  COLOUR_GREY,    11,   447,     0,    13, 0x0,                  STR_018C_WINDOW_TITLE_DRAG_THIS},
 {  WWT_STICKYBOX,     RESIZE_LR,  COLOUR_GREY,   448,   459,     0,    13, 0x0,                  STR_STICKY_BUTTON},
-{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,     0,   199,    14,    25, 0x0,                  STR_NULL},
-{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,     0,   199,    26,    38, 0x0,                  STR_NULL},
-{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,     0,   199,    39,    51, 0x0,                  STR_NULL},
-{     WWT_MATRIX, RESIZE_BOTTOM,  COLOUR_GREY,     0,   187,    52,   168, 0x701,                STR_GROUPS_CLICK_ON_GROUP_FOR_TIP},
-{  WWT_SCROLLBAR, RESIZE_BOTTOM,  COLOUR_GREY,   188,   199,    52,   168, 0x0,                  STR_0190_SCROLL_BAR_SCROLLS_LIST},
 { WWT_PUSHTXTBTN,   RESIZE_NONE,  COLOUR_GREY,   200,   280,    14,    25, STR_SORT_BY,          STR_SORT_ORDER_TIP},
 {   WWT_DROPDOWN,   RESIZE_NONE,  COLOUR_GREY,   281,   447,    14,    25, 0x0,                  STR_SORT_CRITERIA_TIP},
 {      WWT_PANEL,  RESIZE_RIGHT,  COLOUR_GREY,   448,   459,    14,    25, 0x0,                  STR_NULL},
 {     WWT_MATRIX,     RESIZE_RB,  COLOUR_GREY,   200,   447,    26,   181, 0x701,                STR_NULL},
-{ WWT_SCROLL2BAR,    RESIZE_LRB,  COLOUR_GREY,   448,   459,    26,   181, 0x0,                  STR_0190_SCROLL_BAR_SCROLLS_LIST},
-{ WWT_PUSHIMGBTN,     RESIZE_TB,  COLOUR_GREY,     0,    23,   169,   193, 0x0,                  STR_GROUP_CREATE_TIP},
-{ WWT_PUSHIMGBTN,     RESIZE_TB,  COLOUR_GREY,    24,    47,   169,   193, 0x0,                  STR_GROUP_DELETE_TIP},
-{ WWT_PUSHIMGBTN,     RESIZE_TB,  COLOUR_GREY,    48,    71,   169,   193, 0x0,                  STR_GROUP_RENAME_TIP},
-{      WWT_PANEL,     RESIZE_TB,  COLOUR_GREY,    72,   163,   169,   193, 0x0,                  STR_NULL},
-{ WWT_PUSHIMGBTN,     RESIZE_TB,  COLOUR_GREY,   164,   187,   169,   193, 0x0,                  STR_GROUP_REPLACE_PROTECTION_TIP},
+{  WWT_SCROLLBAR,    RESIZE_LRB,  COLOUR_GREY,   448,   459,    26,   181, 0x0,                  STR_0190_SCROLL_BAR_SCROLLS_LIST},
 {      WWT_PANEL,     RESIZE_TB,  COLOUR_GREY,   188,   199,   169,   193, 0x0,                  STR_NULL},
 { WWT_PUSHTXTBTN,     RESIZE_TB,  COLOUR_GREY,   200,   305,   182,   193, 0x0,                  STR_AVAILABLE_ENGINES_TIP},
 {   WWT_DROPDOWN,     RESIZE_TB,  COLOUR_GREY,   306,   423,   182,   193, STR_MANAGE_LIST,      STR_MANAGE_LIST_TIP},
@@ -114,11 +106,22 @@
 { WWT_PUSHIMGBTN,     RESIZE_TB,  COLOUR_GREY,   436,   447,   182,   193, SPR_FLAG_VEH_RUNNING, STR_MASS_START_LIST_TIP},
 {      WWT_PANEL,    RESIZE_RTB,  COLOUR_GREY,   448,   447,   182,   193, 0x0,                  STR_NULL},
 {  WWT_RESIZEBOX,   RESIZE_LRTB,  COLOUR_GREY,   448,   459,   182,   193, 0x0,                  STR_RESIZE_BUTTON},
+
+{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,     0,   199,    14,    25, 0x0,                  STR_NULL},
+{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,     0,   199,    26,    38, 0x0,                  STR_NULL},
+{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,     0,   199,    39,    51, 0x0,                  STR_NULL},
+{     WWT_MATRIX, RESIZE_BOTTOM,  COLOUR_GREY,     0,   187,    52,   168, 0x701,                STR_GROUPS_CLICK_ON_GROUP_FOR_TIP},
+{ WWT_SCROLL2BAR, RESIZE_BOTTOM,  COLOUR_GREY,   188,   199,    52,   168, 0x0,                  STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_PUSHIMGBTN,     RESIZE_TB,  COLOUR_GREY,     0,    23,   169,   193, 0x0,                  STR_GROUP_CREATE_TIP},
+{ WWT_PUSHIMGBTN,     RESIZE_TB,  COLOUR_GREY,    24,    47,   169,   193, 0x0,                  STR_GROUP_DELETE_TIP},
+{ WWT_PUSHIMGBTN,     RESIZE_TB,  COLOUR_GREY,    48,    71,   169,   193, 0x0,                  STR_GROUP_RENAME_TIP},
+{      WWT_PANEL,     RESIZE_TB,  COLOUR_GREY,    72,   163,   169,   193, 0x0,                  STR_NULL},
+{ WWT_PUSHIMGBTN,     RESIZE_TB,  COLOUR_GREY,   164,   187,   169,   193, 0x0,                  STR_GROUP_REPLACE_PROTECTION_TIP},
 {   WIDGETS_END},
 };
 
 
-class VehicleGroupWindow : public Window, public VehicleListBase {
+class VehicleGroupWindow : public BaseVehicleListWindow {
 private:
 	GroupID group_sel;
 	VehicleID vehicle_sel;
@@ -170,7 +173,7 @@
 	}
 
 public:
-	VehicleGroupWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
+	VehicleGroupWindow(const WindowDesc *desc, WindowNumber window_number) : BaseVehicleListWindow(desc, window_number)
 	{
 		const PlayerID owner = (PlayerID)GB(this->window_number, 0, 8);
 		this->vehicle_type = (VehicleType)GB(this->window_number, 11, 5);
@@ -182,20 +185,20 @@
 			default: NOT_REACHED();
 			case VEH_TRAIN:
 			case VEH_ROAD:
-				this->vscroll.cap = 9;
-				this->vscroll2.cap = 6;
+				this->vscroll2.cap = 9;
+				this->vscroll.cap = 6;
 				this->resize.step_height = PLY_WND_PRC__SIZE_OF_ROW_SMALL;
 				break;
 			case VEH_SHIP:
 			case VEH_AIRCRAFT:
-				this->vscroll.cap = 9;
-				this->vscroll2.cap = 4;
+				this->vscroll2.cap = 9;
+				this->vscroll.cap = 4;
 				this->resize.step_height = PLY_WND_PRC__SIZE_OF_ROW_BIG;
 				break;
 		}
 
-		this->widget[GRP_WIDGET_LIST_GROUP].data = (this->vscroll.cap << 8) + 1;
-		this->widget[GRP_WIDGET_LIST_VEHICLE].data = (this->vscroll2.cap << 8) + 1;
+		this->widget[GRP_WIDGET_LIST_GROUP].data = (this->vscroll2.cap << 8) + 1;
+		this->widget[GRP_WIDGET_LIST_VEHICLE].data = (this->vscroll.cap << 8) + 1;
 
 		switch (this->vehicle_type) {
 			default: NOT_REACHED();
@@ -285,21 +288,20 @@
 	{
 		const PlayerID owner = (PlayerID)GB(this->window_number, 0, 8);
 		int x = this->widget[GRP_WIDGET_LIST_VEHICLE].left + 2;
-		int y2 = PLY_WND_PRC__OFFSET_TOP_WIDGET;
 		int y1 = PLY_WND_PRC__OFFSET_TOP_WIDGET + 2;
 		int max;
 		int i;
 
 		/* If we select the all vehicles, this->list will contain all vehicles of the player
 			* else this->list will contain all vehicles which belong to the selected group */
-		BuildVehicleList(this, owner, this->group_sel, IsAllGroupID(this->group_sel) ? VLW_STANDARD : VLW_GROUP_LIST);
-		SortVehicleList(this);
+		this->BuildVehicleList(owner, this->group_sel, IsAllGroupID(this->group_sel) ? VLW_STANDARD : VLW_GROUP_LIST);
+		this->SortVehicleList();
 
 		this->BuildGroupList(owner);
 		this->groups.Sort(&GroupNameSorter);
 
-		SetVScrollCount(this, this->groups.Length());
-		SetVScroll2Count(this, this->vehicles.Length());
+		SetVScroll2Count(this, this->groups.Length());
+		SetVScrollCount(this, this->vehicles.Length());
 
 		/* The drop down menu is out, *but* it may not be used, retract it. */
 		if (this->vehicles.Length() == 0 && this->IsWidgetLowered(GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN)) {
@@ -419,8 +421,8 @@
 
 		DrawString(10, y1, str_no_group_veh, IsDefaultGroupID(this->group_sel) ? TC_WHITE : TC_BLACK);
 
-		max = min(this->vscroll.pos + this->vscroll.cap, this->groups.Length());
-		for (i = this->vscroll.pos ; i < max ; ++i) {
+		max = min(this->vscroll2.pos + this->vscroll2.cap, this->groups.Length());
+		for (i = this->vscroll2.pos ; i < max ; ++i) {
 			const Group *g = this->groups[i];
 
 			assert(g->owner == owner);
@@ -438,34 +440,7 @@
 
 		this->DrawSortButtonState(GRP_WIDGET_SORT_BY_ORDER, this->vehicles.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
 
-		int list_width = this->widget[GRP_WIDGET_LIST_VEHICLE].right - this->widget[GRP_WIDGET_LIST_VEHICLE].left - 20;
-
-		/* Draw Matrix Vehicle according to the vehicle list built before */
-		max = min(this->vscroll2.pos + this->vscroll2.cap, this->vehicles.Length());
-		for (i = this->vscroll2.pos ; i < max ; ++i) {
-			const Vehicle* v = this->vehicles[i];
-
-			assert(v->type == this->vehicle_type && v->owner == owner);
-
-			DrawVehicleImage(v, x + 19, y2 + 6, this->vehicle_sel, list_width, 0);
-			DrawVehicleProfitButton(v, x, y2 + 13);
-
-			SetDParam(0, v->unitnumber);
-			DrawString(x, y2 + 2, v->IsInDepot() ? STR_021F : (v->age > v->max_age - 366 ? STR_00E3 : STR_00E2), TC_FROMSTRING);
-
-			if (this->resize.step_height == PLY_WND_PRC__SIZE_OF_ROW_BIG) DrawSmallOrderList(v, x + 138, y2);
-
-			SetDParam(0, v->GetDisplayProfitThisYear());
-			SetDParam(1, v->GetDisplayProfitLastYear());
-			DrawString(x + 19, y2 + this->resize.step_height - 8, STR_0198_PROFIT_THIS_YEAR_LAST_YEAR, TC_FROMSTRING);
-
-			if (IsValidGroupID(v->group_id)) {
-				SetDParam(0, v->group_id);
-				DrawString(x + 19, y2, STR_GROUP_TINY_NAME, TC_BLACK);
-			}
-
-			y2 += this->resize.step_height;
-		}
+		this->DrawVehicleListItems(x);
 	}
 
 	virtual void OnClick(Point pt, int widget)
@@ -501,9 +476,9 @@
 			case GRP_WIDGET_LIST_GROUP: { // Matrix Group
 				uint16 id_g = (pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET - 26) / PLY_WND_PRC__SIZE_OF_ROW_TINY;
 
-				if (id_g >= this->vscroll.cap) return;
+				if (id_g >= this->vscroll2.cap) return;
 
-				id_g += this->vscroll.pos;
+				id_g += this->vscroll2.pos;
 
 				if (id_g >= this->groups.Length()) return;
 
@@ -518,9 +493,9 @@
 				uint32 id_v = (pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / (int)this->resize.step_height;
 				const Vehicle *v;
 
-				if (id_v >= this->vscroll2.cap) return; // click out of bounds
+				if (id_v >= this->vscroll.cap) return; // click out of bounds
 
-				id_v += this->vscroll2.pos;
+				id_v += this->vscroll.pos;
 
 				if (id_v >= this->vehicles.Length()) return; // click out of list bound
 
@@ -608,9 +583,9 @@
 
 				this->SetDirty();
 
-				if (id_g >= this->vscroll.cap) return;
+				if (id_g >= this->vscroll2.cap) return;
 
-				id_g += this->vscroll.pos;
+				id_g += this->vscroll2.pos;
 
 				if (id_g >= this->groups.Length()) return;
 
@@ -628,9 +603,9 @@
 
 				this->SetDirty();
 
-				if (id_v >= this->vscroll2.cap) return; // click out of bounds
+				if (id_v >= this->vscroll.cap) return; // click out of bounds
 
-				id_v += this->vscroll2.pos;
+				id_v += this->vscroll.pos;
 
 				if (id_v >= this->vehicles.Length()) return; // click out of list bound
 
@@ -657,11 +632,11 @@
 
 	virtual void OnResize(Point new_size, Point delta)
 	{
-		this->vscroll.cap += delta.y / PLY_WND_PRC__SIZE_OF_ROW_TINY;
-		this->vscroll2.cap += delta.y / (int)this->resize.step_height;
+		this->vscroll2.cap += delta.y / PLY_WND_PRC__SIZE_OF_ROW_TINY;
+		this->vscroll.cap += delta.y / (int)this->resize.step_height;
 
-		this->widget[GRP_WIDGET_LIST_GROUP].data = (this->vscroll.cap << 8) + 1;
-		this->widget[GRP_WIDGET_LIST_VEHICLE].data = (this->vscroll2.cap << 8) + 1;
+		this->widget[GRP_WIDGET_LIST_GROUP].data = (this->vscroll2.cap << 8) + 1;
+		this->widget[GRP_WIDGET_LIST_VEHICLE].data = (this->vscroll.cap << 8) + 1;
 	}
 
 	virtual void OnDropdownSelect(int widget, int index)
@@ -717,9 +692,9 @@
 
 	virtual void OnPlaceObjectAbort()
 	{
-			/* abort drag & drop */
-			this->vehicle_sel = INVALID_VEHICLE;
-			this->InvalidateWidget(GRP_WIDGET_LIST_VEHICLE);
+		/* abort drag & drop */
+		this->vehicle_sel = INVALID_VEHICLE;
+		this->InvalidateWidget(GRP_WIDGET_LIST_VEHICLE);
 	}
 };
 
--- a/src/roadveh_cmd.cpp
+++ b/src/roadveh_cmd.cpp
@@ -43,6 +43,7 @@
 #include "depot_base.h"
 #include "depot_func.h"
 #include "effectvehicle_func.h"
+#include "core/alloc_func.hpp"
 
 #include "table/strings.h"
 
--- a/src/station_gui.cpp
+++ b/src/station_gui.cpp
@@ -27,6 +27,7 @@
 #include "newgrf_cargo.h"
 #include "string_func.h"
 #include "player_base.h"
+#include "sortlist_type.h"
 
 #include "table/strings.h"
 #include "table/sprites.h"
--- a/src/vehicle_gui.cpp
+++ b/src/vehicle_gui.cpp
@@ -12,6 +12,7 @@
 #include "command_func.h"
 #include "variables.h"
 #include "vehicle_gui.h"
+#include "vehicle_gui_base.h"
 #include "viewport_func.h"
 #include "gfx_func.h"
 #include "train.h"
@@ -57,7 +58,7 @@
 static GUIVehicleList::SortFunction VehicleValueSorter;
 static GUIVehicleList::SortFunction VehicleLengthSorter;
 
-GUIVehicleList::SortFunction* const VehicleListBase::vehicle_sorter_funcs[] = {
+GUIVehicleList::SortFunction* const BaseVehicleListWindow::vehicle_sorter_funcs[] = {
 	&VehicleNumberSorter,
 	&VehicleNameSorter,
 	&VehicleAgeSorter,
@@ -71,7 +72,7 @@
 	&VehicleLengthSorter,
 };
 
-const StringID VehicleListBase::vehicle_sorter_names[] = {
+const StringID BaseVehicleListWindow::vehicle_sorter_names[] = {
 	STR_SORT_BY_NUMBER,
 	STR_SORT_BY_DROPDOWN_NAME,
 	STR_SORT_BY_AGE,
@@ -86,23 +87,23 @@
 	INVALID_STRING_ID
 };
 
-void BuildVehicleList(VehicleListBase *vl, PlayerID owner, uint16 index, uint16 window_type)
+void BaseVehicleListWindow::BuildVehicleList(PlayerID owner, uint16 index, uint16 window_type)
 {
-	if (!vl->vehicles.NeedRebuild()) return;
+	if (!this->vehicles.NeedRebuild()) return;
 
 	DEBUG(misc, 3, "Building vehicle list for player %d at station %d", owner, index);
 
-	GenerateVehicleSortList(&vl->vehicles, vl->vehicle_type, owner, index, window_type);
+	GenerateVehicleSortList(&this->vehicles, this->vehicle_type, owner, index, window_type);
 
-	vl->vehicles.RebuildDone();
+	this->vehicles.RebuildDone();
 }
 
 /* cached values for VehicleNameSorter to spare many GetString() calls */
 static const Vehicle *_last_vehicle[2] = { NULL, NULL };
 
-void SortVehicleList(VehicleListBase *vl)
+void BaseVehicleListWindow::SortVehicleList()
 {
-	if (vl->vehicles.Sort()) return;
+	if (this->vehicles.Sort()) return;
 
 	/* invalidate cached values for name sorter - vehicle names could change */
 	_last_vehicle[0] = _last_vehicle[1] = NULL;
@@ -703,7 +704,7 @@
 	{   WIDGETS_END},
 };
 
-void DrawSmallOrderList(const Vehicle *v, int x, int y)
+static void DrawSmallOrderList(const Vehicle *v, int x, int y)
 {
 	const Order *order;
 	int sel, i = 0;
@@ -726,6 +727,58 @@
 	}
 }
 
+static void DrawVehicleImage(const Vehicle *v, int x, int y, VehicleID selection, int count, int skip)
+{
+	switch (v->type) {
+		case VEH_TRAIN:    DrawTrainImage(v, x, y, selection, count, skip); break;
+		case VEH_ROAD:     DrawRoadVehImage(v, x, y, selection, count);     break;
+		case VEH_SHIP:     DrawShipImage(v, x, y, selection);               break;
+		case VEH_AIRCRAFT: DrawAircraftImage(v, x, y, selection);           break;
+		default: NOT_REACHED();
+	}
+}
+
+/**
+ * Draw all the vehicle list items.
+ * @param x the position from where to draw the items.
+ */
+void BaseVehicleListWindow::DrawVehicleListItems(int x)
+{
+	int y = PLY_WND_PRC__OFFSET_TOP_WIDGET;
+	uint max = min(this->vscroll.pos + this->vscroll.cap, this->vehicles.Length());
+	for (uint i = this->vscroll.pos; i < max; ++i) {
+		const Vehicle *v = this->vehicles[i];
+		StringID str;
+
+		SetDParam(0, v->GetDisplayProfitThisYear());
+		SetDParam(1, v->GetDisplayProfitLastYear());
+
+		DrawVehicleImage(v, x + 19, y + 6, INVALID_VEHICLE, this->widget[VLW_WIDGET_LIST].right - this->widget[VLW_WIDGET_LIST].left - 20, 0);
+		DrawString(x + 19, y + this->resize.step_height - 8, STR_0198_PROFIT_THIS_YEAR_LAST_YEAR, TC_FROMSTRING);
+
+		if (v->name != NULL) {
+			/* The vehicle got a name so we will print it */
+			SetDParam(0, v->index);
+			DrawString(x + 19, y, STR_01AB, TC_FROMSTRING);
+		}
+
+		if (this->resize.step_height == PLY_WND_PRC__SIZE_OF_ROW_BIG) DrawSmallOrderList(v, x + 138, y);
+
+		if (v->IsInDepot()) {
+			str = STR_021F;
+		} else {
+			str = (v->age > v->max_age - 366) ? STR_00E3 : STR_00E2;
+		}
+
+		SetDParam(0, v->unitnumber);
+		DrawString(x, y + 2, str, TC_FROMSTRING);
+
+		DrawVehicleProfitButton(v, x, y + 13);
+
+		y += this->resize.step_height;
+	}
+}
+
 /**
  * Window for the (old) vehicle listing.
  *
@@ -735,9 +788,9 @@
  * 11-15 vehicle type (using VEH_, but can be compressed to fewer bytes if needed)
  * 16-31 StationID or OrderID depending on window type (bit 8-10)
  */
-struct VehicleListWindow : public Window, public VehicleListBase {
+struct VehicleListWindow : public BaseVehicleListWindow {
 
-	VehicleListWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
+	VehicleListWindow(const WindowDesc *desc, WindowNumber window_number) : BaseVehicleListWindow(desc, window_number)
 	{
 		uint16 window_type = this->window_number & VLW_MASK;
 		PlayerID player = (PlayerID)GB(this->window_number, 0, 8);
@@ -872,15 +925,12 @@
 	virtual void OnPaint()
 	{
 		int x = 2;
-		int y = PLY_WND_PRC__OFFSET_TOP_WIDGET;
-		int max;
-		int i;
 		const PlayerID owner = (PlayerID)this->caption_color;
 		const uint16 window_type = this->window_number & VLW_MASK;
 		const uint16 index = GB(this->window_number, 16, 16);
 
-		BuildVehicleList(this, owner, index, window_type);
-		SortVehicleList(this);
+		this->BuildVehicleList(owner, index, window_type);
+		this->SortVehicleList();
 		SetVScrollCount(this, this->vehicles.Length());
 
 		if (this->vehicles.Length() == 0) HideDropDownMenu(this);
@@ -942,38 +992,7 @@
 		/* draw arrow pointing up/down for ascending/descending sorting */
 		this->DrawSortButtonState(VLW_WIDGET_SORT_ORDER, this->vehicles.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
 
-		max = min(this->vscroll.pos + this->vscroll.cap, this->vehicles.Length());
-		for (i = this->vscroll.pos; i < max; ++i) {
-			const Vehicle *v = this->vehicles[i];
-			StringID str;
-
-			SetDParam(0, v->GetDisplayProfitThisYear());
-			SetDParam(1, v->GetDisplayProfitLastYear());
-
-			DrawVehicleImage(v, x + 19, y + 6, INVALID_VEHICLE, this->widget[VLW_WIDGET_LIST].right - this->widget[VLW_WIDGET_LIST].left - 20, 0);
-			DrawString(x + 19, y + this->resize.step_height - 8, STR_0198_PROFIT_THIS_YEAR_LAST_YEAR, TC_FROMSTRING);
-
-			if (v->name != NULL) {
-				/* The vehicle got a name so we will print it */
-				SetDParam(0, v->index);
-				DrawString(x + 19, y, STR_01AB, TC_FROMSTRING);
-			}
-
-			if (this->resize.step_height == PLY_WND_PRC__SIZE_OF_ROW_BIG) DrawSmallOrderList(v, x + 138, y);
-
-			if (v->IsInDepot()) {
-				str = STR_021F;
-			} else {
-				str = (v->age > v->max_age - 366) ? STR_00E3 : STR_00E2;
-			}
-
-			SetDParam(0, v->unitnumber);
-			DrawString(x, y + 2, str, TC_FROMSTRING);
-
-			DrawVehicleProfitButton(v, x, y + 13);
-
-			y += this->resize.step_height;
-		}
+		this->DrawVehicleListItems(x);
 	}
 
 	virtual void OnClick(Point pt, int widget)
@@ -2015,17 +2034,6 @@
 	AllocateWindowDescFront<VehicleViewWindow>((v->type == VEH_TRAIN) ? &_train_view_desc : &_vehicle_view_desc, v->index);
 }
 
-void DrawVehicleImage(const Vehicle *v, int x, int y, VehicleID selection, int count, int skip)
-{
-	switch (v->type) {
-		case VEH_TRAIN:    DrawTrainImage(v, x, y, selection, count, skip); break;
-		case VEH_ROAD:     DrawRoadVehImage(v, x, y, selection, count);     break;
-		case VEH_SHIP:     DrawShipImage(v, x, y, selection);               break;
-		case VEH_AIRCRAFT: DrawAircraftImage(v, x, y, selection);           break;
-		default: NOT_REACHED();
-	}
-}
-
 void StopGlobalFollowVehicle(const Vehicle *v)
 {
 	Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
--- a/src/vehicle_gui.h
+++ b/src/vehicle_gui.h
@@ -5,7 +5,6 @@
 #ifndef VEHICLE_GUI_H
 #define VEHICLE_GUI_H
 
-#include "sortlist_type.h"
 #include "window_type.h"
 #include "vehicle_type.h"
 #include "order_type.h"
@@ -36,14 +35,6 @@
 	VVW_WIDGET_FORCE_PROCEED,
 };
 
-/** Start of functions regarding vehicle list windows */
-enum {
-	PLY_WND_PRC__OFFSET_TOP_WIDGET = 26,
-	PLY_WND_PRC__SIZE_OF_ROW_TINY  = 13,
-	PLY_WND_PRC__SIZE_OF_ROW_SMALL = 26,
-	PLY_WND_PRC__SIZE_OF_ROW_BIG   = 39,
-};
-
 /** Vehicle List Window type flags */
 enum {
 	VLW_STANDARD      = 0 << 8,
@@ -78,10 +69,6 @@
 void ShowVehicleListWindow(PlayerID player, VehicleType vehicle_type, StationID station);
 void ShowVehicleListWindow(PlayerID player, VehicleType vehicle_type, TileIndex depot_tile);
 
-void DrawSmallOrderList(const Vehicle *v, int x, int y);
-
-void DrawVehicleImage(const Vehicle *v, int x, int y, VehicleID selection, int count, int skip);
-
 
 /* ChangeVehicleViewWindow() moves all windows for one vehicle to another vehicle.
  * For ease of use it can be called with both Vehicle pointers and VehicleIDs. */
@@ -113,33 +100,4 @@
 
 Vehicle *CheckClickOnVehicle(const struct ViewPort *vp, int x, int y);
 
-typedef GUIList<const Vehicle*> GUIVehicleList;
-
-struct VehicleListBase {
-	GUIVehicleList vehicles;  ///< The list of vehicles
-	Listing *sorting;         ///< Pointer to the vehicle type related sorting.
-	VehicleType vehicle_type; ///< The vehicle type that is sorted
-
-	static const StringID vehicle_sorter_names[];
-	static GUIVehicleList::SortFunction *const vehicle_sorter_funcs[];
-
-	VehicleListBase()
-	{
-		this->vehicles.SetSortFuncs(this->vehicle_sorter_funcs);
-	}
-};
-
-struct Sorting {
-	Listing aircraft;
-	Listing roadveh;
-	Listing ship;
-	Listing train;
-};
-
-extern Sorting _sorting;
-
-/* sorter stuff */
-void SortVehicleList(VehicleListBase *vl);
-void BuildVehicleList(VehicleListBase *vl, PlayerID owner, uint16 index, uint16 window_type);
-
 #endif /* VEHICLE_GUI_H */
new file mode 100644
--- /dev/null
+++ b/src/vehicle_gui_base.h
@@ -0,0 +1,47 @@
+/* $Id$ */
+
+/** @file vehicle_gui_base.h Functions/classes shared between the different vehicle list GUIs. */
+
+#ifndef VEHICLE_GUI_BASE_H
+#define VEHICLE_GUI_BASE_H
+
+#include "sortlist_type.h"
+
+/** Start of functions regarding vehicle list windows */
+enum {
+	PLY_WND_PRC__OFFSET_TOP_WIDGET = 26,
+	PLY_WND_PRC__SIZE_OF_ROW_TINY  = 13,
+	PLY_WND_PRC__SIZE_OF_ROW_SMALL = 26,
+	PLY_WND_PRC__SIZE_OF_ROW_BIG   = 39,
+};
+
+typedef GUIList<const Vehicle*> GUIVehicleList;
+
+struct BaseVehicleListWindow: public Window {
+	GUIVehicleList vehicles;  ///< The list of vehicles
+	Listing *sorting;         ///< Pointer to the vehicle type related sorting.
+	VehicleType vehicle_type; ///< The vehicle type that is sorted
+
+	static const StringID vehicle_sorter_names[];
+	static GUIVehicleList::SortFunction *const vehicle_sorter_funcs[];
+
+	BaseVehicleListWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
+	{
+		this->vehicles.SetSortFuncs(this->vehicle_sorter_funcs);
+	}
+
+	void DrawVehicleListItems(int x);
+	void SortVehicleList();
+	void BuildVehicleList(PlayerID owner, uint16 index, uint16 window_type);
+};
+
+struct Sorting {
+	Listing aircraft;
+	Listing roadveh;
+	Listing ship;
+	Listing train;
+};
+
+extern Sorting _sorting;
+
+#endif /* VEHICLE_GUI_BASE_H */