src/autoreplace_gui.cpp
branchNewGRF_ports
changeset 10991 d8811e327d12
parent 10731 67db0d431d5e
equal deleted inserted replaced
10731:67db0d431d5e 10991:d8811e327d12
    20 #include "player_func.h"
    20 #include "player_func.h"
    21 #include "widgets/dropdown_func.h"
    21 #include "widgets/dropdown_func.h"
    22 #include "engine_func.h"
    22 #include "engine_func.h"
    23 #include "engine_base.h"
    23 #include "engine_base.h"
    24 #include "window_gui.h"
    24 #include "window_gui.h"
       
    25 #include "engine_gui.h"
    25 
    26 
    26 #include "table/sprites.h"
    27 #include "table/sprites.h"
    27 #include "table/strings.h"
    28 #include "table/strings.h"
    28 
    29 
    29 void DrawEngineList(VehicleType type, int x, int y, const EngineList eng_list, uint16 min, uint16 max, EngineID selected_id, int count_location, GroupID selected_group);
    30 void DrawEngineList(VehicleType type, int x, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, int count_location, GroupID selected_group);
    30 
    31 
    31 static const StringID _rail_types_list[] = {
    32 static const StringID _rail_types_list[] = {
    32 	STR_RAIL_VEHICLES,
    33 	STR_RAIL_VEHICLES,
    33 	STR_ELRAIL_VEHICLES,
    34 	STR_ELRAIL_VEHICLES,
    34 	STR_MONORAIL_VEHICLES,
    35 	STR_MONORAIL_VEHICLES,
   140 class ReplaceVehicleWindow : public Window {
   141 class ReplaceVehicleWindow : public Window {
   141 	byte sel_index[2];
   142 	byte sel_index[2];
   142 	EngineID sel_engine[2];
   143 	EngineID sel_engine[2];
   143 	uint16 count[2];
   144 	uint16 count[2];
   144 	bool wagon_btnstate; ///< true means engine is selected
   145 	bool wagon_btnstate; ///< true means engine is selected
   145 	EngineList list[2];
   146 	GUIEngineList list[2];
   146 	bool update_left;
   147 	bool update_left;
   147 	bool update_right;
   148 	bool update_right;
   148 	bool init_lists;
   149 	bool init_lists;
   149 	GroupID sel_group;
   150 	GroupID sel_group;
   150 	static RailType sel_railtype;
   151 	static RailType sel_railtype;
   182 	{
   183 	{
   183 		EngineID selected_engine = INVALID_ENGINE;
   184 		EngineID selected_engine = INVALID_ENGINE;
   184 		VehicleType type = (VehicleType)this->window_number;
   185 		VehicleType type = (VehicleType)this->window_number;
   185 		byte i = draw_left ? 0 : 1;
   186 		byte i = draw_left ? 0 : 1;
   186 
   187 
   187 		EngineList *list = &this->list[i];
   188 		GUIEngineList *list = &this->list[i];
   188 		list->clear();
   189 		list->Clear();
   189 
   190 
   190 		const Engine *e;
   191 		const Engine *e;
   191 		FOR_ALL_ENGINES_OF_TYPE(e, type) {
   192 		FOR_ALL_ENGINES_OF_TYPE(e, type) {
   192 			EngineID eid = e->index;
   193 			EngineID eid = e->index;
   193 			if (type == VEH_TRAIN && !GenerateReplaceRailList(eid, draw_left, this->wagon_btnstate)) continue; // special rules for trains
   194 			if (type == VEH_TRAIN && !GenerateReplaceRailList(eid, draw_left, this->wagon_btnstate)) continue; // special rules for trains
   206 				/* Road vehicles can't be replaced by trams and vice-versa */
   207 				/* Road vehicles can't be replaced by trams and vice-versa */
   207 				if (type == VEH_ROAD && HasBit(EngInfo(this->sel_engine[0])->misc_flags, EF_ROAD_TRAM) != HasBit(e->info.misc_flags, EF_ROAD_TRAM)) continue;
   208 				if (type == VEH_ROAD && HasBit(EngInfo(this->sel_engine[0])->misc_flags, EF_ROAD_TRAM) != HasBit(e->info.misc_flags, EF_ROAD_TRAM)) continue;
   208 				if (eid == this->sel_engine[0]) continue; // we can't replace an engine into itself (that would be autorenew)
   209 				if (eid == this->sel_engine[0]) continue; // we can't replace an engine into itself (that would be autorenew)
   209 			}
   210 			}
   210 
   211 
   211 			list->push_back(eid);
   212 			*list->Append() = eid;
   212 			if (eid == this->sel_engine[i]) selected_engine = eid; // The selected engine is still in the list
   213 			if (eid == this->sel_engine[i]) selected_engine = eid; // The selected engine is still in the list
   213 		}
   214 		}
   214 		this->sel_engine[i] = selected_engine; // update which engine we selected (the same or none, if it's not in the list anymore)
   215 		this->sel_engine[i] = selected_engine; // update which engine we selected (the same or none, if it's not in the list anymore)
   215 		if (type == VEH_TRAIN) EngList_Sort(list, &TrainEngineNumberSorter);
   216 		if (type == VEH_TRAIN) EngList_Sort(list, &TrainEngineNumberSorter);
   216 	}
   217 	}
   221 		EngineID e = this->sel_engine[0];
   222 		EngineID e = this->sel_engine[0];
   222 
   223 
   223 		if (this->update_left == true) {
   224 		if (this->update_left == true) {
   224 			/* We need to rebuild the left list */
   225 			/* We need to rebuild the left list */
   225 			GenerateReplaceVehList(this, true);
   226 			GenerateReplaceVehList(this, true);
   226 			SetVScrollCount(this, this->list[0].size());
   227 			SetVScrollCount(this, this->list[0].Length());
   227 			if (this->init_lists && this->sel_engine[0] == INVALID_ENGINE && this->list[0].size() != 0) {
   228 			if (this->init_lists && this->sel_engine[0] == INVALID_ENGINE && this->list[0].Length() != 0) {
   228 				this->sel_engine[0] = this->list[0][0];
   229 				this->sel_engine[0] = this->list[0][0];
   229 			}
   230 			}
   230 		}
   231 		}
   231 
   232 
   232 		if (this->update_right || e != this->sel_engine[0]) {
   233 		if (this->update_right || e != this->sel_engine[0]) {
   233 			/* Either we got a request to rebuild the right list or the left list selected a different engine */
   234 			/* Either we got a request to rebuild the right list or the left list selected a different engine */
   234 			if (this->sel_engine[0] == INVALID_ENGINE) {
   235 			if (this->sel_engine[0] == INVALID_ENGINE) {
   235 				/* Always empty the right list when nothing is selected in the left list */
   236 				/* Always empty the right list when nothing is selected in the left list */
   236 				this->list[1].clear();
   237 				this->list[1].Clear();
   237 				this->sel_engine[1] = INVALID_ENGINE;
   238 				this->sel_engine[1] = INVALID_ENGINE;
   238 			} else {
   239 			} else {
   239 				GenerateReplaceVehList(this, false);
   240 				GenerateReplaceVehList(this, false);
   240 				SetVScroll2Count(this, this->list[1].size());
   241 				SetVScroll2Count(this, this->list[1].Length());
   241 				if (this->init_lists && this->sel_engine[1] == INVALID_ENGINE && this->list[1].size() != 0) {
   242 				if (this->init_lists && this->sel_engine[1] == INVALID_ENGINE && this->list[1].Length() != 0) {
   242 					this->sel_engine[1] = this->list[1][0];
   243 					this->sel_engine[1] = this->list[1][0];
   243 				}
   244 				}
   244 			}
   245 			}
   245 		}
   246 		}
   246 		/* Reset the flags about needed updates */
   247 		/* Reset the flags about needed updates */
   251 
   252 
   252 public:
   253 public:
   253 	ReplaceVehicleWindow(const WindowDesc *desc, VehicleType vehicletype, GroupID id_g) : Window(desc, vehicletype)
   254 	ReplaceVehicleWindow(const WindowDesc *desc, VehicleType vehicletype, GroupID id_g) : Window(desc, vehicletype)
   254 	{
   255 	{
   255 		this->wagon_btnstate = true; // start with locomotives (all other vehicles will not read this bool)
   256 		this->wagon_btnstate = true; // start with locomotives (all other vehicles will not read this bool)
   256 		new (&this->list[0]) EngineList();
       
   257 		new (&this->list[1]) EngineList();
       
   258 		this->update_left   = true;
   257 		this->update_left   = true;
   259 		this->update_right  = true;
   258 		this->update_right  = true;
   260 		this->init_lists    = true;
   259 		this->init_lists    = true;
   261 		this->sel_engine[0] = INVALID_ENGINE;
   260 		this->sel_engine[0] = INVALID_ENGINE;
   262 		this->sel_engine[1] = INVALID_ENGINE;
   261 		this->sel_engine[1] = INVALID_ENGINE;
   378 		DrawString(145, this->widget[RVW_WIDGET_INFO_TAB].top + 1, STR_02BD, TC_BLACK);
   377 		DrawString(145, this->widget[RVW_WIDGET_INFO_TAB].top + 1, STR_02BD, TC_BLACK);
   379 
   378 
   380 		/* Draw the lists */
   379 		/* Draw the lists */
   381 		for (byte i = 0; i < 2; i++) {
   380 		for (byte i = 0; i < 2; i++) {
   382 			uint widget     = (i == 0) ? RVW_WIDGET_LEFT_MATRIX : RVW_WIDGET_RIGHT_MATRIX;
   381 			uint widget     = (i == 0) ? RVW_WIDGET_LEFT_MATRIX : RVW_WIDGET_RIGHT_MATRIX;
   383 			EngineList list = this->list[i]; // which list to draw
   382 			GUIEngineList *list = &this->list[i]; // which list to draw
   384 			EngineID start  = i == 0 ? this->vscroll.pos : this->vscroll2.pos; // what is the offset for the start (scrolling)
   383 			EngineID start  = i == 0 ? this->vscroll.pos : this->vscroll2.pos; // what is the offset for the start (scrolling)
   385 			EngineID end    = min((i == 0 ? this->vscroll.cap : this->vscroll2.cap) + start, list.size());
   384 			EngineID end    = min((i == 0 ? this->vscroll.cap : this->vscroll2.cap) + start, list->Length());
   386 
   385 
   387 			/* Do the actual drawing */
   386 			/* Do the actual drawing */
   388 			DrawEngineList((VehicleType)this->window_number, this->widget[widget].left + 2, this->widget[widget].top + 1, list, start, end, this->sel_engine[i], i == 0 ? this->widget[RVW_WIDGET_LEFT_MATRIX].right - 2 : 0, selected_group);
   387 			DrawEngineList((VehicleType)this->window_number, this->widget[widget].left + 2, this->widget[widget].top + 1, list, start, end, this->sel_engine[i], i == 0 ? this->widget[RVW_WIDGET_LEFT_MATRIX].right - 2 : 0, selected_group);
   389 
   388 
   390 			/* Also draw the details if an engine is selected */
   389 			/* Also draw the details if an engine is selected */
   434 			case RVW_WIDGET_RIGHT_MATRIX: {
   433 			case RVW_WIDGET_RIGHT_MATRIX: {
   435 				uint i = (pt.y - 14) / this->resize.step_height;
   434 				uint i = (pt.y - 14) / this->resize.step_height;
   436 				uint16 click_scroll_pos = widget == RVW_WIDGET_LEFT_MATRIX ? this->vscroll.pos : this->vscroll2.pos;
   435 				uint16 click_scroll_pos = widget == RVW_WIDGET_LEFT_MATRIX ? this->vscroll.pos : this->vscroll2.pos;
   437 				uint16 click_scroll_cap = widget == RVW_WIDGET_LEFT_MATRIX ? this->vscroll.cap : this->vscroll2.cap;
   436 				uint16 click_scroll_cap = widget == RVW_WIDGET_LEFT_MATRIX ? this->vscroll.cap : this->vscroll2.cap;
   438 				byte click_side         = widget == RVW_WIDGET_LEFT_MATRIX ? 0 : 1;
   437 				byte click_side         = widget == RVW_WIDGET_LEFT_MATRIX ? 0 : 1;
   439 				size_t engine_count     = this->list[click_side].size();
   438 				size_t engine_count     = this->list[click_side].Length();
   440 
   439 
   441 				if (i < click_scroll_cap) {
   440 				if (i < click_scroll_cap) {
   442 					i += click_scroll_pos;
   441 					i += click_scroll_pos;
   443 					EngineID e = engine_count > i ? this->list[click_side][i] : INVALID_ENGINE;
   442 					EngineID e = engine_count > i ? this->list[click_side][i] : INVALID_ENGINE;
   444 					if (e == this->sel_engine[click_side]) break; // we clicked the one we already selected
   443 					if (e == this->sel_engine[click_side]) break; // we clicked the one we already selected