1
0
mirror of https://github.com/OpenTTD/OpenTTD synced 2026-01-19 02:12:37 +01:00

Change: Unify station/waypoint/roadstop/object build-picker window code.

These windows now share a common code base for choosing and display class and types.

An additional text filter is added to search types by name instead of just classes.
This commit is contained in:
Peter Nelson
2024-05-07 12:13:48 +01:00
committed by Peter Nelson
parent d2c8b476b5
commit cdc356e7bf
16 changed files with 1261 additions and 1691 deletions

View File

@@ -36,10 +36,7 @@
#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 "picker_gui.h"
#include "timer/timer.h"
#include "timer/timer_game_calendar.h"
@@ -64,40 +61,43 @@ static RoadType _cur_roadtype;
static DiagDirection _road_depot_orientation;
struct RoadStopGUISettings {
DiagDirection orientation;
RoadStopClassID roadstop_class;
uint16_t roadstop_type;
uint16_t roadstop_count;
struct RoadStopPickerSelection {
RoadStopClassID sel_class; ///< Selected road stop class.
uint16_t sel_type; ///< Selected road stop type within the class.
DiagDirection orientation; ///< Selected orientation of the road stop.
};
static RoadStopGUISettings _roadstop_gui_settings;
static RoadStopPickerSelection _roadstop_gui;
static bool IsRoadStopEverAvailable(const RoadStopSpec *spec, StationType type)
{
if (spec == nullptr) return true;
if (HasBit(spec->flags, RSF_BUILD_MENU_ROAD_ONLY) && !RoadTypeIsRoad(_cur_roadtype)) return false;
if (HasBit(spec->flags, RSF_BUILD_MENU_TRAM_ONLY) && !RoadTypeIsTram(_cur_roadtype)) return false;
switch (spec->stop_type) {
case ROADSTOPTYPE_ALL: return true;
case ROADSTOPTYPE_PASSENGER: return type == STATION_BUS;
case ROADSTOPTYPE_FREIGHT: return type == STATION_TRUCK;
default: NOT_REACHED();
}
}
/**
* Check whether a road stop type can be built.
* @return true if building is allowed.
*/
static bool IsRoadStopAvailable(const RoadStopSpec *roadstopspec, StationType type)
static bool IsRoadStopAvailable(const RoadStopSpec *spec, StationType type)
{
if (roadstopspec == nullptr) return true;
if (spec == nullptr) return true;
if (IsRoadStopEverAvailable(spec, type)) 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 (!HasBit(spec->callback_mask, CBM_ROAD_STOP_AVAIL)) return true;
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_t cb_res = GetRoadStopCallback(CBID_STATION_AVAILABILITY, 0, 0, roadstopspec, nullptr, INVALID_TILE, _cur_roadtype, type, 0);
uint16_t cb_res = GetRoadStopCallback(CBID_STATION_AVAILABILITY, 0, 0, spec, 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);
return Convert8bitBooleanCallback(spec->grf_prop.grffile, CBID_STATION_AVAILABILITY, cb_res);
}
void CcPlaySound_CONSTRUCTION_OTHER(Commands, const CommandCost &result, TileIndex tile)
@@ -217,11 +217,11 @@ void CcRoadStop(Commands, const CommandCost &result, TileIndex tile, uint8_t wid
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 = _roadstop_gui_settings.orientation;
DiagDirection ddir = _roadstop_gui.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;
uint16_t spec_index = _roadstop_gui_settings.roadstop_type;
RoadStopClassID spec_class = _roadstop_gui.sel_class;
uint16_t spec_index = _roadstop_gui.sel_type;
auto proc = [=](bool test, StationID to_join) -> bool {
if (test) {
@@ -245,8 +245,8 @@ static void PlaceRoad_BusStation(TileIndex tile)
if (_remove_button_clicked) {
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_REMOVE_BUSSTOP);
} else {
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);
if (_roadstop_gui.orientation < DIAGDIR_END) { // Not a drive-through stop.
VpStartPlaceSizing(tile, (DiagDirToAxis(_roadstop_gui.orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_BUSSTOP);
} else {
VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_BUSSTOP);
}
@@ -263,8 +263,8 @@ static void PlaceRoad_TruckStation(TileIndex tile)
if (_remove_button_clicked) {
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_REMOVE_TRUCKSTOP);
} else {
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);
if (_roadstop_gui.orientation < DIAGDIR_END) { // Not a drive-through stop.
VpStartPlaceSizing(tile, (DiagDirToAxis(_roadstop_gui.orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_TRUCKSTOP);
} else {
VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_TRUCKSTOP);
}
@@ -708,7 +708,7 @@ struct BuildRoadToolbarWindow : Window {
case DDSP_BUILD_BUSSTOP:
case DDSP_REMOVE_BUSSTOP:
if (this->IsWidgetLowered(WID_ROT_BUS_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), ROADSTOP_BUS, _cur_roadtype)) {
if (this->IsWidgetLowered(WID_ROT_BUS_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui.sel_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);
@@ -720,7 +720,7 @@ struct BuildRoadToolbarWindow : Window {
case DDSP_BUILD_TRUCKSTOP:
case DDSP_REMOVE_TRUCKSTOP:
if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), ROADSTOP_TRUCK, _cur_roadtype)) {
if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui.sel_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);
@@ -1093,101 +1093,126 @@ 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
template <RoadStopType roadstoptype>
class RoadStopPickerCallbacks : public PickerCallbacksNewGRFClass<RoadStopClass> {
public:
StringID GetClassTooltip() const override;
StringID GetTypeTooltip() const override;
bool IsActive() const override
{
for (const auto &cls : RoadStopClass::Classes()) {
if (IsWaypointClass(cls)) continue;
for (const auto *spec : cls.Specs()) {
if (spec == nullptr) continue;
if (roadstoptype == ROADSTOP_TRUCK && spec->stop_type != ROADSTOPTYPE_FREIGHT && spec->stop_type != ROADSTOPTYPE_ALL) continue;
if (roadstoptype == ROADSTOP_BUS && spec->stop_type != ROADSTOPTYPE_PASSENGER && spec->stop_type != ROADSTOPTYPE_ALL) continue;
return true;
}
}
return false;
}
static bool IsClassChoice(const RoadStopClass &cls)
{
return !IsWaypointClass(cls) && GetIfClassHasNewStopsByType(&cls, roadstoptype, _cur_roadtype);
}
bool HasClassChoice() const override
{
return std::count_if(std::begin(RoadStopClass::Classes()), std::end(RoadStopClass::Classes()), IsClassChoice);
}
int GetSelectedClass() const override { return _roadstop_gui.sel_class; }
void SetSelectedClass(int id) const override { _roadstop_gui.sel_class = this->GetClassIndex(id); }
StringID GetClassName(int id) const override
{
const auto *rsc = this->GetClass(id);
if (!IsClassChoice(*rsc)) return INVALID_STRING_ID;
return rsc->name;
}
int GetSelectedType() const override { return _roadstop_gui.sel_type; }
void SetSelectedType(int id) const override { _roadstop_gui.sel_type = id; }
StringID GetTypeName(int cls_id, int id) const override
{
const auto *spec = this->GetSpec(cls_id, id);
if (!IsRoadStopEverAvailable(spec, roadstoptype == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK)) return INVALID_STRING_ID;
return (spec == nullptr) ? STR_STATION_CLASS_DFLT_ROADSTOP : spec->name;
}
bool IsTypeAvailable(int cls_id, int id) const override
{
const auto *spec = this->GetSpec(cls_id, id);
return IsRoadStopAvailable(spec, roadstoptype == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK);
}
void DrawType(int x, int y, int cls_id, int id) const override
{
const auto *spec = this->GetSpec(cls_id, id);
if (spec == nullptr) {
StationPickerDrawSprite(x, y, roadstoptype == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK, INVALID_RAILTYPE, _cur_roadtype, _roadstop_gui.orientation);
} else {
DiagDirection orientation = _roadstop_gui.orientation;
if (orientation < DIAGDIR_END && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)) orientation = DIAGDIR_END;
DrawRoadStopTile(x, y, _cur_roadtype, spec, roadstoptype == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK, (uint8_t)orientation);
}
}
};
struct BuildRoadStationWindow : public PickerWindowBase {
template <> StringID RoadStopPickerCallbacks<ROADSTOP_BUS>::GetClassTooltip() const { return STR_PICKER_ROADSTOP_BUS_CLASS_TOOLTIP; }
template <> StringID RoadStopPickerCallbacks<ROADSTOP_BUS>::GetTypeTooltip() const { return STR_PICKER_ROADSTOP_BUS_TYPE_TOOLTIP; }
template <> StringID RoadStopPickerCallbacks<ROADSTOP_TRUCK>::GetClassTooltip() const { return STR_PICKER_ROADSTOP_TRUCK_CLASS_TOOLTIP; }
template <> StringID RoadStopPickerCallbacks<ROADSTOP_TRUCK>::GetTypeTooltip() const { return STR_PICKER_ROADSTOP_TRUCK_TYPE_TOOLTIP; }
static RoadStopPickerCallbacks<ROADSTOP_BUS> _bus_callback_instance;
static RoadStopPickerCallbacks<ROADSTOP_TRUCK> _truck_callback_instance;
static PickerCallbacks &GetRoadStopPickerCallbacks(RoadStopType rs)
{
return rs == ROADSTOP_BUS ? static_cast<PickerCallbacks &>(_bus_callback_instance) : static_cast<PickerCallbacks &>(_truck_callback_instance);
}
struct BuildRoadStationWindow : public PickerWindow {
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, std::nullptr_t, 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 const std::initializer_list<GUIRoadStopClassList::SortFunction * const> sorter_funcs; ///< Sort functions of the #GUIRoadStopClassList.
static const std::initializer_list<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(this->roadstop_classes.size());
this->vscrollList->ScrollTowards(pos);
}
void CheckOrientationValid()
{
const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpec(_roadstop_gui_settings.roadstop_type);
const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui.sel_class)->GetSpec(_roadstop_gui.sel_type);
/* Raise and lower to ensure the correct widget is lowered after changing displayed orientation plane. */
if (RoadTypeIsRoad(_cur_roadtype)) {
this->RaiseWidget(WID_BROS_STATION_NE + _roadstop_gui_settings.orientation);
this->RaiseWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
this->GetWidget<NWidgetStacked>(WID_BROS_AVAILABLE_ORIENTATIONS)->SetDisplayedPlane((spec != nullptr && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)) ? 1 : 0);
this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui_settings.orientation);
this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
}
if (_roadstop_gui_settings.orientation >= DIAGDIR_END) return;
if (_roadstop_gui.orientation >= DIAGDIR_END) return;
if (spec != nullptr && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)) {
this->RaiseWidget(WID_BROS_STATION_NE + _roadstop_gui_settings.orientation);
_roadstop_gui_settings.orientation = DIAGDIR_END;
this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui_settings.orientation);
this->RaiseWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
_roadstop_gui.orientation = DIAGDIR_END;
this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
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)
BuildRoadStationWindow(WindowDesc *desc, Window *parent, RoadStopType rs) : PickerWindow(desc, parent, TRANSPORT_ROAD, GetRoadStopPickerCallbacks(rs))
{
this->coverage_height = 2 * GetCharacterHeight(FS_NORMAL) + 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) && _roadstop_gui_settings.orientation < DIAGDIR_END) {
_roadstop_gui_settings.orientation = DIAGDIR_END;
if (RoadTypeIsTram(_cur_roadtype) && _roadstop_gui.orientation < DIAGDIR_END) {
_roadstop_gui.orientation = DIAGDIR_END;
}
this->ConstructWindow();
const RoadTypeInfo *rti = GetRoadTypeInfo(_cur_roadtype);
this->GetWidget<NWidgetCore>(WID_BROS_CAPTION)->widget_data = rti->strings.picker_title[rs];
@@ -1195,130 +1220,24 @@ public:
this->GetWidget<NWidgetCore>(i)->tool_tip = rti->strings.picker_tooltip[rs];
}
this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui_settings.orientation);
this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
this->LowerWidget(WID_BROS_LT_OFF + _settings_client.gui.station_show_coverage);
this->FinishInitNested(TRANSPORT_ROAD);
this->window_class = (rs == ROADSTOP_BUS) ? WC_BUS_STATION : WC_TRUCK_STATION;
if (!newstops || _roadstop_gui_settings.roadstop_class >= 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([[maybe_unused]] int data = 0) override
{
CloseWindowById(WC_SELECT_STATION, 0);
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 TagNameFilter(RoadStopClassID const *sc, StringFilter &filter)
{
filter.ResetState();
filter.AddLine(GetString(RoadStopClass::Get(*sc)->name));
return filter.GetState();
}
inline bool ShowNewStops() const
{
return this->vscrollList != nullptr;
}
void BuildRoadStopClassesAvailable()
{
if (!this->roadstop_classes.NeedRebuild()) return;
this->roadstop_classes.clear();
this->roadstop_classes.reserve(RoadStopClass::GetClassCount());
for (const auto &cls : RoadStopClass::Classes()) {
/* Skip waypoints. */
if (IsWaypointClass(cls)) continue;
if (GetIfClassHasNewStopsByType(&cls, this->roadStopType, _cur_roadtype)) this->roadstop_classes.push_back(cls.Index());
}
if (this->ShowNewStops()) {
this->roadstop_classes.Filter(this->string_filter);
this->roadstop_classes.RebuildDone();
this->roadstop_classes.Sort();
this->vscrollList->SetCount(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;
}
}
this->PickerWindow::Close();
}
void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
{
if (!gui_scope) return;
this->PickerWindow::OnInvalidateData(data, gui_scope);
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(WidgetID widget) override
{
if (widget == WID_BROS_FILTER_EDITBOX) {
string_filter.SetFilterTerm(this->filter_editbox.text.buf);
this->roadstop_classes.SetFilterState(!string_filter.IsEmpty());
this->roadstop_classes.ForceRebuild();
this->InvalidateData();
if (gui_scope) {
this->CheckOrientationValid();
}
}
@@ -1353,52 +1272,23 @@ public:
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) 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 = GetCharacterHeight(FS_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_ROADSTOP);
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:
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;
size.width = ScaleGUITrad(PREVIEW_WIDTH) + WidgetDimensions::scaled.fullbevel.Horizontal();
size.height = ScaleGUITrad(PREVIEW_HEIGHT) + WidgetDimensions::scaled.fullbevel.Vertical();
break;
case WID_BROS_ACCEPTANCE:
size.height = this->coverage_height;
break;
default:
this->PickerWindow::UpdateWidgetSize(widget, size, padding, fill, resize);
break;
}
}
@@ -1424,13 +1314,13 @@ public:
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);
const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui.sel_class)->GetSpec(_roadstop_gui.sel_type);
DrawPixelInfo tmp_dpi;
Rect ir = r.Shrink(WidgetDimensions::scaled.bevel);
if (FillDrawPixelInfo(&tmp_dpi, ir)) {
AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
int x = (ir.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31);
int y = (ir.Height() + ScaleSpriteTrad(48)) / 2 - ScaleSpriteTrad(31);
int x = (ir.Width() - ScaleSpriteTrad(PREVIEW_WIDTH)) / 2 + ScaleSpriteTrad(PREVIEW_LEFT);
int y = (ir.Height() + ScaleSpriteTrad(PREVIEW_HEIGHT)) / 2 - ScaleSpriteTrad(PREVIEW_BOTTOM);
if (spec == nullptr) {
StationPickerDrawSprite(x, y, st, INVALID_RAILTYPE, _cur_roadtype, widget - WID_BROS_STATION_NE);
} else {
@@ -1440,63 +1330,9 @@ public:
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++;
}
default:
this->PickerWindow::DrawWidget(r, widget);
break;
}
case WID_BROS_IMAGE: {
uint16_t type = this->GetWidget<NWidgetBase>(widget)->GetParentWidget<NWidgetMatrix>()->GetCurrentElement();
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);
/* Set up a clipping area for the sprite preview. */
DrawPixelInfo tmp_dpi;
Rect ir = r.Shrink(WidgetDimensions::scaled.bevel);
if (FillDrawPixelInfo(&tmp_dpi, ir)) {
AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
int x = (ir.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31);
int y = (ir.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_t)orientation);
}
}
if (!IsRoadStopAvailable(spec, st)) {
GfxFillRect(ir, PC_BLACK, FILLRECT_CHECKER);
}
break;
}
}
}
void OnResize() override
{
if (this->vscrollList != nullptr) {
this->vscrollList->SetCapacityFromWidget(this, WID_BROS_NEWST_LIST);
}
}
void SetStringParameters(WidgetID 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_ROADSTOP);
}
}
@@ -1510,12 +1346,12 @@ public:
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);
const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui.sel_class)->GetSpec(_roadstop_gui.sel_type);
if (spec != nullptr && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)) return;
}
this->RaiseWidget(WID_BROS_STATION_NE + _roadstop_gui_settings.orientation);
_roadstop_gui_settings.orientation = (DiagDirection)(widget - WID_BROS_STATION_NE);
this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui_settings.orientation);
this->RaiseWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
_roadstop_gui.orientation = (DiagDirection)(widget - WID_BROS_STATION_NE);
this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
this->SetDirty();
CloseWindowById(WC_SELECT_STATION, 0);
@@ -1531,49 +1367,8 @@ public:
SetViewportCatchmentStation(nullptr, true);
break;
case WID_BROS_NEWST_LIST: {
auto it = this->vscrollList->GetScrolledItemFromWidget(this->roadstop_classes, pt.y, this, WID_BROS_NEWST_LIST);
if (it == this->roadstop_classes.end()) return;
RoadStopClassID class_id = *it;
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);
}
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
this->SetDirty();
CloseWindowById(WC_SELECT_STATION, 0);
this->CheckOrientationValid();
break;
}
case WID_BROS_IMAGE: {
uint16_t y = this->GetWidget<NWidgetBase>(widget)->GetParentWidget<NWidgetMatrix>()->GetCurrentElement();
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<NWidgetBase>(widget)->GetParentWidget<NWidgetMatrix>()->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:
this->PickerWindow::OnClick(pt, widget, click_count);
break;
}
}
@@ -1583,119 +1378,66 @@ public:
CheckRedrawStationCoverage(this);
}
IntervalTimer<TimerGameCalendar> yearly_interval = {{TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [this](auto) {
this->InvalidateData();
}};
static inline HotkeyList road_hotkeys{"buildroadstop", {
Hotkey('F', "focus_filter_box", BROSHK_FOCUS_FILTER_BOX),
Hotkey('F', "focus_filter_box", PCWHK_FOCUS_FILTER_BOX),
}};
static inline HotkeyList tram_hotkeys{"buildtramstop", {
Hotkey('F', "focus_filter_box", BROSHK_FOCUS_FILTER_BOX),
Hotkey('F', "focus_filter_box", PCWHK_FOCUS_FILTER_BOX),
}};
};
Listing BuildRoadStationWindow::last_sorting = { false, 0 };
Filtering BuildRoadStationWindow::last_filtering = { false, 0 };
const std::initializer_list<BuildRoadStationWindow::GUIRoadStopClassList::SortFunction * const> BuildRoadStationWindow::sorter_funcs = {
&RoadStopClassIDSorter,
};
const std::initializer_list<BuildRoadStationWindow::GUIRoadStopClassList::FilterFunction * const> BuildRoadStationWindow::filter_funcs = {
&TagNameFilter,
};
/** Widget definition of the build road station window */
static constexpr 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(),
NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0), SetPadding(WidgetDimensions::unscaled.picker),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 1),
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_picker, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_FILTER_CONTAINER),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 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),
NWidget(NWID_VERTICAL),
NWidgetFunction(MakePickerClassWidgets),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_picker, 0), SetPadding(WidgetDimensions::unscaled.picker),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_AVAILABLE_ORIENTATIONS),
/* 6-orientation plane. */
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 1),
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NW), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NE), SetFill(0, 0), EndContainer(),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetFill(0, 0), EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 1),
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SW), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SE), SetFill(0, 0), EndContainer(),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetFill(0, 0), EndContainer(),
EndContainer(),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_ADDITIONS),
NWidget(NWID_HORIZONTAL),
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), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_AVAILABLE_ORIENTATIONS),
/* 6-orientation plane. */
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 1),
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NW), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NE), SetFill(0, 0), EndContainer(),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetFill(0, 0), EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 1),
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SW), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SE), SetFill(0, 0), EndContainer(),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetFill(0, 0), EndContainer(),
EndContainer(),
EndContainer(),
/* 2-orientation plane. */
NWidget(NWID_VERTICAL), SetPIPRatio(0, 0, 1),
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 1),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetFill(0, 0), EndContainer(),
EndContainer(),
EndContainer(),
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_JUST_STRING, STR_NULL), SetTextStyle(TC_ORANGE), SetFill(1, 0),
EndContainer(),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0),
NWidget(NWID_HORIZONTAL), SetPIPRatio(1, 0, 1),
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),
EndContainer(),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_MATRIX),
/* Hidden panel as NWID_MATRIX does not support SetScrollbar() */
NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetScrollbar(WID_BROS_MATRIX_SCROLL),
NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, WID_BROS_MATRIX), SetPIP(0, 2, 0),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BROS_IMAGE),
SetFill(0, 0), SetResize(0, 0), SetDataTip(0x0, STR_STATION_BUILD_STATION_TYPE_TOOLTIP), SetScrollbar(WID_BROS_MATRIX_SCROLL),
EndContainer(),
/* 2-orientation plane. */
NWidget(NWID_VERTICAL), SetPIPRatio(0, 0, 1),
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 1),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetFill(0, 0), EndContainer(),
EndContainer(),
EndContainer(),
EndContainer(),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0),
NWidget(NWID_HORIZONTAL), SetPIPRatio(1, 0, 1),
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),
EndContainer(),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BROS_ACCEPTANCE), SetFill(1, 1), SetResize(1, 0), SetMinimalTextLines(2, 0),
EndContainer(),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BROS_ACCEPTANCE), SetFill(1, 1), SetResize(1, 0), SetMinimalTextLines(2, WidgetDimensions::unscaled.vsep_normal),
EndContainer(),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_RESIZE),
NWidget(NWID_VERTICAL),
NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, WID_BROS_MATRIX_SCROLL),
NWidget(WWT_RESIZEBOX, COLOUR_DARK_GREEN),
EndContainer(),
EndContainer(),
NWidgetFunction(MakePickerTypeWidgets),
EndContainer(),
};
@@ -1713,67 +1455,29 @@ static constexpr NWidgetPart _nested_tram_station_picker_widgets[] = {
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(),
NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0), SetPadding(WidgetDimensions::unscaled.picker),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 1),
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_picker, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_FILTER_CONTAINER),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 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),
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), SetFill(1, 0),
EndContainer(),
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 1),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetFill(0, 0), EndContainer(),
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_JUST_STRING, STR_NULL), SetTextStyle(TC_ORANGE), SetFill(1, 0),
EndContainer(),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0),
NWidget(NWID_HORIZONTAL), SetPIPRatio(1, 0, 1),
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),
EndContainer(),
NWidget(NWID_VERTICAL),
NWidgetFunction(MakePickerClassWidgets),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_picker, 0), SetPadding(WidgetDimensions::unscaled.picker),
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 1),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetFill(0, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetFill(0, 0), EndContainer(),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_MATRIX),
/* Hidden panel as NWID_MATRIX does not support SetScrollbar() */
NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetScrollbar(WID_BROS_MATRIX_SCROLL),
NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, WID_BROS_MATRIX), SetPIP(0, 2, 0),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BROS_IMAGE),
SetFill(0, 0), SetResize(0, 0), SetDataTip(0x0, STR_STATION_BUILD_STATION_TYPE_TOOLTIP), SetScrollbar(WID_BROS_MATRIX_SCROLL),
EndContainer(),
EndContainer(),
EndContainer(),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0),
NWidget(NWID_HORIZONTAL), SetPIPRatio(1, 0, 1),
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),
EndContainer(),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BROS_ACCEPTANCE), SetFill(1, 1), SetResize(1, 0), SetMinimalTextLines(2, 0),
EndContainer(),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BROS_ACCEPTANCE), SetFill(1, 1), SetResize(1, 0), SetMinimalTextLines(2, WidgetDimensions::unscaled.vsep_normal),
EndContainer(),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_RESIZE),
NWidget(NWID_VERTICAL),
NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, WID_BROS_MATRIX_SCROLL),
NWidget(WWT_RESIZEBOX, COLOUR_DARK_GREEN),
EndContainer(),
EndContainer(),
NWidgetFunction(MakePickerTypeWidgets),
EndContainer(),
};
@@ -1793,7 +1497,7 @@ static void ShowRVStationPicker(Window *parent, RoadStopType rs)
void InitializeRoadGui()
{
_road_depot_orientation = DIAGDIR_NW;
_roadstop_gui_settings.orientation = DIAGDIR_NW;
_roadstop_gui.orientation = DIAGDIR_NW;
}
/**