2005-07-24 14:12:37 +00:00
/* $Id$ */
2009-08-21 20:21:05 +00:00
/*
* This file is part of OpenTTD .
* OpenTTD is free software ; you can redistribute it and / or modify it under the terms of the GNU General Public License as published by the Free Software Foundation , version 2.
* OpenTTD is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
* See the GNU General Public License for more details . You should have received a copy of the GNU General Public License along with OpenTTD . If not , see < http : //www.gnu.org/licenses/>.
*/
2008-05-06 15:11:33 +00:00
/** @file vehicle_gui.cpp The base GUI for all vehicles. */
2007-04-04 04:08:47 +00:00
2004-09-06 18:15:13 +00:00
# include "stdafx.h"
2005-02-05 15:58:59 +00:00
# include "debug.h"
2008-09-30 20:51:04 +00:00
# include "company_func.h"
2005-01-02 17:23:04 +00:00
# include "gui.h"
2007-12-19 20:45:46 +00:00
# include "textbuf_gui.h"
2007-12-21 21:50:46 +00:00
# include "command_func.h"
2005-07-21 22:15:02 +00:00
# include "vehicle_gui.h"
2008-09-13 10:04:36 +00:00
# include "vehicle_gui_base.h"
2008-01-09 09:45:45 +00:00
# include "viewport_func.h"
2006-04-23 22:33:10 +00:00
# include "newgrf_text.h"
2010-04-24 13:39:11 +00:00
# include "newgrf_debug.h"
2006-08-29 17:41:13 +00:00
# include "roadveh.h"
2009-05-22 22:22:46 +00:00
# include "train.h"
2009-07-13 16:37:27 +00:00
# include "aircraft.h"
2010-08-26 22:01:16 +00:00
# include "depot_map.h"
2007-12-21 07:38:36 +00:00
# include "group_gui.h"
2007-12-21 19:49:27 +00:00
# include "strings_func.h"
2007-12-25 11:26:07 +00:00
# include "window_func.h"
2007-12-27 13:35:39 +00:00
# include "vehicle_func.h"
2008-01-07 09:19:53 +00:00
# include "autoreplace_gui.h"
2008-01-07 14:23:25 +00:00
# include "string_func.h"
2008-01-14 16:10:58 +00:00
# include "widgets/dropdown_func.h"
2008-05-06 22:17:12 +00:00
# include "timetable.h"
2009-02-27 20:40:39 +00:00
# include "articulated_vehicles.h"
2009-11-17 15:05:12 +00:00
# include "spritecache.h"
2010-01-15 16:41:15 +00:00
# include "core/geometry_func.hpp"
# include "company_base.h"
# include "engine_func.h"
2010-06-11 00:18:28 +00:00
# include "station_base.h"
2010-09-06 14:14:09 +00:00
# include "tilehighlight_func.h"
2005-07-21 22:15:02 +00:00
2008-01-13 01:21:35 +00:00
# include "table/strings.h"
2008-05-11 14:23:45 +00:00
Sorting _sorting ;
2004-09-06 18:15:13 +00:00
2008-06-19 19:58:30 +00:00
static GUIVehicleList : : SortFunction VehicleNumberSorter ;
static GUIVehicleList : : SortFunction VehicleNameSorter ;
static GUIVehicleList : : SortFunction VehicleAgeSorter ;
static GUIVehicleList : : SortFunction VehicleProfitThisYearSorter ;
static GUIVehicleList : : SortFunction VehicleProfitLastYearSorter ;
static GUIVehicleList : : SortFunction VehicleCargoSorter ;
static GUIVehicleList : : SortFunction VehicleReliabilitySorter ;
static GUIVehicleList : : SortFunction VehicleMaxSpeedSorter ;
static GUIVehicleList : : SortFunction VehicleModelSorter ;
static GUIVehicleList : : SortFunction VehicleValueSorter ;
static GUIVehicleList : : SortFunction VehicleLengthSorter ;
2008-09-17 02:30:24 +00:00
static GUIVehicleList : : SortFunction VehicleTimeToLiveSorter ;
2009-08-15 10:51:33 +00:00
static GUIVehicleList : : SortFunction VehicleTimetableDelaySorter ;
2008-06-19 19:58:30 +00:00
2009-01-10 00:31:47 +00:00
GUIVehicleList : : SortFunction * const BaseVehicleListWindow : : vehicle_sorter_funcs [ ] = {
2004-11-25 06:05:47 +00:00
& VehicleNumberSorter ,
& VehicleNameSorter ,
& VehicleAgeSorter ,
& VehicleProfitThisYearSorter ,
& VehicleProfitLastYearSorter ,
& VehicleCargoSorter ,
& VehicleReliabilitySorter ,
2006-02-03 18:32:59 +00:00
& VehicleMaxSpeedSorter ,
& VehicleModelSorter ,
& VehicleValueSorter ,
2008-04-18 10:58:11 +00:00
& VehicleLengthSorter ,
2008-09-17 02:30:24 +00:00
& VehicleTimeToLiveSorter ,
2009-08-15 10:51:33 +00:00
& VehicleTimetableDelaySorter ,
2004-11-25 06:05:47 +00:00
} ;
2008-09-13 10:04:36 +00:00
const StringID BaseVehicleListWindow : : vehicle_sorter_names [ ] = {
2004-11-25 06:05:47 +00:00
STR_SORT_BY_NUMBER ,
2009-07-23 19:31:50 +00:00
STR_SORT_BY_NAME ,
2004-11-25 06:05:47 +00:00
STR_SORT_BY_AGE ,
STR_SORT_BY_PROFIT_THIS_YEAR ,
STR_SORT_BY_PROFIT_LAST_YEAR ,
STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE ,
STR_SORT_BY_RELIABILITY ,
STR_SORT_BY_MAX_SPEED ,
2006-02-03 18:32:59 +00:00
STR_SORT_BY_MODEL ,
STR_SORT_BY_VALUE ,
2008-04-18 10:58:11 +00:00
STR_SORT_BY_LENGTH ,
2008-09-17 02:30:24 +00:00
STR_SORT_BY_LIFE_TIME ,
2009-08-15 10:51:33 +00:00
STR_SORT_BY_TIMETABLE_DELAY ,
2004-11-25 06:05:47 +00:00
INVALID_STRING_ID
} ;
2010-07-17 14:53:46 +00:00
const StringID BaseVehicleListWindow : : vehicle_depot_name [ ] = {
STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT ,
STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT ,
STR_VEHICLE_LIST_SEND_SHIP_TO_DEPOT ,
STR_VEHICLE_LIST_SEND_AIRCRAFT_TO_HANGAR
} ;
2010-09-09 14:40:39 +00:00
void BaseVehicleListWindow : : BuildVehicleList ( )
2004-12-10 18:16:08 +00:00
{
2008-09-13 10:04:36 +00:00
if ( ! this - > vehicles . NeedRebuild ( ) ) return ;
2004-12-10 18:16:08 +00:00
2010-09-09 14:40:39 +00:00
DEBUG ( misc , 3 , " Building vehicle list type %d for company %d given index %d " , this - > vli . type , this - > vli . company , this - > vli . index ) ;
2004-12-10 18:16:08 +00:00
2010-09-09 14:40:39 +00:00
GenerateVehicleSortList ( & this - > vehicles , this - > vli ) ;
2004-12-10 18:16:08 +00:00
2009-11-17 09:09:20 +00:00
uint unitnumber = 0 ;
for ( const Vehicle * * v = this - > vehicles . Begin ( ) ; v ! = this - > vehicles . End ( ) ; v + + ) {
unitnumber = max < uint > ( unitnumber , ( * v ) - > unitnumber ) ;
}
/* Because 111 is much less wide than e.g. 999 we use the
* wider numbers to determine the width instead of just
* the random number that it seems to be . */
if ( unitnumber > = 1000 ) {
2009-12-20 16:44:41 +00:00
this - > unitnumber_digits = 4 ;
2009-11-17 09:09:20 +00:00
} else if ( unitnumber > = 100 ) {
2009-12-20 16:44:41 +00:00
this - > unitnumber_digits = 3 ;
2009-11-17 09:09:20 +00:00
} else {
2009-12-20 16:44:41 +00:00
this - > unitnumber_digits = 2 ;
2009-11-17 09:09:20 +00:00
}
2008-09-13 10:04:36 +00:00
this - > vehicles . RebuildDone ( ) ;
2010-08-12 08:37:01 +00:00
this - > vscroll - > SetCount ( this - > vehicles . Length ( ) ) ;
2004-12-10 18:16:08 +00:00
}
2010-07-17 14:47:54 +00:00
/**
* Compute the size for the Action dropdown .
2010-07-17 14:58:35 +00:00
* @ param show_autoreplace If true include the autoreplace item .
2010-07-17 14:47:54 +00:00
* @ param show_group If true include group - related stuff .
* @ return Required size .
*/
2010-07-17 14:58:35 +00:00
Dimension BaseVehicleListWindow : : GetActionDropdownSize ( bool show_autoreplace , bool show_group )
2010-07-17 14:47:54 +00:00
{
Dimension d = { 0 , 0 } ;
2010-07-17 14:58:35 +00:00
if ( show_autoreplace ) d = maxdim ( d , GetStringBoundingBox ( STR_VEHICLE_LIST_REPLACE_VEHICLES ) ) ;
2010-07-17 14:47:54 +00:00
d = maxdim ( d , GetStringBoundingBox ( STR_VEHICLE_LIST_SEND_FOR_SERVICING ) ) ;
2010-09-09 14:40:39 +00:00
d = maxdim ( d , GetStringBoundingBox ( this - > vehicle_depot_name [ this - > vli . vtype ] ) ) ;
2010-07-17 14:47:54 +00:00
if ( show_group ) {
d = maxdim ( d , GetStringBoundingBox ( STR_GROUP_ADD_SHARED_VEHICLE ) ) ;
d = maxdim ( d , GetStringBoundingBox ( STR_GROUP_REMOVE_ALL_VEHICLES ) ) ;
}
return d ;
}
2010-07-17 14:36:36 +00:00
/**
* Display the Action dropdown window .
2010-07-17 14:58:35 +00:00
* @ param show_autoreplace If true include the autoreplace item .
2010-07-17 14:36:36 +00:00
* @ param show_group If true include group - related stuff .
* @ return Itemlist for dropdown
*/
2010-07-17 14:58:35 +00:00
DropDownList * BaseVehicleListWindow : : BuildActionDropdownList ( bool show_autoreplace , bool show_group )
2010-07-17 14:36:36 +00:00
{
DropDownList * list = new DropDownList ( ) ;
2010-07-17 14:58:35 +00:00
if ( show_autoreplace ) list - > push_back ( new DropDownListStringItem ( STR_VEHICLE_LIST_REPLACE_VEHICLES , ADI_REPLACE , false ) ) ;
2010-07-17 14:36:36 +00:00
list - > push_back ( new DropDownListStringItem ( STR_VEHICLE_LIST_SEND_FOR_SERVICING , ADI_SERVICE , false ) ) ;
2010-09-09 14:40:39 +00:00
list - > push_back ( new DropDownListStringItem ( this - > vehicle_depot_name [ this - > vli . vtype ] , ADI_DEPOT , false ) ) ;
2010-07-17 14:36:36 +00:00
if ( show_group ) {
list - > push_back ( new DropDownListStringItem ( STR_GROUP_ADD_SHARED_VEHICLE , ADI_ADD_SHARED , false ) ) ;
list - > push_back ( new DropDownListStringItem ( STR_GROUP_REMOVE_ALL_VEHICLES , ADI_REMOVE_ALL , false ) ) ;
}
return list ;
}
2008-03-02 00:25:54 +00:00
/* cached values for VehicleNameSorter to spare many GetString() calls */
static const Vehicle * _last_vehicle [ 2 ] = { NULL , NULL } ;
2008-09-13 10:04:36 +00:00
void BaseVehicleListWindow : : SortVehicleList ( )
2004-12-10 18:16:08 +00:00
{
2008-09-13 10:04:36 +00:00
if ( this - > vehicles . Sort ( ) ) return ;
2004-12-10 18:16:08 +00:00
2008-03-02 00:25:54 +00:00
/* invalidate cached values for name sorter - vehicle names could change */
_last_vehicle [ 0 ] = _last_vehicle [ 1 ] = NULL ;
2004-12-10 18:16:08 +00:00
}
2008-05-25 17:22:49 +00:00
void DepotSortList ( VehicleList * list )
2006-10-05 13:11:17 +00:00
{
2008-05-25 17:22:49 +00:00
if ( list - > Length ( ) < 2 ) return ;
2008-06-19 19:58:30 +00:00
QSortT ( list - > Begin ( ) , list - > Length ( ) , & VehicleNumberSorter ) ;
2006-10-05 13:11:17 +00:00
}
2004-12-10 18:16:08 +00:00
2007-04-04 04:08:47 +00:00
/** draw the vehicle profit button in the vehicle list window. */
2009-11-09 10:40:33 +00:00
static void DrawVehicleProfitButton ( const Vehicle * v , int x , int y )
2004-09-06 18:15:13 +00:00
{
2010-09-02 20:00:48 +00:00
SpriteID spr ;
2004-09-06 18:15:13 +00:00
2009-02-09 02:57:15 +00:00
/* draw profit-based coloured icons */
2011-10-03 17:25:44 +00:00
if ( v - > age < = VEHICLE_PROFIT_MIN_AGE ) {
2010-09-02 20:00:48 +00:00
spr = SPR_PROFIT_NA ;
2008-02-20 17:06:58 +00:00
} else if ( v - > GetDisplayProfitLastYear ( ) < 0 ) {
2010-09-02 20:00:48 +00:00
spr = SPR_PROFIT_NEGATIVE ;
2011-10-03 17:25:44 +00:00
} else if ( v - > GetDisplayProfitLastYear ( ) < VEHICLE_PROFIT_THRESHOLD ) {
2010-09-02 20:00:48 +00:00
spr = SPR_PROFIT_SOME ;
2005-11-14 19:48:04 +00:00
} else {
2010-09-02 20:00:48 +00:00
spr = SPR_PROFIT_LOT ;
2005-11-14 19:48:04 +00:00
}
2010-09-02 20:00:48 +00:00
DrawSprite ( spr , PAL_NONE , x , y ) ;
2004-09-06 18:15:13 +00:00
}
2010-01-10 20:33:10 +00:00
/** Maximum number of refit cycles we try, to prevent infinite loops. And we store only a byte anyway */
static const uint MAX_REFIT_CYCLE = 256 ;
2009-12-13 22:19:19 +00:00
2009-12-14 19:17:18 +00:00
/**
* Get the best fitting subtype when ' cloning ' / ' replacing ' v_from with v_for .
* Assuming they are going to carry the same cargo ofcourse !
* @ param v_from the vehicle to match the subtype from
* @ param v_for the vehicle to get the subtype for
2011-11-04 15:04:24 +00:00
* @ param dest_cargo_type Destination cargo type , taken from # v_from if set to # INVALID_CARGO .
2009-12-14 19:17:18 +00:00
* @ return the best sub type
*/
2011-11-04 15:04:24 +00:00
byte GetBestFittingSubType ( Vehicle * v_from , Vehicle * v_for , CargoID dest_cargo_type )
2009-12-14 19:17:18 +00:00
{
2011-11-01 00:21:08 +00:00
const Engine * e_from = v_from - > GetEngine ( ) ;
const Engine * e_for = v_for - > GetEngine ( ) ;
2009-12-14 19:17:18 +00:00
/* If one them doesn't carry cargo, there's no need to find a sub type */
if ( ! e_from - > CanCarryCargo ( ) | | ! e_for - > CanCarryCargo ( ) ) return 0 ;
if ( ! HasBit ( e_from - > info . callback_mask , CBM_VEHICLE_CARGO_SUFFIX ) | |
! HasBit ( e_for - > info . callback_mask , CBM_VEHICLE_CARGO_SUFFIX ) ) {
/* One of the engines doesn't have cargo suffixes, i.e. sub types. */
return 0 ;
}
2011-11-04 15:04:24 +00:00
if ( dest_cargo_type = = INVALID_CARGO ) dest_cargo_type = v_from - > cargo_type ;
2009-12-14 19:17:18 +00:00
/* It has to be possible for v_for to carry the cargo of v_from. */
2011-11-04 15:04:24 +00:00
if ( ! HasBit ( e_for - > info . refit_mask , dest_cargo_type ) ) return 0 ;
2009-12-14 19:17:18 +00:00
StringID expected_string = GetCargoSubtypeText ( v_from ) ;
CargoID old_cargo_type = v_for - > cargo_type ;
byte old_cargo_subtype = v_for - > cargo_subtype ;
byte ret_refit_cyc = 0 ;
/* Set the 'destination' cargo */
2011-11-04 15:04:24 +00:00
v_for - > cargo_type = dest_cargo_type ;
2009-12-14 19:17:18 +00:00
/* Cycle through the refits */
2010-01-10 20:33:10 +00:00
for ( uint refit_cyc = 0 ; refit_cyc < MAX_REFIT_CYCLE ; refit_cyc + + ) {
2009-12-14 19:17:18 +00:00
v_for - > cargo_subtype = refit_cyc ;
/* Make sure we don't pick up anything cached. */
v_for - > First ( ) - > InvalidateNewGRFCache ( ) ;
v_for - > InvalidateNewGRFCache ( ) ;
uint16 callback = GetVehicleCallback ( CBID_VEHICLE_CARGO_SUFFIX , 0 , 0 , v_for - > engine_type , v_for ) ;
2011-11-08 17:24:43 +00:00
if ( callback ! = CALLBACK_FAILED ) {
if ( callback > 0x400 ) ErrorUnknownCallbackResult ( v_for - > GetGRFID ( ) , CBID_VEHICLE_CARGO_SUFFIX , callback ) ;
if ( callback > = 0x400 | | ( v_for - > GetGRF ( ) - > grf_version < 8 & & callback = = 0xFF ) ) callback = CALLBACK_FAILED ;
}
2009-12-14 19:17:18 +00:00
if ( callback = = CALLBACK_FAILED ) break ;
if ( GetCargoSubtypeText ( v_for ) ! = expected_string ) continue ;
/* We found something matching. */
ret_refit_cyc = refit_cyc ;
break ;
}
/* Reset the vehicle's cargo type */
v_for - > cargo_type = old_cargo_type ;
v_for - > cargo_subtype = old_cargo_subtype ;
/* Make sure we don't taint the vehicle. */
v_for - > First ( ) - > InvalidateNewGRFCache ( ) ;
v_for - > InvalidateNewGRFCache ( ) ;
return ret_refit_cyc ;
}
2010-01-10 21:45:32 +00:00
/** Option to refit a vehicle chain */
2007-03-07 12:11:48 +00:00
struct RefitOption {
2010-01-10 21:45:32 +00:00
CargoID cargo ; ///< Cargo to refit to
byte subtype ; ///< Subcargo to use
uint16 value ; ///< GRF-local String to display for the cargo
2011-11-01 00:23:41 +00:00
const Engine * engine ; ///< Engine for which to resolve #value
2006-10-01 12:00:32 +00:00
2010-08-13 14:24:47 +00:00
/**
* Inequality operator for # RefitOption .
* @ param other Compare to this # RefitOption .
* @ return True if both # RefitOption are different .
*/
2010-01-10 21:45:32 +00:00
FORCEINLINE bool operator ! = ( const RefitOption & other ) const
{
2010-01-20 17:59:31 +00:00
return other . cargo ! = this - > cargo | | other . value ! = this - > value ;
2010-01-10 21:45:32 +00:00
}
2010-04-02 12:28:08 +00:00
2010-08-13 14:24:47 +00:00
/**
* Equality operator for # RefitOption .
* @ param other Compare to this # RefitOption .
* @ return True if both # RefitOption are equal .
*/
2010-04-02 12:28:08 +00:00
FORCEINLINE bool operator = = ( const RefitOption & other ) const
{
return other . cargo = = this - > cargo & & other . value = = this - > value ;
}
2007-03-07 12:11:48 +00:00
} ;
2006-10-01 12:00:32 +00:00
2010-08-13 14:28:51 +00:00
typedef SmallVector < RefitOption , 32 > SubtypeList ; ///< List of refit subtypes associated to a cargo.
2010-01-10 21:45:32 +00:00
2010-08-01 19:22:34 +00:00
/**
* Draw the list of available refit options for a consist and highlight the selected refit option ( if any ) .
2010-08-13 14:28:51 +00:00
* @ param list List of subtype options for each ( sorted ) cargo .
2009-10-24 21:10:57 +00:00
* @ param sel Selected refit cargo - type in the window
* @ param pos Position of the selected item in caller widow
* @ param rows Number of rows ( capacity ) in caller window
* @ param delta Step height in caller window
* @ param r Rectangle of the matrix widget .
2005-05-14 12:36:16 +00:00
*/
2010-08-13 14:28:51 +00:00
static void DrawVehicleRefitWindow ( const SubtypeList list [ NUM_CARGO ] , int sel , uint pos , uint rows , uint delta , const Rect & r )
2005-05-14 12:36:16 +00:00
{
2009-10-24 21:10:57 +00:00
uint y = r . top + WD_MATRIX_TOP ;
2010-08-13 14:28:51 +00:00
uint current = 0 ;
/* Draw the list of subtypes for each cargo, and find the selected refit option (by its position). */
for ( uint i = 0 ; current < pos + rows & & i < NUM_CARGO ; i + + ) {
for ( uint j = 0 ; current < pos + rows & & j < list [ i ] . Length ( ) ; j + + ) {
/* Refit options with a position smaller than pos don't have to be drawn. */
if ( current < pos ) {
current + + ;
continue ;
}
TextColour colour = ( sel = = ( int ) current ) ? TC_WHITE : TC_BLACK ;
const RefitOption refit = list [ i ] [ j ] ;
/* Get the cargo name. */
SetDParam ( 0 , CargoSpec : : Get ( refit . cargo ) - > name ) ;
/* If the callback succeeded, draw the cargo suffix. */
2011-11-08 17:24:43 +00:00
if ( refit . value ! = CALLBACK_FAILED & & refit . value < 0x400 ) {
2011-11-01 00:23:41 +00:00
SetDParam ( 1 , GetGRFStringID ( refit . engine - > GetGRFID ( ) , 0xD000 + refit . value ) ) ;
2010-08-13 14:28:51 +00:00
DrawString ( r . left + WD_MATRIX_LEFT , r . right - WD_MATRIX_RIGHT , y , STR_JUST_STRING_SPACE_STRING , colour ) ;
} else {
DrawString ( r . left + WD_MATRIX_LEFT , r . right - WD_MATRIX_RIGHT , y , STR_JUST_STRING , colour ) ;
}
2009-11-16 13:19:39 +00:00
2010-08-13 14:28:51 +00:00
y + = delta ;
current + + ;
}
2006-02-14 09:31:05 +00:00
}
2005-05-14 12:36:16 +00:00
}
2009-04-13 08:40:40 +00:00
/** Widget numbers of the vehicle refit window. */
enum VehicleRefitWidgets {
VRW_CAPTION ,
2010-12-21 13:58:09 +00:00
VRW_VEHICLE_PANEL_DISPLAY ,
VRW_SHOW_HSCROLLBAR ,
VRW_HSCROLLBAR ,
2009-04-13 08:40:40 +00:00
VRW_SELECTHEADER ,
VRW_MATRIX ,
VRW_SCROLLBAR ,
VRW_INFOPANEL ,
VRW_REFITBUTTON ,
} ;
2009-10-24 20:26:18 +00:00
/** Refit cargo window. */
2008-05-16 23:23:38 +00:00
struct RefitWindow : public Window {
2010-08-13 14:28:51 +00:00
int sel ; ///< Index in refit options, \c -1 if nothing is selected.
RefitOption * cargo ; ///< Refit option selected by \v sel.
SubtypeList list [ NUM_CARGO ] ; ///< List of refit subtypes available for each sorted cargo.
VehicleOrderID order ; ///< If not #INVALID_VEH_ORDER_ID, selection is part of a refit order (rather than execute directly).
2010-10-15 10:22:04 +00:00
uint information_width ; ///< Width required for correctly displaying all cargos in the information panel.
2010-12-21 13:58:09 +00:00
Scrollbar * vscroll ; ///< The main scrollbar.
Scrollbar * hscroll ; ///< Only used for long vehicles.
int vehicle_width ; ///< Width of the vehicle being drawn.
int sprite_left ; ///< Left position of the vehicle sprite.
int sprite_right ; ///< Right position of the vehicle sprite.
2010-12-21 13:59:16 +00:00
uint vehicle_margin ; ///< Margin to use while selecting vehicles when the vehicle image is centered.
int click_x ; ///< Position of the first click while dragging.
VehicleID selected_vehicle ; ///< First vehicle in the current selection.
uint8 num_vehicles ; ///< Number of selected vehicles.
2011-11-04 00:38:59 +00:00
bool auto_refit ; ///< Select cargo for auto-refitting.
2008-05-16 23:23:38 +00:00
2010-08-13 14:26:29 +00:00
/**
* Collects all ( cargo , subcargo ) refit options of a vehicle chain .
*/
void BuildRefitList ( )
{
2010-08-13 14:28:51 +00:00
for ( uint i = 0 ; i < NUM_CARGO ; i + + ) this - > list [ i ] . Clear ( ) ;
2010-08-13 14:26:29 +00:00
Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2010-12-21 13:59:16 +00:00
/* Check only the selected vehicles. */
VehicleSet vehicles_to_refit ;
GetVehicleSet ( vehicles_to_refit , Vehicle : : Get ( this - > selected_vehicle ) , this - > num_vehicles ) ;
2010-08-13 14:26:29 +00:00
do {
2010-12-21 13:59:16 +00:00
if ( v - > type = = VEH_TRAIN & & ! vehicles_to_refit . Contains ( v - > index ) ) continue ;
2011-11-01 00:21:08 +00:00
const Engine * e = v - > GetEngine ( ) ;
2010-08-13 14:26:29 +00:00
uint32 cmask = e - > info . refit_mask ;
byte callback_mask = e - > info . callback_mask ;
/* Skip this engine if it does not carry anything */
if ( ! e - > CanCarryCargo ( ) ) continue ;
2011-11-04 00:38:59 +00:00
/* Skip this engine if we build the list for auto-refitting and engine doesn't allow it. */
if ( this - > auto_refit & & ! HasBit ( e - > info . misc_flags , EF_AUTO_REFIT ) ) continue ;
2010-08-13 14:26:29 +00:00
/* Loop through all cargos in the refit mask */
2010-08-13 14:28:51 +00:00
int current_index = 0 ;
2010-08-13 14:26:29 +00:00
const CargoSpec * cs ;
FOR_ALL_SORTED_CARGOSPECS ( cs ) {
CargoID cid = cs - > Index ( ) ;
/* Skip cargo type if it's not listed */
2010-08-13 14:28:51 +00:00
if ( ! HasBit ( cmask , cid ) ) {
current_index + + ;
continue ;
}
2010-08-13 14:26:29 +00:00
/* Check the vehicle's callback mask for cargo suffixes */
if ( HasBit ( callback_mask , CBM_VEHICLE_CARGO_SUFFIX ) ) {
/* Make a note of the original cargo type. It has to be
* changed to test the cargo & subtype . . . */
CargoID temp_cargo = v - > cargo_type ;
byte temp_subtype = v - > cargo_subtype ;
v - > cargo_type = cid ;
for ( uint refit_cyc = 0 ; refit_cyc < MAX_REFIT_CYCLE ; refit_cyc + + ) {
v - > cargo_subtype = refit_cyc ;
/* Make sure we don't pick up anything cached. */
v - > First ( ) - > InvalidateNewGRFCache ( ) ;
v - > InvalidateNewGRFCache ( ) ;
uint16 callback = GetVehicleCallback ( CBID_VEHICLE_CARGO_SUFFIX , 0 , 0 , v - > engine_type , v ) ;
2011-11-08 17:24:43 +00:00
if ( callback ! = CALLBACK_FAILED ) {
if ( callback > 0x400 ) ErrorUnknownCallbackResult ( v - > GetGRFID ( ) , CBID_VEHICLE_CARGO_SUFFIX , callback ) ;
if ( callback > = 0x400 | | ( v - > GetGRF ( ) - > grf_version < 8 & & callback = = 0xFF ) ) callback = CALLBACK_FAILED ;
}
2010-08-13 14:26:29 +00:00
if ( refit_cyc ! = 0 & & callback = = CALLBACK_FAILED ) break ;
RefitOption option ;
option . cargo = cid ;
option . subtype = refit_cyc ;
option . value = callback ;
2011-11-01 00:23:41 +00:00
option . engine = v - > GetEngine ( ) ;
2010-08-13 14:28:51 +00:00
this - > list [ current_index ] . Include ( option ) ;
2010-08-13 14:26:29 +00:00
}
/* Reset the vehicle's cargo type */
v - > cargo_type = temp_cargo ;
v - > cargo_subtype = temp_subtype ;
/* And make sure we haven't tainted the cache */
v - > First ( ) - > InvalidateNewGRFCache ( ) ;
v - > InvalidateNewGRFCache ( ) ;
} else {
/* No cargo suffix callback -- use no subtype */
RefitOption option ;
option . cargo = cid ;
option . subtype = 0 ;
option . value = CALLBACK_FAILED ;
2011-11-01 00:23:41 +00:00
option . engine = NULL ;
2010-08-13 14:28:51 +00:00
this - > list [ current_index ] . Include ( option ) ;
2010-08-13 14:26:29 +00:00
}
2010-08-13 14:28:51 +00:00
current_index + + ;
2010-08-13 14:26:29 +00:00
}
2010-12-14 21:26:03 +00:00
} while ( v - > IsGroundVehicle ( ) & & ( v = v - > Next ( ) ) ! = NULL ) ;
2010-08-13 14:28:51 +00:00
int scroll_size = 0 ;
for ( uint i = 0 ; i < NUM_CARGO ; i + + ) {
scroll_size + = ( this - > list [ i ] . Length ( ) ) ;
}
this - > vscroll - > SetCount ( scroll_size ) ;
}
/**
* Gets the # RefitOption placed in the selected index .
* @ return Pointer to the # RefitOption currently in use .
*/
RefitOption * GetRefitOption ( )
{
if ( this - > sel < 0 ) return NULL ;
int subtype = 0 ;
for ( uint i = 0 ; subtype < = this - > sel & & i < NUM_CARGO ; i + + ) {
for ( uint j = 0 ; subtype < = this - > sel & & j < this - > list [ i ] . Length ( ) ; j + + ) {
if ( subtype = = this - > sel ) {
return & this - > list [ i ] [ j ] ;
}
subtype + + ;
}
}
return NULL ;
2010-08-13 14:26:29 +00:00
}
2011-11-04 00:38:59 +00:00
RefitWindow ( const WindowDesc * desc , const Vehicle * v , VehicleOrderID order , bool auto_refit ) : Window ( )
2008-05-16 23:23:38 +00:00
{
2010-12-21 13:49:42 +00:00
this - > sel = - 1 ;
2011-11-04 00:38:59 +00:00
this - > auto_refit = auto_refit ;
2009-10-24 20:26:18 +00:00
this - > CreateNestedTree ( desc ) ;
2010-08-12 08:37:01 +00:00
this - > vscroll = this - > GetScrollbar ( VRW_SCROLLBAR ) ;
2010-12-21 13:58:09 +00:00
this - > hscroll = ( v - > IsGroundVehicle ( ) ? this - > GetScrollbar ( VRW_HSCROLLBAR ) : NULL ) ;
2009-10-24 20:26:18 +00:00
this - > GetWidget < NWidgetCore > ( VRW_SELECTHEADER ) - > tool_tip = STR_REFIT_TRAIN_LIST_TOOLTIP + v - > type ;
this - > GetWidget < NWidgetCore > ( VRW_MATRIX ) - > tool_tip = STR_REFIT_TRAIN_LIST_TOOLTIP + v - > type ;
NWidgetCore * nwi = this - > GetWidget < NWidgetCore > ( VRW_REFITBUTTON ) ;
nwi - > widget_data = STR_REFIT_TRAIN_REFIT_BUTTON + v - > type ;
nwi - > tool_tip = STR_REFIT_TRAIN_REFIT_TOOLTIP + v - > type ;
2010-12-21 13:58:09 +00:00
this - > GetWidget < NWidgetStacked > ( VRW_SHOW_HSCROLLBAR ) - > SetDisplayedPlane ( v - > IsGroundVehicle ( ) ? 0 : SZSP_HORIZONTAL ) ;
2010-12-21 13:59:16 +00:00
this - > GetWidget < NWidgetCore > ( VRW_VEHICLE_PANEL_DISPLAY ) - > tool_tip = ( v - > type = = VEH_TRAIN ) ? STR_REFIT_SELECT_VEHICLES_TOOLTIP : STR_NULL ;
2009-10-24 20:26:18 +00:00
this - > FinishInitNested ( desc , v - > index ) ;
2009-02-09 02:33:10 +00:00
this - > owner = v - > owner ;
2008-05-16 23:23:38 +00:00
this - > order = order ;
2010-12-21 13:49:42 +00:00
this - > SetWidgetDisabledState ( VRW_REFITBUTTON , this - > sel = = - 1 ) ;
2008-05-16 23:23:38 +00:00
}
2010-04-02 12:28:08 +00:00
virtual void OnInit ( )
{
if ( this - > cargo ! = NULL ) {
/* Store the RefitOption currently in use. */
RefitOption current_refit_option = * ( this - > cargo ) ;
/* Rebuild the refit list */
2010-08-13 14:26:29 +00:00
this - > BuildRefitList ( ) ;
2010-04-02 12:28:08 +00:00
this - > sel = - 1 ;
this - > cargo = NULL ;
2010-08-13 14:28:51 +00:00
int current = 0 ;
for ( uint i = 0 ; this - > cargo = = NULL & & i < NUM_CARGO ; i + + ) {
for ( uint j = 0 ; j < list [ i ] . Length ( ) ; j + + ) {
if ( list [ i ] [ j ] = = current_refit_option ) {
this - > sel = current ;
this - > cargo = & list [ i ] [ j ] ;
this - > vscroll - > ScrollTowards ( current ) ;
break ;
}
current + + ;
2010-04-02 12:28:08 +00:00
}
}
2010-12-21 13:49:42 +00:00
this - > SetWidgetDisabledState ( VRW_REFITBUTTON , this - > sel = = - 1 ) ;
2010-04-02 12:28:08 +00:00
/* If the selected refit option was not found, scroll the window to the initial position. */
2010-08-12 08:37:01 +00:00
if ( this - > sel = = - 1 ) this - > vscroll - > ScrollTowards ( 0 ) ;
2010-04-02 12:28:08 +00:00
} else {
/* Rebuild the refit list */
2010-04-23 17:29:53 +00:00
this - > OnInvalidateData ( 0 ) ;
2010-04-02 12:28:08 +00:00
}
}
2010-12-21 13:58:09 +00:00
virtual void OnPaint ( )
{
/* Determine amount of items for scroller. */
if ( this - > hscroll ! = NULL ) this - > hscroll - > SetCount ( this - > vehicle_width ) ;
/* Calculate sprite position. */
NWidgetCore * vehicle_panel_display = this - > GetWidget < NWidgetCore > ( VRW_VEHICLE_PANEL_DISPLAY ) ;
int sprite_width = max ( 0 , ( ( int ) vehicle_panel_display - > current_x - this - > vehicle_width ) / 2 ) ;
this - > sprite_left = vehicle_panel_display - > pos_x ;
this - > sprite_right = vehicle_panel_display - > pos_x + vehicle_panel_display - > current_x - 1 ;
if ( _current_text_dir = = TD_RTL ) {
this - > sprite_right - = sprite_width ;
2010-12-21 13:59:16 +00:00
this - > vehicle_margin = vehicle_panel_display - > current_x - sprite_right ;
2010-12-21 13:58:09 +00:00
} else {
this - > sprite_left + = sprite_width ;
2010-12-21 13:59:16 +00:00
this - > vehicle_margin = sprite_left ;
2010-12-21 13:58:09 +00:00
}
this - > DrawWidgets ( ) ;
}
2009-11-22 18:28:14 +00:00
virtual void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize )
2009-10-24 20:26:18 +00:00
{
switch ( widget ) {
case VRW_MATRIX :
resize - > height = WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM ;
size - > height = resize - > height * 8 ;
break ;
2010-10-15 10:22:04 +00:00
2010-12-21 13:58:09 +00:00
case VRW_VEHICLE_PANEL_DISPLAY :
size - > height = GetVehicleHeight ( Vehicle : : Get ( this - > window_number ) - > type ) ;
break ;
2010-10-15 10:22:04 +00:00
case VRW_INFOPANEL :
size - > width = WD_FRAMERECT_LEFT + this - > information_width + WD_FRAMERECT_RIGHT ;
break ;
2009-10-24 20:26:18 +00:00
}
}
2006-09-27 07:23:38 +00:00
2009-10-24 20:26:18 +00:00
virtual void SetStringParameters ( int widget ) const
{
if ( widget = = VRW_CAPTION ) SetDParam ( 0 , Vehicle : : Get ( this - > window_number ) - > index ) ;
}
2006-09-27 07:23:38 +00:00
2010-11-16 20:56:04 +00:00
/**
* Gets the # StringID to use for displaying capacity .
* @ param Cargo and cargo subtype to check for capacity .
* @ return INVALID_STRING_ID if there is no capacity . StringID to use in any other case .
* @ post String parameters have been set .
*/
StringID GetCapacityString ( RefitOption * option ) const
{
2011-02-23 20:54:55 +00:00
assert ( _current_company = = _local_company ) ;
2010-11-16 20:56:04 +00:00
Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2011-11-04 00:38:59 +00:00
CommandCost cost = DoCommand ( v - > tile , this - > selected_vehicle , option - > cargo | ( int ) this - > auto_refit < < 6 | option - > subtype < < 8 |
2011-01-23 13:25:26 +00:00
this - > num_vehicles < < 16 , DC_QUERY_COST , GetCmdRefitVeh ( v - > type ) ) ;
2010-11-16 20:56:04 +00:00
if ( cost . Failed ( ) ) return INVALID_STRING_ID ;
SetDParam ( 0 , option - > cargo ) ;
SetDParam ( 1 , _returned_refit_capacity ) ;
if ( _returned_mail_refit_capacity > 0 ) {
SetDParam ( 2 , CT_MAIL ) ;
SetDParam ( 3 , _returned_mail_refit_capacity ) ;
SetDParam ( 4 , cost . GetCost ( ) ) ;
return STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT ;
} else {
SetDParam ( 2 , cost . GetCost ( ) ) ;
return STR_REFIT_NEW_CAPACITY_COST_OF_REFIT ;
}
}
2009-10-24 20:26:18 +00:00
virtual void DrawWidget ( const Rect & r , int widget ) const
{
switch ( widget ) {
2010-12-21 13:58:09 +00:00
case VRW_VEHICLE_PANEL_DISPLAY : {
Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
DrawVehicleImage ( v , this - > sprite_left + WD_FRAMERECT_LEFT , this - > sprite_right - WD_FRAMERECT_RIGHT ,
2011-11-01 16:51:47 +00:00
r . top + WD_FRAMERECT_TOP , INVALID_VEHICLE , EIT_IN_DETAILS , this - > hscroll ! = NULL ? this - > hscroll - > GetPosition ( ) : 0 ) ;
2010-12-21 13:58:09 +00:00
2010-12-21 14:00:14 +00:00
/* Highlight selected vehicles. */
2011-01-23 13:00:50 +00:00
if ( this - > order ! = INVALID_VEH_ORDER_ID ) break ;
2010-12-21 14:00:14 +00:00
int x = 0 ;
switch ( v - > type ) {
case VEH_TRAIN : {
VehicleSet vehicles_to_refit ;
GetVehicleSet ( vehicles_to_refit , Vehicle : : Get ( this - > selected_vehicle ) , this - > num_vehicles ) ;
int left = INT32_MIN ;
int width = 0 ;
for ( Train * u = Train : : From ( v ) ; u ! = NULL ; u = u - > Next ( ) ) {
/* Start checking. */
if ( vehicles_to_refit . Contains ( u - > index ) & & left = = INT32_MIN ) {
left = x - this - > hscroll - > GetPosition ( ) + r . left + this - > vehicle_margin ;
width = 0 ;
}
/* Draw a selection. */
if ( ( ! vehicles_to_refit . Contains ( u - > index ) | | u - > Next ( ) = = NULL ) & & left ! = INT32_MIN ) {
if ( u - > Next ( ) = = NULL & & vehicles_to_refit . Contains ( u - > index ) ) {
int current_width = u - > GetDisplayImageWidth ( ) ;
width + = current_width ;
x + = current_width ;
}
int right = Clamp ( left + width , 0 , r . right ) ;
left = max ( 0 , left ) ;
if ( _current_text_dir = = TD_RTL ) {
right = this - > GetWidget < NWidgetCore > ( VRW_VEHICLE_PANEL_DISPLAY ) - > current_x - left ;
left = right - width ;
}
if ( left ! = right ) {
DrawFrameRect ( left , r . top + WD_FRAMERECT_TOP , right , r . top + WD_FRAMERECT_TOP + 13 , COLOUR_WHITE , FR_BORDERONLY ) ;
}
left = INT32_MIN ;
}
int current_width = u - > GetDisplayImageWidth ( ) ;
width + = current_width ;
x + = current_width ;
}
break ;
}
default : break ;
}
2010-12-21 13:58:09 +00:00
break ;
}
2009-10-24 20:26:18 +00:00
case VRW_MATRIX :
2010-08-12 08:37:01 +00:00
DrawVehicleRefitWindow ( this - > list , this - > sel , this - > vscroll - > GetPosition ( ) , this - > vscroll - > GetCapacity ( ) , this - > resize . step_height , r ) ;
2009-10-24 20:26:18 +00:00
break ;
2007-02-17 17:12:19 +00:00
2009-10-24 20:26:18 +00:00
case VRW_INFOPANEL :
if ( this - > cargo ! = NULL ) {
2010-11-16 20:56:04 +00:00
StringID string = this - > GetCapacityString ( this - > cargo ) ;
if ( string ! = INVALID_STRING_ID ) {
2009-10-24 20:26:18 +00:00
DrawStringMultiLine ( r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT ,
2010-11-16 20:56:04 +00:00
r . top + WD_FRAMERECT_TOP , r . bottom - WD_FRAMERECT_BOTTOM , string ) ;
2009-10-24 20:26:18 +00:00
}
}
break ;
2008-05-16 23:23:38 +00:00
}
}
2006-09-27 07:23:38 +00:00
2011-03-13 21:31:29 +00:00
/**
* Some data on this window has become invalid .
* @ param data Information about the changed data .
* @ param gui_scope Whether the call is done from GUI scope . You may not do everything when not in GUI scope . See # InvalidateWindowData ( ) for details .
*/
virtual void OnInvalidateData ( int data = 0 , bool gui_scope = true )
2010-04-23 17:29:53 +00:00
{
switch ( data ) {
2011-03-13 21:33:02 +00:00
case - 666 : // Autoreplace replaced the vehicle; selected_vehicle became invalid.
2010-12-21 13:59:16 +00:00
case 0 : { // The consist has changed; rebuild the entire list.
/* Clear the selection. */
Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
this - > selected_vehicle = v - > index ;
this - > num_vehicles = UINT8_MAX ;
/* FALL THROUGH */
}
case 2 : { // The vehicle selection has changed; rebuild the entire list.
2011-03-13 21:33:02 +00:00
if ( ! gui_scope ) break ;
2010-08-13 14:26:29 +00:00
this - > BuildRefitList ( ) ;
2010-12-21 13:59:16 +00:00
2010-12-21 13:58:09 +00:00
/* The vehicle width has changed too. */
2011-11-01 16:51:47 +00:00
this - > vehicle_width = GetVehicleWidth ( Vehicle : : Get ( this - > window_number ) , EIT_IN_DETAILS ) ;
2010-10-15 10:22:04 +00:00
uint max_width = 0 ;
/* Check the width of all cargo information strings. */
for ( uint i = 0 ; i < NUM_CARGO ; i + + ) {
for ( uint j = 0 ; j < this - > list [ i ] . Length ( ) ; j + + ) {
2010-11-16 20:56:04 +00:00
StringID string = this - > GetCapacityString ( & list [ i ] [ j ] ) ;
if ( string ! = INVALID_STRING_ID ) {
Dimension dim = GetStringBoundingBox ( string ) ;
2010-10-15 10:22:04 +00:00
max_width = max ( dim . width , max_width ) ;
}
}
}
if ( this - > information_width < max_width ) {
this - > information_width = max_width ;
this - > ReInit ( ) ;
}
2010-08-01 20:52:11 +00:00
/* FALL THROUGH */
2010-04-23 17:29:53 +00:00
}
case 1 : // A new cargo has been selected.
2011-03-13 21:33:02 +00:00
if ( ! gui_scope ) break ;
2010-08-13 14:28:51 +00:00
this - > cargo = GetRefitOption ( ) ;
2010-04-23 17:29:53 +00:00
break ;
}
}
2010-12-21 13:59:16 +00:00
int GetClickPosition ( int click_x )
{
const NWidgetCore * matrix_widget = this - > GetWidget < NWidgetCore > ( VRW_VEHICLE_PANEL_DISPLAY ) ;
if ( _current_text_dir = = TD_RTL ) click_x = matrix_widget - > current_x - click_x ;
click_x - = this - > vehicle_margin ;
2010-12-21 17:29:00 +00:00
if ( this - > hscroll ! = NULL ) click_x + = this - > hscroll - > GetPosition ( ) ;
2010-12-21 13:59:16 +00:00
return click_x ;
}
void SetSelectedVehicles ( int drag_x )
{
drag_x = GetClickPosition ( drag_x ) ;
int left_x = min ( this - > click_x , drag_x ) ;
int right_x = max ( this - > click_x , drag_x ) ;
this - > num_vehicles = 0 ;
Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
/* Find the vehicle part that was clicked. */
switch ( v - > type ) {
case VEH_TRAIN : {
/* Don't select anything if we are not clicking in the vehicle. */
if ( left_x > = 0 ) {
const Train * u = Train : : From ( v ) ;
bool start_counting = false ;
for ( ; u ! = NULL ; u = u - > Next ( ) ) {
int current_width = u - > GetDisplayImageWidth ( ) ;
left_x - = current_width ;
right_x - = current_width ;
if ( left_x < 0 & & ! start_counting ) {
this - > selected_vehicle = u - > index ;
start_counting = true ;
2011-01-23 14:58:54 +00:00
/* Count the first vehicle, even if articulated part */
this - > num_vehicles + + ;
} else if ( start_counting & & ! u - > IsArticulatedPart ( ) ) {
/* Do not count articulated parts */
this - > num_vehicles + + ;
2010-12-21 13:59:16 +00:00
}
if ( right_x < 0 ) break ;
}
}
/* If the selection is not correct, clear it. */
2010-12-21 14:01:44 +00:00
if ( this - > num_vehicles ! = 0 ) {
if ( _ctrl_pressed ) this - > num_vehicles = UINT8_MAX ;
break ;
}
2010-12-21 13:59:16 +00:00
/* FALL THROUGH */
}
default :
/* Clear the selection. */
this - > selected_vehicle = v - > index ;
this - > num_vehicles = UINT8_MAX ;
break ;
}
}
2010-01-30 18:34:48 +00:00
virtual void OnClick ( Point pt , int widget , int click_count )
2008-05-16 23:23:38 +00:00
{
switch ( widget ) {
2010-12-21 13:59:16 +00:00
case VRW_VEHICLE_PANEL_DISPLAY : { // Vehicle image.
if ( this - > order ! = INVALID_VEH_ORDER_ID ) break ;
NWidgetBase * nwi = this - > GetWidget < NWidgetBase > ( VRW_VEHICLE_PANEL_DISPLAY ) ;
this - > click_x = GetClickPosition ( pt . x - nwi - > pos_x ) ;
this - > SetSelectedVehicles ( pt . x - nwi - > pos_x ) ;
2010-12-21 14:00:14 +00:00
this - > SetWidgetDirty ( VRW_VEHICLE_PANEL_DISPLAY ) ;
2011-02-20 18:32:42 +00:00
if ( ! _ctrl_pressed ) {
SetObjectToPlaceWnd ( SPR_CURSOR_MOUSE , PAL_NONE , HT_DRAG , this ) ;
} else {
/* The vehicle selection has changed. */
this - > InvalidateData ( 2 ) ;
}
2010-12-21 13:59:16 +00:00
break ;
}
2009-04-13 14:04:10 +00:00
case VRW_MATRIX : { // listbox
2010-08-12 08:37:01 +00:00
this - > sel = this - > vscroll - > GetScrolledRowFromWidget ( pt . y , this , VRW_MATRIX ) ;
2010-12-21 13:49:42 +00:00
if ( this - > sel = = INT_MAX ) this - > sel = - 1 ;
this - > SetWidgetDisabledState ( VRW_REFITBUTTON , this - > sel = = - 1 ) ;
2010-07-26 13:08:48 +00:00
this - > InvalidateData ( 1 ) ;
2010-04-23 17:29:53 +00:00
2010-01-30 18:34:48 +00:00
if ( click_count = = 1 ) break ;
2010-08-01 20:52:11 +00:00
/* FALL THROUGH */
2006-09-27 07:23:38 +00:00
}
2010-08-01 20:52:11 +00:00
2009-04-13 14:04:10 +00:00
case VRW_REFITBUTTON : // refit button
2008-05-16 23:23:38 +00:00
if ( this - > cargo ! = NULL ) {
2009-05-16 23:34:14 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2008-05-16 23:23:38 +00:00
if ( this - > order = = INVALID_VEH_ORDER_ID ) {
2010-12-21 14:00:58 +00:00
bool delete_window = this - > selected_vehicle = = v - > index & & this - > num_vehicles = = UINT8_MAX ;
2011-01-23 13:25:26 +00:00
if ( DoCommandP ( v - > tile , this - > selected_vehicle , this - > cargo - > cargo | this - > cargo - > subtype < < 8 | this - > num_vehicles < < 16 , GetCmdRefitVeh ( v ) ) & & delete_window ) delete this ;
2008-05-16 23:23:38 +00:00
} else {
2008-12-28 14:37:19 +00:00
if ( DoCommandP ( v - > tile , v - > index , this - > cargo - > cargo | this - > cargo - > subtype < < 8 | this - > order < < 16 , CMD_ORDER_REFIT ) ) delete this ;
2006-09-27 07:23:38 +00:00
}
2008-05-16 23:23:38 +00:00
}
break ;
}
}
2006-10-01 12:00:32 +00:00
2010-12-21 14:00:14 +00:00
virtual void OnMouseDrag ( Point pt , int widget )
{
switch ( widget ) {
case VRW_VEHICLE_PANEL_DISPLAY : { // Vehicle image.
if ( this - > order ! = INVALID_VEH_ORDER_ID ) break ;
NWidgetBase * nwi = this - > GetWidget < NWidgetBase > ( VRW_VEHICLE_PANEL_DISPLAY ) ;
this - > SetSelectedVehicles ( pt . x - nwi - > pos_x ) ;
this - > SetWidgetDirty ( VRW_VEHICLE_PANEL_DISPLAY ) ;
break ;
}
}
}
2010-12-21 13:59:16 +00:00
virtual void OnDragDrop ( Point pt , int widget )
{
switch ( widget ) {
case VRW_VEHICLE_PANEL_DISPLAY : { // Vehicle image.
if ( this - > order ! = INVALID_VEH_ORDER_ID ) break ;
NWidgetBase * nwi = this - > GetWidget < NWidgetBase > ( VRW_VEHICLE_PANEL_DISPLAY ) ;
this - > SetSelectedVehicles ( pt . x - nwi - > pos_x ) ;
this - > InvalidateData ( 2 ) ;
break ;
}
}
}
2009-10-24 14:53:55 +00:00
virtual void OnResize ( )
2008-05-16 23:23:38 +00:00
{
2011-11-01 16:51:47 +00:00
this - > vehicle_width = GetVehicleWidth ( Vehicle : : Get ( this - > window_number ) , EIT_IN_DETAILS ) ;
2010-08-12 08:37:01 +00:00
this - > vscroll - > SetCapacityFromWidget ( this , VRW_MATRIX ) ;
2010-12-21 13:58:09 +00:00
if ( this - > hscroll ! = NULL ) this - > hscroll - > SetCapacityFromWidget ( this , VRW_VEHICLE_PANEL_DISPLAY ) ;
2010-08-12 08:37:01 +00:00
this - > GetWidget < NWidgetCore > ( VRW_MATRIX ) - > widget_data = ( this - > vscroll - > GetCapacity ( ) < < MAT_ROW_START ) + ( 1 < < MAT_COL_START ) ;
2006-09-27 07:23:38 +00:00
}
2008-05-16 23:23:38 +00:00
} ;
2006-09-27 07:23:38 +00:00
2009-04-13 14:09:56 +00:00
static const NWidgetPart _nested_vehicle_refit_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
2009-04-21 23:40:56 +00:00
NWidget ( WWT_CAPTION , COLOUR_GREY , VRW_CAPTION ) , SetDataTip ( STR_REFIT_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2009-04-13 14:09:56 +00:00
EndContainer ( ) ,
2010-12-21 13:58:09 +00:00
/* Vehicle display + scrollbar. */
NWidget ( NWID_VERTICAL ) ,
NWidget ( WWT_PANEL , COLOUR_GREY , VRW_VEHICLE_PANEL_DISPLAY ) , SetMinimalSize ( 228 , 14 ) , SetResize ( 1 , 0 ) , SetScrollbar ( VRW_HSCROLLBAR ) , EndContainer ( ) ,
NWidget ( NWID_SELECTION , INVALID_COLOUR , VRW_SHOW_HSCROLLBAR ) ,
NWidget ( NWID_HSCROLLBAR , COLOUR_GREY , VRW_HSCROLLBAR ) ,
EndContainer ( ) ,
EndContainer ( ) ,
2009-11-22 19:40:48 +00:00
NWidget ( WWT_TEXTBTN , COLOUR_GREY , VRW_SELECTHEADER ) , SetDataTip ( STR_REFIT_TITLE , STR_NULL ) , SetResize ( 1 , 0 ) ,
2009-04-13 14:09:56 +00:00
/* Matrix + scrollbar. */
NWidget ( NWID_HORIZONTAL ) ,
2010-08-12 06:44:45 +00:00
NWidget ( WWT_MATRIX , COLOUR_GREY , VRW_MATRIX ) , SetMinimalSize ( 228 , 112 ) , SetResize ( 1 , 14 ) , SetFill ( 1 , 1 ) , SetDataTip ( 0x801 , STR_NULL ) , SetScrollbar ( VRW_SCROLLBAR ) ,
2010-08-12 09:16:43 +00:00
NWidget ( NWID_VSCROLLBAR , COLOUR_GREY , VRW_SCROLLBAR ) ,
2009-04-13 14:09:56 +00:00
EndContainer ( ) ,
2009-11-22 19:40:48 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY , VRW_INFOPANEL ) , SetMinimalTextLines ( 2 , WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
2009-04-13 14:09:56 +00:00
NWidget ( NWID_HORIZONTAL ) ,
2009-11-22 19:40:48 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , VRW_REFITBUTTON ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_RESIZEBOX , COLOUR_GREY ) ,
2009-04-13 14:09:56 +00:00
EndContainer ( ) ,
} ;
2009-03-15 15:12:06 +00:00
static const WindowDesc _vehicle_refit_desc (
2009-11-28 14:42:35 +00:00
WDP_AUTO , 240 , 174 ,
2007-04-18 22:10:36 +00:00
WC_VEHICLE_REFIT , WC_VEHICLE_VIEW ,
2009-11-24 17:28:29 +00:00
WDF_UNCLICK_BUTTONS | WDF_CONSTRUCTION ,
2009-11-15 10:26:01 +00:00
_nested_vehicle_refit_widgets , lengthof ( _nested_vehicle_refit_widgets )
2009-03-15 15:12:06 +00:00
) ;
2006-09-27 07:23:38 +00:00
2010-08-01 19:22:34 +00:00
/**
* Show the refit window for a vehicle
2009-03-14 18:16:29 +00:00
* @ param * v The vehicle to show the refit window for
* @ param order of the vehicle ( ? )
2009-09-19 09:51:14 +00:00
* @ param parent the parent window of the refit window
2011-11-04 00:38:59 +00:00
* @ param auto_refit Choose cargo for auto - refitting
2009-03-14 18:16:29 +00:00
*/
2011-11-04 00:38:59 +00:00
void ShowVehicleRefitWindow ( const Vehicle * v , VehicleOrderID order , Window * parent , bool auto_refit )
2006-09-27 07:23:38 +00:00
{
DeleteWindowById ( WC_VEHICLE_REFIT , v - > index ) ;
2011-11-04 00:38:59 +00:00
RefitWindow * w = new RefitWindow ( & _vehicle_refit_desc , v , order , auto_refit ) ;
2008-09-24 16:40:06 +00:00
w - > parent = parent ;
2006-09-27 07:23:38 +00:00
}
2007-04-04 04:08:47 +00:00
/** Display list of cargo types of the engine, for the purchase information window */
2009-03-22 11:06:25 +00:00
uint ShowRefitOptionsList ( int left , int right , int y , EngineID engine )
2006-10-23 21:39:15 +00:00
{
/* List of cargo types of this engine */
2009-10-06 19:52:38 +00:00
uint32 cmask = GetUnionOfArticulatedRefitMasks ( engine , false ) ;
2006-10-23 21:39:15 +00:00
/* List of cargo types available in this climate */
2007-02-22 22:09:51 +00:00
uint32 lmask = _cargo_mask ;
2008-07-17 13:47:04 +00:00
char string [ 512 ] ;
char * b = string ;
2006-10-23 21:39:15 +00:00
/* Draw nothing if the engine is not refittable */
2010-02-05 17:05:58 +00:00
if ( HasAtMostOneBit ( cmask ) ) return y ;
2006-10-23 21:39:15 +00:00
b = InlineString ( b , STR_PURCHASE_INFO_REFITTABLE_TO ) ;
if ( cmask = = lmask ) {
/* Engine can be refitted to all types in this climate */
b = InlineString ( b , STR_PURCHASE_INFO_ALL_TYPES ) ;
} else {
/* Check if we are able to refit to more cargo types and unable to. If
* so , invert the cargo types to list those that we can ' t refit to . */
2010-11-04 19:48:25 +00:00
if ( CountBits ( cmask ^ lmask ) < CountBits ( cmask ) & & CountBits ( cmask ^ lmask ) < = 7 ) {
2006-10-23 21:39:15 +00:00
cmask ^ = lmask ;
b = InlineString ( b , STR_PURCHASE_INFO_ALL_BUT ) ;
}
2007-02-22 22:09:51 +00:00
bool first = true ;
2006-10-23 21:39:15 +00:00
/* Add each cargo type to the list */
2010-04-16 18:49:24 +00:00
const CargoSpec * cs ;
FOR_ALL_SORTED_CARGOSPECS ( cs ) {
if ( ! HasBit ( cmask , cs - > Index ( ) ) ) continue ;
2007-02-22 22:09:51 +00:00
2008-07-17 13:47:04 +00:00
if ( b > = lastof ( string ) - ( 2 + 2 * 4 ) ) break ; // ", " and two calls to Utf8Encode()
2007-12-08 18:50:39 +00:00
2008-07-17 13:47:04 +00:00
if ( ! first ) b = strecpy ( b , " , " , lastof ( string ) ) ;
2007-02-22 22:09:51 +00:00
first = false ;
2006-10-23 21:39:15 +00:00
2010-04-16 18:49:24 +00:00
b = InlineString ( b , cs - > name ) ;
2006-10-23 21:39:15 +00:00
}
}
/* Terminate and display the completed string */
* b = ' \0 ' ;
2007-12-08 18:50:39 +00:00
/* Make sure we detect any buffer overflow */
2008-07-17 13:47:04 +00:00
assert ( b < endof ( string ) ) ;
2007-12-08 18:50:39 +00:00
2008-07-17 21:15:57 +00:00
SetDParamStr ( 0 , string ) ;
2009-03-22 11:06:25 +00:00
return DrawStringMultiLine ( left , right , y , INT32_MAX , STR_JUST_RAW_STRING ) ;
2006-10-23 21:39:15 +00:00
}
2009-02-14 18:42:03 +00:00
/** Get the cargo subtype text from NewGRF for the vehicle details window. */
StringID GetCargoSubtypeText ( const Vehicle * v )
{
2009-09-14 12:22:57 +00:00
if ( HasBit ( EngInfo ( v - > engine_type ) - > callback_mask , CBM_VEHICLE_CARGO_SUFFIX ) ) {
2009-02-14 18:42:03 +00:00
uint16 cb = GetVehicleCallback ( CBID_VEHICLE_CARGO_SUFFIX , 0 , 0 , v - > engine_type , v ) ;
2011-11-08 17:24:43 +00:00
if ( cb ! = CALLBACK_FAILED ) {
if ( cb > 0x400 ) ErrorUnknownCallbackResult ( v - > GetGRFID ( ) , CBID_VEHICLE_CARGO_SUFFIX , cb ) ;
if ( cb > = 0x400 | | ( v - > GetGRF ( ) - > grf_version < 8 & & cb = = 0xFF ) ) cb = CALLBACK_FAILED ;
}
2009-02-14 18:42:03 +00:00
if ( cb ! = CALLBACK_FAILED ) {
2011-11-01 00:23:41 +00:00
return GetGRFStringID ( v - > GetGRFID ( ) , 0xD000 + cb ) ;
2009-02-14 18:42:03 +00:00
}
}
return STR_EMPTY ;
}
2004-09-06 18:15:13 +00:00
2008-06-15 22:10:22 +00:00
/** Sort vehicles by their number */
2009-01-10 00:31:47 +00:00
static int CDECL VehicleNumberSorter ( const Vehicle * const * a , const Vehicle * const * b )
2004-09-06 21:20:01 +00:00
{
2008-06-15 22:10:22 +00:00
return ( * a ) - > unitnumber - ( * b ) - > unitnumber ;
2004-09-06 21:20:01 +00:00
}
2008-06-15 22:10:22 +00:00
/** Sort vehicles by their name */
2009-01-10 00:31:47 +00:00
static int CDECL VehicleNameSorter ( const Vehicle * const * a , const Vehicle * const * b )
2004-09-06 18:15:13 +00:00
{
2008-06-15 22:10:22 +00:00
static char last_name [ 2 ] [ 64 ] ;
2004-09-06 18:15:13 +00:00
2008-06-15 22:10:22 +00:00
if ( * a ! = _last_vehicle [ 0 ] ) {
_last_vehicle [ 0 ] = * a ;
SetDParam ( 0 , ( * a ) - > index ) ;
GetString ( last_name [ 0 ] , STR_VEHICLE_NAME , lastof ( last_name [ 0 ] ) ) ;
2004-09-06 18:15:13 +00:00
}
2008-06-15 22:10:22 +00:00
if ( * b ! = _last_vehicle [ 1 ] ) {
_last_vehicle [ 1 ] = * b ;
SetDParam ( 0 , ( * b ) - > index ) ;
GetString ( last_name [ 1 ] , STR_VEHICLE_NAME , lastof ( last_name [ 1 ] ) ) ;
}
2004-09-06 21:20:01 +00:00
2010-11-27 22:52:12 +00:00
int r = strnatcmp ( last_name [ 0 ] , last_name [ 1 ] ) ; // Sort by name (natural sorting).
2008-06-15 22:10:22 +00:00
return ( r ! = 0 ) ? r : VehicleNumberSorter ( a , b ) ;
2004-09-06 18:15:13 +00:00
}
2008-06-15 22:10:22 +00:00
/** Sort vehicles by their age */
2009-01-10 00:31:47 +00:00
static int CDECL VehicleAgeSorter ( const Vehicle * const * a , const Vehicle * const * b )
2004-09-06 18:15:13 +00:00
{
2008-06-15 22:10:22 +00:00
int r = ( * a ) - > age - ( * b ) - > age ;
return ( r ! = 0 ) ? r : VehicleNumberSorter ( a , b ) ;
2004-09-06 21:20:01 +00:00
}
2008-06-15 22:10:22 +00:00
/** Sort vehicles by this year profit */
2009-01-10 00:31:47 +00:00
static int CDECL VehicleProfitThisYearSorter ( const Vehicle * const * a , const Vehicle * const * b )
2004-09-06 21:20:01 +00:00
{
2008-06-15 22:10:22 +00:00
int r = ClampToI32 ( ( * a ) - > GetDisplayProfitThisYear ( ) - ( * b ) - > GetDisplayProfitThisYear ( ) ) ;
return ( r ! = 0 ) ? r : VehicleNumberSorter ( a , b ) ;
2004-09-06 21:20:01 +00:00
}
2008-06-15 22:10:22 +00:00
/** Sort vehicles by last year profit */
2009-01-10 00:31:47 +00:00
static int CDECL VehicleProfitLastYearSorter ( const Vehicle * const * a , const Vehicle * const * b )
2004-09-06 21:20:01 +00:00
{
2008-06-15 22:10:22 +00:00
int r = ClampToI32 ( ( * a ) - > GetDisplayProfitLastYear ( ) - ( * b ) - > GetDisplayProfitLastYear ( ) ) ;
return ( r ! = 0 ) ? r : VehicleNumberSorter ( a , b ) ;
2004-09-06 21:20:01 +00:00
}
2008-06-15 22:10:22 +00:00
/** Sort vehicles by their cargo */
2009-01-10 00:31:47 +00:00
static int CDECL VehicleCargoSorter ( const Vehicle * const * a , const Vehicle * const * b )
2004-09-06 21:20:01 +00:00
{
2008-06-15 22:10:22 +00:00
const Vehicle * v ;
2009-06-27 18:26:50 +00:00
CargoArray diff ;
2004-09-06 21:20:01 +00:00
2008-06-15 22:10:22 +00:00
/* Append the cargo of the connected weagons */
for ( v = * a ; v ! = NULL ; v = v - > Next ( ) ) diff [ v - > cargo_type ] + = v - > cargo_cap ;
for ( v = * b ; v ! = NULL ; v = v - > Next ( ) ) diff [ v - > cargo_type ] - = v - > cargo_cap ;
2004-09-06 21:20:01 +00:00
2008-06-15 22:10:22 +00:00
int r = 0 ;
2007-03-21 13:19:01 +00:00
for ( CargoID i = 0 ; i < NUM_CARGO ; i + + ) {
2008-06-15 22:10:22 +00:00
r = diff [ i ] ;
2005-10-23 13:04:44 +00:00
if ( r ! = 0 ) break ;
2004-09-06 18:15:13 +00:00
}
2004-09-06 21:20:01 +00:00
2008-06-15 22:10:22 +00:00
return ( r ! = 0 ) ? r : VehicleNumberSorter ( a , b ) ;
2004-09-06 21:20:01 +00:00
}
2008-06-15 22:10:22 +00:00
/** Sort vehicles by their reliability */
2009-01-10 00:31:47 +00:00
static int CDECL VehicleReliabilitySorter ( const Vehicle * const * a , const Vehicle * const * b )
2004-09-06 21:20:01 +00:00
{
2008-06-15 22:10:22 +00:00
int r = ( * a ) - > reliability - ( * b ) - > reliability ;
return ( r ! = 0 ) ? r : VehicleNumberSorter ( a , b ) ;
2004-09-06 18:15:13 +00:00
}
2004-09-06 21:20:01 +00:00
2008-06-15 22:10:22 +00:00
/** Sort vehicles by their max speed */
2009-01-10 00:31:47 +00:00
static int CDECL VehicleMaxSpeedSorter ( const Vehicle * const * a , const Vehicle * const * b )
2004-09-06 21:20:01 +00:00
{
2010-11-06 13:05:11 +00:00
int r = ( * a ) - > vcache . cached_max_speed - ( * b ) - > vcache . cached_max_speed ;
2008-06-15 22:10:22 +00:00
return ( r ! = 0 ) ? r : VehicleNumberSorter ( a , b ) ;
2004-09-10 19:02:27 +00:00
}
2005-01-02 17:23:04 +00:00
2008-06-15 22:10:22 +00:00
/** Sort vehicles by model */
2009-01-10 00:31:47 +00:00
static int CDECL VehicleModelSorter ( const Vehicle * const * a , const Vehicle * const * b )
2006-02-03 18:32:59 +00:00
{
2008-06-15 22:10:22 +00:00
int r = ( * a ) - > engine_type - ( * b ) - > engine_type ;
return ( r ! = 0 ) ? r : VehicleNumberSorter ( a , b ) ;
2006-02-03 18:32:59 +00:00
}
2008-06-15 22:10:22 +00:00
/** Sort vehciles by their value */
2009-01-10 00:31:47 +00:00
static int CDECL VehicleValueSorter ( const Vehicle * const * a , const Vehicle * const * b )
2006-02-03 18:32:59 +00:00
{
const Vehicle * u ;
2008-06-15 22:10:22 +00:00
Money diff = 0 ;
2006-02-03 18:32:59 +00:00
2008-06-15 22:10:22 +00:00
for ( u = * a ; u ! = NULL ; u = u - > Next ( ) ) diff + = u - > value ;
for ( u = * b ; u ! = NULL ; u = u - > Next ( ) ) diff - = u - > value ;
2006-02-03 18:32:59 +00:00
2008-06-15 22:10:22 +00:00
int r = ClampToI32 ( diff ) ;
return ( r ! = 0 ) ? r : VehicleNumberSorter ( a , b ) ;
2006-02-03 18:32:59 +00:00
}
2008-06-15 22:10:22 +00:00
/** Sort vehicles by their length */
2009-01-10 00:31:47 +00:00
static int CDECL VehicleLengthSorter ( const Vehicle * const * a , const Vehicle * const * b )
2008-04-18 10:58:11 +00:00
{
2010-12-14 21:33:53 +00:00
int r = ( * a ) - > GetGroundVehicleCache ( ) - > cached_total_length - ( * b ) - > GetGroundVehicleCache ( ) - > cached_total_length ;
2008-06-15 22:10:22 +00:00
return ( r ! = 0 ) ? r : VehicleNumberSorter ( a , b ) ;
2008-04-18 10:58:11 +00:00
}
2008-09-17 02:30:24 +00:00
/** Sort vehicles by the time they can still live */
2009-01-10 00:31:47 +00:00
static int CDECL VehicleTimeToLiveSorter ( const Vehicle * const * a , const Vehicle * const * b )
2008-09-17 02:30:24 +00:00
{
int r = ClampToI32 ( ( ( * a ) - > max_age - ( * a ) - > age ) - ( ( * b ) - > max_age - ( * b ) - > age ) ) ;
return ( r ! = 0 ) ? r : VehicleNumberSorter ( a , b ) ;
}
2009-08-15 10:51:33 +00:00
/** Sort vehicles by the timetable delay */
static int CDECL VehicleTimetableDelaySorter ( const Vehicle * const * a , const Vehicle * const * b )
{
int r = ( * a ) - > lateness_counter - ( * b ) - > lateness_counter ;
return ( r ! = 0 ) ? r : VehicleNumberSorter ( a , b ) ;
}
2007-03-07 11:47:46 +00:00
void InitializeGUI ( )
2005-01-31 11:03:23 +00:00
{
2008-06-15 22:10:22 +00:00
MemSetT ( & _sorting , 0 ) ;
2005-01-31 11:03:23 +00:00
}
2005-10-24 19:40:48 +00:00
2008-08-06 18:57:37 +00:00
/**
* Assign a vehicle window a new vehicle
* @ param window_class WindowClass to search for
* @ param from_index the old vehicle ID
* @ param to_index the new vehicle ID
2005-11-14 19:48:04 +00:00
*/
2008-08-06 18:57:37 +00:00
static inline void ChangeVehicleWindow ( WindowClass window_class , VehicleID from_index , VehicleID to_index )
2005-10-24 19:40:48 +00:00
{
2008-08-06 18:57:37 +00:00
Window * w = FindWindowById ( window_class , from_index ) ;
2005-10-24 19:40:48 +00:00
if ( w ! = NULL ) {
2011-02-05 23:10:31 +00:00
/* Update window_number */
2008-04-27 18:05:48 +00:00
w - > window_number = to_index ;
2008-08-06 18:57:37 +00:00
if ( w - > viewport ! = NULL ) w - > viewport - > follow_vehicle = to_index ;
2011-02-05 23:10:31 +00:00
/* Update vehicle drag data */
if ( _thd . window_class = = window_class & & _thd . window_number = = ( WindowNumber ) from_index ) {
_thd . window_number = to_index ;
}
2011-03-13 21:33:02 +00:00
/* Notify the window. */
w - > InvalidateData ( - 666 , false ) ;
2005-10-24 19:40:48 +00:00
}
}
2006-08-29 17:41:13 +00:00
2008-08-06 18:57:37 +00:00
/**
* Report a change in vehicle IDs ( due to autoreplace ) to affected vehicle windows .
* @ param from_index the old vehicle ID
* @ param to_index the new vehicle ID
*/
void ChangeVehicleViewWindow ( VehicleID from_index , VehicleID to_index )
{
ChangeVehicleWindow ( WC_VEHICLE_VIEW , from_index , to_index ) ;
ChangeVehicleWindow ( WC_VEHICLE_ORDERS , from_index , to_index ) ;
ChangeVehicleWindow ( WC_VEHICLE_REFIT , from_index , to_index ) ;
ChangeVehicleWindow ( WC_VEHICLE_DETAILS , from_index , to_index ) ;
ChangeVehicleWindow ( WC_VEHICLE_TIMETABLE , from_index , to_index ) ;
}
2006-12-07 00:51:20 +00:00
enum VehicleListWindowWidgets {
2006-09-28 23:05:03 +00:00
VLW_WIDGET_CAPTION ,
VLW_WIDGET_SORT_ORDER ,
VLW_WIDGET_SORT_BY_PULLDOWN ,
VLW_WIDGET_LIST ,
VLW_WIDGET_SCROLLBAR ,
2009-10-25 15:08:16 +00:00
VLW_WIDGET_HIDE_BUTTONS ,
2007-01-26 19:24:02 +00:00
VLW_WIDGET_AVAILABLE_VEHICLES ,
2006-12-07 14:03:55 +00:00
VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN ,
2006-09-29 11:30:48 +00:00
VLW_WIDGET_STOP_ALL ,
VLW_WIDGET_START_ALL ,
2006-09-28 23:05:03 +00:00
} ;
2009-03-22 21:16:57 +00:00
static const NWidgetPart _nested_vehicle_list [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
2009-11-22 11:20:12 +00:00
NWidget ( WWT_CAPTION , COLOUR_GREY , VLW_WIDGET_CAPTION ) ,
2009-12-21 16:24:29 +00:00
NWidget ( WWT_SHADEBOX , COLOUR_GREY ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_STICKYBOX , COLOUR_GREY ) ,
2009-03-22 21:16:57 +00:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2009-11-22 18:26:01 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , VLW_WIDGET_SORT_ORDER ) , SetMinimalSize ( 81 , 12 ) , SetFill ( 0 , 1 ) , SetDataTip ( STR_BUTTON_SORT_BY , STR_TOOLTIP_SORT_ORDER ) ,
2010-02-10 20:20:18 +00:00
NWidget ( WWT_DROPDOWN , COLOUR_GREY , VLW_WIDGET_SORT_BY_PULLDOWN ) , SetMinimalSize ( 167 , 12 ) , SetFill ( 0 , 1 ) , SetDataTip ( 0x0 , STR_TOOLTIP_SORT_CRITERIA ) ,
2009-11-24 21:13:36 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY ) , SetMinimalSize ( 12 , 12 ) , SetFill ( 1 , 1 ) , SetResize ( 1 , 0 ) ,
2009-03-22 21:16:57 +00:00
EndContainer ( ) ,
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2010-08-12 06:44:45 +00:00
NWidget ( WWT_MATRIX , COLOUR_GREY , VLW_WIDGET_LIST ) , SetMinimalSize ( 248 , 0 ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 1 ) , SetScrollbar ( VLW_WIDGET_SCROLLBAR ) ,
2010-08-12 09:16:43 +00:00
NWidget ( NWID_VSCROLLBAR , COLOUR_GREY , VLW_WIDGET_SCROLLBAR ) ,
2009-03-22 21:16:57 +00:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2009-10-25 15:08:16 +00:00
NWidget ( NWID_SELECTION , INVALID_COLOUR , VLW_WIDGET_HIDE_BUTTONS ) ,
2009-03-22 21:16:57 +00:00
NWidget ( NWID_HORIZONTAL ) ,
2009-11-22 18:26:01 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , VLW_WIDGET_AVAILABLE_VEHICLES ) , SetMinimalSize ( 106 , 12 ) , SetFill ( 0 , 1 ) ,
2010-07-30 12:26:58 +00:00
SetDataTip ( STR_BLACK_STRING , STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP ) ,
2009-11-22 18:26:01 +00:00
NWidget ( WWT_DROPDOWN , COLOUR_GREY , VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN ) , SetMinimalSize ( 118 , 12 ) , SetFill ( 0 , 1 ) ,
2009-08-05 17:59:21 +00:00
SetDataTip ( STR_VEHICLE_LIST_MANAGE_LIST , STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP ) ,
2009-11-22 18:26:01 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , VLW_WIDGET_STOP_ALL ) , SetMinimalSize ( 12 , 12 ) , SetFill ( 0 , 1 ) ,
2009-08-05 17:59:21 +00:00
SetDataTip ( SPR_FLAG_VEH_STOPPED , STR_VEHICLE_LIST_MASS_STOP_LIST_TOOLTIP ) ,
2009-11-22 18:26:01 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , VLW_WIDGET_START_ALL ) , SetMinimalSize ( 12 , 12 ) , SetFill ( 0 , 1 ) ,
2009-08-05 17:59:21 +00:00
SetDataTip ( SPR_FLAG_VEH_RUNNING , STR_VEHICLE_LIST_MASS_START_LIST_TOOLTIP ) ,
2009-12-09 08:23:10 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY ) , SetMinimalSize ( 0 , 12 ) , SetResize ( 1 , 0 ) , SetFill ( 1 , 1 ) , EndContainer ( ) ,
2009-03-22 21:16:57 +00:00
EndContainer ( ) ,
2009-10-25 15:08:16 +00:00
/* Widget to be shown for other companies hiding the previous 5 widgets. */
2009-11-24 21:13:36 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY ) , SetFill ( 1 , 1 ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
2009-03-22 21:16:57 +00:00
EndContainer ( ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_RESIZEBOX , COLOUR_GREY ) ,
2009-03-22 21:16:57 +00:00
EndContainer ( ) ,
} ;
2009-11-26 11:34:12 +00:00
static void DrawSmallOrderList ( const Vehicle * v , int left , int right , int y , VehicleOrderID start = 0 )
2006-10-05 08:15:51 +00:00
{
2009-11-26 11:34:12 +00:00
const Order * order = v - > GetOrder ( start ) ;
if ( order = = NULL ) return ;
2006-10-05 08:15:51 +00:00
2009-11-26 11:34:12 +00:00
int i = 0 ;
VehicleOrderID oid = start ;
2006-10-05 08:15:51 +00:00
2009-11-26 11:34:12 +00:00
do {
2011-01-31 20:44:15 +00:00
if ( oid = = v - > cur_real_order_index ) DrawString ( left , right , y , STR_TINY_RIGHT_ARROW , TC_BLACK ) ;
2006-10-05 08:15:51 +00:00
2008-04-05 23:36:54 +00:00
if ( order - > IsType ( OT_GOTO_STATION ) ) {
2008-04-06 07:48:51 +00:00
SetDParam ( 0 , order - > GetDestination ( ) ) ;
2009-11-17 11:36:36 +00:00
DrawString ( left + 6 , right - 6 , y , STR_TINY_BLACK_STATION ) ;
2006-10-05 08:15:51 +00:00
2009-11-16 21:39:47 +00:00
y + = FONT_HEIGHT_SMALL ;
2006-10-05 08:15:51 +00:00
if ( + + i = = 4 ) break ;
}
2009-11-26 11:34:12 +00:00
oid + + ;
order = order - > next ;
if ( order = = NULL ) {
order = v - > orders . list - > GetFirstOrder ( ) ;
oid = 0 ;
}
} while ( oid ! = start ) ;
2006-10-05 08:15:51 +00:00
}
2009-07-12 16:00:11 +00:00
/**
* Draws an image of a vehicle chain
2009-11-16 22:25:01 +00:00
* @ param v Front vehicle
* @ param left The minimum horizontal position
* @ param right The maximum horizontal position
* @ param y Vertical position to draw at
2009-09-19 09:51:14 +00:00
* @ param selection Selected vehicle to draw a frame around
2009-11-16 22:25:01 +00:00
* @ param skip Number of pixels to skip at the front ( for scrolling )
2009-07-12 16:00:11 +00:00
*/
2011-11-01 16:51:47 +00:00
void DrawVehicleImage ( const Vehicle * v , int left , int right , int y , VehicleID selection , EngineImageType image_type , int skip )
2008-09-13 10:04:36 +00:00
{
switch ( v - > type ) {
2011-11-01 16:51:47 +00:00
case VEH_TRAIN : DrawTrainImage ( Train : : From ( v ) , left , right , y , selection , image_type , skip ) ; break ;
case VEH_ROAD : DrawRoadVehImage ( v , left , right , y , selection , image_type , skip ) ; break ;
case VEH_SHIP : DrawShipImage ( v , left , right , y , selection , image_type ) ; break ;
case VEH_AIRCRAFT : DrawAircraftImage ( v , left , right , y , selection , image_type ) ; break ;
2008-09-13 10:04:36 +00:00
default : NOT_REACHED ( ) ;
}
}
2009-11-16 21:28:12 +00:00
/**
* Get the height of a vehicle in the vehicle list GUIs .
* @ param type the vehicle type to look at
* @ param divisor the resulting height must be dividable by this
* @ return the height
*/
uint GetVehicleListHeight ( VehicleType type , uint divisor )
{
2009-11-16 21:39:47 +00:00
/* Name + vehicle + profit */
2009-11-16 21:28:12 +00:00
uint base = GetVehicleHeight ( type ) + 2 * FONT_HEIGHT_SMALL ;
2009-11-16 21:39:47 +00:00
/* Drawing of the 4 small orders + profit*/
if ( type > = VEH_SHIP ) base = max ( base , 5U * FONT_HEIGHT_SMALL ) ;
2009-11-16 21:28:12 +00:00
if ( divisor = = 1 ) return base ;
/* Make sure the height is dividable by divisor */
uint rem = base % divisor ;
return base + ( rem = = 0 ? 0 : divisor - rem ) ;
}
2008-09-13 10:04:36 +00:00
/**
* Draw all the vehicle list items .
2009-10-25 13:33:56 +00:00
* @ param selected_vehicle The vehicle that is to be highlighted .
* @ param line_height Height of a single item line .
* @ param r Rectangle with edge positions of the matrix widget .
2008-09-13 10:04:36 +00:00
*/
2009-10-25 14:52:46 +00:00
void BaseVehicleListWindow : : DrawVehicleListItems ( VehicleID selected_vehicle , int line_height , const Rect & r ) const
2008-09-13 10:04:36 +00:00
{
2009-10-25 13:33:56 +00:00
int left = r . left + WD_MATRIX_LEFT ;
int right = r . right - WD_MATRIX_RIGHT ;
2009-11-17 11:36:36 +00:00
int width = right - left ;
2010-11-13 09:56:25 +00:00
bool rtl = _current_text_dir = = TD_RTL ;
2009-11-16 21:28:12 +00:00
2009-12-20 16:44:41 +00:00
int text_offset = GetDigitWidth ( ) * this - > unitnumber_digits + WD_FRAMERECT_RIGHT ;
2009-11-17 09:09:20 +00:00
int text_left = left + ( rtl ? 0 : text_offset ) ;
int text_right = right - ( rtl ? text_offset : 0 ) ;
2009-11-16 21:28:12 +00:00
2010-09-09 14:40:39 +00:00
bool show_orderlist = this - > vli . vtype > = VEH_SHIP ;
2009-11-17 11:36:36 +00:00
int orderlist_left = left + ( rtl ? 0 : max ( 100 + text_offset , width / 2 ) ) ;
int orderlist_right = right - ( rtl ? max ( 100 + text_offset , width / 2 ) : 0 ) ;
int image_left = ( rtl & & show_orderlist ) ? orderlist_right : text_left ;
int image_right = ( ! rtl & & show_orderlist ) ? orderlist_left : text_right ;
2009-11-16 21:28:12 +00:00
2010-09-02 20:00:48 +00:00
int vehicle_button_x = rtl ? right - GetSpriteSize ( SPR_PROFIT_LOT ) . width : left ;
2009-11-16 21:28:12 +00:00
2009-10-25 13:33:56 +00:00
int y = r . top ;
2010-08-12 08:37:01 +00:00
uint max = min ( this - > vscroll - > GetPosition ( ) + this - > vscroll - > GetCapacity ( ) , this - > vehicles . Length ( ) ) ;
for ( uint i = this - > vscroll - > GetPosition ( ) ; i < max ; + + i ) {
2008-09-13 10:04:36 +00:00
const Vehicle * v = this - > vehicles [ i ] ;
StringID str ;
SetDParam ( 0 , v - > GetDisplayProfitThisYear ( ) ) ;
SetDParam ( 1 , v - > GetDisplayProfitLastYear ( ) ) ;
2011-11-01 16:51:47 +00:00
DrawVehicleImage ( v , image_left , image_right , y + FONT_HEIGHT_SMALL - 1 , selected_vehicle , EIT_IN_LIST , 0 ) ;
2009-11-16 21:28:12 +00:00
DrawString ( text_left , text_right , y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1 , STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR ) ;
2008-09-13 10:04:36 +00:00
if ( v - > name ! = NULL ) {
/* The vehicle got a name so we will print it */
SetDParam ( 0 , v - > index ) ;
2009-11-16 21:28:12 +00:00
DrawString ( text_left , text_right , y , STR_TINY_BLACK_VEHICLE ) ;
2008-11-20 16:48:22 +00:00
} else if ( v - > group_id ! = DEFAULT_GROUP ) {
/* The vehicle has no name, but is member of a group, so print group name */
SetDParam ( 0 , v - > group_id ) ;
2009-11-16 21:28:12 +00:00
DrawString ( text_left , text_right , y , STR_TINY_GROUP , TC_BLACK ) ;
2008-09-13 10:04:36 +00:00
}
2011-01-31 20:44:15 +00:00
if ( show_orderlist ) DrawSmallOrderList ( v , orderlist_left , orderlist_right , y , v - > cur_real_order_index ) ;
2008-09-13 10:04:36 +00:00
if ( v - > IsInDepot ( ) ) {
2009-07-23 19:31:50 +00:00
str = STR_BLUE_COMMA ;
2008-09-13 10:04:36 +00:00
} else {
2009-04-21 23:40:56 +00:00
str = ( v - > age > v - > max_age - DAYS_IN_LEAP_YEAR ) ? STR_RED_COMMA : STR_BLACK_COMMA ;
2008-09-13 10:04:36 +00:00
}
SetDParam ( 0 , v - > unitnumber ) ;
2009-08-15 11:47:11 +00:00
DrawString ( left , right , y + 2 , str ) ;
2008-09-13 10:04:36 +00:00
2009-11-16 21:28:12 +00:00
DrawVehicleProfitButton ( v , vehicle_button_x , y + FONT_HEIGHT_NORMAL + 3 ) ;
2008-09-13 10:04:36 +00:00
2009-10-25 13:33:56 +00:00
y + = line_height ;
2008-09-13 10:04:36 +00:00
}
}
2008-05-11 15:00:11 +00:00
/**
* Window for the ( old ) vehicle listing .
*
* bitmask for w - > window_number
2008-09-30 20:39:50 +00:00
* 0 - 7 CompanyID ( owner )
2008-05-11 15:00:11 +00:00
* 8 - 10 window type ( use flags in vehicle_gui . h )
* 11 - 15 vehicle type ( using VEH_ , but can be compressed to fewer bytes if needed )
* 16 - 31 StationID or OrderID depending on window type ( bit 8 - 10 )
*/
2008-09-13 10:04:36 +00:00
struct VehicleListWindow : public BaseVehicleListWindow {
2009-10-25 15:08:16 +00:00
private :
/** Enumeration of planes of the button row at the bottom. */
enum ButtonPlanes {
BP_SHOW_BUTTONS , ///< Show the buttons.
BP_HIDE_BUTTONS , ///< Show the empty panel.
} ;
public :
2010-09-09 14:40:39 +00:00
VehicleListWindow ( const WindowDesc * desc , WindowNumber window_number ) : BaseVehicleListWindow ( window_number )
2008-05-11 15:00:11 +00:00
{
2009-10-30 20:51:36 +00:00
/* Set up sorting. Make the window-specific _sorting variable
* point to the correct global _sorting struct so we are freed
* from having conditionals during window operation */
2010-09-09 14:40:39 +00:00
switch ( this - > vli . vtype ) {
2009-10-30 20:51:36 +00:00
case VEH_TRAIN : this - > sorting = & _sorting . train ; break ;
case VEH_ROAD : this - > sorting = & _sorting . roadveh ; break ;
case VEH_SHIP : this - > sorting = & _sorting . ship ; break ;
case VEH_AIRCRAFT : this - > sorting = & _sorting . aircraft ; break ;
default : NOT_REACHED ( ) ;
}
2010-08-12 08:37:01 +00:00
this - > CreateNestedTree ( desc ) ;
this - > vscroll = this - > GetScrollbar ( VLW_WIDGET_SCROLLBAR ) ;
2009-10-30 20:51:36 +00:00
this - > vehicles . SetListing ( * this - > sorting ) ;
this - > vehicles . ForceRebuild ( ) ;
this - > vehicles . NeedResort ( ) ;
2010-09-09 14:40:39 +00:00
this - > BuildVehicleList ( ) ;
2009-10-30 20:51:36 +00:00
this - > SortVehicleList ( ) ;
2008-05-11 15:00:11 +00:00
/* Set up the window widgets */
2010-09-09 14:40:39 +00:00
this - > GetWidget < NWidgetCore > ( VLW_WIDGET_LIST ) - > tool_tip = STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP + this - > vli . vtype ;
2006-09-28 18:13:31 +00:00
2010-09-09 14:40:39 +00:00
if ( this - > vli . type = = VL_SHARED_ORDERS ) {
2009-10-25 15:08:16 +00:00
this - > GetWidget < NWidgetCore > ( VLW_WIDGET_CAPTION ) - > widget_data = STR_VEHICLE_LIST_SHARED_ORDERS_LIST_CAPTION ;
2009-07-20 11:12:59 +00:00
} else {
2010-09-09 14:40:39 +00:00
this - > GetWidget < NWidgetCore > ( VLW_WIDGET_CAPTION ) - > widget_data = STR_VEHICLE_LIST_TRAIN_CAPTION + this - > vli . vtype ;
2006-10-05 08:15:51 +00:00
}
2006-09-28 18:13:31 +00:00
2009-10-25 15:08:16 +00:00
this - > FinishInitNested ( desc , window_number ) ;
2010-09-09 14:40:39 +00:00
this - > owner = this - > vli . company ;
2006-09-03 23:27:38 +00:00
2010-09-09 14:40:39 +00:00
if ( this - > vli . vtype = = VEH_TRAIN ) ResizeWindow ( this , 65 , 0 ) ;
2008-05-11 15:00:11 +00:00
}
2006-08-29 17:41:13 +00:00
2008-05-11 15:00:11 +00:00
~ VehicleListWindow ( )
{
2008-06-16 17:09:52 +00:00
* this - > sorting = this - > vehicles . GetListing ( ) ;
2006-09-28 18:13:31 +00:00
}
2009-11-22 18:28:14 +00:00
virtual void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize )
2008-05-11 15:00:11 +00:00
{
2010-07-17 15:03:07 +00:00
switch ( widget ) {
case VLW_WIDGET_LIST :
2010-09-09 14:40:39 +00:00
resize - > height = GetVehicleListHeight ( this - > vli . vtype , 1 ) ;
2010-07-17 15:03:07 +00:00
2010-09-09 14:40:39 +00:00
switch ( this - > vli . vtype ) {
2010-07-17 15:03:07 +00:00
case VEH_TRAIN :
case VEH_ROAD :
size - > height = 6 * resize - > height ;
break ;
case VEH_SHIP :
case VEH_AIRCRAFT :
size - > height = 4 * resize - > height ;
break ;
default : NOT_REACHED ( ) ;
}
2009-10-25 15:08:16 +00:00
break ;
2010-07-17 15:03:07 +00:00
2010-10-19 21:48:20 +00:00
case VLW_WIDGET_SORT_ORDER : {
Dimension d = GetStringBoundingBox ( this - > GetWidget < NWidgetCore > ( widget ) - > widget_data ) ;
d . width + = padding . width + WD_SORTBUTTON_ARROW_WIDTH * 2 ; // Doubled since the string is centred and it also looks better.
d . height + = padding . height ;
* size = maxdim ( * size , d ) ;
break ;
}
2010-07-17 15:03:07 +00:00
case VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN : {
2010-09-09 14:40:39 +00:00
Dimension d = this - > GetActionDropdownSize ( this - > vli . type = = VL_STANDARD , false ) ;
2010-07-17 15:03:07 +00:00
d . height + = padding . height ;
d . width + = padding . width ;
* size = maxdim ( * size , d ) ;
2009-10-25 15:08:16 +00:00
break ;
2010-07-17 15:03:07 +00:00
}
2009-10-25 15:08:16 +00:00
}
}
2008-05-11 15:00:11 +00:00
2009-10-25 15:08:16 +00:00
virtual void SetStringParameters ( int widget ) const
{
2010-07-30 12:26:58 +00:00
switch ( widget ) {
case VLW_WIDGET_AVAILABLE_VEHICLES :
2010-09-09 14:40:39 +00:00
SetDParam ( 0 , STR_VEHICLE_LIST_AVAILABLE_TRAINS + this - > vli . vtype ) ;
2008-05-11 15:00:11 +00:00
break ;
2006-09-28 18:13:31 +00:00
2010-07-30 12:26:58 +00:00
case VLW_WIDGET_CAPTION : {
2010-09-09 14:40:39 +00:00
switch ( this - > vli . type ) {
2010-09-08 21:37:13 +00:00
case VL_SHARED_ORDERS : // Shared Orders
2010-07-30 12:26:58 +00:00
if ( this - > vehicles . Length ( ) = = 0 ) {
/* We can't open this window without vehicles using this order
2011-01-21 01:38:30 +00:00
* and we should close the window when deleting the order . */
2010-07-30 12:26:58 +00:00
NOT_REACHED ( ) ;
}
2010-08-12 08:37:01 +00:00
SetDParam ( 0 , this - > vscroll - > GetCount ( ) ) ;
2010-07-30 12:26:58 +00:00
break ;
2006-09-28 18:13:31 +00:00
2010-09-08 21:37:13 +00:00
case VL_STANDARD : // Company Name
2010-07-30 12:26:58 +00:00
SetDParam ( 0 , STR_COMPANY_NAME ) ;
2010-09-09 14:40:39 +00:00
SetDParam ( 1 , this - > vli . index ) ;
2010-08-12 08:37:01 +00:00
SetDParam ( 3 , this - > vscroll - > GetCount ( ) ) ;
2010-07-30 12:26:58 +00:00
break ;
2006-08-29 17:41:13 +00:00
2010-09-08 21:37:13 +00:00
case VL_STATION_LIST : // Station/Waypoint Name
2010-09-09 14:40:39 +00:00
SetDParam ( 0 , Station : : IsExpected ( BaseStation : : Get ( this - > vli . index ) ) ? STR_STATION_NAME : STR_WAYPOINT_NAME ) ;
SetDParam ( 1 , this - > vli . index ) ;
2010-08-12 08:37:01 +00:00
SetDParam ( 3 , this - > vscroll - > GetCount ( ) ) ;
2010-07-30 12:26:58 +00:00
break ;
2010-09-08 21:37:13 +00:00
case VL_DEPOT_LIST :
2010-07-30 12:26:58 +00:00
SetDParam ( 0 , STR_DEPOT_CAPTION ) ;
2010-09-09 14:40:39 +00:00
SetDParam ( 1 , this - > vli . vtype ) ;
SetDParam ( 2 , this - > vli . index ) ;
2010-08-12 08:37:01 +00:00
SetDParam ( 3 , this - > vscroll - > GetCount ( ) ) ;
2010-07-30 12:26:58 +00:00
break ;
default : NOT_REACHED ( ) ;
}
2010-08-01 18:53:30 +00:00
break ;
}
2008-05-11 15:00:11 +00:00
}
2009-10-25 15:08:16 +00:00
}
virtual void DrawWidget ( const Rect & r , int widget ) const
{
switch ( widget ) {
case VLW_WIDGET_SORT_ORDER :
/* draw arrow pointing up/down for ascending/descending sorting */
this - > DrawSortButtonState ( widget , this - > vehicles . IsDescSortOrder ( ) ? SBS_DOWN : SBS_UP ) ;
break ;
case VLW_WIDGET_LIST :
this - > DrawVehicleListItems ( INVALID_VEHICLE , this - > resize . step_height , r ) ;
break ;
}
}
virtual void OnPaint ( )
{
2010-09-09 14:40:39 +00:00
this - > BuildVehicleList ( ) ;
2009-10-25 15:08:16 +00:00
this - > SortVehicleList ( ) ;
2010-06-23 14:56:17 +00:00
if ( this - > vehicles . Length ( ) = = 0 & & this - > IsWidgetLowered ( VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN ) ) {
HideDropDownMenu ( this ) ;
}
2006-09-04 15:13:49 +00:00
2009-04-13 17:19:43 +00:00
/* Hide the widgets that we will not use in this window
* Some windows contains actions only fit for the owner */
2009-10-25 15:08:16 +00:00
int plane_to_show = ( this - > owner = = _local_company ) ? BP_SHOW_BUTTONS : BP_HIDE_BUTTONS ;
NWidgetStacked * nwi = this - > GetWidget < NWidgetStacked > ( VLW_WIDGET_HIDE_BUTTONS ) ;
if ( plane_to_show ! = nwi - > shown_plane ) {
nwi - > SetDisplayedPlane ( plane_to_show ) ;
nwi - > SetDirty ( this ) ;
}
2009-04-13 17:19:43 +00:00
if ( this - > owner = = _local_company ) {
2010-09-09 14:40:39 +00:00
this - > SetWidgetDisabledState ( VLW_WIDGET_AVAILABLE_VEHICLES , this - > vli . type ! = VL_STANDARD ) ;
2009-04-13 17:19:43 +00:00
this - > SetWidgetsDisabledState ( this - > vehicles . Length ( ) = = 0 ,
VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN ,
VLW_WIDGET_STOP_ALL ,
VLW_WIDGET_START_ALL ,
WIDGET_LIST_END ) ;
}
2009-03-22 21:56:40 +00:00
/* Set text of sort by dropdown widget. */
2009-10-25 15:08:16 +00:00
this - > GetWidget < NWidgetCore > ( VLW_WIDGET_SORT_BY_PULLDOWN ) - > widget_data = this - > vehicle_sorter_names [ this - > vehicles . SortType ( ) ] ;
2009-03-22 21:56:40 +00:00
2008-05-17 12:48:06 +00:00
this - > DrawWidgets ( ) ;
2008-05-11 15:00:11 +00:00
}
2006-09-04 15:13:49 +00:00
2010-01-30 18:34:48 +00:00
virtual void OnClick ( Point pt , int widget , int click_count )
2008-05-11 15:00:11 +00:00
{
switch ( widget ) {
2009-03-15 00:32:18 +00:00
case VLW_WIDGET_SORT_ORDER : // Flip sorting method ascending/descending
2008-06-16 17:09:52 +00:00
this - > vehicles . ToggleSortOrder ( ) ;
2008-05-11 15:00:11 +00:00
this - > SetDirty ( ) ;
break ;
2009-10-25 15:08:16 +00:00
2009-03-15 00:32:18 +00:00
case VLW_WIDGET_SORT_BY_PULLDOWN : // Select sorting criteria dropdown menu
2009-10-25 15:08:16 +00:00
ShowDropDownMenu ( this , this - > vehicle_sorter_names , this - > vehicles . SortType ( ) , VLW_WIDGET_SORT_BY_PULLDOWN , 0 ,
2010-09-09 14:40:39 +00:00
( this - > vli . vtype = = VEH_TRAIN | | this - > vli . vtype = = VEH_ROAD ) ? 0 : ( 1 < < 10 ) ) ;
2008-05-11 15:00:11 +00:00
return ;
2009-10-25 15:08:16 +00:00
2009-03-15 00:32:18 +00:00
case VLW_WIDGET_LIST : { // Matrix to show vehicles
2010-08-12 08:37:01 +00:00
uint id_v = this - > vscroll - > GetScrolledRowFromWidget ( pt . y , this , VLW_WIDGET_LIST ) ;
2008-05-26 16:23:23 +00:00
if ( id_v > = this - > vehicles . Length ( ) ) return ; // click out of list bound
2008-05-11 15:00:11 +00:00
2010-07-30 10:39:24 +00:00
const Vehicle * v = this - > vehicles [ id_v ] ;
2010-09-06 14:14:09 +00:00
if ( ! VehicleClicked ( v ) ) ShowVehicleViewWindow ( v ) ;
2010-08-01 18:53:30 +00:00
break ;
}
2008-05-11 15:00:11 +00:00
case VLW_WIDGET_AVAILABLE_VEHICLES :
2010-09-09 14:40:39 +00:00
ShowBuildVehicleWindow ( INVALID_TILE , this - > vli . vtype ) ;
2008-05-11 15:00:11 +00:00
break ;
case VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN : {
2010-09-08 21:37:13 +00:00
DropDownList * list = this - > BuildActionDropdownList ( VehicleListIdentifier ( this - > window_number ) . type = = VL_STANDARD , false ) ;
2010-07-17 14:58:35 +00:00
ShowDropDownList ( this , list , 0 , VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN ) ;
2008-05-11 15:00:11 +00:00
break ;
2006-08-29 17:41:13 +00:00
}
2008-05-11 15:00:11 +00:00
case VLW_WIDGET_STOP_ALL :
case VLW_WIDGET_START_ALL :
2010-09-08 21:40:00 +00:00
DoCommandP ( 0 , ( 1 < < 1 ) | ( widget = = VLW_WIDGET_START_ALL ? ( 1 < < 0 ) : 0 ) , this - > window_number , CMD_MASS_START_STOP ) ;
2008-05-11 15:00:11 +00:00
break ;
}
2006-08-29 17:41:13 +00:00
}
2008-05-11 15:00:11 +00:00
virtual void OnDropdownSelect ( int widget , int index )
{
switch ( widget ) {
case VLW_WIDGET_SORT_BY_PULLDOWN :
2008-06-16 17:09:52 +00:00
this - > vehicles . SetSortType ( index ) ;
2008-05-11 15:00:11 +00:00
break ;
case VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN :
2008-05-26 16:23:23 +00:00
assert ( this - > vehicles . Length ( ) ! = 0 ) ;
2008-05-11 15:00:11 +00:00
switch ( index ) {
2010-07-17 14:58:35 +00:00
case ADI_REPLACE : // Replace window
2010-09-09 14:40:39 +00:00
ShowReplaceGroupVehicleWindow ( DEFAULT_GROUP , this - > vli . vtype ) ;
2008-05-11 15:00:11 +00:00
break ;
2010-07-17 14:58:35 +00:00
case ADI_SERVICE : // Send for servicing
case ADI_DEPOT : // Send to Depots
2010-09-09 14:40:39 +00:00
DoCommandP ( 0 , DEPOT_MASS_SEND | ( index = = ADI_SERVICE ? DEPOT_SERVICE : ( DepotCommand ) 0 ) , this - > window_number , GetCmdSendToDepot ( this - > vli . vtype ) ) ;
2008-05-11 15:00:11 +00:00
break ;
default : NOT_REACHED ( ) ;
}
break ;
default : NOT_REACHED ( ) ;
}
this - > SetDirty ( ) ;
}
virtual void OnTick ( )
{
2009-05-06 15:06:57 +00:00
if ( _pause_mode ! = PM_UNPAUSED ) return ;
2008-06-16 17:09:52 +00:00
if ( this - > vehicles . NeedResort ( ) ) {
2010-09-09 14:40:39 +00:00
StationID station = ( this - > vli . type = = VL_STATION_LIST ) ? this - > vli . index : INVALID_STATION ;
2008-05-11 15:00:11 +00:00
2010-09-09 14:40:39 +00:00
DEBUG ( misc , 3 , " Periodic resort %d list company %d at station %d " , this - > vli . vtype , this - > owner , station ) ;
2008-05-11 15:00:11 +00:00
this - > SetDirty ( ) ;
}
}
2009-10-24 14:53:55 +00:00
virtual void OnResize ( )
2008-05-11 15:00:11 +00:00
{
2010-08-12 08:37:01 +00:00
this - > vscroll - > SetCapacityFromWidget ( this , VLW_WIDGET_LIST ) ;
this - > GetWidget < NWidgetCore > ( VLW_WIDGET_LIST ) - > widget_data = ( this - > vscroll - > GetCapacity ( ) < < MAT_ROW_START ) + ( 1 < < MAT_COL_START ) ;
2008-05-11 15:00:11 +00:00
}
2008-05-18 16:51:44 +00:00
2011-03-13 21:31:29 +00:00
/**
* Some data on this window has become invalid .
* @ param data Information about the changed data .
* @ param gui_scope Whether the call is done from GUI scope . You may not do everything when not in GUI scope . See # InvalidateWindowData ( ) for details .
*/
virtual void OnInvalidateData ( int data = 0 , bool gui_scope = true )
2008-05-18 16:51:44 +00:00
{
2011-03-13 21:33:30 +00:00
if ( ! gui_scope & & HasBit ( data , 31 ) & & this - > vli . type = = VL_SHARED_ORDERS ) {
/* Needs to be done in command-scope, so everything stays valid */
2010-09-09 14:40:39 +00:00
this - > vli . index = GB ( data , 0 , 20 ) ;
this - > window_number = this - > vli . Pack ( ) ;
2008-08-17 21:07:09 +00:00
this - > vehicles . ForceRebuild ( ) ;
return ;
}
2008-06-16 17:09:52 +00:00
if ( data = = 0 ) {
2011-03-13 21:34:21 +00:00
/* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */
2008-06-16 17:09:52 +00:00
this - > vehicles . ForceRebuild ( ) ;
} else {
this - > vehicles . ForceResort ( ) ;
}
2008-05-18 16:51:44 +00:00
}
2008-05-11 15:00:11 +00:00
} ;
2006-09-28 23:05:03 +00:00
2009-03-15 15:12:06 +00:00
static WindowDesc _vehicle_list_desc (
2009-11-28 14:42:35 +00:00
WDP_AUTO , 260 , 246 ,
2008-09-12 21:58:36 +00:00
WC_INVALID , WC_NONE ,
2009-11-24 17:28:29 +00:00
WDF_UNCLICK_BUTTONS ,
2009-11-15 10:26:01 +00:00
_nested_vehicle_list , lengthof ( _nested_vehicle_list )
2009-03-15 15:12:06 +00:00
) ;
2006-09-28 23:05:03 +00:00
2010-09-08 21:37:13 +00:00
static void ShowVehicleListWindowLocal ( CompanyID company , VehicleListType vlt , VehicleType vehicle_type , uint16 unique_number )
2006-09-28 23:05:03 +00:00
{
2011-04-22 21:51:34 +00:00
if ( ! Company : : IsValidID ( company ) ) return ;
2006-10-31 21:15:56 +00:00
2008-09-12 21:58:36 +00:00
_vehicle_list_desc . cls = GetWindowClassForVehicleType ( vehicle_type ) ;
2010-09-08 21:37:13 +00:00
AllocateWindowDescFront < VehicleListWindow > ( & _vehicle_list_desc , VehicleListIdentifier ( vlt , vehicle_type , company , unique_number ) . Pack ( ) ) ;
2006-09-28 23:05:03 +00:00
}
2008-09-30 20:39:50 +00:00
void ShowVehicleListWindow ( CompanyID company , VehicleType vehicle_type )
2006-09-28 23:05:03 +00:00
{
2008-05-29 15:13:28 +00:00
/* If _settings_client.gui.advanced_vehicle_list > 1, display the Advanced list
2008-09-30 20:39:50 +00:00
* if _settings_client . gui . advanced_vehicle_list = = 1 , display Advanced list only for local company
2007-09-09 10:34:32 +00:00
* if _ctrl_pressed , do the opposite action ( Advanced list x Normal list )
*/
2008-09-30 20:39:50 +00:00
if ( ( _settings_client . gui . advanced_vehicle_list > ( uint ) ( company ! = _local_company ) ) ! = _ctrl_pressed ) {
ShowCompanyGroup ( company , vehicle_type ) ;
2007-05-19 09:40:18 +00:00
} else {
2010-09-08 21:37:13 +00:00
ShowVehicleListWindowLocal ( company , VL_STANDARD , vehicle_type , company ) ;
2007-05-19 09:40:18 +00:00
}
2006-09-28 23:05:03 +00:00
}
2007-01-21 00:01:47 +00:00
void ShowVehicleListWindow ( const Vehicle * v )
2006-09-28 23:05:03 +00:00
{
2010-09-08 21:37:13 +00:00
ShowVehicleListWindowLocal ( v - > owner , VL_SHARED_ORDERS , v - > type , v - > FirstShared ( ) - > index ) ;
2007-01-21 00:01:47 +00:00
}
2008-09-30 20:39:50 +00:00
void ShowVehicleListWindow ( CompanyID company , VehicleType vehicle_type , StationID station )
2007-01-21 00:01:47 +00:00
{
2011-04-22 21:51:34 +00:00
if ( ! Company : : IsValidID ( company ) ) {
company = _local_company ;
/* This can happen when opening the vehicle list as a spectator. */
if ( ! Company : : IsValidID ( company ) ) return ;
_vehicle_list_desc . flags | = WDF_CONSTRUCTION ;
} else {
_vehicle_list_desc . flags & = ~ WDF_CONSTRUCTION ;
}
2010-09-08 21:37:13 +00:00
ShowVehicleListWindowLocal ( company , VL_STATION_LIST , vehicle_type , station ) ;
2006-09-30 13:39:34 +00:00
}
2008-09-30 20:39:50 +00:00
void ShowVehicleListWindow ( CompanyID company , VehicleType vehicle_type , TileIndex depot_tile )
2006-09-30 13:39:34 +00:00
{
uint16 depot_airport_index ;
2007-03-08 16:27:54 +00:00
if ( vehicle_type = = VEH_AIRCRAFT ) {
2006-09-30 13:39:34 +00:00
depot_airport_index = GetStationIndex ( depot_tile ) ;
} else {
2009-09-10 14:37:55 +00:00
depot_airport_index = GetDepotIndex ( depot_tile ) ;
2006-09-30 13:39:34 +00:00
}
2010-09-08 21:37:13 +00:00
ShowVehicleListWindowLocal ( company , VL_DEPOT_LIST , vehicle_type , depot_airport_index ) ;
2006-09-29 07:30:44 +00:00
}
2007-08-29 20:50:58 +00:00
2007-09-05 23:26:45 +00:00
/* Unified vehicle GUI - Vehicle Details Window */
/** Constants of vehicle details widget indices */
enum VehicleDetailsWindowWidgets {
VLD_WIDGET_CAPTION ,
VLD_WIDGET_RENAME_VEHICLE ,
VLD_WIDGET_TOP_DETAILS ,
VLD_WIDGET_INCREASE_SERVICING_INTERVAL ,
VLD_WIDGET_DECREASE_SERVICING_INTERVAL ,
2009-10-25 21:42:04 +00:00
VLD_WIDGET_SERVICING_INTERVAL ,
2007-09-05 23:26:45 +00:00
VLD_WIDGET_MIDDLE_DETAILS ,
2009-10-25 21:42:04 +00:00
VLD_WIDGET_MATRIX ,
2007-09-05 23:26:45 +00:00
VLD_WIDGET_SCROLLBAR ,
VLD_WIDGET_DETAILS_CARGO_CARRIED ,
VLD_WIDGET_DETAILS_TRAIN_VEHICLES ,
VLD_WIDGET_DETAILS_CAPACITY_OF_EACH ,
VLD_WIDGET_DETAILS_TOTAL_CARGO ,
} ;
2009-05-31 14:04:19 +00:00
assert_compile ( VLD_WIDGET_DETAILS_CARGO_CARRIED = = VLD_WIDGET_DETAILS_CARGO_CARRIED + TDW_TAB_CARGO ) ;
assert_compile ( VLD_WIDGET_DETAILS_TRAIN_VEHICLES = = VLD_WIDGET_DETAILS_CARGO_CARRIED + TDW_TAB_INFO ) ;
assert_compile ( VLD_WIDGET_DETAILS_CAPACITY_OF_EACH = = VLD_WIDGET_DETAILS_CARGO_CARRIED + TDW_TAB_CAPACITY ) ;
assert_compile ( VLD_WIDGET_DETAILS_TOTAL_CARGO = = VLD_WIDGET_DETAILS_CARGO_CARRIED + TDW_TAB_TOTALS ) ;
2009-10-25 21:42:04 +00:00
/** Vehicle details widgets (other than train). */
static const NWidgetPart _nested_nontrain_vehicle_details_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
2009-10-25 21:42:04 +00:00
NWidget ( WWT_CAPTION , COLOUR_GREY , VLD_WIDGET_CAPTION ) , SetDataTip ( STR_VEHICLE_DETAILS_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2009-11-17 13:17:09 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , VLD_WIDGET_RENAME_VEHICLE ) , SetMinimalSize ( 40 , 0 ) , SetMinimalTextLines ( 1 , WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2 ) , SetDataTip ( STR_VEHICLE_NAME_BUTTON , STR_NULL /* filled in later */ ) ,
2009-12-21 16:24:29 +00:00
NWidget ( WWT_SHADEBOX , COLOUR_GREY ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_STICKYBOX , COLOUR_GREY ) ,
2009-10-25 21:42:04 +00:00
EndContainer ( ) ,
2009-11-23 16:18:01 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY , VLD_WIDGET_TOP_DETAILS ) , SetMinimalSize ( 405 , 42 ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
NWidget ( WWT_PANEL , COLOUR_GREY , VLD_WIDGET_MIDDLE_DETAILS ) , SetMinimalSize ( 405 , 45 ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2010-08-12 16:44:51 +00:00
NWidget ( WWT_PUSHARROWBTN , COLOUR_GREY , VLD_WIDGET_DECREASE_SERVICING_INTERVAL ) , SetFill ( 0 , 1 ) ,
2009-11-23 16:18:01 +00:00
SetDataTip ( AWV_DECREASE , STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP ) ,
2010-08-12 16:44:51 +00:00
NWidget ( WWT_PUSHARROWBTN , COLOUR_GREY , VLD_WIDGET_INCREASE_SERVICING_INTERVAL ) , SetFill ( 0 , 1 ) ,
2009-11-23 16:18:01 +00:00
SetDataTip ( AWV_INCREASE , STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP ) ,
NWidget ( WWT_PANEL , COLOUR_GREY , VLD_WIDGET_SERVICING_INTERVAL ) , SetFill ( 1 , 1 ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_RESIZEBOX , COLOUR_GREY ) ,
2009-10-25 21:42:04 +00:00
EndContainer ( ) ,
2007-09-05 23:26:45 +00:00
} ;
2009-10-25 21:42:04 +00:00
/** Train details widgets. */
static const NWidgetPart _nested_train_vehicle_details_widgets [ ] = {
2009-04-13 14:09:56 +00:00
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
2009-04-21 23:40:56 +00:00
NWidget ( WWT_CAPTION , COLOUR_GREY , VLD_WIDGET_CAPTION ) , SetDataTip ( STR_VEHICLE_DETAILS_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2009-11-17 13:17:09 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , VLD_WIDGET_RENAME_VEHICLE ) , SetMinimalSize ( 40 , 0 ) , SetMinimalTextLines ( 1 , WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2 ) , SetDataTip ( STR_VEHICLE_NAME_BUTTON , STR_NULL /* filled in later */ ) ,
2009-12-21 16:24:29 +00:00
NWidget ( WWT_SHADEBOX , COLOUR_GREY ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_STICKYBOX , COLOUR_GREY ) ,
2009-04-13 14:09:56 +00:00
EndContainer ( ) ,
NWidget ( WWT_PANEL , COLOUR_GREY , VLD_WIDGET_TOP_DETAILS ) , SetResize ( 1 , 0 ) , SetMinimalSize ( 405 , 42 ) , EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2010-08-12 06:44:45 +00:00
NWidget ( WWT_MATRIX , COLOUR_GREY , VLD_WIDGET_MATRIX ) , SetResize ( 1 , 1 ) , SetMinimalSize ( 393 , 45 ) , SetDataTip ( 0x701 , STR_NULL ) , SetFill ( 1 , 0 ) , SetScrollbar ( VLD_WIDGET_SCROLLBAR ) ,
2010-08-12 09:16:43 +00:00
NWidget ( NWID_VSCROLLBAR , COLOUR_GREY , VLD_WIDGET_SCROLLBAR ) ,
2009-04-13 14:09:56 +00:00
EndContainer ( ) ,
2009-11-23 16:18:01 +00:00
NWidget ( NWID_HORIZONTAL ) ,
2010-08-12 16:44:51 +00:00
NWidget ( WWT_PUSHARROWBTN , COLOUR_GREY , VLD_WIDGET_DECREASE_SERVICING_INTERVAL ) , SetFill ( 0 , 1 ) ,
2009-11-23 16:18:01 +00:00
SetDataTip ( AWV_DECREASE , STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP ) ,
2010-08-12 16:44:51 +00:00
NWidget ( WWT_PUSHARROWBTN , COLOUR_GREY , VLD_WIDGET_INCREASE_SERVICING_INTERVAL ) , SetFill ( 0 , 1 ) ,
2009-11-23 16:18:01 +00:00
SetDataTip ( AWV_INCREASE , STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP ) ,
NWidget ( WWT_PANEL , COLOUR_GREY , VLD_WIDGET_SERVICING_INTERVAL ) , SetFill ( 1 , 1 ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
2009-04-13 14:09:56 +00:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2009-10-25 21:42:04 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , VLD_WIDGET_DETAILS_CARGO_CARRIED ) , SetMinimalSize ( 96 , 12 ) ,
2009-11-23 16:18:01 +00:00
SetDataTip ( STR_VEHICLE_DETAIL_TAB_CARGO , STR_VEHICLE_DETAILS_TRAIN_CARGO_TOOLTIP ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) ,
2009-10-25 21:42:04 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , VLD_WIDGET_DETAILS_TRAIN_VEHICLES ) , SetMinimalSize ( 99 , 12 ) ,
2009-11-23 16:18:01 +00:00
SetDataTip ( STR_VEHICLE_DETAIL_TAB_INFORMATION , STR_VEHICLE_DETAILS_TRAIN_INFORMATION_TOOLTIP ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) ,
2009-10-25 21:42:04 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , VLD_WIDGET_DETAILS_CAPACITY_OF_EACH ) , SetMinimalSize ( 99 , 12 ) ,
2009-11-23 16:18:01 +00:00
SetDataTip ( STR_VEHICLE_DETAIL_TAB_CAPACITIES , STR_VEHICLE_DETAILS_TRAIN_CAPACITIES_TOOLTIP ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) ,
2009-10-25 21:42:04 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , VLD_WIDGET_DETAILS_TOTAL_CARGO ) , SetMinimalSize ( 99 , 12 ) ,
2009-11-23 16:18:01 +00:00
SetDataTip ( STR_VEHICLE_DETAIL_TAB_TOTAL_CARGO , STR_VEHICLE_DETAILS_TRAIN_TOTAL_CARGO_TOOLTIP ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_RESIZEBOX , COLOUR_GREY ) ,
2009-04-13 14:09:56 +00:00
EndContainer ( ) ,
} ;
2007-09-05 23:26:45 +00:00
2009-05-31 14:04:19 +00:00
extern int GetTrainDetailsWndVScroll ( VehicleID veh_id , TrainDetailsWindowTabs det_tab ) ;
2009-07-01 23:57:20 +00:00
extern void DrawTrainDetails ( const Train * v , int left , int right , int y , int vscroll_pos , uint16 vscroll_cap , TrainDetailsWindowTabs det_tab ) ;
2009-03-22 10:37:51 +00:00
extern void DrawRoadVehDetails ( const Vehicle * v , int left , int right , int y ) ;
extern void DrawShipDetails ( const Vehicle * v , int left , int right , int y ) ;
2009-07-13 16:37:27 +00:00
extern void DrawAircraftDetails ( const Aircraft * v , int left , int right , int y ) ;
2007-09-05 23:26:45 +00:00
2009-10-25 21:42:04 +00:00
/** Class for managing the vehicle details window. */
2008-05-16 17:33:09 +00:00
struct VehicleDetailsWindow : Window {
2009-10-25 21:42:04 +00:00
TrainDetailsWindowTabs tab ; ///< For train vehicles: which tab is displayed.
2010-08-12 08:37:01 +00:00
Scrollbar * vscroll ;
2007-09-05 23:26:45 +00:00
2008-05-16 17:33:09 +00:00
/** Initialize a newly created vehicle details window */
2009-10-25 21:42:04 +00:00
VehicleDetailsWindow ( const WindowDesc * desc , WindowNumber window_number ) : Window ( )
2008-05-16 17:33:09 +00:00
{
2010-08-12 08:37:01 +00:00
const Vehicle * v = Vehicle : : Get ( window_number ) ;
2009-10-25 21:42:04 +00:00
2010-08-12 08:37:01 +00:00
this - > CreateNestedTree ( desc ) ;
this - > vscroll = ( v - > type = = VEH_TRAIN ? this - > GetScrollbar ( VLD_WIDGET_SCROLLBAR ) : NULL ) ;
this - > FinishInitNested ( desc , window_number ) ;
2007-09-05 23:26:45 +00:00
2009-10-25 21:42:04 +00:00
this - > GetWidget < NWidgetCore > ( VLD_WIDGET_RENAME_VEHICLE ) - > tool_tip = STR_VEHICLE_DETAILS_TRAIN_RENAME + v - > type ;
2007-09-05 23:26:45 +00:00
2009-10-25 21:42:04 +00:00
this - > owner = v - > owner ;
this - > tab = TDW_TAB_CARGO ;
}
2007-09-05 23:26:45 +00:00
2011-03-13 21:31:29 +00:00
/**
* Some data on this window has become invalid .
* @ param data Information about the changed data .
* @ param gui_scope Whether the call is done from GUI scope . You may not do everything when not in GUI scope . See # InvalidateWindowData ( ) for details .
*/
virtual void OnInvalidateData ( int data = 0 , bool gui_scope = true )
2010-04-01 18:30:00 +00:00
{
2011-03-08 19:41:58 +00:00
if ( data = = - 666 ) {
/* Autoreplace replaced the vehicle.
2011-03-13 21:33:02 +00:00
* Nothing to do for this window . */
2011-03-08 19:41:58 +00:00
return ;
}
2011-03-13 21:33:02 +00:00
if ( ! gui_scope ) return ;
2010-04-01 18:30:00 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
if ( v - > type = = VEH_ROAD ) {
const NWidgetBase * nwid_info = this - > GetWidget < NWidgetBase > ( VLD_WIDGET_MIDDLE_DETAILS ) ;
uint aimed_height = this - > GetRoadVehDetailsHeight ( v ) ;
/* If the number of articulated parts changes, the size of the window must change too. */
if ( aimed_height ! = nwid_info - > current_y ) {
this - > ReInit ( ) ;
}
}
}
/**
* Gets the desired height for the road vehicle details panel .
* @ param v Road vehicle being shown .
* @ return Desired height in pixels .
*/
uint GetRoadVehDetailsHeight ( const Vehicle * v )
{
uint desired_height ;
2011-01-29 17:30:25 +00:00
if ( v - > HasArticulatedPart ( ) ) {
2010-04-01 18:30:00 +00:00
/* An articulated RV has its text drawn under the sprite instead of after it, hence 15 pixels extra. */
desired_height = WD_FRAMERECT_TOP + 15 + 3 * FONT_HEIGHT_NORMAL + 2 + WD_FRAMERECT_BOTTOM ;
/* Add space for the cargo amount for each part. */
for ( const Vehicle * u = v ; u ! = NULL ; u = u - > Next ( ) ) {
if ( u - > cargo_cap ! = 0 ) desired_height + = FONT_HEIGHT_NORMAL + 1 ;
}
} else {
desired_height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM ;
}
return desired_height ;
}
2009-11-22 18:28:14 +00:00
virtual void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize )
2009-10-25 21:42:04 +00:00
{
switch ( widget ) {
2009-12-09 22:25:12 +00:00
case VLD_WIDGET_TOP_DETAILS : {
Dimension dim = { 0 , 0 } ;
2009-10-25 21:42:04 +00:00
size - > height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM ;
2009-12-09 22:25:12 +00:00
for ( uint i = 0 ; i < 4 ; i + + ) SetDParam ( i , INT16_MAX ) ;
static const StringID info_strings [ ] = {
STR_VEHICLE_INFO_MAX_SPEED ,
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED ,
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE ,
STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR ,
STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS
} ;
for ( uint i = 0 ; i < lengthof ( info_strings ) ; i + + ) {
dim = maxdim ( dim , GetStringBoundingBox ( info_strings [ i ] ) ) ;
}
SetDParam ( 0 , STR_VEHICLE_INFO_AGE ) ;
dim = maxdim ( dim , GetStringBoundingBox ( STR_VEHICLE_INFO_AGE_RUNNING_COST_YR ) ) ;
size - > width = dim . width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT ;
2010-08-01 18:53:30 +00:00
break ;
}
2007-09-05 23:26:45 +00:00
2009-10-25 21:42:04 +00:00
case VLD_WIDGET_MIDDLE_DETAILS : {
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
switch ( v - > type ) {
case VEH_ROAD :
2010-04-01 18:30:00 +00:00
size - > height = this - > GetRoadVehDetailsHeight ( v ) ;
2009-10-25 21:42:04 +00:00
break ;
2007-09-05 23:26:45 +00:00
2009-10-25 21:42:04 +00:00
case VEH_SHIP :
size - > height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM ;
break ;
2007-09-05 23:26:45 +00:00
2009-10-25 21:42:04 +00:00
case VEH_AIRCRAFT :
size - > height = WD_FRAMERECT_TOP + 5 * FONT_HEIGHT_NORMAL + 4 + WD_FRAMERECT_BOTTOM ;
break ;
2007-09-05 23:26:45 +00:00
2009-10-25 21:42:04 +00:00
default :
NOT_REACHED ( ) ; // Train uses VLD_WIDGET_MATRIX instead.
}
2008-05-16 17:33:09 +00:00
break ;
2009-10-25 21:42:04 +00:00
}
2007-09-05 23:26:45 +00:00
2009-10-25 21:42:04 +00:00
case VLD_WIDGET_MATRIX :
2009-11-16 21:10:23 +00:00
resize - > height = WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM ;
2009-10-25 21:42:04 +00:00
size - > height = 4 * resize - > height ;
2008-05-16 17:33:09 +00:00
break ;
2007-09-05 23:26:45 +00:00
2009-10-25 21:42:04 +00:00
case VLD_WIDGET_SERVICING_INTERVAL :
2009-11-23 16:18:01 +00:00
SetDParam ( 0 , 9999 ) ; // Roughly the maximum interval
SetDParam ( 1 , MAX_YEAR * DAYS_IN_YEAR ) ; // Roughly the maximum year
size - > width = max ( GetStringBoundingBox ( STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT ) . width , GetStringBoundingBox ( STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS ) . width ) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT ;
2009-10-25 21:42:04 +00:00
size - > height = WD_FRAMERECT_TOP + FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM ;
break ;
2008-05-16 17:33:09 +00:00
}
2007-09-05 23:26:45 +00:00
}
2008-05-16 17:33:09 +00:00
/** Checks whether service interval is enabled for the vehicle. */
2009-05-26 21:59:49 +00:00
static bool IsVehicleServiceIntervalEnabled ( const VehicleType vehicle_type , CompanyID company_id )
2008-05-16 17:33:09 +00:00
{
2009-05-26 21:59:49 +00:00
const VehicleDefaultSettings * vds = & Company : : Get ( company_id ) - > settings . vehicle ;
2008-05-16 17:33:09 +00:00
switch ( vehicle_type ) {
default : NOT_REACHED ( ) ;
2009-05-26 21:59:49 +00:00
case VEH_TRAIN : return vds - > servint_trains ! = 0 ;
case VEH_ROAD : return vds - > servint_roadveh ! = 0 ;
case VEH_SHIP : return vds - > servint_ships ! = 0 ;
case VEH_AIRCRAFT : return vds - > servint_aircraft ! = 0 ;
2008-05-16 17:33:09 +00:00
}
}
2007-09-05 23:26:45 +00:00
2008-05-16 17:33:09 +00:00
/**
2009-03-22 10:37:51 +00:00
* Draw the details for the given vehicle at the position of the Details windows
2008-05-16 17:33:09 +00:00
*
2009-03-22 10:37:51 +00:00
* @ param v current vehicle
* @ param left The left most coordinate to draw
* @ param right The right most coordinate to draw
* @ param y The y coordinate
2009-05-31 14:04:19 +00:00
* @ param vscroll_pos Position of scrollbar ( train only )
* @ param vscroll_cap Number of lines currently displayed ( train only )
* @ param det_tab Selected details tab ( train only )
2008-05-16 17:33:09 +00:00
*/
2009-05-31 14:04:19 +00:00
static void DrawVehicleDetails ( const Vehicle * v , int left , int right , int y , int vscroll_pos , uint vscroll_cap , TrainDetailsWindowTabs det_tab )
2008-05-16 17:33:09 +00:00
{
switch ( v - > type ) {
2009-07-01 23:57:20 +00:00
case VEH_TRAIN : DrawTrainDetails ( Train : : From ( v ) , left , right , y , vscroll_pos , vscroll_cap , det_tab ) ; break ;
2009-03-22 10:37:51 +00:00
case VEH_ROAD : DrawRoadVehDetails ( v , left , right , y ) ; break ;
case VEH_SHIP : DrawShipDetails ( v , left , right , y ) ; break ;
2009-07-13 16:37:27 +00:00
case VEH_AIRCRAFT : DrawAircraftDetails ( Aircraft : : From ( v ) , left , right , y ) ; break ;
2008-05-16 17:33:09 +00:00
default : NOT_REACHED ( ) ;
}
2007-09-05 23:26:45 +00:00
}
2009-10-25 21:42:04 +00:00
virtual void SetStringParameters ( int widget ) const
{
if ( widget = = VLD_WIDGET_CAPTION ) SetDParam ( 0 , Vehicle : : Get ( this - > window_number ) - > index ) ;
}
virtual void DrawWidget ( const Rect & r , int widget ) const
{
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2009-10-27 20:50:47 +00:00
switch ( widget ) {
case VLD_WIDGET_TOP_DETAILS : {
int y = r . top + WD_FRAMERECT_TOP ;
/* Draw running cost */
SetDParam ( 1 , v - > age / DAYS_IN_LEAP_YEAR ) ;
SetDParam ( 0 , ( v - > age + DAYS_IN_YEAR < v - > max_age ) ? STR_VEHICLE_INFO_AGE : STR_VEHICLE_INFO_AGE_RED ) ;
SetDParam ( 2 , v - > max_age / DAYS_IN_LEAP_YEAR ) ;
SetDParam ( 3 , v - > GetDisplayRunningCost ( ) ) ;
DrawString ( r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT , y , STR_VEHICLE_INFO_AGE_RUNNING_COST_YR ) ;
y + = FONT_HEIGHT_NORMAL ;
/* Draw max speed */
2010-12-14 21:31:00 +00:00
StringID string ;
if ( v - > type = = VEH_TRAIN | |
( v - > type = = VEH_ROAD & & _settings_game . vehicle . roadveh_acceleration_model ! = AM_ORIGINAL ) ) {
const GroundVehicleCache * gcache = v - > GetGroundVehicleCache ( ) ;
SetDParam ( 2 , v - > GetDisplayMaxSpeed ( ) ) ;
SetDParam ( 1 , gcache - > cached_power ) ;
SetDParam ( 0 , gcache - > cached_weight ) ;
SetDParam ( 3 , gcache - > cached_max_te / 1000 ) ;
if ( v - > type = = VEH_TRAIN & & ( _settings_game . vehicle . train_acceleration_model = = AM_ORIGINAL | |
GetRailTypeInfo ( Train : : From ( v ) - > railtype ) - > acceleration_type = = 2 ) ) {
string = STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED ;
} else {
string = STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE ;
}
} else {
SetDParam ( 0 , v - > GetDisplayMaxSpeed ( ) ) ;
string = STR_VEHICLE_INFO_MAX_SPEED ;
2009-10-27 20:50:47 +00:00
}
2010-12-14 21:31:00 +00:00
DrawString ( r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT , y , string ) ;
2009-10-27 20:50:47 +00:00
y + = FONT_HEIGHT_NORMAL ;
/* Draw profit */
SetDParam ( 0 , v - > GetDisplayProfitThisYear ( ) ) ;
SetDParam ( 1 , v - > GetDisplayProfitLastYear ( ) ) ;
DrawString ( r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT , y , STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR ) ;
y + = FONT_HEIGHT_NORMAL ;
/* Draw breakdown & reliability */
SetDParam ( 0 , ToPercent16 ( v - > reliability ) ) ;
SetDParam ( 1 , v - > breakdowns_since_last_service ) ;
DrawString ( r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT , y , STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS ) ;
break ;
}
case VLD_WIDGET_MATRIX :
/* For trains only. */
2010-08-12 08:37:01 +00:00
DrawVehicleDetails ( v , r . left + WD_MATRIX_LEFT , r . right - WD_MATRIX_RIGHT , r . top + WD_MATRIX_TOP , this - > vscroll - > GetPosition ( ) , this - > vscroll - > GetCapacity ( ) , this - > tab ) ;
2009-10-27 20:50:47 +00:00
break ;
2009-11-17 15:05:12 +00:00
case VLD_WIDGET_MIDDLE_DETAILS : {
2009-10-27 20:50:47 +00:00
/* For other vehicles, at the place of the matrix. */
2010-11-13 09:56:25 +00:00
bool rtl = _current_text_dir = = TD_RTL ;
2011-11-01 16:51:47 +00:00
uint sprite_width = max < uint > ( GetSprite ( v - > GetImage ( rtl ? DIR_E : DIR_W , EIT_IN_DETAILS ) , ST_NORMAL ) - > width , 70U ) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT ;
2009-11-17 15:05:12 +00:00
uint text_left = r . left + ( rtl ? 0 : sprite_width ) ;
uint text_right = r . right - ( rtl ? sprite_width : 0 ) ;
2010-07-11 13:14:08 +00:00
/* Articulated road vehicles use a complete line. */
2011-01-29 17:30:25 +00:00
if ( v - > type = = VEH_ROAD & & v - > HasArticulatedPart ( ) ) {
2011-11-01 16:51:47 +00:00
DrawVehicleImage ( v , r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT , r . top + WD_FRAMERECT_TOP , INVALID_VEHICLE , EIT_IN_DETAILS , 0 ) ;
2010-07-11 13:14:08 +00:00
} else {
uint sprite_left = rtl ? text_right : r . left ;
uint sprite_right = rtl ? r . right : text_left ;
2011-11-01 16:51:47 +00:00
DrawVehicleImage ( v , sprite_left + WD_FRAMERECT_LEFT , sprite_right - WD_FRAMERECT_RIGHT , r . top + WD_FRAMERECT_TOP , INVALID_VEHICLE , EIT_IN_DETAILS , 0 ) ;
2010-07-11 13:14:08 +00:00
}
2010-08-12 13:26:44 +00:00
DrawVehicleDetails ( v , text_left + WD_FRAMERECT_LEFT , text_right - WD_FRAMERECT_RIGHT , r . top + WD_FRAMERECT_TOP , 0 , 0 , this - > tab ) ;
2010-08-01 18:53:30 +00:00
break ;
}
2009-10-27 20:50:47 +00:00
case VLD_WIDGET_SERVICING_INTERVAL :
/* Draw service interval text */
SetDParam ( 0 , v - > service_interval ) ;
SetDParam ( 1 , v - > date_of_last_service ) ;
DrawString ( r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT , r . top + ( r . bottom - r . top + 1 - FONT_HEIGHT_NORMAL ) / 2 ,
Company : : Get ( v - > owner ) - > settings . vehicle . servint_ispercent ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS ) ;
break ;
}
2009-10-25 21:42:04 +00:00
}
2008-05-16 17:33:09 +00:00
/** Repaint vehicle details window. */
virtual void OnPaint ( )
{
2009-05-16 23:34:14 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2007-09-05 23:26:45 +00:00
2008-09-30 20:39:50 +00:00
this - > SetWidgetDisabledState ( VLD_WIDGET_RENAME_VEHICLE , v - > owner ! = _local_company ) ;
2007-09-05 23:26:45 +00:00
2008-05-16 17:33:09 +00:00
if ( v - > type = = VEH_TRAIN ) {
2009-10-27 20:50:47 +00:00
this - > DisableWidget ( this - > tab + VLD_WIDGET_DETAILS_CARGO_CARRIED ) ;
2010-08-12 08:37:01 +00:00
this - > vscroll - > SetCount ( GetTrainDetailsWndVScroll ( v - > index , this - > tab ) ) ;
2008-05-16 17:33:09 +00:00
}
2007-09-05 23:26:45 +00:00
2008-05-16 17:33:09 +00:00
/* Disable service-scroller when interval is set to disabled */
2009-05-26 21:59:49 +00:00
this - > SetWidgetsDisabledState ( ! IsVehicleServiceIntervalEnabled ( v - > type , v - > owner ) ,
2008-05-16 17:33:09 +00:00
VLD_WIDGET_INCREASE_SERVICING_INTERVAL ,
VLD_WIDGET_DECREASE_SERVICING_INTERVAL ,
WIDGET_LIST_END ) ;
2007-09-05 23:26:45 +00:00
2008-05-17 12:48:06 +00:00
this - > DrawWidgets ( ) ;
2008-05-16 17:33:09 +00:00
}
2007-09-05 23:26:45 +00:00
2010-01-30 18:34:48 +00:00
virtual void OnClick ( Point pt , int widget , int click_count )
2008-05-16 17:33:09 +00:00
{
switch ( widget ) {
2009-10-25 21:42:04 +00:00
case VLD_WIDGET_RENAME_VEHICLE : { // rename
2009-05-16 23:34:14 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2008-05-16 17:33:09 +00:00
SetDParam ( 0 , v - > index ) ;
2009-10-25 21:42:04 +00:00
ShowQueryString ( STR_VEHICLE_NAME , STR_QUERY_RENAME_TRAIN_CAPTION + v - > type ,
2011-04-17 18:42:17 +00:00
MAX_LENGTH_VEHICLE_NAME_CHARS , this , CS_ALPHANUMERAL , QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS ) ;
2010-08-01 18:53:30 +00:00
break ;
}
2007-09-05 23:26:45 +00:00
2008-05-16 17:33:09 +00:00
case VLD_WIDGET_INCREASE_SERVICING_INTERVAL : // increase int
case VLD_WIDGET_DECREASE_SERVICING_INTERVAL : { // decrease int
int mod = _ctrl_pressed ? 5 : 10 ;
2009-05-16 23:34:14 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2007-09-05 23:26:45 +00:00
2008-05-16 17:33:09 +00:00
mod = ( widget = = VLD_WIDGET_DECREASE_SERVICING_INTERVAL ) ? - mod : mod ;
2009-05-26 21:59:49 +00:00
mod = GetServiceIntervalClamped ( mod + v - > service_interval , v - > owner ) ;
2008-05-16 17:33:09 +00:00
if ( mod = = v - > service_interval ) return ;
2007-09-05 23:26:45 +00:00
2009-04-21 23:40:56 +00:00
DoCommandP ( v - > tile , v - > index , mod , CMD_CHANGE_SERVICE_INT | CMD_MSG ( STR_ERROR_CAN_T_CHANGE_SERVICING ) ) ;
2010-08-01 18:53:30 +00:00
break ;
}
2007-09-05 23:26:45 +00:00
2008-05-16 17:33:09 +00:00
case VLD_WIDGET_DETAILS_CARGO_CARRIED :
case VLD_WIDGET_DETAILS_TRAIN_VEHICLES :
case VLD_WIDGET_DETAILS_CAPACITY_OF_EACH :
case VLD_WIDGET_DETAILS_TOTAL_CARGO :
this - > SetWidgetsDisabledState ( false ,
VLD_WIDGET_DETAILS_CARGO_CARRIED ,
VLD_WIDGET_DETAILS_TRAIN_VEHICLES ,
VLD_WIDGET_DETAILS_CAPACITY_OF_EACH ,
VLD_WIDGET_DETAILS_TOTAL_CARGO ,
widget ,
WIDGET_LIST_END ) ;
2009-05-31 14:04:19 +00:00
this - > tab = ( TrainDetailsWindowTabs ) ( widget - VLD_WIDGET_DETAILS_CARGO_CARRIED ) ;
2008-05-16 17:33:09 +00:00
this - > SetDirty ( ) ;
break ;
}
}
2007-09-05 23:26:45 +00:00
2008-05-16 17:33:09 +00:00
virtual void OnQueryTextFinished ( char * str )
{
2008-09-15 19:02:50 +00:00
if ( str = = NULL ) return ;
2009-07-22 20:17:07 +00:00
DoCommandP ( 0 , this - > window_number , 0 , CMD_RENAME_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle : : Get ( this - > window_number ) - > type ) , NULL , str ) ;
2007-09-05 23:26:45 +00:00
}
2008-05-16 17:33:09 +00:00
2009-10-24 14:53:55 +00:00
virtual void OnResize ( )
2008-05-16 17:33:09 +00:00
{
2009-10-25 21:42:04 +00:00
NWidgetCore * nwi = this - > GetWidget < NWidgetCore > ( VLD_WIDGET_MATRIX ) ;
if ( nwi ! = NULL ) {
2010-08-12 08:37:01 +00:00
this - > vscroll - > SetCapacityFromWidget ( this , VLD_WIDGET_MATRIX ) ;
nwi - > widget_data = ( this - > vscroll - > GetCapacity ( ) < < MAT_ROW_START ) + ( 1 < < MAT_COL_START ) ;
2009-10-25 21:42:04 +00:00
}
2008-05-16 17:33:09 +00:00
}
} ;
2007-09-05 23:26:45 +00:00
/** Vehicle details window descriptor. */
2009-10-25 21:42:04 +00:00
static const WindowDesc _train_vehicle_details_desc (
2009-11-28 14:42:35 +00:00
WDP_AUTO , 405 , 178 ,
2009-10-25 21:42:04 +00:00
WC_VEHICLE_DETAILS , WC_VEHICLE_VIEW ,
2009-11-24 17:28:29 +00:00
WDF_UNCLICK_BUTTONS ,
2009-11-15 10:26:01 +00:00
_nested_train_vehicle_details_widgets , lengthof ( _nested_train_vehicle_details_widgets )
2009-10-25 21:42:04 +00:00
) ;
/** Vehicle details window descriptor for other vehicles than a train. */
static const WindowDesc _nontrain_vehicle_details_desc (
2009-11-28 14:42:35 +00:00
WDP_AUTO , 405 , 113 ,
2007-09-05 23:26:45 +00:00
WC_VEHICLE_DETAILS , WC_VEHICLE_VIEW ,
2009-11-24 17:28:29 +00:00
WDF_UNCLICK_BUTTONS ,
2009-11-15 10:26:01 +00:00
_nested_nontrain_vehicle_details_widgets , lengthof ( _nested_nontrain_vehicle_details_widgets )
2009-03-15 15:12:06 +00:00
) ;
2007-09-05 23:26:45 +00:00
/** Shows the vehicle details window of the given vehicle. */
static void ShowVehicleDetailsWindow ( const Vehicle * v )
{
2009-01-03 23:32:59 +00:00
DeleteWindowById ( WC_VEHICLE_ORDERS , v - > index , false ) ;
DeleteWindowById ( WC_VEHICLE_TIMETABLE , v - > index , false ) ;
2009-10-25 21:42:04 +00:00
AllocateWindowDescFront < VehicleDetailsWindow > ( ( v - > type = = VEH_TRAIN ) ? & _train_vehicle_details_desc : & _nontrain_vehicle_details_desc , v - > index ) ;
2007-09-05 23:26:45 +00:00
}
2007-08-29 20:50:58 +00:00
/* Unified vehicle GUI - Vehicle View Window */
/** Vehicle view widgets. */
2009-05-03 13:13:41 +00:00
static const NWidgetPart _nested_vehicle_view_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
2009-05-03 13:13:41 +00:00
NWidget ( WWT_CAPTION , COLOUR_GREY , VVW_WIDGET_CAPTION ) , SetDataTip ( STR_VEHICLE_VIEW_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2010-04-24 13:39:11 +00:00
NWidget ( WWT_DEBUGBOX , COLOUR_GREY ) ,
2009-12-21 16:24:29 +00:00
NWidget ( WWT_SHADEBOX , COLOUR_GREY ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_STICKYBOX , COLOUR_GREY ) ,
2009-05-03 13:13:41 +00:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 21:13:36 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY ) ,
NWidget ( WWT_INSET , COLOUR_GREY ) , SetPadding ( 2 , 2 , 2 , 2 ) ,
2009-10-24 13:58:18 +00:00
NWidget ( NWID_VIEWPORT , INVALID_COLOUR , VVW_WIDGET_VIEWPORT ) , SetMinimalSize ( 226 , 84 ) , SetResize ( 1 , 1 ) , SetPadding ( 1 , 1 , 1 , 1 ) ,
EndContainer ( ) ,
2009-05-03 13:13:41 +00:00
EndContainer ( ) ,
NWidget ( NWID_VERTICAL ) ,
2009-11-22 18:26:01 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , VVW_WIDGET_CENTER_MAIN_VIEH ) , SetMinimalSize ( 18 , 18 ) , SetFill ( 1 , 1 ) , SetDataTip ( SPR_CENTRE_VIEW_VEHICLE , 0x0 /* filled later */ ) ,
2009-10-24 13:49:04 +00:00
NWidget ( NWID_SELECTION , INVALID_COLOUR , VVW_WIDGET_SELECT_DEPOT_CLONE ) ,
2009-11-22 18:26:01 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , VVW_WIDGET_GOTO_DEPOT ) , SetMinimalSize ( 18 , 18 ) , SetFill ( 1 , 1 ) , SetDataTip ( 0x0 /* filled later */ , 0x0 /* filled later */ ) ,
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , VVW_WIDGET_CLONE_VEH ) , SetMinimalSize ( 18 , 18 ) , SetFill ( 1 , 1 ) , SetDataTip ( 0x0 /* filled later */ , 0x0 /* filled later */ ) ,
2009-05-03 13:13:41 +00:00
EndContainer ( ) ,
2009-10-24 13:49:04 +00:00
/* For trains only, 'ignore signal' button. */
2009-11-22 18:26:01 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , VVW_WIDGET_FORCE_PROCEED ) , SetMinimalSize ( 18 , 18 ) , SetFill ( 1 , 1 ) ,
2009-10-24 13:49:04 +00:00
SetDataTip ( SPR_IGNORE_SIGNALS , STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP ) ,
NWidget ( NWID_SELECTION , INVALID_COLOUR , VVW_WIDGET_SELECT_REFIT_TURN ) ,
2009-11-22 18:26:01 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , VVW_WIDGET_REFIT_VEH ) , SetMinimalSize ( 18 , 18 ) , SetFill ( 1 , 1 ) , SetDataTip ( SPR_REFIT_VEHICLE , 0x0 /* filled later */ ) ,
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , VVW_WIDGET_TURN_AROUND ) , SetMinimalSize ( 18 , 18 ) , SetFill ( 1 , 1 ) ,
2009-07-22 22:44:56 +00:00
SetDataTip ( SPR_FORCE_VEHICLE_TURN , STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP ) ,
2009-05-03 13:13:41 +00:00
EndContainer ( ) ,
2009-11-22 18:26:01 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , VVW_WIDGET_SHOW_ORDERS ) , SetFill ( 1 , 1 ) , SetMinimalSize ( 18 , 18 ) , SetDataTip ( SPR_SHOW_ORDERS , 0x0 /* filled later */ ) ,
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , VVW_WIDGET_SHOW_DETAILS ) , SetFill ( 1 , 1 ) , SetMinimalSize ( 18 , 18 ) , SetDataTip ( SPR_SHOW_VEHICLE_DETAILS , 0x0 /* filled later */ ) ,
2009-11-24 21:13:36 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY ) , SetFill ( 1 , 1 ) , SetMinimalSize ( 18 , 0 ) , SetResize ( 0 , 1 ) , EndContainer ( ) ,
2009-05-03 13:13:41 +00:00
EndContainer ( ) ,
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2011-09-17 20:38:23 +00:00
NWidget ( WWT_PUSHBTN , COLOUR_GREY , VVW_WIDGET_START_STOP_VEH ) , SetMinimalTextLines ( 1 , WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2 ) , SetResize ( 1 , 0 ) , SetFill ( 1 , 0 ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_RESIZEBOX , COLOUR_GREY ) ,
2009-05-03 13:13:41 +00:00
EndContainer ( ) ,
} ;
2007-08-29 20:50:58 +00:00
/** Vehicle view window descriptor for all vehicles but trains. */
2009-03-15 15:12:06 +00:00
static const WindowDesc _vehicle_view_desc (
2009-11-28 14:42:35 +00:00
WDP_AUTO , 250 , 116 ,
2007-08-29 20:50:58 +00:00
WC_VEHICLE_VIEW , WC_NONE ,
2009-11-24 17:28:29 +00:00
WDF_UNCLICK_BUTTONS ,
2009-11-15 10:26:01 +00:00
_nested_vehicle_view_widgets , lengthof ( _nested_vehicle_view_widgets )
2009-03-15 15:12:06 +00:00
) ;
2007-08-29 20:50:58 +00:00
2010-08-01 19:22:34 +00:00
/**
* Vehicle view window descriptor for trains . Only minimum_height and
2007-08-29 20:50:58 +00:00
* default_height are different for train view .
*/
2009-03-15 15:12:06 +00:00
static const WindowDesc _train_view_desc (
2009-11-28 14:42:35 +00:00
WDP_AUTO , 250 , 134 ,
2007-08-29 20:50:58 +00:00
WC_VEHICLE_VIEW , WC_NONE ,
2009-11-24 17:28:29 +00:00
WDF_UNCLICK_BUTTONS ,
2009-11-15 10:26:01 +00:00
_nested_vehicle_view_widgets , lengthof ( _nested_vehicle_view_widgets )
2009-03-15 15:12:06 +00:00
) ;
2007-08-29 20:50:58 +00:00
/* Just to make sure, nobody has changed the vehicle type constants, as we are
using them for array indexing in a number of places here . */
assert_compile ( VEH_TRAIN = = 0 ) ;
assert_compile ( VEH_ROAD = = 1 ) ;
assert_compile ( VEH_SHIP = = 2 ) ;
assert_compile ( VEH_AIRCRAFT = = 3 ) ;
/** Zoom levels for vehicle views indexed by vehicle type. */
static const ZoomLevel _vehicle_view_zoom_levels [ ] = {
ZOOM_LVL_TRAIN ,
ZOOM_LVL_ROADVEH ,
ZOOM_LVL_SHIP ,
ZOOM_LVL_AIRCRAFT ,
} ;
/* Constants for geometry of vehicle view viewport */
static const int VV_INITIAL_VIEWPORT_WIDTH = 226 ;
static const int VV_INITIAL_VIEWPORT_HEIGHT = 84 ;
static const int VV_INITIAL_VIEWPORT_HEIGHT_TRAIN = 102 ;
2008-05-19 09:39:05 +00:00
/** Command indices for the _vehicle_command_translation_table. */
enum VehicleCommandTranslation {
VCT_CMD_START_STOP = 0 ,
VCT_CMD_CLONE_VEH ,
VCT_CMD_TURN_AROUND ,
} ;
2007-08-29 20:50:58 +00:00
2008-05-19 09:39:05 +00:00
/** Command codes for the shared buttons indexed by VehicleCommandTranslation and vehicle type. */
static const uint32 _vehicle_command_translation_table [ ] [ 4 ] = {
{ // VCT_CMD_START_STOP
2009-04-21 23:40:56 +00:00
CMD_START_STOP_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_STOP_START_TRAIN ) ,
CMD_START_STOP_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_STOP_START_ROAD_VEHICLE ) ,
CMD_START_STOP_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_STOP_START_SHIP ) ,
CMD_START_STOP_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_STOP_START_AIRCRAFT )
2008-05-19 09:39:05 +00:00
} ,
{ // VCT_CMD_CLONE_VEH
2009-09-07 08:59:43 +00:00
CMD_CLONE_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_BUY_TRAIN ) ,
CMD_CLONE_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_BUY_ROAD_VEHICLE ) ,
CMD_CLONE_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_BUY_SHIP ) ,
CMD_CLONE_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_BUY_AIRCRAFT )
2008-05-19 09:39:05 +00:00
} ,
{ // VCT_CMD_TURN_AROUND
2009-07-08 22:11:55 +00:00
CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG ( STR_ERROR_CAN_T_REVERSE_DIRECTION_TRAIN ) ,
2009-07-22 19:12:20 +00:00
CMD_TURN_ROADVEH | CMD_MSG ( STR_ERROR_CAN_T_MAKE_ROAD_VEHICLE_TURN ) ,
2008-05-19 09:39:05 +00:00
0xffffffff , // invalid for ships
0xffffffff // invalid for aircrafts
} ,
} ;
2007-08-29 20:50:58 +00:00
2010-04-24 20:55:51 +00:00
/**
* This is the Callback method after the cloning attempt of a vehicle
* @ param result the result of the cloning command
* @ param tile unused
* @ param p1 vehicle ID
* @ param p2 unused
*/
void CcStartStopVehicle ( const CommandCost & result , TileIndex tile , uint32 p1 , uint32 p2 )
{
if ( result . Failed ( ) ) return ;
const Vehicle * v = Vehicle : : GetIfValid ( p1 ) ;
if ( v = = NULL | | ! v - > IsPrimaryVehicle ( ) | | v - > owner ! = _local_company ) return ;
StringID msg = ( v - > vehstatus & VS_STOPPED ) ? STR_VEHICLE_COMMAND_STOPPED : STR_VEHICLE_COMMAND_STARTED ;
Point pt = RemapCoords ( v - > x_pos , v - > y_pos , v - > z_pos ) ;
AddTextEffect ( msg , pt . x , pt . y , DAY_TICKS , TE_RISING ) ;
}
2010-04-24 14:29:30 +00:00
/**
* Executes # CMD_START_STOP_VEHICLE for given vehicle .
* @ param v Vehicle to start / stop
2010-04-24 20:55:51 +00:00
* @ param texteffect Should a texteffect be shown ?
2010-04-24 14:29:30 +00:00
*/
2010-04-24 20:55:51 +00:00
void StartStopVehicle ( const Vehicle * v , bool texteffect )
2010-04-24 14:29:30 +00:00
{
assert ( v - > IsPrimaryVehicle ( ) ) ;
2010-04-24 20:55:51 +00:00
DoCommandP ( v - > tile , v - > index , 0 , _vehicle_command_translation_table [ VCT_CMD_START_STOP ] [ v - > type ] , texteffect ? CcStartStopVehicle : NULL ) ;
2010-04-24 14:29:30 +00:00
}
2008-05-19 09:39:05 +00:00
/** Checks whether the vehicle may be refitted at the moment.*/
static bool IsVehicleRefitable ( const Vehicle * v )
2007-08-29 20:50:58 +00:00
{
2008-12-16 22:02:12 +00:00
if ( ! v - > IsStoppedInDepot ( ) ) return false ;
do {
if ( IsEngineRefittable ( v - > engine_type ) ) return true ;
2010-12-14 21:26:03 +00:00
} while ( v - > IsGroundVehicle ( ) & & ( v = v - > Next ( ) ) ! = NULL ) ;
2008-12-16 22:02:12 +00:00
return false ;
2008-05-19 09:39:05 +00:00
}
2009-10-24 15:19:06 +00:00
/** Window manager class for viewing a vehicle. */
2008-05-19 09:39:05 +00:00
struct VehicleViewWindow : Window {
2009-10-24 13:49:04 +00:00
private :
/** Display planes available in the vehicle view window. */
enum PlaneSelections {
SEL_DC_GOTO_DEPOT , ///< Display 'goto depot' button in #VVW_WIDGET_SELECT_DEPOT_CLONE stacked widget.
SEL_DC_CLONE , ///< Display 'clone vehicle' button in #VVW_WIDGET_SELECT_DEPOT_CLONE stacked widget.
SEL_RT_REFIT , ///< Display 'refit' button in #VVW_WIDGET_SELECT_REFIT_TURN stacked widget.
SEL_RT_TURN_AROUND , ///< Display 'turn around' button in #VVW_WIDGET_SELECT_REFIT_TURN stacked widget.
SEL_DC_BASEPLANE = SEL_DC_GOTO_DEPOT , ///< First plane of the #VVW_WIDGET_SELECT_DEPOT_CLONE stacked widget.
SEL_RT_BASEPLANE = SEL_RT_REFIT , ///< First plane of the #VVW_WIDGET_SELECT_REFIT_TURN stacked widget.
} ;
2010-08-01 19:22:34 +00:00
/**
* Display a plane in the window .
2009-10-24 13:49:04 +00:00
* @ param plane Plane to show .
*/
void SelectPlane ( PlaneSelections plane )
2008-05-19 09:39:05 +00:00
{
2009-10-24 13:49:04 +00:00
switch ( plane ) {
case SEL_DC_GOTO_DEPOT :
case SEL_DC_CLONE :
this - > GetWidget < NWidgetStacked > ( VVW_WIDGET_SELECT_DEPOT_CLONE ) - > SetDisplayedPlane ( plane - SEL_DC_BASEPLANE ) ;
break ;
2008-05-19 09:39:05 +00:00
2009-10-24 13:49:04 +00:00
case SEL_RT_REFIT :
case SEL_RT_TURN_AROUND :
this - > GetWidget < NWidgetStacked > ( VVW_WIDGET_SELECT_REFIT_TURN ) - > SetDisplayedPlane ( plane - SEL_RT_BASEPLANE ) ;
break ;
2007-08-29 20:50:58 +00:00
2009-10-24 13:49:04 +00:00
default :
NOT_REACHED ( ) ;
}
}
public :
VehicleViewWindow ( const WindowDesc * desc , WindowNumber window_number ) : Window ( )
{
2009-10-24 15:19:06 +00:00
this - > CreateNestedTree ( desc ) ;
/* Sprites for the 'send to depot' button indexed by vehicle type. */
static const SpriteID vehicle_view_goto_depot_sprites [ ] = {
SPR_SEND_TRAIN_TODEPOT ,
SPR_SEND_ROADVEH_TODEPOT ,
SPR_SEND_SHIP_TODEPOT ,
SPR_SEND_AIRCRAFT_TODEPOT ,
} ;
2009-10-24 13:49:04 +00:00
const Vehicle * v = Vehicle : : Get ( window_number ) ;
2009-10-24 15:19:06 +00:00
this - > GetWidget < NWidgetCore > ( VVW_WIDGET_GOTO_DEPOT ) - > widget_data = vehicle_view_goto_depot_sprites [ v - > type ] ;
2009-10-24 13:49:04 +00:00
2009-10-24 15:19:06 +00:00
/* Sprites for the 'clone vehicle' button indexed by vehicle type. */
static const SpriteID vehicle_view_clone_sprites [ ] = {
SPR_CLONE_TRAIN ,
SPR_CLONE_ROADVEH ,
SPR_CLONE_SHIP ,
SPR_CLONE_AIRCRAFT ,
} ;
this - > GetWidget < NWidgetCore > ( VVW_WIDGET_CLONE_VEH ) - > widget_data = vehicle_view_clone_sprites [ v - > type ] ;
2009-07-22 20:17:07 +00:00
2008-05-19 09:39:05 +00:00
switch ( v - > type ) {
case VEH_TRAIN :
2009-10-24 13:49:04 +00:00
this - > GetWidget < NWidgetCore > ( VVW_WIDGET_TURN_AROUND ) - > tool_tip = STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP ;
2008-05-19 09:39:05 +00:00
break ;
2007-08-29 20:50:58 +00:00
2008-05-19 09:39:05 +00:00
case VEH_ROAD :
break ;
2007-08-29 20:50:58 +00:00
2008-05-19 09:39:05 +00:00
case VEH_SHIP :
case VEH_AIRCRAFT :
2009-10-24 13:49:04 +00:00
this - > SelectPlane ( SEL_RT_REFIT ) ;
2008-05-19 09:39:05 +00:00
break ;
2009-07-22 20:17:07 +00:00
default : NOT_REACHED ( ) ;
2008-05-19 09:39:05 +00:00
}
2009-10-24 13:49:04 +00:00
this - > FinishInitNested ( desc , window_number ) ;
this - > owner = v - > owner ;
2009-10-24 13:58:18 +00:00
this - > GetWidget < NWidgetViewport > ( VVW_WIDGET_VIEWPORT ) - > InitializeViewport ( this , this - > window_number | ( 1 < < 31 ) , _vehicle_view_zoom_levels [ v - > type ] ) ;
2008-05-23 23:02:13 +00:00
2009-10-24 13:49:04 +00:00
this - > GetWidget < NWidgetCore > ( VVW_WIDGET_START_STOP_VEH ) - > tool_tip = STR_VEHICLE_VIEW_TRAIN_STATE_START_STOP_TOOLTIP + v - > type ;
this - > GetWidget < NWidgetCore > ( VVW_WIDGET_CENTER_MAIN_VIEH ) - > tool_tip = STR_VEHICLE_VIEW_TRAIN_LOCATION_TOOLTIP + v - > type ;
this - > GetWidget < NWidgetCore > ( VVW_WIDGET_REFIT_VEH ) - > tool_tip = STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP + v - > type ;
this - > GetWidget < NWidgetCore > ( VVW_WIDGET_GOTO_DEPOT ) - > tool_tip = STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP + v - > type ;
this - > GetWidget < NWidgetCore > ( VVW_WIDGET_SHOW_ORDERS ) - > tool_tip = STR_VEHICLE_VIEW_TRAIN_ORDERS_TOOLTIP + v - > type ;
this - > GetWidget < NWidgetCore > ( VVW_WIDGET_SHOW_DETAILS ) - > tool_tip = STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP + v - > type ;
this - > GetWidget < NWidgetCore > ( VVW_WIDGET_CLONE_VEH ) - > tool_tip = STR_VEHICLE_VIEW_CLONE_TRAIN_INFO + v - > type ;
2007-08-29 20:50:58 +00:00
}
2008-05-19 09:39:05 +00:00
~ VehicleViewWindow ( )
{
2009-01-02 20:59:04 +00:00
DeleteWindowById ( WC_VEHICLE_ORDERS , this - > window_number , false ) ;
DeleteWindowById ( WC_VEHICLE_REFIT , this - > window_number , false ) ;
DeleteWindowById ( WC_VEHICLE_DETAILS , this - > window_number , false ) ;
DeleteWindowById ( WC_VEHICLE_TIMETABLE , this - > window_number , false ) ;
2007-08-29 20:50:58 +00:00
}
2009-11-22 18:28:14 +00:00
virtual void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize )
2009-10-24 13:49:04 +00:00
{
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
switch ( widget ) {
case VVW_WIDGET_FORCE_PROCEED :
if ( v - > type ! = VEH_TRAIN ) {
size - > height = 0 ;
size - > width = 0 ;
2010-08-01 18:53:30 +00:00
}
2010-08-01 23:49:03 +00:00
break ;
2009-10-24 13:58:18 +00:00
case VVW_WIDGET_VIEWPORT :
size - > width = VV_INITIAL_VIEWPORT_WIDTH ;
size - > height = ( v - > type = = VEH_TRAIN ) ? VV_INITIAL_VIEWPORT_HEIGHT_TRAIN : VV_INITIAL_VIEWPORT_HEIGHT ;
break ;
2009-10-24 13:49:04 +00:00
}
}
2008-05-19 09:39:05 +00:00
virtual void OnPaint ( )
{
2009-05-16 23:34:14 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2008-09-30 20:39:50 +00:00
bool is_localcompany = v - > owner = = _local_company ;
2008-05-19 09:39:05 +00:00
bool refitable_and_stopped_in_depot = IsVehicleRefitable ( v ) ;
2008-09-30 20:39:50 +00:00
this - > SetWidgetDisabledState ( VVW_WIDGET_GOTO_DEPOT , ! is_localcompany ) ;
2009-10-24 13:49:04 +00:00
this - > SetWidgetDisabledState ( VVW_WIDGET_REFIT_VEH , ! refitable_and_stopped_in_depot | | ! is_localcompany ) ;
2008-09-30 20:39:50 +00:00
this - > SetWidgetDisabledState ( VVW_WIDGET_CLONE_VEH , ! is_localcompany ) ;
2008-05-19 09:39:05 +00:00
if ( v - > type = = VEH_TRAIN ) {
2010-06-21 17:35:27 +00:00
this - > SetWidgetLoweredState ( VVW_WIDGET_FORCE_PROCEED , Train : : From ( v ) - > force_proceed = = TFP_SIGNAL ) ;
2008-09-30 20:39:50 +00:00
this - > SetWidgetDisabledState ( VVW_WIDGET_FORCE_PROCEED , ! is_localcompany ) ;
this - > SetWidgetDisabledState ( VVW_WIDGET_TURN_AROUND , ! is_localcompany ) ;
2007-08-29 20:50:58 +00:00
}
2008-05-19 09:39:05 +00:00
this - > DrawWidgets ( ) ;
2009-10-24 13:49:04 +00:00
}
virtual void SetStringParameters ( int widget ) const
{
if ( widget ! = VVW_WIDGET_CAPTION ) return ;
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
SetDParam ( 0 , v - > index ) ;
}
virtual void DrawWidget ( const Rect & r , int widget ) const
{
if ( widget ! = VVW_WIDGET_START_STOP_VEH ) return ;
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
StringID str ;
2008-05-19 09:39:05 +00:00
if ( v - > vehstatus & VS_CRASHED ) {
2009-04-21 23:40:56 +00:00
str = STR_VEHICLE_STATUS_CRASHED ;
2008-05-19 09:39:05 +00:00
} else if ( v - > type ! = VEH_AIRCRAFT & & v - > breakdown_ctr = = 1 ) { // check for aircraft necessary?
2009-04-21 23:40:56 +00:00
str = STR_VEHICLE_STATUS_BROKEN_DOWN ;
2008-05-19 09:39:05 +00:00
} else if ( v - > vehstatus & VS_STOPPED ) {
if ( v - > type = = VEH_TRAIN ) {
if ( v - > cur_speed = = 0 ) {
2010-12-14 21:28:45 +00:00
if ( Train : : From ( v ) - > gcache . cached_power = = 0 ) {
2009-08-05 17:59:21 +00:00
str = STR_VEHICLE_STATUS_TRAIN_NO_POWER ;
2008-05-19 09:39:05 +00:00
} else {
2009-04-21 23:40:56 +00:00
str = STR_VEHICLE_STATUS_STOPPED ;
2008-05-19 09:39:05 +00:00
}
2007-08-29 20:50:58 +00:00
} else {
2008-05-19 09:39:05 +00:00
SetDParam ( 0 , v - > GetDisplaySpeed ( ) ) ;
2011-02-04 14:37:24 +00:00
str = STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL ;
2007-08-29 20:50:58 +00:00
}
2008-05-19 09:39:05 +00:00
} else { // no train
2009-04-21 23:40:56 +00:00
str = STR_VEHICLE_STATUS_STOPPED ;
2007-08-29 20:50:58 +00:00
}
2009-07-21 17:14:05 +00:00
} else if ( v - > type = = VEH_TRAIN & & HasBit ( Train : : From ( v ) - > flags , VRF_TRAIN_STUCK ) & & ! v - > current_order . IsType ( OT_LOADING ) ) {
2009-08-05 17:59:21 +00:00
str = STR_VEHICLE_STATUS_TRAIN_STUCK ;
2008-05-19 09:39:05 +00:00
} else { // vehicle is in a "normal" state, show current order
switch ( v - > current_order . GetType ( ) ) {
case OT_GOTO_STATION : {
2008-04-06 07:48:51 +00:00
SetDParam ( 0 , v - > current_order . GetDestination ( ) ) ;
2007-08-29 20:50:58 +00:00
SetDParam ( 1 , v - > GetDisplaySpeed ( ) ) ;
2011-02-04 14:37:24 +00:00
str = STR_VEHICLE_STATUS_HEADING_FOR_STATION_VEL ;
2010-08-01 18:53:30 +00:00
break ;
}
2008-05-19 09:39:05 +00:00
case OT_GOTO_DEPOT : {
2010-05-12 18:19:36 +00:00
SetDParam ( 0 , v - > type ) ;
SetDParam ( 1 , v - > current_order . GetDestination ( ) ) ;
SetDParam ( 2 , v - > GetDisplaySpeed ( ) ) ;
2011-02-08 22:36:16 +00:00
if ( v - > current_order . GetDepotActionType ( ) & ODATFB_NEAREST_DEPOT ) {
/* This case *only* happens when multiple nearest depot orders
* follow eachother ( including an order list only one order : a
* nearest depot order ) and there are no reachable depots .
* It is primarily to guard for the case that there is no
* depot with index 0 , which would be used as fallback for
* evaluating the string in the status bar . */
str = STR_EMPTY ;
} else if ( v - > current_order . GetDepotActionType ( ) & ODATFB_HALT ) {
2011-02-04 14:37:24 +00:00
str = STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_VEL ;
2008-05-19 09:39:05 +00:00
} else {
2011-02-04 14:37:24 +00:00
str = STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_SERVICE_VEL ;
2008-05-19 09:39:05 +00:00
}
2010-08-01 18:53:30 +00:00
break ;
}
2008-05-19 09:39:05 +00:00
case OT_LOADING :
2009-04-21 23:40:56 +00:00
str = STR_VEHICLE_STATUS_LOADING_UNLOADING ;
2008-05-19 09:39:05 +00:00
break ;
case OT_GOTO_WAYPOINT : {
2009-07-10 18:30:02 +00:00
assert ( v - > type = = VEH_TRAIN | | v - > type = = VEH_SHIP ) ;
2008-05-19 09:39:05 +00:00
SetDParam ( 0 , v - > current_order . GetDestination ( ) ) ;
2011-02-04 14:37:24 +00:00
str = STR_VEHICLE_STATUS_HEADING_FOR_WAYPOINT_VEL ;
2007-08-29 20:50:58 +00:00
SetDParam ( 1 , v - > GetDisplaySpeed ( ) ) ;
2008-05-19 09:39:05 +00:00
break ;
2007-08-29 20:50:58 +00:00
}
2008-05-19 09:39:05 +00:00
case OT_LEAVESTATION :
if ( v - > type ! = VEH_AIRCRAFT ) {
2009-04-21 23:40:56 +00:00
str = STR_VEHICLE_STATUS_LEAVING ;
2008-05-19 09:39:05 +00:00
break ;
}
2010-07-29 14:26:28 +00:00
/* FALL THROUGH, if aircraft. Does this even happen? */
2007-08-29 20:50:58 +00:00
2008-05-19 09:39:05 +00:00
default :
2010-12-26 13:25:34 +00:00
if ( v - > GetNumManualOrders ( ) = = 0 ) {
2011-02-04 14:37:24 +00:00
str = STR_VEHICLE_STATUS_NO_ORDERS_VEL ;
2008-05-19 09:39:05 +00:00
SetDParam ( 0 , v - > GetDisplaySpeed ( ) ) ;
} else {
str = STR_EMPTY ;
}
break ;
2007-08-29 20:50:58 +00:00
}
2008-05-19 09:39:05 +00:00
}
2007-08-29 20:50:58 +00:00
2008-05-19 09:39:05 +00:00
/* draw the flag plus orders */
2009-10-24 13:49:04 +00:00
DrawSprite ( v - > vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING , PAL_NONE , WD_FRAMERECT_LEFT , r . top + WD_FRAMERECT_TOP ) ;
2010-07-02 13:53:05 +00:00
DrawString ( r . left + WD_FRAMERECT_LEFT + 6 , r . right - WD_FRAMERECT_RIGHT , r . top + WD_FRAMERECT_TOP , str , TC_FROMSTRING , SA_HOR_CENTER ) ;
2008-05-19 09:39:05 +00:00
}
2010-01-30 18:34:48 +00:00
virtual void OnClick ( Point pt , int widget , int click_count )
2008-05-19 09:39:05 +00:00
{
2009-05-16 23:34:14 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2008-05-19 09:39:05 +00:00
switch ( widget ) {
case VVW_WIDGET_START_STOP_VEH : // start stop
2010-02-22 20:53:45 +00:00
if ( _ctrl_pressed ) {
/* Scroll to current order destination */
TileIndex tile = v - > current_order . GetLocation ( v ) ;
if ( tile ! = INVALID_TILE ) ScrollMainWindowToTile ( tile ) ;
} else {
/* Start/Stop */
2010-04-24 20:55:51 +00:00
StartStopVehicle ( v , false ) ;
2010-02-22 20:53:45 +00:00
}
2008-05-19 09:39:05 +00:00
break ;
2009-03-15 00:32:18 +00:00
case VVW_WIDGET_CENTER_MAIN_VIEH : { // center main view
2008-05-19 09:39:05 +00:00
const Window * mainwindow = FindWindowById ( WC_MAIN_WINDOW , 0 ) ;
/* code to allow the main window to 'follow' the vehicle if the ctrl key is pressed */
if ( _ctrl_pressed & & mainwindow - > viewport - > zoom = = ZOOM_LVL_NORMAL ) {
mainwindow - > viewport - > follow_vehicle = v - > index ;
} else {
2009-03-15 15:25:18 +00:00
ScrollMainWindowTo ( v - > x_pos , v - > y_pos , v - > z_pos ) ;
2007-08-29 20:50:58 +00:00
}
2010-08-01 18:53:30 +00:00
break ;
}
2007-08-29 20:50:58 +00:00
2008-05-19 09:39:05 +00:00
case VVW_WIDGET_GOTO_DEPOT : // goto hangar
2010-09-08 21:37:13 +00:00
DoCommandP ( v - > tile , v - > index | ( _ctrl_pressed ? DEPOT_SERVICE : 0U ) , 0 , GetCmdSendToDepot ( v ) ) ;
2008-05-19 09:39:05 +00:00
break ;
case VVW_WIDGET_REFIT_VEH : // refit
2008-09-24 16:40:06 +00:00
ShowVehicleRefitWindow ( v , INVALID_VEH_ORDER_ID , this ) ;
2008-05-19 09:39:05 +00:00
break ;
case VVW_WIDGET_SHOW_ORDERS : // show orders
if ( _ctrl_pressed ) {
ShowTimetableWindow ( v ) ;
2007-08-29 20:50:58 +00:00
} else {
2008-05-19 09:39:05 +00:00
ShowOrdersWindow ( v ) ;
2007-08-29 20:50:58 +00:00
}
break ;
2008-05-19 09:39:05 +00:00
case VVW_WIDGET_SHOW_DETAILS : // show details
ShowVehicleDetailsWindow ( v ) ;
break ;
case VVW_WIDGET_CLONE_VEH : // clone vehicle
2008-12-28 14:37:19 +00:00
DoCommandP ( v - > tile , v - > index , _ctrl_pressed ? 1 : 0 ,
_vehicle_command_translation_table [ VCT_CMD_CLONE_VEH ] [ v - > type ] ,
CcCloneVehicle ) ;
2008-05-19 09:39:05 +00:00
break ;
case VVW_WIDGET_TURN_AROUND : // turn around
2010-12-14 21:26:03 +00:00
assert ( v - > IsGroundVehicle ( ) ) ;
2008-12-28 14:37:19 +00:00
DoCommandP ( v - > tile , v - > index , 0 ,
2008-05-19 09:39:05 +00:00
_vehicle_command_translation_table [ VCT_CMD_TURN_AROUND ] [ v - > type ] ) ;
break ;
case VVW_WIDGET_FORCE_PROCEED : // force proceed
assert ( v - > type = = VEH_TRAIN ) ;
2009-04-21 23:40:56 +00:00
DoCommandP ( v - > tile , v - > index , 0 , CMD_FORCE_TRAIN_PROCEED | CMD_MSG ( STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL ) ) ;
2008-05-19 09:39:05 +00:00
break ;
2007-08-29 20:50:58 +00:00
}
}
2009-10-24 14:53:55 +00:00
virtual void OnResize ( )
2008-05-19 09:39:05 +00:00
{
2009-10-24 13:58:18 +00:00
if ( this - > viewport ! = NULL ) {
NWidgetViewport * nvp = this - > GetWidget < NWidgetViewport > ( VVW_WIDGET_VIEWPORT ) ;
nvp - > UpdateViewportCoordinates ( this ) ;
}
2008-05-19 09:39:05 +00:00
}
2007-08-29 20:50:58 +00:00
2008-05-19 09:39:05 +00:00
virtual void OnTick ( )
{
2009-05-16 23:34:14 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2008-05-19 09:39:05 +00:00
bool veh_stopped = v - > IsStoppedInDepot ( ) ;
2009-10-24 13:49:04 +00:00
/* Widget VVW_WIDGET_GOTO_DEPOT must be hidden if the vehicle is already stopped in depot.
* Widget VVW_WIDGET_CLONE_VEH should then be shown , since cloning is allowed only while in depot and stopped .
*/
PlaneSelections plane = veh_stopped ? SEL_DC_CLONE : SEL_DC_GOTO_DEPOT ;
NWidgetStacked * nwi = this - > GetWidget < NWidgetStacked > ( VVW_WIDGET_SELECT_DEPOT_CLONE ) ; // Selection widget 'send to depot' / 'clone'.
if ( nwi - > shown_plane + SEL_DC_BASEPLANE ! = plane ) {
this - > SelectPlane ( plane ) ;
this - > SetWidgetDirty ( VVW_WIDGET_SELECT_DEPOT_CLONE ) ;
}
/* The same system applies to widget VVW_WIDGET_REFIT_VEH and VVW_WIDGET_TURN_AROUND.*/
2010-12-14 21:26:03 +00:00
if ( v - > IsGroundVehicle ( ) ) {
2009-10-24 13:49:04 +00:00
PlaneSelections plane = veh_stopped ? SEL_RT_REFIT : SEL_RT_TURN_AROUND ;
NWidgetStacked * nwi = this - > GetWidget < NWidgetStacked > ( VVW_WIDGET_SELECT_REFIT_TURN ) ;
if ( nwi - > shown_plane + SEL_RT_BASEPLANE ! = plane ) {
this - > SelectPlane ( plane ) ;
this - > SetWidgetDirty ( VVW_WIDGET_SELECT_REFIT_TURN ) ;
2008-05-19 09:39:05 +00:00
}
}
}
2010-04-24 13:39:11 +00:00
2011-03-13 21:31:29 +00:00
/**
* Some data on this window has become invalid .
* @ param data Information about the changed data .
* @ param gui_scope Whether the call is done from GUI scope . You may not do everything when not in GUI scope . See # InvalidateWindowData ( ) for details .
*/
virtual void OnInvalidateData ( int data = 0 , bool gui_scope = true )
2011-03-08 19:41:58 +00:00
{
if ( data = = - 666 ) {
/* Autoreplace replaced the vehicle.
2011-03-13 21:33:02 +00:00
* Nothing to do for this window . */
2011-03-08 19:41:58 +00:00
return ;
}
}
2010-04-24 13:39:11 +00:00
virtual bool IsNewGRFInspectable ( ) const
{
return : : IsNewGRFInspectable ( GetGrfSpecFeature ( Vehicle : : Get ( this - > window_number ) - > type ) , this - > window_number ) ;
}
virtual void ShowNewGRFInspectWindow ( ) const
{
: : ShowNewGRFInspectWindow ( GetGrfSpecFeature ( Vehicle : : Get ( this - > window_number ) - > type ) , this - > window_number ) ;
}
2007-08-29 20:50:58 +00:00
} ;
2008-05-19 09:39:05 +00:00
/** Shows the vehicle view window of the given vehicle. */
void ShowVehicleViewWindow ( const Vehicle * v )
2007-08-29 20:50:58 +00:00
{
2008-05-19 09:39:05 +00:00
AllocateWindowDescFront < VehicleViewWindow > ( ( v - > type = = VEH_TRAIN ) ? & _train_view_desc : & _vehicle_view_desc , v - > index ) ;
2007-08-29 20:50:58 +00:00
}
2007-12-27 13:35:39 +00:00
2010-09-06 14:14:09 +00:00
/**
* Dispatch a " vehicle selected " event if any window waits for it .
* @ param v selected vehicle ;
* @ return did any window accept vehicle selection ?
*/
bool VehicleClicked ( const Vehicle * v )
{
assert ( v ! = NULL ) ;
if ( ! ( _thd . place_mode & HT_VEHICLE ) ) return false ;
v = v - > First ( ) ;
if ( ! v - > IsPrimaryVehicle ( ) ) return false ;
2010-12-30 13:18:04 +00:00
_thd . GetCallbackWnd ( ) - > OnVehicleSelect ( v ) ;
2010-09-06 14:14:09 +00:00
return true ;
}
2008-05-17 13:01:30 +00:00
void StopGlobalFollowVehicle ( const Vehicle * v )
{
Window * w = FindWindowById ( WC_MAIN_WINDOW , 0 ) ;
if ( w ! = NULL & & w - > viewport - > follow_vehicle = = v - > index ) {
2009-03-15 15:25:18 +00:00
ScrollMainWindowTo ( v - > x_pos , v - > y_pos , v - > z_pos , true ) ; // lock the main view on the vehicle's last position
2008-05-17 13:01:30 +00:00
w - > viewport - > follow_vehicle = INVALID_VEHICLE ;
}
}
2010-01-11 18:34:02 +00:00
/**
* This is the Callback method after the construction attempt of a primary vehicle
2010-01-11 18:46:09 +00:00
* @ param result indicates completion ( or not ) of the operation
2010-01-11 18:34:02 +00:00
* @ param tile unused
* @ param p1 unused
* @ param p2 unused
*/
2010-01-11 18:46:09 +00:00
void CcBuildPrimaryVehicle ( const CommandCost & result , TileIndex tile , uint32 p1 , uint32 p2 )
2010-01-11 18:34:02 +00:00
{
2010-01-11 18:46:09 +00:00
if ( result . Failed ( ) ) return ;
2010-01-11 18:34:02 +00:00
const Vehicle * v = Vehicle : : Get ( _new_vehicle_id ) ;
ShowVehicleViewWindow ( v ) ;
}
2010-12-21 13:54:57 +00:00
/**
* Get the width of a vehicle ( including all parts of the consist ) in pixels .
* @ param v Vehicle to get the width for .
* @ return Width of the vehicle .
*/
2011-11-01 16:51:47 +00:00
int GetVehicleWidth ( Vehicle * v , EngineImageType image_type )
2010-12-21 13:54:57 +00:00
{
int vehicle_width = 0 ;
switch ( v - > type ) {
case VEH_TRAIN :
for ( const Train * u = Train : : From ( v ) ; u ! = NULL ; u = u - > Next ( ) ) {
vehicle_width + = u - > GetDisplayImageWidth ( ) ;
}
break ;
case VEH_ROAD :
for ( const RoadVehicle * u = RoadVehicle : : From ( v ) ; u ! = NULL ; u = u - > Next ( ) ) {
vehicle_width + = u - > GetDisplayImageWidth ( ) ;
}
break ;
default :
bool rtl = _current_text_dir = = TD_RTL ;
2011-11-01 16:51:47 +00:00
SpriteID sprite = v - > GetImage ( rtl ? DIR_E : DIR_W , image_type ) ;
2010-12-21 13:54:57 +00:00
const Sprite * real_sprite = GetSprite ( sprite , ST_NORMAL ) ;
vehicle_width = real_sprite - > width ;
break ;
}
return vehicle_width ;
}