comparison src/depot_gui.cpp @ 13630:40489a4d0822 draft

(svn r18154) -Codechange: let the depot window better scale with bigger fonts
author rubidium <rubidium@openttd.org>
date Tue, 17 Nov 2009 22:58:41 +0000
parents 2123810ad874
children e809c4dab49d
comparison
equal deleted inserted replaced
13629:de84b51f7506 13630:40489a4d0822
155 DoCommandP(v->tile, v->index + ((wagon == NULL ? INVALID_VEHICLE : wagon->index) << 16), _ctrl_pressed ? 1 : 0, CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_MOVE_VEHICLE)); 155 DoCommandP(v->tile, v->index + ((wagon == NULL ? INVALID_VEHICLE : wagon->index) << 16), _ctrl_pressed ? 1 : 0, CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_MOVE_VEHICLE));
156 } 156 }
157 157
158 /** Array containing the cell size in pixels of the #DEPOT_WIDGET_MATRIX widget for each vehicle type. 158 /** Array containing the cell size in pixels of the #DEPOT_WIDGET_MATRIX widget for each vehicle type.
159 * @note The train vehicle type uses the entire row for each train. */ 159 * @note The train vehicle type uses the entire row for each train. */
160 static Dimension _block_sizes[4]; 160 static Dimension _base_block_sizes[4];
161
162 /** Array containing the default number of cells in horizontal and vertical direction in the #DEPOT_WIDGET_MATRIX widget for each vehicle type.
163 * @note The train vehicle type uses the entire row for each train. */
164 static const Dimension _resize_cap[] = {
165 {10 * 29, 6}, ///< VEH_TRAIN
166 { 5, 5}, ///< VEH_ROAD
167 { 3, 3}, ///< VEH_SHIP
168 { 4, 3}, ///< VEH_AIRCRAFT
169 };
170 161
171 static void InitBlocksizeForShipAircraft(VehicleType type) 162 static void InitBlocksizeForShipAircraft(VehicleType type)
172 { 163 {
173 uint max_width = 0; 164 uint max_width = 0;
174 uint max_height = 0; 165 uint max_height = 0;
188 } 179 }
189 180
190 switch (type) { 181 switch (type) {
191 default: NOT_REACHED(); 182 default: NOT_REACHED();
192 case VEH_SHIP: 183 case VEH_SHIP:
193 _block_sizes[VEH_SHIP].width = max(90U, max_width + 20); // we need 20 pixels from the right edge to the sprite 184 _base_block_sizes[VEH_SHIP].width = max(76U, max_width);
194 break; 185 break;
195 case VEH_AIRCRAFT: 186 case VEH_AIRCRAFT:
196 _block_sizes[VEH_AIRCRAFT].width = max(74U, max_width); 187 _base_block_sizes[VEH_AIRCRAFT].width = max(67U, max_width);
197 break; 188 break;
198 } 189 }
199 _block_sizes[type].height = max(GetVehicleHeight(type), max_height); 190 _base_block_sizes[type].height = max(GetVehicleHeight(type), max_height);
200 } 191 }
201 192
202 /** Set the size of the blocks in the window so we can be sure that they are big enough for the vehicle sprites in the current game. 193 /** Set the size of the blocks in the window so we can be sure that they are big enough for the vehicle sprites in the current game.
203 * @note Calling this function once for each game is enough. */ 194 * @note Calling this function once for each game is enough. */
204 void InitDepotWindowBlockSizes() 195 void InitDepotWindowBlockSizes()
205 { 196 {
206 _block_sizes[VEH_TRAIN].width = 1; 197 _base_block_sizes[VEH_TRAIN].width = 0;
207 _block_sizes[VEH_TRAIN].height = GetVehicleHeight(VEH_TRAIN); 198 _base_block_sizes[VEH_TRAIN].height = GetVehicleHeight(VEH_TRAIN);
208 199
209 _block_sizes[VEH_ROAD].width = 56; 200 _base_block_sizes[VEH_ROAD].width = 32;
210 _block_sizes[VEH_ROAD].height = GetVehicleHeight(VEH_ROAD); 201 _base_block_sizes[VEH_ROAD].height = GetVehicleHeight(VEH_ROAD);
211 202
212 InitBlocksizeForShipAircraft(VEH_SHIP); 203 InitBlocksizeForShipAircraft(VEH_SHIP);
213 InitBlocksizeForShipAircraft(VEH_AIRCRAFT); 204 InitBlocksizeForShipAircraft(VEH_AIRCRAFT);
214 } 205 }
215 206
252 * @param y Top of the box to draw in. 243 * @param y Top of the box to draw in.
253 */ 244 */
254 void DrawVehicleInDepot(const Vehicle *v, int left, int right, int y) const 245 void DrawVehicleInDepot(const Vehicle *v, int left, int right, int y) const
255 { 246 {
256 bool free_wagon = false; 247 bool free_wagon = false;
257 int sprite_y = y + this->resize.step_height - GetVehicleHeight(v->type); 248 int sprite_y = y + (this->resize.step_height - GetVehicleHeight(v->type)) / 2;
258 int x = left + 2; 249 int x = left + 2;
259 250
260 switch (v->type) { 251 switch (v->type) {
261 case VEH_TRAIN: { 252 case VEH_TRAIN: {
262 const Train *u = Train::From(v); 253 const Train *u = Train::From(v);
263 free_wagon = u->IsFreeWagon(); 254 free_wagon = u->IsFreeWagon();
264 255
265 uint x_space = free_wagon ? TRAININFO_DEFAULT_VEHICLE_WIDTH : 0; 256 uint x_space = free_wagon ? TRAININFO_DEFAULT_VEHICLE_WIDTH : 0;
266 DrawTrainImage(u, x + 24 + x_space, right - 10, sprite_y - 1, this->sel, this->hscroll.GetPosition()); 257 DrawTrainImage(u, x + this->header_width + x_space, right - count_width, sprite_y - 1, this->sel, free_wagon ? 0 : this->hscroll.GetPosition());
267 258
268 /* Number of wagons relative to a standard length wagon (rounded up) */ 259 /* Number of wagons relative to a standard length wagon (rounded up) */
269 SetDParam(0, (u->tcache.cached_total_length + 7) / 8); 260 SetDParam(0, (u->tcache.cached_total_length + 7) / 8);
270 DrawString(left, right - 1, y + 4, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT); // Draw the counter 261 DrawString(left, right - 1, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT); // Draw the counter
271 break; 262 break;
272 } 263 }
273 264
274 case VEH_ROAD: DrawRoadVehImage( v, x + 24, right, sprite_y, this->sel); break; 265 case VEH_ROAD: DrawRoadVehImage( v, x + this->header_width, right, sprite_y, this->sel); break;
275 case VEH_SHIP: DrawShipImage( v, x + 12, right, sprite_y - 1, this->sel); break; 266 case VEH_SHIP: DrawShipImage( v, x + this->header_width, right, sprite_y - 1, this->sel); break;
276 case VEH_AIRCRAFT: { 267 case VEH_AIRCRAFT: {
277 const Sprite *spr = GetSprite(v->GetImage(DIR_W), ST_NORMAL); 268 const Sprite *spr = GetSprite(v->GetImage(DIR_W), ST_NORMAL);
278 DrawAircraftImage(v, x + 12, right, 269 DrawAircraftImage(v, x + this->header_width, right,
279 y + max(spr->height + spr->y_offs - 14, 0), // tall sprites needs an y offset 270 y + max(spr->height + spr->y_offs - 14, 0), // tall sprites needs an y offset
280 this->sel); 271 this->sel);
281 } break; 272 } break;
282 default: NOT_REACHED(); 273 default: NOT_REACHED();
283 } 274 }
287 } else { 278 } else {
288 byte diff_x = 0, diff_y = 0; 279 byte diff_x = 0, diff_y = 0;
289 280
290 if (v->type == VEH_TRAIN || v->type == VEH_ROAD) { 281 if (v->type == VEH_TRAIN || v->type == VEH_ROAD) {
291 /* Arrange unitnumber and flag horizontally */ 282 /* Arrange unitnumber and flag horizontally */
292 diff_x = 15; 283 diff_x = this->flag_width;
284 diff_y = (this->resize.step_height - this->flag_height) / 2 - 2;
293 } else { 285 } else {
294 /* Arrange unitnumber and flag vertically */ 286 /* Arrange unitnumber and flag vertically */
295 diff_y = 12; 287 diff_y = FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
296 } 288 }
297 289
298 DrawSprite((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, x + diff_x, y + diff_y); 290 DrawSprite((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, x, y + diff_y);
299 291
300 SetDParam(0, v->unitnumber); 292 SetDParam(0, v->unitnumber);
301 DrawString(x, right - 1, y + 2, (uint16)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? STR_BLACK_COMMA : STR_RED_COMMA); 293 DrawString(x + diff_x, right - 1, y + 2, (uint16)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? STR_BLACK_COMMA : STR_RED_COMMA);
302 } 294 }
303 } 295 }
304 296
305 void DrawWidget(const Rect &r, int widget) const 297 void DrawWidget(const Rect &r, int widget) const
306 { 298 {
360 MODE_START_STOP, 352 MODE_START_STOP,
361 }; 353 };
362 354
363 DepotGUIAction GetVehicleFromDepotWndPt(int x, int y, const Vehicle **veh, GetDepotVehiclePtData *d) const 355 DepotGUIAction GetVehicleFromDepotWndPt(int x, int y, const Vehicle **veh, GetDepotVehiclePtData *d) const
364 { 356 {
365 uint xt, xm = 0, ym = 0; 357 uint xt = 0, xm = 0, ym = 0;
366 if (this->type == VEH_TRAIN) { 358 if (this->type == VEH_TRAIN) {
367 xt = 0; 359 xm = x;
368 x -= 23;
369 } else { 360 } else {
370 xt = x / this->resize.step_width; 361 xt = x / this->resize.step_width;
371 xm = x % this->resize.step_width; 362 xm = x % this->resize.step_width;
372 if (xt >= this->hscroll.GetCapacity()) return MODE_ERROR; 363 if (xt >= this->hscroll.GetCapacity()) return MODE_ERROR;
373 364 }
374 ym = y % this->resize.step_height; 365 ym = y % this->resize.step_height;
375 }
376 366
377 uint row = y / this->resize.step_height; 367 uint row = y / this->resize.step_height;
378 if (row >= this->vscroll.GetCapacity()) return MODE_ERROR; 368 if (row >= this->vscroll.GetCapacity()) return MODE_ERROR;
379 369
380 uint16 boxes_in_each_row = GB(this->GetWidget<NWidgetCore>(DEPOT_WIDGET_MATRIX)->widget_data, MAT_COL_START, MAT_COL_BITS); 370 uint boxes_in_each_row = GB(this->GetWidget<NWidgetCore>(DEPOT_WIDGET_MATRIX)->widget_data, MAT_COL_START, MAT_COL_BITS);
381 int pos = ((row + this->vscroll.GetPosition()) * boxes_in_each_row) + xt; 371 uint pos = ((row + this->vscroll.GetPosition()) * boxes_in_each_row) + xt;
382 372
383 if ((int)(this->vehicle_list.Length() + this->wagon_list.Length()) <= pos) { 373 if (this->vehicle_list.Length() + this->wagon_list.Length() <= pos) {
374 /* Clicking on 'line' / 'block' without a vehicle */
384 if (this->type == VEH_TRAIN) { 375 if (this->type == VEH_TRAIN) {
376 /* End the dragging */
385 d->head = NULL; 377 d->head = NULL;
386 d->wagon = NULL; 378 d->wagon = NULL;
387 return MODE_DRAG_VEHICLE; 379 return MODE_DRAG_VEHICLE;
388 } else { 380 } else {
389 return MODE_ERROR; // empty block, so no vehicle is selected 381 return MODE_ERROR; // empty block, so no vehicle is selected
390 } 382 }
391 } 383 }
392 384
393 int skip = 0; 385 if (this->vehicle_list.Length() > pos) {
394 if ((int)this->vehicle_list.Length() > pos) {
395 *veh = this->vehicle_list[pos]; 386 *veh = this->vehicle_list[pos];
396 skip = this->hscroll.GetPosition(); 387 /* Skip vehicles that are scrolled off the list */
388 x += this->hscroll.GetPosition();
397 } else { 389 } else {
398 pos -= this->vehicle_list.Length(); 390 pos -= this->vehicle_list.Length();
399 *veh = this->wagon_list[pos]; 391 *veh = this->wagon_list[pos];
400 /* free wagons don't have an initial loco. */ 392 /* free wagons don't have an initial loco. */
401 x -= VEHICLEINFO_FULL_VEHICLE_WIDTH; 393 x -= VEHICLEINFO_FULL_VEHICLE_WIDTH;
402 } 394 }
403 395
404 switch (this->type) { 396 const Train *v = NULL;
405 case VEH_TRAIN: { 397 if (this->type == VEH_TRAIN) {
406 const Train *v = Train::From(*veh); 398 v = Train::From(*veh);
407 d->head = d->wagon = v; 399 d->head = d->wagon = v;
408 400 }
409 /* either pressed the flag or the number, but only when it's a loco */ 401
410 if (x < 0 && v->IsFrontEngine()) return (x >= -10) ? MODE_START_STOP : MODE_SHOW_VEHICLE; 402 if (xm <= this->header_width) {
411 403 switch (this->type) {
412 /* Skip vehicles that are scrolled off the list */ 404 case VEH_TRAIN:
413 x += skip; 405 case VEH_ROAD:
414 406 if (xm <= this->flag_width) return MODE_START_STOP;
415 /* find the vehicle in this row that was clicked */ 407 break;
416 for (; v != NULL; v = v->Next()) { 408
417 x -= v->GetDisplayImageWidth(); 409 case VEH_SHIP:
418 if (x < 0) break; 410 case VEH_AIRCRAFT:
419 } 411 if (xm <= this->flag_width && ym >= (uint)(FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL)) return MODE_START_STOP;
420 412 break;
421 d->wagon = (v != NULL ? v->GetFirstEnginePart() : NULL); 413
422 414 default: NOT_REACHED();
423 return MODE_DRAG_VEHICLE;
424 } 415 }
425 416 return MODE_SHOW_VEHICLE;
426 case VEH_ROAD: 417 }
427 if (xm >= 24) return MODE_DRAG_VEHICLE; 418
428 if (xm <= 16) return MODE_SHOW_VEHICLE; 419 if (this->type != VEH_TRAIN) return MODE_DRAG_VEHICLE;
429 break; 420
430 421 /* Account for the header */
431 case VEH_SHIP: 422 x -= this->header_width;
432 if (xm >= 19) return MODE_DRAG_VEHICLE; 423
433 if (ym <= 10) return MODE_SHOW_VEHICLE; 424 /* find the vehicle in this row that was clicked */
434 break; 425 for (; v != NULL; v = v->Next()) {
435 426 x -= v->GetDisplayImageWidth();
436 case VEH_AIRCRAFT: 427 if (x < 0) break;
437 if (xm >= 12) return MODE_DRAG_VEHICLE; 428 }
438 if (ym <= 12) return MODE_SHOW_VEHICLE; 429
439 break; 430 d->wagon = (v != NULL ? v->GetFirstEnginePart() : NULL);
440 431
441 default: NOT_REACHED(); 432 return MODE_DRAG_VEHICLE;
442 }
443 return MODE_START_STOP;
444 } 433 }
445 434
446 /** Handle click in the depot matrix. 435 /** Handle click in the depot matrix.
447 * @param x Horizontal position in the matrix widget in pixels. 436 * @param x Horizontal position in the matrix widget in pixels.
448 * @param y Vertical position in the matrix widget in pixels. 437 * @param y Vertical position in the matrix widget in pixels.
594 this->GetWidget<NWidgetCore>(DEPOT_WIDGET_SELL_ALL)->widget_data = SPR_SELL_ALL_AIRCRAFT; 583 this->GetWidget<NWidgetCore>(DEPOT_WIDGET_SELL_ALL)->widget_data = SPR_SELL_ALL_AIRCRAFT;
595 this->GetWidget<NWidgetCore>(DEPOT_WIDGET_AUTOREPLACE)->widget_data = SPR_REPLACE_AIRCRAFT; 584 this->GetWidget<NWidgetCore>(DEPOT_WIDGET_AUTOREPLACE)->widget_data = SPR_REPLACE_AIRCRAFT;
596 break; 585 break;
597 } 586 }
598 } 587 }
588
589 uint count_width;
590 uint header_width;
591 uint flag_width;
592 uint flag_height;
599 593
600 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *resize) 594 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *resize)
601 { 595 {
602 switch (widget) { 596 switch (widget) {
603 case DEPOT_WIDGET_SELL_CHAIN: 597 case DEPOT_WIDGET_SELL_CHAIN:
607 size->height = 0; 601 size->height = 0;
608 resize->height = 0; 602 resize->height = 0;
609 } 603 }
610 break; 604 break;
611 605
612 case DEPOT_WIDGET_MATRIX: 606 case DEPOT_WIDGET_MATRIX: {
613 resize->width = _block_sizes[this->type].width; 607 uint min_height = 0;
614 resize->height = _block_sizes[this->type].height; 608 uint base_width = 0;
615 size->width = _block_sizes[this->type].width * ((this->type == VEH_TRAIN) ? 1 : _resize_cap[this->type].width); 609
616 size->height = _block_sizes[this->type].height * _resize_cap[this->type].height; 610 if (this->type == VEH_TRAIN) {
617 if (this->type == VEH_TRAIN) size->width += 36; // Make space for the horizontal scrollbar vertically, and the unit number, flag, and length counter horizontally. 611 SetDParam(0, 100);
618 break; 612 this->count_width = GetStringBoundingBox(STR_TINY_BLACK_COMA).width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
613 base_width += this->count_width;
614 }
615
616 SetDParam(0, 999);
617 Dimension unumber = GetStringBoundingBox(STR_BLACK_COMMA);
618 const Sprite *spr = GetSprite(SPR_FLAG_VEH_STOPPED, ST_NORMAL);
619 this->flag_width = spr->width + WD_FRAMERECT_RIGHT;
620 this->flag_height = spr->height;
621
622 if (this->type == VEH_TRAIN || this->type == VEH_ROAD) {
623 min_height = max<uint>(unumber.height + WD_MATRIX_TOP, spr->height);
624 this->header_width = unumber.width + this->flag_width;
625 } else {
626 min_height = unumber.height + spr->height + WD_MATRIX_TOP + WD_PAR_VSEP_NORMAL + WD_MATRIX_BOTTOM;
627 this->header_width = max<uint>(unumber.width, this->flag_width) + WD_FRAMERECT_RIGHT;
628 }
629 base_width += this->header_width;
630
631 resize->height = max(_base_block_sizes[this->type].height, min_height);
632 if (this->type == VEH_TRAIN) {
633 resize->width = 1;
634 size->width = base_width + 10 * 29; // about 10 parts
635 size->height = resize->height * 5;
636 } else {
637 resize->width = base_width + _base_block_sizes[this->type].width;
638 size->width = resize->width * (this->type == VEH_ROAD ? 5 : 3);
639 size->height = resize->height * (this->type == VEH_ROAD ? 5 : 3);
640 }
641 } break;
619 } 642 }
620 } 643 }
621 644
622 virtual void OnInvalidateData(int data) 645 virtual void OnInvalidateData(int data)
623 { 646 {