2009-08-21 22:21:05 +02: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 17:11:33 +02:00
/** @file group_gui.cpp GUI for the group window. */
2007-05-19 11:40:18 +02:00
# include "stdafx.h"
2007-12-19 21:45:46 +01:00
# include "textbuf_gui.h"
2007-12-21 22:50:46 +01:00
# include "command_func.h"
2007-05-19 11:40:18 +02:00
# include "vehicle_gui.h"
2009-01-31 21:16:06 +01:00
# include "vehicle_base.h"
2011-04-30 16:24:23 +02:00
# include "string_func.h"
2007-12-21 20:49:27 +01:00
# include "strings_func.h"
2007-12-25 12:26:07 +01:00
# include "window_func.h"
2007-12-27 14:35:39 +01:00
# include "vehicle_func.h"
2008-01-07 10:19:53 +01:00
# include "autoreplace_gui.h"
2008-09-30 22:51:04 +02:00
# include "company_func.h"
2008-01-14 17:10:58 +01:00
# include "widgets/dropdown_func.h"
2008-05-07 15:10:15 +02:00
# include "tilehighlight_func.h"
2009-11-17 10:09:20 +01:00
# include "vehicle_gui_base.h"
2010-01-15 17:41:15 +01:00
# include "core/geometry_func.hpp"
# include "company_base.h"
2019-01-31 14:57:44 +01:00
# include "company_gui.h"
2007-05-19 11:40:18 +02:00
2011-12-15 23:22:55 +01:00
# include "widgets/group_widget.h"
2008-01-13 02:21:35 +01:00
# include "table/sprites.h"
2007-05-19 11:40:18 +02:00
2014-04-23 22:13:33 +02:00
# include "safeguards.h"
2014-04-08 23:09:06 +02:00
static const int LEVEL_WIDTH = 10 ; ///< Indenting width of a sub-group in pixels
2008-05-11 16:23:45 +02:00
typedef GUIList < const Group * > GUIGroupList ;
2008-03-28 17:34:50 +01:00
2009-03-22 22:16:57 +01:00
static const NWidgetPart _nested_group_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) , // Window header
2009-11-24 19:05:55 +01:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
2011-12-16 17:32:48 +01:00
NWidget ( WWT_CAPTION , COLOUR_GREY , WID_GL_CAPTION ) ,
2009-12-21 17:24:29 +01:00
NWidget ( WWT_SHADEBOX , COLOUR_GREY ) ,
2013-05-26 21:30:07 +02:00
NWidget ( WWT_DEFSIZEBOX , COLOUR_GREY ) ,
2009-11-24 19:05:55 +01:00
NWidget ( WWT_STICKYBOX , COLOUR_GREY ) ,
2009-03-22 22:16:57 +01:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
/* left part */
NWidget ( NWID_VERTICAL ) ,
2009-11-24 22:13:36 +01:00
NWidget ( WWT_PANEL , COLOUR_GREY ) , SetMinimalTextLines ( 1 , WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM ) , SetFill ( 1 , 0 ) , EndContainer ( ) ,
2011-12-16 17:32:48 +01:00
NWidget ( WWT_PANEL , COLOUR_GREY , WID_GL_ALL_VEHICLES ) , SetFill ( 1 , 0 ) , EndContainer ( ) ,
NWidget ( WWT_PANEL , COLOUR_GREY , WID_GL_DEFAULT_VEHICLES ) , SetFill ( 1 , 0 ) , EndContainer ( ) ,
2009-03-22 22:16:57 +01:00
NWidget ( NWID_HORIZONTAL ) ,
2013-06-30 16:36:31 +02:00
NWidget ( WWT_MATRIX , COLOUR_GREY , WID_GL_LIST_GROUP ) , SetMatrixDataTip ( 1 , 0 , STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP ) ,
2011-12-16 17:32:48 +01:00
SetFill ( 1 , 0 ) , SetResize ( 0 , 1 ) , SetScrollbar ( WID_GL_LIST_GROUP_SCROLLBAR ) ,
NWidget ( NWID_VSCROLLBAR , COLOUR_GREY , WID_GL_LIST_GROUP_SCROLLBAR ) ,
2009-03-22 22:16:57 +01:00
EndContainer ( ) ,
2017-03-24 08:33:31 +01:00
NWidget ( WWT_PANEL , COLOUR_GREY , WID_GL_INFO ) , SetFill ( 1 , 0 ) , EndContainer ( ) ,
2009-03-22 22:16:57 +01:00
NWidget ( NWID_HORIZONTAL ) ,
2012-09-22 21:15:16 +02:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_GL_CREATE_GROUP ) , SetFill ( 0 , 1 ) ,
2009-11-13 22:42:49 +01:00
SetDataTip ( SPR_GROUP_CREATE_TRAIN , STR_GROUP_CREATE_TOOLTIP ) ,
2012-09-22 21:15:16 +02:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_GL_DELETE_GROUP ) , SetFill ( 0 , 1 ) ,
2009-11-13 22:42:49 +01:00
SetDataTip ( SPR_GROUP_DELETE_TRAIN , STR_GROUP_DELETE_TOOLTIP ) ,
2012-09-22 21:15:16 +02:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_GL_RENAME_GROUP ) , SetFill ( 0 , 1 ) ,
2009-11-13 22:42:49 +01:00
SetDataTip ( SPR_GROUP_RENAME_TRAIN , STR_GROUP_RENAME_TOOLTIP ) ,
2019-01-31 14:57:44 +01:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_GL_LIVERY_GROUP ) , SetFill ( 0 , 1 ) ,
SetDataTip ( SPR_GROUP_LIVERY_TRAIN , STR_GROUP_LIVERY_TOOLTIP ) ,
2011-10-03 19:25:03 +02:00
NWidget ( WWT_PANEL , COLOUR_GREY ) , SetFill ( 1 , 1 ) , EndContainer ( ) ,
2012-09-22 21:15:16 +02:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_GL_REPLACE_PROTECTION ) , SetFill ( 0 , 1 ) ,
2009-11-13 22:42:49 +01:00
SetDataTip ( SPR_GROUP_REPLACE_OFF_TRAIN , STR_GROUP_REPLACE_PROTECTION_TOOLTIP ) ,
2009-03-22 22:16:57 +01:00
EndContainer ( ) ,
EndContainer ( ) ,
/* right part */
NWidget ( NWID_VERTICAL ) ,
2019-01-11 09:50:38 +01:00
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , WID_GL_GROUP_BY_ORDER ) , SetMinimalSize ( 81 , 12 ) , SetDataTip ( STR_STATION_VIEW_GROUP , STR_TOOLTIP_GROUP_ORDER ) ,
NWidget ( WWT_DROPDOWN , COLOUR_GREY , WID_GL_GROUP_BY_DROPDOWN ) , SetMinimalSize ( 167 , 12 ) , SetDataTip ( 0x0 , STR_TOOLTIP_GROUP_ORDER ) ,
NWidget ( WWT_PANEL , COLOUR_GREY ) , SetMinimalSize ( 12 , 12 ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
EndContainer ( ) ,
2009-03-22 22:16:57 +01:00
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 17:32:48 +01:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_GL_SORT_BY_ORDER ) , SetMinimalSize ( 81 , 12 ) , SetDataTip ( STR_BUTTON_SORT_BY , STR_TOOLTIP_SORT_ORDER ) ,
NWidget ( WWT_DROPDOWN , COLOUR_GREY , WID_GL_SORT_BY_DROPDOWN ) , SetMinimalSize ( 167 , 12 ) , SetDataTip ( 0x0 , STR_TOOLTIP_SORT_CRITERIA ) ,
2009-11-24 22:13:36 +01:00
NWidget ( WWT_PANEL , COLOUR_GREY ) , SetMinimalSize ( 12 , 12 ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
2009-03-22 22:16:57 +01:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2013-06-30 16:36:31 +02:00
NWidget ( WWT_MATRIX , COLOUR_GREY , WID_GL_LIST_VEHICLE ) , SetMinimalSize ( 248 , 0 ) , SetMatrixDataTip ( 1 , 0 , STR_NULL ) , SetResize ( 1 , 1 ) , SetFill ( 1 , 0 ) , SetScrollbar ( WID_GL_LIST_VEHICLE_SCROLLBAR ) ,
2011-12-16 17:32:48 +01:00
NWidget ( NWID_VSCROLLBAR , COLOUR_GREY , WID_GL_LIST_VEHICLE_SCROLLBAR ) ,
2009-03-22 22:16:57 +01:00
EndContainer ( ) ,
2010-09-25 19:46:54 +02:00
NWidget ( WWT_PANEL , COLOUR_GREY ) , SetMinimalSize ( 1 , 0 ) , SetFill ( 1 , 1 ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
2009-03-22 22:16:57 +01:00
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 17:32:48 +01:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_GL_AVAILABLE_VEHICLES ) , SetMinimalSize ( 106 , 12 ) , SetFill ( 0 , 1 ) ,
2010-07-30 14:26:58 +02:00
SetDataTip ( STR_BLACK_STRING , STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP ) ,
2012-09-22 21:12:22 +02:00
NWidget ( WWT_PANEL , COLOUR_GREY ) , SetMinimalSize ( 0 , 12 ) , SetFill ( 1 , 1 ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
2011-12-16 17:32:48 +01:00
NWidget ( WWT_DROPDOWN , COLOUR_GREY , WID_GL_MANAGE_VEHICLES_DROPDOWN ) , SetMinimalSize ( 118 , 12 ) , SetFill ( 0 , 1 ) ,
2009-11-13 22:42:49 +01:00
SetDataTip ( STR_VEHICLE_LIST_MANAGE_LIST , STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP ) ,
2011-12-16 17:32:48 +01:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_GL_STOP_ALL ) , SetMinimalSize ( 12 , 12 ) , SetFill ( 0 , 1 ) ,
2009-11-13 22:42:49 +01:00
SetDataTip ( SPR_FLAG_VEH_STOPPED , STR_VEHICLE_LIST_MASS_STOP_LIST_TOOLTIP ) ,
2011-12-16 17:32:48 +01:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_GL_START_ALL ) , SetMinimalSize ( 12 , 12 ) , SetFill ( 0 , 1 ) ,
2009-11-13 22:42:49 +01:00
SetDataTip ( SPR_FLAG_VEH_RUNNING , STR_VEHICLE_LIST_MASS_START_LIST_TOOLTIP ) ,
2009-11-24 19:05:55 +01:00
NWidget ( WWT_RESIZEBOX , COLOUR_GREY ) ,
2009-03-22 22:16:57 +01:00
EndContainer ( ) ,
EndContainer ( ) ,
EndContainer ( ) ,
} ;
2007-05-19 11:40:18 +02:00
2008-09-13 12:04:36 +02:00
class VehicleGroupWindow : public BaseVehicleListWindow {
2008-05-26 20:30:58 +02:00
private :
2011-10-03 19:25:03 +02:00
/* Columns in the group list */
enum ListColumns {
2019-03-26 01:35:01 +01:00
VGC_FOLD , ///< Fold / Unfold button.
2011-10-03 19:25:03 +02:00
VGC_NAME , ///< Group name.
2011-10-03 19:26:37 +02:00
VGC_PROTECT , ///< Autoreplace protect icon.
VGC_AUTOREPLACE , ///< Autoreplace active icon.
2011-10-03 19:25:44 +02:00
VGC_PROFIT , ///< Profit icon.
2011-10-03 19:25:03 +02:00
VGC_NUMBER , ///< Number of vehicles in the group.
VGC_END
} ;
2009-08-24 23:51:02 +02:00
VehicleID vehicle_sel ; ///< Selected vehicle
2014-04-08 23:09:06 +02:00
GroupID group_sel ; ///< Selected group (for drag/drop)
2009-08-24 23:51:02 +02:00
GroupID group_rename ; ///< Group being renamed, INVALID_GROUP if none
2012-04-17 21:43:09 +02:00
GroupID group_over ; ///< Group over which a vehicle is dragged, INVALID_GROUP if none
2014-04-11 20:14:44 +02:00
GroupID group_confirm ; ///< Group awaiting delete confirmation
2009-08-24 23:51:02 +02:00
GUIGroupList groups ; ///< List of groups
2009-11-16 22:28:12 +01:00
uint tiny_step_height ; ///< Step height for the group list
2010-08-12 10:42:37 +02:00
Scrollbar * group_sb ;
2007-05-19 11:40:18 +02:00
2019-03-03 18:30:09 +01:00
std : : vector < int > indents ; ///< Indentation levels
2014-04-08 23:09:06 +02:00
2011-10-03 19:25:03 +02:00
Dimension column_size [ VGC_END ] ; ///< Size of the columns in the group list.
2019-01-27 13:35:14 +01:00
void AddChildren ( GUIGroupList * source , GroupID parent , int indent )
2008-05-26 20:30:58 +02:00
{
2019-02-17 12:20:52 +01:00
for ( const Group * g : * source ) {
if ( g - > parent ! = parent ) continue ;
this - > groups . push_back ( g ) ;
2019-02-18 23:39:06 +01:00
this - > indents . push_back ( indent ) ;
2019-03-26 01:35:01 +01:00
if ( g - > folded ) {
/* Test if this group has children at all. If not, the folded flag should be cleared to avoid lingering unfold buttons in the list. */
auto child = std : : find_if ( source - > begin ( ) , source - > end ( ) , [ g ] ( const Group * child ) { return child - > parent = = g - > index ; } ) ;
bool has_children = child ! = source - > end ( ) ;
Group : : Get ( g - > index ) - > folded = has_children ;
} else {
AddChildren ( source , g - > index , indent + 1 ) ;
}
2008-05-26 20:30:58 +02:00
}
}
2014-04-08 23:09:06 +02:00
/**
* ( Re ) Build the group list .
*
* @ param owner The owner of the window
*/
void BuildGroupList ( Owner owner )
{
if ( ! this - > groups . NeedRebuild ( ) ) return ;
2018-09-21 00:44:14 +02:00
this - > groups . clear ( ) ;
this - > indents . clear ( ) ;
2014-04-08 23:09:06 +02:00
GUIGroupList list ;
2019-12-16 18:01:57 +01:00
for ( const Group * g : Group : : Iterate ( ) ) {
2014-04-08 23:09:06 +02:00
if ( g - > owner = = owner & & g - > vehicle_type = = this - > vli . vtype ) {
2019-02-18 23:39:06 +01:00
list . push_back ( g ) ;
2014-04-08 23:09:06 +02:00
}
}
list . ForceResort ( ) ;
2020-06-15 19:40:51 +02:00
/* Sort the groups by their name */
const Group * last_group [ 2 ] = { nullptr , nullptr } ;
char last_name [ 2 ] [ 64 ] = { " " , " " } ;
list . Sort ( [ & ] ( const Group * const & a , const Group * const & b ) {
if ( a ! = last_group [ 0 ] ) {
last_group [ 0 ] = a ;
SetDParam ( 0 , a - > index ) ;
GetString ( last_name [ 0 ] , STR_GROUP_NAME , lastof ( last_name [ 0 ] ) ) ;
}
if ( b ! = last_group [ 1 ] ) {
last_group [ 1 ] = b ;
SetDParam ( 0 , b - > index ) ;
GetString ( last_name [ 1 ] , STR_GROUP_NAME , lastof ( last_name [ 1 ] ) ) ;
}
int r = strnatcmp ( last_name [ 0 ] , last_name [ 1 ] ) ; // Sort by name (natural sorting).
if ( r = = 0 ) return a - > index < b - > index ;
return r < 0 ;
} ) ;
2014-04-08 23:09:06 +02:00
2019-01-27 13:35:14 +01:00
AddChildren ( & list , INVALID_GROUP , 0 ) ;
2014-04-08 23:09:06 +02:00
2018-09-21 23:45:44 +02:00
this - > groups . shrink_to_fit ( ) ;
2014-04-08 23:09:06 +02:00
this - > groups . RebuildDone ( ) ;
}
2011-10-03 19:25:03 +02:00
/**
* Compute tiny_step_height and column_size
* @ return Total width required for the group list .
*/
uint ComputeGroupInfoSize ( )
{
2019-03-26 01:35:01 +01:00
this - > column_size [ VGC_FOLD ] = maxdim ( GetSpriteSize ( SPR_CIRCLE_FOLDED ) , GetSpriteSize ( SPR_CIRCLE_UNFOLDED ) ) ;
this - > tiny_step_height = this - > column_size [ VGC_FOLD ] . height ;
2011-10-03 19:25:03 +02:00
this - > column_size [ VGC_NAME ] = maxdim ( GetStringBoundingBox ( STR_GROUP_DEFAULT_TRAINS + this - > vli . vtype ) , GetStringBoundingBox ( STR_GROUP_ALL_TRAINS + this - > vli . vtype ) ) ;
this - > column_size [ VGC_NAME ] . width = max ( 170u , this - > column_size [ VGC_NAME ] . width ) ;
2019-03-26 01:35:01 +01:00
this - > tiny_step_height = max ( this - > tiny_step_height , this - > column_size [ VGC_NAME ] . height ) ;
2011-10-03 19:25:03 +02:00
2011-10-03 19:26:37 +02:00
this - > column_size [ VGC_PROTECT ] = GetSpriteSize ( SPR_GROUP_REPLACE_PROTECT ) ;
this - > tiny_step_height = max ( this - > tiny_step_height , this - > column_size [ VGC_PROTECT ] . height ) ;
this - > column_size [ VGC_AUTOREPLACE ] = GetSpriteSize ( SPR_GROUP_REPLACE_ACTIVE ) ;
this - > tiny_step_height = max ( this - > tiny_step_height , this - > column_size [ VGC_AUTOREPLACE ] . height ) ;
2011-10-03 19:25:44 +02:00
this - > column_size [ VGC_PROFIT ] . width = 0 ;
this - > column_size [ VGC_PROFIT ] . height = 0 ;
static const SpriteID profit_sprites [ ] = { SPR_PROFIT_NA , SPR_PROFIT_NEGATIVE , SPR_PROFIT_SOME , SPR_PROFIT_LOT } ;
for ( uint i = 0 ; i < lengthof ( profit_sprites ) ; i + + ) {
Dimension d = GetSpriteSize ( profit_sprites [ i ] ) ;
this - > column_size [ VGC_PROFIT ] = maxdim ( this - > column_size [ VGC_PROFIT ] , d ) ;
}
this - > tiny_step_height = max ( this - > tiny_step_height , this - > column_size [ VGC_PROFIT ] . height ) ;
2019-03-26 01:07:20 +01:00
int num_vehicle = GetGroupNumVehicle ( this - > vli . company , ALL_GROUP , this - > vli . vtype ) ;
SetDParamMaxValue ( 0 , num_vehicle , 3 , FS_SMALL ) ;
SetDParamMaxValue ( 1 , num_vehicle , 3 , FS_SMALL ) ;
this - > column_size [ VGC_NUMBER ] = GetStringBoundingBox ( STR_GROUP_COUNT_WITH_SUBGROUP ) ;
2011-10-03 19:25:03 +02:00
this - > tiny_step_height = max ( this - > tiny_step_height , this - > column_size [ VGC_NUMBER ] . height ) ;
this - > tiny_step_height + = WD_MATRIX_TOP ;
return WD_FRAMERECT_LEFT + 8 +
2019-03-26 01:35:01 +01:00
this - > column_size [ VGC_FOLD ] . width + 2 +
2011-10-03 19:25:03 +02:00
this - > column_size [ VGC_NAME ] . width + 8 +
2011-10-03 19:26:37 +02:00
this - > column_size [ VGC_PROTECT ] . width + 2 +
this - > column_size [ VGC_AUTOREPLACE ] . width + 2 +
2011-10-03 19:25:44 +02:00
this - > column_size [ VGC_PROFIT ] . width + 2 +
2011-10-03 19:25:03 +02:00
this - > column_size [ VGC_NUMBER ] . width + 2 +
WD_FRAMERECT_RIGHT ;
}
/**
* Draw a row in the group list .
* @ param y Top of the row .
* @ param left Left of the row .
* @ param right Right of the row .
* @ param g_id Group to list .
2014-04-08 23:09:06 +02:00
* @ param indent Indentation level .
2011-10-03 19:26:37 +02:00
* @ param protection Whether autoreplace protection is set .
2019-03-26 01:35:01 +01:00
* @ param has_children Whether the group has children and should have a fold / unfold button .
2011-10-03 19:25:03 +02:00
*/
2019-03-26 01:35:01 +01:00
void DrawGroupInfo ( int y , int left , int right , GroupID g_id , int indent = 0 , bool protection = false , bool has_children = false ) const
2011-10-03 19:25:03 +02:00
{
2012-10-14 21:15:00 +02:00
/* Highlight the group if a vehicle is dragged over it */
if ( g_id = = this - > group_over ) {
2012-04-17 21:43:09 +02:00
GfxFillRect ( left + WD_FRAMERECT_LEFT , y + WD_FRAMERECT_TOP , right - WD_FRAMERECT_RIGHT , y + this - > tiny_step_height - WD_FRAMERECT_BOTTOM - WD_MATRIX_TOP , _colour_gradient [ COLOUR_GREY ] [ 7 ] ) ;
}
2012-10-14 21:15:00 +02:00
if ( g_id = = NEW_GROUP ) return ;
2011-10-03 19:25:03 +02:00
/* draw the selected group in white, else we draw it in black */
TextColour colour = g_id = = this - > vli . index ? TC_WHITE : TC_BLACK ;
const GroupStatistics & stats = GroupStatistics : : Get ( this - > vli . company , g_id , this - > vli . vtype ) ;
bool rtl = _current_text_dir = = TD_RTL ;
2019-03-26 01:35:01 +01:00
/* draw fold / unfold button */
int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this - > column_size [ VGC_FOLD ] . width + 1 : left + WD_FRAMERECT_LEFT + 8 ;
if ( has_children ) {
DrawSprite ( Group : : Get ( g_id ) - > folded ? SPR_CIRCLE_FOLDED : SPR_CIRCLE_UNFOLDED , PAL_NONE , rtl ? x - indent : x + indent , y + ( this - > tiny_step_height - this - > column_size [ VGC_FOLD ] . height ) / 2 ) ;
}
2011-10-03 19:25:03 +02:00
/* draw group name */
StringID str ;
if ( IsAllGroupID ( g_id ) ) {
str = STR_GROUP_ALL_TRAINS + this - > vli . vtype ;
} else if ( IsDefaultGroupID ( g_id ) ) {
str = STR_GROUP_DEFAULT_TRAINS + this - > vli . vtype ;
} else {
SetDParam ( 0 , g_id ) ;
str = STR_GROUP_NAME ;
}
2019-03-26 01:35:01 +01:00
x = rtl ? x - 2 - this - > column_size [ VGC_NAME ] . width : x + 2 + this - > column_size [ VGC_FOLD ] . width ;
2019-01-27 13:33:54 +01:00
DrawString ( x + ( rtl ? 0 : indent ) , x + this - > column_size [ VGC_NAME ] . width - 1 - ( rtl ? indent : 0 ) , y + ( this - > tiny_step_height - this - > column_size [ VGC_NAME ] . height ) / 2 , str , colour ) ;
2011-10-03 19:25:03 +02:00
2011-10-03 19:26:37 +02:00
/* draw autoreplace protection */
x = rtl ? x - 8 - this - > column_size [ VGC_PROTECT ] . width : x + 8 + this - > column_size [ VGC_NAME ] . width ;
if ( protection ) DrawSprite ( SPR_GROUP_REPLACE_PROTECT , PAL_NONE , x , y + ( this - > tiny_step_height - this - > column_size [ VGC_PROTECT ] . height ) / 2 ) ;
/* draw autoreplace status */
x = rtl ? x - 2 - this - > column_size [ VGC_AUTOREPLACE ] . width : x + 2 + this - > column_size [ VGC_PROTECT ] . width ;
if ( stats . autoreplace_defined ) DrawSprite ( SPR_GROUP_REPLACE_ACTIVE , stats . autoreplace_finished ? PALETTE_CRASH : PAL_NONE , x , y + ( this - > tiny_step_height - this - > column_size [ VGC_AUTOREPLACE ] . height ) / 2 ) ;
2011-10-03 19:25:44 +02:00
/* draw the profit icon */
2011-10-03 19:26:37 +02:00
x = rtl ? x - 2 - this - > column_size [ VGC_PROFIT ] . width : x + 2 + this - > column_size [ VGC_AUTOREPLACE ] . width ;
2011-10-03 19:25:44 +02:00
SpriteID spr ;
2019-03-26 01:07:20 +01:00
uint num_profit_vehicle = GetGroupNumProfitVehicle ( this - > vli . company , g_id , this - > vli . vtype ) ;
Money profit_last_year = GetGroupProfitLastYear ( this - > vli . company , g_id , this - > vli . vtype ) ;
if ( num_profit_vehicle = = 0 ) {
2011-10-03 19:25:44 +02:00
spr = SPR_PROFIT_NA ;
2019-03-26 01:07:20 +01:00
} else if ( profit_last_year < 0 ) {
2011-10-03 19:25:44 +02:00
spr = SPR_PROFIT_NEGATIVE ;
2020-01-09 14:42:35 +01:00
} else if ( profit_last_year < VEHICLE_PROFIT_THRESHOLD * num_profit_vehicle ) {
2011-10-03 19:25:44 +02:00
spr = SPR_PROFIT_SOME ;
} else {
spr = SPR_PROFIT_LOT ;
}
DrawSprite ( spr , PAL_NONE , x , y + ( this - > tiny_step_height - this - > column_size [ VGC_PROFIT ] . height ) / 2 ) ;
2011-10-03 19:25:03 +02:00
/* draw the number of vehicles of the group */
2011-10-03 19:25:44 +02:00
x = rtl ? x - 2 - this - > column_size [ VGC_NUMBER ] . width : x + 2 + this - > column_size [ VGC_PROFIT ] . width ;
2019-03-26 01:07:20 +01:00
int num_vehicle_with_subgroups = GetGroupNumVehicle ( this - > vli . company , g_id , this - > vli . vtype ) ;
int num_vehicle = GroupStatistics : : Get ( this - > vli . company , g_id , this - > vli . vtype ) . num_vehicle ;
if ( IsAllGroupID ( g_id ) | | IsDefaultGroupID ( g_id ) | | num_vehicle_with_subgroups = = num_vehicle ) {
SetDParam ( 0 , num_vehicle ) ;
DrawString ( x , x + this - > column_size [ VGC_NUMBER ] . width - 1 , y + ( this - > tiny_step_height - this - > column_size [ VGC_NUMBER ] . height ) / 2 , STR_TINY_COMMA , colour , SA_RIGHT | SA_FORCE ) ;
} else {
SetDParam ( 0 , num_vehicle ) ;
SetDParam ( 1 , num_vehicle_with_subgroups - num_vehicle ) ;
DrawString ( x , x + this - > column_size [ VGC_NUMBER ] . width - 1 , y + ( this - > tiny_step_height - this - > column_size [ VGC_NUMBER ] . height ) / 2 , STR_GROUP_COUNT_WITH_SUBGROUP , colour , SA_RIGHT | SA_FORCE ) ;
}
2011-10-03 19:25:03 +02:00
}
2012-04-17 21:43:09 +02:00
/**
* Mark the widget containing the currently highlighted group as dirty .
*/
void DirtyHighlightedGroupWidget ( )
{
if ( this - > group_over = = INVALID_GROUP ) return ;
if ( IsAllGroupID ( this - > group_over ) ) {
this - > SetWidgetDirty ( WID_GL_ALL_VEHICLES ) ;
} else if ( IsDefaultGroupID ( this - > group_over ) ) {
this - > SetWidgetDirty ( WID_GL_DEFAULT_VEHICLES ) ;
} else {
this - > SetWidgetDirty ( WID_GL_LIST_GROUP ) ;
}
}
2008-05-26 20:30:58 +02:00
public :
2013-05-26 21:23:42 +02:00
VehicleGroupWindow ( WindowDesc * desc , WindowNumber window_number ) : BaseVehicleListWindow ( desc , window_number )
2008-05-11 17:00:11 +02:00
{
2013-05-26 21:23:42 +02:00
this - > CreateNestedTree ( ) ;
2008-05-11 17:00:11 +02:00
2011-12-16 17:32:48 +01:00
this - > vscroll = this - > GetScrollbar ( WID_GL_LIST_VEHICLE_SCROLLBAR ) ;
this - > group_sb = this - > GetScrollbar ( WID_GL_LIST_GROUP_SCROLLBAR ) ;
2010-08-12 10:37:01 +02:00
2010-09-09 16:40:39 +02:00
this - > vli . index = ALL_GROUP ;
2009-11-13 22:42:49 +01:00
this - > vehicle_sel = INVALID_VEHICLE ;
2014-04-08 23:09:06 +02:00
this - > group_sel = INVALID_GROUP ;
2009-11-13 22:42:49 +01:00
this - > group_rename = INVALID_GROUP ;
2012-04-17 21:43:09 +02:00
this - > group_over = INVALID_GROUP ;
2009-11-13 22:42:49 +01:00
2010-09-09 16:40:39 +02:00
this - > BuildVehicleList ( ) ;
2009-11-13 22:42:49 +01:00
this - > SortVehicleList ( ) ;
2008-05-11 16:23:45 +02:00
2008-05-26 20:30:58 +02:00
this - > groups . ForceRebuild ( ) ;
this - > groups . NeedResort ( ) ;
2010-09-10 15:50:47 +02:00
this - > BuildGroupList ( vli . company ) ;
2019-05-10 18:24:16 +02:00
this - > group_sb - > SetCount ( ( uint ) this - > groups . size ( ) ) ;
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
this - > GetWidget < NWidgetCore > ( WID_GL_CAPTION ) - > widget_data = STR_VEHICLE_LIST_TRAIN_CAPTION + this - > vli . vtype ;
this - > GetWidget < NWidgetCore > ( WID_GL_LIST_VEHICLE ) - > tool_tip = STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP + this - > vli . vtype ;
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
this - > GetWidget < NWidgetCore > ( WID_GL_CREATE_GROUP ) - > widget_data + = this - > vli . vtype ;
this - > GetWidget < NWidgetCore > ( WID_GL_RENAME_GROUP ) - > widget_data + = this - > vli . vtype ;
this - > GetWidget < NWidgetCore > ( WID_GL_DELETE_GROUP ) - > widget_data + = this - > vli . vtype ;
2019-01-31 14:57:44 +01:00
this - > GetWidget < NWidgetCore > ( WID_GL_LIVERY_GROUP ) - > widget_data + = this - > vli . vtype ;
2011-12-16 17:32:48 +01:00
this - > GetWidget < NWidgetCore > ( WID_GL_REPLACE_PROTECTION ) - > widget_data + = this - > vli . vtype ;
2009-07-22 22:17:07 +02:00
2013-05-26 21:23:42 +02:00
this - > FinishInitNested ( window_number ) ;
2010-09-10 15:50:47 +02:00
this - > owner = vli . company ;
2009-11-13 22:42:49 +01:00
}
2007-05-19 11:40:18 +02:00
2009-11-13 22:42:49 +01:00
~ VehicleGroupWindow ( )
{
2019-01-11 09:09:37 +01:00
* this - > sorting = this - > vehgroups . GetListing ( ) ;
2009-11-13 22:42:49 +01:00
}
2007-05-19 11:40:18 +02:00
2019-03-04 08:49:37 +01:00
void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize ) override
2009-11-13 22:42:49 +01:00
{
switch ( widget ) {
2011-12-16 17:32:48 +01:00
case WID_GL_LIST_GROUP : {
2011-10-03 19:25:03 +02:00
size - > width = this - > ComputeGroupInfoSize ( ) ;
2009-11-16 22:28:12 +01:00
resize - > height = this - > tiny_step_height ;
2011-10-03 19:25:03 +02:00
/* Minimum height is the height of the list widget minus all and default vehicles... */
size - > height = 4 * GetVehicleListHeight ( this - > vli . vtype , this - > tiny_step_height ) - 2 * this - > tiny_step_height ;
/* ... minus the buttons at the bottom ... */
2012-09-22 21:15:16 +02:00
uint max_icon_height = GetSpriteSize ( this - > GetWidget < NWidgetCore > ( WID_GL_CREATE_GROUP ) - > widget_data ) . height ;
2011-12-16 17:32:48 +01:00
max_icon_height = max ( max_icon_height , GetSpriteSize ( this - > GetWidget < NWidgetCore > ( WID_GL_RENAME_GROUP ) - > widget_data ) . height ) ;
max_icon_height = max ( max_icon_height , GetSpriteSize ( this - > GetWidget < NWidgetCore > ( WID_GL_DELETE_GROUP ) - > widget_data ) . height ) ;
max_icon_height = max ( max_icon_height , GetSpriteSize ( this - > GetWidget < NWidgetCore > ( WID_GL_REPLACE_PROTECTION ) - > widget_data ) . height ) ;
2011-10-03 19:25:03 +02:00
2017-03-24 08:33:31 +01:00
/* ... minus the height of the group info ... */
max_icon_height + = ( FONT_HEIGHT_NORMAL * 3 ) + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM ;
2012-09-22 21:14:06 +02:00
/* Get a multiple of tiny_step_height of that amount */
size - > height = Ceil ( size - > height - max_icon_height , tiny_step_height ) ;
2009-11-16 22:28:12 +01:00
break ;
2011-10-03 19:25:03 +02:00
}
2009-11-16 22:28:12 +01:00
2011-12-16 17:32:48 +01:00
case WID_GL_ALL_VEHICLES :
case WID_GL_DEFAULT_VEHICLES :
2011-10-03 19:25:03 +02:00
size - > width = this - > ComputeGroupInfoSize ( ) ;
size - > height = this - > tiny_step_height ;
2008-05-11 17:00:11 +02:00
break ;
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_SORT_BY_ORDER : {
2010-10-19 23:48:20 +02:00
Dimension d = GetStringBoundingBox ( this - > GetWidget < NWidgetCore > ( widget ) - > widget_data ) ;
2014-10-05 13:20:02 +02:00
d . width + = padding . width + Window : : SortButtonWidth ( ) * 2 ; // Doubled since the string is centred and it also looks better.
2010-10-19 23:48:20 +02:00
d . height + = padding . height ;
* size = maxdim ( * size , d ) ;
break ;
}
2011-12-16 17:32:48 +01:00
case WID_GL_LIST_VEHICLE :
2011-10-03 19:25:03 +02:00
this - > ComputeGroupInfoSize ( ) ;
resize - > height = GetVehicleListHeight ( this - > vli . vtype , this - > tiny_step_height ) ;
2009-11-16 22:28:12 +01:00
size - > height = 4 * resize - > height ;
2008-05-11 17:00:11 +02:00
break ;
2009-11-22 20:18:51 +01:00
2011-12-16 17:32:48 +01:00
case WID_GL_MANAGE_VEHICLES_DROPDOWN : {
2010-07-17 16:58:35 +02:00
Dimension d = this - > GetActionDropdownSize ( true , true ) ;
2009-11-22 20:18:51 +01:00
d . height + = padding . height ;
d . width + = padding . width ;
* size = maxdim ( * size , d ) ;
2010-08-01 20:53:30 +02:00
break ;
}
2017-03-24 08:33:31 +01:00
case WID_GL_INFO : {
size - > height = ( FONT_HEIGHT_NORMAL * 3 ) + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM ;
break ;
}
2008-05-11 17:00:11 +02:00
}
2008-01-16 19:25:23 +01:00
}
2011-03-13 22:31:29 +01: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 .
*/
2019-03-04 08:49:37 +01:00
void OnInvalidateData ( int data = 0 , bool gui_scope = true ) override
2008-05-11 17:00:11 +02:00
{
2008-05-26 20:30:58 +02:00
if ( data = = 0 ) {
2011-03-13 22:34:21 +01:00
/* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */
2019-01-11 09:09:37 +01:00
this - > vehgroups . ForceRebuild ( ) ;
2008-05-26 20:30:58 +02:00
this - > groups . ForceRebuild ( ) ;
} else {
2019-01-11 09:09:37 +01:00
this - > vehgroups . ForceResort ( ) ;
2008-05-26 20:30:58 +02:00
this - > groups . ForceResort ( ) ;
}
2011-03-13 22:34:21 +01:00
/* Process ID-invalidation in command-scope as well */
2009-08-24 23:51:02 +02:00
if ( this - > group_rename ! = INVALID_GROUP & & ! Group : : IsValidID ( this - > group_rename ) ) {
DeleteWindowByClass ( WC_QUERY_STRING ) ;
this - > group_rename = INVALID_GROUP ;
}
2010-09-09 16:40:39 +02:00
if ( ! ( IsAllGroupID ( this - > vli . index ) | | IsDefaultGroupID ( this - > vli . index ) | | Group : : IsValidID ( this - > vli . index ) ) ) {
this - > vli . index = ALL_GROUP ;
2008-05-11 17:00:11 +02:00
HideDropDownMenu ( this ) ;
}
this - > SetDirty ( ) ;
}
2007-05-19 11:40:18 +02:00
2019-03-04 08:49:37 +01:00
void SetStringParameters ( int widget ) const override
2009-11-13 22:42:49 +01:00
{
2010-07-30 14:26:58 +02:00
switch ( widget ) {
2011-12-16 17:32:48 +01:00
case WID_GL_AVAILABLE_VEHICLES :
2010-09-09 16:40:39 +02:00
SetDParam ( 0 , STR_VEHICLE_LIST_AVAILABLE_TRAINS + this - > vli . vtype ) ;
2010-07-30 14:26:58 +02:00
break ;
2009-11-13 22:42:49 +01:00
2011-12-16 17:32:48 +01:00
case WID_GL_CAPTION :
2010-07-30 14:26:58 +02:00
/* If selected_group == DEFAULT_GROUP || ALL_GROUP, draw the standard caption
* We list all vehicles or ungrouped vehicles */
2010-09-09 16:40:39 +02:00
if ( IsDefaultGroupID ( this - > vli . index ) | | IsAllGroupID ( this - > vli . index ) ) {
2010-07-30 14:26:58 +02:00
SetDParam ( 0 , STR_COMPANY_NAME ) ;
2010-10-03 21:17:53 +02:00
SetDParam ( 1 , this - > vli . company ) ;
2018-09-23 13:23:54 +02:00
SetDParam ( 2 , this - > vehicles . size ( ) ) ;
SetDParam ( 3 , this - > vehicles . size ( ) ) ;
2010-07-30 14:26:58 +02:00
} else {
2019-03-26 01:07:20 +01:00
uint num_vehicle = GetGroupNumVehicle ( this - > vli . company , this - > vli . index , this - > vli . vtype ) ;
2010-07-30 14:26:58 +02:00
SetDParam ( 0 , STR_GROUP_NAME ) ;
2019-03-26 01:07:20 +01:00
SetDParam ( 1 , this - > vli . index ) ;
SetDParam ( 2 , num_vehicle ) ;
SetDParam ( 3 , num_vehicle ) ;
2010-07-30 14:26:58 +02:00
}
break ;
2009-11-13 22:42:49 +01:00
}
}
2019-03-04 08:49:37 +01:00
void OnPaint ( ) override
2008-05-11 17:00:11 +02:00
{
2008-09-30 22:39:50 +02:00
/* If we select the all vehicles, this->list will contain all vehicles of the owner
* else this - > list will contain all vehicles which belong to the selected group */
2010-09-09 16:40:39 +02:00
this - > BuildVehicleList ( ) ;
2008-09-13 12:04:36 +02:00
this - > SortVehicleList ( ) ;
2007-05-19 11:40:18 +02:00
2010-09-10 15:50:47 +02:00
this - > BuildGroupList ( this - > owner ) ;
2007-05-19 11:40:18 +02:00
2019-01-11 09:09:37 +01:00
this - > group_sb - > SetCount ( static_cast < int > ( this - > groups . size ( ) ) ) ;
this - > vscroll - > SetCount ( static_cast < int > ( this - > vehgroups . size ( ) ) ) ;
2007-11-15 20:18:52 +01:00
2008-05-11 17:00:11 +02:00
/* The drop down menu is out, *but* it may not be used, retract it. */
2018-09-23 13:23:54 +02:00
if ( this - > vehicles . size ( ) = = 0 & & this - > IsWidgetLowered ( WID_GL_MANAGE_VEHICLES_DROPDOWN ) ) {
2011-12-16 17:32:48 +01:00
this - > RaiseWidget ( WID_GL_MANAGE_VEHICLES_DROPDOWN ) ;
2008-05-11 17:00:11 +02:00
HideDropDownMenu ( this ) ;
}
2007-05-19 11:40:18 +02:00
2008-05-11 17:00:11 +02:00
/* Disable all lists management button when the list is empty */
2018-09-23 13:23:54 +02:00
this - > SetWidgetsDisabledState ( this - > vehicles . size ( ) = = 0 | | _local_company ! = this - > vli . company ,
2011-12-16 17:32:48 +01:00
WID_GL_STOP_ALL ,
WID_GL_START_ALL ,
WID_GL_MANAGE_VEHICLES_DROPDOWN ,
2008-05-11 17:00:11 +02:00
WIDGET_LIST_END ) ;
/* Disable the group specific function when we select the default group or all vehicles */
2010-09-09 16:40:39 +02:00
this - > SetWidgetsDisabledState ( IsDefaultGroupID ( this - > vli . index ) | | IsAllGroupID ( this - > vli . index ) | | _local_company ! = this - > vli . company ,
2011-12-16 17:32:48 +01:00
WID_GL_DELETE_GROUP ,
WID_GL_RENAME_GROUP ,
2019-01-31 14:57:44 +01:00
WID_GL_LIVERY_GROUP ,
2011-12-16 17:32:48 +01:00
WID_GL_REPLACE_PROTECTION ,
2008-05-11 17:00:11 +02:00
WIDGET_LIST_END ) ;
2008-09-30 22:39:50 +02:00
/* Disable remaining buttons for non-local companies
* Needed while changing _local_company , eg . by cheats
* All procedures ( eg . move vehicle to another group )
* verify , whether you are the owner of the vehicle ,
* so it doesn ' t have to be disabled
*/
2010-09-09 16:40:39 +02:00
this - > SetWidgetsDisabledState ( _local_company ! = this - > vli . company ,
2011-12-16 17:32:48 +01:00
WID_GL_CREATE_GROUP ,
WID_GL_AVAILABLE_VEHICLES ,
2008-05-11 17:00:11 +02:00
WIDGET_LIST_END ) ;
2009-11-13 22:42:49 +01:00
/* If not a default group and the group has replace protection, show an enabled replace sprite. */
uint16 protect_sprite = SPR_GROUP_REPLACE_OFF_TRAIN ;
2010-09-09 16:40:39 +02:00
if ( ! IsDefaultGroupID ( this - > vli . index ) & & ! IsAllGroupID ( this - > vli . index ) & & Group : : Get ( this - > vli . index ) - > replace_protection ) protect_sprite = SPR_GROUP_REPLACE_ON_TRAIN ;
2011-12-16 17:32:48 +01:00
this - > GetWidget < NWidgetCore > ( WID_GL_REPLACE_PROTECTION ) - > widget_data = protect_sprite + this - > vli . vtype ;
2007-07-15 01:10:27 +02:00
2019-01-11 09:50:38 +01:00
/* Set text of "group by" dropdown widget. */
this - > GetWidget < NWidgetCore > ( WID_GL_GROUP_BY_DROPDOWN ) - > widget_data = this - > vehicle_group_by_names [ this - > grouping ] ;
/* Set text of "sort by" dropdown widget. */
this - > GetWidget < NWidgetCore > ( WID_GL_SORT_BY_DROPDOWN ) - > widget_data = this - > GetVehicleSorterNames ( ) [ this - > vehgroups . SortType ( ) ] ;
2008-05-11 17:00:11 +02:00
2008-05-17 14:48:06 +02:00
this - > DrawWidgets ( ) ;
2009-11-13 22:42:49 +01:00
}
2008-05-11 17:00:11 +02:00
2019-03-04 08:49:37 +01:00
void DrawWidget ( const Rect & r , int widget ) const override
2009-11-13 22:42:49 +01:00
{
switch ( widget ) {
2011-12-16 17:32:48 +01:00
case WID_GL_ALL_VEHICLES :
2011-10-03 19:25:03 +02:00
DrawGroupInfo ( r . top + WD_FRAMERECT_TOP , r . left , r . right , ALL_GROUP ) ;
2009-11-13 22:42:49 +01:00
break ;
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_DEFAULT_VEHICLES :
2011-10-03 19:25:03 +02:00
DrawGroupInfo ( r . top + WD_FRAMERECT_TOP , r . left , r . right , DEFAULT_GROUP ) ;
2009-11-13 22:42:49 +01:00
break ;
2007-05-19 11:40:18 +02:00
2017-03-24 08:33:31 +01:00
case WID_GL_INFO : {
Money this_year = 0 ;
Money last_year = 0 ;
2019-01-11 09:55:32 +01:00
uint64 occupancy = 0 ;
2017-03-24 08:33:31 +01:00
2019-01-11 09:55:32 +01:00
for ( const Vehicle * const v : this - > vehicles ) {
2017-03-24 08:33:31 +01:00
assert ( v - > owner = = this - > owner ) ;
this_year + = v - > GetDisplayProfitThisYear ( ) ;
last_year + = v - > GetDisplayProfitLastYear ( ) ;
occupancy + = v - > trip_occupancy ;
}
const int left = r . left + WD_FRAMERECT_LEFT + 8 ;
const int right = r . right - WD_FRAMERECT_RIGHT - 8 ;
int y = r . top + WD_FRAMERECT_TOP ;
DrawString ( left , right , y , STR_GROUP_PROFIT_THIS_YEAR , TC_BLACK ) ;
SetDParam ( 0 , this_year ) ;
DrawString ( left , right , y , STR_JUST_CURRENCY_LONG , TC_BLACK , SA_RIGHT ) ;
y + = FONT_HEIGHT_NORMAL ;
DrawString ( left , right , y , STR_GROUP_PROFIT_LAST_YEAR , TC_BLACK ) ;
SetDParam ( 0 , last_year ) ;
DrawString ( left , right , y , STR_JUST_CURRENCY_LONG , TC_BLACK , SA_RIGHT ) ;
y + = FONT_HEIGHT_NORMAL ;
DrawString ( left , right , y , STR_GROUP_OCCUPANCY , TC_BLACK ) ;
2019-01-11 09:55:32 +01:00
const size_t vehicle_count = this - > vehicles . size ( ) ;
2017-03-24 08:33:31 +01:00
if ( vehicle_count > 0 ) {
SetDParam ( 0 , occupancy / vehicle_count ) ;
DrawString ( left , right , y , STR_GROUP_OCCUPANCY_VALUE , TC_BLACK , SA_RIGHT ) ;
}
break ;
}
2011-12-16 17:32:48 +01:00
case WID_GL_LIST_GROUP : {
2011-10-03 19:25:03 +02:00
int y1 = r . top + WD_FRAMERECT_TOP ;
2019-03-28 00:09:33 +01:00
int max = min ( this - > group_sb - > GetPosition ( ) + this - > group_sb - > GetCapacity ( ) , ( uint ) this - > groups . size ( ) ) ;
2010-08-12 10:42:37 +02:00
for ( int i = this - > group_sb - > GetPosition ( ) ; i < max ; + + i ) {
2009-11-13 22:42:49 +01:00
const Group * g = this - > groups [ i ] ;
2007-05-19 11:40:18 +02:00
2009-11-13 22:42:49 +01:00
assert ( g - > owner = = this - > owner ) ;
2007-05-19 11:40:18 +02:00
2019-03-26 01:35:01 +01:00
DrawGroupInfo ( y1 , r . left , r . right , g - > index , this - > indents [ i ] * LEVEL_WIDTH , g - > replace_protection , g - > folded | | ( i + 1 < ( int ) this - > groups . size ( ) & & indents [ i + 1 ] > this - > indents [ i ] ) ) ;
2007-05-19 11:40:18 +02:00
2009-11-16 22:28:12 +01:00
y1 + = this - > tiny_step_height ;
2009-11-13 22:42:49 +01:00
}
2018-09-23 13:23:54 +02:00
if ( ( uint ) this - > group_sb - > GetPosition ( ) + this - > group_sb - > GetCapacity ( ) > this - > groups . size ( ) ) {
2012-10-14 21:15:00 +02:00
DrawGroupInfo ( y1 , r . left , r . right , NEW_GROUP ) ;
}
2009-11-13 22:42:49 +01:00
break ;
}
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_SORT_BY_ORDER :
2019-01-11 09:09:37 +01:00
this - > DrawSortButtonState ( WID_GL_SORT_BY_ORDER , this - > vehgroups . IsDescSortOrder ( ) ? SBS_DOWN : SBS_UP ) ;
2009-11-13 22:42:49 +01:00
break ;
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_LIST_VEHICLE :
2019-01-11 09:09:37 +01:00
if ( this - > vli . index ! = ALL_GROUP & & this - > grouping = = GB_NONE ) {
/* Mark vehicles which are in sub-groups (only if we are not using shared order coalescing) */
2014-04-08 23:09:06 +02:00
int y = r . top ;
2019-01-11 09:09:37 +01:00
uint max = min ( this - > vscroll - > GetPosition ( ) + this - > vscroll - > GetCapacity ( ) , static_cast < uint > ( this - > vehgroups . size ( ) ) ) ;
2014-04-08 23:09:06 +02:00
for ( uint i = this - > vscroll - > GetPosition ( ) ; i < max ; + + i ) {
2019-01-11 09:09:37 +01:00
const Vehicle * v = this - > vehgroups [ i ] . GetSingleVehicle ( ) ;
2014-04-08 23:09:06 +02:00
if ( v - > group_id ! = this - > vli . index ) {
GfxFillRect ( r . left + 1 , y + 1 , r . right - 1 , y + this - > resize . step_height - 2 , _colour_gradient [ COLOUR_GREY ] [ 3 ] , FILLRECT_CHECKER ) ;
}
y + = this - > resize . step_height ;
}
}
2009-11-13 22:42:49 +01:00
this - > DrawVehicleListItems ( this - > vehicle_sel , this - > resize . step_height , r ) ;
break ;
}
2008-05-11 17:00:11 +02:00
}
2007-05-19 11:40:18 +02:00
2014-04-11 20:14:44 +02:00
static void DeleteGroupCallback ( Window * win , bool confirmed )
{
if ( confirmed ) {
VehicleGroupWindow * w = ( VehicleGroupWindow * ) win ;
w - > vli . index = ALL_GROUP ;
DoCommandP ( 0 , w - > group_confirm , 0 , CMD_DELETE_GROUP | CMD_MSG ( STR_ERROR_GROUP_CAN_T_DELETE ) ) ;
}
}
2019-03-04 08:49:37 +01:00
void OnClick ( Point pt , int widget , int click_count ) override
2008-05-11 17:00:11 +02:00
{
2009-08-09 16:40:34 +02:00
switch ( widget ) {
2011-12-16 17:32:48 +01:00
case WID_GL_SORT_BY_ORDER : // Flip sorting method ascending/descending
2019-01-11 09:09:37 +01:00
this - > vehgroups . ToggleSortOrder ( ) ;
2008-05-11 17:00:11 +02:00
this - > SetDirty ( ) ;
break ;
2007-05-19 11:40:18 +02:00
2019-01-11 09:50:38 +01:00
case WID_GL_GROUP_BY_DROPDOWN : // Select grouping option dropdown menu
ShowDropDownMenu ( this , this - > vehicle_group_by_names , this - > grouping , WID_GL_GROUP_BY_DROPDOWN , 0 , 0 ) ;
return ;
2011-12-16 17:32:48 +01:00
case WID_GL_SORT_BY_DROPDOWN : // Select sorting criteria dropdown menu
2019-01-11 09:09:37 +01:00
ShowDropDownMenu ( this , this - > GetVehicleSorterNames ( ) , this - > vehgroups . SortType ( ) , WID_GL_SORT_BY_DROPDOWN , 0 , ( this - > vli . vtype = = VEH_TRAIN | | this - > vli . vtype = = VEH_ROAD ) ? 0 : ( 1 < < 10 ) ) ;
2008-05-11 17:00:11 +02:00
return ;
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_ALL_VEHICLES : // All vehicles button
2010-09-09 16:40:39 +02:00
if ( ! IsAllGroupID ( this - > vli . index ) ) {
this - > vli . index = ALL_GROUP ;
2019-01-11 09:09:37 +01:00
this - > vehgroups . ForceRebuild ( ) ;
2008-05-11 17:00:11 +02:00
this - > SetDirty ( ) ;
}
break ;
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_DEFAULT_VEHICLES : // Ungrouped vehicles button
2010-09-09 16:40:39 +02:00
if ( ! IsDefaultGroupID ( this - > vli . index ) ) {
this - > vli . index = DEFAULT_GROUP ;
2019-01-11 09:09:37 +01:00
this - > vehgroups . ForceRebuild ( ) ;
2008-05-11 17:00:11 +02:00
this - > SetDirty ( ) ;
}
break ;
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_LIST_GROUP : { // Matrix Group
uint id_g = this - > group_sb - > GetScrolledRowFromWidget ( pt . y , this , WID_GL_LIST_GROUP , 0 , this - > tiny_step_height ) ;
2018-09-23 13:23:54 +02:00
if ( id_g > = this - > groups . size ( ) ) return ;
2007-05-19 11:40:18 +02:00
2019-03-26 01:35:01 +01:00
if ( groups [ id_g ] - > folded | | ( id_g + 1 < this - > groups . size ( ) & & this - > indents [ id_g + 1 ] > this - > indents [ id_g ] ) ) {
/* The group has children, check if the user clicked the fold / unfold button. */
NWidgetCore * group_display = this - > GetWidget < NWidgetCore > ( widget ) ;
int x = _current_text_dir = = TD_RTL ?
group_display - > pos_x + group_display - > current_x - WD_FRAMERECT_RIGHT - 8 - this - > indents [ id_g ] * LEVEL_WIDTH - this - > column_size [ VGC_FOLD ] . width :
group_display - > pos_x + WD_FRAMERECT_LEFT + 8 + this - > indents [ id_g ] * LEVEL_WIDTH ;
if ( click_count > 1 | | ( pt . x > = x & & pt . x < ( int ) ( x + this - > column_size [ VGC_FOLD ] . width ) ) ) {
GroupID g = this - > vli . index ;
if ( ! IsAllGroupID ( g ) & & ! IsDefaultGroupID ( g ) ) {
do {
g = Group : : Get ( g ) - > parent ;
if ( g = = groups [ id_g ] - > index ) {
this - > vli . index = g ;
break ;
}
} while ( g ! = INVALID_GROUP ) ;
}
Group : : Get ( groups [ id_g ] - > index ) - > folded = ! groups [ id_g ] - > folded ;
this - > groups . ForceRebuild ( ) ;
this - > SetDirty ( ) ;
break ;
}
}
2014-04-08 23:09:06 +02:00
this - > group_sel = this - > vli . index = this - > groups [ id_g ] - > index ;
SetObjectToPlaceWnd ( SPR_CURSOR_MOUSE , PAL_NONE , HT_DRAG , this ) ;
2007-05-19 11:40:18 +02:00
2019-01-11 09:09:37 +01:00
this - > vehgroups . ForceRebuild ( ) ;
2008-05-11 17:00:11 +02:00
this - > SetDirty ( ) ;
break ;
}
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_LIST_VEHICLE : { // Matrix Vehicle
uint id_v = this - > vscroll - > GetScrolledRowFromWidget ( pt . y , this , WID_GL_LIST_VEHICLE ) ;
2019-01-11 09:09:37 +01:00
if ( id_v > = this - > vehgroups . size ( ) ) return ; // click out of list bound
2007-05-19 11:40:18 +02:00
2019-01-11 09:09:37 +01:00
const GUIVehicleGroup & vehgroup = this - > vehgroups [ id_v ] ;
2019-01-11 09:50:38 +01:00
switch ( this - > grouping ) {
case GB_NONE : {
const Vehicle * v = vehgroup . GetSingleVehicle ( ) ;
if ( VehicleClicked ( v ) ) break ;
2007-05-19 11:40:18 +02:00
2019-01-11 09:50:38 +01:00
this - > vehicle_sel = v - > index ;
2007-05-19 11:40:18 +02:00
2019-01-11 09:50:38 +01:00
if ( _ctrl_pressed ) {
this - > SelectGroup ( v - > group_id ) ;
}
2019-05-10 19:33:59 +02:00
2019-01-11 09:50:38 +01:00
SetObjectToPlaceWnd ( SPR_CURSOR_MOUSE , PAL_NONE , HT_DRAG , this ) ;
SetMouseCursorVehicle ( v , EIT_IN_LIST ) ;
_cursor . vehchain = true ;
this - > SetDirty ( ) ;
break ;
}
case GB_SHARED_ORDERS :
assert ( vehgroup . NumVehicles ( ) > 0 ) ;
/* No drag-and-drop support for shared order grouping; we immediately open the shared orders window */
ShowVehicleListWindow ( vehgroup . vehicles_begin [ 0 ] ) ;
break ;
default :
NOT_REACHED ( ) ;
}
2007-05-19 11:40:18 +02:00
2008-05-11 17:00:11 +02:00
break ;
}
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_CREATE_GROUP : { // Create a new group
2019-02-15 19:43:33 +01:00
DoCommandP ( 0 , this - > vli . vtype , this - > vli . index , CMD_CREATE_GROUP | CMD_MSG ( STR_ERROR_GROUP_CAN_T_CREATE ) , CcCreateGroup ) ;
2008-05-11 17:00:11 +02:00
break ;
2009-08-25 12:44:19 +02:00
}
2007-05-22 21:48:11 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_DELETE_GROUP : { // Delete the selected group
2014-04-11 20:14:44 +02:00
this - > group_confirm = this - > vli . index ;
ShowQuery ( STR_QUERY_GROUP_DELETE_CAPTION , STR_GROUP_DELETE_QUERY_TEXT , this , DeleteGroupCallback ) ;
2008-05-11 17:00:11 +02:00
break ;
}
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_RENAME_GROUP : // Rename the selected roup
2010-09-09 16:40:39 +02:00
this - > ShowRenameGroupWindow ( this - > vli . index , false ) ;
2009-08-25 12:44:19 +02:00
break ;
2007-05-19 11:40:18 +02:00
2019-01-31 14:57:44 +01:00
case WID_GL_LIVERY_GROUP : // Set group livery
ShowCompanyLiveryWindow ( this - > owner , this - > vli . index ) ;
break ;
2011-12-16 17:32:48 +01:00
case WID_GL_AVAILABLE_VEHICLES :
2010-09-09 16:40:39 +02:00
ShowBuildVehicleWindow ( INVALID_TILE , this - > vli . vtype ) ;
2008-05-11 17:00:11 +02:00
break ;
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_MANAGE_VEHICLES_DROPDOWN : {
2019-04-02 21:31:24 +02:00
ShowDropDownList ( this , this - > BuildActionDropdownList ( true , Group : : IsValidID ( this - > vli . index ) ) , 0 , WID_GL_MANAGE_VEHICLES_DROPDOWN ) ;
2008-05-11 17:00:11 +02:00
break ;
2010-07-17 16:36:36 +02:00
}
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_START_ALL :
case WID_GL_STOP_ALL : { // Start/stop all vehicles of the list
DoCommandP ( 0 , ( 1 < < 1 ) | ( widget = = WID_GL_START_ALL ? ( 1 < < 0 ) : 0 ) , this - > vli . Pack ( ) , CMD_MASS_START_STOP ) ;
2008-05-11 17:00:11 +02:00
break ;
2007-05-19 11:40:18 +02:00
}
2011-12-16 17:32:48 +01:00
case WID_GL_REPLACE_PROTECTION : {
2010-09-09 16:40:39 +02:00
const Group * g = Group : : GetIfValid ( this - > vli . index ) ;
2019-04-10 23:07:06 +02:00
if ( g ! = nullptr ) {
2015-06-20 13:05:11 +02:00
DoCommandP ( 0 , this - > vli . index , ( g - > replace_protection ? 0 : 1 ) | ( _ctrl_pressed < < 1 ) , CMD_SET_GROUP_REPLACE_PROTECTION ) ;
2008-05-11 17:00:11 +02:00
}
break ;
2009-05-18 18:21:28 +02:00
}
2008-05-11 17:00:11 +02:00
}
}
2007-05-19 11:40:18 +02:00
2014-04-08 23:09:06 +02:00
void OnDragDrop_Group ( Point pt , int widget )
{
const Group * g = Group : : Get ( this - > group_sel ) ;
switch ( widget ) {
case WID_GL_ALL_VEHICLES : // All vehicles
2019-11-25 22:59:03 +01:00
case WID_GL_DEFAULT_VEHICLES : // Ungrouped vehicles
2014-04-08 23:09:06 +02:00
if ( g - > parent ! = INVALID_GROUP ) {
DoCommandP ( 0 , this - > group_sel | ( 1 < < 16 ) , INVALID_GROUP , CMD_ALTER_GROUP | CMD_MSG ( STR_ERROR_GROUP_CAN_T_SET_PARENT ) ) ;
}
this - > group_sel = INVALID_GROUP ;
this - > group_over = INVALID_GROUP ;
this - > SetDirty ( ) ;
break ;
case WID_GL_LIST_GROUP : { // Matrix group
uint id_g = this - > group_sb - > GetScrolledRowFromWidget ( pt . y , this , WID_GL_LIST_GROUP , 0 , this - > tiny_step_height ) ;
2018-09-23 13:23:54 +02:00
GroupID new_g = id_g > = this - > groups . size ( ) ? INVALID_GROUP : this - > groups [ id_g ] - > index ;
2014-04-08 23:09:06 +02:00
if ( this - > group_sel ! = new_g & & g - > parent ! = new_g ) {
DoCommandP ( 0 , this - > group_sel | ( 1 < < 16 ) , new_g , CMD_ALTER_GROUP | CMD_MSG ( STR_ERROR_GROUP_CAN_T_SET_PARENT ) ) ;
}
this - > group_sel = INVALID_GROUP ;
this - > group_over = INVALID_GROUP ;
this - > SetDirty ( ) ;
break ;
}
}
}
void OnDragDrop_Vehicle ( Point pt , int widget )
2008-05-11 17:00:11 +02:00
{
switch ( widget ) {
2011-12-16 17:32:48 +01:00
case WID_GL_DEFAULT_VEHICLES : // Ungrouped vehicles
2012-04-17 21:44:12 +02:00
DoCommandP ( 0 , DEFAULT_GROUP , this - > vehicle_sel | ( _ctrl_pressed ? 1 < < 31 : 0 ) , CMD_ADD_VEHICLE_GROUP | CMD_MSG ( STR_ERROR_GROUP_CAN_T_ADD_VEHICLE ) ) ;
2007-05-19 11:40:18 +02:00
2008-05-11 17:00:11 +02:00
this - > vehicle_sel = INVALID_VEHICLE ;
2012-04-17 21:43:09 +02:00
this - > group_over = INVALID_GROUP ;
2007-05-19 11:40:18 +02:00
2008-05-11 17:00:11 +02:00
this - > SetDirty ( ) ;
break ;
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_LIST_GROUP : { // Matrix group
2008-05-11 17:00:11 +02:00
const VehicleID vindex = this - > vehicle_sel ;
this - > vehicle_sel = INVALID_VEHICLE ;
2012-04-17 21:43:09 +02:00
this - > group_over = INVALID_GROUP ;
2008-05-11 17:00:11 +02:00
this - > SetDirty ( ) ;
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
uint id_g = this - > group_sb - > GetScrolledRowFromWidget ( pt . y , this , WID_GL_LIST_GROUP , 0 , this - > tiny_step_height ) ;
2018-09-23 13:23:54 +02:00
GroupID new_g = id_g > = this - > groups . size ( ) ? NEW_GROUP : this - > groups [ id_g ] - > index ;
2007-05-19 11:40:18 +02:00
2019-04-10 23:07:06 +02:00
DoCommandP ( 0 , new_g , vindex | ( _ctrl_pressed ? 1 < < 31 : 0 ) , CMD_ADD_VEHICLE_GROUP | CMD_MSG ( STR_ERROR_GROUP_CAN_T_ADD_VEHICLE ) , new_g = = NEW_GROUP ? CcAddVehicleNewGroup : nullptr ) ;
2008-05-11 17:00:11 +02:00
break ;
}
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_LIST_VEHICLE : { // Matrix vehicle
2008-05-11 17:00:11 +02:00
const VehicleID vindex = this - > vehicle_sel ;
this - > vehicle_sel = INVALID_VEHICLE ;
2012-04-17 21:43:09 +02:00
this - > group_over = INVALID_GROUP ;
2008-05-11 17:00:11 +02:00
this - > SetDirty ( ) ;
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
uint id_v = this - > vscroll - > GetScrolledRowFromWidget ( pt . y , this , WID_GL_LIST_VEHICLE ) ;
2019-01-11 09:09:37 +01:00
if ( id_v > = this - > vehgroups . size ( ) ) return ; // click out of list bound
2007-05-19 11:40:18 +02:00
2019-01-11 09:09:37 +01:00
const GUIVehicleGroup & vehgroup = this - > vehgroups [ id_v ] ;
2019-01-11 09:50:38 +01:00
switch ( this - > grouping ) {
case GB_NONE : {
const Vehicle * v = vehgroup . GetSingleVehicle ( ) ;
if ( ! VehicleClicked ( v ) & & vindex = = v - > index ) {
ShowVehicleViewWindow ( v ) ;
}
break ;
}
case GB_SHARED_ORDERS :
/* Currently no drag-and-drop support when grouped by shared orders. Modify this if we want to support some drag-drop behaviour for shared order list items. */
NOT_REACHED ( ) ;
default :
NOT_REACHED ( ) ;
2007-05-19 11:40:18 +02:00
}
2019-01-11 09:50:38 +01:00
break ;
2007-05-19 11:40:18 +02:00
}
}
2014-04-08 23:09:06 +02:00
}
2019-03-04 08:49:37 +01:00
void OnDragDrop ( Point pt , int widget ) override
2014-04-08 23:09:06 +02:00
{
if ( this - > vehicle_sel ! = INVALID_VEHICLE ) OnDragDrop_Vehicle ( pt , widget ) ;
if ( this - > group_sel ! = INVALID_GROUP ) OnDragDrop_Group ( pt , widget ) ;
2008-05-11 17:00:11 +02:00
_cursor . vehchain = false ;
}
2007-05-19 11:40:18 +02:00
2019-03-04 08:49:37 +01:00
void OnQueryTextFinished ( char * str ) override
2008-05-11 17:00:11 +02:00
{
2019-04-10 23:07:06 +02:00
if ( str ! = nullptr ) DoCommandP ( 0 , this - > group_rename , 0 , CMD_ALTER_GROUP | CMD_MSG ( STR_ERROR_GROUP_CAN_T_RENAME ) , nullptr , str ) ;
2009-08-24 23:51:02 +02:00
this - > group_rename = INVALID_GROUP ;
2008-05-11 17:00:11 +02:00
}
2007-05-19 11:40:18 +02:00
2019-03-04 08:49:37 +01:00
void OnResize ( ) override
2008-05-11 17:00:11 +02:00
{
2013-06-30 16:33:32 +02:00
this - > group_sb - > SetCapacityFromWidget ( this , WID_GL_LIST_GROUP ) ;
2011-12-16 17:32:48 +01:00
this - > vscroll - > SetCapacityFromWidget ( this , WID_GL_LIST_VEHICLE ) ;
2008-05-11 17:00:11 +02:00
}
2007-05-19 11:40:18 +02:00
2019-03-04 08:49:37 +01:00
void OnDropdownSelect ( int widget , int index ) override
2008-05-11 17:00:11 +02:00
{
switch ( widget ) {
2019-01-11 09:50:38 +01:00
case WID_GL_GROUP_BY_DROPDOWN :
this - > UpdateVehicleGroupBy ( static_cast < GroupBy > ( index ) ) ;
break ;
2011-12-16 17:32:48 +01:00
case WID_GL_SORT_BY_DROPDOWN :
2019-01-11 09:09:37 +01:00
this - > vehgroups . SetSortType ( index ) ;
2008-05-11 17:00:11 +02:00
break ;
2007-05-19 11:40:18 +02:00
2011-12-16 17:32:48 +01:00
case WID_GL_MANAGE_VEHICLES_DROPDOWN :
2018-09-23 13:23:54 +02:00
assert ( this - > vehicles . size ( ) ! = 0 ) ;
2007-05-19 11:40:18 +02:00
2008-05-11 17:00:11 +02:00
switch ( index ) {
2010-07-17 16:36:36 +02:00
case ADI_REPLACE : // Replace window
2010-09-09 16:40:39 +02:00
ShowReplaceGroupVehicleWindow ( this - > vli . index , this - > vli . vtype ) ;
2008-05-11 17:00:11 +02:00
break ;
2010-07-17 16:36:36 +02:00
case ADI_SERVICE : // Send for servicing
2010-09-08 23:40:00 +02:00
case ADI_DEPOT : { // Send to Depots
2010-09-09 16:40:39 +02:00
DoCommandP ( 0 , DEPOT_MASS_SEND | ( index = = ADI_SERVICE ? DEPOT_SERVICE : 0U ) , this - > vli . Pack ( ) , GetCmdSendToDepot ( this - > vli . vtype ) ) ;
2008-05-11 17:00:11 +02:00
break ;
2010-09-08 23:40:00 +02:00
}
2010-07-17 16:36:36 +02:00
case ADI_ADD_SHARED : // Add shared Vehicles
2010-09-09 16:40:39 +02:00
assert ( Group : : IsValidID ( this - > vli . index ) ) ;
2007-05-19 11:40:18 +02:00
2010-09-09 16:40:39 +02:00
DoCommandP ( 0 , this - > vli . index , this - > vli . vtype , CMD_ADD_SHARED_VEHICLE_GROUP | CMD_MSG ( STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE ) ) ;
2008-05-11 17:00:11 +02:00
break ;
2010-07-17 16:36:36 +02:00
case ADI_REMOVE_ALL : // Remove all Vehicles from the selected group
2010-09-09 16:40:39 +02:00
assert ( Group : : IsValidID ( this - > vli . index ) ) ;
2007-05-19 11:40:18 +02:00
2011-11-20 15:39:12 +01:00
DoCommandP ( 0 , this - > vli . index , 0 , CMD_REMOVE_ALL_VEHICLES_GROUP | CMD_MSG ( STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES ) ) ;
2008-05-11 17:00:11 +02:00
break ;
default : NOT_REACHED ( ) ;
}
break ;
2008-02-17 13:21:05 +01:00
2008-05-11 17:00:11 +02:00
default : NOT_REACHED ( ) ;
}
2008-02-17 13:21:05 +01:00
2008-05-11 17:00:11 +02:00
this - > SetDirty ( ) ;
2008-01-01 23:34:00 +01:00
}
2008-05-11 17:00:11 +02:00
2019-03-04 08:49:37 +01:00
void OnGameTick ( ) override
2008-05-11 17:00:11 +02:00
{
2019-01-11 09:09:37 +01:00
if ( this - > groups . NeedResort ( ) | | this - > vehgroups . NeedResort ( ) ) {
2008-05-11 17:00:11 +02:00
this - > SetDirty ( ) ;
}
}
2019-03-04 08:49:37 +01:00
void OnPlaceObjectAbort ( ) override
2008-05-11 17:00:11 +02:00
{
2008-09-13 12:04:36 +02:00
/* abort drag & drop */
this - > vehicle_sel = INVALID_VEHICLE ;
2012-04-17 21:43:09 +02:00
this - > DirtyHighlightedGroupWidget ( ) ;
this - > group_over = INVALID_GROUP ;
2011-12-16 17:32:48 +01:00
this - > SetWidgetDirty ( WID_GL_LIST_VEHICLE ) ;
2008-05-11 17:00:11 +02:00
}
2009-01-08 22:16:19 +01:00
2019-03-04 08:49:37 +01:00
void OnMouseDrag ( Point pt , int widget ) override
2012-04-17 21:43:09 +02:00
{
2014-04-08 23:09:06 +02:00
if ( this - > vehicle_sel = = INVALID_VEHICLE & & this - > group_sel = = INVALID_GROUP ) return ;
2012-04-17 21:43:09 +02:00
/* A vehicle is dragged over... */
GroupID new_group_over = INVALID_GROUP ;
switch ( widget ) {
case WID_GL_DEFAULT_VEHICLES : // ... the 'default' group.
2012-10-14 21:15:00 +02:00
new_group_over = DEFAULT_GROUP ;
2012-04-17 21:43:09 +02:00
break ;
case WID_GL_LIST_GROUP : { // ... the list of custom groups.
uint id_g = this - > group_sb - > GetScrolledRowFromWidget ( pt . y , this , WID_GL_LIST_GROUP , 0 , this - > tiny_step_height ) ;
2018-09-23 13:23:54 +02:00
new_group_over = id_g > = this - > groups . size ( ) ? NEW_GROUP : this - > groups [ id_g ] - > index ;
2012-04-17 21:43:09 +02:00
break ;
}
}
2012-10-14 21:15:00 +02:00
/* Do not highlight when dragging over the current group */
2014-04-08 23:09:06 +02:00
if ( this - > vehicle_sel ! = INVALID_VEHICLE ) {
if ( Vehicle : : Get ( vehicle_sel ) - > group_id = = new_group_over ) new_group_over = INVALID_GROUP ;
} else if ( this - > group_sel ! = INVALID_GROUP ) {
if ( this - > group_sel = = new_group_over | | Group : : Get ( this - > group_sel ) - > parent = = new_group_over ) new_group_over = INVALID_GROUP ;
}
2012-10-14 21:15:00 +02:00
2012-04-17 21:43:09 +02:00
/* Mark widgets as dirty if the group changed. */
if ( new_group_over ! = this - > group_over ) {
this - > DirtyHighlightedGroupWidget ( ) ;
this - > group_over = new_group_over ;
this - > DirtyHighlightedGroupWidget ( ) ;
}
}
2010-02-01 19:38:28 +01:00
void ShowRenameGroupWindow ( GroupID group , bool empty )
2009-08-25 12:44:19 +02:00
{
assert ( Group : : IsValidID ( group ) ) ;
this - > group_rename = group ;
2010-02-01 19:38:28 +01:00
/* Show empty query for new groups */
StringID str = STR_EMPTY ;
if ( ! empty ) {
SetDParam ( 0 , group ) ;
str = STR_GROUP_NAME ;
}
2011-04-17 20:42:17 +02:00
ShowQueryString ( str , STR_GROUP_RENAME_CAPTION , MAX_LENGTH_GROUP_NAME_CHARS , this , CS_ALPHANUMERAL , QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS ) ;
2009-08-25 12:44:19 +02:00
}
2009-01-08 22:16:19 +01:00
/**
* Tests whether a given vehicle is selected in the window , and unselects it if necessary .
* Called when the vehicle is deleted .
* @ param vehicle Vehicle that is going to be deleted
*/
void UnselectVehicle ( VehicleID vehicle )
{
if ( this - > vehicle_sel = = vehicle ) ResetObjectToPlace ( ) ;
}
2019-05-10 18:24:16 +02:00
/**
* Selects the specified group in the list
*
* @ param g_id The ID of the group to be selected
*/
void SelectGroup ( const GroupID g_id )
{
if ( g_id = = INVALID_GROUP | | g_id = = this - > vli . index ) return ;
this - > vli . index = g_id ;
if ( g_id ! = ALL_GROUP & & g_id ! = DEFAULT_GROUP ) {
const Group * g = Group : : Get ( g_id ) ;
int id_g = find_index ( this - > groups , g ) ;
// The group's branch is maybe collapsed, so try to expand it
if ( id_g = = - 1 ) {
for ( auto pg = Group : : GetIfValid ( g - > parent ) ; pg ! = nullptr ; pg = Group : : GetIfValid ( pg - > parent ) ) {
pg - > folded = false ;
}
this - > groups . ForceRebuild ( ) ;
this - > BuildGroupList ( this - > owner ) ;
2020-02-04 23:26:59 +01:00
this - > group_sb - > SetCount ( ( uint ) this - > groups . size ( ) ) ;
2019-05-10 18:24:16 +02:00
id_g = find_index ( this - > groups , g ) ;
}
this - > group_sb - > ScrollTowards ( id_g ) ;
}
2019-01-11 09:09:37 +01:00
this - > vehgroups . ForceRebuild ( ) ;
2019-05-10 18:24:16 +02:00
this - > SetDirty ( ) ;
}
2008-05-11 17:00:11 +02:00
} ;
2007-05-19 11:40:18 +02:00
2009-11-13 22:42:49 +01:00
static WindowDesc _other_group_desc (
2013-05-26 21:25:01 +02:00
WDP_AUTO , " list_groups " , 460 , 246 ,
2008-09-12 23:58:36 +02:00
WC_INVALID , WC_NONE ,
2012-11-11 17:10:43 +01:00
0 ,
2009-11-15 11:26:01 +01:00
_nested_group_widgets , lengthof ( _nested_group_widgets )
2009-11-13 22:42:49 +01:00
) ;
2013-05-26 21:23:42 +02:00
static WindowDesc _train_group_desc (
2013-05-26 21:25:01 +02:00
WDP_AUTO , " list_groups_train " , 525 , 246 ,
2009-11-13 22:42:49 +01:00
WC_TRAINS_LIST , WC_NONE ,
2012-11-11 17:10:43 +01:00
0 ,
2009-11-15 11:26:01 +01:00
_nested_group_widgets , lengthof ( _nested_group_widgets )
2009-03-15 16:12:06 +01:00
) ;
2007-05-19 11:40:18 +02:00
2011-05-02 19:42:12 +02:00
/**
* Show the group window for the given company and vehicle type .
* @ param company The company to show the window for .
* @ param vehicle_type The type of vehicle to show it for .
2019-05-10 19:49:50 +02:00
* @ param group The group to be selected . Defaults to INVALID_GROUP .
* @ param need_existing_window Whether the existing window is needed . Defaults to false .
2011-05-02 19:42:12 +02:00
*/
2019-05-10 19:49:50 +02:00
void ShowCompanyGroup ( CompanyID company , VehicleType vehicle_type , GroupID group = INVALID_GROUP , bool need_existing_window = false )
2007-05-19 11:40:18 +02:00
{
2009-05-17 03:00:56 +02:00
if ( ! Company : : IsValidID ( company ) ) return ;
2007-08-04 03:25:44 +02:00
2019-05-10 19:49:50 +02:00
const WindowNumber num = VehicleListIdentifier ( VL_GROUP_LIST , vehicle_type , company ) . Pack ( ) ;
VehicleGroupWindow * w ;
2009-11-13 22:42:49 +01:00
if ( vehicle_type = = VEH_TRAIN ) {
2019-05-10 19:49:50 +02:00
w = AllocateWindowDescFront < VehicleGroupWindow > ( & _train_group_desc , num , need_existing_window ) ;
2009-11-13 22:42:49 +01:00
} else {
_other_group_desc . cls = GetWindowClassForVehicleType ( vehicle_type ) ;
2019-05-10 19:49:50 +02:00
w = AllocateWindowDescFront < VehicleGroupWindow > ( & _other_group_desc , num , need_existing_window ) ;
2009-11-13 22:42:49 +01:00
}
2019-05-10 19:49:50 +02:00
if ( w ! = nullptr ) w - > SelectGroup ( group ) ;
}
/**
* Show the group window for the given vehicle .
* @ param v The vehicle to show the window for .
*/
void ShowCompanyGroupForVehicle ( const Vehicle * v )
{
ShowCompanyGroup ( v - > owner , v - > type , v - > group_id , true ) ;
2007-05-19 11:40:18 +02:00
}
2009-01-08 22:16:19 +01:00
2009-08-25 12:44:19 +02:00
/**
* Finds a group list window determined by vehicle type and owner
* @ param vt vehicle type
* @ param owner owner of groups
2019-04-10 23:07:06 +02:00
* @ return pointer to VehicleGroupWindow , nullptr if not found
2009-08-25 12:44:19 +02:00
*/
static inline VehicleGroupWindow * FindVehicleGroupWindow ( VehicleType vt , Owner owner )
{
2010-09-08 23:37:13 +02:00
return ( VehicleGroupWindow * ) FindWindowById ( GetWindowClassForVehicleType ( vt ) , VehicleListIdentifier ( VL_GROUP_LIST , vt , owner ) . Pack ( ) ) ;
2009-08-25 12:44:19 +02:00
}
/**
2018-10-28 03:17:36 +01:00
* Opens a ' Rename group ' window for newly created group .
* @ param result Did command succeed ?
* @ param tile Unused .
* @ param p1 Vehicle type .
* @ param p2 Unused .
2019-09-07 18:37:01 +02:00
* @ param cmd Unused .
2009-08-25 12:44:19 +02:00
* @ see CmdCreateGroup
*/
2019-09-07 18:37:01 +02:00
void CcCreateGroup ( const CommandCost & result , TileIndex tile , uint32 p1 , uint32 p2 , uint32 cmd )
2009-08-25 12:44:19 +02:00
{
2010-01-11 19:46:09 +01:00
if ( result . Failed ( ) ) return ;
2009-08-25 12:44:19 +02:00
assert ( p1 < = VEH_AIRCRAFT ) ;
VehicleGroupWindow * w = FindVehicleGroupWindow ( ( VehicleType ) p1 , _current_company ) ;
2019-04-10 23:07:06 +02:00
if ( w ! = nullptr ) w - > ShowRenameGroupWindow ( _new_group_id , true ) ;
2009-08-25 12:44:19 +02:00
}
2012-04-17 21:44:16 +02:00
/**
* Open rename window after adding a vehicle to a new group via drag and drop .
2018-10-28 03:17:36 +01:00
* @ param result Did command succeed ?
2012-04-17 21:44:16 +02:00
* @ param tile Unused .
* @ param p1 Unused .
* @ param p2 Bit 0 - 19 : Vehicle ID .
2019-09-07 18:37:01 +02:00
* @ param cmd Unused .
2012-04-17 21:44:16 +02:00
*/
2019-09-07 18:37:01 +02:00
void CcAddVehicleNewGroup ( const CommandCost & result , TileIndex tile , uint32 p1 , uint32 p2 , uint32 cmd )
2012-04-17 21:44:16 +02:00
{
if ( result . Failed ( ) ) return ;
assert ( Vehicle : : IsValidID ( GB ( p2 , 0 , 20 ) ) ) ;
2019-09-07 18:37:01 +02:00
CcCreateGroup ( result , 0 , Vehicle : : Get ( GB ( p2 , 0 , 20 ) ) - > type , 0 , cmd ) ;
2012-04-17 21:44:16 +02:00
}
2009-01-08 22:16:19 +01:00
/**
* Removes the highlight of a vehicle in a group window
* @ param * v Vehicle to remove all highlights from
*/
void DeleteGroupHighlightOfVehicle ( const Vehicle * v )
{
/* If we haven't got any vehicles on the mouse pointer, we haven't got any highlighted in any group windows either
* If that is the case , we can skip looping though the windows and save time
*/
if ( _special_mouse_mode ! = WSM_DRAGDROP ) return ;
2009-08-25 12:44:19 +02:00
VehicleGroupWindow * w = FindVehicleGroupWindow ( v - > type , v - > owner ) ;
2019-04-10 23:07:06 +02:00
if ( w ! = nullptr ) w - > UnselectVehicle ( v - > index ) ;
2009-01-08 22:16:19 +01:00
}