diff options
Diffstat (limited to 'src/station_gui.cpp')
-rw-r--r-- | src/station_gui.cpp | 468 |
1 files changed, 228 insertions, 240 deletions
diff --git a/src/station_gui.cpp b/src/station_gui.cpp index dcf26efcc..a0e4c8937 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -727,12 +727,6 @@ static void DrawCargoIcons(CargoID i, uint waiting, int x, int y, uint width) } while (--num); } -struct stationview_d { - uint32 cargo; ///< Bitmask of cargo types to expand - uint16 cargo_rows[NUM_CARGO]; ///< Header row for each cargo type -}; -assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(stationview_d)); - struct CargoData { CargoID cargo; StationID source; @@ -748,285 +742,285 @@ struct CargoData { typedef std::list<CargoData> CargoDataList; /** - * Redraws whole StationView window - * - * @param w pointer to window + * The StationView window */ -static void DrawStationViewWindow(Window *w) -{ - StationID station_id = w->window_number; - const Station *st = GetStation(station_id); - CargoDataList cargolist; - uint32 transfers = 0; - - /* count types of cargos waiting in station */ - for (CargoID i = 0; i < NUM_CARGO; i++) { - if (st->goods[i].cargo.Empty()) { - WP(w, stationview_d).cargo_rows[i] = 0; - } else { - /* Add an entry for total amount of cargo of this type waiting. */ - cargolist.push_back(CargoData(i, INVALID_STATION, st->goods[i].cargo.Count())); - - /* Set the row for this cargo entry for the expand/hide button */ - WP(w, stationview_d).cargo_rows[i] = cargolist.size(); - - /* Add an entry for each distinct cargo source. */ - const CargoList::List *packets = st->goods[i].cargo.Packets(); - for (CargoList::List::const_iterator it = packets->begin(); it != packets->end(); it++) { - const CargoPacket *cp = *it; - if (cp->source != station_id) { - bool added = false; - - /* Enable the expand/hide button for this cargo type */ - SetBit(transfers, i); - - /* Don't add cargo lines if not expanded */ - if (!HasBit(WP(w, stationview_d).cargo, i)) break; - - /* Check if we already have this source in the list */ - for (CargoDataList::iterator jt = cargolist.begin(); jt != cargolist.end(); jt++) { - CargoData *cd = &(*jt); - if (cd->cargo == i && cd->source == cp->source) { - cd->count += cp->count; - added = true; - break; +struct StationViewWindow : public Window { + uint32 cargo; ///< Bitmask of cargo types to expand + uint16 cargo_rows[NUM_CARGO]; ///< Header row for each cargo type + + StationViewWindow(const WindowDesc *desc, void *data, WindowNumber window_number) : Window(desc, data, window_number) + { + PlayerID owner = GetStation(window_number)->owner; + if (owner != OWNER_NONE) this->caption_color = owner; + this->vscroll.cap = 5; + this->resize.step_height = 10; + + this->FindWindowPlacementAndResize(desc); + } + + ~StationViewWindow() + { + WindowNumber wno = + (this->window_number << 16) | VLW_STATION_LIST | GetStation(this->window_number)->owner; + + DeleteWindowById(WC_TRAINS_LIST, wno); + DeleteWindowById(WC_ROADVEH_LIST, wno); + DeleteWindowById(WC_SHIPS_LIST, wno); + DeleteWindowById(WC_AIRCRAFT_LIST, wno); + } + + virtual void OnPaint() + { + StationID station_id = this->window_number; + const Station *st = GetStation(station_id); + CargoDataList cargolist; + uint32 transfers = 0; + + /* count types of cargos waiting in station */ + for (CargoID i = 0; i < NUM_CARGO; i++) { + if (st->goods[i].cargo.Empty()) { + this->cargo_rows[i] = 0; + } else { + /* Add an entry for total amount of cargo of this type waiting. */ + cargolist.push_back(CargoData(i, INVALID_STATION, st->goods[i].cargo.Count())); + + /* Set the row for this cargo entry for the expand/hide button */ + this->cargo_rows[i] = cargolist.size(); + + /* Add an entry for each distinct cargo source. */ + const CargoList::List *packets = st->goods[i].cargo.Packets(); + for (CargoList::List::const_iterator it = packets->begin(); it != packets->end(); it++) { + const CargoPacket *cp = *it; + if (cp->source != station_id) { + bool added = false; + + /* Enable the expand/hide button for this cargo type */ + SetBit(transfers, i); + + /* Don't add cargo lines if not expanded */ + if (!HasBit(this->cargo, i)) break; + + /* Check if we already have this source in the list */ + for (CargoDataList::iterator jt = cargolist.begin(); jt != cargolist.end(); jt++) { + CargoData *cd = &(*jt); + if (cd->cargo == i && cd->source == cp->source) { + cd->count += cp->count; + added = true; + break; + } } - } - if (!added) cargolist.push_back(CargoData(i, cp->source, cp->count)); + if (!added) cargolist.push_back(CargoData(i, cp->source, cp->count)); + } } } } - } - SetVScrollCount(w, cargolist.size() + 1); // update scrollbar + SetVScrollCount(this, cargolist.size() + 1); // update scrollbar - /* disable some buttons */ - w->SetWidgetDisabledState(SVW_RENAME, st->owner != _local_player); - w->SetWidgetDisabledState(SVW_TRAINS, !(st->facilities & FACIL_TRAIN)); - w->SetWidgetDisabledState(SVW_ROADVEHS, !(st->facilities & FACIL_TRUCK_STOP) && !(st->facilities & FACIL_BUS_STOP)); - w->SetWidgetDisabledState(SVW_PLANES, !(st->facilities & FACIL_AIRPORT)); - w->SetWidgetDisabledState(SVW_SHIPS, !(st->facilities & FACIL_DOCK)); + /* disable some buttons */ + this->SetWidgetDisabledState(SVW_RENAME, st->owner != _local_player); + this->SetWidgetDisabledState(SVW_TRAINS, !(st->facilities & FACIL_TRAIN)); + this->SetWidgetDisabledState(SVW_ROADVEHS, !(st->facilities & FACIL_TRUCK_STOP) && !(st->facilities & FACIL_BUS_STOP)); + this->SetWidgetDisabledState(SVW_PLANES, !(st->facilities & FACIL_AIRPORT)); + this->SetWidgetDisabledState(SVW_SHIPS, !(st->facilities & FACIL_DOCK)); - SetDParam(0, st->index); - SetDParam(1, st->facilities); - DrawWindowWidgets(w); + SetDParam(0, st->index); + SetDParam(1, st->facilities); + DrawWindowWidgets(this); - int x = 2; ///< coordinates used for printing waiting/accepted/rating of cargo - int y = 15; - int pos = w->vscroll.pos; ///< = w->vscroll.pos + int x = 2; ///< coordinates used for printing waiting/accepted/rating of cargo + int y = 15; + int pos = this->vscroll.pos; ///< = this->vscroll.pos - uint width = w->widget[SVW_WAITING].right - w->widget[SVW_WAITING].left - 4; - int maxrows = w->vscroll.cap; + uint width = this->widget[SVW_WAITING].right - this->widget[SVW_WAITING].left - 4; + int maxrows = this->vscroll.cap; - StringID str; + StringID str; - if (--pos < 0) { - str = STR_00D0_NOTHING; - for (CargoID i = 0; i < NUM_CARGO; i++) { - if (!st->goods[i].cargo.Empty()) str = STR_EMPTY; + if (--pos < 0) { + str = STR_00D0_NOTHING; + for (CargoID i = 0; i < NUM_CARGO; i++) { + if (!st->goods[i].cargo.Empty()) str = STR_EMPTY; + } + SetDParam(0, str); + DrawString(x, y, STR_0008_WAITING, TC_FROMSTRING); + y += 10; } - SetDParam(0, str); - DrawString(x, y, STR_0008_WAITING, TC_FROMSTRING); - y += 10; - } - for (CargoDataList::const_iterator it = cargolist.begin(); it != cargolist.end() && pos > -maxrows; ++it) { - if (--pos < 0) { - const CargoData *cd = &(*it); - if (cd->source == INVALID_STATION) { - /* Heading */ - DrawCargoIcons(cd->cargo, cd->count, x, y, width); - SetDParam(0, cd->cargo); - SetDParam(1, cd->count); - if (HasBit(transfers, cd->cargo)) { - /* This cargo has transfers waiting so show the expand or shrink 'button' */ - const char *sym = HasBit(WP(w, stationview_d).cargo, cd->cargo) ? "-" : "+"; - DrawStringRightAligned(x + width - 8, y, STR_0009, TC_FROMSTRING); - DoDrawString(sym, x + width - 6, y, TC_YELLOW); + for (CargoDataList::const_iterator it = cargolist.begin(); it != cargolist.end() && pos > -maxrows; ++it) { + if (--pos < 0) { + const CargoData *cd = &(*it); + if (cd->source == INVALID_STATION) { + /* Heading */ + DrawCargoIcons(cd->cargo, cd->count, x, y, width); + SetDParam(0, cd->cargo); + SetDParam(1, cd->count); + if (HasBit(transfers, cd->cargo)) { + /* This cargo has transfers waiting so show the expand or shrink 'button' */ + const char *sym = HasBit(this->cargo, cd->cargo) ? "-" : "+"; + DrawStringRightAligned(x + width - 8, y, STR_0009, TC_FROMSTRING); + DoDrawString(sym, x + width - 6, y, TC_YELLOW); + } else { + DrawStringRightAligned(x + width, y, STR_0009, TC_FROMSTRING); + } } else { - DrawStringRightAligned(x + width, y, STR_0009, TC_FROMSTRING); + SetDParam(0, cd->cargo); + SetDParam(1, cd->count); + SetDParam(2, cd->source); + DrawStringRightAlignedTruncated(x + width, y, STR_EN_ROUTE_FROM, TC_FROMSTRING, width); } - } else { - SetDParam(0, cd->cargo); - SetDParam(1, cd->count); - SetDParam(2, cd->source); - DrawStringRightAlignedTruncated(x + width, y, STR_EN_ROUTE_FROM, TC_FROMSTRING, width); - } - y += 10; + y += 10; + } } - } - if (w->widget[SVW_ACCEPTS].data == STR_3032_RATINGS) { // small window with list of accepted cargo - char *b = _userstring; - bool first = true; + if (this->widget[SVW_ACCEPTS].data == STR_3032_RATINGS) { // small window with list of accepted cargo + char *b = _userstring; + bool first = true; - b = InlineString(b, STR_000C_ACCEPTS); + b = InlineString(b, STR_000C_ACCEPTS); - for (CargoID i = 0; i < NUM_CARGO; i++) { - if (b >= lastof(_userstring) - (1 + 2 * 4)) break; // ',' or ' ' and two calls to Utf8Encode() - if (HasBit(st->goods[i].acceptance_pickup, GoodsEntry::ACCEPTANCE)) { - if (first) { - first = false; - } else { - /* Add a comma if this is not the first item */ - *b++ = ','; - *b++ = ' '; + for (CargoID i = 0; i < NUM_CARGO; i++) { + if (b >= lastof(_userstring) - (1 + 2 * 4)) break; // ',' or ' ' and two calls to Utf8Encode() + if (HasBit(st->goods[i].acceptance_pickup, GoodsEntry::ACCEPTANCE)) { + if (first) { + first = false; + } else { + /* Add a comma if this is not the first item */ + *b++ = ','; + *b++ = ' '; + } + b = InlineString(b, GetCargo(i)->name); } - b = InlineString(b, GetCargo(i)->name); } - } - /* If first is still true then no cargo is accepted */ - if (first) b = InlineString(b, STR_00D0_NOTHING); + /* If first is still true then no cargo is accepted */ + if (first) b = InlineString(b, STR_00D0_NOTHING); - *b = '\0'; + *b = '\0'; - /* Make sure we detect any buffer overflow */ - assert(b < endof(_userstring)); + /* Make sure we detect any buffer overflow */ + assert(b < endof(_userstring)); - DrawStringMultiLine(2, w->widget[SVW_ACCEPTLIST].top + 1, STR_SPEC_USERSTRING, w->widget[SVW_ACCEPTLIST].right - w->widget[SVW_ACCEPTLIST].left); - } else { // extended window with list of cargo ratings - y = w->widget[SVW_RATINGLIST].top + 1; + DrawStringMultiLine(2, this->widget[SVW_ACCEPTLIST].top + 1, STR_SPEC_USERSTRING, this->widget[SVW_ACCEPTLIST].right - this->widget[SVW_ACCEPTLIST].left); + } else { // extended window with list of cargo ratings + y = this->widget[SVW_RATINGLIST].top + 1; - DrawString(2, y, STR_3034_LOCAL_RATING_OF_TRANSPORT, TC_FROMSTRING); - y += 10; + DrawString(2, y, STR_3034_LOCAL_RATING_OF_TRANSPORT, TC_FROMSTRING); + y += 10; - for (CargoID i = 0; i < NUM_CARGO; i++) { - const CargoSpec *cs = GetCargo(i); - if (!cs->IsValid()) continue; + for (CargoID i = 0; i < NUM_CARGO; i++) { + const CargoSpec *cs = GetCargo(i); + if (!cs->IsValid()) continue; - const GoodsEntry *ge = &st->goods[i]; - if (!HasBit(ge->acceptance_pickup, GoodsEntry::PICKUP)) continue; + const GoodsEntry *ge = &st->goods[i]; + if (!HasBit(ge->acceptance_pickup, GoodsEntry::PICKUP)) continue; - SetDParam(0, cs->name); - SetDParam(2, ge->rating * 101 >> 8); - SetDParam(1, STR_3035_APPALLING + (ge->rating >> 5)); - DrawString(8, y, STR_303D, TC_FROMSTRING); - y += 10; + SetDParam(0, cs->name); + SetDParam(2, ge->rating * 101 >> 8); + SetDParam(1, STR_3035_APPALLING + (ge->rating >> 5)); + DrawString(8, y, STR_303D, TC_FROMSTRING); + y += 10; + } } } -} -static void HandleCargoWaitingClick(Window *w, int row) -{ - if (row == 0) return; + void HandleCargoWaitingClick(int row) + { + if (row == 0) return; - for (CargoID c = 0; c < NUM_CARGO; c++) { - if (WP(w, stationview_d).cargo_rows[c] == row) { - ToggleBit(WP(w, stationview_d).cargo, c); - w->InvalidateWidget(SVW_WAITING); - break; + for (CargoID c = 0; c < NUM_CARGO; c++) { + if (this->cargo_rows[c] == row) { + ToggleBit(this->cargo, c); + this->InvalidateWidget(SVW_WAITING); + break; + } } } -} - - -/** - * Fuction called when any WindowEvent occurs for any StationView window - * - * @param w pointer to the StationView window - * @param e pointer to window event - */ -static void StationViewWndProc(Window *w, WindowEvent *e) -{ - switch (e->event) { - case WE_PAINT: - DrawStationViewWindow(w); - break; - - case WE_CLICK: - switch (e->we.click.widget) { - case SVW_WAITING: - HandleCargoWaitingClick(w, (e->we.click.pt.y - w->widget[SVW_WAITING].top) / 10 + w->vscroll.pos); - break; - case SVW_LOCATION: - if (_ctrl_pressed) { - ShowExtraViewPortWindow(GetStation(w->window_number)->xy); - } else { - ScrollMainWindowToTile(GetStation(w->window_number)->xy); - } - break; - - case SVW_RATINGS: - w->SetDirty(); + virtual void OnClick(Point pt, int widget) + { + switch (widget) { + case SVW_WAITING: + this->HandleCargoWaitingClick((pt.y - this->widget[SVW_WAITING].top) / 10 + this->vscroll.pos); + break; - if (w->widget[SVW_RATINGS].data == STR_3032_RATINGS) { - /* Switch to ratings view */ - w->widget[SVW_RATINGS].data = STR_3033_ACCEPTS; - w->widget[SVW_RATINGS].tooltips = STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO; - ResizeWindowForWidget(w, SVW_ACCEPTLIST, 0, 100); - } else { - /* Switch to accepts view */ - w->widget[SVW_RATINGS].data = STR_3032_RATINGS; - w->widget[SVW_RATINGS].tooltips = STR_3054_SHOW_STATION_RATINGS; - ResizeWindowForWidget(w, SVW_ACCEPTLIST, 0, -100); - } - - w->SetDirty(); - break; + case SVW_LOCATION: + if (_ctrl_pressed) { + ShowExtraViewPortWindow(GetStation(this->window_number)->xy); + } else { + ScrollMainWindowToTile(GetStation(this->window_number)->xy); + } + break; - case SVW_RENAME: - SetDParam(0, w->window_number); - ShowQueryString(STR_STATION, STR_3030_RENAME_STATION_LOADING, 31, 180, w, CS_ALPHANUMERAL); - break; + case SVW_RATINGS: + this->SetDirty(); - case SVW_TRAINS: { // 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); - break; + if (this->widget[SVW_RATINGS].data == STR_3032_RATINGS) { + /* Switch to ratings view */ + this->widget[SVW_RATINGS].data = STR_3033_ACCEPTS; + this->widget[SVW_RATINGS].tooltips = STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO; + ResizeWindowForWidget(this, SVW_ACCEPTLIST, 0, 100); + } else { + /* Switch to accepts view */ + this->widget[SVW_RATINGS].data = STR_3032_RATINGS; + this->widget[SVW_RATINGS].tooltips = STR_3054_SHOW_STATION_RATINGS; + ResizeWindowForWidget(this, SVW_ACCEPTLIST, 0, -100); } - case SVW_ROADVEHS: { // 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); - break; - } + this->SetDirty(); + break; - case SVW_PLANES: { // Show a list of scheduled aircraft to this station - 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); - break; - } + case SVW_RENAME: + SetDParam(0, this->window_number); + ShowQueryString(STR_STATION, STR_3030_RENAME_STATION_LOADING, 31, 180, this, CS_ALPHANUMERAL); + break; - case SVW_SHIPS: { // Show a list of scheduled ships to this station - 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); - break; - } + case SVW_TRAINS: { // Show a list of scheduled trains to this station + const Station *st = GetStation(this->window_number); + ShowVehicleListWindow(st->owner, VEH_TRAIN, (StationID)this->window_number); + break; } - break; - case WE_ON_EDIT_TEXT: - if (!StrEmpty(e->we.edittext.str)) { - _cmd_text = e->we.edittext.str; - DoCommandP(0, w->window_number, 0, NULL, - CMD_RENAME_STATION | CMD_MSG(STR_3031_CAN_T_RENAME_STATION)); + case SVW_ROADVEHS: { // Show a list of scheduled road-vehicles to this station + const Station *st = GetStation(this->window_number); + ShowVehicleListWindow(st->owner, VEH_ROAD, (StationID)this->window_number); + break; + } + + case SVW_PLANES: { // Show a list of scheduled aircraft to this station + const Station *st = GetStation(this->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)this->window_number); + break; } - break; - case WE_DESTROY: { - WindowNumber wno = - (w->window_number << 16) | VLW_STATION_LIST | GetStation(w->window_number)->owner; + case SVW_SHIPS: { // Show a list of scheduled ships to this station + const Station *st = GetStation(this->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)this->window_number); + break; + } + } + } - DeleteWindowById(WC_TRAINS_LIST, wno); - DeleteWindowById(WC_ROADVEH_LIST, wno); - DeleteWindowById(WC_SHIPS_LIST, wno); - DeleteWindowById(WC_AIRCRAFT_LIST, wno); - break; + virtual void OnQueryTextFinished(char *str) + { + if (!StrEmpty(str)) { + _cmd_text = str; + DoCommandP(0, this->window_number, 0, NULL, + CMD_RENAME_STATION | CMD_MSG(STR_3031_CAN_T_RENAME_STATION)); } + } - case WE_RESIZE: - if (e->we.sizing.diff.x != 0) ResizeButtons(w, SVW_LOCATION, SVW_RENAME); - w->vscroll.cap += e->we.sizing.diff.y / (int)w->resize.step_height; - break; + virtual void OnResize(Point new_size, Point delta) + { + if (delta.x != 0) ResizeButtons(this, SVW_LOCATION, SVW_RENAME); + this->vscroll.cap += delta.y / (int)this->resize.step_height; } -} +}; static const WindowDesc _station_view_desc = { @@ -1034,7 +1028,7 @@ static const WindowDesc _station_view_desc = { WC_STATION_VIEW, WC_NONE, WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE, _station_view_widgets, - StationViewWndProc + NULL }; /** @@ -1044,11 +1038,5 @@ static const WindowDesc _station_view_desc = { */ void ShowStationViewWindow(StationID station) { - Window *w = AllocateWindowDescFront<Window>(&_station_view_desc, station); - if (w == NULL) return; - - PlayerID owner = GetStation(w->window_number)->owner; - if (owner != OWNER_NONE) w->caption_color = owner; - w->vscroll.cap = 5; - w->resize.step_height = 10; + AllocateWindowDescFront<StationViewWindow>(&_station_view_desc, station); } |