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 |
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); |