
This approximately corresponds to 971ba4928a5c7c7916fea55d91a3b6dd5bba140c, excluding the different virtual train build GUI, but including the basic changes to the original train build GUI for multiplayer to work. Fixup
517 lines
16 KiB
C++
517 lines
16 KiB
C++
// replace all gui impl
|
|
|
|
#include "tbtr_template_gui_replaceall.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
/*
|
|
* A wrapper which contains a virtual train and additional info of the template vehicle it is replacing
|
|
* We will restore this additional info when creating a new template from the changed virtual train
|
|
*/
|
|
struct VirtTrainInfo {
|
|
// the virtual train
|
|
Train *vt;
|
|
|
|
// additional info from the template
|
|
VehicleID original_index;
|
|
|
|
bool reuse_depot_vehicles,
|
|
keep_remaining_vehicles,
|
|
refit_as_template;
|
|
|
|
CargoID cargo_type;
|
|
byte cargo_subtype;
|
|
|
|
// a fancy constructor
|
|
VirtTrainInfo(Train *t) { this->vt = t; }
|
|
};
|
|
|
|
typedef AutoFreeSmallVector<VirtTrainInfo*, 64> VirtTrainList;
|
|
enum Widgets {
|
|
RPLALL_GUI_CAPTION,
|
|
|
|
RPLALL_GUI_INSET_1,
|
|
RPLALL_GUI_INSET_1_1,
|
|
RPLALL_GUI_INSET_1_2,
|
|
RPLALL_GUI_MATRIX_TOPLEFT,
|
|
RPLALL_GUI_MATRIX_TOPRIGHT,
|
|
RPLALL_GUI_SCROLL_TL,
|
|
RPLALL_GUI_SCROLL_TR,
|
|
|
|
RPLALL_GUI_INSET_2,
|
|
RPLALL_GUI_MATRIX_BOTTOM,
|
|
RPLALL_GUI_SCROLL_BO,
|
|
|
|
RPLALL_GUI_INSET_3,
|
|
RPLALL_GUI_BUTTON_RPLALL,
|
|
RPLALL_GUI_PANEL_BUTTONFLUFF_1,
|
|
RPLALL_GUI_PANEL_BUTTONFLUFF_2,
|
|
RPLALL_GUI_BUTTON_APPLY,
|
|
RPLALL_GUI_PANEL_BUTTONFLUFF_3,
|
|
RPLALL_GUI_BUTTON_CANCEL,
|
|
|
|
RPLALL_GUI_PANEL_RESIZEFLUFF
|
|
};
|
|
|
|
static const NWidgetPart widgets[] = {
|
|
// title bar
|
|
NWidget(NWID_HORIZONTAL),
|
|
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
|
|
NWidget(WWT_CAPTION, COLOUR_GREY, RPLALL_GUI_CAPTION), SetDataTip(STR_TMPL_RPLALLGUI_TITLE, STR_TMPL_RPLALLGUI_TITLE),
|
|
NWidget(WWT_SHADEBOX, COLOUR_GREY),
|
|
NWidget(WWT_STICKYBOX, COLOUR_GREY),
|
|
EndContainer(),
|
|
// top matrices
|
|
NWidget(WWT_INSET, COLOUR_GREY, RPLALL_GUI_INSET_1), SetMinimalSize(100,12), SetResize(1,0), SetDataTip(STR_TMPL_RPLALLGUI_INSET_TOP, STR_TMPL_RPLALLGUI_INSET_TOP), EndContainer(),
|
|
NWidget(NWID_HORIZONTAL),
|
|
NWidget(NWID_VERTICAL),
|
|
NWidget(WWT_INSET, COLOUR_GREY, RPLALL_GUI_INSET_1_1), SetMinimalSize(100,12), SetResize(1,0), SetDataTip(STR_TMPL_RPLALLGUI_INSET_TOP_1, STR_TMPL_RPLALLGUI_INSET_TOP_1), EndContainer(),
|
|
NWidget(NWID_HORIZONTAL),
|
|
NWidget(WWT_MATRIX, COLOUR_GREY, RPLALL_GUI_MATRIX_TOPLEFT), SetMinimalSize(100, 16), SetFill(1, 1), SetResize(1, 1), SetScrollbar(RPLALL_GUI_SCROLL_TL),// SetDataTip(0x1, STR_REPLACE_HELP_LEFT_ARRAY),
|
|
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, RPLALL_GUI_SCROLL_TL),
|
|
EndContainer(),
|
|
EndContainer(),
|
|
NWidget(NWID_VERTICAL),
|
|
NWidget(WWT_INSET, COLOUR_GREY, RPLALL_GUI_INSET_1_2), SetMinimalSize(100,12), SetResize(1,0), SetDataTip(STR_TMPL_RPLALLGUI_INSET_TOP_2, STR_TMPL_RPLALLGUI_INSET_TOP_2), EndContainer(),
|
|
NWidget(NWID_HORIZONTAL),
|
|
NWidget(WWT_MATRIX, COLOUR_GREY, RPLALL_GUI_MATRIX_TOPRIGHT), SetMinimalSize(100, 16), SetFill(1, 1), SetResize(1, 1), SetScrollbar(RPLALL_GUI_SCROLL_TR),// SetDataTip(0x1, STR_REPLACE_HELP_LEFT_ARRAY),
|
|
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, RPLALL_GUI_SCROLL_TR),
|
|
EndContainer(),
|
|
EndContainer(),
|
|
EndContainer(),
|
|
// bottom matrix
|
|
NWidget(WWT_INSET, COLOUR_GREY, RPLALL_GUI_INSET_2), SetMinimalSize(200,12), SetResize(1,0), SetDataTip(STR_TMPL_RPLALLGUI_INSET_BOTTOM, STR_TMPL_RPLALLGUI_INSET_BOTTOM), EndContainer(),
|
|
NWidget(NWID_HORIZONTAL),
|
|
NWidget(WWT_MATRIX, COLOUR_GREY, RPLALL_GUI_MATRIX_BOTTOM), SetMinimalSize(200, 16), SetFill(1, 1), SetResize(1, 1), SetScrollbar(RPLALL_GUI_SCROLL_BO),// SetDataTip(0x1, STR_REPLACE_HELP_LEFT_ARRAY),
|
|
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, RPLALL_GUI_SCROLL_BO),
|
|
EndContainer(),
|
|
// control area
|
|
NWidget(WWT_INSET, COLOUR_GREY, RPLALL_GUI_INSET_3), SetMinimalSize(200,12), SetResize(1,0), EndContainer(),// SetDataTip(STR_TMPL_MAINGUI_DEFINEDGROUPS, STR_TMPL_MAINGUI_DEFINEDGROUPS),
|
|
NWidget(NWID_HORIZONTAL),
|
|
NWidget(WWT_PANEL, COLOUR_GREY, RPLALL_GUI_PANEL_BUTTONFLUFF_1), SetMinimalSize(75,12), SetResize(1,0), EndContainer(),
|
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, RPLALL_GUI_BUTTON_RPLALL), SetMinimalSize(150,12), SetResize(0,0), SetDataTip(STR_TMPL_RPLALLGUI_BUTTON_RPLALL, STR_TMPL_RPLALLGUI_BUTTON_RPLALL),
|
|
NWidget(WWT_PANEL, COLOUR_GREY, RPLALL_GUI_PANEL_BUTTONFLUFF_2), SetMinimalSize(75,12), SetResize(1,0), EndContainer(),
|
|
EndContainer(),
|
|
NWidget(NWID_HORIZONTAL),
|
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, RPLALL_GUI_BUTTON_APPLY), SetMinimalSize(75,12), SetResize(1,0), SetDataTip(STR_TMPL_RPLALLGUI_BUTTON_APPLY, STR_TMPL_RPLALLGUI_BUTTON_APPLY),
|
|
NWidget(WWT_PANEL, COLOUR_GREY, RPLALL_GUI_PANEL_BUTTONFLUFF_3), SetMinimalSize(150,12), SetResize(0,0), EndContainer(),
|
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, RPLALL_GUI_BUTTON_CANCEL), SetMinimalSize(75,12), SetResize(1,0), SetDataTip(STR_TMPL_RPLALLGUI_BUTTON_CANCEL, STR_TMPL_RPLALLGUI_BUTTON_CANCEL),
|
|
EndContainer(),
|
|
NWidget(NWID_HORIZONTAL),
|
|
NWidget(WWT_PANEL, COLOUR_GREY, RPLALL_GUI_PANEL_RESIZEFLUFF), SetMinimalSize(100,12), SetResize(1,0), EndContainer(),
|
|
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
|
|
EndContainer(),
|
|
};
|
|
|
|
static WindowDesc _template_replace_replaceall_desc(
|
|
WDP_AUTO,
|
|
"template replace window",
|
|
400, 200,
|
|
WC_TEMPLATEGUI_RPLALL, WC_NONE,
|
|
WDF_CONSTRUCTION,
|
|
widgets, lengthof(widgets)
|
|
);
|
|
|
|
static int CDECL EngineNumberSorter(const EngineID *a, const EngineID *b)
|
|
{
|
|
int r = Engine::Get(*a)->list_position - Engine::Get(*b)->list_position;
|
|
|
|
return r;
|
|
}
|
|
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 r;
|
|
}
|
|
|
|
|
|
class TemplateReplacementReplaceAllWindow : public Window {
|
|
private:
|
|
uint16 line_height;
|
|
Scrollbar *vscroll_tl,
|
|
*vscroll_tr,
|
|
*vscroll_bo;
|
|
GUIEngineList *engines_left,
|
|
*engines_right;
|
|
short selected_left,
|
|
selected_right;
|
|
VirtTrainList *virtualTrains;
|
|
|
|
public:
|
|
TemplateReplacementReplaceAllWindow(WindowDesc *wdesc) : Window(wdesc)
|
|
{
|
|
this->CreateNestedTree(wdesc != nullptr);
|
|
|
|
this->vscroll_tl = this->GetScrollbar(RPLALL_GUI_SCROLL_TL);
|
|
this->vscroll_tr = this->GetScrollbar(RPLALL_GUI_SCROLL_TR);
|
|
this->vscroll_bo = this->GetScrollbar(RPLALL_GUI_SCROLL_BO);
|
|
this->vscroll_tl->SetStepSize(16);
|
|
this->vscroll_tr->SetStepSize(16);
|
|
this->vscroll_bo->SetStepSize(16);
|
|
|
|
this->FinishInitNested(VEH_TRAIN);
|
|
|
|
this->owner = _local_company;
|
|
|
|
engines_left = new GUIEngineList();
|
|
engines_right = new GUIEngineList();
|
|
virtualTrains = new VirtTrainList();
|
|
|
|
this->GenerateBuyableEnginesList();
|
|
this->GenerateIncludedTemplateList();
|
|
|
|
this->line_height = 16;
|
|
this->selected_left = -1;
|
|
this->selected_right = -1;
|
|
}
|
|
|
|
~TemplateReplacementReplaceAllWindow()
|
|
{
|
|
for ( uint i=0; i<this->virtualTrains->Length(); ++i )
|
|
delete (*this->virtualTrains)[i]->vt;
|
|
SetWindowClassesDirty(WC_TEMPLATEGUI_MAIN);
|
|
}
|
|
|
|
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
|
{
|
|
switch ( widget ) {
|
|
case RPLALL_GUI_MATRIX_TOPLEFT:
|
|
case RPLALL_GUI_MATRIX_TOPRIGHT:
|
|
case RPLALL_GUI_MATRIX_BOTTOM: {
|
|
resize->height = 16;
|
|
size->height = 16;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual void OnPaint()
|
|
{
|
|
this->GetWidget<NWidgetCore>(RPLALL_GUI_PANEL_BUTTONFLUFF_3)->colour = _company_colours[_local_company];
|
|
|
|
this->DrawWidgets();
|
|
}
|
|
|
|
virtual void OnResize()
|
|
{
|
|
NWidgetCore *nwi_tl = this->GetWidget<NWidgetCore>(RPLALL_GUI_MATRIX_TOPLEFT);
|
|
this->vscroll_tl->SetCapacityFromWidget(this, RPLALL_GUI_MATRIX_TOPLEFT);
|
|
nwi_tl->widget_data = (this->vscroll_tl->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START);
|
|
|
|
NWidgetCore *nwi_tr = this->GetWidget<NWidgetCore>(RPLALL_GUI_MATRIX_TOPRIGHT);
|
|
this->vscroll_tr->SetCapacityFromWidget(this, RPLALL_GUI_MATRIX_TOPRIGHT);
|
|
nwi_tr->widget_data = (this->vscroll_tr->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START);
|
|
|
|
NWidgetCore *nwi_bo = this->GetWidget<NWidgetCore>(RPLALL_GUI_MATRIX_BOTTOM);
|
|
this->vscroll_bo->SetCapacityFromWidget(this, RPLALL_GUI_MATRIX_BOTTOM);
|
|
nwi_bo->widget_data = (this->vscroll_bo->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START);
|
|
}
|
|
|
|
virtual void DrawWidget(const Rect &r, int widget) const
|
|
{
|
|
switch (widget) {
|
|
case RPLALL_GUI_MATRIX_TOPLEFT: {
|
|
this->DrawEngineList(r, true);
|
|
break;
|
|
}
|
|
case RPLALL_GUI_MATRIX_TOPRIGHT: {
|
|
this->DrawEngineList(r, false);
|
|
break;
|
|
}
|
|
case RPLALL_GUI_MATRIX_BOTTOM: {
|
|
this->DrawVirtualTrains(r);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual void OnClick(Point pt, int widget, int click_count)
|
|
{
|
|
switch(widget) {
|
|
case RPLALL_GUI_MATRIX_TOPLEFT: {
|
|
uint16 newindex = (uint16)((pt.y - this->nested_array[RPLALL_GUI_MATRIX_TOPLEFT]->pos_y) / this->line_height) + this->vscroll_tl->GetPosition();
|
|
if ( newindex >= this->engines_left->Length() || newindex==this->selected_left )
|
|
this->selected_left = -1;
|
|
else
|
|
this->selected_left = newindex;
|
|
this->SetDirty();
|
|
break;
|
|
}
|
|
case RPLALL_GUI_MATRIX_TOPRIGHT: {
|
|
uint16 newindex = (uint16)((pt.y - this->nested_array[RPLALL_GUI_MATRIX_TOPRIGHT]->pos_y) / this->line_height) + this->vscroll_tr->GetPosition();
|
|
if ( newindex > this->engines_right->Length() || newindex==this->selected_right )
|
|
this->selected_right = -1;
|
|
else
|
|
this->selected_right = newindex;
|
|
this->SetDirty();
|
|
break;
|
|
}
|
|
case RPLALL_GUI_BUTTON_RPLALL: {
|
|
this->ReplaceAll();
|
|
break;
|
|
}
|
|
case RPLALL_GUI_BUTTON_APPLY: {
|
|
// check if we actually did anything so far, if not, applying is forbidden
|
|
if ( this->virtualTrains->Length() == 0 )
|
|
return;
|
|
// first delete all current templates
|
|
this->DeleteAllTemplateTrains();
|
|
// then build a new list from the current virtual trains
|
|
for ( uint i=0; i<this->virtualTrains->Length(); ++i ) {
|
|
// the relevant info struct
|
|
VirtTrainInfo *vti = (*this->virtualTrains)[i];
|
|
// setup template from contained train
|
|
Train *t = vti->vt;
|
|
TemplateVehicle *tv = TemplateVehicleFromVirtualTrain(t);
|
|
// restore template specific stuff
|
|
tv->reuse_depot_vehicles = vti->reuse_depot_vehicles;
|
|
tv->keep_remaining_vehicles = vti->keep_remaining_vehicles;
|
|
tv->refit_as_template = vti->refit_as_template;
|
|
tv->cargo_type = vti->cargo_type;
|
|
tv->cargo_subtype = vti->cargo_subtype;
|
|
// use the original_index information to repoint the relevant TemplateReplacement if existing
|
|
TemplateReplacement *tr = GetTemplateReplacementByTemplateID(vti->original_index);
|
|
if ( tr )
|
|
tr->sel_template = tv->index;
|
|
}
|
|
// then close this window and return to parent
|
|
delete this;
|
|
break;
|
|
}
|
|
case RPLALL_GUI_BUTTON_CANCEL: {
|
|
delete this;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool HasTemplateWithEngine(EngineID eid) const
|
|
{
|
|
const TemplateVehicle *tv;
|
|
FOR_ALL_TEMPLATES(tv) {
|
|
if ( tv->Prev() || tv->owner != _local_company ) continue;
|
|
for ( const TemplateVehicle *tmp=tv; tmp; tmp=tmp->GetNextUnit() ) {
|
|
if ( tmp->engine_type == eid )
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void GenerateVirtualTrains()
|
|
{
|
|
this->virtualTrains->Clear();
|
|
|
|
TemplateVehicle *tv;
|
|
FOR_ALL_TEMPLATES(tv) {
|
|
if ( !tv->Prev() && tv->owner==this->owner ) {
|
|
// setup template train
|
|
Train *newtrain = VirtualTrainFromTemplateVehicle(tv);
|
|
VirtTrainInfo *vti = new VirtTrainInfo(newtrain);
|
|
// store template specific stuff
|
|
vti->original_index = tv->index;
|
|
vti->reuse_depot_vehicles = tv->reuse_depot_vehicles;
|
|
vti->keep_remaining_vehicles = tv->keep_remaining_vehicles;
|
|
vti->refit_as_template = tv->refit_as_template;
|
|
vti->cargo_type = tv->cargo_type;
|
|
vti->cargo_subtype = tv->cargo_subtype;
|
|
// add new info struct
|
|
*this->virtualTrains->Append() = vti;
|
|
}
|
|
}
|
|
|
|
this->vscroll_bo->SetCount(this->virtualTrains->Length());
|
|
}
|
|
|
|
void DeleteAllTemplateTrains()
|
|
{
|
|
TemplateVehicle *tv, *tmp;
|
|
FOR_ALL_TEMPLATES(tv) {
|
|
tmp = tv;
|
|
if ( tmp->Prev()==0 && tmp->owner==this->owner )
|
|
delete tmp;
|
|
}
|
|
}
|
|
|
|
void GenerateIncludedTemplateList()
|
|
{
|
|
int num_engines = 0;
|
|
int num_wagons = 0;
|
|
|
|
this->engines_left->Clear();
|
|
|
|
const Engine *e;
|
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
|
|
EngineID eid = e->index;
|
|
const RailVehicleInfo*rvi = &e->u.rail;
|
|
|
|
if ( !HasTemplateWithEngine(eid) ) continue;
|
|
|
|
*this->engines_left->Append() = eid;
|
|
|
|
if (rvi->railveh_type != RAILVEH_WAGON) {
|
|
num_engines++;
|
|
} else {
|
|
num_wagons++;
|
|
}
|
|
}
|
|
this->vscroll_tl->SetCount(this->engines_left->Length());
|
|
}
|
|
|
|
bool VirtualTrainHasEngineID(EngineID eid)
|
|
{
|
|
|
|
for ( uint i=0; i<this->virtualTrains->Length(); ++i ) {
|
|
const Train *tmp = (*this->virtualTrains)[i]->vt;
|
|
for ( ; tmp; tmp=tmp->Next() )
|
|
if ( tmp->engine_type == eid )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// after 'replace all' we need to replace the currently used templates as well
|
|
void RebuildIncludedTemplateList() {
|
|
// first remove all engine ids
|
|
for ( uint i=0; i<this->engines_left->Length(); ++i ) {
|
|
EngineID entry = (*this->engines_left)[i];
|
|
if ( !VirtualTrainHasEngineID(entry) )
|
|
this->engines_left->Erase(&((*this->engines_left)[i]));
|
|
}
|
|
}
|
|
|
|
void ReplaceAll()
|
|
{
|
|
|
|
if ( this->selected_left==-1 || this->selected_right==-1 )
|
|
return;
|
|
|
|
EngineID eid_orig = (*this->engines_left)[this->selected_left];
|
|
EngineID eid_repl = (*this->engines_right)[this->selected_right];
|
|
|
|
if ( eid_orig == eid_repl )
|
|
return;
|
|
|
|
if ( this->virtualTrains->Length() == 0 )
|
|
this->GenerateVirtualTrains();
|
|
|
|
for ( uint i=0; i<this->virtualTrains->Length(); ++i ) {
|
|
Train *tmp = (*this->virtualTrains)[i]->vt;
|
|
while ( tmp ) {
|
|
if ( tmp->engine_type == eid_orig ) {
|
|
// build a new virtual rail vehicle and test for success
|
|
Train *nt = CmdBuildVirtualRailVehicle(eid_repl);
|
|
if ( !nt ) continue;
|
|
// include the (probably) new engine into the 'included'-list
|
|
this->engines_left->Include( nt->engine_type );
|
|
// advance the tmp pointer in the chain, otherwise it would get deleted later on
|
|
Train *to_del = tmp;
|
|
tmp = tmp->GetNextUnit();
|
|
// first move the new virtual rail vehicle behind to_del
|
|
CommandCost move = CmdMoveRailVehicle(INVALID_TILE, DC_EXEC, nt->index|(1<<21), to_del->index, 0);
|
|
// then move to_del away from the chain and delete it
|
|
move = CmdMoveRailVehicle(INVALID_TILE, DC_EXEC, to_del->index|(1<<21), INVALID_VEHICLE, 0);
|
|
(*this->virtualTrains)[i]->vt = nt->First();
|
|
delete to_del;
|
|
} else {
|
|
tmp = tmp->GetNextUnit();
|
|
}
|
|
}
|
|
}
|
|
this->selected_left = -1;
|
|
// rebuild the left engines list as some engines might not be there anymore
|
|
this->RebuildIncludedTemplateList();
|
|
this->SetDirty();
|
|
}
|
|
|
|
void GenerateBuyableEnginesList()
|
|
{
|
|
int num_engines = 0;
|
|
int num_wagons = 0;
|
|
|
|
this->engines_right->Clear();
|
|
|
|
const Engine *e;
|
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
|
|
EngineID eid = e->index;
|
|
const RailVehicleInfo *rvi = &e->u.rail;
|
|
|
|
if (!IsEngineBuildable(eid, VEH_TRAIN, _local_company)) continue;
|
|
|
|
*this->engines_right->Append() = eid;
|
|
|
|
if (rvi->railveh_type != RAILVEH_WAGON) {
|
|
num_engines++;
|
|
} else {
|
|
num_wagons++;
|
|
}
|
|
}
|
|
|
|
/* make engines first, and then wagons, sorted by ListPositionOfEngine() */
|
|
EngList_Sort(this->engines_right, TrainEnginesThenWagonsSorter);
|
|
|
|
this->vscroll_tr->SetCount(this->engines_right->Length());
|
|
}
|
|
|
|
void DrawEngineList(const Rect &r, bool left) const//, GUIEngineList el, Scrollbar* sb) const
|
|
{
|
|
uint16 y = r.top;
|
|
uint32 eid;
|
|
|
|
Scrollbar *sb;
|
|
const GUIEngineList *el;
|
|
|
|
if ( left ) {
|
|
sb = this->vscroll_tl;
|
|
el = this->engines_left;
|
|
} else {
|
|
sb = this->vscroll_tr;
|
|
el = this->engines_right;
|
|
}
|
|
|
|
int maximum = min((int)sb->GetCapacity(), (int)el->Length()) + sb->GetPosition();
|
|
|
|
for ( int i=sb->GetPosition(); i<maximum; ++i ) {
|
|
|
|
eid = (*el)[i];
|
|
|
|
/* Draw a grey background rectangle if the current line is the selected one */
|
|
if ( (left && this->selected_left == i) || (!left && this->selected_right == i) )
|
|
GfxFillRect(r.left, y, r.right, y+this->line_height, _colour_gradient[COLOUR_GREY][3]);
|
|
|
|
/* Draw a description string of the current engine */
|
|
SetDParam(0, eid);
|
|
DrawString(r.left+100, r.right, y+4, STR_ENGINE_NAME, TC_BLACK);
|
|
|
|
/* Draw the engine */
|
|
DrawVehicleEngine( r.left, r.right, r.left+29, y+8, eid, GetEnginePalette(eid, _local_company), EIT_PURCHASE );
|
|
|
|
y += this->line_height;
|
|
}
|
|
}
|
|
|
|
void DrawVirtualTrains(const Rect &r) const
|
|
{
|
|
uint16 y = r.top;
|
|
|
|
uint16 max = min(virtualTrains->Length(), this->vscroll_bo->GetCapacity());
|
|
|
|
for ( uint16 i=vscroll_bo->GetPosition(); i<max+vscroll_bo->GetPosition(); ++i ) {
|
|
/* Draw a virtual train*/
|
|
DrawTrainImage( (*this->virtualTrains)[i]->vt, r.left+32, r.right, y, INVALID_VEHICLE, EIT_PURCHASE, 0, -1 );
|
|
|
|
y+= this->line_height;
|
|
}
|
|
}
|
|
};
|
|
|
|
void ShowTemplateReplaceAllGui()
|
|
{
|
|
new TemplateReplacementReplaceAllWindow(&_template_replace_replaceall_desc);
|
|
}
|