2005-07-24 14:12:37 +00:00
/* $Id$ */
2009-08-21 20:21:05 +00:00
/*
* This file is part of OpenTTD .
* OpenTTD is free software ; you can redistribute it and / or modify it under the terms of the GNU General Public License as published by the Free Software Foundation , version 2.
* OpenTTD is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
* See the GNU General Public License for more details . You should have received a copy of the GNU General Public License along with OpenTTD . If not , see < http : //www.gnu.org/licenses/>.
*/
2008-05-06 15:11:33 +00:00
/** @file industry_gui.cpp GUIs related to industries. */
2007-03-03 04:04:22 +00:00
2004-08-09 17:04:08 +00:00
# include "stdafx.h"
2011-12-10 13:54:10 +00:00
# include "error.h"
2005-02-19 14:40:32 +00:00
# include "gui.h"
2012-06-01 10:44:45 +00:00
# include "settings_gui.h"
2010-08-08 11:17:14 +00:00
# include "sound_func.h"
# include "window_func.h"
2007-12-19 20:45:46 +00:00
# include "textbuf_gui.h"
2007-12-21 21:50:46 +00:00
# include "command_func.h"
2008-01-09 09:45:45 +00:00
# include "viewport_func.h"
2004-08-09 17:04:08 +00:00
# include "industry.h"
# include "town.h"
2009-01-31 20:16:06 +00:00
# include "cheat_type.h"
2007-07-08 00:25:05 +00:00
# include "newgrf_industries.h"
# include "newgrf_text.h"
2010-04-24 13:39:11 +00:00
# include "newgrf_debug.h"
2007-12-21 19:49:27 +00:00
# include "strings_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-10 08:58:52 +00:00
# include "string_func.h"
2008-05-18 23:36:33 +00:00
# include "sortlist_type.h"
2008-05-28 16:45:00 +00:00
# include "widgets/dropdown_func.h"
2008-09-30 20:51:04 +00:00
# include "company_base.h"
2010-01-15 16:41:15 +00:00
# include "core/geometry_func.hpp"
# include "core/random_func.hpp"
2010-05-31 20:22:57 +00:00
# include "core/backup_type.hpp"
2010-07-19 17:17:36 +00:00
# include "genworld.h"
2010-08-08 11:17:14 +00:00
# include "smallmap_gui.h"
2012-11-25 15:24:02 +00:00
# include "widgets/dropdown_type.h"
2011-12-15 22:22:55 +00:00
# include "widgets/industry_widget.h"
2008-01-13 01:21:35 +00:00
# include "table/strings.h"
2007-07-10 00:59:00 +00:00
bool _ignore_restrictions ;
2010-08-08 11:17:14 +00:00
uint64 _displayed_industries ; ///< Communication from the industry chain window to the smallmap window about what industries to display.
assert_compile ( NUM_INDUSTRYTYPES < = 64 ) ; // Make sure all industry types fit in _displayed_industries.
2007-07-10 00:59:00 +00:00
2009-08-14 18:41:03 +00:00
/** Cargo suffix type (for which window is it requested) */
2008-05-05 22:37:40 +00:00
enum CargoSuffixType {
2009-08-14 18:41:03 +00:00
CST_FUND , ///< Fund-industry window
CST_VIEW , ///< View-industry window
CST_DIR , ///< Industry-directory window
2008-05-05 22:37:40 +00:00
} ;
2010-07-23 18:44:04 +00:00
static void ShowIndustryCargoesWindow ( IndustryType id ) ;
2008-03-28 02:30:10 +00:00
/**
* Gets the string to display after the cargo name ( using callback 37 )
* @ param cargo the cargo for which the suffix is requested
* - 00 - first accepted cargo type
* - 01 - second accepted cargo type
* - 02 - third accepted cargo type
* - 03 - first produced cargo type
* - 04 - second produced cargo type
2009-08-14 18:41:03 +00:00
* @ param cst the cargo suffix type ( for which window is it requested ) . @ see CargoSuffixType
2008-03-28 02:30:10 +00:00
* @ param ind the industry ( NULL if in fund window )
* @ param ind_type the industry type
* @ param indspec the industry spec
2009-10-18 15:36:30 +00:00
* @ param suffix is filled with the string to display
* @ param suffix_last lastof ( suffix )
2008-03-28 02:30:10 +00:00
*/
2009-10-18 15:36:30 +00:00
static void GetCargoSuffix ( uint cargo , CargoSuffixType cst , const Industry * ind , IndustryType ind_type , const IndustrySpec * indspec , char * suffix , const char * suffix_last )
2008-03-28 02:30:10 +00:00
{
2009-10-18 15:36:30 +00:00
suffix [ 0 ] = ' \0 ' ;
2009-09-14 12:22:57 +00:00
if ( HasBit ( indspec - > callback_mask , CBM_IND_CARGO_SUFFIX ) ) {
2010-01-04 18:21:07 +00:00
uint16 callback = GetIndustryCallback ( CBID_INDUSTRY_CARGO_SUFFIX , 0 , ( cst < < 8 ) | cargo , const_cast < Industry * > ( ind ) , ind_type , ( cst ! = CST_FUND ) ? ind - > location . tile : INVALID_TILE ) ;
2011-11-08 17:24:43 +00:00
if ( callback = = CALLBACK_FAILED | | callback = = 0x400 ) return ;
if ( callback > 0x400 ) {
ErrorUnknownCallbackResult ( indspec - > grf_prop . grffile - > grfid , CBID_INDUSTRY_CARGO_SUFFIX , callback ) ;
} else if ( indspec - > grf_prop . grffile - > grf_version > = 8 | | GB ( callback , 0 , 8 ) ! = 0xFF ) {
2011-07-03 13:49:29 +00:00
StartTextRefStackUsage ( 6 ) ;
2009-10-18 15:36:30 +00:00
GetString ( suffix , GetGRFStringID ( indspec - > grf_prop . grffile - > grfid , 0xD000 + callback ) , suffix_last ) ;
StopTextRefStackUsage ( ) ;
}
}
}
/**
2011-12-15 21:56:00 +00:00
* Gets all strings to display after the cargoes of industries ( using callback 37 )
* @ param cb_offset The offset for the cargo used in cb37 , 0 for accepted cargoes , 3 for produced cargoes
2009-10-18 15:36:30 +00:00
* @ param cst the cargo suffix type ( for which window is it requested ) . @ see CargoSuffixType
* @ param ind the industry ( NULL if in fund window )
* @ param ind_type the industry type
* @ param indspec the industry spec
2011-12-15 21:56:00 +00:00
* @ param cargoes array with cargotypes . for CT_INVALID no suffix will be determined
2009-10-18 15:36:30 +00:00
* @ param suffixes is filled with the suffixes
*/
template < typename TC , typename TS >
2011-12-15 21:56:00 +00:00
static inline void GetAllCargoSuffixes ( uint cb_offset , CargoSuffixType cst , const Industry * ind , IndustryType ind_type , const IndustrySpec * indspec , const TC & cargoes , TS & suffixes )
2009-10-18 15:36:30 +00:00
{
2011-12-15 21:56:00 +00:00
assert_compile ( lengthof ( cargoes ) < = lengthof ( suffixes ) ) ;
for ( uint j = 0 ; j < lengthof ( cargoes ) ; j + + ) {
if ( cargoes [ j ] ! = CT_INVALID ) {
2009-10-18 15:36:30 +00:00
GetCargoSuffix ( cb_offset + j , cst , ind , ind_type , indspec , suffixes [ j ] , lastof ( suffixes [ j ] ) ) ;
} else {
suffixes [ j ] [ 0 ] = ' \0 ' ;
}
2008-03-28 02:30:10 +00:00
}
}
2012-12-01 13:12:39 +00:00
IndustryType _sorted_industry_types [ NUM_INDUSTRYTYPES ] ; ///< Industry types sorted by name.
2010-03-28 12:25:09 +00:00
/** Sort industry types by their name. */
static int CDECL IndustryTypeNameSorter ( const IndustryType * a , const IndustryType * b )
{
static char industry_name [ 2 ] [ 64 ] ;
const IndustrySpec * indsp1 = GetIndustrySpec ( * a ) ;
SetDParam ( 0 , indsp1 - > name ) ;
GetString ( industry_name [ 0 ] , STR_JUST_STRING , lastof ( industry_name [ 0 ] ) ) ;
const IndustrySpec * indsp2 = GetIndustrySpec ( * b ) ;
SetDParam ( 0 , indsp2 - > name ) ;
GetString ( industry_name [ 1 ] , STR_JUST_STRING , lastof ( industry_name [ 1 ] ) ) ;
2010-11-27 22:52:12 +00:00
int r = strnatcmp ( industry_name [ 0 ] , industry_name [ 1 ] ) ; // Sort by name (natural sorting).
2010-03-28 12:25:09 +00:00
/* If the names are equal, sort by industry type. */
return ( r ! = 0 ) ? r : ( * a - * b ) ;
}
2010-08-01 19:22:34 +00:00
/**
* Initialize the list of sorted industry types .
2010-03-28 12:25:09 +00:00
*/
void SortIndustryTypes ( )
{
/* Add each industry type to the list. */
for ( IndustryType i = 0 ; i < NUM_INDUSTRYTYPES ; i + + ) {
_sorted_industry_types [ i ] = i ;
}
/* Sort industry types by name. */
QSortT ( _sorted_industry_types , NUM_INDUSTRYTYPES , & IndustryTypeNameSorter ) ;
}
2010-08-01 19:22:34 +00:00
/**
* Command callback . In case of failure to build an industry , show an error message .
2010-03-14 19:59:45 +00:00
* @ param result Result of the command .
* @ param tile Tile where the industry is placed .
* @ param p1 Additional data of the # CMD_BUILD_INDUSTRY command .
* @ param p2 Additional data of the # CMD_BUILD_INDUSTRY command .
*/
void CcBuildIndustry ( const CommandCost & result , TileIndex tile , uint32 p1 , uint32 p2 )
{
if ( result . Succeeded ( ) ) return ;
uint8 indtype = GB ( p1 , 0 , 8 ) ;
if ( indtype < NUM_INDUSTRYTYPES ) {
const IndustrySpec * indsp = GetIndustrySpec ( indtype ) ;
if ( indsp - > enabled ) {
SetDParam ( 0 , indsp - > name ) ;
ShowErrorMessage ( STR_ERROR_CAN_T_BUILD_HERE , result . GetErrorMessage ( ) , WL_INFO , TileX ( tile ) * TILE_SIZE , TileY ( tile ) * TILE_SIZE ) ;
}
}
}
2009-03-28 19:08:55 +00:00
static const NWidgetPart _nested_build_industry_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_DARK_GREEN ) ,
NWidget ( WWT_CAPTION , COLOUR_DARK_GREEN ) , SetDataTip ( STR_FUND_INDUSTRY_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2009-12-21 16:24:29 +00:00
NWidget ( WWT_SHADEBOX , COLOUR_DARK_GREEN ) ,
2009-12-09 17:10:57 +00:00
NWidget ( WWT_STICKYBOX , COLOUR_DARK_GREEN ) ,
2009-03-28 19:08:55 +00:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 16:39:48 +00:00
NWidget ( WWT_MATRIX , COLOUR_DARK_GREEN , WID_DPI_MATRIX_WIDGET ) , SetDataTip ( 0x801 , STR_FUND_INDUSTRY_SELECTION_TOOLTIP ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 1 ) , SetScrollbar ( WID_DPI_SCROLLBAR ) ,
NWidget ( NWID_VSCROLLBAR , COLOUR_DARK_GREEN , WID_DPI_SCROLLBAR ) ,
2009-03-28 19:08:55 +00:00
EndContainer ( ) ,
2011-12-16 16:39:48 +00:00
NWidget ( WWT_PANEL , COLOUR_DARK_GREEN , WID_DPI_INFOPANEL ) , SetResize ( 1 , 0 ) ,
2009-03-28 19:08:55 +00:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 16:39:48 +00:00
NWidget ( WWT_TEXTBTN , COLOUR_DARK_GREEN , WID_DPI_DISPLAY_WIDGET ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) ,
2010-07-23 18:46:52 +00:00
SetDataTip ( STR_INDUSTRY_DISPLAY_CHAIN , STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP ) ,
2011-12-16 16:39:48 +00:00
NWidget ( WWT_TEXTBTN , COLOUR_DARK_GREEN , WID_DPI_FUND_WIDGET ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) , SetDataTip ( STR_JUST_STRING , STR_NULL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_RESIZEBOX , COLOUR_DARK_GREEN ) ,
2009-03-28 19:08:55 +00:00
EndContainer ( ) ,
} ;
2008-05-10 23:43:08 +00:00
/** Window definition of the dynamic place industries gui */
2009-03-15 15:12:06 +00:00
static const WindowDesc _build_industry_desc (
2009-11-28 14:42:35 +00:00
WDP_AUTO , 170 , 212 ,
2008-05-10 23:43:08 +00:00
WC_BUILD_INDUSTRY , WC_NONE ,
2009-11-24 17:28:29 +00:00
WDF_CONSTRUCTION ,
2009-11-15 10:26:01 +00:00
_nested_build_industry_widgets , lengthof ( _nested_build_industry_widgets )
2009-03-15 15:12:06 +00:00
) ;
2008-02-03 12:41:06 +00:00
2009-10-20 20:06:25 +00:00
/** Build (fund or prospect) a new industry, */
2008-05-10 23:43:08 +00:00
class BuildIndustryWindow : public Window {
int selected_index ; ///< index of the element in the matrix
IndustryType selected_type ; ///< industry corresponding to the above index
uint16 callback_timer ; ///< timer counter for callback eventual verification
bool timer_enabled ; ///< timer can be used
uint16 count ; ///< How many industries are loaded
IndustryType index [ NUM_INDUSTRYTYPES + 1 ] ; ///< Type of industry, in the order it was loaded
2011-11-08 17:26:13 +00:00
bool enabled [ NUM_INDUSTRYTYPES + 1 ] ; ///< availability state, coming from CBID_INDUSTRY_PROBABILITY (if ever)
2010-08-12 08:37:01 +00:00
Scrollbar * vscroll ;
2007-07-10 00:59:00 +00:00
2009-10-24 19:36:24 +00:00
/** The offset for the text in the matrix. */
static const int MATRIX_TEXT_OFFSET = 17 ;
2008-05-12 14:54:33 +00:00
void SetupArrays ( )
2008-05-10 23:43:08 +00:00
{
this - > count = 0 ;
for ( uint i = 0 ; i < lengthof ( this - > index ) ; i + + ) {
2008-05-12 14:54:33 +00:00
this - > index [ i ] = INVALID_INDUSTRYTYPE ;
2008-05-10 23:43:08 +00:00
this - > enabled [ i ] = false ;
}
if ( _game_mode = = GM_EDITOR ) { // give room for the Many Random "button"
this - > index [ this - > count ] = INVALID_INDUSTRYTYPE ;
2010-02-20 21:21:54 +00:00
this - > enabled [ this - > count ] = true ;
2008-05-10 23:43:08 +00:00
this - > count + + ;
this - > timer_enabled = false ;
}
2008-05-12 14:54:33 +00:00
/* Fill the arrays with industries.
2008-05-10 23:43:08 +00:00
* The tests performed after the enabled allow to load the industries
* In the same way they are inserted by grf ( if any )
*/
2010-03-28 12:29:41 +00:00
for ( uint8 i = 0 ; i < NUM_INDUSTRYTYPES ; i + + ) {
IndustryType ind = _sorted_industry_types [ i ] ;
2009-10-20 20:06:25 +00:00
const IndustrySpec * indsp = GetIndustrySpec ( ind ) ;
2009-08-14 17:11:59 +00:00
if ( indsp - > enabled ) {
2008-05-10 23:43:08 +00:00
/* Rule is that editor mode loads all industries.
* In game mode , all non raw industries are loaded too
* and raw ones are loaded only when setting allows it */
2008-05-29 15:13:28 +00:00
if ( _game_mode ! = GM_EDITOR & & indsp - > IsRawIndustry ( ) & & _settings_game . construction . raw_industry_construction = = 0 ) {
2008-05-12 14:54:33 +00:00
/* Unselect if the industry is no longer in the list */
if ( this - > selected_type = = ind ) this - > selected_index = - 1 ;
continue ;
}
2008-05-10 23:43:08 +00:00
this - > index [ this - > count ] = ind ;
2011-11-08 17:26:13 +00:00
this - > enabled [ this - > count ] = ( _game_mode = = GM_EDITOR ) | | GetIndustryProbabilityCallback ( ind , IACT_USERCREATION , 1 ) > 0 ;
2008-05-12 14:54:33 +00:00
/* Keep the selection to the correct line */
if ( this - > selected_type = = ind ) this - > selected_index = this - > count ;
2008-05-10 23:43:08 +00:00
this - > count + + ;
2007-07-10 00:59:00 +00:00
}
2008-05-10 23:43:08 +00:00
}
2007-07-10 00:59:00 +00:00
2013-01-08 22:46:42 +00:00
/* first industry type is selected if the current selection is invalid.
2008-05-10 23:43:08 +00:00
* I ' ll be damned if there are none available ; ) */
2008-05-12 14:54:33 +00:00
if ( this - > selected_index = = - 1 ) {
this - > selected_index = 0 ;
this - > selected_type = this - > index [ 0 ] ;
}
2009-10-24 19:36:24 +00:00
2010-08-12 08:37:01 +00:00
this - > vscroll - > SetCount ( this - > count ) ;
2008-05-12 14:54:33 +00:00
}
2010-08-06 12:12:20 +00:00
/** Update status of the fund and display-chain widgets. */
void SetButtons ( )
{
2011-12-16 16:39:48 +00:00
this - > SetWidgetDisabledState ( WID_DPI_FUND_WIDGET , this - > selected_type ! = INVALID_INDUSTRYTYPE & & ! this - > enabled [ this - > selected_index ] ) ;
this - > SetWidgetDisabledState ( WID_DPI_DISPLAY_WIDGET , this - > selected_type = = INVALID_INDUSTRYTYPE & & this - > enabled [ this - > selected_index ] ) ;
2010-08-06 12:12:20 +00:00
}
2008-05-12 14:54:33 +00:00
public :
2009-10-24 19:36:24 +00:00
BuildIndustryWindow ( ) : Window ( )
2008-05-12 14:54:33 +00:00
{
this - > timer_enabled = _loaded_newgrf_features . has_newindustries ;
this - > selected_index = - 1 ;
this - > selected_type = INVALID_INDUSTRYTYPE ;
2008-05-10 23:43:08 +00:00
this - > callback_timer = DAY_TICKS ;
2008-05-11 11:41:18 +00:00
2010-08-12 08:37:01 +00:00
this - > CreateNestedTree ( & _build_industry_desc ) ;
2011-12-16 16:39:48 +00:00
this - > vscroll = this - > GetScrollbar ( WID_DPI_SCROLLBAR ) ;
2010-08-12 08:37:01 +00:00
this - > FinishInitNested ( & _build_industry_desc , 0 ) ;
2010-08-06 12:19:01 +00:00
this - > SetButtons ( ) ;
2008-05-10 23:43:08 +00:00
}
2007-07-10 00:59:00 +00:00
2010-03-28 12:29:41 +00:00
virtual void OnInit ( )
{
this - > SetupArrays ( ) ;
}
2009-11-22 18:28:14 +00:00
virtual void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize )
2008-05-10 23:43:08 +00:00
{
2009-10-24 19:36:24 +00:00
switch ( widget ) {
2011-12-16 16:39:48 +00:00
case WID_DPI_MATRIX_WIDGET : {
2009-10-24 19:36:24 +00:00
Dimension d = GetStringBoundingBox ( STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES ) ;
for ( byte i = 0 ; i < this - > count ; i + + ) {
if ( this - > index [ i ] = = INVALID_INDUSTRYTYPE ) continue ;
d = maxdim ( d , GetStringBoundingBox ( GetIndustrySpec ( this - > index [ i ] ) - > name ) ) ;
}
resize - > height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM ;
d . width + = MATRIX_TEXT_OFFSET + padding . width ;
d . height = 5 * resize - > height ;
* size = maxdim ( * size , d ) ;
break ;
}
2008-05-10 23:43:08 +00:00
2011-12-16 16:39:48 +00:00
case WID_DPI_INFOPANEL : {
2009-10-24 19:36:24 +00:00
/* Extra line for cost outside of editor + extra lines for 'extra' information for NewGRFs. */
int height = 2 + ( _game_mode = = GM_EDITOR ? 0 : 1 ) + ( _loaded_newgrf_features . has_newindustries ? 4 : 0 ) ;
Dimension d = { 0 , 0 } ;
for ( byte i = 0 ; i < this - > count ; i + + ) {
if ( this - > index [ i ] = = INVALID_INDUSTRYTYPE ) continue ;
const IndustrySpec * indsp = GetIndustrySpec ( this - > index [ i ] ) ;
char cargo_suffix [ 3 ] [ 512 ] ;
2009-12-15 22:39:58 +00:00
GetAllCargoSuffixes ( 0 , CST_FUND , NULL , this - > index [ i ] , indsp , indsp - > accepts_cargo , cargo_suffix ) ;
2009-10-24 19:36:24 +00:00
StringID str = STR_INDUSTRY_VIEW_REQUIRES_CARGO ;
byte p = 0 ;
SetDParam ( 0 , STR_JUST_NOTHING ) ;
SetDParamStr ( 1 , " " ) ;
for ( byte j = 0 ; j < lengthof ( indsp - > accepts_cargo ) ; j + + ) {
if ( indsp - > accepts_cargo [ j ] = = CT_INVALID ) continue ;
if ( p > 0 ) str + + ;
SetDParam ( p + + , CargoSpec : : Get ( indsp - > accepts_cargo [ j ] ) - > name ) ;
SetDParamStr ( p + + , cargo_suffix [ j ] ) ;
}
d = maxdim ( d , GetStringBoundingBox ( str ) ) ;
2010-08-15 14:06:43 +00:00
/* Draw the produced cargoes, if any. Otherwise, will print "Nothing". */
2009-12-15 22:39:58 +00:00
GetAllCargoSuffixes ( 3 , CST_FUND , NULL , this - > index [ i ] , indsp , indsp - > produced_cargo , cargo_suffix ) ;
2009-10-24 19:36:24 +00:00
str = STR_INDUSTRY_VIEW_PRODUCES_CARGO ;
p = 0 ;
SetDParam ( 0 , STR_JUST_NOTHING ) ;
SetDParamStr ( 1 , " " ) ;
for ( byte j = 0 ; j < lengthof ( indsp - > produced_cargo ) ; j + + ) {
if ( indsp - > produced_cargo [ j ] = = CT_INVALID ) continue ;
if ( p > 0 ) str + + ;
SetDParam ( p + + , CargoSpec : : Get ( indsp - > produced_cargo [ j ] ) - > name ) ;
SetDParamStr ( p + + , cargo_suffix [ j ] ) ;
}
d = maxdim ( d , GetStringBoundingBox ( str ) ) ;
}
2008-05-10 23:43:08 +00:00
2009-10-24 19:36:24 +00:00
/* Set it to something more sane :) */
size - > height = height * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM ;
size - > width = d . width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT ;
2010-08-01 18:53:30 +00:00
break ;
}
2008-05-10 23:43:08 +00:00
2011-12-16 16:39:48 +00:00
case WID_DPI_FUND_WIDGET : {
2009-10-24 19:36:24 +00:00
Dimension d = GetStringBoundingBox ( STR_FUND_INDUSTRY_BUILD_NEW_INDUSTRY ) ;
d = maxdim ( d , GetStringBoundingBox ( STR_FUND_INDUSTRY_PROSPECT_NEW_INDUSTRY ) ) ;
d = maxdim ( d , GetStringBoundingBox ( STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY ) ) ;
d . width + = padding . width ;
d . height + = padding . height ;
* size = maxdim ( * size , d ) ;
break ;
2007-07-10 00:59:00 +00:00
}
2008-05-10 23:43:08 +00:00
}
2009-10-24 19:36:24 +00:00
}
2008-05-10 23:43:08 +00:00
2009-10-24 19:36:24 +00:00
virtual void SetStringParameters ( int widget ) const
{
switch ( widget ) {
2011-12-16 16:39:48 +00:00
case WID_DPI_FUND_WIDGET :
2009-10-24 19:36:24 +00:00
/* Raw industries might be prospected. Show this fact by changing the string
* In Editor , you just build , while ingame , or you fund or you prospect */
if ( _game_mode = = GM_EDITOR ) {
/* We've chosen many random industries but no industries have been specified */
SetDParam ( 0 , STR_FUND_INDUSTRY_BUILD_NEW_INDUSTRY ) ;
} else {
const IndustrySpec * indsp = GetIndustrySpec ( this - > index [ this - > selected_index ] ) ;
SetDParam ( 0 , ( _settings_game . construction . raw_industry_construction = = 2 & & indsp - > IsRawIndustry ( ) ) ? STR_FUND_INDUSTRY_PROSPECT_NEW_INDUSTRY : STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY ) ;
}
break ;
2008-05-10 23:43:08 +00:00
}
2009-10-24 19:36:24 +00:00
}
2008-05-10 23:43:08 +00:00
2009-10-24 19:36:24 +00:00
virtual void DrawWidget ( const Rect & r , int widget ) const
{
switch ( widget ) {
2011-12-16 16:39:48 +00:00
case WID_DPI_MATRIX_WIDGET :
2010-08-12 08:37:01 +00:00
for ( byte i = 0 ; i < this - > vscroll - > GetCapacity ( ) & & i + this - > vscroll - > GetPosition ( ) < this - > count ; i + + ) {
2009-10-24 19:36:24 +00:00
int x = r . left + WD_MATRIX_LEFT ;
int y = r . top + WD_MATRIX_TOP + i * this - > resize . step_height ;
2010-08-12 08:37:01 +00:00
bool selected = this - > selected_index = = i + this - > vscroll - > GetPosition ( ) ;
2009-10-24 19:36:24 +00:00
2010-08-12 08:37:01 +00:00
if ( this - > index [ i + this - > vscroll - > GetPosition ( ) ] = = INVALID_INDUSTRYTYPE ) {
2009-10-24 19:36:24 +00:00
DrawString ( x + MATRIX_TEXT_OFFSET , r . right - WD_MATRIX_RIGHT , y , STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES , selected ? TC_WHITE : TC_ORANGE ) ;
continue ;
}
2010-08-12 08:37:01 +00:00
const IndustrySpec * indsp = GetIndustrySpec ( this - > index [ i + this - > vscroll - > GetPosition ( ) ] ) ;
2008-05-10 23:43:08 +00:00
2009-10-24 19:36:24 +00:00
/* Draw the name of the industry in white is selected, otherwise, in orange */
DrawString ( x + MATRIX_TEXT_OFFSET , r . right - WD_MATRIX_RIGHT , y , indsp - > name , selected ? TC_WHITE : TC_ORANGE ) ;
2011-05-06 21:13:29 +00:00
GfxFillRect ( x , y + 1 , x + 10 , y + 7 , selected ? PC_WHITE : PC_BLACK ) ;
2009-10-24 19:36:24 +00:00
GfxFillRect ( x + 1 , y + 2 , x + 9 , y + 6 , indsp - > map_colour ) ;
}
break ;
2011-12-16 16:39:48 +00:00
case WID_DPI_INFOPANEL : {
2009-10-24 19:36:24 +00:00
int y = r . top + WD_FRAMERECT_TOP ;
int bottom = r . bottom - WD_FRAMERECT_BOTTOM ;
int left = r . left + WD_FRAMERECT_LEFT ;
int right = r . right - WD_FRAMERECT_RIGHT ;
if ( this - > selected_type = = INVALID_INDUSTRYTYPE ) {
DrawStringMultiLine ( left , right , y , bottom , STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP ) ;
break ;
}
const IndustrySpec * indsp = GetIndustrySpec ( this - > selected_type ) ;
if ( _game_mode ! = GM_EDITOR ) {
SetDParam ( 0 , indsp - > GetConstructionCost ( ) ) ;
DrawString ( left , right , y , STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST ) ;
y + = FONT_HEIGHT_NORMAL ;
2007-07-10 00:59:00 +00:00
}
2008-05-10 23:43:08 +00:00
2010-08-15 14:06:43 +00:00
/* Draw the accepted cargoes, if any. Otherwise, will print "Nothing". */
2009-10-24 19:36:24 +00:00
char cargo_suffix [ 3 ] [ 512 ] ;
GetAllCargoSuffixes ( 0 , CST_FUND , NULL , this - > selected_type , indsp , indsp - > accepts_cargo , cargo_suffix ) ;
StringID str = STR_INDUSTRY_VIEW_REQUIRES_CARGO ;
byte p = 0 ;
SetDParam ( 0 , STR_JUST_NOTHING ) ;
SetDParamStr ( 1 , " " ) ;
for ( byte j = 0 ; j < lengthof ( indsp - > accepts_cargo ) ; j + + ) {
if ( indsp - > accepts_cargo [ j ] = = CT_INVALID ) continue ;
if ( p > 0 ) str + + ;
SetDParam ( p + + , CargoSpec : : Get ( indsp - > accepts_cargo [ j ] ) - > name ) ;
SetDParamStr ( p + + , cargo_suffix [ j ] ) ;
}
DrawString ( left , right , y , str ) ;
y + = FONT_HEIGHT_NORMAL ;
2010-08-15 14:06:43 +00:00
/* Draw the produced cargoes, if any. Otherwise, will print "Nothing". */
2009-10-24 19:36:24 +00:00
GetAllCargoSuffixes ( 3 , CST_FUND , NULL , this - > selected_type , indsp , indsp - > produced_cargo , cargo_suffix ) ;
str = STR_INDUSTRY_VIEW_PRODUCES_CARGO ;
p = 0 ;
SetDParam ( 0 , STR_JUST_NOTHING ) ;
SetDParamStr ( 1 , " " ) ;
for ( byte j = 0 ; j < lengthof ( indsp - > produced_cargo ) ; j + + ) {
if ( indsp - > produced_cargo [ j ] = = CT_INVALID ) continue ;
if ( p > 0 ) str + + ;
SetDParam ( p + + , CargoSpec : : Get ( indsp - > produced_cargo [ j ] ) - > name ) ;
SetDParamStr ( p + + , cargo_suffix [ j ] ) ;
}
DrawString ( left , right , y , str ) ;
y + = FONT_HEIGHT_NORMAL ;
/* Get the additional purchase info text, if it has not already been queried. */
str = STR_NULL ;
if ( HasBit ( indsp - > callback_mask , CBM_IND_FUND_MORE_TEXT ) ) {
uint16 callback_res = GetIndustryCallback ( CBID_INDUSTRY_FUND_MORE_TEXT , 0 , 0 , NULL , this - > selected_type , INVALID_TILE ) ;
2011-11-08 17:24:43 +00:00
if ( callback_res ! = CALLBACK_FAILED & & callback_res ! = 0x400 ) {
if ( callback_res > 0x400 ) {
ErrorUnknownCallbackResult ( indsp - > grf_prop . grffile - > grfid , CBID_INDUSTRY_FUND_MORE_TEXT , callback_res ) ;
} else {
str = GetGRFStringID ( indsp - > grf_prop . grffile - > grfid , 0xD000 + callback_res ) ; // No. here's the new string
if ( str ! = STR_UNDEFINED ) {
StartTextRefStackUsage ( 6 ) ;
DrawStringMultiLine ( left , right , y , bottom , str , TC_YELLOW ) ;
StopTextRefStackUsage ( ) ;
}
2010-07-07 20:00:04 +00:00
}
2009-10-24 19:36:24 +00:00
}
}
2010-08-01 18:53:30 +00:00
break ;
}
2008-05-10 23:43:08 +00:00
}
}
2007-07-10 00:59:00 +00:00
2010-01-30 18:34:48 +00:00
virtual void OnClick ( Point pt , int widget , int click_count )
2008-05-10 23:43:08 +00:00
{
switch ( widget ) {
2011-12-16 16:39:48 +00:00
case WID_DPI_MATRIX_WIDGET : {
int y = this - > vscroll - > GetScrolledRowFromWidget ( pt . y , this , WID_DPI_MATRIX_WIDGET ) ;
2010-07-26 13:08:48 +00:00
if ( y < this - > count ) { // Is it within the boundaries of available data?
2008-05-10 23:43:08 +00:00
this - > selected_index = y ;
this - > selected_type = this - > index [ y ] ;
2010-07-30 10:39:24 +00:00
const IndustrySpec * indsp = ( this - > selected_type = = INVALID_INDUSTRYTYPE ) ? NULL : GetIndustrySpec ( this - > selected_type ) ;
2008-05-10 23:43:08 +00:00
this - > SetDirty ( ) ;
2010-12-30 13:16:31 +00:00
if ( _thd . GetCallbackWnd ( ) = = this & &
2010-04-23 21:47:03 +00:00
( ( _game_mode ! = GM_EDITOR & & _settings_game . construction . raw_industry_construction = = 2 & & indsp ! = NULL & & indsp - > IsRawIndustry ( ) ) | |
this - > selected_type = = INVALID_INDUSTRYTYPE | |
! this - > enabled [ this - > selected_index ] ) ) {
2008-05-10 23:43:08 +00:00
/* Reset the button state if going to prospecting or "build many industries" */
this - > RaiseButtons ( ) ;
ResetObjectToPlace ( ) ;
2007-07-10 00:59:00 +00:00
}
2009-10-24 19:36:24 +00:00
2010-08-06 12:12:20 +00:00
this - > SetButtons ( ) ;
2011-12-16 16:39:48 +00:00
if ( this - > enabled [ this - > selected_index ] & & click_count > 1 ) this - > OnClick ( pt , WID_DPI_FUND_WIDGET , 1 ) ;
2007-07-10 00:59:00 +00:00
}
2010-08-01 18:53:30 +00:00
break ;
}
2007-07-10 00:59:00 +00:00
2011-12-16 16:39:48 +00:00
case WID_DPI_DISPLAY_WIDGET :
2010-07-23 18:46:52 +00:00
if ( this - > selected_type ! = INVALID_INDUSTRYTYPE ) ShowIndustryCargoesWindow ( this - > selected_type ) ;
break ;
2011-12-16 16:39:48 +00:00
case WID_DPI_FUND_WIDGET : {
2008-05-10 23:43:08 +00:00
if ( this - > selected_type = = INVALID_INDUSTRYTYPE ) {
2011-12-16 16:39:48 +00:00
this - > HandleButtonClick ( WID_DPI_FUND_WIDGET ) ;
2008-05-10 23:43:08 +00:00
2009-05-22 15:23:47 +00:00
if ( Town : : GetNumItems ( ) = = 0 ) {
2010-02-24 14:46:15 +00:00
ShowErrorMessage ( STR_ERROR_CAN_T_GENERATE_INDUSTRIES , STR_ERROR_MUST_FOUND_TOWN_FIRST , WL_INFO ) ;
2007-07-19 01:35:48 +00:00
} else {
2008-05-10 23:43:08 +00:00
extern void GenerateIndustries ( ) ;
_generating_world = true ;
GenerateIndustries ( ) ;
_generating_world = false ;
2007-07-10 00:59:00 +00:00
}
2008-05-29 15:13:28 +00:00
} else if ( _game_mode ! = GM_EDITOR & & _settings_game . construction . raw_industry_construction = = 2 & & GetIndustrySpec ( this - > selected_type ) - > IsRawIndustry ( ) ) {
2009-04-21 23:40:56 +00:00
DoCommandP ( 0 , this - > selected_type , InteractiveRandom ( ) , CMD_BUILD_INDUSTRY | CMD_MSG ( STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY ) ) ;
2011-12-16 16:39:48 +00:00
this - > HandleButtonClick ( WID_DPI_FUND_WIDGET ) ;
2008-05-10 23:43:08 +00:00
} else {
2011-12-16 16:39:48 +00:00
HandlePlacePushButton ( this , WID_DPI_FUND_WIDGET , SPR_CURSOR_INDUSTRY , HT_RECT ) ;
2007-07-16 23:48:25 +00:00
}
2010-08-01 18:53:30 +00:00
break ;
}
2008-05-10 23:43:08 +00:00
}
}
2007-07-16 23:48:25 +00:00
2009-10-24 14:53:55 +00:00
virtual void OnResize ( )
2008-05-10 23:43:08 +00:00
{
2009-10-24 19:36:24 +00:00
/* Adjust the number of items in the matrix depending of the resize */
2011-12-16 16:39:48 +00:00
this - > vscroll - > SetCapacityFromWidget ( this , WID_DPI_MATRIX_WIDGET ) ;
this - > GetWidget < NWidgetCore > ( WID_DPI_MATRIX_WIDGET ) - > widget_data = ( this - > vscroll - > GetCapacity ( ) < < MAT_ROW_START ) + ( 1 < < MAT_COL_START ) ;
2008-05-10 23:43:08 +00:00
}
2007-07-19 01:35:48 +00:00
2008-05-10 23:43:08 +00:00
virtual void OnPlaceObject ( Point pt , TileIndex tile )
{
bool success = true ;
/* We do not need to protect ourselves against "Random Many Industries" in this mode */
const IndustrySpec * indsp = GetIndustrySpec ( this - > selected_type ) ;
uint32 seed = InteractiveRandom ( ) ;
if ( _game_mode = = GM_EDITOR ) {
/* Show error if no town exists at all */
2009-05-22 15:23:47 +00:00
if ( Town : : GetNumItems ( ) = = 0 ) {
2008-05-10 23:43:08 +00:00
SetDParam ( 0 , indsp - > name ) ;
2010-02-24 14:46:15 +00:00
ShowErrorMessage ( STR_ERROR_CAN_T_BUILD_HERE , STR_ERROR_MUST_FOUND_TOWN_FIRST , WL_INFO , pt . x , pt . y ) ;
2008-05-10 23:43:08 +00:00
return ;
2007-10-17 14:54:18 +00:00
}
2007-07-19 01:35:48 +00:00
2010-06-05 12:16:12 +00:00
Backup < CompanyByte > cur_company ( _current_company , OWNER_NONE , FILE_LINE ) ;
2008-05-10 23:43:08 +00:00
_generating_world = true ;
_ignore_restrictions = true ;
2010-05-31 20:22:57 +00:00
2010-03-14 19:59:45 +00:00
DoCommandP ( tile , ( InteractiveRandomRange ( indsp - > num_table ) < < 8 ) | this - > selected_type , seed ,
CMD_BUILD_INDUSTRY | CMD_MSG ( STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY ) , & CcBuildIndustry ) ;
2007-07-16 23:48:25 +00:00
2010-05-31 20:22:57 +00:00
cur_company . Restore ( ) ;
2008-05-10 23:43:08 +00:00
_ignore_restrictions = false ;
_generating_world = false ;
} else {
2009-09-04 20:04:54 +00:00
success = DoCommandP ( tile , ( InteractiveRandomRange ( indsp - > num_table ) < < 8 ) | this - > selected_type , seed , CMD_BUILD_INDUSTRY | CMD_MSG ( STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY ) ) ;
2008-05-10 23:43:08 +00:00
}
2007-07-19 01:47:32 +00:00
2008-05-10 23:43:08 +00:00
/* If an industry has been built, just reset the cursor and the system */
2009-01-07 17:40:17 +00:00
if ( success & & ! _settings_client . gui . persistent_buildingtools ) ResetObjectToPlace ( ) ;
2008-05-10 23:43:08 +00:00
}
2007-07-19 01:47:32 +00:00
2008-05-10 23:43:08 +00:00
virtual void OnTick ( )
{
2009-05-06 15:06:57 +00:00
if ( _pause_mode ! = PM_UNPAUSED ) return ;
2008-05-10 23:43:08 +00:00
if ( ! this - > timer_enabled ) return ;
if ( - - this - > callback_timer = = 0 ) {
/* We have just passed another day.
* See if we need to update availability of currently selected industry */
2009-03-15 00:32:18 +00:00
this - > callback_timer = DAY_TICKS ; // restart counter
2007-07-19 01:47:32 +00:00
2008-05-10 23:43:08 +00:00
const IndustrySpec * indsp = GetIndustrySpec ( this - > selected_type ) ;
if ( indsp - > enabled ) {
2011-11-08 17:26:13 +00:00
bool call_back_result = GetIndustryProbabilityCallback ( this - > selected_type , IACT_USERCREATION , 1 ) > 0 ;
2008-05-10 23:43:08 +00:00
/* Only if result does match the previous state would it require a redraw. */
if ( call_back_result ! = this - > enabled [ this - > selected_index ] ) {
this - > enabled [ this - > selected_index ] = call_back_result ;
2010-08-06 12:12:20 +00:00
this - > SetButtons ( ) ;
2008-05-10 23:43:08 +00:00
this - > SetDirty ( ) ;
2007-07-19 01:47:32 +00:00
}
}
2008-05-10 23:43:08 +00:00
}
2004-08-09 17:04:08 +00:00
}
2008-05-10 23:43:08 +00:00
virtual void OnTimeout ( )
{
this - > RaiseButtons ( ) ;
}
2004-08-09 17:04:08 +00:00
2008-05-10 23:43:08 +00:00
virtual void OnPlaceObjectAbort ( )
{
this - > RaiseButtons ( ) ;
}
2008-05-12 14:54:33 +00:00
2011-03-13 21:31:29 +00:00
/**
* Some data on this window has become invalid .
* @ param data Information about the changed data .
* @ param gui_scope Whether the call is done from GUI scope . You may not do everything when not in GUI scope . See # InvalidateWindowData ( ) for details .
*/
virtual void OnInvalidateData ( int data = 0 , bool gui_scope = true )
2008-05-12 14:54:33 +00:00
{
2011-03-13 21:31:29 +00:00
if ( ! gui_scope ) return ;
2008-05-12 14:54:33 +00:00
this - > SetupArrays ( ) ;
2009-10-24 19:36:24 +00:00
const IndustrySpec * indsp = ( this - > selected_type = = INVALID_INDUSTRYTYPE ) ? NULL : GetIndustrySpec ( this - > selected_type ) ;
2011-02-06 18:26:50 +00:00
if ( indsp = = NULL ) this - > enabled [ this - > selected_index ] = _settings_game . difficulty . industry_density ! = ID_FUND_ONLY ;
2010-08-06 12:12:20 +00:00
this - > SetButtons ( ) ;
2008-05-12 14:54:33 +00:00
}
2004-08-09 17:04:08 +00:00
} ;
2007-03-07 11:47:46 +00:00
void ShowBuildIndustryWindow ( )
2004-09-10 19:02:27 +00:00
{
2009-05-17 01:00:56 +00:00
if ( _game_mode ! = GM_EDITOR & & ! Company : : IsValidID ( _local_company ) ) return ;
2008-05-10 23:43:08 +00:00
if ( BringWindowToFrontById ( WC_BUILD_INDUSTRY , 0 ) ) return ;
new BuildIndustryWindow ( ) ;
2004-08-09 17:04:08 +00:00
}
2007-07-10 00:59:00 +00:00
static void UpdateIndustryProduction ( Industry * i ) ;
2006-07-30 14:56:40 +00:00
static inline bool IsProductionAlterable ( const Industry * i )
{
2010-10-04 20:20:50 +00:00
const IndustrySpec * is = GetIndustrySpec ( i - > type ) ;
2006-07-30 14:56:40 +00:00
return ( ( _game_mode = = GM_EDITOR | | _cheats . setup_prod . value ) & &
2010-10-04 20:20:50 +00:00
( is - > production_rate [ 0 ] ! = 0 | | is - > production_rate [ 1 ] ! = 0 | | is - > IsRawIndustry ( ) ) ) ;
2006-07-30 14:56:40 +00:00
}
2008-05-11 17:44:56 +00:00
class IndustryViewWindow : public Window
{
2010-10-04 19:35:40 +00:00
/** Modes for changing production */
enum Editability {
EA_NONE , ///< Not alterable
2010-10-04 20:12:38 +00:00
EA_MULTIPLIER , ///< Allow changing the production multiplier
2010-10-04 19:35:40 +00:00
EA_RATE , ///< Allow changing the production rates
} ;
2010-10-04 19:14:43 +00:00
/** Specific lines in the info panel */
enum InfoLine {
IL_NONE , ///< No line
2010-10-04 20:12:38 +00:00
IL_MULTIPLIER , ///< Production multiplier
2010-10-04 19:14:43 +00:00
IL_RATE1 , ///< Production rate of cargo 1
IL_RATE2 , ///< Production rate of cargo 2
} ;
2010-10-04 19:35:40 +00:00
Editability editable ; ///< Mode for changing production
2010-10-04 19:14:43 +00:00
InfoLine editbox_line ; ///< The line clicked to open the edit box
InfoLine clicked_line ; ///< The line of the button that has been clicked
2007-07-19 16:24:48 +00:00
byte clicked_button ; ///< The button that has been clicked (to raise)
2010-10-03 15:49:44 +00:00
int production_offset_y ; ///< The offset of the production texts/buttons
2011-12-16 16:39:48 +00:00
int info_height ; ///< Height needed for the #WID_IV_INFO panel
2007-07-19 16:24:48 +00:00
2008-05-11 17:44:56 +00:00
public :
2009-10-18 14:10:59 +00:00
IndustryViewWindow ( const WindowDesc * desc , WindowNumber window_number ) : Window ( )
2008-05-11 17:44:56 +00:00
{
2011-12-15 19:54:23 +00:00
this - > flags | = WF_DISABLE_VP_SCROLL ;
2010-10-04 19:14:43 +00:00
this - > editbox_line = IL_NONE ;
this - > clicked_line = IL_NONE ;
2008-05-11 17:44:56 +00:00
this - > clicked_button = 0 ;
2009-10-18 14:10:59 +00:00
this - > info_height = WD_FRAMERECT_TOP + 2 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM + 1 ; // Info panel has at least two lines text.
this - > InitNested ( desc , window_number ) ;
2011-12-16 16:39:48 +00:00
NWidgetViewport * nvp = this - > GetWidget < NWidgetViewport > ( WID_IV_VIEWPORT ) ;
2010-10-23 20:34:12 +00:00
nvp - > InitializeViewport ( this , Industry : : Get ( window_number ) - > location . GetCenterTile ( ) , ZOOM_LVL_INDUSTRY ) ;
2010-10-04 19:35:40 +00:00
this - > InvalidateData ( ) ;
2009-10-18 14:10:59 +00:00
}
virtual void OnPaint ( )
{
this - > DrawWidgets ( ) ;
2009-12-21 16:24:29 +00:00
if ( this - > IsShaded ( ) ) return ; // Don't draw anything when the window is shaded.
2011-12-16 16:39:48 +00:00
NWidgetBase * nwi = this - > GetWidget < NWidgetBase > ( WID_IV_INFO ) ;
2009-10-18 14:10:59 +00:00
uint expected = this - > DrawInfo ( nwi - > pos_x , nwi - > pos_x + nwi - > current_x - 1 , nwi - > pos_y ) - nwi - > pos_y ;
if ( expected > nwi - > current_y - 1 ) {
this - > info_height = expected + 1 ;
this - > ReInit ( ) ;
return ;
}
2008-05-11 17:44:56 +00:00
}
2007-07-19 16:24:48 +00:00
2010-08-01 19:22:34 +00:00
/**
2011-12-16 16:39:48 +00:00
* Draw the text in the # WID_IV_INFO panel .
2009-10-18 13:40:11 +00:00
* @ param left Left edge of the panel .
* @ param right Right edge of the panel .
* @ param top Top edge of the panel .
* @ return Expected position of the bottom edge of the panel .
*/
int DrawInfo ( uint left , uint right , uint top )
2008-05-11 17:44:56 +00:00
{
2009-05-16 23:34:14 +00:00
Industry * i = Industry : : Get ( this - > window_number ) ;
2008-05-11 17:44:56 +00:00
const IndustrySpec * ind = GetIndustrySpec ( i - > type ) ;
2009-10-18 13:56:09 +00:00
int y = top + WD_FRAMERECT_TOP ;
2008-05-11 17:44:56 +00:00
bool first = true ;
bool has_accept = false ;
2009-10-18 15:36:30 +00:00
char cargo_suffix [ 3 ] [ 512 ] ;
2008-05-11 17:44:56 +00:00
2009-09-14 12:22:57 +00:00
if ( HasBit ( ind - > callback_mask , CBM_IND_PRODUCTION_CARGO_ARRIVAL ) | | HasBit ( ind - > callback_mask , CBM_IND_PRODUCTION_256_TICKS ) ) {
2009-10-18 15:36:30 +00:00
GetAllCargoSuffixes ( 0 , CST_VIEW , i , i - > type , ind , i - > accepts_cargo , cargo_suffix ) ;
2008-05-11 17:44:56 +00:00
for ( byte j = 0 ; j < lengthof ( i - > accepts_cargo ) ; j + + ) {
if ( i - > accepts_cargo [ j ] = = CT_INVALID ) continue ;
has_accept = true ;
2007-11-03 15:32:07 +00:00
if ( first ) {
2009-10-18 13:56:09 +00:00
DrawString ( left + WD_FRAMERECT_LEFT , right - WD_FRAMERECT_RIGHT , y , STR_INDUSTRY_VIEW_WAITING_FOR_PROCESSING ) ;
y + = FONT_HEIGHT_NORMAL ;
2007-11-03 15:32:07 +00:00
first = false ;
2007-07-08 00:25:05 +00:00
}
2008-05-11 17:44:56 +00:00
SetDParam ( 0 , i - > accepts_cargo [ j ] ) ;
SetDParam ( 1 , i - > incoming_cargo_waiting [ j ] ) ;
2009-10-18 15:36:30 +00:00
SetDParamStr ( 2 , cargo_suffix [ j ] ) ;
2009-10-18 13:56:09 +00:00
DrawString ( left + WD_FRAMETEXT_LEFT , right - WD_FRAMERECT_RIGHT , y , STR_INDUSTRY_VIEW_WAITING_STOCKPILE_CARGO ) ;
y + = FONT_HEIGHT_NORMAL ;
2008-05-11 17:44:56 +00:00
}
} else {
2009-10-18 15:36:30 +00:00
GetAllCargoSuffixes ( 0 , CST_VIEW , i , i - > type , ind , i - > accepts_cargo , cargo_suffix ) ;
2009-04-21 23:40:56 +00:00
StringID str = STR_INDUSTRY_VIEW_REQUIRES_CARGO ;
2008-05-11 17:44:56 +00:00
byte p = 0 ;
for ( byte j = 0 ; j < lengthof ( i - > accepts_cargo ) ; j + + ) {
if ( i - > accepts_cargo [ j ] = = CT_INVALID ) continue ;
has_accept = true ;
if ( p > 0 ) str + + ;
2009-07-16 19:00:13 +00:00
SetDParam ( p + + , CargoSpec : : Get ( i - > accepts_cargo [ j ] ) - > name ) ;
2009-10-18 15:36:30 +00:00
SetDParamStr ( p + + , cargo_suffix [ j ] ) ;
2008-05-11 17:44:56 +00:00
}
if ( has_accept ) {
2009-10-18 13:56:09 +00:00
DrawString ( left + WD_FRAMERECT_LEFT , right - WD_FRAMERECT_RIGHT , y , str ) ;
y + = FONT_HEIGHT_NORMAL ;
2008-05-11 17:44:56 +00:00
}
}
2004-09-10 19:02:27 +00:00
2009-10-18 15:36:30 +00:00
GetAllCargoSuffixes ( 3 , CST_VIEW , i , i - > type , ind , i - > produced_cargo , cargo_suffix ) ;
2008-05-11 17:44:56 +00:00
first = true ;
for ( byte j = 0 ; j < lengthof ( i - > produced_cargo ) ; j + + ) {
if ( i - > produced_cargo [ j ] = = CT_INVALID ) continue ;
if ( first ) {
2009-10-18 13:59:25 +00:00
if ( has_accept ) y + = WD_PAR_VSEP_WIDE ;
2009-10-18 13:56:09 +00:00
DrawString ( left + WD_FRAMERECT_LEFT , right - WD_FRAMERECT_RIGHT , y , STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE ) ;
y + = FONT_HEIGHT_NORMAL ;
2010-10-04 20:12:38 +00:00
if ( this - > editable = = EA_RATE ) this - > production_offset_y = y ;
2008-05-11 17:44:56 +00:00
first = false ;
2007-07-08 00:25:05 +00:00
}
2004-08-09 17:04:08 +00:00
2008-05-11 17:44:56 +00:00
SetDParam ( 0 , i - > produced_cargo [ j ] ) ;
SetDParam ( 1 , i - > last_month_production [ j ] ) ;
2009-10-18 15:36:30 +00:00
SetDParamStr ( 2 , cargo_suffix [ j ] ) ;
2009-08-27 13:31:26 +00:00
SetDParam ( 3 , ToPercent8 ( i - > last_month_pct_transported [ j ] ) ) ;
2012-06-01 14:41:09 +00:00
uint x = left + WD_FRAMETEXT_LEFT + ( this - > editable = = EA_RATE ? SETTING_BUTTON_WIDTH + 10 : 0 ) ;
2009-10-18 13:56:09 +00:00
DrawString ( x , right - WD_FRAMERECT_RIGHT , y , STR_INDUSTRY_VIEW_TRANSPORTED ) ;
2008-05-11 17:44:56 +00:00
/* Let's put out those buttons.. */
2010-10-04 19:35:40 +00:00
if ( this - > editable = = EA_RATE ) {
2010-10-04 19:14:43 +00:00
DrawArrowButtons ( left + WD_FRAMETEXT_LEFT , y , COLOUR_YELLOW , ( this - > clicked_line = = IL_RATE1 + j ) ? this - > clicked_button : 0 ,
2010-08-15 10:14:08 +00:00
i - > production_rate [ j ] > 0 , i - > production_rate [ j ] < 255 ) ;
2004-08-09 17:04:08 +00:00
}
2009-10-18 13:56:09 +00:00
y + = FONT_HEIGHT_NORMAL ;
2008-05-11 17:44:56 +00:00
}
2004-08-09 17:04:08 +00:00
2010-10-04 20:12:38 +00:00
/* Display production multiplier if editable */
if ( this - > editable = = EA_MULTIPLIER ) {
y + = WD_PAR_VSEP_WIDE ;
this - > production_offset_y = y ;
SetDParam ( 0 , RoundDivSU ( i - > prod_level * 100 , PRODLEVEL_DEFAULT ) ) ;
2012-06-01 14:41:09 +00:00
uint x = left + WD_FRAMETEXT_LEFT + SETTING_BUTTON_WIDTH + 10 ;
2010-10-04 20:12:38 +00:00
DrawString ( x , right - WD_FRAMERECT_RIGHT , y , STR_INDUSTRY_VIEW_PRODUCTION_LEVEL ) ;
DrawArrowButtons ( left + WD_FRAMETEXT_LEFT , y , COLOUR_YELLOW , ( this - > clicked_line = = IL_MULTIPLIER ) ? this - > clicked_button : 0 ,
i - > prod_level > PRODLEVEL_MINIMUM , i - > prod_level < PRODLEVEL_MAXIMUM ) ;
y + = FONT_HEIGHT_NORMAL ;
}
2008-05-11 17:44:56 +00:00
/* Get the extra message for the GUI */
2009-09-14 12:22:57 +00:00
if ( HasBit ( ind - > callback_mask , CBM_IND_WINDOW_MORE_TEXT ) ) {
2010-01-04 18:21:07 +00:00
uint16 callback_res = GetIndustryCallback ( CBID_INDUSTRY_WINDOW_MORE_TEXT , 0 , 0 , i , i - > type , i - > location . tile ) ;
2011-11-08 17:24:43 +00:00
if ( callback_res ! = CALLBACK_FAILED & & callback_res ! = 0x400 ) {
if ( callback_res > 0x400 ) {
ErrorUnknownCallbackResult ( ind - > grf_prop . grffile - > grfid , CBID_INDUSTRY_WINDOW_MORE_TEXT , callback_res ) ;
} else {
StringID message = GetGRFStringID ( ind - > grf_prop . grffile - > grfid , 0xD000 + callback_res ) ;
if ( message ! = STR_NULL & & message ! = STR_UNDEFINED ) {
y + = WD_PAR_VSEP_WIDE ;
StartTextRefStackUsage ( 6 ) ;
/* Use all the available space left from where we stand up to the
* end of the window . We ALSO enlarge the window if needed , so we
* can ' go ' wild with the bottom of the window . */
y = DrawStringMultiLine ( left + WD_FRAMERECT_LEFT , right - WD_FRAMERECT_RIGHT , y , UINT16_MAX , message , TC_BLACK ) ;
StopTextRefStackUsage ( ) ;
}
2008-05-11 17:44:56 +00:00
}
2008-05-05 16:05:36 +00:00
}
2008-05-11 17:44:56 +00:00
}
2009-10-18 14:10:59 +00:00
return y + WD_FRAMERECT_BOTTOM ;
2009-10-18 13:40:11 +00:00
}
2009-10-18 14:10:59 +00:00
virtual void SetStringParameters ( int widget ) const
2009-10-18 13:40:11 +00:00
{
2011-12-16 16:39:48 +00:00
if ( widget = = WID_IV_CAPTION ) SetDParam ( 0 , this - > window_number ) ;
2009-10-18 14:10:59 +00:00
}
2008-05-11 17:44:56 +00:00
2009-11-22 18:28:14 +00:00
virtual void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize )
2009-10-18 14:10:59 +00:00
{
2011-12-16 16:39:48 +00:00
if ( widget = = WID_IV_INFO ) size - > height = this - > info_height ;
2008-05-11 17:44:56 +00:00
}
2010-01-30 18:34:48 +00:00
virtual void OnClick ( Point pt , int widget , int click_count )
2008-05-11 17:44:56 +00:00
{
switch ( widget ) {
2011-12-16 16:39:48 +00:00
case WID_IV_INFO : {
2010-07-23 18:40:39 +00:00
Industry * i = Industry : : Get ( this - > window_number ) ;
2010-10-04 19:14:43 +00:00
InfoLine line = IL_NONE ;
2010-10-04 20:00:23 +00:00
switch ( this - > editable ) {
case EA_NONE : break ;
2010-10-04 20:12:38 +00:00
case EA_MULTIPLIER :
if ( IsInsideBS ( pt . y , this - > production_offset_y , FONT_HEIGHT_NORMAL ) ) line = IL_MULTIPLIER ;
break ;
2010-10-04 20:00:23 +00:00
case EA_RATE :
if ( pt . y > = this - > production_offset_y ) {
int row = ( pt . y - this - > production_offset_y ) / FONT_HEIGHT_NORMAL ;
for ( uint j = 0 ; j < lengthof ( i - > produced_cargo ) ; j + + ) {
if ( i - > produced_cargo [ j ] = = CT_INVALID ) continue ;
row - - ;
if ( row < 0 ) {
line = ( InfoLine ) ( IL_RATE1 + j ) ;
break ;
}
}
2010-10-04 19:14:43 +00:00
}
2010-10-04 20:00:23 +00:00
break ;
2010-10-04 19:14:43 +00:00
}
if ( line = = IL_NONE ) return ;
2008-05-11 17:44:56 +00:00
2010-10-04 20:00:23 +00:00
NWidgetBase * nwi = this - > GetWidget < NWidgetBase > ( widget ) ;
int left = nwi - > pos_x + WD_FRAMETEXT_LEFT ;
int right = nwi - > pos_x + nwi - > current_x - 1 - WD_FRAMERECT_RIGHT ;
2012-06-01 14:41:09 +00:00
if ( IsInsideMM ( pt . x , left , left + SETTING_BUTTON_WIDTH ) ) {
2010-10-04 20:00:23 +00:00
/* Clicked buttons, decrease or increase production */
2012-06-01 14:41:09 +00:00
byte button = ( pt . x < left + SETTING_BUTTON_WIDTH / 2 ) ? 1 : 2 ;
2010-10-04 20:00:23 +00:00
switch ( this - > editable ) {
2010-10-04 20:12:38 +00:00
case EA_MULTIPLIER :
if ( button = = 1 ) {
if ( i - > prod_level < = PRODLEVEL_MINIMUM ) return ;
i - > prod_level = max < uint > ( i - > prod_level / 2 , PRODLEVEL_MINIMUM ) ;
} else {
if ( i - > prod_level > = PRODLEVEL_MAXIMUM ) return ;
i - > prod_level = minu ( i - > prod_level * 2 , PRODLEVEL_MAXIMUM ) ;
}
break ;
2010-10-04 20:00:23 +00:00
case EA_RATE :
if ( button = = 1 ) {
if ( i - > production_rate [ line - IL_RATE1 ] < = 0 ) return ;
i - > production_rate [ line - IL_RATE1 ] = max ( i - > production_rate [ line - IL_RATE1 ] / 2 , 0 ) ;
} else {
if ( i - > production_rate [ line - IL_RATE1 ] > = 255 ) return ;
/* a zero production industry is unlikely to give anything but zero, so push it a little bit */
int new_prod = i - > production_rate [ line - IL_RATE1 ] = = 0 ? 1 : i - > production_rate [ line - IL_RATE1 ] * 2 ;
i - > production_rate [ line - IL_RATE1 ] = minu ( new_prod , 255 ) ;
}
break ;
default : NOT_REACHED ( ) ;
}
UpdateIndustryProduction ( i ) ;
this - > SetDirty ( ) ;
2011-12-15 19:54:23 +00:00
this - > SetTimeout ( ) ;
2010-10-04 20:00:23 +00:00
this - > clicked_line = line ;
this - > clicked_button = button ;
2012-06-01 14:41:09 +00:00
} else if ( IsInsideMM ( pt . x , left + SETTING_BUTTON_WIDTH + 10 , right ) ) {
2010-10-04 20:00:23 +00:00
/* clicked the text */
this - > editbox_line = line ;
switch ( this - > editable ) {
2010-10-04 20:12:38 +00:00
case EA_MULTIPLIER :
SetDParam ( 0 , RoundDivSU ( i - > prod_level * 100 , PRODLEVEL_DEFAULT ) ) ;
2011-04-17 18:42:17 +00:00
ShowQueryString ( STR_JUST_INT , STR_CONFIG_GAME_PRODUCTION_LEVEL , 10 , this , CS_ALPHANUMERAL , QSF_NONE ) ;
2010-10-04 20:12:38 +00:00
break ;
2010-10-04 20:00:23 +00:00
case EA_RATE :
SetDParam ( 0 , i - > production_rate [ line - IL_RATE1 ] * 8 ) ;
2011-04-17 18:42:17 +00:00
ShowQueryString ( STR_JUST_INT , STR_CONFIG_GAME_PRODUCTION , 10 , this , CS_ALPHANUMERAL , QSF_NONE ) ;
2010-10-04 20:00:23 +00:00
break ;
2005-01-14 00:14:13 +00:00
2010-10-04 20:00:23 +00:00
default : NOT_REACHED ( ) ;
2005-01-14 00:14:13 +00:00
}
2008-05-11 17:44:56 +00:00
}
2010-08-01 18:53:30 +00:00
break ;
}
2008-05-11 17:44:56 +00:00
2011-12-16 16:39:48 +00:00
case WID_IV_GOTO : {
2010-07-23 18:40:39 +00:00
Industry * i = Industry : : Get ( this - > window_number ) ;
2008-05-11 17:44:56 +00:00
if ( _ctrl_pressed ) {
2010-10-23 20:34:12 +00:00
ShowExtraViewPortWindow ( i - > location . GetCenterTile ( ) ) ;
2008-05-11 17:44:56 +00:00
} else {
2010-10-23 20:34:12 +00:00
ScrollMainWindowToTile ( i - > location . GetCenterTile ( ) ) ;
2008-05-11 17:44:56 +00:00
}
break ;
2010-07-23 18:40:39 +00:00
}
2010-07-23 18:44:04 +00:00
2011-12-16 16:39:48 +00:00
case WID_IV_DISPLAY : {
2010-07-23 18:44:04 +00:00
Industry * i = Industry : : Get ( this - > window_number ) ;
ShowIndustryCargoesWindow ( i - > type ) ;
break ;
}
2008-05-11 17:44:56 +00:00
}
2004-08-09 17:04:08 +00:00
}
2008-05-11 17:44:56 +00:00
virtual void OnTimeout ( )
{
2010-10-04 19:14:43 +00:00
this - > clicked_line = IL_NONE ;
2008-05-11 17:44:56 +00:00
this - > clicked_button = 0 ;
this - > SetDirty ( ) ;
}
2009-10-24 14:53:55 +00:00
virtual void OnResize ( )
2008-05-11 17:44:56 +00:00
{
2009-10-18 14:10:59 +00:00
if ( this - > viewport ! = NULL ) {
2011-12-16 16:39:48 +00:00
NWidgetViewport * nvp = this - > GetWidget < NWidgetViewport > ( WID_IV_VIEWPORT ) ;
2009-10-18 14:10:59 +00:00
nvp - > UpdateViewportCoordinates ( this ) ;
2010-10-23 20:51:48 +00:00
ScrollWindowToTile ( Industry : : Get ( this - > window_number ) - > location . GetCenterTile ( ) , this , true ) ; // Re-center viewport.
2009-10-18 14:10:59 +00:00
}
2008-05-11 17:44:56 +00:00
}
virtual void OnQueryTextFinished ( char * str )
{
if ( StrEmpty ( str ) ) return ;
2009-05-16 23:34:14 +00:00
Industry * i = Industry : : Get ( this - > window_number ) ;
2010-10-04 19:45:27 +00:00
uint value = atoi ( str ) ;
2010-10-04 20:12:38 +00:00
switch ( this - > editbox_line ) {
case IL_NONE : NOT_REACHED ( ) ;
case IL_MULTIPLIER :
i - > prod_level = ClampU ( RoundDivSU ( value * PRODLEVEL_DEFAULT , 100 ) , PRODLEVEL_MINIMUM , PRODLEVEL_MAXIMUM ) ;
break ;
2008-05-11 17:44:56 +00:00
2010-10-04 20:12:38 +00:00
default :
i - > production_rate [ this - > editbox_line - IL_RATE1 ] = ClampU ( RoundDivSU ( value , 8 ) , 0 , 255 ) ;
break ;
}
2008-05-11 17:44:56 +00:00
UpdateIndustryProduction ( i ) ;
this - > SetDirty ( ) ;
}
2010-04-24 13:39:11 +00:00
2011-03-13 21:31:29 +00:00
/**
* Some data on this window has become invalid .
* @ param data Information about the changed data .
* @ param gui_scope Whether the call is done from GUI scope . You may not do everything when not in GUI scope . See # InvalidateWindowData ( ) for details .
*/
virtual void OnInvalidateData ( int data = 0 , bool gui_scope = true )
2010-10-04 19:35:40 +00:00
{
2011-03-13 21:31:29 +00:00
if ( ! gui_scope ) return ;
2010-10-04 19:35:40 +00:00
const Industry * i = Industry : : Get ( this - > window_number ) ;
if ( IsProductionAlterable ( i ) ) {
2010-10-04 20:12:38 +00:00
const IndustrySpec * ind = GetIndustrySpec ( i - > type ) ;
this - > editable = ind - > UsesSmoothEconomy ( ) ? EA_RATE : EA_MULTIPLIER ;
2010-10-04 19:35:40 +00:00
} else {
this - > editable = EA_NONE ;
}
}
2010-04-24 13:39:11 +00:00
virtual bool IsNewGRFInspectable ( ) const
{
return : : IsNewGRFInspectable ( GSF_INDUSTRIES , this - > window_number ) ;
}
virtual void ShowNewGRFInspectWindow ( ) const
{
: : ShowNewGRFInspectWindow ( GSF_INDUSTRIES , this - > window_number ) ;
}
2008-05-11 17:44:56 +00:00
} ;
2004-08-09 17:04:08 +00:00
2005-01-14 00:14:13 +00:00
static void UpdateIndustryProduction ( Industry * i )
{
2010-10-04 20:12:38 +00:00
const IndustrySpec * indspec = GetIndustrySpec ( i - > type ) ;
if ( ! indspec - > UsesSmoothEconomy ( ) ) i - > RecomputeProductionMultipliers ( ) ;
2007-09-27 21:39:13 +00:00
for ( byte j = 0 ; j < lengthof ( i - > produced_cargo ) ; j + + ) {
if ( i - > produced_cargo [ j ] ! = CT_INVALID ) {
2007-06-07 14:38:45 +00:00
i - > last_month_production [ j ] = 8 * i - > production_rate [ j ] ;
2007-05-18 00:33:47 +00:00
}
}
2005-01-14 00:14:13 +00:00
}
2010-07-31 21:02:56 +00:00
/** Widget definition of the view industry gui */
2009-03-28 19:08:55 +00:00
static const NWidgetPart _nested_industry_view_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_CREAM ) ,
2011-12-16 16:39:48 +00:00
NWidget ( WWT_CAPTION , COLOUR_CREAM , WID_IV_CAPTION ) , SetDataTip ( STR_INDUSTRY_VIEW_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2010-04-24 13:39:11 +00:00
NWidget ( WWT_DEBUGBOX , COLOUR_CREAM ) ,
2009-12-21 16:24:29 +00:00
NWidget ( WWT_SHADEBOX , COLOUR_CREAM ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_STICKYBOX , COLOUR_CREAM ) ,
2009-03-28 19:08:55 +00:00
EndContainer ( ) ,
2009-11-24 21:13:36 +00:00
NWidget ( WWT_PANEL , COLOUR_CREAM ) ,
NWidget ( WWT_INSET , COLOUR_CREAM ) , SetPadding ( 2 , 2 , 2 , 2 ) ,
2011-12-16 16:39:48 +00:00
NWidget ( NWID_VIEWPORT , INVALID_COLOUR , WID_IV_VIEWPORT ) , SetMinimalSize ( 254 , 86 ) , SetFill ( 1 , 0 ) , SetPadding ( 1 , 1 , 1 , 1 ) , SetResize ( 1 , 1 ) ,
2009-03-28 19:08:55 +00:00
EndContainer ( ) ,
EndContainer ( ) ,
2011-12-16 16:39:48 +00:00
NWidget ( WWT_PANEL , COLOUR_CREAM , WID_IV_INFO ) , SetMinimalSize ( 260 , 2 ) , SetResize ( 1 , 0 ) ,
2009-03-28 19:08:55 +00:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 16:39:48 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_CREAM , WID_IV_GOTO ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) , SetDataTip ( STR_BUTTON_LOCATION , STR_INDUSTRY_VIEW_LOCATION_TOOLTIP ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_CREAM , WID_IV_DISPLAY ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) , SetDataTip ( STR_INDUSTRY_DISPLAY_CHAIN , STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_RESIZEBOX , COLOUR_CREAM ) ,
2009-03-28 19:08:55 +00:00
EndContainer ( ) ,
} ;
2010-07-31 21:02:56 +00:00
/** Window definition of the view industry gui */
2009-03-15 15:12:06 +00:00
static const WindowDesc _industry_view_desc (
2009-11-28 14:42:35 +00:00
WDP_AUTO , 260 , 120 ,
2007-02-01 15:49:12 +00:00
WC_INDUSTRY_VIEW , WC_NONE ,
2012-11-11 16:10:43 +00:00
0 ,
2009-11-15 10:26:01 +00:00
_nested_industry_view_widgets , lengthof ( _nested_industry_view_widgets )
2009-03-15 15:12:06 +00:00
) ;
2004-08-09 17:04:08 +00:00
void ShowIndustryViewWindow ( int industry )
{
2008-05-11 17:44:56 +00:00
AllocateWindowDescFront < IndustryViewWindow > ( & _industry_view_desc , industry ) ;
2004-08-09 17:04:08 +00:00
}
2010-07-31 21:02:56 +00:00
/** Widget definition of the industry directory gui */
2009-03-28 19:08:55 +00:00
static const NWidgetPart _nested_industry_directory_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_BROWN ) ,
NWidget ( WWT_CAPTION , COLOUR_BROWN ) , SetDataTip ( STR_INDUSTRY_DIRECTORY_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2009-12-21 16:24:29 +00:00
NWidget ( WWT_SHADEBOX , COLOUR_BROWN ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_STICKYBOX , COLOUR_BROWN ) ,
2009-03-28 19:08:55 +00:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( NWID_VERTICAL ) ,
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 16:39:48 +00:00
NWidget ( WWT_TEXTBTN , COLOUR_BROWN , WID_ID_DROPDOWN_ORDER ) , SetDataTip ( STR_BUTTON_SORT_BY , STR_TOOLTIP_SORT_ORDER ) ,
NWidget ( WWT_DROPDOWN , COLOUR_BROWN , WID_ID_DROPDOWN_CRITERIA ) , SetDataTip ( STR_JUST_STRING , STR_TOOLTIP_SORT_CRITERIA ) ,
2009-11-24 21:13:36 +00:00
NWidget ( WWT_PANEL , COLOUR_BROWN ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
2009-03-28 19:08:55 +00:00
EndContainer ( ) ,
2011-12-16 16:39:48 +00:00
NWidget ( WWT_PANEL , COLOUR_BROWN , WID_ID_INDUSTRY_LIST ) , SetDataTip ( 0x0 , STR_INDUSTRY_DIRECTORY_LIST_CAPTION ) , SetResize ( 1 , 1 ) , SetScrollbar ( WID_ID_SCROLLBAR ) , EndContainer ( ) ,
2009-03-28 19:08:55 +00:00
EndContainer ( ) ,
NWidget ( NWID_VERTICAL ) ,
2011-12-16 16:39:48 +00:00
NWidget ( NWID_VSCROLLBAR , COLOUR_BROWN , WID_ID_SCROLLBAR ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_RESIZEBOX , COLOUR_BROWN ) ,
2009-03-28 19:08:55 +00:00
EndContainer ( ) ,
EndContainer ( ) ,
} ;
2008-05-28 16:45:00 +00:00
typedef GUIList < const Industry * > GUIIndustryList ;
2004-08-09 17:04:08 +00:00
2008-05-28 16:45:00 +00:00
/**
* The list of industries .
2008-05-25 17:26:16 +00:00
*/
2008-05-28 16:45:00 +00:00
class IndustryDirectoryWindow : public Window {
protected :
/* Runtime saved values */
static Listing last_sorting ;
static const Industry * last_industry ;
2008-05-25 17:26:16 +00:00
2008-05-28 16:45:00 +00:00
/* Constants for sorting stations */
static const StringID sorter_names [ ] ;
2009-03-15 16:04:39 +00:00
static GUIIndustryList : : SortFunction * const sorter_funcs [ ] ;
2008-05-25 17:26:16 +00:00
2008-05-28 16:45:00 +00:00
GUIIndustryList industries ;
2010-08-12 08:37:01 +00:00
Scrollbar * vscroll ;
2008-05-25 17:26:16 +00:00
2008-05-28 16:45:00 +00:00
/** (Re)Build industries list */
2009-08-30 13:44:25 +00:00
void BuildSortIndustriesList ( )
2008-05-28 16:45:00 +00:00
{
2009-08-30 13:44:25 +00:00
if ( this - > industries . NeedRebuild ( ) ) {
this - > industries . Clear ( ) ;
2008-05-25 17:26:16 +00:00
2009-08-30 13:44:25 +00:00
const Industry * i ;
FOR_ALL_INDUSTRIES ( i ) {
* this - > industries . Append ( ) = i ;
}
2006-08-15 13:31:43 +00:00
2009-08-30 13:44:25 +00:00
this - > industries . Compact ( ) ;
this - > industries . RebuildDone ( ) ;
2010-08-12 08:37:01 +00:00
this - > vscroll - > SetCount ( this - > industries . Length ( ) ) ; // Update scrollbar as well.
2008-05-28 16:45:00 +00:00
}
2009-09-07 08:52:01 +00:00
if ( ! this - > industries . Sort ( ) ) return ;
IndustryDirectoryWindow : : last_industry = NULL ; // Reset name sorter sort cache
2011-12-16 16:39:48 +00:00
this - > SetWidgetDirty ( WID_ID_INDUSTRY_LIST ) ; // Set the modified widget dirty
2008-05-28 16:45:00 +00:00
}
2006-08-15 13:31:43 +00:00
2008-05-28 16:45:00 +00:00
/**
* Returns percents of cargo transported if industry produces this cargo , else - 1
*
* @ param i industry to check
* @ param id cargo slot
* @ return percents of cargo transported , or - 1 if industry doesn ' t use this cargo slot
*/
static inline int GetCargoTransportedPercentsIfValid ( const Industry * i , uint id )
{
assert ( id < lengthof ( i - > produced_cargo ) ) ;
2004-08-09 17:04:08 +00:00
2008-05-28 16:45:00 +00:00
if ( i - > produced_cargo [ id ] = = CT_INVALID ) return 101 ;
2009-08-27 13:31:26 +00:00
return ToPercent8 ( i - > last_month_pct_transported [ id ] ) ;
2004-08-09 17:04:08 +00:00
}
2004-09-10 19:02:27 +00:00
2008-05-28 16:45:00 +00:00
/**
* Returns value representing industry ' s transported cargo
* percentage for industry sorting
*
* @ param i industry to check
* @ return value used for sorting
*/
static int GetCargoTransportedSortValue ( const Industry * i )
{
int p1 = GetCargoTransportedPercentsIfValid ( i , 0 ) ;
int p2 = GetCargoTransportedPercentsIfValid ( i , 1 ) ;
2004-08-09 17:04:08 +00:00
2008-05-28 16:45:00 +00:00
if ( p1 > p2 ) Swap ( p1 , p2 ) ; // lower value has higher priority
2008-05-18 23:36:33 +00:00
2008-05-28 16:45:00 +00:00
return ( p1 < < 8 ) + p2 ;
}
2005-01-06 22:31:58 +00:00
2008-05-28 16:45:00 +00:00
/** Sort industries by name */
2009-01-10 00:31:47 +00:00
static int CDECL IndustryNameSorter ( const Industry * const * a , const Industry * const * b )
2008-05-28 16:45:00 +00:00
{
static char buf_cache [ 96 ] ;
static char buf [ 96 ] ;
2004-08-09 17:04:08 +00:00
2010-11-27 22:42:24 +00:00
SetDParam ( 0 , ( * a ) - > index ) ;
GetString ( buf , STR_INDUSTRY_NAME , lastof ( buf ) ) ;
2008-05-18 23:36:33 +00:00
2008-05-28 16:45:00 +00:00
if ( * b ! = last_industry ) {
last_industry = * b ;
2010-11-27 22:42:24 +00:00
SetDParam ( 0 , ( * b ) - > index ) ;
GetString ( buf_cache , STR_INDUSTRY_NAME , lastof ( buf_cache ) ) ;
2008-05-28 16:45:00 +00:00
}
2010-11-27 22:52:12 +00:00
return strnatcmp ( buf , buf_cache ) ; // Sort by name (natural sorting).
2008-05-26 16:23:23 +00:00
}
2004-08-09 17:04:08 +00:00
2008-05-28 16:45:00 +00:00
/** Sort industries by type and name */
2009-01-10 00:31:47 +00:00
static int CDECL IndustryTypeSorter ( const Industry * const * a , const Industry * const * b )
2008-05-28 16:45:00 +00:00
{
2010-12-04 22:54:11 +00:00
int it_a = 0 ;
while ( it_a ! = NUM_INDUSTRYTYPES & & ( * a ) - > type ! = _sorted_industry_types [ it_a ] ) it_a + + ;
int it_b = 0 ;
while ( it_b ! = NUM_INDUSTRYTYPES & & ( * b ) - > type ! = _sorted_industry_types [ it_b ] ) it_b + + ;
int r = it_a - it_b ;
2008-06-05 11:34:26 +00:00
return ( r = = 0 ) ? IndustryNameSorter ( a , b ) : r ;
2008-05-28 16:45:00 +00:00
}
2008-05-18 23:36:33 +00:00
2008-05-28 16:45:00 +00:00
/** Sort industries by production and name */
2009-01-10 00:31:47 +00:00
static int CDECL IndustryProductionSorter ( const Industry * const * a , const Industry * const * b )
2008-05-28 16:45:00 +00:00
{
2010-04-02 11:03:56 +00:00
uint prod_a = 0 , prod_b = 0 ;
for ( uint i = 0 ; i < lengthof ( ( * a ) - > produced_cargo ) ; i + + ) {
if ( ( * a ) - > produced_cargo [ i ] ! = CT_INVALID ) prod_a + = ( * a ) - > last_month_production [ i ] ;
if ( ( * b ) - > produced_cargo [ i ] ! = CT_INVALID ) prod_b + = ( * b ) - > last_month_production [ i ] ;
2008-05-28 16:45:00 +00:00
}
2010-04-02 11:03:56 +00:00
int r = prod_a - prod_b ;
2004-08-09 17:04:08 +00:00
2010-04-02 11:03:56 +00:00
return ( r = = 0 ) ? IndustryTypeSorter ( a , b ) : r ;
2008-05-28 16:45:00 +00:00
}
2004-08-09 17:04:08 +00:00
2008-05-28 16:45:00 +00:00
/** Sort industries by transported cargo and name */
2009-01-10 00:31:47 +00:00
static int CDECL IndustryTransportedCargoSorter ( const Industry * const * a , const Industry * const * b )
2008-05-28 16:45:00 +00:00
{
int r = GetCargoTransportedSortValue ( * a ) - GetCargoTransportedSortValue ( * b ) ;
2008-06-05 11:34:26 +00:00
return ( r = = 0 ) ? IndustryNameSorter ( a , b ) : r ;
2008-05-28 16:45:00 +00:00
}
2004-08-09 17:04:08 +00:00
2009-08-30 14:06:55 +00:00
/**
* Get the StringID to draw and set the appropriate DParams .
* @ param i the industry to get the StringID of .
* @ return the StringID .
*/
2009-08-30 15:25:20 +00:00
StringID GetIndustryString ( const Industry * i ) const
2009-08-30 14:06:55 +00:00
{
const IndustrySpec * indsp = GetIndustrySpec ( i - > type ) ;
byte p = 0 ;
/* Industry name */
SetDParam ( p + + , i - > index ) ;
2010-01-03 22:43:12 +00:00
static char cargo_suffix [ lengthof ( i - > produced_cargo ) ] [ 512 ] ;
2009-10-18 15:36:30 +00:00
GetAllCargoSuffixes ( 3 , CST_DIR , i , i - > type , indsp , i - > produced_cargo , cargo_suffix ) ;
2009-08-30 14:06:55 +00:00
/* Industry productions */
for ( byte j = 0 ; j < lengthof ( i - > produced_cargo ) ; j + + ) {
if ( i - > produced_cargo [ j ] = = CT_INVALID ) continue ;
SetDParam ( p + + , i - > produced_cargo [ j ] ) ;
SetDParam ( p + + , i - > last_month_production [ j ] ) ;
2009-10-18 15:36:30 +00:00
SetDParamStr ( p + + , cargo_suffix [ j ] ) ;
2009-08-30 14:06:55 +00:00
}
/* Transported productions */
for ( byte j = 0 ; j < lengthof ( i - > produced_cargo ) ; j + + ) {
if ( i - > produced_cargo [ j ] = = CT_INVALID ) continue ;
SetDParam ( p + + , ToPercent8 ( i - > last_month_pct_transported [ j ] ) ) ;
}
/* Drawing the right string */
switch ( p ) {
case 1 : return STR_INDUSTRY_DIRECTORY_ITEM_NOPROD ;
case 5 : return STR_INDUSTRY_DIRECTORY_ITEM ;
default : return STR_INDUSTRY_DIRECTORY_ITEM_TWO ;
}
}
2008-05-28 16:45:00 +00:00
public :
2009-08-30 15:25:20 +00:00
IndustryDirectoryWindow ( const WindowDesc * desc , WindowNumber number ) : Window ( )
2008-05-18 23:36:33 +00:00
{
2010-08-12 08:37:01 +00:00
this - > CreateNestedTree ( desc ) ;
2011-12-16 16:39:48 +00:00
this - > vscroll = this - > GetScrollbar ( WID_ID_SCROLLBAR ) ;
2010-08-12 08:37:01 +00:00
2008-05-28 16:45:00 +00:00
this - > industries . SetListing ( this - > last_sorting ) ;
2009-08-30 15:25:20 +00:00
this - > industries . SetSortFuncs ( IndustryDirectoryWindow : : sorter_funcs ) ;
2008-05-28 16:45:00 +00:00
this - > industries . ForceRebuild ( ) ;
2009-08-30 13:44:25 +00:00
this - > BuildSortIndustriesList ( ) ;
2008-05-28 16:45:00 +00:00
2010-08-12 08:37:01 +00:00
this - > FinishInitNested ( desc , 0 ) ;
2008-05-28 16:45:00 +00:00
}
~ IndustryDirectoryWindow ( )
{
this - > last_sorting = this - > industries . GetListing ( ) ;
2008-05-18 23:36:33 +00:00
}
2004-09-10 19:02:27 +00:00
2009-08-30 15:25:20 +00:00
virtual void SetStringParameters ( int widget ) const
{
2011-12-16 16:39:48 +00:00
if ( widget = = WID_ID_DROPDOWN_CRITERIA ) SetDParam ( 0 , IndustryDirectoryWindow : : sorter_names [ this - > industries . SortType ( ) ] ) ;
2009-08-30 15:25:20 +00:00
}
virtual void DrawWidget ( const Rect & r , int widget ) const
{
switch ( widget ) {
2011-12-16 16:39:48 +00:00
case WID_ID_DROPDOWN_ORDER :
2009-08-30 15:25:20 +00:00
this - > DrawSortButtonState ( widget , this - > industries . IsDescSortOrder ( ) ? SBS_DOWN : SBS_UP ) ;
break ;
2011-12-16 16:39:48 +00:00
case WID_ID_INDUSTRY_LIST : {
2009-08-30 15:25:20 +00:00
int n = 0 ;
int y = r . top + WD_FRAMERECT_TOP ;
2009-09-05 11:27:28 +00:00
if ( this - > industries . Length ( ) = = 0 ) {
DrawString ( r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT , y , STR_INDUSTRY_DIRECTORY_NONE ) ;
break ;
}
2010-08-12 08:37:01 +00:00
for ( uint i = this - > vscroll - > GetPosition ( ) ; i < this - > industries . Length ( ) ; i + + ) {
2009-08-30 15:25:20 +00:00
DrawString ( r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT , y , this - > GetIndustryString ( this - > industries [ i ] ) ) ;
2008-05-18 23:36:33 +00:00
2009-08-30 15:25:20 +00:00
y + = this - > resize . step_height ;
2010-08-12 08:37:01 +00:00
if ( + + n = = this - > vscroll - > GetCapacity ( ) ) break ; // max number of industries in 1 window
2009-08-30 15:25:20 +00:00
}
2010-08-01 18:53:30 +00:00
break ;
}
2009-08-30 15:25:20 +00:00
}
}
2009-11-22 18:28:14 +00:00
virtual void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize )
2009-08-30 15:25:20 +00:00
{
switch ( widget ) {
2011-12-16 16:39:48 +00:00
case WID_ID_DROPDOWN_ORDER : {
2009-09-19 11:31:12 +00:00
Dimension d = GetStringBoundingBox ( this - > GetWidget < NWidgetCore > ( widget ) - > widget_data ) ;
2010-10-19 21:48:20 +00:00
d . width + = padding . width + WD_SORTBUTTON_ARROW_WIDTH * 2 ; // Doubled since the string is centred and it also looks better.
2009-08-30 15:25:20 +00:00
d . height + = padding . height ;
* size = maxdim ( * size , d ) ;
break ;
}
2008-05-18 23:36:33 +00:00
2011-12-16 16:39:48 +00:00
case WID_ID_DROPDOWN_CRITERIA : {
2009-08-30 15:25:20 +00:00
Dimension d = { 0 , 0 } ;
for ( uint i = 0 ; IndustryDirectoryWindow : : sorter_names [ i ] ! = INVALID_STRING_ID ; i + + ) {
d = maxdim ( d , GetStringBoundingBox ( IndustryDirectoryWindow : : sorter_names [ i ] ) ) ;
}
d . width + = padding . width ;
d . height + = padding . height ;
* size = maxdim ( * size , d ) ;
break ;
}
2011-12-16 16:39:48 +00:00
case WID_ID_INDUSTRY_LIST : {
2009-09-05 11:27:28 +00:00
Dimension d = GetStringBoundingBox ( STR_INDUSTRY_DIRECTORY_NONE ) ;
2009-08-30 15:25:20 +00:00
for ( uint i = 0 ; i < this - > industries . Length ( ) ; i + + ) {
d = maxdim ( d , GetStringBoundingBox ( this - > GetIndustryString ( this - > industries [ i ] ) ) ) ;
}
resize - > height = d . height ;
2010-09-22 19:47:01 +00:00
d . height * = 5 ;
2009-08-30 15:25:20 +00:00
d . width + = padding . width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT ;
d . height + = padding . height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM ;
* size = maxdim ( * size , d ) ;
break ;
}
2008-05-18 23:36:33 +00:00
}
2004-09-10 19:02:27 +00:00
}
2008-05-18 23:36:33 +00:00
2009-08-30 15:25:20 +00:00
2010-01-30 18:34:48 +00:00
virtual void OnClick ( Point pt , int widget , int click_count )
2008-05-18 23:36:33 +00:00
{
switch ( widget ) {
2011-12-16 16:39:48 +00:00
case WID_ID_DROPDOWN_ORDER :
2008-05-28 16:45:00 +00:00
this - > industries . ToggleSortOrder ( ) ;
2008-05-18 23:36:33 +00:00
this - > SetDirty ( ) ;
break ;
2011-12-16 16:39:48 +00:00
case WID_ID_DROPDOWN_CRITERIA :
ShowDropDownMenu ( this , IndustryDirectoryWindow : : sorter_names , this - > industries . SortType ( ) , WID_ID_DROPDOWN_CRITERIA , 0 , 0 ) ;
2008-05-28 16:45:00 +00:00
break ;
2011-12-16 16:39:48 +00:00
case WID_ID_INDUSTRY_LIST : {
uint p = this - > vscroll - > GetScrolledRowFromWidget ( pt . y , this , WID_ID_INDUSTRY_LIST , WD_FRAMERECT_TOP ) ;
2008-05-27 18:50:31 +00:00
if ( p < this - > industries . Length ( ) ) {
2008-05-18 23:36:33 +00:00
if ( _ctrl_pressed ) {
2010-01-04 18:21:07 +00:00
ShowExtraViewPortWindow ( this - > industries [ p ] - > location . tile ) ;
2008-05-18 23:36:33 +00:00
} else {
2010-01-04 18:21:07 +00:00
ScrollMainWindowToTile ( this - > industries [ p ] - > location . tile ) ;
2008-05-18 23:36:33 +00:00
}
}
2010-08-01 18:53:30 +00:00
break ;
}
2008-05-18 23:36:33 +00:00
}
}
2008-05-28 16:45:00 +00:00
virtual void OnDropdownSelect ( int widget , int index )
{
if ( this - > industries . SortType ( ) ! = index ) {
this - > industries . SetSortType ( index ) ;
2009-09-07 08:52:01 +00:00
this - > BuildSortIndustriesList ( ) ;
2008-05-28 16:45:00 +00:00
}
}
2009-10-24 14:53:55 +00:00
virtual void OnResize ( )
2008-05-18 23:36:33 +00:00
{
2011-12-16 16:39:48 +00:00
this - > vscroll - > SetCapacityFromWidget ( this , WID_ID_INDUSTRY_LIST ) ;
2008-05-18 23:36:33 +00:00
}
2011-03-08 20:52:59 +00:00
virtual void OnPaint ( )
{
if ( this - > industries . NeedRebuild ( ) ) this - > BuildSortIndustriesList ( ) ;
this - > DrawWidgets ( ) ;
}
2009-08-30 13:44:25 +00:00
virtual void OnHundredthTick ( )
{
2009-09-07 08:52:01 +00:00
this - > industries . ForceResort ( ) ;
2009-08-30 13:44:25 +00:00
this - > BuildSortIndustriesList ( ) ;
}
2011-03-13 21:31:29 +00:00
/**
* Some data on this window has become invalid .
* @ param data Information about the changed data .
* @ param gui_scope Whether the call is done from GUI scope . You may not do everything when not in GUI scope . See # InvalidateWindowData ( ) for details .
*/
virtual void OnInvalidateData ( int data = 0 , bool gui_scope = true )
2008-05-18 23:36:33 +00:00
{
2008-05-28 16:45:00 +00:00
if ( data = = 0 ) {
2011-03-13 21:34:21 +00:00
/* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */
2008-05-28 16:45:00 +00:00
this - > industries . ForceRebuild ( ) ;
} else {
this - > industries . ForceResort ( ) ;
}
2008-05-18 23:36:33 +00:00
}
} ;
2008-05-28 16:45:00 +00:00
Listing IndustryDirectoryWindow : : last_sorting = { false , 0 } ;
const Industry * IndustryDirectoryWindow : : last_industry = NULL ;
2010-08-15 14:06:43 +00:00
/* Available station sorting functions. */
2009-01-10 00:31:47 +00:00
GUIIndustryList : : SortFunction * const IndustryDirectoryWindow : : sorter_funcs [ ] = {
2008-05-28 16:45:00 +00:00
& IndustryNameSorter ,
& IndustryTypeSorter ,
& IndustryProductionSorter ,
& IndustryTransportedCargoSorter
} ;
/* Names of the sorting functions */
const StringID IndustryDirectoryWindow : : sorter_names [ ] = {
2009-07-23 19:31:50 +00:00
STR_SORT_BY_NAME ,
2008-05-28 16:45:00 +00:00
STR_SORT_BY_TYPE ,
STR_SORT_BY_PRODUCTION ,
STR_SORT_BY_TRANSPORTED ,
INVALID_STRING_ID
} ;
2004-08-09 17:04:08 +00:00
2010-07-31 21:02:56 +00:00
/** Window definition of the industry directory gui */
2009-03-15 15:12:06 +00:00
static const WindowDesc _industry_directory_desc (
2009-11-28 14:42:35 +00:00
WDP_AUTO , 428 , 190 ,
2007-02-01 15:49:12 +00:00
WC_INDUSTRY_DIRECTORY , WC_NONE ,
2012-11-11 16:10:43 +00:00
0 ,
2009-11-15 10:26:01 +00:00
_nested_industry_directory_widgets , lengthof ( _nested_industry_directory_widgets )
2009-03-15 15:12:06 +00:00
) ;
2004-08-09 17:04:08 +00:00
2007-03-07 11:47:46 +00:00
void ShowIndustryDirectory ( )
2004-08-09 17:04:08 +00:00
{
2008-05-18 23:36:33 +00:00
AllocateWindowDescFront < IndustryDirectoryWindow > ( & _industry_directory_desc , 0 ) ;
2004-08-09 17:04:08 +00:00
}
2010-07-23 18:39:02 +00:00
/** Widgets of the industry cargoes window. */
static const NWidgetPart _nested_industry_cargoes_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( WWT_CLOSEBOX , COLOUR_BROWN ) ,
2011-12-16 16:39:48 +00:00
NWidget ( WWT_CAPTION , COLOUR_BROWN , WID_IC_CAPTION ) , SetDataTip ( STR_INDUSTRY_CARGOES_INDUSTRY_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2010-07-23 18:39:02 +00:00
NWidget ( WWT_SHADEBOX , COLOUR_BROWN ) ,
NWidget ( WWT_STICKYBOX , COLOUR_BROWN ) ,
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2010-08-08 11:17:14 +00:00
NWidget ( NWID_VERTICAL ) ,
2011-12-16 16:39:48 +00:00
NWidget ( WWT_PANEL , COLOUR_BROWN , WID_IC_PANEL ) , SetResize ( 1 , 10 ) , SetMinimalSize ( 200 , 90 ) , SetScrollbar ( WID_IC_SCROLLBAR ) , EndContainer ( ) ,
2010-08-08 11:17:14 +00:00
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 16:39:48 +00:00
NWidget ( WWT_TEXTBTN , COLOUR_BROWN , WID_IC_NOTIFY ) ,
2010-08-08 11:17:14 +00:00
SetDataTip ( STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP , STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP_TOOLTIP ) ,
2012-11-25 15:31:45 +00:00
NWidget ( WWT_PANEL , COLOUR_BROWN ) , SetFill ( 1 , 0 ) , SetResize ( 0 , 0 ) , EndContainer ( ) ,
2012-11-25 15:24:02 +00:00
NWidget ( WWT_DROPDOWN , COLOUR_BROWN , WID_IC_IND_DROPDOWN ) , SetFill ( 0 , 0 ) , SetResize ( 0 , 0 ) ,
SetDataTip ( STR_INDUSTRY_CARGOES_SELECT_INDUSTRY , STR_INDUSTRY_CARGOES_SELECT_INDUSTRY_TOOLTIP ) ,
NWidget ( WWT_DROPDOWN , COLOUR_BROWN , WID_IC_CARGO_DROPDOWN ) , SetFill ( 0 , 0 ) , SetResize ( 0 , 0 ) ,
SetDataTip ( STR_INDUSTRY_CARGOES_SELECT_CARGO , STR_INDUSTRY_CARGOES_SELECT_CARGO_TOOLTIP ) ,
2010-08-08 11:17:14 +00:00
EndContainer ( ) ,
EndContainer ( ) ,
2010-07-23 18:39:02 +00:00
NWidget ( NWID_VERTICAL ) ,
2011-12-16 16:39:48 +00:00
NWidget ( NWID_VSCROLLBAR , COLOUR_BROWN , WID_IC_SCROLLBAR ) ,
2010-07-23 18:39:02 +00:00
NWidget ( WWT_RESIZEBOX , COLOUR_BROWN ) ,
EndContainer ( ) ,
EndContainer ( ) ,
} ;
/** Window description for the industry cargoes window. */
static const WindowDesc _industry_cargoes_desc (
2010-07-25 12:38:06 +00:00
WDP_AUTO , 300 , 210 ,
2010-07-23 18:39:02 +00:00
WC_INDUSTRY_CARGOES , WC_NONE ,
0 ,
_nested_industry_cargoes_widgets , lengthof ( _nested_industry_cargoes_widgets )
) ;
/** Available types of field. */
enum CargoesFieldType {
CFT_EMPTY , ///< Empty field.
CFT_SMALL_EMPTY , ///< Empty small field (for the header).
CFT_INDUSTRY , ///< Display industry.
CFT_CARGO , ///< Display cargo connections.
CFT_CARGO_LABEL , ///< Display cargo labels.
CFT_HEADER , ///< Header text.
} ;
static const uint MAX_CARGOES = 3 ; ///< Maximum number of cargoes carried in a #CFT_CARGO field in #CargoesField.
/** Data about a single field in the #IndustryCargoesWindow panel. */
struct CargoesField {
static const int VERT_INTER_INDUSTRY_SPACE ;
static const int HOR_CARGO_BORDER_SPACE ;
static const int CARGO_STUB_WIDTH ;
static const int HOR_CARGO_WIDTH , HOR_CARGO_SPACE ;
static const int CARGO_FIELD_WIDTH ;
static const int VERT_CARGO_SPACE , VERT_CARGO_EDGE ;
2010-08-07 20:36:23 +00:00
static const int BLOB_DISTANCE , BLOB_WIDTH , BLOB_HEIGHT ;
2010-07-23 18:39:02 +00:00
static const int INDUSTRY_LINE_COLOUR ;
static const int CARGO_LINE_COLOUR ;
static int small_height , normal_height ;
static int industry_width ;
CargoesFieldType type ; ///< Type of field.
union {
struct {
IndustryType ind_type ; ///< Industry type (#NUM_INDUSTRYTYPES means 'houses').
CargoID other_produced [ MAX_CARGOES ] ; ///< Cargoes produced but not used in this figure.
CargoID other_accepted [ MAX_CARGOES ] ; ///< Cargoes accepted but not used in this figure.
} industry ; ///< Industry data (for #CFT_INDUSTRY).
struct {
CargoID vertical_cargoes [ MAX_CARGOES ] ; ///< Cargoes running from top to bottom (cargo ID or #INVALID_CARGO).
byte num_cargoes ; ///< Number of cargoes.
CargoID supp_cargoes [ MAX_CARGOES ] ; ///< Cargoes entering from the left (index in #vertical_cargoes, or #INVALID_CARGO).
byte top_end ; ///< Stop at the top of the vertical cargoes.
CargoID cust_cargoes [ MAX_CARGOES ] ; ///< Cargoes leaving to the right (index in #vertical_cargoes, or #INVALID_CARGO).
byte bottom_end ; ///< Stop at the bottom of the vertical cargoes.
} cargo ; ///< Cargo data (for #CFT_CARGO).
struct {
CargoID cargoes [ MAX_CARGOES ] ; ///< Cargoes to display (or #INVALID_CARGO).
bool left_align ; ///< Align all cargo texts to the left (else align to the right).
} cargo_label ; ///< Label data (for #CFT_CARGO_LABEL).
StringID header ; ///< Header text (for #CFT_HEADER).
} u ; // Data for each type.
/**
* Make one of the empty fields ( # CFT_EMPTY or # CFT_SMALL_EMPTY ) .
* @ param type Type of empty field .
*/
void MakeEmpty ( CargoesFieldType type )
{
this - > type = type ;
}
/**
* Make an industry type field .
* @ param ind_type Industry type ( # NUM_INDUSTRYTYPES means ' houses ' ) .
* @ note # other_accepted and # other_produced should be filled later .
*/
void MakeIndustry ( IndustryType ind_type )
{
this - > type = CFT_INDUSTRY ;
this - > u . industry . ind_type = ind_type ;
MemSetT ( this - > u . industry . other_accepted , INVALID_CARGO , MAX_CARGOES ) ;
MemSetT ( this - > u . industry . other_produced , INVALID_CARGO , MAX_CARGOES ) ;
}
/**
* Connect a cargo from an industry to the # CFT_CARGO column .
* @ param cargo Cargo to connect .
* @ param produced Cargo is produced ( if \ c false , cargo is assumed to be accepted ) .
* @ return Horizontal connection index , or \ c - 1 if not accepted at all .
*/
int ConnectCargo ( CargoID cargo , bool producer )
{
assert ( this - > type = = CFT_CARGO ) ;
if ( cargo = = INVALID_CARGO ) return - 1 ;
/* Find the vertical cargo column carrying the cargo. */
int column = - 1 ;
for ( int i = 0 ; i < this - > u . cargo . num_cargoes ; i + + ) {
if ( cargo = = this - > u . cargo . vertical_cargoes [ i ] ) {
column = i ;
break ;
}
}
if ( column < 0 ) return - 1 ;
if ( producer ) {
assert ( this - > u . cargo . supp_cargoes [ column ] = = INVALID_CARGO ) ;
this - > u . cargo . supp_cargoes [ column ] = column ;
} else {
assert ( this - > u . cargo . cust_cargoes [ column ] = = INVALID_CARGO ) ;
this - > u . cargo . cust_cargoes [ column ] = column ;
}
return column ;
}
/**
* Does this # CFT_CARGO field have a horizontal connection ?
* @ return \ c true if a horizontal connection exists , \ c false otherwise .
*/
bool HasConnection ( )
{
assert ( this - > type = = CFT_CARGO ) ;
for ( uint i = 0 ; i < MAX_CARGOES ; i + + ) {
if ( this - > u . cargo . supp_cargoes [ i ] ! = INVALID_CARGO ) return true ;
if ( this - > u . cargo . cust_cargoes [ i ] ! = INVALID_CARGO ) return true ;
}
return false ;
}
/**
* Make a piece of cargo column .
* @ param cargoes Array of # CargoID ( may contain # INVALID_CARGO ) .
2012-07-10 18:37:54 +00:00
* @ param length Number of cargoes in \ a cargoes .
2010-07-23 18:39:02 +00:00
* @ param count Number of cargoes to display ( should be at least the number of valid cargoes , or \ c - 1 to let the method compute it ) .
* @ param top_end This is the first cargo field of this column .
* @ param bottom_end This is the last cargo field of this column .
* @ note # supp_cargoes and # cust_cargoes should be filled in later .
*/
void MakeCargo ( const CargoID * cargoes , uint length , int count = - 1 , bool top_end = false , bool bottom_end = false )
{
this - > type = CFT_CARGO ;
uint i ;
uint num = 0 ;
for ( i = 0 ; i < MAX_CARGOES & & i < length ; i + + ) {
if ( cargoes [ i ] ! = INVALID_CARGO ) {
this - > u . cargo . vertical_cargoes [ num ] = cargoes [ i ] ;
num + + ;
}
}
this - > u . cargo . num_cargoes = ( count < 0 ) ? num : count ;
for ( ; num < MAX_CARGOES ; num + + ) this - > u . cargo . vertical_cargoes [ num ] = INVALID_CARGO ;
this - > u . cargo . top_end = top_end ;
this - > u . cargo . bottom_end = bottom_end ;
MemSetT ( this - > u . cargo . supp_cargoes , INVALID_CARGO , MAX_CARGOES ) ;
MemSetT ( this - > u . cargo . cust_cargoes , INVALID_CARGO , MAX_CARGOES ) ;
}
/**
* Make a field displaying cargo type names .
* @ param cargoes Array of # CargoID ( may contain # INVALID_CARGO ) .
2012-07-10 18:37:54 +00:00
* @ param length Number of cargoes in \ a cargoes .
2010-07-23 18:39:02 +00:00
* @ param left_align ALign texts to the left ( else to the right ) .
*/
void MakeCargoLabel ( const CargoID * cargoes , uint length , bool left_align )
{
this - > type = CFT_CARGO_LABEL ;
uint i ;
for ( i = 0 ; i < MAX_CARGOES & & i < length ; i + + ) this - > u . cargo_label . cargoes [ i ] = cargoes [ i ] ;
for ( ; i < MAX_CARGOES ; i + + ) this - > u . cargo_label . cargoes [ i ] = INVALID_CARGO ;
this - > u . cargo_label . left_align = left_align ;
}
/**
* Make a header above an industry column .
* @ param textid Text to display .
*/
void MakeHeader ( StringID textid )
{
this - > type = CFT_HEADER ;
this - > u . header = textid ;
}
/**
* For a # CFT_CARGO , compute the left position of the left - most vertical cargo connection .
* @ param xpos Left position of the field .
* @ return Left position of the left - most vertical cargo column .
*/
int GetCargoBase ( int xpos ) const
{
assert ( this - > type = = CFT_CARGO ) ;
switch ( this - > u . cargo . num_cargoes ) {
case 0 : return xpos + CARGO_FIELD_WIDTH / 2 ;
case 1 : return xpos + CARGO_FIELD_WIDTH / 2 - HOR_CARGO_WIDTH / 2 ;
case 2 : return xpos + CARGO_FIELD_WIDTH / 2 - HOR_CARGO_WIDTH - HOR_CARGO_SPACE / 2 ;
case 3 : return xpos + CARGO_FIELD_WIDTH / 2 - HOR_CARGO_WIDTH - HOR_CARGO_SPACE - HOR_CARGO_WIDTH / 2 ;
default : NOT_REACHED ( ) ;
}
}
/**
* Draw the field .
* @ param xpos Position of the left edge .
* @ param vpos Position of the top edge .
*/
void Draw ( int xpos , int ypos ) const
{
switch ( this - > type ) {
case CFT_EMPTY :
case CFT_SMALL_EMPTY :
break ;
case CFT_HEADER :
ypos + = ( small_height - FONT_HEIGHT_NORMAL ) / 2 ;
DrawString ( xpos , xpos + industry_width , ypos , this - > u . header , TC_WHITE , SA_HOR_CENTER ) ;
break ;
case CFT_INDUSTRY : {
int ypos1 = ypos + VERT_INTER_INDUSTRY_SPACE / 2 ;
int ypos2 = ypos + normal_height - 1 - VERT_INTER_INDUSTRY_SPACE / 2 ;
int xpos2 = xpos + industry_width - 1 ;
GfxDrawLine ( xpos , ypos1 , xpos2 , ypos1 , INDUSTRY_LINE_COLOUR ) ;
GfxDrawLine ( xpos , ypos1 , xpos , ypos2 , INDUSTRY_LINE_COLOUR ) ;
GfxDrawLine ( xpos , ypos2 , xpos2 , ypos2 , INDUSTRY_LINE_COLOUR ) ;
GfxDrawLine ( xpos2 , ypos1 , xpos2 , ypos2 , INDUSTRY_LINE_COLOUR ) ;
ypos + = ( normal_height - FONT_HEIGHT_NORMAL ) / 2 ;
if ( this - > u . industry . ind_type < NUM_INDUSTRYTYPES ) {
2010-08-07 20:36:23 +00:00
const IndustrySpec * indsp = GetIndustrySpec ( this - > u . industry . ind_type ) ;
SetDParam ( 0 , indsp - > name ) ;
2010-07-23 18:39:02 +00:00
DrawString ( xpos , xpos2 , ypos , STR_JUST_STRING , TC_WHITE , SA_HOR_CENTER ) ;
2010-08-07 20:36:23 +00:00
/* Draw the industry legend. */
int blob_left , blob_right ;
2010-11-13 09:56:25 +00:00
if ( _current_text_dir = = TD_RTL ) {
2010-08-07 20:36:23 +00:00
blob_right = xpos2 - BLOB_DISTANCE ;
blob_left = blob_right - BLOB_WIDTH ;
} else {
blob_left = xpos + BLOB_DISTANCE ;
blob_right = blob_left + BLOB_WIDTH ;
}
2011-05-06 21:13:29 +00:00
GfxFillRect ( blob_left , ypos2 - BLOB_DISTANCE - BLOB_HEIGHT , blob_right , ypos2 - BLOB_DISTANCE , PC_BLACK ) ; // Border
2010-08-07 20:36:23 +00:00
GfxFillRect ( blob_left + 1 , ypos2 - BLOB_DISTANCE - BLOB_HEIGHT + 1 , blob_right - 1 , ypos2 - BLOB_DISTANCE - 1 , indsp - > map_colour ) ;
2010-07-23 18:39:02 +00:00
} else {
DrawString ( xpos , xpos2 , ypos , STR_INDUSTRY_CARGOES_HOUSES , TC_FROMSTRING , SA_HOR_CENTER ) ;
}
/* Draw the other_produced/other_accepted cargoes. */
const CargoID * other_right , * other_left ;
2010-11-13 09:56:25 +00:00
if ( _current_text_dir = = TD_RTL ) {
2010-07-23 18:39:02 +00:00
other_right = this - > u . industry . other_accepted ;
other_left = this - > u . industry . other_produced ;
} else {
other_right = this - > u . industry . other_produced ;
other_left = this - > u . industry . other_accepted ;
}
ypos1 + = VERT_CARGO_EDGE ;
for ( uint i = 0 ; i < MAX_CARGOES ; i + + ) {
if ( other_right [ i ] ! = INVALID_CARGO ) {
const CargoSpec * csp = CargoSpec : : Get ( other_right [ i ] ) ;
int xp = xpos + industry_width + CARGO_STUB_WIDTH ;
DrawHorConnection ( xpos + industry_width , xp - 1 , ypos1 , csp ) ;
GfxDrawLine ( xp , ypos1 , xp , ypos1 + FONT_HEIGHT_NORMAL - 1 , CARGO_LINE_COLOUR ) ;
}
if ( other_left [ i ] ! = INVALID_CARGO ) {
const CargoSpec * csp = CargoSpec : : Get ( other_left [ i ] ) ;
int xp = xpos - CARGO_STUB_WIDTH ;
DrawHorConnection ( xp + 1 , xpos - 1 , ypos1 , csp ) ;
GfxDrawLine ( xp , ypos1 , xp , ypos1 + FONT_HEIGHT_NORMAL - 1 , CARGO_LINE_COLOUR ) ;
}
ypos1 + = FONT_HEIGHT_NORMAL + VERT_CARGO_SPACE ;
}
break ;
}
case CFT_CARGO : {
int cargo_base = this - > GetCargoBase ( xpos ) ;
int top = ypos + ( this - > u . cargo . top_end ? VERT_INTER_INDUSTRY_SPACE / 2 + 1 : 0 ) ;
int bot = ypos - ( this - > u . cargo . bottom_end ? VERT_INTER_INDUSTRY_SPACE / 2 + 1 : 0 ) + normal_height - 1 ;
int colpos = cargo_base ;
for ( int i = 0 ; i < this - > u . cargo . num_cargoes ; i + + ) {
if ( this - > u . cargo . top_end ) GfxDrawLine ( colpos , top - 1 , colpos + HOR_CARGO_WIDTH - 1 , top - 1 , CARGO_LINE_COLOUR ) ;
if ( this - > u . cargo . bottom_end ) GfxDrawLine ( colpos , bot + 1 , colpos + HOR_CARGO_WIDTH - 1 , bot + 1 , CARGO_LINE_COLOUR ) ;
GfxDrawLine ( colpos , top , colpos , bot , CARGO_LINE_COLOUR ) ;
colpos + + ;
const CargoSpec * csp = CargoSpec : : Get ( this - > u . cargo . vertical_cargoes [ i ] ) ;
GfxFillRect ( colpos , top , colpos + HOR_CARGO_WIDTH - 2 , bot , csp - > legend_colour , FILLRECT_OPAQUE ) ;
colpos + = HOR_CARGO_WIDTH - 2 ;
GfxDrawLine ( colpos , top , colpos , bot , CARGO_LINE_COLOUR ) ;
colpos + = 1 + HOR_CARGO_SPACE ;
}
const CargoID * hor_left , * hor_right ;
2010-11-13 09:56:25 +00:00
if ( _current_text_dir = = TD_RTL ) {
2010-07-23 18:39:02 +00:00
hor_left = this - > u . cargo . cust_cargoes ;
hor_right = this - > u . cargo . supp_cargoes ;
} else {
hor_left = this - > u . cargo . supp_cargoes ;
hor_right = this - > u . cargo . cust_cargoes ;
}
ypos + = VERT_CARGO_EDGE + VERT_INTER_INDUSTRY_SPACE / 2 ;
for ( uint i = 0 ; i < MAX_CARGOES ; i + + ) {
if ( hor_left [ i ] ! = INVALID_CARGO ) {
int col = hor_left [ i ] ;
int dx = 0 ;
const CargoSpec * csp = CargoSpec : : Get ( this - > u . cargo . vertical_cargoes [ col ] ) ;
for ( ; col > 0 ; col - - ) {
int lf = cargo_base + col * HOR_CARGO_WIDTH + ( col - 1 ) * HOR_CARGO_SPACE ;
DrawHorConnection ( lf , lf + HOR_CARGO_SPACE - dx , ypos , csp ) ;
dx = 1 ;
}
DrawHorConnection ( xpos , cargo_base - dx , ypos , csp ) ;
}
if ( hor_right [ i ] ! = INVALID_CARGO ) {
int col = hor_right [ i ] ;
int dx = 0 ;
const CargoSpec * csp = CargoSpec : : Get ( this - > u . cargo . vertical_cargoes [ col ] ) ;
for ( ; col < this - > u . cargo . num_cargoes - 1 ; col + + ) {
int lf = cargo_base + ( col + 1 ) * HOR_CARGO_WIDTH + col * HOR_CARGO_SPACE ;
DrawHorConnection ( lf + dx - 1 , lf + HOR_CARGO_SPACE - 1 , ypos , csp ) ;
dx = 1 ;
}
DrawHorConnection ( cargo_base + col * HOR_CARGO_SPACE + ( col + 1 ) * HOR_CARGO_WIDTH - 1 + dx , xpos + CARGO_FIELD_WIDTH - 1 , ypos , csp ) ;
}
ypos + = FONT_HEIGHT_NORMAL + VERT_CARGO_SPACE ;
}
break ;
}
case CFT_CARGO_LABEL :
ypos + = VERT_CARGO_EDGE + VERT_INTER_INDUSTRY_SPACE / 2 ;
for ( uint i = 0 ; i < MAX_CARGOES ; i + + ) {
if ( this - > u . cargo_label . cargoes [ i ] ! = INVALID_CARGO ) {
const CargoSpec * csp = CargoSpec : : Get ( this - > u . cargo_label . cargoes [ i ] ) ;
DrawString ( xpos + WD_FRAMERECT_LEFT , xpos + industry_width - 1 - WD_FRAMERECT_RIGHT , ypos , csp - > name , TC_WHITE ,
( this - > u . cargo_label . left_align ) ? SA_LEFT : SA_RIGHT ) ;
}
ypos + = FONT_HEIGHT_NORMAL + VERT_CARGO_SPACE ;
}
break ;
default :
NOT_REACHED ( ) ;
}
}
/**
* Decide which cargo was clicked at in a # CFT_CARGO field .
* @ param left Left industry neighbour if available ( else \ c NULL should be supplied ) .
* @ param right Right industry neighbour if available ( else \ c NULL should be supplied ) .
* @ param pt Click position in the cargo field .
* @ return Cargo clicked at , or # INVALID_CARGO if none .
*/
CargoID CargoClickedAt ( const CargoesField * left , const CargoesField * right , Point pt ) const
{
assert ( this - > type = = CFT_CARGO ) ;
/* Vertical matching. */
int cpos = this - > GetCargoBase ( 0 ) ;
uint col ;
for ( col = 0 ; col < this - > u . cargo . num_cargoes ; col + + ) {
if ( pt . x < cpos ) break ;
if ( pt . x < cpos + CargoesField : : HOR_CARGO_WIDTH ) return this - > u . cargo . vertical_cargoes [ col ] ;
cpos + = CargoesField : : HOR_CARGO_WIDTH + CargoesField : : HOR_CARGO_SPACE ;
}
2011-01-30 12:58:54 +00:00
/* col = 0 -> left of first col, 1 -> left of 2nd col, ... this->u.cargo.num_cargoes right of last-col. */
2010-07-23 18:39:02 +00:00
int vpos = VERT_INTER_INDUSTRY_SPACE / 2 + VERT_CARGO_EDGE ;
uint row ;
for ( row = 0 ; row < MAX_CARGOES ; row + + ) {
if ( pt . y < vpos ) return INVALID_CARGO ;
if ( pt . y < vpos + FONT_HEIGHT_NORMAL ) break ;
vpos + = FONT_HEIGHT_NORMAL + VERT_CARGO_SPACE ;
}
if ( row = = MAX_CARGOES ) return INVALID_CARGO ;
2011-01-30 12:58:54 +00:00
/* row = 0 -> at first horizontal row, row = 1 -> second horizontal row, 2 = 3rd horizontal row. */
2010-07-23 18:39:02 +00:00
if ( col = = 0 ) {
if ( this - > u . cargo . supp_cargoes [ row ] ! = INVALID_CARGO ) return this - > u . cargo . vertical_cargoes [ this - > u . cargo . supp_cargoes [ row ] ] ;
if ( left ! = NULL ) {
if ( left - > type = = CFT_INDUSTRY ) return left - > u . industry . other_produced [ row ] ;
if ( left - > type = = CFT_CARGO_LABEL & & ! left - > u . cargo_label . left_align ) return left - > u . cargo_label . cargoes [ row ] ;
}
return INVALID_CARGO ;
}
if ( col = = this - > u . cargo . num_cargoes ) {
if ( this - > u . cargo . cust_cargoes [ row ] ! = INVALID_CARGO ) return this - > u . cargo . vertical_cargoes [ this - > u . cargo . cust_cargoes [ row ] ] ;
if ( right ! = NULL ) {
if ( right - > type = = CFT_INDUSTRY ) return right - > u . industry . other_accepted [ row ] ;
if ( right - > type = = CFT_CARGO_LABEL & & right - > u . cargo_label . left_align ) return right - > u . cargo_label . cargoes [ row ] ;
}
return INVALID_CARGO ;
}
if ( row > = col ) {
/* Clicked somewhere in-between vertical cargo connection.
* Since the horizontal connection is made in the same order as the vertical list , the above condition
* ensures we are left - below the main diagonal , thus at the supplying side .
*/
return ( this - > u . cargo . supp_cargoes [ row ] ! = INVALID_CARGO ) ? this - > u . cargo . vertical_cargoes [ this - > u . cargo . supp_cargoes [ row ] ] : INVALID_CARGO ;
} else {
/* Clicked at a customer connection. */
return ( this - > u . cargo . cust_cargoes [ row ] ! = INVALID_CARGO ) ? this - > u . cargo . vertical_cargoes [ this - > u . cargo . cust_cargoes [ row ] ] : INVALID_CARGO ;
}
}
/**
* Decide what cargo the user clicked in the cargo label field .
* @ param pt Click position in the cargo label field .
* @ return Cargo clicked at , or # INVALID_CARGO if none .
*/
CargoID CargoLabelClickedAt ( Point pt ) const
{
assert ( this - > type = = CFT_CARGO_LABEL ) ;
int vpos = VERT_INTER_INDUSTRY_SPACE / 2 + VERT_CARGO_EDGE ;
uint row ;
for ( row = 0 ; row < MAX_CARGOES ; row + + ) {
if ( pt . y < vpos ) return INVALID_CARGO ;
if ( pt . y < vpos + FONT_HEIGHT_NORMAL ) break ;
vpos + = FONT_HEIGHT_NORMAL + VERT_CARGO_SPACE ;
}
if ( row = = MAX_CARGOES ) return INVALID_CARGO ;
return this - > u . cargo_label . cargoes [ row ] ;
}
private :
/**
* Draw a horizontal cargo connection .
* @ param left Left - most coordinate to draw .
* @ param right Right - most coordinate to draw .
* @ param top Top coordinate of the cargo connection .
2012-01-01 17:36:19 +00:00
* @ param csp Cargo to draw .
2010-07-23 18:39:02 +00:00
*/
static void DrawHorConnection ( int left , int right , int top , const CargoSpec * csp )
{
GfxDrawLine ( left , top , right , top , CARGO_LINE_COLOUR ) ;
GfxFillRect ( left , top + 1 , right , top + FONT_HEIGHT_NORMAL - 2 , csp - > legend_colour , FILLRECT_OPAQUE ) ;
GfxDrawLine ( left , top + FONT_HEIGHT_NORMAL - 1 , right , top + FONT_HEIGHT_NORMAL - 1 , CARGO_LINE_COLOUR ) ;
}
} ;
2010-07-23 19:07:00 +00:00
assert_compile ( MAX_CARGOES > = cpp_lengthof ( IndustrySpec , produced_cargo ) ) ;
assert_compile ( MAX_CARGOES > = cpp_lengthof ( IndustrySpec , accepts_cargo ) ) ;
2010-07-23 18:39:02 +00:00
int CargoesField : : small_height ; ///< Height of the header row.
int CargoesField : : normal_height ; ///< Height of the non-header rows.
int CargoesField : : industry_width ; ///< Width of an industry field.
const int CargoesField : : VERT_INTER_INDUSTRY_SPACE = 6 ; ///< Amount of space between two industries in a column.
const int CargoesField : : HOR_CARGO_BORDER_SPACE = 15 ; ///< Amount of space between the left/right edge of a #CFT_CARGO field, and the left/right most vertical cargo.
const int CargoesField : : CARGO_STUB_WIDTH = 10 ; ///< Width of a cargo not carried in the column (should be less than #HOR_CARGO_BORDER_SPACE).
const int CargoesField : : HOR_CARGO_WIDTH = 15 ; ///< Width of a vertical cargo column (inclusive the border line).
const int CargoesField : : HOR_CARGO_SPACE = 5 ; ///< Amount of horizontal space between two vertical cargoes.
const int CargoesField : : VERT_CARGO_EDGE = 4 ; ///< Amount of vertical space between top/bottom and the top/bottom connected cargo at an industry.
const int CargoesField : : VERT_CARGO_SPACE = 4 ; ///< Amount of vertical space between two connected cargoes at an industry.
2010-08-07 20:36:23 +00:00
const int CargoesField : : BLOB_DISTANCE = 5 ; ///< Distance of the industry legend colour from the edge of the industry box.
const int CargoesField : : BLOB_WIDTH = 12 ; ///< Width of the industry legend colour, including border.
const int CargoesField : : BLOB_HEIGHT = 9 ; ///< Height of the industry legend colour, including border
2010-07-23 18:39:02 +00:00
/** Width of a #CFT_CARGO field. */
const int CargoesField : : CARGO_FIELD_WIDTH = HOR_CARGO_BORDER_SPACE * 2 + HOR_CARGO_WIDTH * MAX_CARGOES + HOR_CARGO_SPACE * ( MAX_CARGOES - 1 ) ;
2011-05-06 21:13:29 +00:00
const int CargoesField : : INDUSTRY_LINE_COLOUR = PC_YELLOW ; ///< Line colour of the industry type box.
const int CargoesField : : CARGO_LINE_COLOUR = PC_YELLOW ; ///< Line colour around the cargo.
2010-07-23 18:39:02 +00:00
/** A single row of #CargoesField. */
struct CargoesRow {
CargoesField columns [ 5 ] ; ///< One row of fields.
/**
* Connect industry production cargoes to the cargo column after it .
* @ param column Column of the industry .
*/
void ConnectIndustryProduced ( int column )
{
CargoesField * ind_fld = this - > columns + column ;
CargoesField * cargo_fld = this - > columns + column + 1 ;
assert ( ind_fld - > type = = CFT_INDUSTRY & & cargo_fld - > type = = CFT_CARGO ) ;
MemSetT ( ind_fld - > u . industry . other_produced , INVALID_CARGO , MAX_CARGOES ) ;
if ( ind_fld - > u . industry . ind_type < NUM_INDUSTRYTYPES ) {
CargoID others [ MAX_CARGOES ] ; // Produced cargoes not carried in the cargo column.
int other_count = 0 ;
const IndustrySpec * indsp = GetIndustrySpec ( ind_fld - > u . industry . ind_type ) ;
for ( uint i = 0 ; i < lengthof ( indsp - > produced_cargo ) ; i + + ) {
int col = cargo_fld - > ConnectCargo ( indsp - > produced_cargo [ i ] , true ) ;
if ( col < 0 ) others [ other_count + + ] = indsp - > produced_cargo [ i ] ;
}
/* Allocate other cargoes in the empty holes of the horizontal cargo connections. */
for ( uint i = 0 ; i < MAX_CARGOES & & other_count > 0 ; i + + ) {
if ( cargo_fld - > u . cargo . supp_cargoes [ i ] = = INVALID_CARGO ) ind_fld - > u . industry . other_produced [ i ] = others [ - - other_count ] ;
}
} else {
/* Houses only display what is demanded. */
for ( uint i = 0 ; i < cargo_fld - > u . cargo . num_cargoes ; i + + ) {
CargoID cid = cargo_fld - > u . cargo . vertical_cargoes [ i ] ;
if ( cid = = CT_PASSENGERS | | cid = = CT_MAIL ) cargo_fld - > ConnectCargo ( cid , true ) ;
}
}
}
/**
* Construct a # CFT_CARGO_LABEL field .
* @ param column Column to create the new field .
* @ param accepting Display accepted cargo ( if \ c false , display produced cargo ) .
*/
void MakeCargoLabel ( int column , bool accepting )
{
CargoID cargoes [ MAX_CARGOES ] ;
MemSetT ( cargoes , INVALID_CARGO , lengthof ( cargoes ) ) ;
CargoesField * label_fld = this - > columns + column ;
CargoesField * cargo_fld = this - > columns + ( accepting ? column - 1 : column + 1 ) ;
assert ( cargo_fld - > type = = CFT_CARGO & & label_fld - > type = = CFT_EMPTY ) ;
for ( uint i = 0 ; i < cargo_fld - > u . cargo . num_cargoes ; i + + ) {
int col = cargo_fld - > ConnectCargo ( cargo_fld - > u . cargo . vertical_cargoes [ i ] , ! accepting ) ;
cargoes [ col ] = cargo_fld - > u . cargo . vertical_cargoes [ i ] ;
}
label_fld - > MakeCargoLabel ( cargoes , lengthof ( cargoes ) , accepting ) ;
}
/**
* Connect industry accepted cargoes to the cargo column before it .
* @ param column Column of the industry .
*/
void ConnectIndustryAccepted ( int column )
{
CargoesField * ind_fld = this - > columns + column ;
CargoesField * cargo_fld = this - > columns + column - 1 ;
assert ( ind_fld - > type = = CFT_INDUSTRY & & cargo_fld - > type = = CFT_CARGO ) ;
MemSetT ( ind_fld - > u . industry . other_accepted , INVALID_CARGO , MAX_CARGOES ) ;
if ( ind_fld - > u . industry . ind_type < NUM_INDUSTRYTYPES ) {
CargoID others [ MAX_CARGOES ] ; // Accepted cargoes not carried in the cargo column.
int other_count = 0 ;
const IndustrySpec * indsp = GetIndustrySpec ( ind_fld - > u . industry . ind_type ) ;
for ( uint i = 0 ; i < lengthof ( indsp - > accepts_cargo ) ; i + + ) {
int col = cargo_fld - > ConnectCargo ( indsp - > accepts_cargo [ i ] , false ) ;
if ( col < 0 ) others [ other_count + + ] = indsp - > accepts_cargo [ i ] ;
}
/* Allocate other cargoes in the empty holes of the horizontal cargo connections. */
for ( uint i = 0 ; i < MAX_CARGOES & & other_count > 0 ; i + + ) {
if ( cargo_fld - > u . cargo . cust_cargoes [ i ] = = INVALID_CARGO ) ind_fld - > u . industry . other_accepted [ i ] = others [ - - other_count ] ;
}
} else {
/* Houses only display what is demanded. */
for ( uint i = 0 ; i < cargo_fld - > u . cargo . num_cargoes ; i + + ) {
for ( uint h = 0 ; h < HOUSE_MAX ; h + + ) {
HouseSpec * hs = HouseSpec : : Get ( h ) ;
if ( ! hs - > enabled ) continue ;
for ( uint j = 0 ; j < lengthof ( hs - > accepts_cargo ) ; j + + ) {
if ( cargo_fld - > u . cargo . vertical_cargoes [ i ] = = hs - > accepts_cargo [ j ] ) {
cargo_fld - > ConnectCargo ( cargo_fld - > u . cargo . vertical_cargoes [ i ] , false ) ;
goto next_cargo ;
}
}
}
next_cargo : ;
}
}
}
} ;
/**
* Window displaying the cargo connections around an industry ( or cargo ) .
*
* The main display is constructed from ' fields ' , rectangles that contain an industry , piece of the cargo connection , cargo labels , or headers .
* For a nice display , the following should be kept in mind :
* - A # CFT_HEADER is always at the top of an column of # CFT_INDUSTRY fields .
* - A # CFT_CARGO_LABEL field is also always put in a column of # CFT_INDUSTRY fields .
* - The top row contains # CFT_HEADER and # CFT_SMALL_EMPTY fields .
* - Cargo connections have a column of their own ( # CFT_CARGO fields ) .
* - Cargo accepted or produced by an industry , but not carried in a cargo connection , is drawn in the space of a cargo column attached to the industry .
* The information however is part of the industry .
*
* This results in the following invariants :
* - Width of a # CFT_INDUSTRY column is large enough to hold all industry type labels , all cargo labels , and all header texts .
* - Height of a # CFT_INDUSTRY is large enough to hold a header line , or a industry type line , \ c N cargo labels
* ( where \ c N is the maximum number of cargoes connected between industries ) , \ c N connections of cargo types , and space
* between two industry types ( 1 / 2 above it , and 1 / 2 underneath it ) .
* - Width of a cargo field ( # CFT_CARGO ) is large enough to hold \ c N vertical columns ( one for each type of cargo ) .
* Also , space is needed between an industry and the leftmost / rightmost column to draw the non - carried cargoes .
* - Height of a # CFT_CARGO field is equally high as the height of the # CFT_INDUSTRY .
* - A field at the top ( # CFT_HEADER or # CFT_SMALL_EMPTY ) match the width of the fields below them ( # CFT_INDUSTRY respectively
* # CFT_CARGO ) , the height should be sufficient to display the header text .
*
* When displaying the cargoes around an industry type , five columns are needed ( supplying industries , accepted cargoes , the industry ,
* produced cargoes , customer industries ) . Displaying the industries around a cargo needs three columns ( supplying industries , the cargo ,
2010-10-30 17:51:07 +00:00
* customer industries ) . The remaining two columns are set to # CFT_EMPTY with a width equal to the average of a cargo and an industry column .
2010-07-23 18:39:02 +00:00
*/
struct IndustryCargoesWindow : public Window {
static const int HOR_TEXT_PADDING , VERT_TEXT_PADDING ;
typedef SmallVector < CargoesRow , 4 > Fields ;
2011-12-16 16:39:48 +00:00
Fields fields ; ///< Fields to display in the #WID_IC_PANEL.
2010-07-23 18:39:02 +00:00
uint ind_cargo ; ///< If less than #NUM_INDUSTRYTYPES, an industry type, else a cargo id + NUM_INDUSTRYTYPES.
2012-11-25 15:24:02 +00:00
Dimension cargo_textsize ; ///< Size to hold any cargo text, as well as STR_INDUSTRY_CARGOES_SELECT_CARGO.
Dimension ind_textsize ; ///< Size to hold any industry type text, as well as STR_INDUSTRY_CARGOES_SELECT_INDUSTRY.
2010-08-12 08:37:01 +00:00
Scrollbar * vscroll ;
2010-07-23 18:39:02 +00:00
IndustryCargoesWindow ( int id ) : Window ( )
{
this - > OnInit ( ) ;
2010-08-12 08:37:01 +00:00
this - > CreateNestedTree ( & _industry_cargoes_desc ) ;
2011-12-16 16:39:48 +00:00
this - > vscroll = this - > GetScrollbar ( WID_IC_SCROLLBAR ) ;
2010-08-12 08:37:01 +00:00
this - > FinishInitNested ( & _industry_cargoes_desc , 0 ) ;
2010-07-23 18:39:02 +00:00
this - > OnInvalidateData ( id ) ;
}
virtual void OnInit ( )
{
/* Initialize static CargoesField size variables. */
Dimension d = GetStringBoundingBox ( STR_INDUSTRY_CARGOES_PRODUCERS ) ;
d = maxdim ( d , GetStringBoundingBox ( STR_INDUSTRY_CARGOES_CUSTOMERS ) ) ;
d . width + = WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT ;
d . height + = WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM ;
CargoesField : : small_height = d . height ;
/* Decide about the size of the box holding the text of an industry type. */
2012-11-25 15:24:02 +00:00
this - > ind_textsize . width = 0 ;
this - > ind_textsize . height = 0 ;
2010-07-23 18:39:02 +00:00
for ( IndustryType it = 0 ; it < NUM_INDUSTRYTYPES ; it + + ) {
const IndustrySpec * indsp = GetIndustrySpec ( it ) ;
if ( ! indsp - > enabled ) continue ;
2012-11-25 15:24:02 +00:00
this - > ind_textsize = maxdim ( this - > ind_textsize , GetStringBoundingBox ( indsp - > name ) ) ;
2010-07-23 18:39:02 +00:00
}
2012-11-25 15:24:02 +00:00
d . width = max ( d . width , this - > ind_textsize . width ) ;
d . height = this - > ind_textsize . height ;
this - > ind_textsize = maxdim ( this - > ind_textsize , GetStringBoundingBox ( STR_INDUSTRY_CARGOES_SELECT_INDUSTRY ) ) ;
/* Compute max size of the cargo texts. */
this - > cargo_textsize . width = 0 ;
this - > cargo_textsize . height = 0 ;
2010-07-23 18:39:02 +00:00
for ( uint i = 0 ; i < NUM_CARGO ; i + + ) {
const CargoSpec * csp = CargoSpec : : Get ( i ) ;
if ( ! csp - > IsValid ( ) ) continue ;
2012-11-25 15:24:02 +00:00
this - > cargo_textsize = maxdim ( this - > cargo_textsize , GetStringBoundingBox ( csp - > name ) ) ;
2010-07-23 18:39:02 +00:00
}
2012-11-25 15:24:02 +00:00
d = maxdim ( d , this - > cargo_textsize ) ; // Box must also be wide enough to hold any cargo label.
this - > cargo_textsize = maxdim ( this - > cargo_textsize , GetStringBoundingBox ( STR_INDUSTRY_CARGOES_SELECT_CARGO ) ) ;
2010-07-23 18:39:02 +00:00
d . width + = 2 * HOR_TEXT_PADDING ;
/* Ensure the height is enough for the industry type text, for the horizontal connections, and for the cargo labels. */
uint min_ind_height = CargoesField : : VERT_CARGO_EDGE * 2 + MAX_CARGOES * FONT_HEIGHT_NORMAL + ( MAX_CARGOES - 1 ) * CargoesField : : VERT_CARGO_SPACE ;
d . height = max ( d . height + 2 * VERT_TEXT_PADDING , min_ind_height ) ;
CargoesField : : industry_width = d . width ;
CargoesField : : normal_height = d . height + CargoesField : : VERT_INTER_INDUSTRY_SPACE ;
}
virtual void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize )
{
2012-11-25 15:24:02 +00:00
switch ( widget ) {
case WID_IC_PANEL :
size - > width = WD_FRAMETEXT_LEFT + CargoesField : : industry_width * 3 + CargoesField : : CARGO_FIELD_WIDTH * 2 + WD_FRAMETEXT_RIGHT ;
break ;
2010-07-23 18:39:02 +00:00
2012-11-25 15:24:02 +00:00
case WID_IC_IND_DROPDOWN :
size - > width = max ( size - > width , this - > ind_textsize . width + padding . width ) ;
break ;
case WID_IC_CARGO_DROPDOWN :
size - > width = max ( size - > width , this - > cargo_textsize . width + padding . width ) ;
break ;
}
2010-07-23 18:39:02 +00:00
}
CargoesFieldType type ; ///< Type of field.
virtual void SetStringParameters ( int widget ) const
{
2011-12-16 16:39:48 +00:00
if ( widget ! = WID_IC_CAPTION ) return ;
2010-07-23 18:39:02 +00:00
if ( this - > ind_cargo < NUM_INDUSTRYTYPES ) {
const IndustrySpec * indsp = GetIndustrySpec ( this - > ind_cargo ) ;
SetDParam ( 0 , indsp - > name ) ;
} else {
const CargoSpec * csp = CargoSpec : : Get ( this - > ind_cargo - NUM_INDUSTRYTYPES ) ;
SetDParam ( 0 , csp - > name ) ;
}
}
/**
* Do the two sets of cargoes have a valid cargo in common ?
* @ param cargoes1 Base address of the first cargo array .
* @ param length1 Number of cargoes in the first cargo array .
* @ param cargoes2 Base address of the second cargo array .
* @ param length2 Number of cargoes in the second cargo array .
* @ return Arrays have at least one valid cargo in common .
*/
static bool HasCommonValidCargo ( const CargoID * cargoes1 , uint length1 , const CargoID * cargoes2 , uint length2 )
{
while ( length1 > 0 ) {
if ( * cargoes1 ! = INVALID_CARGO ) {
for ( uint i = 0 ; i < length2 ; i + + ) if ( * cargoes1 = = cargoes2 [ i ] ) return true ;
}
cargoes1 + + ;
length1 - - ;
}
return false ;
}
/**
* Can houses be used to supply one of the cargoes ?
* @ param cargoes Base address of the cargo array .
* @ param length Number of cargoes in the array .
* @ return Houses can supply at least one of the cargoes .
*/
static bool HousesCanSupply ( const CargoID * cargoes , uint length )
{
for ( uint i = 0 ; i < length ; i + + ) {
if ( cargoes [ i ] = = INVALID_CARGO ) continue ;
if ( cargoes [ i ] = = CT_PASSENGERS | | cargoes [ i ] = = CT_MAIL ) return true ;
}
return false ;
}
/**
* Can houses be used as customers of the produced cargoes ?
* @ param cargoes Base address of the cargo array .
* @ param length Number of cargoes in the array .
* @ return Houses can accept at least one of the cargoes .
*/
static bool HousesCanAccept ( const CargoID * cargoes , uint length )
{
2010-09-05 19:46:04 +00:00
HouseZones climate_mask ;
switch ( _settings_game . game_creation . landscape ) {
case LT_TEMPERATE : climate_mask = HZ_TEMP ; break ;
case LT_ARCTIC : climate_mask = HZ_SUBARTC_ABOVE | HZ_SUBARTC_BELOW ; break ;
case LT_TROPIC : climate_mask = HZ_SUBTROPIC ; break ;
case LT_TOYLAND : climate_mask = HZ_TOYLND ; break ;
default : NOT_REACHED ( ) ;
}
2010-07-23 18:39:02 +00:00
for ( uint i = 0 ; i < length ; i + + ) {
if ( cargoes [ i ] = = INVALID_CARGO ) continue ;
for ( uint h = 0 ; h < HOUSE_MAX ; h + + ) {
HouseSpec * hs = HouseSpec : : Get ( h ) ;
2010-09-05 19:46:04 +00:00
if ( ! hs - > enabled | | ! ( hs - > building_availability & climate_mask ) ) continue ;
2010-07-23 18:39:02 +00:00
for ( uint j = 0 ; j < lengthof ( hs - > accepts_cargo ) ; j + + ) {
if ( cargoes [ i ] = = hs - > accepts_cargo [ j ] ) return true ;
}
}
}
return false ;
}
/**
* Count how many industries have accepted cargoes in common with one of the supplied set .
* @ param cargoes Cargoes to search .
2012-07-10 18:37:54 +00:00
* @ param length Number of cargoes in \ a cargoes .
2010-07-23 18:39:02 +00:00
* @ return Number of industries that have an accepted cargo in common with the supplied set .
*/
static int CountMatchingAcceptingIndustries ( const CargoID * cargoes , uint length )
{
int count = 0 ;
for ( IndustryType it = 0 ; it < NUM_INDUSTRYTYPES ; it + + ) {
const IndustrySpec * indsp = GetIndustrySpec ( it ) ;
if ( ! indsp - > enabled ) continue ;
if ( HasCommonValidCargo ( cargoes , length , indsp - > accepts_cargo , lengthof ( indsp - > accepts_cargo ) ) ) count + + ;
}
return count ;
}
/**
* Count how many industries have produced cargoes in common with one of the supplied set .
* @ param cargoes Cargoes to search .
2012-07-10 18:37:54 +00:00
* @ param length Number of cargoes in \ a cargoes .
2010-07-23 18:39:02 +00:00
* @ return Number of industries that have a produced cargo in common with the supplied set .
*/
static int CountMatchingProducingIndustries ( const CargoID * cargoes , uint length )
{
int count = 0 ;
for ( IndustryType it = 0 ; it < NUM_INDUSTRYTYPES ; it + + ) {
const IndustrySpec * indsp = GetIndustrySpec ( it ) ;
if ( ! indsp - > enabled ) continue ;
if ( HasCommonValidCargo ( cargoes , length , indsp - > produced_cargo , lengthof ( indsp - > produced_cargo ) ) ) count + + ;
}
return count ;
}
/**
* Shorten the cargo column to just the part between industries .
* @ param column Column number of the cargo column .
* @ param top Current top row .
* @ param bottom Current bottom row .
*/
void ShortenCargoColumn ( int column , int top , int bottom )
{
while ( top < bottom & & ! this - > fields [ top ] . columns [ column ] . HasConnection ( ) ) {
this - > fields [ top ] . columns [ column ] . MakeEmpty ( CFT_EMPTY ) ;
top + + ;
}
this - > fields [ top ] . columns [ column ] . u . cargo . top_end = true ;
while ( bottom > top & & ! this - > fields [ bottom ] . columns [ column ] . HasConnection ( ) ) {
this - > fields [ bottom ] . columns [ column ] . MakeEmpty ( CFT_EMPTY ) ;
bottom - - ;
}
this - > fields [ bottom ] . columns [ column ] . u . cargo . bottom_end = true ;
}
/**
* Place an industry in the fields .
* @ param row Row of the new industry .
* @ param col Column of the new industry .
* @ param it Industry to place .
*/
void PlaceIndustry ( int row , int col , IndustryType it )
{
assert ( this - > fields [ row ] . columns [ col ] . type = = CFT_EMPTY ) ;
this - > fields [ row ] . columns [ col ] . MakeIndustry ( it ) ;
if ( col = = 0 ) {
this - > fields [ row ] . ConnectIndustryProduced ( col ) ;
} else {
this - > fields [ row ] . ConnectIndustryAccepted ( col ) ;
}
}
2010-08-08 11:17:14 +00:00
/**
* Notify smallmap that new displayed industries have been selected ( in # _displayed_industries ) .
*/
void NotifySmallmap ( )
{
2011-12-16 16:39:48 +00:00
if ( ! this - > IsWidgetLowered ( WID_IC_NOTIFY ) ) return ;
2010-08-08 11:17:14 +00:00
/* Only notify the smallmap window if it exists. In particular, do not
* bring it to the front to prevent messing up any nice layout of the user . */
InvalidateWindowClassesData ( WC_SMALLMAP , 0 ) ;
}
2010-07-23 18:39:02 +00:00
/**
* Compute what and where to display for industry type \ a it .
* @ param it Industry type to display .
*/
void ComputeIndustryDisplay ( IndustryType it )
{
2011-12-16 16:39:48 +00:00
this - > GetWidget < NWidgetCore > ( WID_IC_CAPTION ) - > widget_data = STR_INDUSTRY_CARGOES_INDUSTRY_CAPTION ;
2010-07-23 18:39:02 +00:00
this - > ind_cargo = it ;
2010-08-10 16:17:51 +00:00
_displayed_industries = 1ULL < < it ;
2010-07-23 18:39:02 +00:00
this - > fields . Clear ( ) ;
CargoesRow * row = this - > fields . Append ( ) ;
row - > columns [ 0 ] . MakeHeader ( STR_INDUSTRY_CARGOES_PRODUCERS ) ;
row - > columns [ 1 ] . MakeEmpty ( CFT_SMALL_EMPTY ) ;
row - > columns [ 2 ] . MakeEmpty ( CFT_SMALL_EMPTY ) ;
row - > columns [ 3 ] . MakeEmpty ( CFT_SMALL_EMPTY ) ;
row - > columns [ 4 ] . MakeHeader ( STR_INDUSTRY_CARGOES_CUSTOMERS ) ;
const IndustrySpec * central_sp = GetIndustrySpec ( it ) ;
bool houses_supply = HousesCanSupply ( central_sp - > accepts_cargo , lengthof ( central_sp - > accepts_cargo ) ) ;
bool houses_accept = HousesCanAccept ( central_sp - > produced_cargo , lengthof ( central_sp - > produced_cargo ) ) ;
/* Make a field consisting of two cargo columns. */
int num_supp = CountMatchingProducingIndustries ( central_sp - > accepts_cargo , lengthof ( central_sp - > accepts_cargo ) ) + houses_supply ;
int num_cust = CountMatchingAcceptingIndustries ( central_sp - > produced_cargo , lengthof ( central_sp - > produced_cargo ) ) + houses_accept ;
int num_indrows = max ( 3 , max ( num_supp , num_cust ) ) ; // One is needed for the 'it' industry, and 2 for the cargo labels.
for ( int i = 0 ; i < num_indrows ; i + + ) {
CargoesRow * row = this - > fields . Append ( ) ;
row - > columns [ 0 ] . MakeEmpty ( CFT_EMPTY ) ;
row - > columns [ 1 ] . MakeCargo ( central_sp - > accepts_cargo , lengthof ( central_sp - > accepts_cargo ) ) ;
row - > columns [ 2 ] . MakeEmpty ( CFT_EMPTY ) ;
row - > columns [ 3 ] . MakeCargo ( central_sp - > produced_cargo , lengthof ( central_sp - > produced_cargo ) ) ;
row - > columns [ 4 ] . MakeEmpty ( CFT_EMPTY ) ;
}
/* Add central industry. */
int central_row = 1 + num_indrows / 2 ;
this - > fields [ central_row ] . columns [ 2 ] . MakeIndustry ( it ) ;
this - > fields [ central_row ] . ConnectIndustryProduced ( 2 ) ;
this - > fields [ central_row ] . ConnectIndustryAccepted ( 2 ) ;
/* Add cargo labels. */
this - > fields [ central_row - 1 ] . MakeCargoLabel ( 2 , true ) ;
this - > fields [ central_row + 1 ] . MakeCargoLabel ( 2 , false ) ;
/* Add suppliers and customers of the 'it' industry. */
int supp_count = 0 ;
int cust_count = 0 ;
for ( IndustryType it = 0 ; it < NUM_INDUSTRYTYPES ; it + + ) {
const IndustrySpec * indsp = GetIndustrySpec ( it ) ;
if ( ! indsp - > enabled ) continue ;
if ( HasCommonValidCargo ( central_sp - > accepts_cargo , lengthof ( central_sp - > accepts_cargo ) , indsp - > produced_cargo , lengthof ( indsp - > produced_cargo ) ) ) {
this - > PlaceIndustry ( 1 + supp_count * num_indrows / num_supp , 0 , it ) ;
2010-08-08 11:17:14 +00:00
SetBit ( _displayed_industries , it ) ;
2010-07-23 18:39:02 +00:00
supp_count + + ;
}
if ( HasCommonValidCargo ( central_sp - > produced_cargo , lengthof ( central_sp - > produced_cargo ) , indsp - > accepts_cargo , lengthof ( indsp - > accepts_cargo ) ) ) {
this - > PlaceIndustry ( 1 + cust_count * num_indrows / num_cust , 4 , it ) ;
2010-08-08 11:17:14 +00:00
SetBit ( _displayed_industries , it ) ;
2010-07-23 18:39:02 +00:00
cust_count + + ;
}
}
if ( houses_supply ) {
this - > PlaceIndustry ( 1 + supp_count * num_indrows / num_supp , 0 , NUM_INDUSTRYTYPES ) ;
supp_count + + ;
}
if ( houses_accept ) {
this - > PlaceIndustry ( 1 + cust_count * num_indrows / num_cust , 4 , NUM_INDUSTRYTYPES ) ;
cust_count + + ;
}
this - > ShortenCargoColumn ( 1 , 1 , num_indrows ) ;
this - > ShortenCargoColumn ( 3 , 1 , num_indrows ) ;
2011-12-16 16:39:48 +00:00
const NWidgetBase * nwp = this - > GetWidget < NWidgetBase > ( WID_IC_PANEL ) ;
2010-08-12 08:37:01 +00:00
this - > vscroll - > SetCount ( CeilDiv ( WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM + CargoesField : : small_height + num_indrows * CargoesField : : normal_height , nwp - > resize_y ) ) ;
2010-07-23 18:39:02 +00:00
this - > SetDirty ( ) ;
2010-08-08 11:17:14 +00:00
this - > NotifySmallmap ( ) ;
2010-07-23 18:39:02 +00:00
}
/**
* Compute what and where to display for cargo id \ a cid .
* @ param cid Cargo id to display .
*/
void ComputeCargoDisplay ( CargoID cid )
{
2011-12-16 16:39:48 +00:00
this - > GetWidget < NWidgetCore > ( WID_IC_CAPTION ) - > widget_data = STR_INDUSTRY_CARGOES_CARGO_CAPTION ;
2010-07-23 18:39:02 +00:00
this - > ind_cargo = cid + NUM_INDUSTRYTYPES ;
2010-08-08 11:17:14 +00:00
_displayed_industries = 0 ;
2010-07-23 18:39:02 +00:00
this - > fields . Clear ( ) ;
CargoesRow * row = this - > fields . Append ( ) ;
row - > columns [ 0 ] . MakeHeader ( STR_INDUSTRY_CARGOES_PRODUCERS ) ;
row - > columns [ 1 ] . MakeEmpty ( CFT_SMALL_EMPTY ) ;
row - > columns [ 2 ] . MakeHeader ( STR_INDUSTRY_CARGOES_CUSTOMERS ) ;
row - > columns [ 3 ] . MakeEmpty ( CFT_SMALL_EMPTY ) ;
row - > columns [ 4 ] . MakeEmpty ( CFT_SMALL_EMPTY ) ;
bool houses_supply = HousesCanSupply ( & cid , 1 ) ;
bool houses_accept = HousesCanAccept ( & cid , 1 ) ;
int num_supp = CountMatchingProducingIndustries ( & cid , 1 ) + houses_supply + 1 ; // Ensure room for the cargo label.
int num_cust = CountMatchingAcceptingIndustries ( & cid , 1 ) + houses_accept ;
int num_indrows = max ( num_supp , num_cust ) ;
for ( int i = 0 ; i < num_indrows ; i + + ) {
CargoesRow * row = this - > fields . Append ( ) ;
row - > columns [ 0 ] . MakeEmpty ( CFT_EMPTY ) ;
row - > columns [ 1 ] . MakeCargo ( & cid , 1 ) ;
row - > columns [ 2 ] . MakeEmpty ( CFT_EMPTY ) ;
row - > columns [ 3 ] . MakeEmpty ( CFT_EMPTY ) ;
row - > columns [ 4 ] . MakeEmpty ( CFT_EMPTY ) ;
}
this - > fields [ num_indrows ] . MakeCargoLabel ( 0 , false ) ; // Add cargo labels at the left bottom.
/* Add suppliers and customers of the cargo. */
int supp_count = 0 ;
int cust_count = 0 ;
for ( IndustryType it = 0 ; it < NUM_INDUSTRYTYPES ; it + + ) {
const IndustrySpec * indsp = GetIndustrySpec ( it ) ;
if ( ! indsp - > enabled ) continue ;
if ( HasCommonValidCargo ( & cid , 1 , indsp - > produced_cargo , lengthof ( indsp - > produced_cargo ) ) ) {
this - > PlaceIndustry ( 1 + supp_count * num_indrows / num_supp , 0 , it ) ;
2010-08-08 11:17:14 +00:00
SetBit ( _displayed_industries , it ) ;
2010-07-23 18:39:02 +00:00
supp_count + + ;
}
if ( HasCommonValidCargo ( & cid , 1 , indsp - > accepts_cargo , lengthof ( indsp - > accepts_cargo ) ) ) {
this - > PlaceIndustry ( 1 + cust_count * num_indrows / num_cust , 2 , it ) ;
2010-08-08 11:17:14 +00:00
SetBit ( _displayed_industries , it ) ;
2010-07-23 18:39:02 +00:00
cust_count + + ;
}
}
if ( houses_supply ) {
this - > PlaceIndustry ( 1 + supp_count * num_indrows / num_supp , 0 , NUM_INDUSTRYTYPES ) ;
supp_count + + ;
}
if ( houses_accept ) {
this - > PlaceIndustry ( 1 + cust_count * num_indrows / num_cust , 2 , NUM_INDUSTRYTYPES ) ;
cust_count + + ;
}
this - > ShortenCargoColumn ( 1 , 1 , num_indrows ) ;
2011-12-16 16:39:48 +00:00
const NWidgetBase * nwp = this - > GetWidget < NWidgetBase > ( WID_IC_PANEL ) ;
2010-08-12 08:37:01 +00:00
this - > vscroll - > SetCount ( CeilDiv ( WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM + CargoesField : : small_height + num_indrows * CargoesField : : normal_height , nwp - > resize_y ) ) ;
2010-07-23 18:39:02 +00:00
this - > SetDirty ( ) ;
2010-08-08 11:17:14 +00:00
this - > NotifySmallmap ( ) ;
2010-07-23 18:39:02 +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 .
2010-08-08 11:21:24 +00:00
* - data = 0 . . NUM_INDUSTRYTYPES - 1 : Display the chain around the given industry .
* - data = NUM_INDUSTRYTYPES : Stop sending updates to the smallmap window .
2011-03-13 21:31:29 +00:00
* @ 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 .
2010-07-23 18:39:02 +00:00
*/
2011-03-13 21:31:29 +00:00
virtual void OnInvalidateData ( int data = 0 , bool gui_scope = true )
2010-07-23 18:39:02 +00:00
{
2011-03-13 21:31:29 +00:00
if ( ! gui_scope ) return ;
2010-08-08 11:21:24 +00:00
if ( data = = NUM_INDUSTRYTYPES ) {
2011-12-16 16:39:48 +00:00
if ( this - > IsWidgetLowered ( WID_IC_NOTIFY ) ) {
this - > RaiseWidget ( WID_IC_NOTIFY ) ;
this - > SetWidgetDirty ( WID_IC_NOTIFY ) ;
2010-08-08 11:21:24 +00:00
}
return ;
}
2010-07-23 18:39:02 +00:00
assert ( data > = 0 & & data < NUM_INDUSTRYTYPES ) ;
this - > ComputeIndustryDisplay ( data ) ;
}
virtual void DrawWidget ( const Rect & r , int widget ) const
{
2011-12-16 16:39:48 +00:00
if ( widget ! = WID_IC_PANEL ) return ;
2010-07-23 18:39:02 +00:00
DrawPixelInfo tmp_dpi , * old_dpi ;
int width = r . right - r . left + 1 ;
int height = r . bottom - r . top + 1 - WD_FRAMERECT_TOP - WD_FRAMERECT_BOTTOM ;
if ( ! FillDrawPixelInfo ( & tmp_dpi , r . left + WD_FRAMERECT_LEFT , r . top + WD_FRAMERECT_TOP , width , height ) ) return ;
old_dpi = _cur_dpi ;
_cur_dpi = & tmp_dpi ;
int left_pos = WD_FRAMERECT_LEFT ;
if ( this - > ind_cargo > = NUM_INDUSTRYTYPES ) left_pos + = ( CargoesField : : industry_width + CargoesField : : CARGO_FIELD_WIDTH ) / 2 ;
int last_column = ( this - > ind_cargo < NUM_INDUSTRYTYPES ) ? 4 : 2 ;
2011-12-16 16:39:48 +00:00
const NWidgetBase * nwp = this - > GetWidget < NWidgetBase > ( WID_IC_PANEL ) ;
2010-08-12 08:37:01 +00:00
int vpos = - this - > vscroll - > GetPosition ( ) * nwp - > resize_y ;
2010-07-23 18:39:02 +00:00
for ( uint i = 0 ; i < this - > fields . Length ( ) ; i + + ) {
int row_height = ( i = = 0 ) ? CargoesField : : small_height : CargoesField : : normal_height ;
if ( vpos + row_height > = 0 ) {
int xpos = left_pos ;
int col , dir ;
2010-11-13 09:56:25 +00:00
if ( _current_text_dir = = TD_RTL ) {
2010-07-23 18:39:02 +00:00
col = last_column ;
dir = - 1 ;
} else {
col = 0 ;
dir = 1 ;
}
while ( col > = 0 & & col < = last_column ) {
this - > fields [ i ] . columns [ col ] . Draw ( xpos , vpos ) ;
xpos + = ( col & 1 ) ? CargoesField : : CARGO_FIELD_WIDTH : CargoesField : : industry_width ;
col + = dir ;
}
}
vpos + = row_height ;
if ( vpos > = height ) break ;
}
_cur_dpi = old_dpi ;
}
/**
* Calculate in which field was clicked , and within the field , at what position .
2011-12-16 16:39:48 +00:00
* @ param pt Clicked position in the # WID_IC_PANEL widget .
2010-07-23 18:39:02 +00:00
* @ param fieldxy If \ c true is returned , field x / y coordinate of \ a pt .
* @ param xy If \ c true is returned , x / y coordinate with in the field .
* @ return Clicked at a valid position .
*/
bool CalculatePositionInWidget ( Point pt , Point * fieldxy , Point * xy )
{
2011-12-16 16:39:48 +00:00
const NWidgetBase * nw = this - > GetWidget < NWidgetBase > ( WID_IC_PANEL ) ;
2010-07-23 18:39:02 +00:00
pt . x - = nw - > pos_x ;
pt . y - = nw - > pos_y ;
2010-08-12 08:37:01 +00:00
int vpos = WD_FRAMERECT_TOP + CargoesField : : small_height - this - > vscroll - > GetPosition ( ) * nw - > resize_y ;
2010-07-23 18:39:02 +00:00
if ( pt . y < vpos ) return false ;
int row = ( pt . y - vpos ) / CargoesField : : normal_height ; // row is relative to row 1.
if ( row + 1 > = ( int ) this - > fields . Length ( ) ) return false ;
vpos = pt . y - vpos - row * CargoesField : : normal_height ; // Position in the row + 1 field
row + + ; // rebase row to match index of this->fields.
int xpos = 2 * WD_FRAMERECT_LEFT + ( ( this - > ind_cargo < NUM_INDUSTRYTYPES ) ? 0 : ( CargoesField : : industry_width + CargoesField : : CARGO_FIELD_WIDTH ) / 2 ) ;
if ( pt . x < xpos ) return false ;
int column ;
for ( column = 0 ; column < = 5 ; column + + ) {
int width = ( column & 1 ) ? CargoesField : : CARGO_FIELD_WIDTH : CargoesField : : industry_width ;
if ( pt . x < xpos + width ) break ;
xpos + = width ;
}
int num_columns = ( this - > ind_cargo < NUM_INDUSTRYTYPES ) ? 4 : 2 ;
if ( column > num_columns ) return false ;
xpos = pt . x - xpos ;
/* Return both positions, compensating for RTL languages (which works due to the equal symmetry in both displays). */
fieldxy - > y = row ;
xy - > y = vpos ;
2010-11-13 09:56:25 +00:00
if ( _current_text_dir = = TD_RTL ) {
2010-07-23 18:39:02 +00:00
fieldxy - > x = num_columns - column ;
xy - > x = ( ( column & 1 ) ? CargoesField : : CARGO_FIELD_WIDTH : CargoesField : : industry_width ) - xpos ;
} else {
fieldxy - > x = column ;
xy - > x = xpos ;
}
return true ;
}
virtual void OnClick ( Point pt , int widget , int click_count )
{
2010-08-08 11:02:57 +00:00
switch ( widget ) {
2011-12-16 16:39:48 +00:00
case WID_IC_PANEL : {
2010-08-08 11:02:57 +00:00
Point fieldxy , xy ;
if ( ! CalculatePositionInWidget ( pt , & fieldxy , & xy ) ) return ;
const CargoesField * fld = this - > fields [ fieldxy . y ] . columns + fieldxy . x ;
switch ( fld - > type ) {
case CFT_INDUSTRY :
if ( fld - > u . industry . ind_type < NUM_INDUSTRYTYPES ) this - > ComputeIndustryDisplay ( fld - > u . industry . ind_type ) ;
break ;
case CFT_CARGO : {
CargoesField * lft = ( fieldxy . x > 0 ) ? this - > fields [ fieldxy . y ] . columns + fieldxy . x - 1 : NULL ;
CargoesField * rgt = ( fieldxy . x < 4 ) ? this - > fields [ fieldxy . y ] . columns + fieldxy . x + 1 : NULL ;
CargoID cid = fld - > CargoClickedAt ( lft , rgt , xy ) ;
if ( cid ! = INVALID_CARGO ) this - > ComputeCargoDisplay ( cid ) ;
break ;
}
2010-07-23 18:39:02 +00:00
2010-08-08 11:02:57 +00:00
case CFT_CARGO_LABEL : {
CargoID cid = fld - > CargoLabelClickedAt ( xy ) ;
if ( cid ! = INVALID_CARGO ) this - > ComputeCargoDisplay ( cid ) ;
break ;
}
2010-07-23 18:39:02 +00:00
2010-08-08 11:02:57 +00:00
default :
break ;
}
2010-07-23 18:39:02 +00:00
break ;
}
2010-08-08 11:17:14 +00:00
2011-12-16 16:39:48 +00:00
case WID_IC_NOTIFY :
this - > ToggleWidgetLoweredState ( WID_IC_NOTIFY ) ;
this - > SetWidgetDirty ( WID_IC_NOTIFY ) ;
2012-12-23 21:09:09 +00:00
if ( _settings_client . sound . click_beep ) SndPlayFx ( SND_15_BEEP ) ;
2010-08-08 11:17:14 +00:00
2011-12-16 16:39:48 +00:00
if ( this - > IsWidgetLowered ( WID_IC_NOTIFY ) ) {
2010-08-08 11:17:14 +00:00
if ( FindWindowByClass ( WC_SMALLMAP ) = = NULL ) ShowSmallMap ( ) ;
this - > NotifySmallmap ( ) ;
}
break ;
2012-11-25 15:24:02 +00:00
case WID_IC_CARGO_DROPDOWN : {
DropDownList * lst = new DropDownList ;
const CargoSpec * cs ;
FOR_ALL_SORTED_STANDARD_CARGOSPECS ( cs ) {
lst - > push_back ( new DropDownListStringItem ( cs - > name , cs - > Index ( ) , false ) ) ;
}
if ( lst - > size ( ) = = 0 ) {
delete lst ;
break ;
}
int selected = ( this - > ind_cargo > = NUM_INDUSTRYTYPES ) ? this - > ind_cargo - NUM_INDUSTRYTYPES : - 1 ;
ShowDropDownList ( this , lst , selected , WID_IC_CARGO_DROPDOWN , 0 , true ) ;
break ;
}
case WID_IC_IND_DROPDOWN : {
DropDownList * lst = new DropDownList ;
for ( uint8 i = 0 ; i < NUM_INDUSTRYTYPES ; i + + ) {
IndustryType ind = _sorted_industry_types [ i ] ;
const IndustrySpec * indsp = GetIndustrySpec ( ind ) ;
if ( ! indsp - > enabled ) continue ;
lst - > push_back ( new DropDownListStringItem ( indsp - > name , ind , false ) ) ;
}
if ( lst - > size ( ) = = 0 ) {
delete lst ;
break ;
}
int selected = ( this - > ind_cargo < NUM_INDUSTRYTYPES ) ? this - > ind_cargo : - 1 ;
ShowDropDownList ( this , lst , selected , WID_IC_IND_DROPDOWN , 0 , true ) ;
break ;
}
}
}
virtual void OnDropdownSelect ( int widget , int index )
{
if ( index < 0 ) return ;
switch ( widget ) {
case WID_IC_CARGO_DROPDOWN :
this - > ComputeCargoDisplay ( index ) ;
break ;
case WID_IC_IND_DROPDOWN :
this - > ComputeIndustryDisplay ( index ) ;
break ;
2010-07-23 18:39:02 +00:00
}
}
virtual void OnHover ( Point pt , int widget )
{
2011-12-16 16:39:48 +00:00
if ( widget ! = WID_IC_PANEL ) return ;
2010-07-23 18:39:02 +00:00
Point fieldxy , xy ;
if ( ! CalculatePositionInWidget ( pt , & fieldxy , & xy ) ) return ;
const CargoesField * fld = this - > fields [ fieldxy . y ] . columns + fieldxy . x ;
CargoID cid = INVALID_CARGO ;
switch ( fld - > type ) {
case CFT_CARGO : {
CargoesField * lft = ( fieldxy . x > 0 ) ? this - > fields [ fieldxy . y ] . columns + fieldxy . x - 1 : NULL ;
CargoesField * rgt = ( fieldxy . x < 4 ) ? this - > fields [ fieldxy . y ] . columns + fieldxy . x + 1 : NULL ;
cid = fld - > CargoClickedAt ( lft , rgt , xy ) ;
break ;
}
case CFT_CARGO_LABEL : {
cid = fld - > CargoLabelClickedAt ( xy ) ;
break ;
}
case CFT_INDUSTRY :
if ( fld - > u . industry . ind_type < NUM_INDUSTRYTYPES & & ( this - > ind_cargo > = NUM_INDUSTRYTYPES | | fieldxy . x ! = 2 ) ) {
2010-12-12 14:14:26 +00:00
GuiShowTooltips ( this , STR_INDUSTRY_CARGOES_INDUSTRY_TOOLTIP , 0 , NULL , TCC_HOVER ) ;
2010-07-23 18:39:02 +00:00
}
return ;
default :
break ;
}
if ( cid ! = INVALID_CARGO & & ( this - > ind_cargo < NUM_INDUSTRYTYPES | | cid ! = this - > ind_cargo - NUM_INDUSTRYTYPES ) ) {
const CargoSpec * csp = CargoSpec : : Get ( cid ) ;
uint64 params [ 5 ] ;
params [ 0 ] = csp - > name ;
2010-12-12 14:14:26 +00:00
GuiShowTooltips ( this , STR_INDUSTRY_CARGOES_CARGO_TOOLTIP , 1 , params , TCC_HOVER ) ;
2010-07-23 18:39:02 +00:00
}
}
virtual void OnResize ( )
{
2011-12-16 16:39:48 +00:00
this - > vscroll - > SetCapacityFromWidget ( this , WID_IC_PANEL ) ;
2010-07-23 18:39:02 +00:00
}
} ;
const int IndustryCargoesWindow : : HOR_TEXT_PADDING = 5 ; ///< Horizontal padding around the industry type text.
const int IndustryCargoesWindow : : VERT_TEXT_PADDING = 5 ; ///< Vertical padding around the industry type text.
/**
* Open the industry and cargoes window .
2012-11-25 15:24:02 +00:00
* @ param id Industry type to display , \ c NUM_INDUSTRYTYPES selects a default industry type .
2010-07-23 18:39:02 +00:00
*/
2010-07-23 18:44:04 +00:00
static void ShowIndustryCargoesWindow ( IndustryType id )
2010-07-23 18:39:02 +00:00
{
2012-11-25 15:24:02 +00:00
if ( id > = NUM_INDUSTRYTYPES ) {
for ( uint8 i = 0 ; i < NUM_INDUSTRYTYPES ; i + + ) {
const IndustrySpec * indsp = GetIndustrySpec ( _sorted_industry_types [ i ] ) ;
if ( indsp - > enabled ) {
id = _sorted_industry_types [ i ] ;
break ;
}
}
if ( id > = NUM_INDUSTRYTYPES ) return ;
}
2010-07-23 18:39:02 +00:00
Window * w = BringWindowToFrontById ( WC_INDUSTRY_CARGOES , 0 ) ;
if ( w ! = NULL ) {
w - > InvalidateData ( id ) ;
return ;
}
new IndustryCargoesWindow ( id ) ;
}
2012-11-25 15:24:02 +00:00
/** Open the industry and cargoes window with an industry. */
void ShowIndustryCargoesWindow ( )
{
ShowIndustryCargoesWindow ( NUM_INDUSTRYTYPES ) ;
}