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 depot_gui.cpp The GUI for depots. */
2007-02-23 18:55:07 +00:00
2010-01-15 16:41:15 +00:00
# include "stdafx.h"
2006-09-27 15:47:00 +00:00
# include "train.h"
2012-12-23 01:00:25 +00:00
# include "roadveh.h"
2006-09-26 16:47:51 +00:00
# include "ship.h"
2006-09-27 15:40:55 +00:00
# include "aircraft.h"
2006-09-26 16:47:51 +00:00
# include "gui.h"
2007-12-19 20:45:46 +00:00
# include "textbuf_gui.h"
2008-01-09 09:45:45 +00:00
# include "viewport_func.h"
2007-12-21 21:50:46 +00:00
# include "command_func.h"
2008-04-17 19:10:30 +00:00
# include "depot_base.h"
2007-02-10 13:37:32 +00:00
# include "spritecache.h"
2007-12-21 19:49:27 +00:00
# include "strings_func.h"
2007-12-27 13:35:39 +00:00
# include "vehicle_func.h"
2008-09-30 20:51:04 +00:00
# include "company_func.h"
2008-05-07 13:10:15 +00:00
# include "tilehighlight_func.h"
2008-05-17 13:01:30 +00:00
# include "window_gui.h"
2008-05-28 11:56:21 +00:00
# include "vehiclelist.h"
2022-11-26 17:03:21 +00:00
# include "vehicle_func.h"
2010-08-18 15:15:59 +00:00
# include "order_backup.h"
2011-11-24 12:38:48 +00:00
# include "zoom_func.h"
2022-11-26 17:03:21 +00:00
# include "error.h"
2021-10-31 18:39:09 +00:00
# include "depot_cmd.h"
# include "train_cmd.h"
# include "vehicle_cmd.h"
2022-11-23 21:01:09 +00:00
# include "core/geometry_func.hpp"
2006-09-27 13:01:56 +00:00
2011-12-15 22:22:55 +00:00
# include "widgets/depot_widget.h"
2008-01-13 01:21:35 +00:00
# include "table/strings.h"
2014-04-23 20:13:33 +00:00
# include "safeguards.h"
2006-09-27 13:01:56 +00:00
/*
* Since all depot window sizes aren ' t the same , we need to modify sizes a little .
* It ' s done with the following arrays of widget indexes . Each of them tells if a widget side should be moved and in what direction .
* How long they should be moved and for what window types are controlled in ShowDepotWindow ( )
*/
2009-09-26 19:21:20 +00:00
/** Nested widget definition for train depots. */
2024-01-15 22:49:24 +00:00
static constexpr NWidgetPart _nested_train_depot_widgets [ ] = {
2009-09-26 19:21:20 +00:00
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
2020-12-27 21:45:58 +00:00
NWidget ( NWID_SELECTION , INVALID_COLOUR , WID_D_SHOW_RENAME ) , // rename button
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_D_RENAME ) , SetMinimalSize ( 12 , 14 ) , SetDataTip ( SPR_RENAME , STR_DEPOT_RENAME_TOOLTIP ) ,
EndContainer ( ) ,
2011-12-16 16:57:56 +00:00
NWidget ( WWT_CAPTION , COLOUR_GREY , WID_D_CAPTION ) , SetDataTip ( STR_DEPOT_CAPTION , STR_NULL ) ,
2020-12-27 21:45:58 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_D_LOCATION ) , SetMinimalSize ( 12 , 14 ) , SetDataTip ( SPR_GOTO_LOCATION , STR_NULL ) ,
2009-12-21 16:24:29 +00:00
NWidget ( WWT_SHADEBOX , COLOUR_GREY ) ,
2013-05-26 19:30:07 +00:00
NWidget ( WWT_DEFSIZEBOX , COLOUR_GREY ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_STICKYBOX , COLOUR_GREY ) ,
2009-09-26 19:21:20 +00:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( NWID_VERTICAL ) ,
2013-06-30 14:32:31 +00:00
NWidget ( WWT_MATRIX , COLOUR_GREY , WID_D_MATRIX ) , SetResize ( 1 , 1 ) , SetScrollbar ( WID_D_V_SCROLL ) ,
2011-12-16 16:57:56 +00:00
NWidget ( NWID_SELECTION , INVALID_COLOUR , WID_D_SHOW_H_SCROLL ) ,
NWidget ( NWID_HSCROLLBAR , COLOUR_GREY , WID_D_H_SCROLL ) ,
2010-08-12 11:46:20 +00:00
EndContainer ( ) ,
2009-09-26 19:21:20 +00:00
EndContainer ( ) ,
NWidget ( NWID_VERTICAL ) ,
2011-12-16 16:57:56 +00:00
NWidget ( WWT_IMGBTN , COLOUR_GREY , WID_D_SELL ) , SetDataTip ( 0x0 , STR_NULL ) , SetResize ( 0 , 1 ) , SetFill ( 0 , 1 ) ,
NWidget ( NWID_SELECTION , INVALID_COLOUR , WID_D_SHOW_SELL_CHAIN ) ,
NWidget ( WWT_IMGBTN , COLOUR_GREY , WID_D_SELL_CHAIN ) , SetDataTip ( SPR_SELL_CHAIN_TRAIN , STR_DEPOT_DRAG_WHOLE_TRAIN_TO_SELL_TOOLTIP ) , SetResize ( 0 , 1 ) , SetFill ( 0 , 1 ) ,
2010-08-12 11:46:20 +00:00
EndContainer ( ) ,
2011-12-16 16:57:56 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_D_SELL_ALL ) , SetDataTip ( 0x0 , STR_NULL ) ,
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_D_AUTOREPLACE ) , SetDataTip ( 0x0 , STR_NULL ) ,
2009-09-26 19:21:20 +00:00
EndContainer ( ) ,
2011-12-16 16:57:56 +00:00
NWidget ( NWID_VSCROLLBAR , COLOUR_GREY , WID_D_V_SCROLL ) ,
2009-09-26 19:21:20 +00:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL , NC_EQUALSIZE ) ,
2011-12-16 16:57:56 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_D_BUILD ) , SetDataTip ( 0x0 , STR_NULL ) , SetFill ( 1 , 1 ) , SetResize ( 1 , 0 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , WID_D_CLONE ) , SetDataTip ( 0x0 , STR_NULL ) , SetFill ( 1 , 1 ) , SetResize ( 1 , 0 ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_D_VEHICLE_LIST ) , SetDataTip ( 0x0 , STR_NULL ) , SetFill ( 0 , 1 ) ,
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_D_STOP_ALL ) , SetDataTip ( SPR_FLAG_VEH_STOPPED , STR_NULL ) , SetFill ( 0 , 1 ) ,
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_D_START_ALL ) , SetDataTip ( SPR_FLAG_VEH_RUNNING , STR_NULL ) , SetFill ( 0 , 1 ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_RESIZEBOX , COLOUR_GREY ) ,
2009-09-26 19:21:20 +00:00
EndContainer ( ) ,
2006-09-26 16:47:51 +00:00
} ;
2023-11-02 19:33:01 +00:00
static WindowDesc _train_depot_desc ( __FILE__ , __LINE__ ,
2013-05-26 19:25:01 +00:00
WDP_AUTO , " depot_train " , 362 , 123 ,
2007-02-01 15:49:12 +00:00
WC_VEHICLE_DEPOT , WC_NONE ,
2012-11-11 16:10:43 +00:00
0 ,
2023-09-03 20:54:13 +00:00
std : : begin ( _nested_train_depot_widgets ) , std : : end ( _nested_train_depot_widgets )
2009-03-15 15:12:06 +00:00
) ;
2006-09-26 16:47:51 +00:00
2023-11-02 19:33:01 +00:00
static WindowDesc _road_depot_desc ( __FILE__ , __LINE__ ,
2013-05-26 19:25:01 +00:00
WDP_AUTO , " depot_roadveh " , 316 , 97 ,
2007-02-01 15:49:12 +00:00
WC_VEHICLE_DEPOT , WC_NONE ,
2012-11-11 16:10:43 +00:00
0 ,
2023-09-03 20:54:13 +00:00
std : : begin ( _nested_train_depot_widgets ) , std : : end ( _nested_train_depot_widgets )
2009-03-15 15:12:06 +00:00
) ;
2006-09-26 16:47:51 +00:00
2023-11-02 19:33:01 +00:00
static WindowDesc _ship_depot_desc ( __FILE__ , __LINE__ ,
2013-05-26 19:25:01 +00:00
WDP_AUTO , " depot_ship " , 306 , 99 ,
2007-02-01 15:49:12 +00:00
WC_VEHICLE_DEPOT , WC_NONE ,
2012-11-11 16:10:43 +00:00
0 ,
2023-09-03 20:54:13 +00:00
std : : begin ( _nested_train_depot_widgets ) , std : : end ( _nested_train_depot_widgets )
2009-03-15 15:12:06 +00:00
) ;
2006-09-26 16:47:51 +00:00
2023-11-02 19:33:01 +00:00
static WindowDesc _aircraft_depot_desc ( __FILE__ , __LINE__ ,
2013-05-26 19:25:01 +00:00
WDP_AUTO , " depot_aircraft " , 332 , 99 ,
2007-02-01 15:49:12 +00:00
WC_VEHICLE_DEPOT , WC_NONE ,
2012-11-11 16:10:43 +00:00
0 ,
2023-09-03 20:54:13 +00:00
std : : begin ( _nested_train_depot_widgets ) , std : : end ( _nested_train_depot_widgets )
2009-03-15 15:12:06 +00:00
) ;
2006-09-26 16:47:51 +00:00
2008-05-25 17:22:49 +00:00
extern void DepotSortList ( VehicleList * list ) ;
2006-09-26 16:47:51 +00:00
2007-08-26 21:21:59 +00:00
/**
* This is the Callback method after the cloning attempt of a vehicle
2021-11-28 21:43:38 +00:00
* @ param result the result of the cloning command
2021-11-30 22:21:16 +00:00
* @ param veh_id cloned vehicle ID
2007-08-26 21:21:59 +00:00
*/
2023-09-16 20:20:53 +00:00
void CcCloneVehicle ( Commands , const CommandCost & result , VehicleID veh_id )
2006-09-26 16:47:51 +00:00
{
2010-01-11 18:46:09 +00:00
if ( result . Failed ( ) ) return ;
2007-08-26 21:21:59 +00:00
2021-11-30 22:21:16 +00:00
const Vehicle * v = Vehicle : : Get ( veh_id ) ;
2007-08-26 21:21:59 +00:00
2007-08-29 20:50:58 +00:00
ShowVehicleViewWindow ( v ) ;
2006-09-26 16:47:51 +00:00
}
2008-05-25 09:40:44 +00:00
static void TrainDepotMoveVehicle ( const Vehicle * wagon , VehicleID sel , const Vehicle * head )
2006-09-26 16:47:51 +00:00
{
2009-05-16 23:34:14 +00:00
const Vehicle * v = Vehicle : : Get ( sel ) ;
2006-09-26 16:47:51 +00:00
if ( v = = wagon ) return ;
2019-04-10 21:07:06 +00:00
if ( wagon = = nullptr ) {
if ( head ! = nullptr ) wagon = head - > Last ( ) ;
2009-08-20 10:23:39 +00:00
} else {
2007-08-30 21:11:12 +00:00
wagon = wagon - > Previous ( ) ;
2019-04-10 21:07:06 +00:00
if ( wagon = = nullptr ) return ;
2006-09-26 16:47:51 +00:00
}
if ( wagon = = v ) return ;
2021-11-05 22:55:23 +00:00
Command < CMD_MOVE_RAIL_VEHICLE > : : Post ( STR_ERROR_CAN_T_MOVE_VEHICLE , v - > tile , v - > index , wagon = = nullptr ? INVALID_VEHICLE : wagon - > index , _ctrl_pressed ) ;
2006-09-26 16:47:51 +00:00
}
2012-12-23 01:00:25 +00:00
static VehicleCellSize _base_block_sizes_depot [ VEH_COMPANY_END ] ; ///< Cell size for vehicle images in the depot view.
static VehicleCellSize _base_block_sizes_purchase [ VEH_COMPANY_END ] ; ///< Cell size for vehicle images in the purchase list.
2017-08-26 12:12:59 +00:00
static uint _consistent_train_width ; ///< Whether trains of all lengths are consistently scaled. Either TRAININFO_DEFAULT_VEHICLE_WIDTH, VEHICLEINFO_FULL_VEHICLE_WIDTH, or 0.
2012-12-23 01:00:25 +00:00
2010-08-01 19:22:34 +00:00
/**
2012-12-23 01:00:25 +00:00
* Get the GUI cell size for a vehicle image .
* @ param type Vehicle type to get the size for .
* @ param image_type Image type to get size for .
* @ pre image_type = = EIT_IN_DEPOT | | image_type = = EIT_PURCHASE
* @ return Cell dimensions for the vehicle and image type .
2010-08-01 19:44:49 +00:00
*/
2012-12-23 01:00:25 +00:00
VehicleCellSize GetVehicleImageCellSize ( VehicleType type , EngineImageType image_type )
{
switch ( image_type ) {
case EIT_IN_DEPOT : return _base_block_sizes_depot [ type ] ;
case EIT_PURCHASE : return _base_block_sizes_purchase [ type ] ;
default : NOT_REACHED ( ) ;
}
}
2007-02-10 13:37:32 +00:00
2012-12-23 01:00:25 +00:00
static void InitBlocksizeForVehicles ( VehicleType type , EngineImageType image_type )
2007-02-10 13:37:32 +00:00
{
2012-12-23 01:00:25 +00:00
int max_extend_left = 0 ;
int max_extend_right = 0 ;
2007-02-10 13:37:32 +00:00
uint max_height = 0 ;
2019-12-15 21:45:18 +00:00
for ( const Engine * e : Engine : : IterateType ( type ) ) {
2012-12-26 12:24:03 +00:00
if ( ! e - > IsEnabled ( ) ) continue ;
2008-04-29 21:31:29 +00:00
EngineID eid = e - > index ;
2007-02-10 13:37:32 +00:00
uint x , y ;
2012-12-23 01:00:25 +00:00
int x_offs , y_offs ;
2007-02-10 13:37:32 +00:00
switch ( type ) {
default : NOT_REACHED ( ) ;
2012-12-23 01:00:25 +00:00
case VEH_TRAIN : GetTrainSpriteSize ( eid , x , y , x_offs , y_offs , image_type ) ; break ;
case VEH_ROAD : GetRoadVehSpriteSize ( eid , x , y , x_offs , y_offs , image_type ) ; break ;
case VEH_SHIP : GetShipSpriteSize ( eid , x , y , x_offs , y_offs , image_type ) ; break ;
case VEH_AIRCRAFT : GetAircraftSpriteSize ( eid , x , y , x_offs , y_offs , image_type ) ; break ;
2007-02-10 13:37:32 +00:00
}
if ( y > max_height ) max_height = y ;
2012-12-23 01:00:25 +00:00
if ( - x_offs > max_extend_left ) max_extend_left = - x_offs ;
if ( ( int ) x + x_offs > max_extend_right ) max_extend_right = x + x_offs ;
2007-02-10 13:37:32 +00:00
}
2022-09-05 20:05:18 +00:00
int min_extend = ScaleSpriteTrad ( 16 ) ;
int max_extend = ScaleSpriteTrad ( 98 ) ;
2014-10-04 16:40:23 +00:00
2012-12-23 01:00:25 +00:00
switch ( image_type ) {
case EIT_IN_DEPOT :
2022-09-05 20:05:18 +00:00
_base_block_sizes_depot [ type ] . height = std : : max < uint > ( ScaleSpriteTrad ( GetVehicleHeight ( type ) ) , max_height ) ;
2014-10-04 16:40:23 +00:00
_base_block_sizes_depot [ type ] . extend_left = Clamp ( max_extend_left , min_extend , max_extend ) ;
_base_block_sizes_depot [ type ] . extend_right = Clamp ( max_extend_right , min_extend , max_extend ) ;
2007-02-10 13:37:32 +00:00
break ;
2012-12-23 01:00:25 +00:00
case EIT_PURCHASE :
2022-09-05 20:05:18 +00:00
_base_block_sizes_purchase [ type ] . height = std : : max < uint > ( ScaleSpriteTrad ( GetVehicleHeight ( type ) ) , max_height ) ;
2014-10-04 16:40:23 +00:00
_base_block_sizes_purchase [ type ] . extend_left = Clamp ( max_extend_left , min_extend , max_extend ) ;
_base_block_sizes_purchase [ type ] . extend_right = Clamp ( max_extend_right , min_extend , max_extend ) ;
2007-02-10 13:37:32 +00:00
break ;
2012-12-23 01:00:25 +00:00
default : NOT_REACHED ( ) ;
2007-02-10 13:37:32 +00:00
}
}
2010-08-01 19:22:34 +00:00
/**
* Set the size of the blocks in the window so we can be sure that they are big enough for the vehicle sprites in the current game .
2010-08-01 19:44:49 +00:00
* @ note Calling this function once for each game is enough .
*/
2007-02-10 13:37:32 +00:00
void InitDepotWindowBlockSizes ( )
{
2012-12-23 01:00:25 +00:00
for ( VehicleType vt = VEH_BEGIN ; vt < VEH_COMPANY_END ; vt + + ) {
InitBlocksizeForVehicles ( vt , EIT_IN_DEPOT ) ;
InitBlocksizeForVehicles ( vt , EIT_PURCHASE ) ;
}
2017-08-26 12:12:59 +00:00
_consistent_train_width = TRAININFO_DEFAULT_VEHICLE_WIDTH ;
bool first = true ;
2019-12-15 21:45:18 +00:00
for ( const Engine * e : Engine : : IterateType ( VEH_TRAIN ) ) {
2017-08-26 12:12:59 +00:00
if ( ! e - > IsEnabled ( ) ) continue ;
uint w = TRAININFO_DEFAULT_VEHICLE_WIDTH ;
2019-04-10 21:07:06 +00:00
if ( e - > GetGRF ( ) ! = nullptr & & is_custom_sprite ( e - > u . rail . image_index ) ) {
2017-08-26 12:12:59 +00:00
w = e - > GetGRF ( ) - > traininfo_vehicle_width ;
if ( w ! = VEHICLEINFO_FULL_VEHICLE_WIDTH ) {
/* Hopeless.
* This is a NewGRF vehicle that uses TRAININFO_DEFAULT_VEHICLE_WIDTH .
* If the vehicles are shorter than 8 / 8 we have fractional lengths , which are not consistent after rounding .
*/
_consistent_train_width = 0 ;
break ;
}
}
if ( first ) {
_consistent_train_width = w ;
first = false ;
} else if ( w ! = _consistent_train_width ) {
_consistent_train_width = 0 ;
break ;
}
}
2007-02-10 13:37:32 +00:00
}
2008-05-13 13:39:50 +00:00
static void DepotSellAllConfirmationCallback ( Window * w , bool confirmed ) ;
const Sprite * GetAircraftSprite ( EngineID engine ) ;
struct DepotWindow : Window {
VehicleID sel ;
2010-05-23 15:02:26 +00:00
VehicleID vehicle_over ; ///< Rail vehicle over which another one is dragged, \c INVALID_VEHICLE if none.
2008-05-13 13:39:50 +00:00
VehicleType type ;
bool generate_list ;
2023-12-29 19:11:59 +00:00
WidgetID hovered_widget ; ///< Index of the widget being hovered during drag/drop. -1 if no drag is in progress.
2008-05-25 17:22:49 +00:00
VehicleList vehicle_list ;
VehicleList wagon_list ;
2014-10-14 11:40:38 +00:00
uint unitnumber_digits ;
2010-08-12 11:21:30 +00:00
uint num_columns ; ///< Number of columns.
2010-08-12 08:37:01 +00:00
Scrollbar * hscroll ; ///< Only for trains.
Scrollbar * vscroll ;
2006-12-07 00:51:20 +00:00
2013-05-26 19:23:42 +00:00
DepotWindow ( WindowDesc * desc , TileIndex tile , VehicleType type ) : Window ( desc )
2008-05-13 13:39:50 +00:00
{
2009-11-16 20:34:57 +00:00
assert ( IsCompanyBuildableVehicleType ( type ) ) ; // ensure that we make the call with a valid type
2008-05-13 13:39:50 +00:00
this - > sel = INVALID_VEHICLE ;
2010-05-23 15:02:26 +00:00
this - > vehicle_over = INVALID_VEHICLE ;
2008-05-13 13:39:50 +00:00
this - > generate_list = true ;
2015-11-20 09:25:27 +00:00
this - > hovered_widget = - 1 ;
2009-09-26 18:47:41 +00:00
this - > type = type ;
2010-08-12 11:21:30 +00:00
this - > num_columns = 1 ; // for non-trains this gets set in FinishInitNested()
2014-10-14 11:40:38 +00:00
this - > unitnumber_digits = 2 ;
2007-02-10 13:37:32 +00:00
2013-05-26 19:23:42 +00:00
this - > CreateNestedTree ( ) ;
2019-04-10 21:07:06 +00:00
this - > hscroll = ( this - > type = = VEH_TRAIN ? this - > GetScrollbar ( WID_D_H_SCROLL ) : nullptr ) ;
2011-12-16 16:57:56 +00:00
this - > vscroll = this - > GetScrollbar ( WID_D_V_SCROLL ) ;
2010-05-12 20:50:10 +00:00
/* Don't show 'rename button' of aircraft hangar */
2011-12-16 16:57:56 +00:00
this - > GetWidget < NWidgetStacked > ( WID_D_SHOW_RENAME ) - > SetDisplayedPlane ( type = = VEH_AIRCRAFT ? SZSP_NONE : 0 ) ;
2010-08-12 11:46:20 +00:00
/* Only train depots have a horizontal scrollbar and a 'sell chain' button */
2013-06-30 14:36:31 +00:00
if ( type = = VEH_TRAIN ) this - > GetWidget < NWidgetCore > ( WID_D_MATRIX ) - > widget_data = 1 < < MAT_COL_START ;
2011-12-16 16:57:56 +00:00
this - > GetWidget < NWidgetStacked > ( WID_D_SHOW_H_SCROLL ) - > SetDisplayedPlane ( type = = VEH_TRAIN ? 0 : SZSP_HORIZONTAL ) ;
this - > GetWidget < NWidgetStacked > ( WID_D_SHOW_SELL_CHAIN ) - > SetDisplayedPlane ( type = = VEH_TRAIN ? 0 : SZSP_NONE ) ;
2009-09-26 19:21:20 +00:00
this - > SetupWidgetData ( type ) ;
2013-05-26 19:23:42 +00:00
this - > FinishInitNested ( tile ) ;
2009-10-20 21:25:25 +00:00
2009-09-26 19:21:20 +00:00
this - > owner = GetTileOwner ( tile ) ;
2010-08-18 15:15:59 +00:00
OrderBackup : : Reset ( ) ;
2008-05-13 13:39:50 +00:00
}
2023-10-13 11:59:15 +00:00
void Close ( [[maybe_unused]] int data = 0 ) override
2008-05-13 13:39:50 +00:00
{
2021-05-17 13:46:38 +00:00
CloseWindowById ( WC_BUILD_VEHICLE , this - > window_number ) ;
CloseWindowById ( GetWindowClassForVehicleType ( this - > type ) , VehicleListIdentifier ( VL_DEPOT_LIST , this - > type , this - > owner , this - > GetDepotIndex ( ) ) . Pack ( ) , false ) ;
2010-08-18 18:52:16 +00:00
OrderBackup : : Reset ( this - > window_number ) ;
2021-05-15 21:12:25 +00:00
this - > Window : : Close ( ) ;
2008-05-13 13:39:50 +00:00
}
2006-12-07 00:51:20 +00:00
2010-08-01 19:22:34 +00:00
/**
* Draw a vehicle in the depot window in the box with the top left corner at x , y .
2009-09-26 18:15:35 +00:00
* @ param v Vehicle to draw .
2022-11-23 21:01:09 +00:00
* @ param r Rect to draw in .
2009-03-14 18:16:29 +00:00
*/
2022-11-23 21:01:09 +00:00
void DrawVehicleInDepot ( const Vehicle * v , const Rect & r ) const
2008-05-13 13:39:50 +00:00
{
2009-07-18 17:38:18 +00:00
bool free_wagon = false ;
2008-05-13 13:39:50 +00:00
2010-11-13 09:56:25 +00:00
bool rtl = _current_text_dir = = TD_RTL ;
2022-11-23 21:01:09 +00:00
Rect text = r . Shrink ( RectPadding : : zero , WidgetDimensions : : scaled . matrix ) ; /* Ract for text elements, horizontal is already applied. */
Rect image = r . Indent ( this - > header_width , rtl ) . Indent ( this - > count_width , ! rtl ) ; /* Rect for vehicle images */
2009-11-18 10:45:49 +00:00
2008-05-13 13:39:50 +00:00
switch ( v - > type ) {
2009-07-18 17:38:18 +00:00
case VEH_TRAIN : {
const Train * u = Train : : From ( v ) ;
free_wagon = u - > IsFreeWagon ( ) ;
2017-08-26 12:12:59 +00:00
uint x_space = free_wagon ?
2022-09-05 20:05:18 +00:00
ScaleSpriteTrad ( _consistent_train_width ! = 0 ? _consistent_train_width : TRAININFO_DEFAULT_VEHICLE_WIDTH ) :
2017-08-26 12:12:59 +00:00
0 ;
2022-11-23 21:01:09 +00:00
DrawTrainImage ( u , image . Indent ( x_space , rtl ) , this - > sel , EIT_IN_DEPOT , free_wagon ? 0 : this - > hscroll - > GetPosition ( ) , this - > vehicle_over ) ;
2008-05-13 13:39:50 +00:00
2011-04-09 20:27:34 +00:00
/* Length of consist in tiles with 1 fractional digit (rounded up) */
SetDParam ( 0 , CeilDiv ( u - > gcache . cached_total_length * 10 , TILE_SIZE ) ) ;
SetDParam ( 1 , 1 ) ;
2022-11-23 21:01:09 +00:00
Rect count = text . WithWidth ( this - > count_width - WidgetDimensions : : scaled . hsep_normal , ! rtl ) ;
2023-11-21 19:04:24 +00:00
DrawString ( count . left , count . right , count . bottom - GetCharacterHeight ( FS_SMALL ) + 1 , STR_JUST_DECIMAL , TC_BLACK , SA_RIGHT , false , FS_SMALL ) ; // Draw the counter
2008-05-13 13:39:50 +00:00
break ;
2009-07-18 17:38:18 +00:00
}
2008-05-13 13:39:50 +00:00
2022-11-23 21:01:09 +00:00
case VEH_ROAD : DrawRoadVehImage ( v , image , this - > sel , EIT_IN_DEPOT ) ; break ;
case VEH_SHIP : DrawShipImage ( v , image , this - > sel , EIT_IN_DEPOT ) ; break ;
case VEH_AIRCRAFT : DrawAircraftImage ( v , image , this - > sel , EIT_IN_DEPOT ) ; break ;
2008-05-13 13:39:50 +00:00
default : NOT_REACHED ( ) ;
}
2006-12-07 00:51:20 +00:00
2009-11-18 10:45:49 +00:00
uint diff_x , diff_y ;
2010-12-14 21:26:03 +00:00
if ( v - > IsGroundVehicle ( ) ) {
2009-11-18 10:45:49 +00:00
/* Arrange unitnumber and flag horizontally */
2022-11-23 21:01:09 +00:00
diff_x = this - > flag_size . width + WidgetDimensions : : scaled . hsep_normal ;
diff_y = WidgetDimensions : : scaled . matrix . top ;
2008-05-13 13:39:50 +00:00
} else {
2009-11-18 10:45:49 +00:00
/* Arrange unitnumber and flag vertically */
2022-09-23 08:36:22 +00:00
diff_x = 0 ;
2023-11-21 19:04:24 +00:00
diff_y = WidgetDimensions : : scaled . matrix . top + GetCharacterHeight ( FS_NORMAL ) + WidgetDimensions : : scaled . vsep_normal ;
2009-11-18 10:45:49 +00:00
}
2006-12-07 00:51:20 +00:00
2023-11-21 19:04:24 +00:00
text = text . WithWidth ( this - > header_width - WidgetDimensions : : scaled . hsep_normal , rtl ) . WithHeight ( GetCharacterHeight ( FS_NORMAL ) ) . Indent ( diff_x , rtl ) ;
2009-11-18 10:45:49 +00:00
if ( free_wagon ) {
2022-11-23 21:01:09 +00:00
DrawString ( text , STR_DEPOT_NO_ENGINE ) ;
2009-11-18 10:45:49 +00:00
} else {
2022-11-23 21:01:09 +00:00
Rect flag = r . WithWidth ( this - > flag_size . width , rtl ) . WithHeight ( this - > flag_size . height ) . Translate ( 0 , diff_y ) ;
2023-12-04 18:19:55 +00:00
DrawSpriteIgnorePadding ( ( v - > vehstatus & VS_STOPPED ) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING , PAL_NONE , flag , SA_CENTER ) ;
2007-02-10 13:37:32 +00:00
2009-07-18 17:38:18 +00:00
SetDParam ( 0 , v - > unitnumber ) ;
2023-08-16 13:43:31 +00:00
DrawString ( text , STR_JUST_COMMA , ( v - > max_age - CalendarTime : : DAYS_IN_LEAP_YEAR ) > = v - > age ? TC_BLACK : TC_RED ) ;
2009-07-18 17:38:18 +00:00
}
2006-12-07 00:51:20 +00:00
}
2023-12-29 19:11:59 +00:00
void DrawWidget ( const Rect & r , WidgetID widget ) const override
2008-05-13 13:39:50 +00:00
{
2011-12-16 16:57:56 +00:00
if ( widget ! = WID_D_MATRIX ) return ;
2006-12-07 00:51:20 +00:00
2010-11-13 09:56:25 +00:00
bool rtl = _current_text_dir = = TD_RTL ;
2009-11-18 10:45:49 +00:00
2009-09-26 19:21:20 +00:00
/* Set the row and number of boxes in each row based on the number of boxes drawn in the matrix */
2013-06-30 14:36:31 +00:00
const NWidgetCore * wid = this - > GetWidget < NWidgetCore > ( WID_D_MATRIX ) ;
2017-08-26 12:12:59 +00:00
2022-11-23 21:01:09 +00:00
/* Set up rect for each cell */
Rect ir = r . WithHeight ( this - > resize . step_height ) ;
if ( this - > num_columns ! = 1 ) ir = ir . WithWidth ( this - > resize . step_width , rtl ) ;
ir = ir . Shrink ( WidgetDimensions : : scaled . framerect , RectPadding : : zero ) ;
2022-09-23 08:36:22 +00:00
2017-08-26 12:12:59 +00:00
/* Draw vertical separators at whole tiles.
* This only works in two cases :
* - All vehicles use VEHICLEINFO_FULL_VEHICLE_WIDTH as reference width .
* - All vehicles are 8 / 8. This cannot be checked for NewGRF , so instead we check for " all vehicles are original vehicles " .
*/
if ( this - > type = = VEH_TRAIN & & _consistent_train_width ! = 0 ) {
2022-09-05 20:05:18 +00:00
int w = ScaleSpriteTrad ( 2 * _consistent_train_width ) ;
2017-08-26 12:12:59 +00:00
int col = _colour_gradient [ wid - > colour ] [ 4 ] ;
2022-11-23 21:01:09 +00:00
Rect image = ir . Indent ( this - > header_width , rtl ) . Indent ( this - > count_width , ! rtl ) ;
2017-12-10 13:48:49 +00:00
int first_line = w + ( - this - > hscroll - > GetPosition ( ) ) % w ;
2017-08-26 12:12:59 +00:00
if ( rtl ) {
2022-11-23 21:01:09 +00:00
for ( int x = image . right - first_line ; x > = image . left ; x - = w ) {
2022-09-23 08:36:22 +00:00
GfxDrawLine ( x , r . top , x , r . bottom , col , ScaleGUITrad ( 1 ) , ScaleGUITrad ( 3 ) ) ;
2017-08-26 12:12:59 +00:00
}
} else {
2022-11-23 21:01:09 +00:00
for ( int x = image . left + first_line ; x < = image . right ; x + = w ) {
2022-09-23 08:36:22 +00:00
GfxDrawLine ( x , r . top , x , r . bottom , col , ScaleGUITrad ( 1 ) , ScaleGUITrad ( 3 ) ) ;
2017-08-26 12:12:59 +00:00
}
}
}
2023-05-08 17:01:06 +00:00
uint16_t rows_in_display = wid - > current_y / wid - > resize_y ;
2006-12-07 00:51:20 +00:00
2021-05-10 21:43:52 +00:00
uint num = this - > vscroll - > GetPosition ( ) * this - > num_columns ;
2021-01-08 10:16:18 +00:00
uint maxval = static_cast < uint > ( std : : min < size_t > ( this - > vehicle_list . size ( ) , num + ( rows_in_display * this - > num_columns ) ) ) ;
2022-11-23 21:01:09 +00:00
for ( ; num < maxval ; ir = ir . Translate ( 0 , this - > resize . step_height ) ) { // Draw the rows
Rect cell = ir ; /* Keep track of horizontal cells */
2021-05-10 21:43:52 +00:00
for ( uint i = 0 ; i < this - > num_columns & & num < maxval ; i + + , num + + ) {
2008-05-13 13:39:50 +00:00
/* Draw all vehicles in the current row */
2008-05-25 17:22:49 +00:00
const Vehicle * v = this - > vehicle_list [ num ] ;
2022-11-23 21:01:09 +00:00
this - > DrawVehicleInDepot ( v , cell ) ;
cell = cell . Translate ( rtl ? - ( int ) this - > resize . step_width : ( int ) this - > resize . step_width , 0 ) ;
2008-05-13 13:39:50 +00:00
}
}
2006-10-05 13:11:17 +00:00
2021-01-08 10:16:18 +00:00
maxval = static_cast < uint > ( std : : min < size_t > ( this - > vehicle_list . size ( ) + this - > wagon_list . size ( ) , ( this - > vscroll - > GetPosition ( ) * this - > num_columns ) + ( rows_in_display * this - > num_columns ) ) ) ;
2006-10-05 12:59:28 +00:00
2010-10-30 17:51:07 +00:00
/* Draw the train wagons without an engine in front. */
2022-11-23 21:01:09 +00:00
for ( ; num < maxval ; num + + , ir = ir . Translate ( 0 , this - > resize . step_height ) ) {
2018-09-23 11:23:54 +00:00
const Vehicle * v = this - > wagon_list [ num - this - > vehicle_list . size ( ) ] ;
2022-11-23 21:01:09 +00:00
this - > DrawVehicleInDepot ( v , ir ) ;
2009-09-26 19:21:20 +00:00
}
}
2023-12-29 19:11:59 +00:00
void SetStringParameters ( WidgetID widget ) const override
2009-09-26 19:21:20 +00:00
{
2011-12-16 16:57:56 +00:00
if ( widget ! = WID_D_CAPTION ) return ;
2009-09-26 19:21:20 +00:00
2010-05-12 18:19:36 +00:00
SetDParam ( 0 , this - > type ) ;
2021-02-22 13:50:32 +00:00
SetDParam ( 1 , this - > GetDepotIndex ( ) ) ;
2008-05-13 13:39:50 +00:00
}
struct GetDepotVehiclePtData {
2008-05-25 09:40:44 +00:00
const Vehicle * head ;
const Vehicle * wagon ;
2008-05-13 13:39:50 +00:00
} ;
enum DepotGUIAction {
MODE_ERROR ,
MODE_DRAG_VEHICLE ,
MODE_SHOW_VEHICLE ,
MODE_START_STOP ,
} ;
2008-05-25 09:40:44 +00:00
DepotGUIAction GetVehicleFromDepotWndPt ( int x , int y , const Vehicle * * veh , GetDepotVehiclePtData * d ) const
2008-05-13 13:39:50 +00:00
{
2011-12-16 16:57:56 +00:00
const NWidgetCore * matrix_widget = this - > GetWidget < NWidgetCore > ( WID_D_MATRIX ) ;
2023-05-13 22:18:36 +00:00
/* Make X relative to widget. Y is left alone for GetScrolledRowFromWidget(). */
x - = matrix_widget - > pos_x ;
2009-11-18 10:45:49 +00:00
/* In case of RTL the widgets are swapped as a whole */
2010-11-13 09:56:25 +00:00
if ( _current_text_dir = = TD_RTL ) x = matrix_widget - > current_x - x ;
2009-11-18 10:45:49 +00:00
2009-11-17 22:58:41 +00:00
uint xt = 0 , xm = 0 , ym = 0 ;
2008-05-13 13:39:50 +00:00
if ( this - > type = = VEH_TRAIN ) {
2009-11-17 22:58:41 +00:00
xm = x ;
2008-05-13 13:39:50 +00:00
} else {
xt = x / this - > resize . step_width ;
xm = x % this - > resize . step_width ;
2010-08-12 11:21:30 +00:00
if ( xt > = this - > num_columns ) return MODE_ERROR ;
2008-05-13 13:39:50 +00:00
}
2023-05-13 22:18:36 +00:00
ym = ( y - matrix_widget - > pos_y ) % this - > resize . step_height ;
2008-05-13 13:39:50 +00:00
2023-05-03 10:17:52 +00:00
int row = this - > vscroll - > GetScrolledRowFromWidget ( y , this , WID_D_MATRIX ) ;
uint pos = ( row * this - > num_columns ) + xt ;
2008-05-13 13:39:50 +00:00
2023-11-28 13:52:36 +00:00
if ( row = = INT_MAX | | this - > vehicle_list . size ( ) + this - > wagon_list . size ( ) < = pos ) {
2009-11-17 22:58:41 +00:00
/* Clicking on 'line' / 'block' without a vehicle */
2008-05-13 13:39:50 +00:00
if ( this - > type = = VEH_TRAIN ) {
2009-11-17 22:58:41 +00:00
/* End the dragging */
2019-04-10 21:07:06 +00:00
d - > head = nullptr ;
d - > wagon = nullptr ;
2008-05-13 13:39:50 +00:00
return MODE_DRAG_VEHICLE ;
2006-10-05 12:59:28 +00:00
} else {
2008-05-13 13:39:50 +00:00
return MODE_ERROR ; // empty block, so no vehicle is selected
2006-10-05 12:59:28 +00:00
}
2008-05-13 13:39:50 +00:00
}
2006-09-26 16:47:51 +00:00
2009-11-18 10:45:49 +00:00
bool wagon = false ;
2018-09-23 11:23:54 +00:00
if ( this - > vehicle_list . size ( ) > pos ) {
2008-05-25 17:22:49 +00:00
* veh = this - > vehicle_list [ pos ] ;
2009-11-17 22:58:41 +00:00
/* Skip vehicles that are scrolled off the list */
2010-08-12 11:21:30 +00:00
if ( this - > type = = VEH_TRAIN ) x + = this - > hscroll - > GetPosition ( ) ;
2008-05-13 13:39:50 +00:00
} else {
2019-03-27 23:09:33 +00:00
pos - = ( uint ) this - > vehicle_list . size ( ) ;
2008-05-25 17:22:49 +00:00
* veh = this - > wagon_list [ pos ] ;
2008-05-13 13:39:50 +00:00
/* free wagons don't have an initial loco. */
2022-09-05 20:05:18 +00:00
x - = ScaleSpriteTrad ( VEHICLEINFO_FULL_VEHICLE_WIDTH ) ;
2009-11-18 10:45:49 +00:00
wagon = true ;
2008-05-13 13:39:50 +00:00
}
2006-09-26 16:47:51 +00:00
2019-04-10 21:07:06 +00:00
const Train * v = nullptr ;
2009-11-17 22:58:41 +00:00
if ( this - > type = = VEH_TRAIN ) {
v = Train : : From ( * veh ) ;
d - > head = d - > wagon = v ;
}
2006-09-26 16:47:51 +00:00
2009-11-17 22:58:41 +00:00
if ( xm < = this - > header_width ) {
switch ( this - > type ) {
case VEH_TRAIN :
2009-11-18 10:45:49 +00:00
if ( wagon ) return MODE_ERROR ;
2024-01-31 20:03:17 +00:00
[[fallthrough]] ;
2017-08-13 18:38:42 +00:00
2009-11-17 22:58:41 +00:00
case VEH_ROAD :
2022-11-23 21:01:09 +00:00
if ( xm < = this - > flag_size . width ) return MODE_START_STOP ;
2009-11-17 22:58:41 +00:00
break ;
2006-09-26 19:20:35 +00:00
2009-11-17 22:58:41 +00:00
case VEH_SHIP :
case VEH_AIRCRAFT :
2023-11-21 19:04:24 +00:00
if ( xm < = this - > flag_size . width & & ym > = ( uint ) ( GetCharacterHeight ( FS_NORMAL ) + WidgetDimensions : : scaled . vsep_normal ) ) return MODE_START_STOP ;
2009-11-17 22:58:41 +00:00
break ;
2006-09-27 22:44:39 +00:00
2009-11-17 22:58:41 +00:00
default : NOT_REACHED ( ) ;
2009-07-13 19:30:37 +00:00
}
2009-11-17 22:58:41 +00:00
return MODE_SHOW_VEHICLE ;
}
2006-09-30 13:39:34 +00:00
2009-11-17 22:58:41 +00:00
if ( this - > type ! = VEH_TRAIN ) return MODE_DRAG_VEHICLE ;
2006-09-26 16:47:51 +00:00
2009-11-18 10:45:49 +00:00
/* Clicking on the counter */
if ( xm > = matrix_widget - > current_x - this - > count_width ) return wagon ? MODE_ERROR : MODE_SHOW_VEHICLE ;
2009-11-17 22:58:41 +00:00
/* Account for the header */
x - = this - > header_width ;
2006-09-26 16:47:51 +00:00
2009-11-17 22:58:41 +00:00
/* find the vehicle in this row that was clicked */
2019-04-10 21:07:06 +00:00
for ( ; v ! = nullptr ; v = v - > Next ( ) ) {
2009-11-17 22:58:41 +00:00
x - = v - > GetDisplayImageWidth ( ) ;
if ( x < 0 ) break ;
2008-05-13 13:39:50 +00:00
}
2009-11-17 22:58:41 +00:00
2019-04-10 21:07:06 +00:00
d - > wagon = ( v ! = nullptr ? v - > GetFirstEnginePart ( ) : nullptr ) ;
2009-11-17 22:58:41 +00:00
return MODE_DRAG_VEHICLE ;
2008-05-13 13:39:50 +00:00
}
2008-02-17 12:21:05 +00:00
2010-08-01 19:22:34 +00:00
/**
* Handle click in the depot matrix .
2009-10-20 21:41:44 +00:00
* @ param x Horizontal position in the matrix widget in pixels .
* @ param y Vertical position in the matrix widget in pixels .
*/
2008-05-13 13:39:50 +00:00
void DepotClick ( int x , int y )
{
2019-04-10 21:07:06 +00:00
GetDepotVehiclePtData gdvp = { nullptr , nullptr } ;
const Vehicle * v = nullptr ;
2008-05-13 13:39:50 +00:00
DepotGUIAction mode = this - > GetVehicleFromDepotWndPt ( x , y , & v , & gdvp ) ;
2006-09-26 16:47:51 +00:00
2008-05-13 13:39:50 +00:00
if ( this - > type = = VEH_TRAIN ) v = gdvp . wagon ;
switch ( mode ) {
case MODE_ERROR : // invalid
return ;
case MODE_DRAG_VEHICLE : { // start dragging of vehicle
2019-04-10 21:07:06 +00:00
if ( v ! = nullptr & & VehicleClicked ( v ) ) return ;
2010-09-06 14:14:09 +00:00
2008-05-13 13:39:50 +00:00
VehicleID sel = this - > sel ;
if ( this - > type = = VEH_TRAIN & & sel ! = INVALID_VEHICLE ) {
this - > sel = INVALID_VEHICLE ;
TrainDepotMoveVehicle ( v , sel , gdvp . head ) ;
2019-04-10 21:07:06 +00:00
} else if ( v ! = nullptr ) {
2016-08-15 18:33:52 +00:00
SetObjectToPlaceWnd ( SPR_CURSOR_MOUSE , PAL_NONE , HT_DRAG , this ) ;
SetMouseCursorVehicle ( v , EIT_IN_DEPOT ) ;
_cursor . vehchain = _ctrl_pressed ;
2008-05-13 13:39:50 +00:00
this - > sel = v - > index ;
this - > SetDirty ( ) ;
}
2010-08-01 18:53:30 +00:00
break ;
}
2008-05-13 13:39:50 +00:00
case MODE_SHOW_VEHICLE : // show info window
ShowVehicleViewWindow ( v ) ;
break ;
2010-04-24 14:29:30 +00:00
case MODE_START_STOP : // click start/stop flag
2010-04-24 20:55:51 +00:00
StartStopVehicle ( v , false ) ;
2010-04-24 14:29:30 +00:00
break ;
2006-09-26 16:47:51 +00:00
2008-05-13 13:39:50 +00:00
default : NOT_REACHED ( ) ;
}
}
2006-09-26 16:47:51 +00:00
2010-10-30 17:51:07 +00:00
/**
* Function to set up vehicle specific widgets ( mainly sprites and strings ) .
* Only use this function to if the widget is used for several vehicle types and each has
* different text / sprites . If the widget is only used for a single vehicle type , or the same
* text / sprites are used every time , use the nested widget array to initialize the widget .
2008-05-13 13:39:50 +00:00
*/
2009-09-26 19:21:20 +00:00
void SetupWidgetData ( VehicleType type )
2008-05-13 13:39:50 +00:00
{
2011-12-16 16:57:56 +00:00
this - > GetWidget < NWidgetCore > ( WID_D_STOP_ALL ) - > tool_tip = STR_DEPOT_MASS_STOP_DEPOT_TRAIN_TOOLTIP + type ;
this - > GetWidget < NWidgetCore > ( WID_D_START_ALL ) - > tool_tip = STR_DEPOT_MASS_START_DEPOT_TRAIN_TOOLTIP + type ;
this - > GetWidget < NWidgetCore > ( WID_D_SELL ) - > tool_tip = STR_DEPOT_TRAIN_SELL_TOOLTIP + type ;
this - > GetWidget < NWidgetCore > ( WID_D_SELL_ALL ) - > tool_tip = STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TOOLTIP + type ;
2009-07-22 20:17:07 +00:00
2011-12-16 16:57:56 +00:00
this - > GetWidget < NWidgetCore > ( WID_D_BUILD ) - > SetDataTip ( STR_DEPOT_TRAIN_NEW_VEHICLES_BUTTON + type , STR_DEPOT_TRAIN_NEW_VEHICLES_TOOLTIP + type ) ;
this - > GetWidget < NWidgetCore > ( WID_D_CLONE ) - > SetDataTip ( STR_DEPOT_CLONE_TRAIN + type , STR_DEPOT_CLONE_TRAIN_DEPOT_INFO + type ) ;
2009-07-22 20:17:07 +00:00
2011-12-16 16:57:56 +00:00
this - > GetWidget < NWidgetCore > ( WID_D_LOCATION ) - > tool_tip = STR_DEPOT_TRAIN_LOCATION_TOOLTIP + type ;
this - > GetWidget < NWidgetCore > ( WID_D_VEHICLE_LIST ) - > tool_tip = STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TOOLTIP + type ;
this - > GetWidget < NWidgetCore > ( WID_D_AUTOREPLACE ) - > tool_tip = STR_DEPOT_AUTOREPLACE_TRAIN_TOOLTIP + type ;
this - > GetWidget < NWidgetCore > ( WID_D_MATRIX ) - > tool_tip = STR_DEPOT_TRAIN_LIST_TOOLTIP + this - > type ;
2009-07-22 20:17:07 +00:00
2008-05-13 13:39:50 +00:00
switch ( type ) {
default : NOT_REACHED ( ) ;
2006-09-26 16:47:51 +00:00
2008-05-13 13:39:50 +00:00
case VEH_TRAIN :
2011-12-16 16:57:56 +00:00
this - > GetWidget < NWidgetCore > ( WID_D_VEHICLE_LIST ) - > widget_data = STR_TRAIN ;
2008-05-13 13:39:50 +00:00
/* Sprites */
2011-12-16 16:57:56 +00:00
this - > GetWidget < NWidgetCore > ( WID_D_SELL ) - > widget_data = SPR_SELL_TRAIN ;
this - > GetWidget < NWidgetCore > ( WID_D_SELL_ALL ) - > widget_data = SPR_SELL_ALL_TRAIN ;
this - > GetWidget < NWidgetCore > ( WID_D_AUTOREPLACE ) - > widget_data = SPR_REPLACE_TRAIN ;
2008-05-13 13:39:50 +00:00
break ;
case VEH_ROAD :
2011-12-16 16:57:56 +00:00
this - > GetWidget < NWidgetCore > ( WID_D_VEHICLE_LIST ) - > widget_data = STR_LORRY ;
2008-05-13 13:39:50 +00:00
/* Sprites */
2011-12-16 16:57:56 +00:00
this - > GetWidget < NWidgetCore > ( WID_D_SELL ) - > widget_data = SPR_SELL_ROADVEH ;
this - > GetWidget < NWidgetCore > ( WID_D_SELL_ALL ) - > widget_data = SPR_SELL_ALL_ROADVEH ;
this - > GetWidget < NWidgetCore > ( WID_D_AUTOREPLACE ) - > widget_data = SPR_REPLACE_ROADVEH ;
2008-05-13 13:39:50 +00:00
break ;
case VEH_SHIP :
2011-12-16 16:57:56 +00:00
this - > GetWidget < NWidgetCore > ( WID_D_VEHICLE_LIST ) - > widget_data = STR_SHIP ;
2008-05-13 13:39:50 +00:00
/* Sprites */
2011-12-16 16:57:56 +00:00
this - > GetWidget < NWidgetCore > ( WID_D_SELL ) - > widget_data = SPR_SELL_SHIP ;
this - > GetWidget < NWidgetCore > ( WID_D_SELL_ALL ) - > widget_data = SPR_SELL_ALL_SHIP ;
this - > GetWidget < NWidgetCore > ( WID_D_AUTOREPLACE ) - > widget_data = SPR_REPLACE_SHIP ;
2008-05-13 13:39:50 +00:00
break ;
case VEH_AIRCRAFT :
2011-12-16 16:57:56 +00:00
this - > GetWidget < NWidgetCore > ( WID_D_VEHICLE_LIST ) - > widget_data = STR_PLANE ;
2008-05-13 13:39:50 +00:00
/* Sprites */
2011-12-16 16:57:56 +00:00
this - > GetWidget < NWidgetCore > ( WID_D_SELL ) - > widget_data = SPR_SELL_AIRCRAFT ;
this - > GetWidget < NWidgetCore > ( WID_D_SELL_ALL ) - > widget_data = SPR_SELL_ALL_AIRCRAFT ;
this - > GetWidget < NWidgetCore > ( WID_D_AUTOREPLACE ) - > widget_data = SPR_REPLACE_AIRCRAFT ;
2008-05-13 13:39:50 +00:00
break ;
}
}
2022-11-23 21:01:09 +00:00
uint count_width ; ///< Width of length count, including separator.
uint header_width ; ///< Width of unit number and flag, including separator.
Dimension flag_size ; ///< Size of start/stop flag.
VehicleCellSize cell_size ; ///< Vehicle sprite cell size.
void OnInit ( ) override
{
this - > cell_size = GetVehicleImageCellSize ( this - > type , EIT_IN_DEPOT ) ;
this - > flag_size = maxdim ( GetScaledSpriteSize ( SPR_FLAG_VEH_STOPPED ) , GetScaledSpriteSize ( SPR_FLAG_VEH_RUNNING ) ) ;
}
2009-11-17 22:58:41 +00:00
2023-12-29 19:11:59 +00:00
void UpdateWidgetSize ( WidgetID widget , Dimension * size , [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension * resize ) override
2009-09-26 19:21:20 +00:00
{
switch ( widget ) {
2011-12-16 16:57:56 +00:00
case WID_D_MATRIX : {
2009-11-17 22:58:41 +00:00
uint min_height = 0 ;
if ( this - > type = = VEH_TRAIN ) {
2013-06-01 14:33:48 +00:00
SetDParamMaxValue ( 0 , 1000 , 0 , FS_SMALL ) ;
2011-04-09 20:27:34 +00:00
SetDParam ( 1 , 1 ) ;
2023-04-25 08:49:44 +00:00
this - > count_width = GetStringBoundingBox ( STR_JUST_DECIMAL , FS_SMALL ) . width + WidgetDimensions : : scaled . hsep_normal ;
2009-11-18 10:45:49 +00:00
} else {
this - > count_width = 0 ;
2009-11-17 22:58:41 +00:00
}
2014-10-14 11:40:38 +00:00
SetDParamMaxDigits ( 0 , this - > unitnumber_digits ) ;
2023-04-25 08:45:05 +00:00
Dimension unumber = GetStringBoundingBox ( STR_JUST_COMMA ) ;
2009-11-17 22:58:41 +00:00
if ( this - > type = = VEH_TRAIN | | this - > type = = VEH_ROAD ) {
2022-11-23 21:01:09 +00:00
min_height = std : : max < uint > ( unumber . height , this - > flag_size . height ) ;
this - > header_width = unumber . width + WidgetDimensions : : scaled . hsep_normal + this - > flag_size . width + WidgetDimensions : : scaled . hsep_normal ;
2009-11-17 22:58:41 +00:00
} else {
2022-11-23 21:01:09 +00:00
min_height = unumber . height + WidgetDimensions : : scaled . vsep_normal + this - > flag_size . height ;
this - > header_width = std : : max < uint > ( unumber . width , this - > flag_size . width ) + WidgetDimensions : : scaled . hsep_normal ;
2009-11-17 22:58:41 +00:00
}
2022-11-23 21:01:09 +00:00
int base_width = this - > count_width + this - > header_width + padding . width ;
2009-11-17 22:58:41 +00:00
2022-11-23 21:01:09 +00:00
resize - > height = std : : max < uint > ( this - > cell_size . height , min_height + padding . height ) ;
2009-11-17 22:58:41 +00:00
if ( this - > type = = VEH_TRAIN ) {
resize - > width = 1 ;
2022-09-05 20:05:18 +00:00
size - > width = base_width + 2 * ScaleSpriteTrad ( 29 ) ; // about 2 parts
2009-11-17 23:32:18 +00:00
size - > height = resize - > height * 6 ;
2009-11-17 22:58:41 +00:00
} else {
2022-11-23 21:01:09 +00:00
resize - > width = base_width + this - > cell_size . extend_left + this - > cell_size . extend_right ;
2009-11-17 22:58:41 +00:00
size - > width = resize - > width * ( this - > type = = VEH_ROAD ? 5 : 3 ) ;
size - > height = resize - > height * ( this - > type = = VEH_ROAD ? 5 : 3 ) ;
}
2009-11-22 18:29:52 +00:00
fill - > width = resize - > width ;
fill - > height = resize - > height ;
2010-08-01 18:53:30 +00:00
break ;
}
2009-09-26 19:21:20 +00:00
}
2008-05-13 13:39:50 +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 .
*/
2023-09-16 20:20:53 +00:00
void OnInvalidateData ( [[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true ) override
2008-05-13 13:39:50 +00:00
{
this - > generate_list = true ;
}
2006-09-26 16:47:51 +00:00
2019-03-04 07:49:37 +00:00
void OnPaint ( ) override
2008-05-13 13:39:50 +00:00
{
if ( this - > generate_list ) {
/* Generate the vehicle list
* It ' s ok to use the wagon pointers for non - trains as they will be ignored */
2008-05-25 17:22:49 +00:00
BuildDepotVehicleList ( this - > type , this - > window_number , & this - > vehicle_list , & this - > wagon_list ) ;
2008-05-13 13:39:50 +00:00
this - > generate_list = false ;
2008-05-25 17:22:49 +00:00
DepotSortList ( & this - > vehicle_list ) ;
2014-10-14 11:40:38 +00:00
uint new_unitnumber_digits = GetUnitNumberDigits ( this - > vehicle_list ) ;
2016-05-29 12:21:40 +00:00
/* Only increase the size; do not decrease to prevent constant changes */
if ( this - > unitnumber_digits < new_unitnumber_digits ) {
2014-10-14 11:40:38 +00:00
this - > unitnumber_digits = new_unitnumber_digits ;
this - > ReInit ( ) ;
}
2008-05-13 13:39:50 +00:00
}
2009-09-26 19:21:20 +00:00
/* determine amount of items for scroller */
if ( this - > type = = VEH_TRAIN ) {
2022-09-05 20:05:18 +00:00
uint max_width = ScaleSpriteTrad ( VEHICLEINFO_FULL_VEHICLE_WIDTH ) ;
2018-09-23 11:23:54 +00:00
for ( uint num = 0 ; num < this - > vehicle_list . size ( ) ; num + + ) {
2009-09-26 19:21:20 +00:00
uint width = 0 ;
2019-04-10 21:07:06 +00:00
for ( const Train * v = Train : : From ( this - > vehicle_list [ num ] ) ; v ! = nullptr ; v = v - > Next ( ) ) {
2009-09-26 19:21:20 +00:00
width + = v - > GetDisplayImageWidth ( ) ;
}
2021-01-08 10:16:18 +00:00
max_width = std : : max ( max_width , width ) ;
2009-09-26 19:21:20 +00:00
}
/* Always have 1 empty row, so people can change the setting of the train */
2023-05-07 15:10:56 +00:00
this - > vscroll - > SetCount ( this - > vehicle_list . size ( ) + this - > wagon_list . size ( ) + 1 ) ;
2017-12-10 13:48:06 +00:00
/* Always make it longer than the longest train, so you can attach vehicles at the end, and also see the next vertical tile separator line */
2022-09-05 20:05:18 +00:00
this - > hscroll - > SetCount ( max_width + ScaleSpriteTrad ( 2 * VEHICLEINFO_FULL_VEHICLE_WIDTH + 1 ) ) ;
2009-09-26 19:21:20 +00:00
} else {
2019-03-27 23:09:33 +00:00
this - > vscroll - > SetCount ( CeilDiv ( ( uint ) this - > vehicle_list . size ( ) , this - > num_columns ) ) ;
2009-09-26 19:21:20 +00:00
}
2009-10-11 08:23:30 +00:00
/* Setup disabled buttons. */
TileIndex tile = this - > window_number ;
this - > SetWidgetsDisabledState ( ! IsTileOwner ( tile , _local_company ) ,
2011-12-16 16:57:56 +00:00
WID_D_STOP_ALL ,
WID_D_START_ALL ,
WID_D_SELL ,
WID_D_SELL_CHAIN ,
WID_D_SELL_ALL ,
WID_D_BUILD ,
WID_D_CLONE ,
WID_D_RENAME ,
2023-09-16 19:56:09 +00:00
WID_D_AUTOREPLACE ) ;
2009-10-11 08:23:30 +00:00
2009-09-26 19:21:20 +00:00
this - > DrawWidgets ( ) ;
2008-05-13 13:39:50 +00:00
}
2023-12-29 19:11:59 +00:00
void OnClick ( [[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count ) override
2008-05-13 13:39:50 +00:00
{
switch ( widget ) {
2023-05-13 22:18:36 +00:00
case WID_D_MATRIX : // List
this - > DepotClick ( pt . x , pt . y ) ;
2008-05-13 13:39:50 +00:00
break ;
2011-12-16 16:57:56 +00:00
case WID_D_BUILD : // Build vehicle
2008-05-13 13:39:50 +00:00
ResetObjectToPlace ( ) ;
ShowBuildVehicleWindow ( this - > window_number , this - > type ) ;
break ;
2011-12-16 16:57:56 +00:00
case WID_D_CLONE : // Clone button
this - > SetWidgetDirty ( WID_D_CLONE ) ;
this - > ToggleWidgetLoweredState ( WID_D_CLONE ) ;
2008-05-13 13:39:50 +00:00
2011-12-16 16:57:56 +00:00
if ( this - > IsWidgetLowered ( WID_D_CLONE ) ) {
2008-05-13 13:39:50 +00:00
static const CursorID clone_icons [ ] = {
SPR_CURSOR_CLONE_TRAIN , SPR_CURSOR_CLONE_ROADVEH ,
SPR_CURSOR_CLONE_SHIP , SPR_CURSOR_CLONE_AIRPLANE
} ;
2010-09-06 14:14:09 +00:00
SetObjectToPlaceWnd ( clone_icons [ this - > type ] , PAL_NONE , HT_VEHICLE , this ) ;
2008-05-13 13:39:50 +00:00
} else {
ResetObjectToPlace ( ) ;
}
2010-08-01 18:53:30 +00:00
break ;
2008-05-13 13:39:50 +00:00
2011-12-16 16:57:56 +00:00
case WID_D_LOCATION :
2008-05-13 13:39:50 +00:00
if ( _ctrl_pressed ) {
2020-06-29 01:38:29 +00:00
ShowExtraViewportWindow ( this - > window_number ) ;
2008-05-13 13:39:50 +00:00
} else {
ScrollMainWindowToTile ( this - > window_number ) ;
}
break ;
2011-12-16 16:57:56 +00:00
case WID_D_RENAME : // Rename button
2010-05-12 20:50:10 +00:00
SetDParam ( 0 , this - > type ) ;
SetDParam ( 1 , Depot : : GetByTile ( ( TileIndex ) this - > window_number ) - > index ) ;
2011-04-17 18:42:17 +00:00
ShowQueryString ( STR_DEPOT_NAME , STR_DEPOT_RENAME_DEPOT_CAPTION , MAX_LENGTH_DEPOT_NAME_CHARS , this , CS_ALPHANUMERAL , QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS ) ;
2010-05-12 20:50:10 +00:00
break ;
2011-12-16 16:57:56 +00:00
case WID_D_STOP_ALL :
case WID_D_START_ALL : {
2010-09-12 16:54:39 +00:00
VehicleListIdentifier vli ( VL_DEPOT_LIST , this - > type , this - > owner ) ;
2021-11-05 22:55:23 +00:00
Command < CMD_MASS_START_STOP > : : Post ( this - > window_number , widget = = WID_D_START_ALL , false , vli ) ;
2008-05-13 13:39:50 +00:00
break ;
2010-09-12 16:54:39 +00:00
}
2008-05-13 13:39:50 +00:00
2011-12-16 16:57:56 +00:00
case WID_D_SELL_ALL :
2013-01-08 22:46:42 +00:00
/* Only open the confirmation window if there are anything to sell */
2023-10-20 18:22:49 +00:00
if ( ! this - > vehicle_list . empty ( ) | | ! this - > wagon_list . empty ( ) ) {
2021-02-22 13:50:32 +00:00
SetDParam ( 0 , this - > type ) ;
SetDParam ( 1 , this - > GetDepotIndex ( ) ) ;
2008-05-13 13:39:50 +00:00
ShowQuery (
2010-05-12 18:19:36 +00:00
STR_DEPOT_CAPTION ,
2008-05-13 13:39:50 +00:00
STR_DEPOT_SELL_CONFIRMATION_TEXT ,
this ,
DepotSellAllConfirmationCallback
) ;
}
break ;
2011-12-16 16:57:56 +00:00
case WID_D_VEHICLE_LIST :
2008-05-13 13:39:50 +00:00
ShowVehicleListWindow ( GetTileOwner ( this - > window_number ) , this - > type , ( TileIndex ) this - > window_number ) ;
break ;
2011-12-16 16:57:56 +00:00
case WID_D_AUTOREPLACE :
2021-11-05 22:55:23 +00:00
Command < CMD_DEPOT_MASS_AUTOREPLACE > : : Post ( this - > window_number , this - > type ) ;
2008-05-13 13:39:50 +00:00
break ;
}
}
2019-03-04 07:49:37 +00:00
void OnQueryTextFinished ( char * str ) override
2010-05-12 20:50:10 +00:00
{
2019-04-10 21:07:06 +00:00
if ( str = = nullptr ) return ;
2010-05-12 20:50:10 +00:00
/* Do depot renaming */
2021-11-14 15:39:17 +00:00
Command < CMD_RENAME_DEPOT > : : Post ( STR_ERROR_CAN_T_RENAME_DEPOT , this - > GetDepotIndex ( ) , str ) ;
2010-05-12 20:50:10 +00:00
}
2023-12-29 19:11:59 +00:00
bool OnRightClick ( [[maybe_unused]] Point pt , WidgetID widget ) override
2008-08-02 12:43:45 +00:00
{
2011-12-16 16:57:56 +00:00
if ( widget ! = WID_D_MATRIX ) return false ;
2008-08-02 12:43:45 +00:00
2019-04-10 21:07:06 +00:00
GetDepotVehiclePtData gdvp = { nullptr , nullptr } ;
const Vehicle * v = nullptr ;
2023-05-13 22:18:36 +00:00
DepotGUIAction mode = this - > GetVehicleFromDepotWndPt ( pt . x , pt . y , & v , & gdvp ) ;
2008-08-02 12:43:45 +00:00
if ( this - > type = = VEH_TRAIN ) v = gdvp . wagon ;
2019-04-10 21:07:06 +00:00
if ( v = = nullptr | | mode ! = MODE_DRAG_VEHICLE ) return false ;
2008-08-02 12:43:45 +00:00
2023-05-23 11:23:50 +00:00
CargoArray capacity { } , loaded { } ;
2008-08-02 12:43:45 +00:00
2010-07-14 17:36:27 +00:00
/* Display info for single (articulated) vehicle, or for whole chain starting with selected vehicle */
bool whole_chain = ( this - > type = = VEH_TRAIN & & _ctrl_pressed ) ;
2008-08-02 12:43:45 +00:00
2011-12-15 21:56:00 +00:00
/* loop through vehicle chain and collect cargoes */
2010-07-14 17:36:27 +00:00
uint num = 0 ;
2019-04-10 21:07:06 +00:00
for ( const Vehicle * w = v ; w ! = nullptr ; w = w - > Next ( ) ) {
2010-07-14 17:36:27 +00:00
if ( w - > cargo_cap > 0 & & w - > cargo_type < NUM_CARGO ) {
capacity [ w - > cargo_type ] + = w - > cargo_cap ;
2013-04-13 13:42:08 +00:00
loaded [ w - > cargo_type ] + = w - > cargo . StoredCount ( ) ;
2008-08-02 12:43:45 +00:00
}
2011-01-29 17:30:25 +00:00
if ( w - > type = = VEH_TRAIN & & ! w - > HasArticulatedPart ( ) ) {
2010-07-14 17:36:27 +00:00
num + + ;
if ( ! whole_chain ) break ;
}
}
2008-08-02 12:43:45 +00:00
2010-07-14 17:36:27 +00:00
/* Build tooltipstring */
2023-06-04 17:28:18 +00:00
static std : : string details ;
details . clear ( ) ;
2008-08-02 12:43:45 +00:00
2023-10-20 16:32:17 +00:00
for ( const CargoSpec * cs : _sorted_cargo_specs ) {
CargoID cargo_type = cs - > Index ( ) ;
2010-07-14 17:36:27 +00:00
if ( capacity [ cargo_type ] = = 0 ) continue ;
2008-08-02 12:43:45 +00:00
2010-07-14 17:36:27 +00:00
SetDParam ( 0 , cargo_type ) ; // {CARGO} #1
SetDParam ( 1 , loaded [ cargo_type ] ) ; // {CARGO} #2
SetDParam ( 2 , cargo_type ) ; // {SHORTCARGO} #1
SetDParam ( 3 , capacity [ cargo_type ] ) ; // {SHORTCARGO} #2
2023-06-04 17:28:18 +00:00
details + = GetString ( STR_DEPOT_VEHICLE_TOOLTIP_CARGO ) ;
2008-08-02 12:43:45 +00:00
}
2010-07-14 17:36:27 +00:00
/* Show tooltip window */
2023-06-17 06:46:59 +00:00
SetDParam ( 0 , whole_chain ? num : v - > engine_type ) ;
SetDParamStr ( 1 , details ) ;
GuiShowTooltips ( this , whole_chain ? STR_DEPOT_VEHICLE_TOOLTIP_CHAIN : STR_DEPOT_VEHICLE_TOOLTIP , TCC_RIGHT_CLICK , 2 ) ;
2010-07-14 17:36:27 +00:00
return true ;
2008-08-02 12:43:45 +00:00
}
2010-09-06 14:14:09 +00:00
/**
* Clones a vehicle
* @ param v the original vehicle to clone
2011-12-10 19:20:30 +00:00
* @ return Always true .
2010-09-06 14:14:09 +00:00
*/
2019-03-04 07:49:37 +00:00
bool OnVehicleSelect ( const Vehicle * v ) override
2008-05-13 13:39:50 +00:00
{
2018-10-31 11:51:10 +00:00
if ( _ctrl_pressed ) {
/* Share-clone, do not open new viewport, and keep tool active */
2021-11-05 22:55:23 +00:00
Command < CMD_CLONE_VEHICLE > : : Post ( STR_ERROR_CAN_T_BUY_TRAIN + v - > type , this - > window_number , v - > index , true ) ;
2018-10-31 11:51:10 +00:00
} else {
2021-10-31 18:39:09 +00:00
/* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to change things on new vehicle) */
2021-11-05 22:55:23 +00:00
if ( Command < CMD_CLONE_VEHICLE > : : Post ( STR_ERROR_CAN_T_BUY_TRAIN + v - > type , CcCloneVehicle , this - > window_number , v - > index , false ) ) {
2018-10-31 11:51:10 +00:00
ResetObjectToPlace ( ) ;
}
2010-09-06 14:14:09 +00:00
}
2018-10-31 11:51:10 +00:00
2011-12-10 19:20:30 +00:00
return true ;
2008-05-13 13:39:50 +00:00
}
2022-11-26 17:03:21 +00:00
/**
* Clones a vehicle from a vehicle list . If this doesn ' t make sense ( because not all vehicles in the list have the same orders ) , then it displays an error .
* @ return This always returns true , which indicates that the contextual action handled the mouse click .
* Note that it ' s correct behaviour to always handle the click even though an error is displayed ,
* because users aren ' t going to expect the default action to be performed just because they overlooked that cloning doesn ' t make sense .
*/
bool OnVehicleSelect ( VehicleList : : const_iterator begin , VehicleList : : const_iterator end ) override
{
if ( ! _ctrl_pressed ) {
/* If CTRL is not pressed: If all the vehicles in this list have the same orders, then copy orders */
if ( AllEqual ( begin , end , [ ] ( const Vehicle * v1 , const Vehicle * v2 ) {
return VehiclesHaveSameEngineList ( v1 , v2 ) ;
} ) ) {
if ( AllEqual ( begin , end , [ ] ( const Vehicle * v1 , const Vehicle * v2 ) {
return VehiclesHaveSameOrderList ( v1 , v2 ) ;
} ) ) {
OnVehicleSelect ( * begin ) ;
} else {
ShowErrorMessage ( STR_ERROR_CAN_T_BUY_TRAIN + ( * begin ) - > type , STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST , WL_INFO ) ;
}
} else {
ShowErrorMessage ( STR_ERROR_CAN_T_BUY_TRAIN + ( * begin ) - > type , STR_ERROR_CAN_T_CLONE_VEHICLE_LIST , WL_INFO ) ;
}
} else {
/* If CTRL is pressed: If all the vehicles in this list share orders, then copy orders */
if ( AllEqual ( begin , end , [ ] ( const Vehicle * v1 , const Vehicle * v2 ) {
return VehiclesHaveSameEngineList ( v1 , v2 ) ;
} ) ) {
if ( AllEqual ( begin , end , [ ] ( const Vehicle * v1 , const Vehicle * v2 ) {
return v1 - > FirstShared ( ) = = v2 - > FirstShared ( ) ;
} ) ) {
OnVehicleSelect ( * begin ) ;
} else {
ShowErrorMessage ( STR_ERROR_CAN_T_BUY_TRAIN + ( * begin ) - > type , STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST , WL_INFO ) ;
}
} else {
ShowErrorMessage ( STR_ERROR_CAN_T_BUY_TRAIN + ( * begin ) - > type , STR_ERROR_CAN_T_CLONE_VEHICLE_LIST , WL_INFO ) ;
}
}
return true ;
}
2019-03-04 07:49:37 +00:00
void OnPlaceObjectAbort ( ) override
2008-05-13 13:39:50 +00:00
{
/* abort clone */
2011-12-16 16:57:56 +00:00
this - > RaiseWidget ( WID_D_CLONE ) ;
this - > SetWidgetDirty ( WID_D_CLONE ) ;
2008-05-13 13:39:50 +00:00
/* abort drag & drop */
this - > sel = INVALID_VEHICLE ;
2010-05-23 15:02:26 +00:00
this - > vehicle_over = INVALID_VEHICLE ;
2011-12-16 16:57:56 +00:00
this - > SetWidgetDirty ( WID_D_MATRIX ) ;
2015-11-14 22:54:52 +00:00
2015-11-20 09:25:27 +00:00
if ( this - > hovered_widget ! = - 1 ) {
this - > SetWidgetLoweredState ( this - > hovered_widget , false ) ;
this - > SetWidgetDirty ( this - > hovered_widget ) ;
this - > hovered_widget = - 1 ;
2015-11-14 22:54:52 +00:00
}
2011-01-15 15:36:58 +00:00
}
2008-05-13 13:39:50 +00:00
2023-12-29 19:11:59 +00:00
void OnMouseDrag ( Point pt , WidgetID widget ) override
2010-05-23 15:02:26 +00:00
{
2015-11-14 22:54:52 +00:00
if ( this - > sel = = INVALID_VEHICLE ) return ;
2015-11-20 09:25:27 +00:00
if ( widget ! = this - > hovered_widget ) {
if ( this - > hovered_widget = = WID_D_SELL | | this - > hovered_widget = = WID_D_SELL_CHAIN ) {
this - > SetWidgetLoweredState ( this - > hovered_widget , false ) ;
this - > SetWidgetDirty ( this - > hovered_widget ) ;
}
this - > hovered_widget = widget ;
if ( this - > hovered_widget = = WID_D_SELL | | this - > hovered_widget = = WID_D_SELL_CHAIN ) {
this - > SetWidgetLoweredState ( this - > hovered_widget , true ) ;
this - > SetWidgetDirty ( this - > hovered_widget ) ;
}
2015-11-14 22:54:52 +00:00
}
if ( this - > type ! = VEH_TRAIN ) return ;
2010-05-23 15:02:26 +00:00
/* A rail vehicle is dragged.. */
2011-12-16 16:57:56 +00:00
if ( widget ! = WID_D_MATRIX ) { // ..outside of the depot matrix.
2010-05-23 15:02:26 +00:00
if ( this - > vehicle_over ! = INVALID_VEHICLE ) {
this - > vehicle_over = INVALID_VEHICLE ;
2011-12-16 16:57:56 +00:00
this - > SetWidgetDirty ( WID_D_MATRIX ) ;
2010-05-23 15:02:26 +00:00
}
return ;
}
2019-04-10 21:07:06 +00:00
const Vehicle * v = nullptr ;
GetDepotVehiclePtData gdvp = { nullptr , nullptr } ;
2010-05-23 15:02:26 +00:00
2023-05-13 22:18:36 +00:00
if ( this - > GetVehicleFromDepotWndPt ( pt . x , pt . y , & v , & gdvp ) ! = MODE_DRAG_VEHICLE ) return ;
2010-05-23 15:02:26 +00:00
VehicleID new_vehicle_over = INVALID_VEHICLE ;
2019-04-10 21:07:06 +00:00
if ( gdvp . head ! = nullptr ) {
if ( gdvp . wagon = = nullptr & & gdvp . head - > Last ( ) - > index ! = this - > sel ) { // ..at the end of the train.
2010-05-23 15:02:26 +00:00
/* NOTE: As a wagon can't be moved at the begin of a train, head index isn't used to mark a drag-and-drop
* destination inside a train . This head index is then used to indicate that a wagon is inserted at
* the end of the train .
*/
new_vehicle_over = gdvp . head - > index ;
2019-04-10 21:07:06 +00:00
} else if ( gdvp . wagon ! = nullptr & & gdvp . head ! = gdvp . wagon & &
2010-05-23 15:02:26 +00:00
gdvp . wagon - > index ! = this - > sel & &
gdvp . wagon - > Previous ( ) - > index ! = this - > sel ) { // ..over an existing wagon.
new_vehicle_over = gdvp . wagon - > index ;
}
}
if ( this - > vehicle_over = = new_vehicle_over ) return ;
this - > vehicle_over = new_vehicle_over ;
this - > SetWidgetDirty ( widget ) ;
}
2023-12-29 19:11:59 +00:00
void OnDragDrop ( Point pt , WidgetID widget ) override
2008-05-13 13:39:50 +00:00
{
switch ( widget ) {
2011-12-16 16:57:56 +00:00
case WID_D_MATRIX : {
2019-04-10 21:07:06 +00:00
const Vehicle * v = nullptr ;
2008-05-13 13:39:50 +00:00
VehicleID sel = this - > sel ;
this - > sel = INVALID_VEHICLE ;
this - > SetDirty ( ) ;
if ( this - > type = = VEH_TRAIN ) {
2019-04-10 21:07:06 +00:00
GetDepotVehiclePtData gdvp = { nullptr , nullptr } ;
2008-05-13 13:39:50 +00:00
2023-05-13 22:18:36 +00:00
if ( this - > GetVehicleFromDepotWndPt ( pt . x , pt . y , & v , & gdvp ) = = MODE_DRAG_VEHICLE & & sel ! = INVALID_VEHICLE ) {
2019-04-10 21:07:06 +00:00
if ( gdvp . wagon ! = nullptr & & gdvp . wagon - > index = = sel & & _ctrl_pressed ) {
2021-11-05 22:55:23 +00:00
Command < CMD_REVERSE_TRAIN_DIRECTION > : : Post ( STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE , Vehicle : : Get ( sel ) - > tile , Vehicle : : Get ( sel ) - > index , true ) ;
2019-04-10 21:07:06 +00:00
} else if ( gdvp . wagon = = nullptr | | gdvp . wagon - > index ! = sel ) {
2010-05-23 15:02:26 +00:00
this - > vehicle_over = INVALID_VEHICLE ;
2008-05-13 13:39:50 +00:00
TrainDepotMoveVehicle ( gdvp . wagon , sel , gdvp . head ) ;
2019-04-10 21:07:06 +00:00
} else if ( gdvp . head ! = nullptr & & gdvp . head - > IsFrontEngine ( ) ) {
2008-05-13 13:39:50 +00:00
ShowVehicleViewWindow ( gdvp . head ) ;
2006-09-26 16:47:51 +00:00
}
2008-05-13 13:39:50 +00:00
}
2023-05-13 22:18:36 +00:00
} else if ( this - > GetVehicleFromDepotWndPt ( pt . x , pt . y , & v , nullptr ) = = MODE_DRAG_VEHICLE & & v ! = nullptr & & sel = = v - > index ) {
2008-05-13 13:39:50 +00:00
ShowVehicleViewWindow ( v ) ;
}
2010-08-01 18:53:30 +00:00
break ;
}
2008-05-13 13:39:50 +00:00
2011-12-16 16:57:56 +00:00
case WID_D_SELL : case WID_D_SELL_CHAIN : {
2009-09-26 19:26:08 +00:00
if ( this - > IsWidgetDisabled ( widget ) ) return ;
if ( this - > sel = = INVALID_VEHICLE ) return ;
2008-05-13 13:39:50 +00:00
2009-09-26 19:26:08 +00:00
this - > HandleButtonClick ( widget ) ;
2006-09-26 16:47:51 +00:00
2009-09-26 19:26:08 +00:00
const Vehicle * v = Vehicle : : Get ( this - > sel ) ;
this - > sel = INVALID_VEHICLE ;
this - > SetDirty ( ) ;
2008-05-13 13:39:50 +00:00
2021-11-02 20:34:39 +00:00
bool sell_cmd = ( v - > type = = VEH_TRAIN & & ( widget = = WID_D_SELL_CHAIN | | _ctrl_pressed ) ) ;
Command < CMD_SELL_VEHICLE > : : Post ( GetCmdSellVehMsg ( v - > type ) , v - > tile , v - > index , sell_cmd , true , INVALID_CLIENT_ID ) ;
2010-08-01 18:53:30 +00:00
break ;
}
2006-09-26 16:47:51 +00:00
2008-05-13 13:39:50 +00:00
default :
this - > sel = INVALID_VEHICLE ;
this - > SetDirty ( ) ;
2015-11-14 22:54:52 +00:00
break ;
2008-05-13 13:39:50 +00:00
}
2015-11-20 09:25:27 +00:00
this - > hovered_widget = - 1 ;
2008-05-13 13:39:50 +00:00
_cursor . vehchain = false ;
}
2019-03-04 07:49:37 +00:00
void OnTimeout ( ) override
2009-08-15 20:59:49 +00:00
{
2011-12-16 16:57:56 +00:00
if ( ! this - > IsWidgetDisabled ( WID_D_SELL ) ) {
this - > RaiseWidget ( WID_D_SELL ) ;
this - > SetWidgetDirty ( WID_D_SELL ) ;
2009-08-15 20:59:49 +00:00
}
2021-04-29 19:04:50 +00:00
if ( this - > GetWidget < NWidgetBase > ( WID_D_SELL ) ! = nullptr & & ! this - > IsWidgetDisabled ( WID_D_SELL_CHAIN ) ) {
2011-12-16 16:57:56 +00:00
this - > RaiseWidget ( WID_D_SELL_CHAIN ) ;
this - > SetWidgetDirty ( WID_D_SELL_CHAIN ) ;
2009-08-15 20:59:49 +00:00
}
}
2019-03-04 07:49:37 +00:00
void OnResize ( ) override
2008-05-13 13:39:50 +00:00
{
2011-12-16 16:57:56 +00:00
this - > vscroll - > SetCapacityFromWidget ( this , WID_D_MATRIX ) ;
2013-07-01 17:15:30 +00:00
NWidgetCore * nwi = this - > GetWidget < NWidgetCore > ( WID_D_MATRIX ) ;
2009-11-17 16:03:51 +00:00
if ( this - > type = = VEH_TRAIN ) {
2010-08-12 08:37:01 +00:00
this - > hscroll - > SetCapacity ( nwi - > current_x - this - > header_width - this - > count_width ) ;
2013-07-01 17:15:30 +00:00
} else {
this - > num_columns = nwi - > current_x / nwi - > resize_x ;
2009-11-17 16:03:51 +00:00
}
2008-05-13 13:39:50 +00:00
}
2019-03-04 07:49:37 +00:00
EventState OnCTRLStateChange ( ) override
2008-05-13 13:39:50 +00:00
{
if ( this - > sel ! = INVALID_VEHICLE ) {
_cursor . vehchain = _ctrl_pressed ;
2011-12-16 16:57:56 +00:00
this - > SetWidgetDirty ( WID_D_MATRIX ) ;
2008-08-16 18:01:23 +00:00
return ES_HANDLED ;
2008-05-13 13:39:50 +00:00
}
2008-08-16 18:01:23 +00:00
return ES_NOT_HANDLED ;
2008-05-13 13:39:50 +00:00
}
2021-02-22 13:50:32 +00:00
/**
* Gets the DepotID of the current window .
* In the case of airports , this is the station ID .
* @ return Depot or station ID of this window .
*/
2023-05-08 17:01:06 +00:00
inline uint16_t GetDepotIndex ( ) const
2021-02-22 13:50:32 +00:00
{
return ( this - > type = = VEH_AIRCRAFT ) ? : : GetStationIndex ( this - > window_number ) : : : GetDepotIndex ( this - > window_number ) ;
}
2008-05-13 13:39:50 +00:00
} ;
static void DepotSellAllConfirmationCallback ( Window * win , bool confirmed )
{
if ( confirmed ) {
DepotWindow * w = ( DepotWindow * ) win ;
TileIndex tile = w - > window_number ;
2021-11-05 22:55:23 +00:00
VehicleType vehtype = w - > type ;
Command < CMD_DEPOT_SELL_ALL_VEHICLES > : : Post ( tile , vehtype ) ;
2006-09-26 16:47:51 +00:00
}
}
2010-08-01 19:22:34 +00:00
/**
* Opens a depot window
2006-09-26 16:47:51 +00:00
* @ param tile The tile where the depot / hangar is located
* @ param type The type of vehicles in the depot
*/
2007-05-18 17:31:41 +00:00
void ShowDepotWindow ( TileIndex tile , VehicleType type )
2006-09-26 16:47:51 +00:00
{
2019-04-10 21:07:06 +00:00
if ( BringWindowToFrontById ( WC_VEHICLE_DEPOT , tile ) ! = nullptr ) return ;
2006-09-26 16:47:51 +00:00
2013-05-26 19:23:42 +00:00
WindowDesc * desc ;
2006-09-26 16:47:51 +00:00
switch ( type ) {
2006-12-07 00:51:20 +00:00
default : NOT_REACHED ( ) ;
2008-12-28 20:53:19 +00:00
case VEH_TRAIN : desc = & _train_depot_desc ; break ;
case VEH_ROAD : desc = & _road_depot_desc ; break ;
case VEH_SHIP : desc = & _ship_depot_desc ; break ;
case VEH_AIRCRAFT : desc = & _aircraft_depot_desc ; break ;
2006-09-26 16:47:51 +00:00
}
2008-12-28 20:53:19 +00:00
new DepotWindow ( desc , tile , type ) ;
2006-09-26 16:47:51 +00:00
}
2006-12-05 22:40:42 +00:00
2010-08-01 19:22:34 +00:00
/**
* Removes the highlight of a vehicle in a depot window
2006-12-05 22:40:42 +00:00
* @ param * v Vehicle to remove all highlights from
*/
void DeleteDepotHighlightOfVehicle ( const Vehicle * v )
{
2008-05-13 13:39:50 +00:00
DepotWindow * w ;
2006-12-05 22:40:42 +00:00
2006-12-06 00:03:24 +00:00
/* If we haven't got any vehicles on the mouse pointer, we haven't got any highlighted in any depots either
2008-05-13 13:39:50 +00:00
* If that is the case , we can skip looping though the windows and save time
*/
2006-12-06 00:03:24 +00:00
if ( _special_mouse_mode ! = WSM_DRAGDROP ) return ;
2008-05-13 13:39:50 +00:00
w = dynamic_cast < DepotWindow * > ( FindWindowById ( WC_VEHICLE_DEPOT , v - > tile ) ) ;
2019-04-10 21:07:06 +00:00
if ( w ! = nullptr ) {
2009-01-08 21:13:20 +00:00
if ( w - > sel = = v - > index ) ResetObjectToPlace ( ) ;
2006-12-05 22:40:42 +00:00
}
}