src/station_gui.cpp
branchNewGRF_ports
changeset 10184 fcf5fb2548eb
parent 6877 889301acc299
child 10242 52b4a9006029
equal deleted inserted replaced
10179:eec5a7dcbf61 10184:fcf5fb2548eb
     6 #include "openttd.h"
     6 #include "openttd.h"
     7 #include "debug.h"
     7 #include "debug.h"
     8 #include "gui.h"
     8 #include "gui.h"
     9 #include "window_gui.h"
     9 #include "window_gui.h"
    10 #include "textbuf_gui.h"
    10 #include "textbuf_gui.h"
    11 #include "station.h"
    11 #include "station_base.h"
    12 #include "player_func.h"
    12 #include "player_func.h"
    13 #include "economy_func.h"
    13 #include "economy_func.h"
    14 #include "town.h"
    14 #include "town.h"
    15 #include "command_func.h"
    15 #include "command_func.h"
    16 #include "variables.h"
    16 #include "variables.h"
    17 #include "vehicle_gui.h"
    17 #include "vehicle_gui.h"
    18 #include "cargotype.h"
    18 #include "cargotype.h"
    19 #include "station_gui.h"
    19 #include "station_gui.h"
    20 #include "station.h"
    20 #include "station_func.h"
    21 #include "strings_func.h"
    21 #include "strings_func.h"
    22 #include "core/alloc_func.hpp"
    22 #include "core/alloc_func.hpp"
    23 #include "window_func.h"
    23 #include "window_func.h"
    24 #include "viewport_func.h"
    24 #include "viewport_func.h"
    25 #include "gfx_func.h"
    25 #include "gfx_func.h"
    26 #include "widgets/dropdown_func.h"
    26 #include "widgets/dropdown_func.h"
       
    27 #include "newgrf_cargo.h"
    27 
    28 
    28 #include "table/strings.h"
    29 #include "table/strings.h"
    29 #include "table/sprites.h"
    30 #include "table/sprites.h"
    30 
    31 
    31 typedef int CDECL StationSortListingTypeFunction(const void*, const void*);
    32 typedef int CDECL StationSortListingTypeFunction(const void*, const void*);
   385 				const Station *st = sl->sort_list[i];
   386 				const Station *st = sl->sort_list[i];
   386 				int x;
   387 				int x;
   387 
   388 
   388 				assert(st->xy != 0);
   389 				assert(st->xy != 0);
   389 
   390 
   390  				/* Do not do the complex check HasStationInUse here, it may be even false
   391 				/* Do not do the complex check HasStationInUse here, it may be even false
   391 				 * when the order had been removed and the station list hasn't been removed yet */
   392 				 * when the order had been removed and the station list hasn't been removed yet */
   392 				assert(st->owner == owner || (st->owner == OWNER_NONE && !st->IsBuoy()));
   393 				assert(st->owner == owner || (st->owner == OWNER_NONE && !st->IsBuoy()));
   393 
   394 
   394 				SetDParam(0, st->index);
   395 				SetDParam(0, st->index);
   395 				SetDParam(1, st->facilities);
   396 				SetDParam(1, st->facilities);
   680 { WWT_PUSHTXTBTN,   RESIZE_LRTB,    14,   223,   236,    98,   109, STR_SHIP,          STR_SCHEDULED_SHIPS_TIP },             // SVW_SHIPS
   681 { WWT_PUSHTXTBTN,   RESIZE_LRTB,    14,   223,   236,    98,   109, STR_SHIP,          STR_SCHEDULED_SHIPS_TIP },             // SVW_SHIPS
   681 {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   237,   248,    98,   109, 0x0,               STR_RESIZE_BUTTON},
   682 {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   237,   248,    98,   109, 0x0,               STR_RESIZE_BUTTON},
   682 {   WIDGETS_END},
   683 {   WIDGETS_END},
   683 };
   684 };
   684 
   685 
   685 /**
   686 SpriteID GetCargoSprite(CargoID i)
   686  * Draws icons of wainting cargo in the StationView window
   687 {
   687  *
       
   688  * @param i type of cargo
       
   689  * @param waiting number of wainting units
       
   690  * @param x x on-screen coordinate where to start with drawing icons
       
   691  * @param y y coordinate
       
   692  */
       
   693 static void DrawCargoIcons(CargoID i, uint waiting, int x, int y, uint width)
       
   694 {
       
   695 	uint num = min((waiting + 5) / 10, width / 10); // maximum is width / 10 icons so it won't overflow
       
   696 	if (num == 0) return;
       
   697 
       
   698 	const CargoSpec *cs = GetCargo(i);
   688 	const CargoSpec *cs = GetCargo(i);
   699 	SpriteID sprite;
   689 	SpriteID sprite;
   700 
   690 
   701 	if (cs->sprite == 0xFFFF) {
   691 	if (cs->sprite == 0xFFFF) {
   702 		/* A value of 0xFFFF indicates we should draw a custom icon */
   692 		/* A value of 0xFFFF indicates we should draw a custom icon */
   705 		sprite = cs->sprite;
   695 		sprite = cs->sprite;
   706 	}
   696 	}
   707 
   697 
   708 	if (sprite == 0) sprite = SPR_CARGO_GOODS;
   698 	if (sprite == 0) sprite = SPR_CARGO_GOODS;
   709 
   699 
       
   700 	return sprite;
       
   701 }
       
   702 
       
   703 /**
       
   704  * Draws icons of waiting cargo in the StationView window
       
   705  *
       
   706  * @param i type of cargo
       
   707  * @param waiting number of waiting units
       
   708  * @param x x on-screen coordinate where to start with drawing icons
       
   709  * @param y y coordinate
       
   710  */
       
   711 static void DrawCargoIcons(CargoID i, uint waiting, int x, int y, uint width)
       
   712 {
       
   713 	uint num = min((waiting + 5) / 10, width / 10); // maximum is width / 10 icons so it won't overflow
       
   714 	if (num == 0) return;
       
   715 
       
   716 	SpriteID sprite = GetCargoSprite(i);
       
   717 
   710 	do {
   718 	do {
   711 		DrawSprite(sprite, PAL_NONE, x, y);
   719 		DrawSprite(sprite, PAL_NONE, x, y);
   712 		x += 10;
   720 		x += 10;
   713 	} while (--num);
   721 	} while (--num);
   714 }
   722 }
       
   723 
       
   724 struct stationview_d {
       
   725 	uint32 cargo;                 ///< Bitmask of cargo types to expand
       
   726 	uint16 cargo_rows[NUM_CARGO]; ///< Header row for each cargo type
       
   727 };
       
   728 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(stationview_d));
   715 
   729 
   716 struct CargoData {
   730 struct CargoData {
   717 	CargoID cargo;
   731 	CargoID cargo;
   718 	StationID source;
   732 	StationID source;
   719 	uint count;
   733 	uint count;
   738 	const Station* st = GetStation(station_id);
   752 	const Station* st = GetStation(station_id);
   739 	int x, y;     ///< coordinates used for printing waiting/accepted/rating of cargo
   753 	int x, y;     ///< coordinates used for printing waiting/accepted/rating of cargo
   740 	int pos;      ///< = w->vscroll.pos
   754 	int pos;      ///< = w->vscroll.pos
   741 	StringID str;
   755 	StringID str;
   742 	CargoDataList cargolist;
   756 	CargoDataList cargolist;
       
   757 	uint32 transfers = 0;
   743 
   758 
   744 	/* count types of cargos waiting in station */
   759 	/* count types of cargos waiting in station */
   745 	for (CargoID i = 0; i < NUM_CARGO; i++) {
   760 	for (CargoID i = 0; i < NUM_CARGO; i++) {
   746 		if (!st->goods[i].cargo.Empty()) {
   761 		if (st->goods[i].cargo.Empty()) {
       
   762 			WP(w, stationview_d).cargo_rows[i] = 0;
       
   763 		} else {
   747 			/* Add an entry for total amount of cargo of this type waiting. */
   764 			/* Add an entry for total amount of cargo of this type waiting. */
   748 			cargolist.push_back(CargoData(i, INVALID_STATION, st->goods[i].cargo.Count()));
   765 			cargolist.push_back(CargoData(i, INVALID_STATION, st->goods[i].cargo.Count()));
       
   766 
       
   767 			/* Set the row for this cargo entry for the expand/hide button */
       
   768 			WP(w, stationview_d).cargo_rows[i] = cargolist.size();
   749 
   769 
   750 			/* Add an entry for each distinct cargo source. */
   770 			/* Add an entry for each distinct cargo source. */
   751 			const CargoList::List *packets = st->goods[i].cargo.Packets();
   771 			const CargoList::List *packets = st->goods[i].cargo.Packets();
   752 			for (CargoList::List::const_iterator it = packets->begin(); it != packets->end(); it++) {
   772 			for (CargoList::List::const_iterator it = packets->begin(); it != packets->end(); it++) {
   753 				const CargoPacket *cp = *it;
   773 				const CargoPacket *cp = *it;
   754 				if (cp->source != station_id) {
   774 				if (cp->source != station_id) {
   755 					bool added = false;
   775 					bool added = false;
       
   776 
       
   777 					/* Enable the expand/hide button for this cargo type */
       
   778 					SetBit(transfers, i);
       
   779 
       
   780 					/* Don't add cargo lines if not expanded */
       
   781 					if (!HasBit(WP(w, stationview_d).cargo, i)) break;
   756 
   782 
   757 					/* Check if we already have this source in the list */
   783 					/* Check if we already have this source in the list */
   758 					for (CargoDataList::iterator jt = cargolist.begin(); jt != cargolist.end(); jt++) {
   784 					for (CargoDataList::iterator jt = cargolist.begin(); jt != cargolist.end(); jt++) {
   759 						CargoData *cd = &(*jt);
   785 						CargoData *cd = &(*jt);
   760 						if (cd->cargo == i && cd->source == cp->source) {
   786 						if (cd->cargo == i && cd->source == cp->source) {
   805 			if (cd->source == INVALID_STATION) {
   831 			if (cd->source == INVALID_STATION) {
   806 				/* Heading */
   832 				/* Heading */
   807 				DrawCargoIcons(cd->cargo, cd->count, x, y, width);
   833 				DrawCargoIcons(cd->cargo, cd->count, x, y, width);
   808 				SetDParam(0, cd->cargo);
   834 				SetDParam(0, cd->cargo);
   809 				SetDParam(1, cd->count);
   835 				SetDParam(1, cd->count);
   810 				DrawStringRightAligned(x + width, y, STR_0009, TC_FROMSTRING);
   836 				if (HasBit(transfers, cd->cargo)) {
       
   837 					/* This cargo has transfers waiting so show the expand or shrink 'button' */
       
   838 					const char *sym = HasBit(WP(w, stationview_d).cargo, cd->cargo) ? "-" : "+";
       
   839 					DrawStringRightAligned(x + width - 8, y, STR_0009, TC_FROMSTRING);
       
   840 					DoDrawString(sym, x + width - 6, y, TC_YELLOW);
       
   841 				} else {
       
   842 					DrawStringRightAligned(x + width, y, STR_0009, TC_FROMSTRING);
       
   843 				}
   811 			} else {
   844 			} else {
   812 				SetDParam(0, cd->cargo);
   845 				SetDParam(0, cd->cargo);
   813 				SetDParam(1, cd->count);
   846 				SetDParam(1, cd->count);
   814 				SetDParam(2, cd->source);
   847 				SetDParam(2, cd->source);
   815 				DrawStringRightAlignedTruncated(x + width, y, STR_EN_ROUTE_FROM, TC_FROMSTRING, width);
   848 				DrawStringRightAlignedTruncated(x + width, y, STR_EN_ROUTE_FROM, TC_FROMSTRING, width);
   868 			y += 10;
   901 			y += 10;
   869 		}
   902 		}
   870 	}
   903 	}
   871 }
   904 }
   872 
   905 
       
   906 static void HandleCargoWaitingClick(Window *w, int row)
       
   907 {
       
   908 	if (row == 0) return;
       
   909 
       
   910 	for (CargoID c = 0; c < NUM_CARGO; c++) {
       
   911 		if (WP(w, stationview_d).cargo_rows[c] == row) {
       
   912 			ToggleBit(WP(w, stationview_d).cargo, c);
       
   913 			w->InvalidateWidget(SVW_WAITING);
       
   914 			break;
       
   915 		}
       
   916 	}
       
   917 }
       
   918 
   873 
   919 
   874 /**
   920 /**
   875  * Fuction called when any WindowEvent occurs for any StationView window
   921  * Fuction called when any WindowEvent occurs for any StationView window
   876  *
   922  *
   877  * @param w pointer to the StationView window
   923  * @param w pointer to the StationView window
   884 			DrawStationViewWindow(w);
   930 			DrawStationViewWindow(w);
   885 			break;
   931 			break;
   886 
   932 
   887 		case WE_CLICK:
   933 		case WE_CLICK:
   888 			switch (e->we.click.widget) {
   934 			switch (e->we.click.widget) {
       
   935 				case SVW_WAITING:
       
   936 					HandleCargoWaitingClick(w, (e->we.click.pt.y - w->widget[SVW_WAITING].top) / 10 + w->vscroll.pos);
       
   937 					break;
       
   938 
   889 				case SVW_LOCATION:
   939 				case SVW_LOCATION:
   890 					ScrollMainWindowToTile(GetStation(w->window_number)->xy);
   940 					ScrollMainWindowToTile(GetStation(w->window_number)->xy);
   891 					break;
   941 					break;
   892 
   942 
   893 				case SVW_RATINGS:
   943 				case SVW_RATINGS:
   951 			}
  1001 			}
   952 			break;
  1002 			break;
   953 
  1003 
   954 		case WE_DESTROY: {
  1004 		case WE_DESTROY: {
   955 			WindowNumber wno =
  1005 			WindowNumber wno =
   956 				(w->window_number << 16) | GetStation(w->window_number)->owner;
  1006 				(w->window_number << 16) | VLW_STATION_LIST | GetStation(w->window_number)->owner;
   957 
  1007 
   958 			DeleteWindowById(WC_TRAINS_LIST, wno);
  1008 			DeleteWindowById(WC_TRAINS_LIST, wno);
   959 			DeleteWindowById(WC_ROADVEH_LIST, wno);
  1009 			DeleteWindowById(WC_ROADVEH_LIST, wno);
   960 			DeleteWindowById(WC_SHIPS_LIST, wno);
  1010 			DeleteWindowById(WC_SHIPS_LIST, wno);
   961 			DeleteWindowById(WC_AIRCRAFT_LIST, wno);
  1011 			DeleteWindowById(WC_AIRCRAFT_LIST, wno);