--- a/src/station_gui.cpp Sat Mar 10 11:07:13 2007 +0000
+++ b/src/station_gui.cpp Sun Mar 11 16:31:18 2007 +0000
@@ -30,9 +30,9 @@
STATIONLIST_WIDGET_BUS,
STATIONLIST_WIDGET_AIRPLANE,
STATIONLIST_WIDGET_SHIP,
- STATIONLIST_WIDGET_CARGOSTART = 12,
- STATIONLIST_WIDGET_NOCARGOWAITING = 24,
- STATIONLIST_WIDGET_FACILALL = 26,
+ STATIONLIST_WIDGET_CARGOSTART = 20,
+ STATIONLIST_WIDGET_NOCARGOWAITING = 12,
+ STATIONLIST_WIDGET_FACILALL = 14,
STATIONLIST_WIDGET_CARGOALL,
STATIONLIST_WIDGET_SORTBY,
STATIONLIST_WIDGET_SORTCRITERIA,
@@ -138,6 +138,14 @@
return (_internal_sort_order & 1) ? sum2 - sum1 : sum1 - sum2;
}
+/**
+ * qsort-compatible version of sorting two stations by maximum rating
+ * @param a First object to be sorted, must be of type (const Station *)
+ * @param b Second object to be sorted, must be of type (const Station *)
+ * @return The sort order
+ * @retval >0 a should come before b in the list
+ * @retval <0 b should come before a in the list
+ */
static int CDECL StationRatingMaxSorter(const void *a, const void *b)
{
const Station* st1 = *(const Station**)a;
@@ -146,31 +154,31 @@
byte maxr2 = 0;
for (CargoID j = 0; j < NUM_CARGO; j++) {
- if (st1->goods[j].waiting_acceptance & 0xfff) maxr1 = max(maxr1, st1->goods[j].rating);
- if (st2->goods[j].waiting_acceptance & 0xfff) maxr2 = max(maxr2, st2->goods[j].rating);
+ if (st1->goods[j].enroute_from != INVALID_STATION) maxr1 = max(maxr1, st1->goods[j].rating);
+ if (st2->goods[j].enroute_from != INVALID_STATION) maxr2 = max(maxr2, st2->goods[j].rating);
}
return (_internal_sort_order & 1) ? maxr2 - maxr1 : maxr1 - maxr2;
}
-typedef enum StationListFlags {
+enum StationListFlags {
SL_ORDER = 0x01,
SL_RESORT = 0x02,
SL_REBUILD = 0x04,
-} StationListFlags;
+};
DECLARE_ENUM_AS_BIT_SET(StationListFlags);
-typedef struct plstations_d {
+struct plstations_d {
const Station** sort_list;
uint16 list_length;
byte sort_type;
StationListFlags flags;
uint16 resort_timer; //was byte refresh_counter;
-} plstations_d;
+};
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(plstations_d));
-void RebuildStationLists(void)
+void RebuildStationLists()
{
BaseWindow *w = NULL;
@@ -182,7 +190,7 @@
}
}
-void ResortStationLists(void)
+void ResortStationLists()
{
BaseWindow *w = NULL;
@@ -194,7 +202,7 @@
}
}
-static void BuildStationsList(plstations_d* sl, PlayerID owner, byte facilities, uint16 cargo_filter)
+static void BuildStationsList(plstations_d* sl, PlayerID owner, byte facilities, uint32 cargo_filter, bool include_empty)
{
uint n = 0;
const Station *st;
@@ -221,7 +229,7 @@
}
}
//stations without waiting cargo
- if (num_waiting_cargo == 0 && HASBIT(cargo_filter, NUM_CARGO)) {
+ if (num_waiting_cargo == 0 && include_empty) {
station_sort[n++] = st;
}
}
@@ -259,28 +267,28 @@
sl->flags &= ~SL_RESORT;
}
+static uint32 _cargo_filter = std::numeric_limits<uint32>::max();
+
static void PlayerStationsWndProc(BaseWindow *w, WindowEvent *e)
{
- static const uint16 CARGO_ALL_SELECTED = 0x1FFF;
-
const PlayerID owner = (PlayerID)w->window_number;
static byte facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
- static uint16 cargo_filter = CARGO_ALL_SELECTED;
static Listing station_sort = {0, 0};
+ static bool include_empty = true;
plstations_d *sl = &WP(w, plstations_d);
switch (e->event) {
case WE_CREATE: /* set up resort timer */
+ if (_cargo_filter == std::numeric_limits<uint32>::max()) _cargo_filter = _cargo_mask;
+
for (uint i = 0; i < 5; i++) {
if (HASBIT(facilities, i)) w->LowerWidget(i + STATIONLIST_WIDGET_TRAIN);
}
- for (CargoID i = 0; i < NUM_CARGO; i++) {
- if (HASBIT(cargo_filter, i)) w->LowerWidget(i + STATIONLIST_WIDGET_CARGOSTART);
- }
+
w->SetWidgetLoweredState(STATIONLIST_WIDGET_FACILALL, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
- w->SetWidgetLoweredState(STATIONLIST_WIDGET_CARGOALL, cargo_filter == CARGO_ALL_SELECTED);
- w->SetWidgetLoweredState(STATIONLIST_WIDGET_NOCARGOWAITING, HASBIT(cargo_filter, STATIONLIST_WIDGET_NOCARGOWAITING - NUM_CARGO));
+ w->SetWidgetLoweredState(STATIONLIST_WIDGET_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
+ w->SetWidgetLoweredState(STATIONLIST_WIDGET_NOCARGOWAITING, include_empty);
sl->sort_list = NULL;
sl->flags = SL_REBUILD;
@@ -290,7 +298,7 @@
break;
case WE_PAINT: {
- BuildStationsList(sl, owner, facilities, cargo_filter);
+ BuildStationsList(sl, owner, facilities, _cargo_filter, include_empty);
SortStationsList(sl);
SetVScrollCount(w, sl->list_length);
@@ -312,14 +320,16 @@
int y = 14;
int xb = 2; // offset from left of widget
- for (CargoID i = 0; i < NUM_CARGO; i++) {
- const CargoSpec *cs = GetCargo(i);
- if (cs->IsValid()) {
- cg_ofst = w->IsWidgetLowered(i + STATIONLIST_WIDGET_CARGOSTART) ? 2 : 1;
- GfxFillRect(x + cg_ofst, y + cg_ofst, x + cg_ofst + 10 , y + cg_ofst + 7, cs->rating_colour);
- DrawStringCentered(x + 6 + cg_ofst, y + cg_ofst, cs->abbrev, 0x10);
- }
+ uint i = 0;
+ for (CargoID c = 0; c < NUM_CARGO; c++) {
+ const CargoSpec *cs = GetCargo(c);
+ if (!cs->IsValid()) continue;
+
+ cg_ofst = HASBIT(_cargo_filter, c) ? 2 : 1;
+ GfxFillRect(x + cg_ofst, y + cg_ofst, x + cg_ofst + 10 , y + cg_ofst + 7, cs->rating_colour);
+ DrawStringCentered(x + 6 + cg_ofst, y + cg_ofst, cs->abbrev, 0x10);
x += 14;
+ i++;
}
x += 6;
@@ -412,17 +422,22 @@
w->SetDirty();
break;
- case STATIONLIST_WIDGET_CARGOALL:
- for (CargoID i = 0; i < NUM_CARGO; i++) {
+ case STATIONLIST_WIDGET_CARGOALL: {
+ uint i = 0;
+ for (CargoID c = 0; c < NUM_CARGO; c++) {
+ if (!GetCargo(c)->IsValid()) continue;
w->LowerWidget(i + STATIONLIST_WIDGET_CARGOSTART);
+ i++;
}
w->LowerWidget(STATIONLIST_WIDGET_NOCARGOWAITING);
w->LowerWidget(STATIONLIST_WIDGET_CARGOALL);
- cargo_filter = CARGO_ALL_SELECTED;
+ _cargo_filter = _cargo_mask;
+ include_empty = true;
sl->flags |= SL_REBUILD;
w->SetDirty();
break;
+ }
case STATIONLIST_WIDGET_SORTBY: /*flip sorting method asc/desc*/
sl->flags ^= SL_ORDER; //DESC-flag
@@ -438,20 +453,53 @@
w->ShowDropDownMenu(_station_sort_listing, sl->sort_type, STATIONLIST_WIDGET_SORTDROPBTN, 0, 0);
break;
+ case STATIONLIST_WIDGET_NOCARGOWAITING:
+ if (_ctrl_pressed) {
+ include_empty = !include_empty;
+ w->ToggleWidgetLoweredState(STATIONLIST_WIDGET_NOCARGOWAITING);
+ } else {
+ for (uint i = STATIONLIST_WIDGET_CARGOSTART; i < w->widget_count; i++) {
+ w->RaiseWidget(i);
+ }
+
+ _cargo_filter = 0;
+ include_empty = true;
+
+ w->LowerWidget(STATIONLIST_WIDGET_NOCARGOWAITING);
+ }
+ sl->flags |= SL_REBUILD;
+ w->SetWidgetLoweredState(STATIONLIST_WIDGET_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
+ w->SetDirty();
+ break;
+
default:
- if (e->we.click.widget >= STATIONLIST_WIDGET_CARGOSTART && e->we.click.widget <= STATIONLIST_WIDGET_NOCARGOWAITING) { //change cargo_filter
+ if (e->we.click.widget >= STATIONLIST_WIDGET_CARGOSTART) { //change cargo_filter
+ /* Determine the selected cargo type */
+ CargoID c;
+ int i = 0;
+ for (c = 0; c < NUM_CARGO; c++) {
+ if (!GetCargo(c)->IsValid()) continue;
+ if (e->we.click.widget - STATIONLIST_WIDGET_CARGOSTART == i) break;
+ i++;
+ }
+
if (_ctrl_pressed) {
- TOGGLEBIT(cargo_filter, e->we.click.widget - STATIONLIST_WIDGET_CARGOSTART);
+ TOGGLEBIT(_cargo_filter, c);
w->ToggleWidgetLoweredState(e->we.click.widget);
} else {
- for (uint i = 0; cargo_filter != 0; i++, cargo_filter >>= 1) {
- if (HASBIT(cargo_filter, 0)) w->RaiseWidget(i + STATIONLIST_WIDGET_CARGOSTART);
+ for (uint i = STATIONLIST_WIDGET_CARGOSTART; i < w->widget_count; i++) {
+ w->RaiseWidget(i);
}
- SETBIT(cargo_filter, e->we.click.widget - STATIONLIST_WIDGET_CARGOSTART);
+ w->RaiseWidget(STATIONLIST_WIDGET_NOCARGOWAITING);
+
+ _cargo_filter = 0;
+ include_empty = false;
+
+ SETBIT(_cargo_filter, c);
w->LowerWidget(e->we.click.widget);
}
sl->flags |= SL_REBUILD;
- w->SetWidgetLoweredState(STATIONLIST_WIDGET_CARGOALL, cargo_filter == CARGO_ALL_SELECTED);
+ w->SetWidgetLoweredState(STATIONLIST_WIDGET_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
w->SetDirty();
}
break;
@@ -503,26 +551,14 @@
{ WWT_TEXTBTN, RESIZE_NONE, 14, 56, 69, 14, 24, STR_SHIP, STR_USE_CTRL_TO_SELECT_MORE},
//Index 11
{ WWT_PANEL, RESIZE_NONE, 14, 83, 88, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
-{ WWT_PANEL, RESIZE_NONE, 14, 89, 102, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
-{ WWT_PANEL, RESIZE_NONE, 14, 103, 116, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
-{ WWT_PANEL, RESIZE_NONE, 14, 117, 130, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
-{ WWT_PANEL, RESIZE_NONE, 14, 131, 144, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
-{ WWT_PANEL, RESIZE_NONE, 14, 145, 158, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
-{ WWT_PANEL, RESIZE_NONE, 14, 159, 172, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
-{ WWT_PANEL, RESIZE_NONE, 14, 173, 186, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
-{ WWT_PANEL, RESIZE_NONE, 14, 187, 200, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
-{ WWT_PANEL, RESIZE_NONE, 14, 201, 214, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
-{ WWT_PANEL, RESIZE_NONE, 14, 215, 228, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
-{ WWT_PANEL, RESIZE_NONE, 14, 229, 242, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
-{ WWT_PANEL, RESIZE_NONE, 14, 243, 256, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
-{ WWT_PANEL, RESIZE_NONE, 14, 257, 270, 14, 24, 0x0, STR_NO_WAITING_CARGO},
-{ WWT_PANEL, RESIZE_RIGHT, 14, 285, 357, 14, 24, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 89, 102, 14, 24, 0x0, STR_NO_WAITING_CARGO},
+{ WWT_PANEL, RESIZE_RIGHT, 14, 117, 357, 14, 24, 0x0, STR_NULL},
-//26
+//14
{ WWT_PANEL, RESIZE_NONE, 14, 70, 83, 14, 24, 0x0, STR_SELECT_ALL_FACILITIES},
-{ WWT_PANEL, RESIZE_NONE, 14, 271, 284, 14, 24, 0x0, STR_SELECT_ALL_TYPES},
+{ WWT_PANEL, RESIZE_NONE, 14, 103, 116, 14, 24, 0x0, STR_SELECT_ALL_TYPES},
-//28
+//16
{ WWT_TEXTBTN, RESIZE_NONE, 14, 0, 80, 25, 36, STR_SORT_BY, STR_SORT_ORDER_TIP},
{ WWT_PANEL, RESIZE_NONE, 14, 81, 232, 25, 36, 0x0, STR_SORT_CRITERIA_TIP},
{ WWT_TEXTBTN, RESIZE_NONE, 14, 233, 243, 25, 36, STR_0225, STR_SORT_CRITERIA_TIP},
@@ -550,6 +586,47 @@
w->vscroll.cap = 12;
w->resize.step_height = 10;
w->resize.height = w->Height() - 10 * 7; // minimum if 5 in the list
+
+ /* Add cargo filter buttons */
+ uint num_active = 0;
+ for (CargoID c = 0; c < NUM_CARGO; c++) {
+ if (GetCargo(c)->IsValid()) num_active++;
+ }
+
+ w->widget_count += num_active;
+ w->widget = ReallocT(w->widget, w->widget_count + 1);
+ w->widget[w->widget_count].type = WWT_LAST;
+
+ uint i = 0;
+ for (CargoID c = 0; c < NUM_CARGO; c++) {
+ if (!GetCargo(c)->IsValid()) continue;
+
+ OldWidget *wi = &w->widget[STATIONLIST_WIDGET_CARGOSTART + i];
+ wi->type = WWT_PANEL;
+ wi->m_display_flags = RESIZE_NONE;
+ wi->color = 14;
+ wi->left = 89 + i * 14;
+ wi->right = wi->left + 13;
+ wi->top = 14;
+ wi->bottom = 24;
+ wi->data = 0;
+ wi->tooltips = STR_USE_CTRL_TO_SELECT_MORE;
+
+ if (HASBIT(_cargo_filter, c)) w->LowerWidget(STATIONLIST_WIDGET_CARGOSTART + i);
+ i++;
+ }
+
+ w->widget[STATIONLIST_WIDGET_NOCARGOWAITING].left += num_active * 14;
+ w->widget[STATIONLIST_WIDGET_NOCARGOWAITING].right += num_active * 14;
+ w->widget[STATIONLIST_WIDGET_CARGOALL].left += num_active * 14;
+ w->widget[STATIONLIST_WIDGET_CARGOALL].right += num_active * 14;
+ w->widget[13].left += num_active * 14;
+
+ if (num_active > 15) {
+ /* Resize and fix the minimum width, if necessary */
+ w->Resize((num_active - 15) * 14, 0);
+ w->resize.width = w->Width();
+ }
}
static const OldWidget _station_view_expanded_widgets[] = {
@@ -630,8 +707,7 @@
y += 10;
}
- CargoID i = 0;
- do {
+ for (CargoID i = 0; i != NUM_CARGO && pos > -5; i++) {
uint waiting = GB(st->goods[i].waiting_acceptance, 0, 12);
if (waiting == 0) continue;
@@ -667,7 +743,7 @@
y += 10;
}
}
- } while (pos > -5 && ++i != NUM_CARGO);
+ }
if (w->IsOfPrototype(_station_view_widgets)) {
char *b = _userstring;
@@ -746,13 +822,13 @@
case 10: { /* Show a list of scheduled trains to this station */
const Station *st = GetStation(w->window_number);
- ShowVehicleListWindow(st->owner, VEH_Train, (StationID)w->window_number);
+ ShowVehicleListWindow(st->owner, VEH_TRAIN, (StationID)w->window_number);
break;
}
case 11: { /* Show a list of scheduled road-vehicles to this station */
const Station *st = GetStation(w->window_number);
- ShowVehicleListWindow(st->owner, VEH_Road, (StationID)w->window_number);
+ ShowVehicleListWindow(st->owner, VEH_ROAD, (StationID)w->window_number);
break;
}
@@ -760,7 +836,7 @@
const Station *st = GetStation(w->window_number);
/* Since oilrigs have no owners, show the scheduled aircraft of current player */
PlayerID owner = (st->owner == OWNER_NONE) ? _current_player : st->owner;
- ShowVehicleListWindow(owner, VEH_Aircraft, (StationID)w->window_number);
+ ShowVehicleListWindow(owner, VEH_AIRCRAFT, (StationID)w->window_number);
break;
}
@@ -768,7 +844,7 @@
const Station *st = GetStation(w->window_number);
/* Since oilrigs/bouys have no owners, show the scheduled ships of current player */
PlayerID owner = (st->owner == OWNER_NONE) ? _current_player : st->owner;
- ShowVehicleListWindow(owner, VEH_Ship, (StationID)w->window_number);
+ ShowVehicleListWindow(owner, VEH_SHIP, (StationID)w->window_number);
break;
}
}