Add: NewGRF road stops

This commit is contained in:
Jonathan G Rennison
2022-11-06 15:01:27 +00:00
committed by rubidium42
parent a18182e24b
commit 4c1406a4b5
33 changed files with 2086 additions and 132 deletions

View File

@@ -34,6 +34,11 @@
#include "station_cmd.h"
#include "road_cmd.h"
#include "tunnelbridge_cmd.h"
#include "newgrf_roadstop.h"
#include "querystring_gui.h"
#include "sortlist_type.h"
#include "stringfilter_type.h"
#include "string_func.h"
#include "widgets/road_widget.h"
@@ -55,7 +60,42 @@ static bool _place_road_end_half;
static RoadType _cur_roadtype;
static DiagDirection _road_depot_orientation;
static DiagDirection _road_station_picker_orientation;
struct RoadStopGUISettings {
DiagDirection orientation;
RoadStopClassID roadstop_class;
byte roadstop_type;
byte roadstop_count;
};
static RoadStopGUISettings _roadstop_gui_settings;
/**
* Check whether a road stop type can be built.
* @return true if building is allowed.
*/
static bool IsRoadStopAvailable(const RoadStopSpec *roadstopspec, StationType type)
{
if (roadstopspec == nullptr) return true;
if (HasBit(roadstopspec->flags, RSF_BUILD_MENU_ROAD_ONLY) && !RoadTypeIsRoad(_cur_roadtype)) return false;
if (HasBit(roadstopspec->flags, RSF_BUILD_MENU_TRAM_ONLY) && !RoadTypeIsTram(_cur_roadtype)) return false;
if (roadstopspec->stop_type != ROADSTOPTYPE_ALL) {
switch (type) {
case STATION_BUS: if (roadstopspec->stop_type != ROADSTOPTYPE_PASSENGER) return false; break;
case STATION_TRUCK: if (roadstopspec->stop_type != ROADSTOPTYPE_FREIGHT) return false; break;
default: break;
}
}
if (!HasBit(roadstopspec->callback_mask, CBM_ROAD_STOP_AVAIL)) return true;
uint16 cb_res = GetRoadStopCallback(CBID_STATION_AVAILABILITY, 0, 0, roadstopspec, nullptr, INVALID_TILE, _cur_roadtype, type, 0);
if (cb_res == CALLBACK_FAILED) return true;
return Convert8bitBooleanCallback(roadstopspec->grf_prop.grffile, CBID_STATION_AVAILABILITY, cb_res);
}
void CcPlaySound_CONSTRUCTION_OTHER(Commands cmd, const CommandCost &result, TileIndex tile)
{
@@ -135,19 +175,31 @@ void CcRoadDepot(Commands cmd, const CommandCost &result, TileIndex tile, RoadTy
* @param length Length of the road stop.
* @param is_drive_through False for normal stops, true for drive-through.
* @param dir Entrance direction (#DiagDirection) for normal stops. Converted to the axis for drive-through stops.
* @param spec_class Road stop spec class.
* @param spec_index Road stop spec index.
* @see CmdBuildRoadStop
*/
void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, uint8 width, uint8 length, RoadStopType, bool is_drive_through, DiagDirection dir, RoadType, StationID, bool)
void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, uint8 width, uint8 length, RoadStopType, bool is_drive_through,
DiagDirection dir, RoadType, RoadStopClassID spec_class, byte spec_index, StationID, bool)
{
if (result.Failed()) return;
if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile);
if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
TileArea roadstop_area(tile, width, length);
for (TileIndex cur_tile : roadstop_area) {
ConnectRoadToStructure(cur_tile, dir);
/* For a drive-through road stop build connecting road for other entrance. */
if (is_drive_through) ConnectRoadToStructure(cur_tile, ReverseDiagDir(dir));
bool connect_to_road = true;
if ((uint)spec_class < RoadStopClass::GetClassCount() && spec_index < RoadStopClass::Get(spec_class)->GetSpecCount()) {
const RoadStopSpec *roadstopspec = RoadStopClass::Get(spec_class)->GetSpec(spec_index);
if (roadstopspec != nullptr && HasBit(roadstopspec->flags, RSF_NO_AUTO_ROAD_CONNECTION)) connect_to_road = false;
}
if (connect_to_road) {
TileArea roadstop_area(tile, width, length);
for (TileIndex cur_tile : roadstop_area) {
ConnectRoadToStructure(cur_tile, dir);
/* For a drive-through road stop build connecting road for other entrance. */
if (is_drive_through) ConnectRoadToStructure(cur_tile, ReverseDiagDir(dir));
}
}
}
@@ -164,15 +216,19 @@ void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, uint8 w
static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, RoadStopType stop_type, bool adjacent, RoadType rt, StringID err_msg)
{
TileArea ta(start_tile, end_tile);
DiagDirection ddir = _road_station_picker_orientation;
DiagDirection ddir = _roadstop_gui_settings.orientation;
bool drive_through = ddir >= DIAGDIR_END;
if (drive_through) ddir = static_cast<DiagDirection>(ddir - DIAGDIR_END); // Adjust picker result to actual direction.
RoadStopClassID spec_class = _roadstop_gui_settings.roadstop_class;
byte spec_index = _roadstop_gui_settings.roadstop_type;
auto proc = [=](bool test, StationID to_join) -> bool {
if (test) {
return Command<CMD_BUILD_ROAD_STOP>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_ROAD_STOP>()), ta.tile, ta.w, ta.h, stop_type, drive_through, ddir, rt, INVALID_STATION, adjacent).Succeeded();
return Command<CMD_BUILD_ROAD_STOP>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_ROAD_STOP>()), ta.tile, ta.w, ta.h, stop_type, drive_through,
ddir, rt, spec_class, spec_index, INVALID_STATION, adjacent).Succeeded();
} else {
return Command<CMD_BUILD_ROAD_STOP>::Post(err_msg, CcRoadStop, ta.tile, ta.w, ta.h, stop_type, drive_through, ddir, rt, to_join, adjacent);
return Command<CMD_BUILD_ROAD_STOP>::Post(err_msg, CcRoadStop, ta.tile, ta.w, ta.h, stop_type, drive_through,
ddir, rt, spec_class, spec_index, to_join, adjacent);
}
};
@@ -188,8 +244,8 @@ static void PlaceRoad_BusStation(TileIndex tile)
if (_remove_button_clicked) {
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_REMOVE_BUSSTOP);
} else {
if (_road_station_picker_orientation < DIAGDIR_END) { // Not a drive-through stop.
VpStartPlaceSizing(tile, (DiagDirToAxis(_road_station_picker_orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_BUSSTOP);
if (_roadstop_gui_settings.orientation < DIAGDIR_END) { // Not a drive-through stop.
VpStartPlaceSizing(tile, (DiagDirToAxis(_roadstop_gui_settings.orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_BUSSTOP);
} else {
VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_BUSSTOP);
}
@@ -206,8 +262,8 @@ static void PlaceRoad_TruckStation(TileIndex tile)
if (_remove_button_clicked) {
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_REMOVE_TRUCKSTOP);
} else {
if (_road_station_picker_orientation < DIAGDIR_END) { // Not a drive-through stop.
VpStartPlaceSizing(tile, (DiagDirToAxis(_road_station_picker_orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_TRUCKSTOP);
if (_roadstop_gui_settings.orientation < DIAGDIR_END) { // Not a drive-through stop.
VpStartPlaceSizing(tile, (DiagDirToAxis(_roadstop_gui_settings.orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_TRUCKSTOP);
} else {
VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_TRUCKSTOP);
}
@@ -652,7 +708,7 @@ struct BuildRoadToolbarWindow : Window {
case DDSP_BUILD_BUSSTOP:
case DDSP_REMOVE_BUSSTOP:
if (this->IsWidgetLowered(WID_ROT_BUS_STATION)) {
if (this->IsWidgetLowered(WID_ROT_BUS_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), ROADSTOP_BUS, _cur_roadtype)) {
if (_remove_button_clicked) {
TileArea ta(start_tile, end_tile);
Command<CMD_REMOVE_ROAD_STOP>::Post(this->rti->strings.err_remove_station[ROADSTOP_BUS], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w, ta.h, ROADSTOP_BUS, _ctrl_pressed);
@@ -664,7 +720,7 @@ struct BuildRoadToolbarWindow : Window {
case DDSP_BUILD_TRUCKSTOP:
case DDSP_REMOVE_TRUCKSTOP:
if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION)) {
if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), ROADSTOP_TRUCK, _cur_roadtype)) {
if (_remove_button_clicked) {
TileArea ta(start_tile, end_tile);
Command<CMD_REMOVE_ROAD_STOP>::Post(this->rti->strings.err_remove_station[ROADSTOP_TRUCK], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w, ta.h, ROADSTOP_TRUCK, _ctrl_pressed);
@@ -1046,14 +1102,91 @@ static void ShowRoadDepotPicker(Window *parent)
new BuildRoadDepotWindow(&_build_road_depot_desc, parent);
}
/** Enum referring to the Hotkeys in the build road stop window */
enum BuildRoadStopHotkeys {
BROSHK_FOCUS_FILTER_BOX, ///< Focus the edit box for editing the filter string
};
struct BuildRoadStationWindow : public PickerWindowBase {
BuildRoadStationWindow(WindowDesc *desc, Window *parent, RoadStopType rs) : PickerWindowBase(desc, parent)
private:
RoadStopType roadStopType; ///< The RoadStopType for this Window.
uint line_height; ///< Height of a single line in the newstation selection matrix.
uint coverage_height; ///< Height of the coverage texts.
Scrollbar *vscrollList; ///< Vertical scrollbar of the new station list.
Scrollbar *vscrollMatrix; ///< Vertical scrollbar of the station picker matrix.
typedef GUIList<RoadStopClassID, StringFilter &> GUIRoadStopClassList; ///< Type definition for the list to hold available road stop classes.
static const uint EDITBOX_MAX_SIZE = 16; ///< The maximum number of characters for the filter edit box.
static Listing last_sorting; ///< Default sorting of #GUIRoadStopClassList.
static Filtering last_filtering; ///< Default filtering of #GUIRoadStopClassList.
static GUIRoadStopClassList::SortFunction * const sorter_funcs[]; ///< Sort functions of the #GUIRoadStopClassList.
static GUIRoadStopClassList::FilterFunction * const filter_funcs[]; ///< Filter functions of the #GUIRoadStopClassList.
GUIRoadStopClassList roadstop_classes; ///< Available road stop classes.
StringFilter string_filter; ///< Filter for available road stop classes.
QueryString filter_editbox; ///< Filter editbox.
void EnsureSelectedClassIsVisible()
{
uint pos = 0;
for (auto rs_class : this->roadstop_classes) {
if (rs_class == _roadstop_gui_settings.roadstop_class) break;
pos++;
}
this->vscrollList->SetCount((int)this->roadstop_classes.size());
this->vscrollList->ScrollTowards(pos);
}
void CheckOrientationValid()
{
if (_roadstop_gui_settings.orientation >= DIAGDIR_END) return;
const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpec(_roadstop_gui_settings.roadstop_type);
if (spec != nullptr && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)) {
this->RaiseWidget(_roadstop_gui_settings.orientation + WID_BROS_STATION_NE);
_roadstop_gui_settings.orientation = DIAGDIR_END;
this->LowerWidget(_roadstop_gui_settings.orientation + WID_BROS_STATION_NE);
this->SetDirty();
CloseWindowById(WC_SELECT_STATION, 0);
}
}
public:
BuildRoadStationWindow(WindowDesc *desc, Window *parent, RoadStopType rs) : PickerWindowBase(desc, parent), filter_editbox(EDITBOX_MAX_SIZE * MAX_CHAR_LENGTH, EDITBOX_MAX_SIZE)
{
this->coverage_height = 2 * FONT_HEIGHT_NORMAL + 3 * WidgetDimensions::scaled.vsep_normal;
this->vscrollList = nullptr;
this->vscrollMatrix = nullptr;
this->roadStopType = rs;
bool newstops = GetIfNewStopsByType(rs, _cur_roadtype);
this->CreateNestedTree();
/* Hide the station class filter if no stations other than the default one are available. */
this->GetWidget<NWidgetStacked>(WID_BROS_SHOW_NEWST_DEFSIZE)->SetDisplayedPlane(newstops ? 0 : SZSP_NONE);
this->GetWidget<NWidgetStacked>(WID_BROS_FILTER_CONTAINER)->SetDisplayedPlane(newstops ? 0 : SZSP_HORIZONTAL);
this->GetWidget<NWidgetStacked>(WID_BROS_SHOW_NEWST_ADDITIONS)->SetDisplayedPlane(newstops ? 0 : SZSP_HORIZONTAL);
this->GetWidget<NWidgetStacked>(WID_BROS_SHOW_NEWST_ORIENTATION)->SetDisplayedPlane(newstops ? 0 : SZSP_HORIZONTAL);
this->GetWidget<NWidgetStacked>(WID_BROS_SHOW_NEWST_TYPE_SEL)->SetDisplayedPlane(newstops ? 0 : SZSP_HORIZONTAL);
this->GetWidget<NWidgetStacked>(WID_BROS_SHOW_NEWST_MATRIX)->SetDisplayedPlane(newstops ? 0 : SZSP_NONE);
this->GetWidget<NWidgetStacked>(WID_BROS_SHOW_NEWST_RESIZE)->SetDisplayedPlane(newstops ? 0 : SZSP_NONE);
if (newstops) {
this->vscrollList = this->GetScrollbar(WID_BROS_NEWST_SCROLL);
this->vscrollMatrix = this->GetScrollbar(WID_BROS_MATRIX_SCROLL);
this->querystrings[WID_BROS_FILTER_EDITBOX] = &this->filter_editbox;
this->roadstop_classes.SetListing(this->last_sorting);
this->roadstop_classes.SetFiltering(this->last_filtering);
this->roadstop_classes.SetSortFuncs(this->sorter_funcs);
this->roadstop_classes.SetFilterFuncs(this->filter_funcs);
}
this->roadstop_classes.ForceRebuild();
BuildRoadStopClassesAvailable();
/* Trams don't have non-drivethrough stations */
if (RoadTypeIsTram(_cur_roadtype) && _road_station_picker_orientation < DIAGDIR_END) {
_road_station_picker_orientation = DIAGDIR_END;
if (RoadTypeIsTram(_cur_roadtype) && _roadstop_gui_settings.orientation < DIAGDIR_END) {
_roadstop_gui_settings.orientation = DIAGDIR_END;
}
const RoadTypeInfo *rti = GetRoadTypeInfo(_cur_roadtype);
this->GetWidget<NWidgetCore>(WID_BROS_CAPTION)->widget_data = rti->strings.picker_title[rs];
@@ -1062,12 +1195,42 @@ struct BuildRoadStationWindow : public PickerWindowBase {
this->GetWidget<NWidgetCore>(i)->tool_tip = rti->strings.picker_tooltip[rs];
}
this->LowerWidget(_road_station_picker_orientation + WID_BROS_STATION_NE);
this->LowerWidget(_roadstop_gui_settings.orientation + WID_BROS_STATION_NE);
this->LowerWidget(_settings_client.gui.station_show_coverage + WID_BROS_LT_OFF);
this->FinishInitNested(TRANSPORT_ROAD);
this->window_class = (rs == ROADSTOP_BUS) ? WC_BUS_STATION : WC_TRUCK_STATION;
if (!newstops || _roadstop_gui_settings.roadstop_class >= (int)RoadStopClass::GetClassCount()) {
/* There's no new stops available or the list has reduced in size.
* Now, set the default road stops as selected. */
_roadstop_gui_settings.roadstop_class = ROADSTOP_CLASS_DFLT;
_roadstop_gui_settings.roadstop_type = 0;
}
if (newstops) {
/* The currently selected class doesn't have any stops for this RoadStopType, reset the selection. */
if (!GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), rs, _cur_roadtype)) {
_roadstop_gui_settings.roadstop_class = ROADSTOP_CLASS_DFLT;
_roadstop_gui_settings.roadstop_type = 0;
}
_roadstop_gui_settings.roadstop_count = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpecCount();
_roadstop_gui_settings.roadstop_type = std::min((int)_roadstop_gui_settings.roadstop_type, _roadstop_gui_settings.roadstop_count - 1);
/* Reset back to default class if the previously selected class is not available for this road stop type. */
if (!GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), roadStopType, _cur_roadtype)) {
_roadstop_gui_settings.roadstop_class = ROADSTOP_CLASS_DFLT;
}
this->SelectFirstAvailableTypeIfUnavailable();
NWidgetMatrix *matrix = this->GetWidget<NWidgetMatrix>(WID_BROS_MATRIX);
matrix->SetScrollbar(this->vscrollMatrix);
matrix->SetCount(_roadstop_gui_settings.roadstop_count);
matrix->SetClicked(_roadstop_gui_settings.roadstop_type);
this->EnsureSelectedClassIsVisible();
this->CheckOrientationValid();
}
}
void Close() override
@@ -1076,6 +1239,94 @@ struct BuildRoadStationWindow : public PickerWindowBase {
this->PickerWindowBase::Close();
}
/** Sort classes by RoadStopClassID. */
static bool RoadStopClassIDSorter(RoadStopClassID const &a, RoadStopClassID const &b)
{
return a < b;
}
/** Filter classes by class name. */
static bool CDECL TagNameFilter(RoadStopClassID const *sc, StringFilter &filter)
{
char buffer[DRAW_STRING_BUFFER];
GetString(buffer, RoadStopClass::Get(*sc)->name, lastof(buffer));
filter.ResetState();
filter.AddLine(buffer);
return filter.GetState();
}
inline bool ShowNewStops() const
{
return this->vscrollList != nullptr;
}
void BuildRoadStopClassesAvailable()
{
if (!this->roadstop_classes.NeedRebuild()) return;
this->roadstop_classes.clear();
for (uint i = 0; i < RoadStopClass::GetClassCount(); i++) {
RoadStopClassID rs_id = (RoadStopClassID)i;
if (rs_id == ROADSTOP_CLASS_WAYP) {
// Skip waypoints.
continue;
}
RoadStopClass *rs_class = RoadStopClass::Get(rs_id);
if (GetIfClassHasNewStopsByType(rs_class, this->roadStopType, _cur_roadtype)) this->roadstop_classes.push_back(rs_id);
}
if (this->ShowNewStops()) {
this->roadstop_classes.Filter(this->string_filter);
this->roadstop_classes.shrink_to_fit();
this->roadstop_classes.RebuildDone();
this->roadstop_classes.Sort();
this->vscrollList->SetCount((uint)this->roadstop_classes.size());
}
}
void SelectFirstAvailableTypeIfUnavailable()
{
const RoadStopClass *rs_class = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class);
StationType st = GetRoadStationTypeByWindowClass(this->window_class);
if (IsRoadStopAvailable(rs_class->GetSpec(_roadstop_gui_settings.roadstop_type), st)) return;
for (uint i = 0; i < _roadstop_gui_settings.roadstop_count; i++) {
if (IsRoadStopAvailable(rs_class->GetSpec(i), st)) {
_roadstop_gui_settings.roadstop_type = i;
break;
}
}
}
void OnInvalidateData(int data = 0, bool gui_scope = true) override
{
if (!gui_scope) return;
this->BuildRoadStopClassesAvailable();
}
EventState OnHotkey(int hotkey) override
{
if (hotkey == BROSHK_FOCUS_FILTER_BOX) {
this->SetFocusedWidget(WID_BROS_FILTER_EDITBOX);
SetFocusedWindow(this); // The user has asked to give focus to the text box, so make sure this window is focused.
return ES_HANDLED;
}
return ES_NOT_HANDLED;
}
void OnEditboxChanged(int wid) override
{
string_filter.SetFilterTerm(this->filter_editbox.text.buf);
this->roadstop_classes.SetFilterState(!string_filter.IsEmpty());
this->roadstop_classes.ForceRebuild();
this->InvalidateData();
}
void OnPaint() override
{
this->DrawWidgets();
@@ -1087,6 +1338,8 @@ struct BuildRoadStationWindow : public PickerWindowBase {
SetTileSelectSize(1, 1);
}
if (this->IsShaded()) return;
/* 'Accepts' and 'Supplies' texts. */
StationCoverageType sct = (this->window_class == WC_BUS_STATION) ? SCT_PASSENGERS_ONLY : SCT_NON_PASSENGERS_ONLY;
Rect r = this->GetWidget<NWidgetBase>(WID_BROS_ACCEPTANCE)->GetCurrentRect();
@@ -1097,45 +1350,175 @@ struct BuildRoadStationWindow : public PickerWindowBase {
* Never make the window smaller to avoid oscillating if the size change affects the acceptance.
* (This is the case, if making the window bigger moves the mouse into the window.) */
if (top > r.bottom) {
ResizeWindow(this, 0, top - r.bottom, false);
this->coverage_height += top - r.bottom;
this->ReInit();
}
}
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
{
if (!IsInsideMM(widget, WID_BROS_STATION_NE, WID_BROS_STATION_Y + 1)) return;
size->width = ScaleGUITrad(64) + WidgetDimensions::scaled.fullbevel.Horizontal();
size->height = ScaleGUITrad(48) + WidgetDimensions::scaled.fullbevel.Vertical();
}
void DrawWidget(const Rect &r, int widget) const override
{
if (!IsInsideMM(widget, WID_BROS_STATION_NE, WID_BROS_STATION_Y + 1)) return;
StationType st = (this->window_class == WC_BUS_STATION) ? STATION_BUS : STATION_TRUCK;
DrawPixelInfo tmp_dpi;
if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) {
AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31);
int y = (r.Height() + ScaleSpriteTrad(48)) / 2 - ScaleSpriteTrad(31);
StationPickerDrawSprite(x, y, st, INVALID_RAILTYPE, _cur_roadtype, widget - WID_BROS_STATION_NE);
}
}
void OnClick(Point pt, int widget, int click_count) override
{
switch (widget) {
case WID_BROS_NEWST_LIST: {
Dimension d = { 0, 0 };
for (auto rs_class : this->roadstop_classes) {
d = maxdim(d, GetStringBoundingBox(RoadStopClass::Get(rs_class)->name));
}
size->width = std::max(size->width, d.width + padding.width);
this->line_height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.matrix.Vertical();
size->height = 5 * this->line_height;
resize->height = this->line_height;
break;
}
case WID_BROS_SHOW_NEWST_TYPE: {
Dimension d = {0, 0};
StringID str = this->GetWidget<NWidgetCore>(widget)->widget_data;
for (auto roadstop_class : this->roadstop_classes) {
RoadStopClass *rs_class = RoadStopClass::Get(roadstop_class);
for (uint j = 0; j < rs_class->GetSpecCount(); j++) {
const RoadStopSpec *roadstopspec = rs_class->GetSpec(j);
SetDParam(0, (roadstopspec != nullptr && roadstopspec->name != 0) ? roadstopspec->name : STR_STATION_CLASS_DFLT);
d = maxdim(d, GetStringBoundingBox(str));
}
}
size->width = std::max(size->width, d.width + padding.width);
break;
}
case WID_BROS_STATION_NE:
case WID_BROS_STATION_SE:
case WID_BROS_STATION_SW:
case WID_BROS_STATION_NW:
case WID_BROS_STATION_X:
case WID_BROS_STATION_Y:
this->RaiseWidget(_road_station_picker_orientation + WID_BROS_STATION_NE);
_road_station_picker_orientation = (DiagDirection)(widget - WID_BROS_STATION_NE);
this->LowerWidget(_road_station_picker_orientation + WID_BROS_STATION_NE);
case WID_BROS_IMAGE:
size->width = ScaleGUITrad(64) + WidgetDimensions::scaled.fullbevel.Horizontal();
size->height = ScaleGUITrad(48) + WidgetDimensions::scaled.fullbevel.Vertical();
break;
case WID_BROS_MATRIX:
fill->height = 1;
resize->height = 1;
break;
case WID_BROS_ACCEPTANCE:
size->height = this->coverage_height;
break;
}
}
/**
* Simply to have a easier way to get the StationType for bus, truck and trams from the WindowClass.
*/
StationType GetRoadStationTypeByWindowClass(WindowClass window_class) const {
switch (window_class) {
case WC_BUS_STATION: return STATION_BUS;
case WC_TRUCK_STATION: return STATION_TRUCK;
default: NOT_REACHED();
}
}
void DrawWidget(const Rect &r, int widget) const override
{
switch (GB(widget, 0, 16)) {
case WID_BROS_STATION_NE:
case WID_BROS_STATION_SE:
case WID_BROS_STATION_SW:
case WID_BROS_STATION_NW:
case WID_BROS_STATION_X:
case WID_BROS_STATION_Y: {
StationType st = GetRoadStationTypeByWindowClass(this->window_class);
const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpec(_roadstop_gui_settings.roadstop_type);
bool disabled = (spec != nullptr && widget < WID_BROS_STATION_X && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY));
DrawPixelInfo tmp_dpi;
if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) {
AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31);
int y = (r.Height() + ScaleSpriteTrad(48)) / 2 - ScaleSpriteTrad(31);
if (spec == nullptr || disabled) {
StationPickerDrawSprite(x, y, st, INVALID_RAILTYPE, _cur_roadtype, widget - WID_BROS_STATION_NE);
if (disabled) GfxFillRect(1, 1, r.Width() - 1, r.Height() - 1, PC_BLACK, FILLRECT_CHECKER);
} else {
DrawRoadStopTile(x, y, _cur_roadtype, spec, st, widget - WID_BROS_STATION_NE);
}
}
break;
}
case WID_BROS_NEWST_LIST: {
uint statclass = 0;
uint row = 0;
for (auto rs_class : this->roadstop_classes) {
if (this->vscrollList->IsVisible(statclass)) {
DrawString(r.left + WidgetDimensions::scaled.matrix.left, r.right, row * this->line_height + r.top + WidgetDimensions::scaled.matrix.top,
RoadStopClass::Get(rs_class)->name,
rs_class == _roadstop_gui_settings.roadstop_class ? TC_WHITE : TC_BLACK);
row++;
}
statclass++;
}
break;
}
case WID_BROS_IMAGE: {
byte type = GB(widget, 16, 16);
assert(type < _roadstop_gui_settings.roadstop_count);
const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpec(type);
StationType st = GetRoadStationTypeByWindowClass(this->window_class);
if (!IsRoadStopAvailable(spec, st)) {
GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), PC_BLACK, FILLRECT_CHECKER);
}
/* Set up a clipping area for the sprite preview. */
DrawPixelInfo tmp_dpi;
if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) {
AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31);
int y = (r.Height() + ScaleSpriteTrad(48)) / 2 - ScaleSpriteTrad(31);
if (spec == nullptr) {
StationPickerDrawSprite(x, y, st, INVALID_RAILTYPE, _cur_roadtype, _roadstop_gui_settings.orientation);
} else {
DiagDirection orientation = _roadstop_gui_settings.orientation;
if (orientation < DIAGDIR_END && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)) orientation = DIAGDIR_END;
DrawRoadStopTile(x, y, _cur_roadtype, spec, st, (uint8)orientation);
}
}
break;
}
}
}
void OnResize() override {
if (this->vscrollList != nullptr) {
this->vscrollList->SetCapacityFromWidget(this, WID_BROS_NEWST_LIST);
}
}
void SetStringParameters(int widget) const override {
if (widget == WID_BROS_SHOW_NEWST_TYPE) {
const RoadStopSpec *roadstopspec = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpec(_roadstop_gui_settings.roadstop_type);
SetDParam(0, (roadstopspec != nullptr && roadstopspec->name != 0) ? roadstopspec->name : STR_STATION_CLASS_DFLT);
}
}
void OnClick(Point pt, int widget, int click_count) override
{
switch (GB(widget, 0, 16)) {
case WID_BROS_STATION_NE:
case WID_BROS_STATION_SE:
case WID_BROS_STATION_SW:
case WID_BROS_STATION_NW:
case WID_BROS_STATION_X:
case WID_BROS_STATION_Y:
if (widget < WID_BROS_STATION_X) {
const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpec(_roadstop_gui_settings.roadstop_type);
if (spec != nullptr && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)) return;
}
this->RaiseWidget(_roadstop_gui_settings.orientation + WID_BROS_STATION_NE);
_roadstop_gui_settings.orientation = (DiagDirection)(widget - WID_BROS_STATION_NE);
this->LowerWidget(_roadstop_gui_settings.orientation + WID_BROS_STATION_NE);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
this->SetDirty();
CloseWindowById(WC_SELECT_STATION, 0);
@@ -1151,6 +1534,48 @@ struct BuildRoadStationWindow : public PickerWindowBase {
SetViewportCatchmentStation(nullptr, true);
break;
case WID_BROS_NEWST_LIST: {
int y = this->vscrollList->GetScrolledRowFromWidget(pt.y, this, WID_BROS_NEWST_LIST);
if (y >= (int)this->roadstop_classes.size()) return;
RoadStopClassID class_id = this->roadstop_classes[y];
if (_roadstop_gui_settings.roadstop_class != class_id && GetIfClassHasNewStopsByType(RoadStopClass::Get(class_id), roadStopType, _cur_roadtype)) {
_roadstop_gui_settings.roadstop_class = class_id;
RoadStopClass *rsclass = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class);
_roadstop_gui_settings.roadstop_count = rsclass->GetSpecCount();
_roadstop_gui_settings.roadstop_type = std::min((int)_roadstop_gui_settings.roadstop_type, std::max(0, (int)_roadstop_gui_settings.roadstop_count - 1));
this->SelectFirstAvailableTypeIfUnavailable();
NWidgetMatrix *matrix = this->GetWidget<NWidgetMatrix>(WID_BROS_MATRIX);
matrix->SetCount(_roadstop_gui_settings.roadstop_count);
matrix->SetClicked(_roadstop_gui_settings.roadstop_type);
this->CheckOrientationValid();
}
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
this->SetDirty();
CloseWindowById(WC_SELECT_STATION, 0);
break;
}
case WID_BROS_IMAGE: {
int y = GB(widget, 16, 16);
if (y >= _roadstop_gui_settings.roadstop_count) return;
const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpec(y);
StationType st = GetRoadStationTypeByWindowClass(this->window_class);
if (!IsRoadStopAvailable(spec, st)) return;
_roadstop_gui_settings.roadstop_type = y;
this->GetWidget<NWidgetMatrix>(WID_BROS_MATRIX)->SetClicked(_roadstop_gui_settings.roadstop_type);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
this->SetDirty();
CloseWindowById(WC_SELECT_STATION, 0);
this->CheckOrientationValid();
break;
}
default:
break;
}
@@ -1160,6 +1585,25 @@ struct BuildRoadStationWindow : public PickerWindowBase {
{
CheckRedrawStationCoverage(this);
}
static HotkeyList hotkeys;
};
static Hotkey buildroadstop_hotkeys[] = {
Hotkey('F', "focus_filter_box", BROSHK_FOCUS_FILTER_BOX),
HOTKEY_LIST_END
};
HotkeyList BuildRoadStationWindow::hotkeys("buildroadstop", buildroadstop_hotkeys);
Listing BuildRoadStationWindow::last_sorting = { false, 0 };
Filtering BuildRoadStationWindow::last_filtering = { false, 0 };
BuildRoadStationWindow::GUIRoadStopClassList::SortFunction * const BuildRoadStationWindow::sorter_funcs[] = {
&RoadStopClassIDSorter,
};
BuildRoadStationWindow::GUIRoadStopClassList::FilterFunction * const BuildRoadStationWindow::filter_funcs[] = {
&TagNameFilter,
};
/** Widget definition of the build road station window */
@@ -1167,34 +1611,82 @@ static const NWidgetPart _nested_road_station_picker_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROS_CAPTION),
NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_DEFSIZE),
NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN),
EndContainer(),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BROS_BACKGROUND),
NWidget(NWID_HORIZONTAL), SetPadding(3),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(NWID_VERTICAL), SetPIP(0, 2, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NW), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NE), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(NWID_HORIZONTAL), SetPadding(2, 0, 0, 2),
NWidget(NWID_VERTICAL),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_FILTER_CONTAINER),
NWidget(NWID_HORIZONTAL), SetPadding(0, 5, 2, 0),
NWidget(WWT_TEXT, COLOUR_DARK_GREEN), SetFill(0, 1), SetDataTip(STR_LIST_FILTER_TITLE, STR_NULL),
NWidget(WWT_EDITBOX, COLOUR_GREY, WID_BROS_FILTER_EDITBOX), SetFill(1, 0), SetResize(1, 0),
SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SW), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SE), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_ADDITIONS),
NWidget(NWID_HORIZONTAL), SetPadding(0, 5, 2, 0),
NWidget(WWT_MATRIX, COLOUR_GREY, WID_BROS_NEWST_LIST), SetMinimalSize(122, 71), SetFill(1, 0),
SetMatrixDataTip(1, 0, STR_STATION_BUILD_STATION_CLASS_TOOLTIP), SetScrollbar(WID_BROS_NEWST_SCROLL),
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_BROS_NEWST_SCROLL),
EndContainer(),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_ORIENTATION),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_ORIENTATION, STR_NULL), SetPadding(4, 2, 1, 2), SetFill(1, 0),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPadding(3),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(NWID_VERTICAL), SetPIP(0, 2, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NW), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NE), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SW), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SE), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_TYPE_SEL),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_SHOW_NEWST_TYPE), SetMinimalSize(144, 8), SetDataTip(STR_ORANGE_STRING, STR_NULL), SetPadding(4, 2, 4, 2), SetFill(1, 0),
EndContainer(),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(WidgetDimensions::unscaled.framerect), SetFill(1, 0),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_OFF), SetMinimalSize(60, 12),
SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_ON), SetMinimalSize(60, 12),
SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
EndContainer(),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_MATRIX),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetScrollbar(WID_BROS_MATRIX_SCROLL),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, WID_BROS_MATRIX), SetScrollbar(WID_BROS_MATRIX_SCROLL), SetPIP(0, 2, 0),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BROS_IMAGE), SetMinimalSize(66, 60),
SetFill(0, 0), SetResize(0, 0), SetDataTip(0x0, STR_STATION_BUILD_STATION_TYPE_TOOLTIP), SetScrollbar(WID_BROS_MATRIX_SCROLL),
EndContainer(),
EndContainer(),
NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, WID_BROS_MATRIX_SCROLL),
EndContainer(),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_INFO), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0),
NWidget(NWID_HORIZONTAL), SetPadding(3),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_OFF), SetMinimalSize(60, 12),
SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_ON), SetMinimalSize(60, 12),
SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BROS_ACCEPTANCE), SetPadding(WidgetDimensions::unscaled.framerect), SetFill(1, 1), SetResize(1, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_RESIZE),
NWidget(NWID_VERTICAL),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(0, 1), EndContainer(),
NWidget(WWT_RESIZEBOX, COLOUR_DARK_GREEN),
EndContainer(),
EndContainer(),
EndContainer(),
NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_BROS_ACCEPTANCE), SetPadding(WidgetDimensions::unscaled.framerect), SetResize(0, 1),
EndContainer(),
};
@@ -1210,28 +1702,76 @@ static const NWidgetPart _nested_tram_station_picker_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROS_CAPTION),
NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_DEFSIZE),
NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN),
EndContainer(),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BROS_BACKGROUND),
NWidget(NWID_HORIZONTAL), SetPadding(3),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(NWID_VERTICAL), SetPIP(0, 2, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(NWID_HORIZONTAL), SetPadding(2, 0, 0, 2),
NWidget(NWID_VERTICAL),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_FILTER_CONTAINER),
NWidget(NWID_HORIZONTAL), SetPadding(0, 5, 2, 0),
NWidget(WWT_TEXT, COLOUR_DARK_GREEN), SetFill(0, 1), SetDataTip(STR_LIST_FILTER_TITLE, STR_NULL),
NWidget(WWT_EDITBOX, COLOUR_GREY, WID_BROS_FILTER_EDITBOX), SetFill(1, 0), SetResize(1, 0),
SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
EndContainer(),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_ADDITIONS),
NWidget(NWID_HORIZONTAL), SetPadding(0, 5, 2, 0),
NWidget(WWT_MATRIX, COLOUR_GREY, WID_BROS_NEWST_LIST), SetMinimalSize(122, 71), SetFill(1, 0),
SetMatrixDataTip(1, 0, STR_STATION_BUILD_STATION_CLASS_TOOLTIP), SetScrollbar(WID_BROS_NEWST_SCROLL),
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_BROS_NEWST_SCROLL),
EndContainer(),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_ORIENTATION),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_ORIENTATION, STR_NULL), SetPadding(4, 2, 1, 2), SetFill(1, 0),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPadding(3),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(NWID_VERTICAL), SetPIP(0, 2, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_TYPE_SEL),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_SHOW_NEWST_TYPE), SetMinimalSize(144, 8), SetDataTip(STR_ORANGE_STRING, STR_NULL), SetPadding(4, 2, 4, 2), SetFill(1, 0),
EndContainer(),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(WidgetDimensions::unscaled.framerect), SetFill(1, 0),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_OFF), SetMinimalSize(60, 12),
SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_ON), SetMinimalSize(60, 12),
SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
EndContainer(),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_MATRIX),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetScrollbar(WID_BROS_MATRIX_SCROLL),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, WID_BROS_MATRIX), SetScrollbar(WID_BROS_MATRIX_SCROLL), SetPIP(0, 2, 0), SetPadding(2, 0, 0, 0),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BROS_IMAGE), SetMinimalSize(66, 60),
SetFill(0, 0), SetResize(0, 0), SetDataTip(0x0, STR_STATION_BUILD_STATION_TYPE_TOOLTIP), SetScrollbar(WID_BROS_MATRIX_SCROLL),
EndContainer(),
EndContainer(),
NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, WID_BROS_MATRIX_SCROLL),
EndContainer(),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_INFO), SetPadding(WidgetDimensions::unscaled.framerect), SetMinimalSize(140, 14), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0),
NWidget(NWID_HORIZONTAL), SetPadding(3),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_OFF), SetMinimalSize(60, 12),
SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_ON), SetMinimalSize(60, 12),
SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BROS_ACCEPTANCE), SetPadding(WidgetDimensions::unscaled.framerect), SetFill(1, 1), SetResize(1, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_RESIZE),
NWidget(NWID_VERTICAL),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(0, 1), EndContainer(),
NWidget(WWT_RESIZEBOX, COLOUR_DARK_GREEN),
EndContainer(),
EndContainer(),
EndContainer(),
NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_BROS_ACCEPTANCE), SetPadding(WidgetDimensions::unscaled.framerect), SetResize(0, 1),
EndContainer(),
};
@@ -1250,7 +1790,7 @@ static void ShowRVStationPicker(Window *parent, RoadStopType rs)
void InitializeRoadGui()
{
_road_depot_orientation = DIAGDIR_NW;
_road_station_picker_orientation = DIAGDIR_NW;
_roadstop_gui_settings.orientation = DIAGDIR_NW;
}
/**