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 |