Mercurial > hg > openttd
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 { |