diff --git a/projects/openttd_vs100.vcxproj b/projects/openttd_vs100.vcxproj index 200502ef78..5aa70d072a 100644 --- a/projects/openttd_vs100.vcxproj +++ b/projects/openttd_vs100.vcxproj @@ -293,12 +293,10 @@ - - diff --git a/projects/openttd_vs100.vcxproj.filters b/projects/openttd_vs100.vcxproj.filters index 6423835e82..552d9e92c7 100644 --- a/projects/openttd_vs100.vcxproj.filters +++ b/projects/openttd_vs100.vcxproj.filters @@ -108,9 +108,6 @@ Source Files - - Source Files - Source Files @@ -123,9 +120,6 @@ Source Files - - Source Files - Source Files diff --git a/projects/openttd_vs140.vcxproj b/projects/openttd_vs140.vcxproj index e55d31ae85..fdce86459d 100644 --- a/projects/openttd_vs140.vcxproj +++ b/projects/openttd_vs140.vcxproj @@ -310,12 +310,10 @@ - - diff --git a/projects/openttd_vs140.vcxproj.filters b/projects/openttd_vs140.vcxproj.filters index 6423835e82..552d9e92c7 100644 --- a/projects/openttd_vs140.vcxproj.filters +++ b/projects/openttd_vs140.vcxproj.filters @@ -108,9 +108,6 @@ Source Files - - Source Files - Source Files @@ -123,9 +120,6 @@ Source Files - - Source Files - Source Files diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj index dd33150fb5..0ac64562b8 100644 --- a/projects/openttd_vs80.vcproj +++ b/projects/openttd_vs80.vcproj @@ -442,10 +442,6 @@ RelativePath=".\..\src\tbtr_template_gui_create.cpp" > - - @@ -462,10 +458,6 @@ RelativePath=".\..\src\tbtr_template_gui_create.h" > - - diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj index 36e02cb215..9d879d603e 100644 --- a/projects/openttd_vs90.vcproj +++ b/projects/openttd_vs90.vcproj @@ -439,10 +439,6 @@ RelativePath=".\..\src\tbtr_template_gui_create.cpp" > - - @@ -459,10 +455,6 @@ RelativePath=".\..\src\tbtr_template_gui_create.h" > - - diff --git a/source.list b/source.list index cdf5ab80d3..1c5d0085a4 100644 --- a/source.list +++ b/source.list @@ -1,12 +1,10 @@ # Source Files tbtr_template_gui_main.cpp tbtr_template_gui_create.cpp -tbtr_template_gui_create_virtualtrain.cpp tbtr_template_vehicle.cpp tbtr_template_vehicle_func.cpp tbtr_template_gui_main.h tbtr_template_gui_create.h -tbtr_template_gui_create_virtualtrain.h tbtr_template_vehicle.h tbtr_template_vehicle_func.h diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index bd4bf3b59b..d41b1345d7 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -32,6 +32,7 @@ #include "cargotype.h" #include "core/geometry_func.hpp" #include "autoreplace_func.h" +#include "train.h" #include "widgets/build_vehicle_widget.h" @@ -974,11 +975,16 @@ struct BuildVehicleWindow : Window { byte cargo_filter_criteria; ///< Selected cargo filter int details_height; ///< Minimal needed height of the details panels (found so far). Scrollbar *vscroll; + bool virtual_train_mode; ///< Are we building a virtual train? + Train **virtual_train_out; ///< Virtual train ptr - BuildVehicleWindow(WindowDesc *desc, TileIndex tile, VehicleType type) : Window(desc) + BuildVehicleWindow(WindowDesc *desc, TileIndex tile, VehicleType type, Train **virtual_train_out) : Window(desc) { this->vehicle_type = type; this->window_number = tile == INVALID_TILE ? (int)type : tile; + this->virtual_train_out = virtual_train_out; + this->virtual_train_mode = (virtual_train_out != NULL); + if (this->virtual_train_mode) this->window_number = 0; this->sel_engine = INVALID_ENGINE; @@ -998,7 +1004,7 @@ struct BuildVehicleWindow : Window { break; } - this->listview_mode = (this->window_number <= VEH_END); + this->listview_mode = !(this->virtual_train_mode) && (this->window_number <= VEH_END); this->CreateNestedTree(); @@ -1018,8 +1024,13 @@ struct BuildVehicleWindow : Window { widget->tool_tip = STR_BUY_VEHICLE_TRAIN_HIDE_SHOW_TOGGLE_TOOLTIP + type; widget = this->GetWidget(WID_BV_BUILD); - widget->widget_data = STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON + type; - widget->tool_tip = STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP + type; + if (this->virtual_train_mode) { + widget->widget_data = STR_TMPL_CONFIRM; + widget->tool_tip = STR_TMPL_CONFIRM; + } else { + widget->widget_data = STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON + type; + widget->tool_tip = STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP + type; + } widget = this->GetWidget(WID_BV_RENAME); widget->widget_data = STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON + type; @@ -1032,7 +1043,7 @@ struct BuildVehicleWindow : Window { this->details_height = ((this->vehicle_type == VEH_TRAIN) ? 10 : 9) * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; - this->FinishInitNested(tile == INVALID_TILE ? (int)type : tile); + this->FinishInitNested(this->window_number); this->owner = (tile != INVALID_TILE) ? GetTileOwner(tile) : _local_company; @@ -1116,7 +1127,7 @@ struct BuildVehicleWindow : Window { int num_engines = 0; int num_wagons = 0; - this->filter.railtype = (this->listview_mode) ? RAILTYPE_END : GetRailType(this->window_number); + this->filter.railtype = (this->listview_mode || this->virtual_train_mode) ? RAILTYPE_END : GetRailType(this->window_number); this->eng_list.Clear(); @@ -1308,8 +1319,13 @@ struct BuildVehicleWindow : Window { case WID_BV_BUILD: { EngineID sel_eng = this->sel_engine; if (sel_eng != INVALID_ENGINE) { - CommandCallback *callback = (this->vehicle_type == VEH_TRAIN && RailVehInfo(sel_eng)->railveh_type == RAILVEH_WAGON) ? CcBuildWagon : CcBuildPrimaryVehicle; - DoCommandP(this->window_number, sel_eng, 0, GetCmdBuildVeh(this->vehicle_type), callback); + if (this->virtual_train_mode) { + DoCommandP(0, sel_eng, 0, CMD_BUILD_VIRTUAL_RAIL_VEHICLE, CcAddVirtualEngine); + } else { + CommandCallback *callback = (this->vehicle_type == VEH_TRAIN && RailVehInfo(sel_eng)->railveh_type == RAILVEH_WAGON) + ? CcBuildWagon : CcBuildPrimaryVehicle; + DoCommandP(this->window_number, sel_eng, 0, GetCmdBuildVeh(this->vehicle_type), callback); + } } break; } @@ -1348,7 +1364,7 @@ struct BuildVehicleWindow : Window { { switch (widget) { case WID_BV_CAPTION: - if (this->vehicle_type == VEH_TRAIN && !this->listview_mode) { + if (this->vehicle_type == VEH_TRAIN && !this->listview_mode && !this->virtual_train_mode) { const RailtypeInfo *rti = GetRailTypeInfo(this->filter.railtype); SetDParam(0, rti->strings.build_caption); } else { @@ -1481,8 +1497,34 @@ struct BuildVehicleWindow : Window { { this->vscroll->SetCapacityFromWidget(this, WID_BV_LIST); } + + void AddVirtualEngine(Train *toadd) + { + if (this->virtual_train_out == NULL) return; + + if (*(this->virtual_train_out) == NULL) { + *(this->virtual_train_out) = toadd; + } else { + VehicleID target = (*(this->virtual_train_out))->GetLastUnit()->index; + + DoCommandP(0, (1 << 21) | toadd->index, target, CMD_MOVE_RAIL_VEHICLE); + } + InvalidateWindowClassesData(WC_CREATE_TEMPLATE); + InvalidateWindowClassesData(WC_TEMPLATEGUI_MAIN); + } }; +void CcAddVirtualEngine(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +{ + if (result.Failed()) return; + + Window* window = FindWindowById(WC_BUILD_VIRTUAL_TRAIN, 0); + if (window) { + Train* train = Train::From(Vehicle::Get(_new_vehicle_id)); + ((BuildVehicleWindow*) window)->AddVirtualEngine(train); + } +} + static WindowDesc _build_vehicle_desc( WDP_AUTO, "build_vehicle", 240, 268, WC_BUILD_VEHICLE, WC_NONE, @@ -1490,6 +1532,13 @@ static WindowDesc _build_vehicle_desc( _nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets) ); +static WindowDesc _build_template_vehicle_desc( + WDP_AUTO, "build_vehicle", 240, 268, + WC_BUILD_VIRTUAL_TRAIN, WC_CREATE_TEMPLATE, + WDF_CONSTRUCTION, + _nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets) +); + void ShowBuildVehicleWindow(TileIndex tile, VehicleType type) { /* We want to be able to open both Available Train as Available Ships, @@ -1502,5 +1551,14 @@ void ShowBuildVehicleWindow(TileIndex tile, VehicleType type) DeleteWindowById(WC_BUILD_VEHICLE, num); - new BuildVehicleWindow(&_build_vehicle_desc, tile, type); + new BuildVehicleWindow(&_build_vehicle_desc, tile, type, NULL); +} + +void ShowTemplateTrainBuildVehicleWindow(Train **virtual_train) +{ + assert(IsCompanyBuildableVehicleType(VEH_TRAIN)); + + DeleteWindowById(WC_BUILD_VIRTUAL_TRAIN, 0); + + new BuildVehicleWindow(&_build_template_vehicle_desc, INVALID_TILE, VEH_TRAIN, virtual_train); } diff --git a/src/command_func.h b/src/command_func.h index d719aba570..416ed45178 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -130,7 +130,7 @@ CommandCallback CcSetVirtualTrain; CommandCallback CcVirtualTrainWaggonsMoved; CommandCallback CcDeleteVirtualTrain; -/* tbtr_template_gui_create_virtualtrain.cpp */ +/* build_vehicle_gui.cpp */ CommandCallback CcAddVirtualEngine; #endif /* COMMAND_FUNC_H */ diff --git a/src/tbtr_template_gui_create.cpp b/src/tbtr_template_gui_create.cpp index ed35624b31..1e9c174a5d 100644 --- a/src/tbtr_template_gui_create.cpp +++ b/src/tbtr_template_gui_create.cpp @@ -104,6 +104,8 @@ static WindowDesc _template_create_window_desc( _widgets, lengthof(_widgets) // widgets + num widgets ); +void ShowTemplateTrainBuildVehicleWindow(Train **virtual_train); + static void TrainDepotMoveVehicle(const Vehicle *wagon, VehicleID sel, const Vehicle *head) { const Vehicle *v = Vehicle::Get(sel); @@ -130,15 +132,13 @@ private: int line_height; Train* virtual_train; bool editMode; - bool *noticeParent; bool *createWindowOpen; /// used to notify main window of progress (dummy way of disabling 'delete' while editing a template) - bool virtualTrainChangedNotice; VehicleID sel; VehicleID vehicle_over; TemplateVehicle *editTemplate; public: - TemplateCreateWindow(WindowDesc* _wdesc, TemplateVehicle *to_edit, bool *notice, bool *windowOpen, int step_h) : Window(_wdesc) + TemplateCreateWindow(WindowDesc* _wdesc, TemplateVehicle *to_edit, bool *windowOpen, int step_h) : Window(_wdesc) { this->line_height = step_h; this->CreateNestedTree(_wdesc != NULL); @@ -150,9 +150,7 @@ public: this->owner = _local_company; - noticeParent = notice; createWindowOpen = windowOpen; - virtualTrainChangedNotice = false; this->editTemplate = to_edit; editMode = (to_edit != NULL); @@ -181,6 +179,7 @@ public: /* more cleanup */ *createWindowOpen = false; DeleteWindowById(WC_BUILD_VIRTUAL_TRAIN, this->window_number); + InvalidateWindowClassesData(WC_TEMPLATEGUI_MAIN); } void SetVirtualTrain(Train* const train) @@ -205,7 +204,7 @@ public: virtual void OnInvalidateData(int data = 0, bool gui_scope = true) { - virtualTrainChangedNotice = true; + this->SetDirty(); UpdateButtonState(); } @@ -218,7 +217,7 @@ public: break; } case TCW_NEW: { - ShowBuildVirtualTrainWindow(&virtual_train, &virtualTrainChangedNotice); + ShowTemplateTrainBuildVehicleWindow(&virtual_train); break; } case TCW_CLONE: { @@ -330,15 +329,6 @@ public: } } - virtual void OnTick() - { - if (virtualTrainChangedNotice) { - this->SetDirty(); - virtualTrainChangedNotice = false; - UpdateButtonState(); - } - } - virtual void OnDragDrop(Point pt, int widget) { switch (widget) { @@ -546,10 +536,10 @@ public: } }; -void ShowTemplateCreateWindow(TemplateVehicle *to_edit, bool *noticeParent, bool *createWindowOpen, int step_h) +void ShowTemplateCreateWindow(TemplateVehicle *to_edit, bool *createWindowOpen, int step_h) { if (BringWindowToFrontById(WC_CREATE_TEMPLATE, VEH_TRAIN) != NULL) return; - new TemplateCreateWindow(&_template_create_window_desc, to_edit, noticeParent, createWindowOpen, step_h); + new TemplateCreateWindow(&_template_create_window_desc, to_edit, createWindowOpen, step_h); } void CcSetVirtualTrain(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) diff --git a/src/tbtr_template_gui_create.h b/src/tbtr_template_gui_create.h index d95cf53bdf..8e267a7303 100644 --- a/src/tbtr_template_gui_create.h +++ b/src/tbtr_template_gui_create.h @@ -13,8 +13,7 @@ #define TEMPLATE_GUI_CREATE #include "tbtr_template_vehicle.h" -#include "tbtr_template_gui_create_virtualtrain.h" -void ShowTemplateCreateWindow(TemplateVehicle*, bool*, bool*, int); +void ShowTemplateCreateWindow(TemplateVehicle*, bool*, int); #endif diff --git a/src/tbtr_template_gui_create_virtualtrain.cpp b/src/tbtr_template_gui_create_virtualtrain.cpp deleted file mode 100644 index de3f537327..0000000000 --- a/src/tbtr_template_gui_create_virtualtrain.cpp +++ /dev/null @@ -1,837 +0,0 @@ -/* $Id$ */ - -/* - * This file is part of OpenTTD. - * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. - * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . - */ - -/** @file tbtr_template_gui_create_virtualtrain.cpp Template-based train replacement: template creation vehicle build GUI. */ - -#include "stdafx.h" -#include "engine_base.h" -#include "engine_func.h" -#include "station_base.h" -#include "articulated_vehicles.h" -#include "textbuf_gui.h" -#include "command_func.h" -#include "company_func.h" -#include "vehicle_gui.h" -#include "newgrf_engine.h" -#include "newgrf_text.h" -#include "group.h" -#include "string_func.h" -#include "strings_func.h" -#include "window_func.h" -#include "date_func.h" -#include "vehicle_func.h" -#include "widgets/dropdown_func.h" -#include "engine_gui.h" -#include "cargotype.h" -#include "core/geometry_func.hpp" -#include "vehicle_gui.h" -#include "tbtr_template_gui_create_virtualtrain.h" - -#include "widgets/build_vehicle_widget.h" - -#include "table/strings.h" - -#include "safeguards.h" - -static const NWidgetPart _nested_build_vehicle_widgets[] = { - NWidget(NWID_HORIZONTAL), - NWidget(WWT_CLOSEBOX, COLOUR_GREY), - NWidget(WWT_CAPTION, COLOUR_GREY, WID_BV_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - NWidget(WWT_SHADEBOX, COLOUR_GREY), - NWidget(WWT_STICKYBOX, COLOUR_GREY), - EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(NWID_HORIZONTAL), - NWidget(NWID_VERTICAL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_BV_SORT_ASCENDING_DESCENDING), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), - NWidget(NWID_SPACER), SetFill(1, 1), - EndContainer(), - NWidget(NWID_VERTICAL), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_BV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_BV_CARGO_FILTER_DROPDOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_FILTER_CRITERIA), - EndContainer(), - EndContainer(), - EndContainer(), - /* Vehicle list. */ - NWidget(NWID_HORIZONTAL), - NWidget(WWT_MATRIX, COLOUR_GREY, WID_BV_LIST), SetResize(1, 1), SetFill(1, 0), SetDataTip(0x101, STR_NULL), SetScrollbar(WID_BV_SCROLLBAR), - NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_BV_SCROLLBAR), - EndContainer(), - /* Panel with details. */ - NWidget(WWT_PANEL, COLOUR_GREY, WID_BV_PANEL), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(), - /* Build/rename buttons, resize button. */ - NWidget(NWID_HORIZONTAL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_BV_BUILD), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_TMPL_CONFIRM, STR_TMPL_CONFIRM), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_BV_RENAME), SetResize(1, 0), SetFill(1, 0), - NWidget(WWT_RESIZEBOX, COLOUR_GREY), - EndContainer(), -}; - -/** Special cargo filter criteria */ -static const CargoID CF_ANY = CT_NO_REFIT; ///< Show all vehicles independent of carried cargo (i.e. no filtering) -static const CargoID CF_NONE = CT_INVALID; ///< Show only vehicles which do not carry cargo (e.g. train engines) - -static bool _internal_sort_order; ///< false = descending, true = ascending -static byte _last_sort_criteria[] = {0, 0, 0, 0}; -static bool _last_sort_order[] = {false, false, false, false}; -static CargoID _last_filter_criteria[] = {CF_ANY, CF_ANY, CF_ANY, CF_ANY}; - -/** - * Determines order of engines by engineID - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal - */ -static int CDECL EngineNumberSorter(const EngineID *a, const EngineID *b) -{ - int r = Engine::Get(*a)->list_position - Engine::Get(*b)->list_position; - - return _internal_sort_order ? -r : r; -} - -/** - * Determines order of engines by introduction date - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal - */ -static int CDECL EngineIntroDateSorter(const EngineID *a, const EngineID *b) -{ - const int va = Engine::Get(*a)->intro_date; - const int vb = Engine::Get(*b)->intro_date; - const int r = va - vb; - - /* Use EngineID to sort instead since we want consistent sorting */ - if (r == 0) return EngineNumberSorter(a, b); - return _internal_sort_order ? -r : r; -} - -/** - * Determines order of engines by name - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal - */ -static int CDECL EngineNameSorter(const EngineID *a, const EngineID *b) -{ - static EngineID last_engine[2] = { INVALID_ENGINE, INVALID_ENGINE }; - static char last_name[2][64] = { "\0", "\0" }; - - const EngineID va = *a; - const EngineID vb = *b; - - if (va != last_engine[0]) { - last_engine[0] = va; - SetDParam(0, va); - GetString(last_name[0], STR_ENGINE_NAME, lastof(last_name[0])); - } - - if (vb != last_engine[1]) { - last_engine[1] = vb; - SetDParam(0, vb); - GetString(last_name[1], STR_ENGINE_NAME, lastof(last_name[1])); - } - - int r = strnatcmp(last_name[0], last_name[1]); // Sort by name (natural sorting). - - /* Use EngineID to sort instead since we want consistent sorting */ - if (r == 0) return EngineNumberSorter(a, b); - return _internal_sort_order ? -r : r; -} - -/** - * Determines order of engines by reliability - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal - */ -static int CDECL EngineReliabilitySorter(const EngineID *a, const EngineID *b) -{ - const int va = Engine::Get(*a)->reliability; - const int vb = Engine::Get(*b)->reliability; - const int r = va - vb; - - /* Use EngineID to sort instead since we want consistent sorting */ - if (r == 0) return EngineNumberSorter(a, b); - return _internal_sort_order ? -r : r; -} - -/** - * Determines order of engines by purchase cost - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal - */ -static int CDECL EngineCostSorter(const EngineID *a, const EngineID *b) -{ - Money va = Engine::Get(*a)->GetCost(); - Money vb = Engine::Get(*b)->GetCost(); - int r = ClampToI32(va - vb); - - /* Use EngineID to sort instead since we want consistent sorting */ - if (r == 0) return EngineNumberSorter(a, b); - return _internal_sort_order ? -r : r; -} - -/** - * Determines order of engines by speed - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal - */ -static int CDECL EngineSpeedSorter(const EngineID *a, const EngineID *b) -{ - int va = Engine::Get(*a)->GetDisplayMaxSpeed(); - int vb = Engine::Get(*b)->GetDisplayMaxSpeed(); - int r = va - vb; - - /* Use EngineID to sort instead since we want consistent sorting */ - if (r == 0) return EngineNumberSorter(a, b); - return _internal_sort_order ? -r : r; -} - -/** - * Determines order of engines by power - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal - */ -static int CDECL EnginePowerSorter(const EngineID *a, const EngineID *b) -{ - int va = Engine::Get(*a)->GetPower(); - int vb = Engine::Get(*b)->GetPower(); - int r = va - vb; - - /* Use EngineID to sort instead since we want consistent sorting */ - if (r == 0) return EngineNumberSorter(a, b); - return _internal_sort_order ? -r : r; -} - -/** - * Determines order of engines by tractive effort - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal - */ -static int CDECL EngineTractiveEffortSorter(const EngineID *a, const EngineID *b) -{ - int va = Engine::Get(*a)->GetDisplayMaxTractiveEffort(); - int vb = Engine::Get(*b)->GetDisplayMaxTractiveEffort(); - int r = va - vb; - - /* Use EngineID to sort instead since we want consistent sorting */ - if (r == 0) return EngineNumberSorter(a, b); - return _internal_sort_order ? -r : r; -} - -/** - * Determines order of engines by running costs - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal - */ -static int CDECL EngineRunningCostSorter(const EngineID *a, const EngineID *b) -{ - Money va = Engine::Get(*a)->GetRunningCost(); - Money vb = Engine::Get(*b)->GetRunningCost(); - int r = ClampToI32(va - vb); - - /* Use EngineID to sort instead since we want consistent sorting */ - if (r == 0) return EngineNumberSorter(a, b); - return _internal_sort_order ? -r : r; -} - -/** - * Determines order of engines by running costs - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal - */ -static int CDECL EnginePowerVsRunningCostSorter(const EngineID *a, const EngineID *b) -{ - const Engine *e_a = Engine::Get(*a); - const Engine *e_b = Engine::Get(*b); - - /* Here we are using a few tricks to get the right sort. - * We want power/running cost, but since we usually got higher running cost than power and we store the result in an int, - * we will actually calculate cunning cost/power (to make it more than 1). - * Because of this, the return value have to be reversed as well and we return b - a instead of a - b. - * Another thing is that both power and running costs should be doubled for multiheaded engines. - * Since it would be multipling with 2 in both numerator and denumerator, it will even themselves out and we skip checking for multiheaded. */ - Money va = (e_a->GetRunningCost()) / max(1U, (uint)e_a->GetPower()); - Money vb = (e_b->GetRunningCost()) / max(1U, (uint)e_b->GetPower()); - int r = ClampToI32(vb - va); - - /* Use EngineID to sort instead since we want consistent sorting */ - if (r == 0) return EngineNumberSorter(a, b); - return _internal_sort_order ? -r : r; -} - -/* Train sorting functions */ - -/** - * Determines order of train engines by capacity - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal - */ -static int CDECL TrainEngineCapacitySorter(const EngineID *a, const EngineID *b) -{ - const RailVehicleInfo *rvi_a = RailVehInfo(*a); - const RailVehicleInfo *rvi_b = RailVehInfo(*b); - - int va = GetTotalCapacityOfArticulatedParts(*a) * (rvi_a->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1); - int vb = GetTotalCapacityOfArticulatedParts(*b) * (rvi_b->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1); - int r = va - vb; - - /* Use EngineID to sort instead since we want consistent sorting */ - if (r == 0) return EngineNumberSorter(a, b); - return _internal_sort_order ? -r : r; -} - -/** - * Determines order of train engines by engine / wagon - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal - */ -static int CDECL TrainEnginesThenWagonsSorter(const EngineID *a, const EngineID *b) -{ - int val_a = (RailVehInfo(*a)->railveh_type == RAILVEH_WAGON ? 1 : 0); - int val_b = (RailVehInfo(*b)->railveh_type == RAILVEH_WAGON ? 1 : 0); - int r = val_a - val_b; - - /* Use EngineID to sort instead since we want consistent sorting */ - if (r == 0) return EngineNumberSorter(a, b); - return _internal_sort_order ? -r : r; -} - -/** Sort functions for the vehicle sort criteria, for each vehicle type. */ -static EngList_SortTypeFunction * const _sorter[][11] = {{ - /* Trains */ - &EngineNumberSorter, - &EngineCostSorter, - &EngineSpeedSorter, - &EnginePowerSorter, - &EngineTractiveEffortSorter, - &EngineIntroDateSorter, - &EngineNameSorter, - &EngineRunningCostSorter, - &EnginePowerVsRunningCostSorter, - &EngineReliabilitySorter, - &TrainEngineCapacitySorter, -}}; - -static const StringID _sort_listing[][12] = {{ - /* Trains */ - STR_SORT_BY_ENGINE_ID, - STR_SORT_BY_COST, - STR_SORT_BY_MAX_SPEED, - STR_SORT_BY_POWER, - STR_SORT_BY_TRACTIVE_EFFORT, - STR_SORT_BY_INTRO_DATE, - STR_SORT_BY_NAME, - STR_SORT_BY_RUNNING_COST, - STR_SORT_BY_POWER_VS_RUNNING_COST, - STR_SORT_BY_RELIABILITY, - STR_SORT_BY_CARGO_CAPACITY, - INVALID_STRING_ID -}}; - -/** Cargo filter functions */ -static bool CDECL CargoFilter(const EngineID *eid, const CargoID cid) -{ - if (cid == CF_ANY) return true; - uint32 refit_mask = GetUnionOfArticulatedRefitMasks(*eid, true); - return (cid == CF_NONE ? refit_mask == 0 : HasBit(refit_mask, cid)); -} - -static GUIEngineList::FilterFunction * const _filter_funcs[] = { - &CargoFilter, -}; - -/** - * Engine drawing loop - * @param type Type of vehicle (VEH_*) - * @param l The left most location of the list - * @param r The right most location of the list - * @param y The top most location of the list - * @param eng_list What engines to draw - * @param min where to start in the list - * @param max where in the list to end - * @param selected_id what engine to highlight as selected, if any - * @param show_count Whether to show the amount of engines or not - * @param selected_group the group to list the engines of - */ -static void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group) -{ - static const int sprite_widths[] = { 60, 60, 76, 67 }; - static const int sprite_y_offsets[] = { -1, -1, -2, -2 }; - - /* Obligatory sanity checks! */ - assert((uint)type < lengthof(sprite_widths)); - assert_compile(lengthof(sprite_y_offsets) == lengthof(sprite_widths)); - assert(max <= eng_list->Length()); - - bool rtl = _current_text_dir == TD_RTL; - int step_size = GetEngineListHeight(type); - int sprite_width = sprite_widths[type]; - - int sprite_x = (rtl ? r - sprite_width / 2 : l + sprite_width / 2) - 1; - int sprite_y_offset = sprite_y_offsets[type] + step_size / 2; - - int text_left = l + (rtl ? WD_FRAMERECT_LEFT : sprite_width); - int text_right = r - (rtl ? sprite_width : WD_FRAMERECT_RIGHT); - - int normal_text_y_offset = (step_size - FONT_HEIGHT_NORMAL) / 2; - int small_text_y_offset = step_size - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1; - - for (; min < max; min++, y += step_size) { - const EngineID engine = (*eng_list)[min]; - /* Note: num_engines is only used in the autoreplace GUI, so it is correct to use _local_company here. */ - const uint num_engines = GetGroupNumEngines(_local_company, selected_group, engine); - - SetDParam(0, engine); - DrawString(text_left, text_right, y + normal_text_y_offset, STR_ENGINE_NAME, engine == selected_id ? TC_WHITE : TC_BLACK); - DrawVehicleEngine(l, r, sprite_x, y + sprite_y_offset, engine, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(engine, _local_company), EIT_PURCHASE); - if (show_count) { - SetDParam(0, num_engines); - DrawString(text_left, text_right, y + small_text_y_offset, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT); - } - } -} - - -struct BuildVirtualTrainWindow : Window { - VehicleType vehicle_type; - union { - RailTypeByte railtype; - RoadTypes roadtypes; - } filter; - bool descending_sort_order; - byte sort_criteria; - bool listview_mode; - EngineID sel_engine; - EngineID rename_engine; - GUIEngineList eng_list; - CargoID cargo_filter[NUM_CARGO + 2]; ///< Available cargo filters; CargoID or CF_ANY or CF_NONE - StringID cargo_filter_texts[NUM_CARGO + 3]; ///< Texts for filter_cargo, terminated by INVALID_STRING_ID - byte cargo_filter_criteria; ///< Selected cargo filter - int details_height; ///< Minimal needed height of the details panels (found so far). - Scrollbar *vscroll; - Train **virtual_train; ///< the virtual train that is currently being created - bool *noticeParent; - - BuildVirtualTrainWindow(WindowDesc *desc, Train **vt, bool *notice) : Window(desc) - { - this->vehicle_type = VEH_TRAIN; - this->window_number = 0; - - this->sel_engine = INVALID_ENGINE; - - this->sort_criteria = _last_sort_criteria[VEH_TRAIN]; - this->descending_sort_order = _last_sort_order[VEH_TRAIN]; - - this->filter.railtype = RAILTYPE_END; - - this->listview_mode = (this->window_number <= VEH_END); - - this->CreateNestedTree(desc); - - this->vscroll = this->GetScrollbar(WID_BV_SCROLLBAR); - - NWidgetCore *widget = this->GetWidget(WID_BV_LIST); - - widget = this->GetWidget(WID_BV_BUILD); - - widget = this->GetWidget(WID_BV_RENAME); - widget->widget_data = STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON + VEH_TRAIN; - widget->tool_tip = STR_BUY_VEHICLE_TRAIN_RENAME_TOOLTIP + VEH_TRAIN; - - this->details_height = ((this->vehicle_type == VEH_TRAIN) ? 10 : 9) * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; - - this->FinishInitNested(VEH_TRAIN); - - this->owner = _local_company; - - this->eng_list.ForceRebuild(); - this->GenerateBuildList(); - - if (this->eng_list.Length() > 0) this->sel_engine = this->eng_list[0]; - - this->virtual_train = vt; - this->noticeParent = notice; - } - - /** Populate the filter list and set the cargo filter criteria. */ - void SetCargoFilterArray() - { - uint filter_items = 0; - - /* Add item for disabling filtering. */ - this->cargo_filter[filter_items] = CF_ANY; - this->cargo_filter_texts[filter_items] = STR_PURCHASE_INFO_ALL_TYPES; - filter_items++; - - /* Add item for vehicles not carrying anything, e.g. train engines. - * This could also be useful for eyecandy vehicles of other types, but is likely too confusing for joe, */ - if (this->vehicle_type == VEH_TRAIN) { - this->cargo_filter[filter_items] = CF_NONE; - this->cargo_filter_texts[filter_items] = STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE; - filter_items++; - } - - /* Collect available cargo types for filtering. */ - const CargoSpec *cs; - FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { - this->cargo_filter[filter_items] = cs->Index(); - this->cargo_filter_texts[filter_items] = cs->name; - filter_items++; - } - - /* Terminate the filter list. */ - this->cargo_filter_texts[filter_items] = INVALID_STRING_ID; - - /* If not found, the cargo criteria will be set to all cargoes. */ - this->cargo_filter_criteria = 0; - - /* Find the last cargo filter criteria. */ - for (uint i = 0; i < filter_items; ++i) { - if (this->cargo_filter[i] == _last_filter_criteria[this->vehicle_type]) { - this->cargo_filter_criteria = i; - break; - } - } - - this->eng_list.SetFilterFuncs(_filter_funcs); - this->eng_list.SetFilterState(this->cargo_filter[this->cargo_filter_criteria] != CF_ANY); - } - - void OnInit() - { - this->SetCargoFilterArray(); - } - - /** Filter the engine list against the currently selected cargo filter */ - void FilterEngineList() - { - this->eng_list.Filter(this->cargo_filter[this->cargo_filter_criteria]); - if (0 == this->eng_list.Length()) { // no engine passed through the filter, invalidate the previously selected engine - this->sel_engine = INVALID_ENGINE; - } else if (!this->eng_list.Contains(this->sel_engine)) { // previously selected engine didn't pass the filter, select the first engine of the list - this->sel_engine = this->eng_list[0]; - } - } - - /** Filter a single engine */ - bool FilterSingleEngine(EngineID eid) - { - CargoID filter_type = this->cargo_filter[this->cargo_filter_criteria]; - return (filter_type == CF_ANY || CargoFilter(&eid, filter_type)); - } - - /* Figure out what train EngineIDs to put in the list */ - void GenerateBuildTrainList() - { - EngineID sel_id = INVALID_ENGINE; - int num_engines = 0; - int num_wagons = 0; - - this->filter.railtype = (this->listview_mode) ? RAILTYPE_END : GetRailType(this->window_number); - - this->eng_list.Clear(); - - /* Make list of all available train engines and wagons. - * Also check to see if the previously selected engine is still available, - * and if not, reset selection to INVALID_ENGINE. This could be the case - * when engines become obsolete and are removed */ - const Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) { - EngineID eid = e->index; - const RailVehicleInfo *rvi = &e->u.rail; - - if (this->filter.railtype != RAILTYPE_END && !HasPowerOnRail(rvi->railtype, this->filter.railtype)) continue; - if (!IsEngineBuildable(eid, VEH_TRAIN, _local_company)) continue; - - /* Filter now! So num_engines and num_wagons is valid */ - if (!FilterSingleEngine(eid)) continue; - - *this->eng_list.Append() = eid; - - if (rvi->railveh_type != RAILVEH_WAGON) { - num_engines++; - } else { - num_wagons++; - } - - if (eid == this->sel_engine) sel_id = eid; - } - - this->sel_engine = sel_id; - - /* make engines first, and then wagons, sorted by ListPositionOfEngine() */ - _internal_sort_order = false; - EngList_Sort(&this->eng_list, TrainEnginesThenWagonsSorter); - - /* and then sort engines */ - _internal_sort_order = this->descending_sort_order; - EngList_SortPartial(&this->eng_list, _sorter[0][this->sort_criteria], 0, num_engines); - - /* and finally sort wagons */ - EngList_SortPartial(&this->eng_list, _sorter[0][this->sort_criteria], num_engines, num_wagons); - } - - /* Generate the list of vehicles */ - void GenerateBuildList() - { - if (!this->eng_list.NeedRebuild()) return; - - this->GenerateBuildTrainList(); - this->eng_list.Compact(); - this->eng_list.RebuildDone(); - return; // trains should not reach the last sorting - - - this->FilterEngineList(); - - _internal_sort_order = this->descending_sort_order; - EngList_Sort(&this->eng_list, _sorter[this->vehicle_type][this->sort_criteria]); - - this->eng_list.Compact(); - this->eng_list.RebuildDone(); - } - - virtual void OnClick(Point pt, int widget, int click_count) - { - switch (widget) { - case WID_BV_SORT_ASCENDING_DESCENDING: - this->descending_sort_order ^= true; - _last_sort_order[this->vehicle_type] = this->descending_sort_order; - this->eng_list.ForceRebuild(); - this->SetDirty(); - break; - - case WID_BV_LIST: { - uint i = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_BV_LIST); - size_t num_items = this->eng_list.Length(); - this->sel_engine = (i < num_items) ? this->eng_list[i] : INVALID_ENGINE; - this->SetDirty(); - if (click_count > 1 && !this->listview_mode) this->OnClick(pt, WID_BV_BUILD, 1); - break; - } - case WID_BV_SORT_DROPDOWN: { // Select sorting criteria dropdown menu - uint32 hidden_mask = 0; - /* Disable sorting by power or tractive effort when the original acceleration model for road vehicles is being used. */ - if (this->vehicle_type == VEH_ROAD && - _settings_game.vehicle.roadveh_acceleration_model == AM_ORIGINAL) { - SetBit(hidden_mask, 3); // power - SetBit(hidden_mask, 4); // tractive effort - SetBit(hidden_mask, 8); // power by running costs - } - /* Disable sorting by tractive effort when the original acceleration model for trains is being used. */ - if (this->vehicle_type == VEH_TRAIN && - _settings_game.vehicle.train_acceleration_model == AM_ORIGINAL) { - SetBit(hidden_mask, 4); // tractive effort - } - ShowDropDownMenu(this, _sort_listing[this->vehicle_type], this->sort_criteria, WID_BV_SORT_DROPDOWN, 0, hidden_mask); - break; - } - - case WID_BV_CARGO_FILTER_DROPDOWN: // Select cargo filtering criteria dropdown menu - ShowDropDownMenu(this, this->cargo_filter_texts, this->cargo_filter_criteria, WID_BV_CARGO_FILTER_DROPDOWN, 0, 0); - break; - - case WID_BV_BUILD: { - EngineID sel_eng = this->sel_engine; - if (sel_eng != INVALID_ENGINE) { - DoCommandP(0, sel_engine, 0, CMD_BUILD_VIRTUAL_RAIL_VEHICLE, CcAddVirtualEngine); - } - break; - } - } - } - - /** - * Some data on this window has become invalid. - * @param data Information about the changed data. - * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details. - */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) - { - if (!gui_scope) return; - /* When switching to original acceleration model for road vehicles, clear the selected sort criteria if it is not available now. */ - - this->eng_list.ForceRebuild(); - } - - virtual void SetStringParameters(int widget) const - { - switch (widget) { - case WID_BV_CAPTION: - if (this->vehicle_type == VEH_TRAIN && !this->listview_mode) { - const RailtypeInfo *rti = GetRailTypeInfo(this->filter.railtype); - SetDParam(0, rti->strings.build_caption); - } else { - SetDParam(0, (this->listview_mode ? STR_VEHICLE_LIST_AVAILABLE_TRAINS : STR_BUY_VEHICLE_TRAIN_ALL_CAPTION) + this->vehicle_type); - } - break; - - case WID_BV_SORT_DROPDOWN: - SetDParam(0, _sort_listing[this->vehicle_type][this->sort_criteria]); - break; - - case WID_BV_CARGO_FILTER_DROPDOWN: - SetDParam(0, this->cargo_filter_texts[this->cargo_filter_criteria]); - break; - } - } - - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) - { - switch (widget) { - case WID_BV_LIST: - resize->height = GetEngineListHeight(this->vehicle_type); - size->height = 3 * resize->height; - break; - - case WID_BV_PANEL: - size->height = this->details_height; - break; - - case WID_BV_SORT_ASCENDING_DESCENDING: { - Dimension d = GetStringBoundingBox(this->GetWidget(widget)->widget_data); - d.width += padding.width + WD_CLOSEBOX_WIDTH * 2; // Doubled since the string is centred and it also looks better. - d.height += padding.height; - *size = maxdim(*size, d); - break; - } - } - } - - virtual void DrawWidget(const Rect &r, int widget) const - { - switch (widget) { - case WID_BV_LIST: - DrawEngineList(this->vehicle_type, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, - &this->eng_list, this->vscroll->GetPosition(), min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), - this->eng_list.Length()), this->sel_engine, false, DEFAULT_GROUP); - break; - - case WID_BV_SORT_ASCENDING_DESCENDING: - this->DrawSortButtonState(WID_BV_SORT_ASCENDING_DESCENDING, this->descending_sort_order ? SBS_DOWN : SBS_UP); - break; - } - } - - virtual void OnPaint() - { - this->GenerateBuildList(); - this->vscroll->SetCount(this->eng_list.Length()); - - this->DrawWidgets(); - - if (!this->IsShaded()) { - int needed_height = this->details_height; - /* Draw details panels. */ - if (this->sel_engine != INVALID_ENGINE) { - NWidgetBase *nwi = this->GetWidget(WID_BV_PANEL); - int text_end = DrawVehiclePurchaseInfo(nwi->pos_x + WD_FRAMETEXT_LEFT, nwi->pos_x + nwi->current_x - WD_FRAMETEXT_RIGHT, - nwi->pos_y + WD_FRAMERECT_TOP, this->sel_engine); - needed_height = max(needed_height, text_end - (int)nwi->pos_y + WD_FRAMERECT_BOTTOM); - } - if (needed_height != this->details_height) { // Details window are not high enough, enlarge them. - int resize = needed_height - this->details_height; - this->details_height = needed_height; - this->ReInit(0, resize); - return; - } - } - } - - virtual void OnQueryTextFinished(char *str) - { - if (str == NULL) return; - - DoCommandP(0, this->rename_engine, 0, CMD_RENAME_ENGINE | CMD_MSG(STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type), NULL, str); - } - - virtual void OnDropdownSelect(int widget, int index) - { - switch (widget) { - case WID_BV_SORT_DROPDOWN: - if (this->sort_criteria != index) { - this->sort_criteria = index; - _last_sort_criteria[this->vehicle_type] = this->sort_criteria; - this->eng_list.ForceRebuild(); - } - break; - - case WID_BV_CARGO_FILTER_DROPDOWN: // Select a cargo filter criteria - if (this->cargo_filter_criteria != index) { - this->cargo_filter_criteria = index; - _last_filter_criteria[this->vehicle_type] = this->cargo_filter[this->cargo_filter_criteria]; - /* deactivate filter if criteria is 'Show All', activate it otherwise */ - this->eng_list.SetFilterState(this->cargo_filter[this->cargo_filter_criteria] != CF_ANY); - this->eng_list.ForceRebuild(); - } - break; - } - this->SetDirty(); - } - - virtual void OnResize() - { - this->vscroll->SetCapacityFromWidget(this, WID_BV_LIST); - this->GetWidget(WID_BV_LIST)->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); - } - - void AddVirtualEngine(Train *toadd) - { - if (*virtual_train == NULL) { - *virtual_train = toadd; - } else { - VehicleID target = (*(this->virtual_train))->GetLastUnit()->index; - - DoCommandP(0, (1 << 21) | toadd->index, target, CMD_MOVE_RAIL_VEHICLE); - } - *noticeParent = true; - } -}; - -void CcAddVirtualEngine(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) -{ - if (result.Failed()) return; - - Window* window = FindWindowById(WC_BUILD_VIRTUAL_TRAIN, 0); - if (window) { - Train* train = Train::From(Vehicle::Get(_new_vehicle_id)); - ((BuildVirtualTrainWindow*)window)->AddVirtualEngine(train); - window->InvalidateData(); - } -} - -static WindowDesc _build_vehicle_desc( - WDP_AUTO, // window position - "template create virtual train", // const char* ini_key - 240, 268, // window size - WC_BUILD_VIRTUAL_TRAIN, // window class - WC_CREATE_TEMPLATE, // parent window class - WDF_CONSTRUCTION, // window flags - _nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets) // widgets + num widgets -); - -void ShowBuildVirtualTrainWindow(Train **vt, bool *noticeParent) -{ - // '0' as in VEH_TRAIN = Tile=0 - assert(IsCompanyBuildableVehicleType(VEH_TRAIN)); - - DeleteWindowById(WC_BUILD_VEHICLE, 0); - - new BuildVirtualTrainWindow(&_build_vehicle_desc, vt, noticeParent); -} diff --git a/src/tbtr_template_gui_create_virtualtrain.h b/src/tbtr_template_gui_create_virtualtrain.h deleted file mode 100644 index ee0b4123c3..0000000000 --- a/src/tbtr_template_gui_create_virtualtrain.h +++ /dev/null @@ -1,19 +0,0 @@ -/* $Id$ */ - -/* - * This file is part of OpenTTD. - * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. - * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . - */ - -/** @file tbtr_template_gui_create_virtualtrain.cpp Template-based train replacement: template creation vehicle build GUI header. */ - -#ifndef BUILD_VIRTUAL_TRAIN_GUI -#define BUILD_VIRTUAL_TRAIN_GUI - -#include "train.h" - -void ShowBuildVirtualTrainWindow(Train**, bool*); - -#endif diff --git a/src/tbtr_template_gui_main.cpp b/src/tbtr_template_gui_main.cpp index 23960739ce..49afffed50 100644 --- a/src/tbtr_template_gui_main.cpp +++ b/src/tbtr_template_gui_main.cpp @@ -200,7 +200,6 @@ private: short selected_template_index; short selected_group_index; - bool templateNotice; bool editInProgress; public: @@ -235,7 +234,6 @@ public: this->UpdateButtonState(); - this->templateNotice = false; this->editInProgress = false; this->templates.ForceRebuild(); @@ -319,11 +317,6 @@ public: this->BuildGroupList(_local_company); - if (templateNotice) { - BuildTemplateGuiList(&this->templates, vscroll[1], _local_company, this->sel_railtype); - templateNotice = false; - this->SetDirty(); - } /* sets the colour of that art thing */ this->GetWidget(TRW_WIDGET_TRAIN_FLUFF_LEFT)->colour = _company_colours[_local_company]; this->GetWidget(TRW_WIDGET_TRAIN_FLUFF_RIGHT)->colour = _company_colours[_local_company]; @@ -392,14 +385,17 @@ public: break; } case TRW_WIDGET_TMPL_BUTTONS_DEFINE: { - ShowTemplateCreateWindow(0, &templateNotice, &editInProgress, this->line_height); + editInProgress = true; + ShowTemplateCreateWindow(0, &editInProgress, this->line_height); + UpdateButtonState(); break; } case TRW_WIDGET_TMPL_BUTTONS_EDIT: { if ((this->selected_template_index >= 0) && (this->selected_template_index < (short)this->templates.Length())) { editInProgress = true; TemplateVehicle *sel = TemplateVehicle::Get(((this->templates)[selected_template_index])->index); - ShowTemplateCreateWindow(sel, &templateNotice, &editInProgress, this->line_height); + ShowTemplateCreateWindow(sel, &editInProgress, this->line_height); + UpdateButtonState(); } break; } @@ -522,21 +518,12 @@ public: this->vscroll[2]->SetCapacity(nwi3->current_y); } - virtual void OnTick() - { - if (templateNotice) { - BuildTemplateGuiList(&this->templates, this->vscroll[1], this->owner, this->sel_railtype); - this->SetDirty(); - templateNotice = false; - } - - } - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) { this->groups.ForceRebuild(); this->templates.ForceRebuild(); this->UpdateButtonState(); + this->SetDirty(); } /** For a given group (id) find the template that is issued for template replacement for this group and return this template's index @@ -791,14 +778,18 @@ public: g_id = g->index; } - this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_EDIT, !selected_ok); - this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_DELETE, !selected_ok); - this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_REUSE, !selected_ok); - this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_KEEP, !selected_ok); - this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_REFIT, !selected_ok); + this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_EDIT, this->editInProgress || !selected_ok); + this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_DELETE, this->editInProgress || !selected_ok); + this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_REUSE, this->editInProgress || !selected_ok); + this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_KEEP, this->editInProgress ||!selected_ok); + this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_REFIT, this->editInProgress ||!selected_ok); - this->SetWidgetDisabledState(TRW_WIDGET_START, !(selected_ok && group_ok && FindTemplateIndexForGroup(g_id) != this->selected_template_index)); - this->SetWidgetDisabledState(TRW_WIDGET_STOP, !(group_ok && GetTemplateReplacementByGroupID(g_id) != NULL)); + this->SetWidgetDisabledState(TRW_WIDGET_START, this->editInProgress || !(selected_ok && group_ok && FindTemplateIndexForGroup(g_id) != this->selected_template_index)); + this->SetWidgetDisabledState(TRW_WIDGET_STOP, this->editInProgress || !(group_ok && GetTemplateReplacementByGroupID(g_id) != NULL)); + + this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_DEFINE, this->editInProgress); + this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_CLONE, this->editInProgress); + this->SetWidgetDisabledState(TRW_WIDGET_TRAIN_RAILTYPE_DROPDOWN, this->editInProgress); } };