src/depot_gui.cpp
changeset 9351 ecf2fdeb2328
parent 9344 d3b1b1fbbad9
child 9396 3f70b1b8642c
equal deleted inserted replaced
9350:922f99fb3da4 9351:ecf2fdeb2328
   129 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
   129 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
   130 	_depot_widgets,
   130 	_depot_widgets,
   131 };
   131 };
   132 
   132 
   133 extern int WagonLengthToPixels(int len);
   133 extern int WagonLengthToPixels(int len);
   134 extern void DepotSortList(Vehicle **v, uint16 length);
   134 extern void DepotSortList(VehicleList *list);
   135 
   135 
   136 /**
   136 /**
   137  * This is the Callback method after the cloning attempt of a vehicle
   137  * This is the Callback method after the cloning attempt of a vehicle
   138  * @param success indicates completion (or not) of the operation
   138  * @param success indicates completion (or not) of the operation
   139  * @param tile unused
   139  * @param tile unused
   238 
   238 
   239 struct DepotWindow : Window {
   239 struct DepotWindow : Window {
   240 	VehicleID sel;
   240 	VehicleID sel;
   241 	VehicleType type;
   241 	VehicleType type;
   242 	bool generate_list;
   242 	bool generate_list;
   243 	uint16 engine_list_length;
   243 	VehicleList vehicle_list;
   244 	uint16 wagon_list_length;
   244 	VehicleList wagon_list;
   245 	uint16 engine_count;
       
   246 	uint16 wagon_count;
       
   247 	Vehicle **vehicle_list;
       
   248 	Vehicle **wagon_list;
       
   249 
   245 
   250 	DepotWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
   246 	DepotWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
   251 	{
   247 	{
   252 		this->sel = INVALID_VEHICLE;
   248 		this->sel = INVALID_VEHICLE;
   253 		this->vehicle_list  = NULL;
       
   254 		this->wagon_list    = NULL;
       
   255 		this->engine_count  = 0;
       
   256 		this->wagon_count   = 0;
       
   257 		this->generate_list = true;
   249 		this->generate_list = true;
   258 
   250 
   259 		this->FindWindowPlacementAndResize(desc);
   251 		this->FindWindowPlacementAndResize(desc);
   260 	}
   252 	}
   261 
   253 
   262 	~DepotWindow()
   254 	~DepotWindow()
   263 	{
   255 	{
   264 		DeleteWindowById(WC_BUILD_VEHICLE, this->window_number);
   256 		DeleteWindowById(WC_BUILD_VEHICLE, this->window_number);
   265 		free((void*)this->vehicle_list);
       
   266 		free((void*)this->wagon_list);
       
   267 	}
   257 	}
   268 
   258 
   269 	/** Draw a vehicle in the depot window in the box with the top left corner at x,y
   259 	/** Draw a vehicle in the depot window in the box with the top left corner at x,y
   270 	* @param *w Window to draw in
   260 	* @param *w Window to draw in
   271 	* @param *v Vehicle to draw
   261 	* @param *v Vehicle to draw
   312 		DrawString(x, y + 2, (uint16)(v->max_age - 366) >= v->age ? STR_00E2 : STR_00E3, TC_FROMSTRING);
   302 		DrawString(x, y + 2, (uint16)(v->max_age - 366) >= v->age ? STR_00E2 : STR_00E3, TC_FROMSTRING);
   313 	}
   303 	}
   314 
   304 
   315 	void DrawDepotWindow(Window *w)
   305 	void DrawDepotWindow(Window *w)
   316 	{
   306 	{
   317 		Vehicle **vl = this->vehicle_list;
       
   318 		TileIndex tile = this->window_number;
   307 		TileIndex tile = this->window_number;
   319 		int x, y, i, maxval;
   308 		int x, y, i, maxval;
   320 		uint16 hnum;
   309 		uint16 hnum;
   321 		uint16 num = this->engine_count;
       
   322 
   310 
   323 		/* Set the row and number of boxes in each row based on the number of boxes drawn in the matrix */
   311 		/* Set the row and number of boxes in each row based on the number of boxes drawn in the matrix */
   324 		uint16 rows_in_display   = this->widget[DEPOT_WIDGET_MATRIX].data >> 8;
   312 		uint16 rows_in_display   = this->widget[DEPOT_WIDGET_MATRIX].data >> 8;
   325 		uint16 boxes_in_each_row = this->widget[DEPOT_WIDGET_MATRIX].data & 0xFF;
   313 		uint16 boxes_in_each_row = this->widget[DEPOT_WIDGET_MATRIX].data & 0xFF;
   326 
   314 
   337 			WIDGET_LIST_END);
   325 			WIDGET_LIST_END);
   338 
   326 
   339 		/* determine amount of items for scroller */
   327 		/* determine amount of items for scroller */
   340 		if (this->type == VEH_TRAIN) {
   328 		if (this->type == VEH_TRAIN) {
   341 			hnum = 8;
   329 			hnum = 8;
   342 			for (num = 0; num < this->engine_count; num++) {
   330 			for (uint num = 0; num < this->vehicle_list.Length(); num++) {
   343 				const Vehicle *v = vl[num];
   331 				const Vehicle *v = this->vehicle_list[num];
   344 				hnum = max(hnum, v->u.rail.cached_total_length);
   332 				hnum = max(hnum, v->u.rail.cached_total_length);
   345 			}
   333 			}
   346 			/* Always have 1 empty row, so people can change the setting of the train */
   334 			/* Always have 1 empty row, so people can change the setting of the train */
   347 			SetVScrollCount(w, this->engine_count + this->wagon_count + 1);
   335 			SetVScrollCount(w, this->vehicle_list.Length() + this->wagon_list.Length() + 1);
   348 			SetHScrollCount(w, WagonLengthToPixels(hnum));
   336 			SetHScrollCount(w, WagonLengthToPixels(hnum));
   349 		} else {
   337 		} else {
   350 			SetVScrollCount(w, (num + this->hscroll.cap - 1) / this->hscroll.cap);
   338 			SetVScrollCount(w, (this->vehicle_list.Length() + this->hscroll.cap - 1) / this->hscroll.cap);
   351 		}
   339 		}
   352 
   340 
   353 		/* locate the depot struct */
   341 		/* locate the depot struct */
   354 		if (this->type == VEH_AIRCRAFT) {
   342 		if (this->type == VEH_AIRCRAFT) {
   355 			SetDParam(0, GetStationIndex(tile)); // Airport name
   343 			SetDParam(0, GetStationIndex(tile)); // Airport name
   360 			SetDParam(0, depot->town_index);
   348 			SetDParam(0, depot->town_index);
   361 		}
   349 		}
   362 
   350 
   363 		w->DrawWidgets();
   351 		w->DrawWidgets();
   364 
   352 
   365 		num = this->vscroll.pos * boxes_in_each_row;
   353 		uint16 num = this->vscroll.pos * boxes_in_each_row;
   366 		maxval = min(this->engine_count, num + (rows_in_display * boxes_in_each_row));
   354 		maxval = min(this->vehicle_list.Length(), num + (rows_in_display * boxes_in_each_row));
   367 
   355 
   368 		for (x = 2, y = 15; num < maxval; y += this->resize.step_height, x = 2) { // Draw the rows
   356 		for (x = 2, y = 15; num < maxval; y += this->resize.step_height, x = 2) { // Draw the rows
   369 			byte i;
   357 			byte i;
   370 
   358 
   371 			for (i = 0; i < boxes_in_each_row && num < maxval; i++, num++, x += this->resize.step_width) {
   359 			for (i = 0; i < boxes_in_each_row && num < maxval; i++, num++, x += this->resize.step_width) {
   372 				/* Draw all vehicles in the current row */
   360 				/* Draw all vehicles in the current row */
   373 				const Vehicle *v = vl[num];
   361 				const Vehicle *v = this->vehicle_list[num];
   374 				DrawVehicleInDepot(w, v, x, y);
   362 				DrawVehicleInDepot(w, v, x, y);
   375 			}
   363 			}
   376 		}
   364 		}
   377 
   365 
   378 		maxval = min(this->engine_count + this->wagon_count, (this->vscroll.pos * boxes_in_each_row) + (rows_in_display * boxes_in_each_row));
   366 		maxval = min(this->vehicle_list.Length() + this->wagon_list.Length(), (this->vscroll.pos * boxes_in_each_row) + (rows_in_display * boxes_in_each_row));
   379 
   367 
   380 		/* draw the train wagons, that do not have an engine in front */
   368 		/* draw the train wagons, that do not have an engine in front */
   381 		for (; num < maxval; num++, y += 14) {
   369 		for (; num < maxval; num++, y += 14) {
   382 			const Vehicle *v = this->wagon_list[num - this->engine_count];
   370 			const Vehicle *v = this->wagon_list[num - this->vehicle_list.Length()];
   383 			const Vehicle *u;
   371 			const Vehicle *u;
   384 
   372 
   385 			DrawTrainImage(v, x + 50, y, this->sel, this->hscroll.cap - 29, 0);
   373 			DrawTrainImage(v, x + 50, y, this->sel, this->hscroll.cap - 29, 0);
   386 			DrawString(x, y + 2, STR_8816, TC_FROMSTRING);
   374 			DrawString(x, y + 2, STR_8816, TC_FROMSTRING);
   387 
   375 
   406 		MODE_START_STOP,
   394 		MODE_START_STOP,
   407 	};
   395 	};
   408 
   396 
   409 	DepotGUIAction GetVehicleFromDepotWndPt(int x, int y, const Vehicle **veh, GetDepotVehiclePtData *d) const
   397 	DepotGUIAction GetVehicleFromDepotWndPt(int x, int y, const Vehicle **veh, GetDepotVehiclePtData *d) const
   410 	{
   398 	{
   411 		Vehicle **vl = this->vehicle_list;
       
   412 		uint xt, row, xm = 0, ym = 0;
   399 		uint xt, row, xm = 0, ym = 0;
   413 		int pos, skip = 0;
   400 		int pos, skip = 0;
   414 		uint16 boxes_in_each_row = this->widget[DEPOT_WIDGET_MATRIX].data & 0xFF;
   401 		uint16 boxes_in_each_row = this->widget[DEPOT_WIDGET_MATRIX].data & 0xFF;
   415 
   402 
   416 		if (this->type == VEH_TRAIN) {
   403 		if (this->type == VEH_TRAIN) {
   427 		row = (y - 14) / this->resize.step_height;
   414 		row = (y - 14) / this->resize.step_height;
   428 		if (row >= this->vscroll.cap) return MODE_ERROR;
   415 		if (row >= this->vscroll.cap) return MODE_ERROR;
   429 
   416 
   430 		pos = ((row + this->vscroll.pos) * boxes_in_each_row) + xt;
   417 		pos = ((row + this->vscroll.pos) * boxes_in_each_row) + xt;
   431 
   418 
   432 		if (this->engine_count + this->wagon_count <= pos) {
   419 		if ((int)(this->vehicle_list.Length() + this->wagon_list.Length()) <= pos) {
   433 			if (this->type == VEH_TRAIN) {
   420 			if (this->type == VEH_TRAIN) {
   434 				d->head  = NULL;
   421 				d->head  = NULL;
   435 				d->wagon = NULL;
   422 				d->wagon = NULL;
   436 				return MODE_DRAG_VEHICLE;
   423 				return MODE_DRAG_VEHICLE;
   437 			} else {
   424 			} else {
   438 				return MODE_ERROR; // empty block, so no vehicle is selected
   425 				return MODE_ERROR; // empty block, so no vehicle is selected
   439 			}
   426 			}
   440 		}
   427 		}
   441 
   428 
   442 		if (this->engine_count > pos) {
   429 		if ((int)this->vehicle_list.Length() > pos) {
   443 			*veh = vl[pos];
   430 			*veh = this->vehicle_list[pos];
   444 			skip = this->hscroll.pos;
   431 			skip = this->hscroll.pos;
   445 		} else {
   432 		} else {
   446 			vl = this->wagon_list;
   433 			pos -= this->vehicle_list.Length();
   447 			pos -= this->engine_count;
   434 			*veh = this->wagon_list[pos];
   448 			*veh = vl[pos];
       
   449 			/* free wagons don't have an initial loco. */
   435 			/* free wagons don't have an initial loco. */
   450 			x -= _traininfo_vehicle_width;
   436 			x -= _traininfo_vehicle_width;
   451 		}
   437 		}
   452 
   438 
   453 		switch (this->type) {
   439 		switch (this->type) {
   757 	virtual void OnPaint()
   743 	virtual void OnPaint()
   758 	{
   744 	{
   759 		if (this->generate_list) {
   745 		if (this->generate_list) {
   760 			/* Generate the vehicle list
   746 			/* Generate the vehicle list
   761 			 * It's ok to use the wagon pointers for non-trains as they will be ignored */
   747 			 * It's ok to use the wagon pointers for non-trains as they will be ignored */
   762 			BuildDepotVehicleList(this->type, this->window_number,
   748 			BuildDepotVehicleList(this->type, this->window_number, &this->vehicle_list, &this->wagon_list);
   763 				&this->vehicle_list, &this->engine_list_length, &this->engine_count,
       
   764 				&this->wagon_list,   &this->wagon_list_length,  &this->wagon_count);
       
   765 			this->generate_list = false;
   749 			this->generate_list = false;
   766 			DepotSortList(this->vehicle_list, this->engine_count);
   750 			DepotSortList(&this->vehicle_list);
   767 		}
   751 		}
   768 		DrawDepotWindow(this);
   752 		DrawDepotWindow(this);
   769 	}
   753 	}
   770 
   754 
   771 	virtual void OnClick(Point pt, int widget)
   755 	virtual void OnClick(Point pt, int widget)
   810 				DoCommandP(this->window_number, 0, this->type | (widget == DEPOT_WIDGET_START_ALL ? (1 << 5) : 0), NULL, CMD_MASS_START_STOP);
   794 				DoCommandP(this->window_number, 0, this->type | (widget == DEPOT_WIDGET_START_ALL ? (1 << 5) : 0), NULL, CMD_MASS_START_STOP);
   811 				break;
   795 				break;
   812 
   796 
   813 			case DEPOT_WIDGET_SELL_ALL:
   797 			case DEPOT_WIDGET_SELL_ALL:
   814 				/* Only open the confimation window if there are anything to sell */
   798 				/* Only open the confimation window if there are anything to sell */
   815 				if (this->engine_count != 0 || this->wagon_count != 0) {
   799 				if (this->vehicle_list.Length() != 0 || this->wagon_list.Length() != 0) {
   816 					static const StringID confirm_captions[] = {
   800 					static const StringID confirm_captions[] = {
   817 						STR_8800_TRAIN_DEPOT,
   801 						STR_8800_TRAIN_DEPOT,
   818 						STR_9003_ROAD_VEHICLE_DEPOT,
   802 						STR_9003_ROAD_VEHICLE_DEPOT,
   819 						STR_9803_SHIP_DEPOT,
   803 						STR_9803_SHIP_DEPOT,
   820 						STR_A002_AIRCRAFT_HANGAR
   804 						STR_A002_AIRCRAFT_HANGAR