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 misc_gui.cpp GUIs for a number of misc windows. */
2007-03-03 04:04:22 +00:00
2004-08-09 17:04:08 +00:00
# include "stdafx.h"
2010-06-03 11:05:20 +00:00
# include "debug.h"
2007-04-12 13:07:15 +00:00
# include "landscape.h"
2011-12-10 13:54:10 +00:00
# include "error.h"
2004-08-09 17:04:08 +00:00
# include "gui.h"
2007-12-21 21:50:46 +00:00
# include "command_func.h"
2008-09-30 20:51:04 +00:00
# include "company_func.h"
2004-08-09 17:04:08 +00:00
# include "town.h"
2010-06-03 11:05:20 +00:00
# include "string_func.h"
2009-01-31 20:16:06 +00:00
# include "company_base.h"
# include "texteff.hpp"
2007-12-21 19:49:27 +00:00
# include "strings_func.h"
2007-12-25 11:26:07 +00:00
# include "window_func.h"
2008-05-11 12:26:20 +00:00
# include "querystring_gui.h"
2010-01-15 16:41:15 +00:00
# include "core/geometry_func.hpp"
2010-04-24 13:39:11 +00:00
# include "newgrf_debug.h"
2014-10-18 16:11:40 +00:00
# include "zoom_func.h"
2018-05-20 08:58:36 +00:00
# include "guitimer_func.h"
2020-12-27 22:25:43 +00:00
# include "viewport_func.h"
2021-10-29 23:31:46 +00:00
# include "landscape_cmd.h"
2020-05-05 16:36:27 +00:00
# include "rev.h"
2007-12-21 22:50:51 +00:00
2011-12-15 22:22:55 +00:00
# include "widgets/misc_widget.h"
2008-01-13 01:21:35 +00:00
# include "table/strings.h"
2021-06-12 17:13:22 +00:00
# include <sstream>
# include <iomanip>
2014-04-23 20:13:33 +00:00
# include "safeguards.h"
2012-12-05 19:34:25 +00:00
/** Method to open the OSK. */
enum OskActivation {
OSKA_DISABLED , ///< The OSK shall not be activated at all.
OSKA_DOUBLE_CLICK , ///< Double click on the edit box opens OSK.
OSKA_SINGLE_CLICK , ///< Single click after focus click opens OSK.
2013-01-08 22:46:42 +00:00
OSKA_IMMEDIATELY , ///< Focusing click already opens OSK.
2012-12-05 19:34:25 +00:00
} ;
2009-04-11 19:14:34 +00:00
static const NWidgetPart _nested_land_info_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
NWidget ( WWT_CAPTION , COLOUR_GREY ) , SetDataTip ( STR_LAND_AREA_INFORMATION_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2020-12-27 22:25:43 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_LI_LOCATION ) , SetMinimalSize ( 12 , 14 ) , SetDataTip ( SPR_GOTO_LOCATION , STR_LAND_AREA_INFORMATION_LOCATION_TOOLTIP ) ,
2010-04-24 13:39:11 +00:00
NWidget ( WWT_DEBUGBOX , COLOUR_GREY ) ,
2009-04-11 19:14:34 +00:00
EndContainer ( ) ,
2011-12-16 16:49:53 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY , WID_LI_BACKGROUND ) , EndContainer ( ) ,
2009-04-11 19:14:34 +00:00
} ;
2013-05-26 19:23:42 +00:00
static WindowDesc _land_info_desc (
2013-05-26 19:25:01 +00:00
WDP_AUTO , " land_info " , 0 , 0 ,
2007-02-01 15:49:12 +00:00
WC_LAND_INFO , WC_NONE ,
2009-11-24 17:28:29 +00:00
0 ,
2009-11-15 10:26:01 +00:00
_nested_land_info_widgets , lengthof ( _nested_land_info_widgets )
2009-03-15 15:12:06 +00:00
) ;
2004-08-09 17:04:08 +00:00
2008-05-08 19:26:55 +00:00
class LandInfoWindow : public Window {
2021-06-12 17:13:22 +00:00
StringList landinfo_data ; ///< Info lines to show.
std : : string cargo_acceptance ; ///< Centered multi-line string for cargo acceptance.
2010-05-13 10:14:29 +00:00
2008-05-08 19:26:55 +00:00
public :
2010-04-24 13:39:11 +00:00
TileIndex tile ;
2004-08-09 17:04:08 +00:00
2019-03-04 07:49:37 +00:00
void DrawWidget ( const Rect & r , int widget ) const override
2009-08-30 17:07:53 +00:00
{
2011-12-16 16:49:53 +00:00
if ( widget ! = WID_LI_BACKGROUND ) return ;
2009-08-30 17:07:53 +00:00
uint y = r . top + WD_TEXTPANEL_TOP ;
2021-06-12 17:13:22 +00:00
for ( size_t i = 0 ; i < this - > landinfo_data . size ( ) ; i + + ) {
2010-07-02 13:53:05 +00:00
DrawString ( r . left + WD_FRAMETEXT_LEFT , r . right - WD_FRAMETEXT_RIGHT , y , this - > landinfo_data [ i ] , i = = 0 ? TC_LIGHT_BLUE : TC_FROMSTRING , SA_HOR_CENTER ) ;
2009-08-30 17:07:53 +00:00
y + = FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL ;
if ( i = = 0 ) y + = 4 ;
}
2004-09-10 19:02:27 +00:00
2021-06-12 17:13:22 +00:00
if ( ! this - > cargo_acceptance . empty ( ) ) {
SetDParamStr ( 0 , this - > cargo_acceptance ) ;
2009-08-30 17:07:53 +00:00
DrawStringMultiLine ( r . left + WD_FRAMETEXT_LEFT , r . right - WD_FRAMETEXT_RIGHT , y , r . bottom - WD_TEXTPANEL_BOTTOM , STR_JUST_RAW_STRING , TC_FROMSTRING , SA_CENTER ) ;
}
}
2019-03-04 07:49:37 +00:00
void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize ) override
2009-08-30 17:07:53 +00:00
{
2011-12-16 16:49:53 +00:00
if ( widget ! = WID_LI_BACKGROUND ) return ;
2009-08-30 17:07:53 +00:00
size - > height = WD_TEXTPANEL_TOP + WD_TEXTPANEL_BOTTOM ;
2021-06-12 17:13:22 +00:00
for ( size_t i = 0 ; i < this - > landinfo_data . size ( ) ; i + + ) {
2009-08-30 17:07:53 +00:00
uint width = GetStringBoundingBox ( this - > landinfo_data [ i ] ) . width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT ;
2021-01-08 10:16:18 +00:00
size - > width = std : : max ( size - > width , width ) ;
2009-08-30 17:07:53 +00:00
size - > height + = FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL ;
if ( i = = 0 ) size - > height + = 4 ;
2008-05-21 22:15:39 +00:00
}
2021-06-12 17:13:22 +00:00
if ( ! this - > cargo_acceptance . empty ( ) ) {
uint width = GetStringBoundingBox ( this - > cargo_acceptance ) . width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT ;
2021-01-08 10:16:18 +00:00
size - > width = std : : max ( size - > width , std : : min ( 300u , width ) ) ;
2021-06-12 17:13:22 +00:00
SetDParamStr ( 0 , cargo_acceptance ) ;
2009-11-21 17:22:37 +00:00
size - > height + = GetStringHeight ( STR_JUST_RAW_STRING , size - > width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT ) ;
2008-07-17 13:47:04 +00:00
}
2008-05-08 19:26:55 +00:00
}
2008-04-04 17:27:38 +00:00
2013-05-26 19:23:42 +00:00
LandInfoWindow ( TileIndex tile ) : Window ( & _land_info_desc ) , tile ( tile )
2011-02-23 20:29:48 +00:00
{
2013-05-26 19:23:42 +00:00
this - > InitNested ( ) ;
2011-02-10 20:49:36 +00:00
# if defined(_DEBUG)
# define LANDINFOD_LEVEL 0
# else
# define LANDINFOD_LEVEL 1
# endif
2021-06-12 07:10:17 +00:00
Debug ( misc , LANDINFOD_LEVEL , " TILE: {:#x} ({},{}) " , tile , TileX ( tile ) , TileY ( tile ) ) ;
Debug ( misc , LANDINFOD_LEVEL , " type = {:#x} " , _m [ tile ] . type ) ;
Debug ( misc , LANDINFOD_LEVEL , " height = {:#x} " , _m [ tile ] . height ) ;
Debug ( misc , LANDINFOD_LEVEL , " m1 = {:#x} " , _m [ tile ] . m1 ) ;
Debug ( misc , LANDINFOD_LEVEL , " m2 = {:#x} " , _m [ tile ] . m2 ) ;
Debug ( misc , LANDINFOD_LEVEL , " m3 = {:#x} " , _m [ tile ] . m3 ) ;
Debug ( misc , LANDINFOD_LEVEL , " m4 = {:#x} " , _m [ tile ] . m4 ) ;
Debug ( misc , LANDINFOD_LEVEL , " m5 = {:#x} " , _m [ tile ] . m5 ) ;
Debug ( misc , LANDINFOD_LEVEL , " m6 = {:#x} " , _me [ tile ] . m6 ) ;
Debug ( misc , LANDINFOD_LEVEL , " m7 = {:#x} " , _me [ tile ] . m7 ) ;
Debug ( misc , LANDINFOD_LEVEL , " m8 = {:#x} " , _me [ tile ] . m8 ) ;
2011-02-10 20:49:36 +00:00
# undef LANDINFOD_LEVEL
}
2019-03-04 07:49:37 +00:00
void OnInit ( ) override
2011-02-10 20:49:36 +00:00
{
2008-05-29 15:13:28 +00:00
Town * t = ClosestTownFromTile ( tile , _settings_game . economy . dist_local_authority ) ;
2007-01-10 16:31:40 +00:00
2008-05-08 19:26:55 +00:00
/* Because build_date is not set yet in every TileDesc, we make sure it is empty */
TileDesc td ;
2004-09-10 19:02:27 +00:00
2008-07-25 19:50:40 +00:00
td . build_date = INVALID_DATE ;
2008-05-21 22:15:39 +00:00
/* Most tiles have only one owner, but
* - drivethrough roadstops can be build on town owned roads ( up to 2 owners ) and
* - roads can have up to four owners ( railroad , road , tram , 3 rd - roadtype " highway " ) .
*/
2009-04-21 23:40:56 +00:00
td . owner_type [ 0 ] = STR_LAND_AREA_INFORMATION_OWNER ; // At least one owner is displayed, though it might be "N/A".
2008-05-21 22:15:39 +00:00
td . owner_type [ 1 ] = STR_NULL ; // STR_NULL results in skipping the owner
td . owner_type [ 2 ] = STR_NULL ;
td . owner_type [ 3 ] = STR_NULL ;
td . owner [ 0 ] = OWNER_NONE ;
td . owner [ 1 ] = OWNER_NONE ;
td . owner [ 2 ] = OWNER_NONE ;
td . owner [ 3 ] = OWNER_NONE ;
2008-07-25 22:37:34 +00:00
td . station_class = STR_NULL ;
td . station_name = STR_NULL ;
2010-09-01 23:14:15 +00:00
td . airport_class = STR_NULL ;
td . airport_name = STR_NULL ;
2010-02-22 14:17:17 +00:00
td . airport_tile_name = STR_NULL ;
2016-12-09 21:27:22 +00:00
td . railtype = STR_NULL ;
2010-03-16 06:43:41 +00:00
td . rail_speed = 0 ;
2019-04-06 06:46:15 +00:00
td . roadtype = STR_NULL ;
2014-01-26 13:50:10 +00:00
td . road_speed = 0 ;
2019-04-06 06:46:15 +00:00
td . tramtype = STR_NULL ;
td . tram_speed = 0 ;
2008-07-25 22:37:34 +00:00
2019-04-10 21:07:06 +00:00
td . grf = nullptr ;
2008-07-25 22:37:34 +00:00
2009-06-27 18:26:50 +00:00
CargoArray acceptance ;
2019-04-10 21:07:06 +00:00
AddAcceptedCargo ( tile , acceptance , nullptr ) ;
2008-05-08 19:26:55 +00:00
GetTileDesc ( tile , & td ) ;
2007-01-10 16:31:40 +00:00
2021-06-12 17:13:22 +00:00
this - > landinfo_data . clear ( ) ;
2008-05-21 22:15:39 +00:00
/* Tiletype */
2008-05-08 19:26:55 +00:00
SetDParam ( 0 , td . dparam [ 0 ] ) ;
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( td . str ) ) ;
2007-01-10 16:31:40 +00:00
2008-05-21 22:15:39 +00:00
/* Up to four owners */
for ( uint i = 0 ; i < 4 ; i + + ) {
if ( td . owner_type [ i ] = = STR_NULL ) continue ;
2009-04-21 23:40:56 +00:00
SetDParam ( 0 , STR_LAND_AREA_INFORMATION_OWNER_N_A ) ;
2008-05-21 22:15:39 +00:00
if ( td . owner [ i ] ! = OWNER_NONE & & td . owner [ i ] ! = OWNER_WATER ) GetNameOfOwner ( td . owner [ i ] , tile ) ;
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( td . owner_type [ i ] ) ) ;
2008-05-21 22:15:39 +00:00
}
2008-05-08 19:26:55 +00:00
2008-12-26 23:37:53 +00:00
/* Cost to clear/revenue when cleared */
2009-04-21 23:40:56 +00:00
StringID str = STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A ;
2009-05-19 19:26:03 +00:00
Company * c = Company : : GetIfValid ( _local_company ) ;
2019-04-10 21:07:06 +00:00
if ( c ! = nullptr ) {
2011-02-23 20:54:55 +00:00
assert ( _current_company = = _local_company ) ;
2021-11-21 22:02:29 +00:00
CommandCost costclear = Command < CMD_LANDSCAPE_CLEAR > : : Do ( DC_QUERY_COST , tile ) ;
2010-01-18 22:57:21 +00:00
if ( costclear . Succeeded ( ) ) {
2009-05-19 19:26:03 +00:00
Money cost = costclear . GetCost ( ) ;
if ( cost < 0 ) {
cost = - cost ; // Negate negative cost to a positive revenue
2009-08-05 17:59:21 +00:00
str = STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED ;
2009-05-19 19:26:03 +00:00
} else {
str = STR_LAND_AREA_INFORMATION_COST_TO_CLEAR ;
}
SetDParam ( 0 , cost ) ;
2008-12-26 23:37:53 +00:00
}
2008-05-08 19:26:55 +00:00
}
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( str ) ) ;
2008-05-08 19:26:55 +00:00
2008-05-21 22:15:39 +00:00
/* Location */
2021-06-12 17:13:22 +00:00
std : : stringstream tile_ss ;
tile_ss < < " 0x " < < std : : setfill ( ' 0 ' ) < < std : : setw ( 4 ) < < std : : hex < < std : : uppercase < < tile ; // 0x%.4X
std : : string tile_str = tile_ss . str ( ) ; // Can't pass it directly to SetDParamStr as the string is only a temporary and would be destructed before the GetString call.
2008-05-08 19:26:55 +00:00
SetDParam ( 0 , TileX ( tile ) ) ;
SetDParam ( 1 , TileY ( tile ) ) ;
2011-11-04 10:31:46 +00:00
SetDParam ( 2 , GetTileZ ( tile ) ) ;
2021-06-12 17:13:22 +00:00
SetDParamStr ( 3 , tile_str ) ;
this - > landinfo_data . push_back ( GetString ( STR_LAND_AREA_INFORMATION_LANDINFO_COORDS ) ) ;
2008-05-08 19:26:55 +00:00
2008-05-21 22:15:39 +00:00
/* Local authority */
2009-04-21 23:40:56 +00:00
SetDParam ( 0 , STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE ) ;
2019-04-10 21:07:06 +00:00
if ( t ! = nullptr ) {
2009-07-20 11:21:57 +00:00
SetDParam ( 0 , STR_TOWN_NAME ) ;
2008-05-08 19:26:55 +00:00
SetDParam ( 1 , t - > index ) ;
}
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY ) ) ;
2008-05-08 19:26:55 +00:00
2008-05-21 22:15:39 +00:00
/* Build date */
2008-07-25 19:50:40 +00:00
if ( td . build_date ! = INVALID_DATE ) {
2008-05-21 22:15:39 +00:00
SetDParam ( 0 , td . build_date ) ;
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( STR_LAND_AREA_INFORMATION_BUILD_DATE ) ) ;
2008-05-21 22:15:39 +00:00
}
2008-07-25 22:37:34 +00:00
/* Station class */
if ( td . station_class ! = STR_NULL ) {
SetDParam ( 0 , td . station_class ) ;
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( STR_LAND_AREA_INFORMATION_STATION_CLASS ) ) ;
2008-07-25 22:37:34 +00:00
}
/* Station type name */
if ( td . station_name ! = STR_NULL ) {
SetDParam ( 0 , td . station_name ) ;
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( STR_LAND_AREA_INFORMATION_STATION_TYPE ) ) ;
2008-07-25 22:37:34 +00:00
}
2010-09-01 23:14:15 +00:00
/* Airport class */
if ( td . airport_class ! = STR_NULL ) {
SetDParam ( 0 , td . airport_class ) ;
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( STR_LAND_AREA_INFORMATION_AIRPORT_CLASS ) ) ;
2010-09-01 23:14:15 +00:00
}
/* Airport name */
if ( td . airport_name ! = STR_NULL ) {
SetDParam ( 0 , td . airport_name ) ;
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( STR_LAND_AREA_INFORMATION_AIRPORT_NAME ) ) ;
2010-09-01 23:14:15 +00:00
}
/* Airport tile name */
2010-02-22 14:17:17 +00:00
if ( td . airport_tile_name ! = STR_NULL ) {
SetDParam ( 0 , td . airport_tile_name ) ;
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME ) ) ;
2010-02-22 14:17:17 +00:00
}
2016-12-09 21:27:22 +00:00
/* Rail type name */
if ( td . railtype ! = STR_NULL ) {
SetDParam ( 0 , td . railtype ) ;
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( STR_LANG_AREA_INFORMATION_RAIL_TYPE ) ) ;
2016-12-09 21:27:22 +00:00
}
2010-02-22 14:17:17 +00:00
2010-03-16 06:43:41 +00:00
/* Rail speed limit */
if ( td . rail_speed ! = 0 ) {
SetDParam ( 0 , td . rail_speed ) ;
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT ) ) ;
2010-03-16 06:43:41 +00:00
}
2019-04-06 06:46:15 +00:00
/* Road type name */
if ( td . roadtype ! = STR_NULL ) {
SetDParam ( 0 , td . roadtype ) ;
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( STR_LANG_AREA_INFORMATION_ROAD_TYPE ) ) ;
2019-04-06 06:46:15 +00:00
}
2014-01-26 13:50:10 +00:00
/* Road speed limit */
if ( td . road_speed ! = 0 ) {
SetDParam ( 0 , td . road_speed ) ;
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT ) ) ;
2014-01-26 13:50:10 +00:00
}
2019-04-06 06:46:15 +00:00
/* Tram type name */
if ( td . tramtype ! = STR_NULL ) {
SetDParam ( 0 , td . tramtype ) ;
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( STR_LANG_AREA_INFORMATION_TRAM_TYPE ) ) ;
2019-04-06 06:46:15 +00:00
}
/* Tram speed limit */
if ( td . tram_speed ! = 0 ) {
SetDParam ( 0 , td . tram_speed ) ;
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT ) ) ;
2019-04-06 06:46:15 +00:00
}
2008-07-25 22:37:34 +00:00
/* NewGRF name */
2019-04-10 21:07:06 +00:00
if ( td . grf ! = nullptr ) {
2008-07-25 22:37:34 +00:00
SetDParamStr ( 0 , td . grf ) ;
2021-06-12 17:13:22 +00:00
this - > landinfo_data . push_back ( GetString ( STR_LAND_AREA_INFORMATION_NEWGRF_NAME ) ) ;
2008-07-25 22:37:34 +00:00
}
2008-05-21 22:15:39 +00:00
/* Cargo acceptance is displayed in a extra multiline */
2021-06-12 17:13:22 +00:00
std : : stringstream line ;
line < < GetString ( STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED ) ;
2008-05-08 19:26:55 +00:00
2021-06-12 17:13:22 +00:00
bool found = false ;
2008-05-08 19:26:55 +00:00
for ( CargoID i = 0 ; i < NUM_CARGO ; + + i ) {
2009-06-27 18:26:50 +00:00
if ( acceptance [ i ] > 0 ) {
2008-05-08 19:26:55 +00:00
/* Add a comma between each item. */
2021-06-12 17:13:22 +00:00
if ( found ) line < < " , " ;
2008-05-08 19:26:55 +00:00
found = true ;
/* If the accepted value is less than 8, show it in 1/8:ths */
2009-06-27 18:26:50 +00:00
if ( acceptance [ i ] < 8 ) {
SetDParam ( 0 , acceptance [ i ] ) ;
2009-07-16 19:00:13 +00:00
SetDParam ( 1 , CargoSpec : : Get ( i ) - > name ) ;
2021-06-12 17:13:22 +00:00
line < < GetString ( STR_LAND_AREA_INFORMATION_CARGO_EIGHTS ) ;
2008-05-08 19:26:55 +00:00
} else {
2021-06-12 17:13:22 +00:00
line < < GetString ( CargoSpec : : Get ( i ) - > name ) ;
2008-05-08 19:26:55 +00:00
}
2007-01-10 16:31:40 +00:00
}
}
2021-06-12 17:13:22 +00:00
if ( found ) {
this - > cargo_acceptance = line . str ( ) ;
} else {
this - > cargo_acceptance . clear ( ) ;
}
2008-05-08 19:26:55 +00:00
}
2010-04-24 13:39:11 +00:00
2019-03-04 07:49:37 +00:00
bool IsNewGRFInspectable ( ) const override
2010-04-24 13:39:11 +00:00
{
return : : IsNewGRFInspectable ( GetGrfSpecFeature ( this - > tile ) , this - > tile ) ;
}
2019-03-04 07:49:37 +00:00
void ShowNewGRFInspectWindow ( ) const override
2010-04-24 13:39:11 +00:00
{
: : ShowNewGRFInspectWindow ( GetGrfSpecFeature ( this - > tile ) , this - > tile ) ;
}
2011-02-23 20:45:52 +00:00
2020-12-27 22:25:43 +00:00
void OnClick ( Point pt , int widget , int click_count ) override
{
switch ( widget ) {
case WID_LI_LOCATION :
if ( _ctrl_pressed ) {
ShowExtraViewportWindow ( this - > tile ) ;
} else {
ScrollMainWindowToTile ( this - > tile ) ;
}
break ;
}
}
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 .
*/
2019-03-04 07:49:37 +00:00
void OnInvalidateData ( int data = 0 , bool gui_scope = true ) override
2011-02-23 20:45:52 +00:00
{
2011-03-13 21:31:29 +00:00
if ( ! gui_scope ) return ;
2011-02-23 20:45:52 +00:00
switch ( data ) {
case 1 :
/* ReInit, "debug" sprite might have changed */
this - > ReInit ( ) ;
break ;
}
}
2008-05-08 19:26:55 +00:00
} ;
2011-02-14 19:52:26 +00:00
/**
* Show land information window .
* @ param tile The tile to show information about .
*/
2010-12-21 21:46:19 +00:00
void ShowLandInfo ( TileIndex tile )
2008-05-08 19:26:55 +00:00
{
2021-05-17 13:46:38 +00:00
CloseWindowById ( WC_LAND_INFO , 0 ) ;
2008-05-08 19:26:55 +00:00
new LandInfoWindow ( tile ) ;
2004-08-09 17:04:08 +00:00
}
2009-04-11 19:14:34 +00:00
static const NWidgetPart _nested_about_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
NWidget ( WWT_CAPTION , COLOUR_GREY ) , SetDataTip ( STR_ABOUT_OPENTTD , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2009-04-11 19:14:34 +00:00
EndContainer ( ) ,
2009-11-24 21:13:36 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY ) , SetPIP ( 4 , 2 , 4 ) ,
2009-11-28 15:00:45 +00:00
NWidget ( WWT_LABEL , COLOUR_GREY ) , SetDataTip ( STR_ABOUT_ORIGINAL_COPYRIGHT , STR_NULL ) ,
NWidget ( WWT_LABEL , COLOUR_GREY ) , SetDataTip ( STR_ABOUT_VERSION , STR_NULL ) ,
2009-11-24 21:13:36 +00:00
NWidget ( WWT_FRAME , COLOUR_GREY ) , SetPadding ( 0 , 5 , 1 , 5 ) ,
2011-12-16 16:49:53 +00:00
NWidget ( WWT_EMPTY , INVALID_COLOUR , WID_A_SCROLLING_TEXT ) ,
2009-11-19 22:49:04 +00:00
EndContainer ( ) ,
2011-12-16 16:49:53 +00:00
NWidget ( WWT_LABEL , COLOUR_GREY , WID_A_WEBSITE ) , SetDataTip ( STR_BLACK_RAW_STRING , STR_NULL ) ,
2020-05-05 16:36:27 +00:00
NWidget ( WWT_LABEL , COLOUR_GREY , WID_A_COPYRIGHT ) , SetDataTip ( STR_ABOUT_COPYRIGHT_OPENTTD , STR_NULL ) ,
2009-04-11 19:14:34 +00:00
EndContainer ( ) ,
} ;
2013-05-26 19:23:42 +00:00
static WindowDesc _about_desc (
2019-04-10 21:07:06 +00:00
WDP_CENTER , nullptr , 0 , 0 ,
2007-02-01 15:49:12 +00:00
WC_GAME_OPTIONS , WC_NONE ,
2009-11-24 17:28:29 +00:00
0 ,
2009-11-15 10:26:01 +00:00
_nested_about_widgets , lengthof ( _nested_about_widgets )
2009-03-15 15:12:06 +00:00
) ;
2004-08-09 17:04:08 +00:00
2009-09-20 23:11:01 +00:00
static const char * const _credits [ ] = {
2020-12-14 19:25:01 +00:00
u8 " Original design by Chris Sawyer " ,
u8 " Original graphics by Simon Foster " ,
u8 " " ,
u8 " The OpenTTD team (in alphabetical order): " ,
u8 " Grzegorz Duczy \u0144 ski (adf88) - General coding (since 1.7.2) " ,
u8 " Albert Hofkamp (Alberth) - GUI expert (since 0.7) " ,
u8 " Matthijs Kooijman (blathijs) - Pathfinder-guru, Debian port (since 0.3) " ,
u8 " Ulf Hermann (fonsinchen) - Cargo Distribution (since 1.3) " ,
u8 " Christoph Elsenhans (frosch) - General coding (since 0.6) " ,
u8 " Lo \u00ef c Guilloux (glx) - General / Windows Expert (since 0.4.5) " ,
u8 " Charles Pigott (LordAro) - General / Correctness police (since 1.9) " ,
u8 " Michael Lutz (michi_cc) - Path based signals (since 0.7) " ,
u8 " Niels Martin Hansen (nielsm) - Music system, general coding (since 1.9) " ,
u8 " Owen Rudge (orudge) - Forum host, OS/2 port (since 0.1) " ,
u8 " Peter Nelson (peter1138) - Spiritual descendant from NewGRF gods (since 0.4.5) " ,
u8 " Ingo von Borstel (planetmaker) - General, Support (since 1.1) " ,
u8 " Remko Bijker (Rubidium) - Lead coder and way more (since 0.4.5) " ,
u8 " Jos \u00e9 Soler (Terkhen) - General coding (since 1.0) " ,
u8 " " ,
u8 " Inactive Developers: " ,
u8 " Jean-Fran \u00e7 ois Claeys (Belugas) - GUI, NewGRF and more (0.4.5 - 1.0) " ,
u8 " Bjarni Corfitzen (Bjarni) - MacOSX port, coder and vehicles (0.3 - 0.7) " ,
u8 " Victor Fischer (Celestar) - Programming everywhere you need him to (0.3 - 0.6) " ,
u8 " Jaroslav Mazanec (KUDr) - YAPG (Yet Another Pathfinder God) ;) (0.4.5 - 0.6) " ,
u8 " Jonathan Coome (Maedhros) - High priest of the NewGRF Temple (0.5 - 0.6) " ,
u8 " Attila B \u00e1 n (MiHaMiX) - Developer WebTranslator 1 and 2 (0.3 - 0.5) " ,
u8 " Zden \u011b k Sojka (SmatZ) - Bug finder and fixer (0.6 - 1.3) " ,
u8 " Christoph Mallon (Tron) - Programmer, code correctness police (0.3 - 0.5) " ,
u8 " Patric Stout (TrueBrain) - NoAI, NoGo, Network (0.3 - 1.2), sys op (active) " ,
u8 " Thijs Marinussen (Yexo) - AI Framework, General (0.6 - 1.3) " ,
2021-04-24 16:49:37 +00:00
u8 " Leif Linse (Zuu) - AI/Game Script (1.2 - 1.6) " ,
2020-12-14 19:25:01 +00:00
u8 " " ,
u8 " Retired Developers: " ,
u8 " Tam \u00e1 s Farag \u00f3 (Darkvater) - Ex-Lead coder (0.3 - 0.5) " ,
u8 " Dominik Scherer (dominik81) - Lead programmer, GUI expert (0.3 - 0.3) " ,
u8 " Emil Djupfeld (egladil) - MacOSX (0.4.5 - 0.6) " ,
u8 " Simon Sasburg (HackyKid) - Many bugfixes (0.4 - 0.4.5) " ,
u8 " Ludvig Strigeus (ludde) - Original author of OpenTTD, main coder (0.1 - 0.3) " ,
u8 " Cian Duffy (MYOB) - BeOS port / manual writing (0.1 - 0.3) " ,
u8 " Petr Baudi \u0161 (pasky) - Many patches, NewGRF support (0.3 - 0.3) " ,
u8 " Benedikt Br \u00fc ggemeier (skidd13) - Bug fixer and code reworker (0.6 - 0.7) " ,
u8 " Serge Paquet (vurlix) - 2nd contributor after ludde (0.1 - 0.3) " ,
u8 " " ,
u8 " Special thanks go out to: " ,
u8 " Josef Drexler - For his great work on TTDPatch " ,
u8 " Marcin Grzegorczyk - Track foundations and for describing TTD internals " ,
u8 " Stefan Mei \u00df ner (sign_de) - For his work on the console " ,
u8 " Mike Ragsdale - OpenTTD installer " ,
u8 " Christian Rosentreter (tokai) - MorphOS / AmigaOS port " ,
u8 " Richard Kempton (richK) - additional airports, initial TGP implementation " ,
u8 " " ,
u8 " Alberto Demichelis - Squirrel scripting language \u00a9 2003-2008 " ,
u8 " L. Peter Deutsch - MD5 implementation \u00a9 1999, 2000, 2002 " ,
u8 " Michael Blunck - Pre-signals and semaphores \u00a9 2003 " ,
u8 " George - Canal/Lock graphics \u00a9 2003-2004 " ,
u8 " Andrew Parkhouse (andythenorth) - River graphics " ,
u8 " David Dallaston (Pikka) - Tram tracks " ,
u8 " All Translators - Who made OpenTTD a truly international game " ,
u8 " Bug Reporters - Without whom OpenTTD would still be full of bugs! " ,
u8 " " ,
u8 " " ,
u8 " And last but not least: " ,
u8 " Chris Sawyer - For an amazing game! "
2009-08-29 20:54:32 +00:00
} ;
2008-05-14 20:01:06 +00:00
struct AboutWindow : public Window {
2009-08-29 20:54:32 +00:00
int text_position ; ///< The top of the scrolling text
int line_height ; ///< The height of a single line
2009-09-01 21:27:33 +00:00
static const int num_visible_lines = 19 ; ///< The number of lines visible simultaneously
2008-05-14 20:01:06 +00:00
2021-04-10 11:40:56 +00:00
static const uint TIMER_INTERVAL = 2100 ; ///< Scrolling interval, scaled by line text line height. This value chosen to maintain parity: 2100 / FONT_HEIGHT_NORMAL = 150ms
2018-05-20 08:58:36 +00:00
GUITimer timer ;
2018-05-04 20:29:22 +00:00
2013-05-26 19:23:42 +00:00
AboutWindow ( ) : Window ( & _about_desc )
2008-05-14 20:01:06 +00:00
{
2013-05-26 19:23:42 +00:00
this - > InitNested ( WN_GAME_OPTIONS_ABOUT ) ;
2009-08-29 20:54:32 +00:00
2011-12-16 16:49:53 +00:00
this - > text_position = this - > GetWidget < NWidgetBase > ( WID_A_SCROLLING_TEXT ) - > pos_y + this - > GetWidget < NWidgetBase > ( WID_A_SCROLLING_TEXT ) - > current_y ;
2008-05-14 20:01:06 +00:00
}
2019-03-04 07:49:37 +00:00
void SetStringParameters ( int widget ) const override
2008-05-14 20:01:06 +00:00
{
2021-02-08 18:07:34 +00:00
if ( widget = = WID_A_WEBSITE ) SetDParamStr ( 0 , " Website: https://www.openttd.org " ) ;
2020-05-05 16:36:27 +00:00
if ( widget = = WID_A_COPYRIGHT ) SetDParamStr ( 0 , _openttd_revision_year ) ;
2009-08-29 20:54:32 +00:00
}
2008-05-14 20:01:06 +00:00
2019-03-04 07:49:37 +00:00
void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize ) override
2009-08-29 20:54:32 +00:00
{
2011-12-16 16:49:53 +00:00
if ( widget ! = WID_A_SCROLLING_TEXT ) return ;
2008-05-14 20:01:06 +00:00
2009-08-29 20:54:32 +00:00
this - > line_height = FONT_HEIGHT_NORMAL ;
2008-05-14 20:01:06 +00:00
2009-08-29 20:54:32 +00:00
Dimension d ;
d . height = this - > line_height * num_visible_lines ;
2008-05-14 20:01:06 +00:00
2009-08-29 20:54:32 +00:00
d . width = 0 ;
for ( uint i = 0 ; i < lengthof ( _credits ) ; i + + ) {
2021-01-08 10:16:18 +00:00
d . width = std : : max ( d . width , GetStringBoundingBox ( _credits [ i ] ) . width ) ;
2008-05-14 20:01:06 +00:00
}
2009-08-29 20:54:32 +00:00
* size = maxdim ( * size , d ) ;
2021-04-10 11:40:56 +00:00
/* Set scroll interval based on required speed. To keep scrolling smooth,
* the interval is adjusted rather than the distance moved . */
this - > timer . SetInterval ( TIMER_INTERVAL / FONT_HEIGHT_NORMAL ) ;
2009-08-29 20:54:32 +00:00
}
2008-05-14 20:01:06 +00:00
2019-03-04 07:49:37 +00:00
void DrawWidget ( const Rect & r , int widget ) const override
2009-08-29 20:54:32 +00:00
{
2011-12-16 16:49:53 +00:00
if ( widget ! = WID_A_SCROLLING_TEXT ) return ;
2009-08-29 20:54:32 +00:00
int y = this - > text_position ;
/* Show all scrolling _credits */
for ( uint i = 0 ; i < lengthof ( _credits ) ; i + + ) {
if ( y > = r . top + 7 & & y < r . bottom - this - > line_height ) {
2009-11-19 22:49:04 +00:00
DrawString ( r . left , r . right , y , _credits [ i ] , TC_BLACK , SA_LEFT | SA_FORCE ) ;
2009-08-29 20:54:32 +00:00
}
y + = this - > line_height ;
}
2008-05-14 20:01:06 +00:00
}
2019-03-04 07:49:37 +00:00
void OnRealtimeTick ( uint delta_ms ) override
2008-05-14 20:01:06 +00:00
{
2018-05-20 08:58:36 +00:00
uint count = this - > timer . CountElapsed ( delta_ms ) ;
2018-05-04 20:29:22 +00:00
if ( count > 0 ) {
this - > text_position - = count ;
2009-08-29 20:54:32 +00:00
/* If the last text has scrolled start a new from the start */
2011-12-16 16:49:53 +00:00
if ( this - > text_position < ( int ) ( this - > GetWidget < NWidgetBase > ( WID_A_SCROLLING_TEXT ) - > pos_y - lengthof ( _credits ) * this - > line_height ) ) {
this - > text_position = this - > GetWidget < NWidgetBase > ( WID_A_SCROLLING_TEXT ) - > pos_y + this - > GetWidget < NWidgetBase > ( WID_A_SCROLLING_TEXT ) - > current_y ;
2009-08-29 20:54:32 +00:00
}
2021-05-06 00:36:56 +00:00
this - > SetWidgetDirty ( WID_A_SCROLLING_TEXT ) ;
2008-05-14 20:01:06 +00:00
}
}
} ;
2004-08-09 17:04:08 +00:00
2007-03-07 11:47:46 +00:00
void ShowAboutWindow ( )
2004-08-09 17:04:08 +00:00
{
2021-05-17 13:46:38 +00:00
CloseWindowByClass ( WC_GAME_OPTIONS ) ;
2008-05-14 20:01:06 +00:00
new AboutWindow ( ) ;
2004-08-09 17:04:08 +00:00
}
2011-02-14 19:52:26 +00:00
/**
* Display estimated costs .
* @ param cost Estimated cost ( or income if negative ) .
* @ param x X position of the notification window .
* @ param y Y position of the notification window .
*/
2007-06-21 14:32:27 +00:00
void ShowEstimatedCostOrIncome ( Money cost , int x , int y )
2004-08-09 17:04:08 +00:00
{
2009-04-21 23:40:56 +00:00
StringID msg = STR_MESSAGE_ESTIMATED_COST ;
2004-08-09 17:04:08 +00:00
if ( cost < 0 ) {
cost = - cost ;
2009-04-21 23:40:56 +00:00
msg = STR_MESSAGE_ESTIMATED_INCOME ;
2004-08-09 17:04:08 +00:00
}
2007-06-21 17:25:17 +00:00
SetDParam ( 0 , cost ) ;
2010-02-24 14:46:15 +00:00
ShowErrorMessage ( msg , INVALID_STRING_ID , WL_INFO , x , y ) ;
2004-08-09 17:04:08 +00:00
}
2011-02-14 19:52:26 +00:00
/**
* Display animated income or costs on the map .
* @ param x World X position of the animation location .
* @ param y World Y position of the animation location .
* @ param z World Z position of the animation location .
* @ param cost Estimated cost ( or income if negative ) .
*/
2007-06-21 14:32:27 +00:00
void ShowCostOrIncomeAnimation ( int x , int y , int z , Money cost )
2004-08-09 17:04:08 +00:00
{
2009-01-09 22:56:28 +00:00
Point pt = RemapCoords ( x , y , z ) ;
2009-04-21 23:40:56 +00:00
StringID msg = STR_INCOME_FLOAT_COST ;
2004-08-09 17:04:08 +00:00
if ( cost < 0 ) {
cost = - cost ;
2009-04-21 23:40:56 +00:00
msg = STR_INCOME_FLOAT_INCOME ;
2004-08-09 17:04:08 +00:00
}
2007-06-21 17:25:17 +00:00
SetDParam ( 0 , cost ) ;
2009-12-25 23:22:41 +00:00
AddTextEffect ( msg , pt . x , pt . y , DAY_TICKS , TE_RISING ) ;
2005-06-15 16:58:15 +00:00
}
2011-02-14 19:52:26 +00:00
/**
* Display animated feeder income .
2013-02-17 14:50:54 +00:00
* @ param x World X position of the animation location .
* @ param y World Y position of the animation location .
* @ param z World Z position of the animation location .
* @ param transfer Estimated feeder income .
* @ param income Real income from goods being delivered to their final destination .
2011-02-14 19:52:26 +00:00
*/
2013-02-17 14:50:54 +00:00
void ShowFeederIncomeAnimation ( int x , int y , int z , Money transfer , Money income )
2005-06-15 16:58:15 +00:00
{
2009-01-09 22:56:28 +00:00
Point pt = RemapCoords ( x , y , z ) ;
2005-06-15 16:58:15 +00:00
2013-02-17 14:50:54 +00:00
SetDParam ( 0 , transfer ) ;
if ( income = = 0 ) {
AddTextEffect ( STR_FEEDER , pt . x , pt . y , DAY_TICKS , TE_RISING ) ;
} else {
StringID msg = STR_FEEDER_COST ;
if ( income < 0 ) {
income = - income ;
msg = STR_FEEDER_INCOME ;
}
SetDParam ( 1 , income ) ;
AddTextEffect ( msg , pt . x , pt . y , DAY_TICKS , TE_RISING ) ;
}
2007-06-21 16:17:47 +00:00
}
2011-02-14 19:52:26 +00:00
/**
* Display vehicle loading indicators .
* @ param x World X position of the animation location .
* @ param y World Y position of the animation location .
* @ param z World Z position of the animation location .
* @ param percent Estimated feeder income .
* @ param string String which is drawn on the map .
* @ return TextEffectID to be used for future updates of the loading indicators .
*/
2007-06-22 18:28:44 +00:00
TextEffectID ShowFillingPercent ( int x , int y , int z , uint8 percent , StringID string )
2007-06-21 16:17:47 +00:00
{
Point pt = RemapCoords ( x , y , z ) ;
2007-06-22 18:28:44 +00:00
assert ( string ! = STR_NULL ) ;
2007-06-21 16:17:47 +00:00
SetDParam ( 0 , percent ) ;
2009-12-25 23:22:41 +00:00
return AddTextEffect ( string , pt . x , pt . y , 0 , TE_STATIC ) ;
2007-06-21 16:17:47 +00:00
}
2011-02-14 19:52:26 +00:00
/**
* Update vehicle loading indicators .
* @ param te_id TextEffectID to be updated .
2016-05-11 20:48:46 +00:00
* @ param string String which is printed .
2011-02-14 19:52:26 +00:00
*/
2007-06-22 18:28:44 +00:00
void UpdateFillingPercent ( TextEffectID te_id , uint8 percent , StringID string )
2007-06-21 16:17:47 +00:00
{
2007-06-22 18:28:44 +00:00
assert ( string ! = STR_NULL ) ;
2007-06-21 16:17:47 +00:00
SetDParam ( 0 , percent ) ;
2007-06-22 18:28:44 +00:00
UpdateTextEffect ( te_id , string ) ;
2007-06-21 16:17:47 +00:00
}
2011-02-14 19:52:26 +00:00
/**
* Hide vehicle loading indicators .
* @ param * te_id TextEffectID which is supposed to be hidden .
*/
2008-09-21 18:28:35 +00:00
void HideFillingPercent ( TextEffectID * te_id )
2007-06-21 16:17:47 +00:00
{
2008-09-21 18:28:35 +00:00
if ( * te_id = = INVALID_TE_ID ) return ;
RemoveTextEffect ( * te_id ) ;
* te_id = INVALID_TE_ID ;
2004-08-09 17:04:08 +00:00
}
2009-05-04 18:42:49 +00:00
static const NWidgetPart _nested_tooltips_widgets [ ] = {
2011-12-16 16:49:53 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY , WID_TT_BACKGROUND ) , SetMinimalSize ( 200 , 32 ) , EndContainer ( ) ,
2009-05-04 18:42:49 +00:00
} ;
2013-05-26 19:23:42 +00:00
static WindowDesc _tool_tips_desc (
2019-04-10 21:07:06 +00:00
WDP_MANUAL , nullptr , 0 , 0 , // Coordinates and sizes are not used,
2009-10-31 13:01:52 +00:00
WC_TOOLTIPS , WC_NONE ,
2015-02-01 12:23:39 +00:00
WDF_NO_FOCUS ,
2009-11-15 10:26:01 +00:00
_nested_tooltips_widgets , lengthof ( _nested_tooltips_widgets )
2009-10-31 13:01:52 +00:00
) ;
/** Window for displaying a tooltip. */
2008-05-11 17:44:38 +00:00
struct TooltipsWindow : public Window
2004-08-09 17:04:08 +00:00
{
2010-07-11 10:55:57 +00:00
StringID string_id ; ///< String to display as tooltip.
byte paramcount ; ///< Number of string parameters in #string_id.
uint64 params [ 5 ] ; ///< The string parameters.
TooltipCloseCondition close_cond ; ///< Condition for closing the window.
2006-10-12 15:13:40 +00:00
2013-05-26 19:23:42 +00:00
TooltipsWindow ( Window * parent , StringID str , uint paramcount , const uint64 params [ ] , TooltipCloseCondition close_tooltip ) : Window ( & _tool_tips_desc )
2008-05-11 17:44:38 +00:00
{
2010-12-12 14:14:26 +00:00
this - > parent = parent ;
2008-05-11 17:44:38 +00:00
this - > string_id = str ;
2020-12-27 10:44:22 +00:00
static_assert ( sizeof ( this - > params [ 0 ] ) = = sizeof ( params [ 0 ] ) ) ;
2008-09-29 16:27:02 +00:00
assert ( paramcount < = lengthof ( this - > params ) ) ;
2018-06-06 07:22:58 +00:00
if ( paramcount > 0 ) memcpy ( this - > params , params , sizeof ( this - > params [ 0 ] ) * paramcount ) ;
2008-05-11 17:44:38 +00:00
this - > paramcount = paramcount ;
2010-07-11 10:55:57 +00:00
this - > close_cond = close_tooltip ;
2004-08-09 17:04:08 +00:00
2013-05-26 19:23:42 +00:00
this - > InitNested ( ) ;
2009-10-31 13:01:52 +00:00
2011-12-15 19:54:23 +00:00
CLRBITS ( this - > flags , WF_WHITE_BORDER ) ;
2009-10-31 13:01:52 +00:00
}
2006-10-12 15:13:40 +00:00
2019-03-04 07:49:37 +00:00
Point OnInitialPosition ( int16 sm_width , int16 sm_height , int window_number ) override
2009-10-31 13:01:52 +00:00
{
2009-11-07 17:24:04 +00:00
/* Find the free screen space between the main toolbar at the top, and the statusbar at the bottom.
2009-11-01 19:19:14 +00:00
* Add a fixed distance 2 so the tooltip floats free from both bars .
*/
2009-11-07 17:24:04 +00:00
int scr_top = GetMainViewTop ( ) + 2 ;
int scr_bot = GetMainViewBottom ( ) - 2 ;
2009-11-01 19:19:14 +00:00
2009-10-31 13:14:51 +00:00
Point pt ;
/* Correctly position the tooltip position, watch out for window and cursor size
* Clamp value to below main toolbar and above statusbar . If tooltip would
* go below window , flip it so it is shown above the cursor */
2016-08-15 18:33:08 +00:00
pt . y = Clamp ( _cursor . pos . y + _cursor . total_size . y + _cursor . total_offs . y + 5 , scr_top , scr_bot ) ;
2021-01-08 10:16:18 +00:00
if ( pt . y + sm_height > scr_bot ) pt . y = std : : min ( _cursor . pos . y + _cursor . total_offs . y - 5 , scr_bot ) - sm_height ;
2010-08-22 20:25:45 +00:00
pt . x = sm_width > = _screen . width ? 0 : Clamp ( _cursor . pos . x - ( sm_width > > 1 ) , 0 , _screen . width - sm_width ) ;
2009-10-31 13:14:51 +00:00
return pt ;
2008-05-11 17:44:38 +00:00
}
2019-03-04 07:49:37 +00:00
void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize ) override
2008-05-11 17:44:38 +00:00
{
2009-10-31 13:01:52 +00:00
/* There is only one widget. */
2009-10-31 13:29:53 +00:00
for ( uint i = 0 ; i ! = this - > paramcount ; i + + ) SetDParam ( i , this - > params [ i ] ) ;
2021-01-08 10:16:18 +00:00
size - > width = std : : min < uint > ( GetStringBoundingBox ( this - > string_id ) . width , ScaleGUITrad ( 194 ) ) ;
2009-10-31 13:29:53 +00:00
size - > height = GetStringHeight ( this - > string_id , size - > width ) ;
/* Increase slightly to have some space around the box. */
size - > width + = 2 + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT ;
size - > height + = 2 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM ;
2009-10-31 13:01:52 +00:00
}
2019-03-04 07:49:37 +00:00
void DrawWidget ( const Rect & r , int widget ) const override
2009-10-31 13:01:52 +00:00
{
/* There is only one widget. */
2011-05-06 21:13:29 +00:00
GfxFillRect ( r . left , r . top , r . right , r . bottom , PC_BLACK ) ;
GfxFillRect ( r . left + 1 , r . top + 1 , r . right - 1 , r . bottom - 1 , PC_LIGHT_YELLOW ) ;
2008-05-11 17:44:38 +00:00
for ( uint arg = 0 ; arg < this - > paramcount ; arg + + ) {
SetDParam ( arg , this - > params [ arg ] ) ;
}
2009-10-31 13:01:52 +00:00
DrawStringMultiLine ( r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT , r . top + WD_FRAMERECT_TOP , r . bottom - WD_FRAMERECT_BOTTOM , this - > string_id , TC_FROMSTRING , SA_CENTER ) ;
}
2019-03-04 07:49:37 +00:00
void OnMouseLoop ( ) override
2008-05-11 17:44:38 +00:00
{
2010-08-19 08:22:08 +00:00
/* Always close tooltips when the cursor is not in our window. */
if ( ! _cursor . in_window ) {
2021-05-15 21:12:25 +00:00
this - > Close ( ) ;
2010-08-19 08:22:08 +00:00
return ;
}
2008-05-11 17:44:38 +00:00
/* We can show tooltips while dragging tools. These are shown as long as
2010-08-19 08:22:08 +00:00
* we are dragging the tool . Normal tooltips work with hover or rmb . */
2010-07-11 10:55:57 +00:00
switch ( this - > close_cond ) {
2021-05-15 21:12:25 +00:00
case TCC_RIGHT_CLICK : if ( ! _right_button_down ) this - > Close ( ) ; break ;
case TCC_HOVER : if ( ! _mouse_hovering ) this - > Close ( ) ; break ;
2019-03-20 01:21:10 +00:00
case TCC_NONE : break ;
2021-04-05 11:30:58 +00:00
case TCC_EXIT_VIEWPORT : {
Window * w = FindWindowFromPt ( _cursor . pos . x , _cursor . pos . y ) ;
2021-05-15 21:12:25 +00:00
if ( w = = nullptr | | IsPtInWindowViewport ( w , _cursor . pos . x , _cursor . pos . y ) = = nullptr ) this - > Close ( ) ;
2021-04-05 11:30:58 +00:00
break ;
}
2010-07-11 10:55:57 +00:00
}
2008-05-11 17:44:38 +00:00
}
} ;
2004-08-09 17:04:08 +00:00
2010-08-01 19:22:34 +00:00
/**
* Shows a tooltip
2010-12-12 14:14:26 +00:00
* @ param parent The window this tooltip is related to .
2007-04-17 20:23:13 +00:00
* @ param str String to be displayed
* @ param paramcount number of params to deal with
2008-08-02 11:26:25 +00:00
* @ param params ( optional ) up to 5 pieces of additional information that may be added to a tooltip
2018-10-28 02:17:36 +00:00
* @ param close_tooltip when the left ( true ) or right ( false ) mouse button is released
2008-08-02 11:26:25 +00:00
*/
2010-12-12 14:14:26 +00:00
void GuiShowTooltips ( Window * parent , StringID str , uint paramcount , const uint64 params [ ] , TooltipCloseCondition close_tooltip )
2004-08-09 17:04:08 +00:00
{
2021-05-17 13:46:38 +00:00
CloseWindowById ( WC_TOOLTIPS , 0 ) ;
2004-08-09 17:04:08 +00:00
2021-04-05 11:13:56 +00:00
if ( str = = STR_NULL | | ! _cursor . in_window ) return ;
2004-08-09 17:04:08 +00:00
2010-12-12 14:14:26 +00:00
new TooltipsWindow ( parent , str , paramcount , params , close_tooltip ) ;
2004-08-09 17:04:08 +00:00
}
2008-05-11 12:26:20 +00:00
void QueryString : : HandleEditBox ( Window * w , int wid )
2005-02-21 18:59:54 +00:00
{
2012-11-28 21:14:28 +00:00
if ( w - > IsWidgetGloballyFocused ( wid ) & & this - > text . HandleCaret ( ) ) {
2009-09-13 19:15:59 +00:00
w - > SetWidgetDirty ( wid ) ;
2012-11-28 21:14:28 +00:00
/* For the OSK also invalidate the parent window */
if ( w - > window_class = = WC_OSK ) w - > InvalidateData ( ) ;
2009-01-25 22:16:08 +00:00
}
2004-08-09 17:04:08 +00:00
}
2012-11-13 21:46:19 +00:00
void QueryString : : DrawEditBox ( const Window * w , int wid ) const
2004-08-09 17:04:08 +00:00
{
2012-11-14 22:50:46 +00:00
const NWidgetLeaf * wi = w - > GetWidget < NWidgetLeaf > ( wid ) ;
2008-03-26 10:08:17 +00:00
2009-11-15 13:36:30 +00:00
assert ( ( wi - > type & WWT_MASK ) = = WWT_EDITBOX ) ;
2012-11-14 22:50:56 +00:00
bool rtl = _current_text_dir = = TD_RTL ;
Dimension sprite_size = GetSpriteSize ( rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT ) ;
int clearbtn_width = sprite_size . width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT ;
int clearbtn_left = wi - > pos_x + ( rtl ? 0 : wi - > current_x - clearbtn_width ) ;
int clearbtn_right = wi - > pos_x + ( rtl ? clearbtn_width : wi - > current_x ) - 1 ;
int left = wi - > pos_x + ( rtl ? clearbtn_width : 0 ) ;
int right = wi - > pos_x + ( rtl ? wi - > current_x : wi - > current_x - clearbtn_width ) - 1 ;
2009-11-15 13:36:30 +00:00
int top = wi - > pos_y ;
int bottom = wi - > pos_y + wi - > current_y - 1 ;
2007-01-13 15:00:40 +00:00
2012-11-14 22:50:56 +00:00
DrawFrameRect ( clearbtn_left , top , clearbtn_right , bottom , wi - > colour , wi - > IsLowered ( ) ? FR_LOWERED : FR_NONE ) ;
DrawSprite ( rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT , PAL_NONE , clearbtn_left + WD_IMGBTN_LEFT + ( wi - > IsLowered ( ) ? 1 : 0 ) , ( top + bottom - sprite_size . height ) / 2 + ( wi - > IsLowered ( ) ? 1 : 0 ) ) ;
if ( this - > text . bytes = = 1 ) GfxFillRect ( clearbtn_left + 1 , top + 1 , clearbtn_right - 1 , bottom - 1 , _colour_gradient [ wi - > colour & 0xF ] [ 2 ] , FILLRECT_CHECKER ) ;
2012-11-14 22:50:46 +00:00
DrawFrameRect ( left , top , right , bottom , wi - > colour , FR_LOWERED | FR_DARKENED ) ;
2011-05-06 21:13:29 +00:00
GfxFillRect ( left + 1 , top + 1 , right - 1 , bottom - 1 , PC_BLACK ) ;
2008-04-04 17:27:38 +00:00
2006-10-27 10:12:57 +00:00
/* Limit the drawing of the string inside the widget boundaries */
2009-09-11 18:52:56 +00:00
DrawPixelInfo dpi ;
2009-09-23 15:42:29 +00:00
if ( ! FillDrawPixelInfo ( & dpi , left + WD_FRAMERECT_LEFT , top + WD_FRAMERECT_TOP , right - left - WD_FRAMERECT_RIGHT , bottom - top - WD_FRAMERECT_BOTTOM ) ) return ;
2006-10-27 10:12:57 +00:00
2008-04-04 17:27:38 +00:00
DrawPixelInfo * old_dpi = _cur_dpi ;
2006-10-27 10:12:57 +00:00
_cur_dpi = & dpi ;
/* We will take the current widget length as maximum width, with a small
* space reserved at the end for the caret to show */
2008-05-11 12:26:20 +00:00
const Textbuf * tb = & this - > text ;
2021-01-08 10:16:18 +00:00
int delta = std : : min ( 0 , ( right - left ) - tb - > pixels - 10 ) ;
2006-10-27 10:12:57 +00:00
if ( tb - > caretxoffs + delta < 0 ) delta = - tb - > caretxoffs ;
2013-08-05 20:37:22 +00:00
/* If we have a marked area, draw a background highlight. */
if ( tb - > marklength ! = 0 ) GfxFillRect ( delta + tb - > markxoffs , 0 , delta + tb - > markxoffs + tb - > marklength - 1 , bottom - top , PC_GREY ) ;
2010-12-05 22:21:37 +00:00
DrawString ( delta , tb - > pixels , 0 , tb - > buf , TC_YELLOW ) ;
2012-11-28 21:14:28 +00:00
bool focussed = w - > IsWidgetGloballyFocused ( wid ) | | IsOSKOpenedFor ( w , wid ) ;
if ( focussed & & tb - > caret ) {
2009-03-25 00:28:57 +00:00
int caret_width = GetStringBoundingBox ( " _ " ) . width ;
DrawString ( tb - > caretxoffs + delta , tb - > caretxoffs + delta + caret_width , 0 , " _ " , TC_WHITE ) ;
}
2006-10-27 10:12:57 +00:00
_cur_dpi = old_dpi ;
2004-08-09 17:04:08 +00:00
}
2013-08-05 20:37:14 +00:00
/**
* Get the current caret position .
* @ param w Window the edit box is in .
* @ param wid Widget index .
* @ return Top - left location of the caret , relative to the window .
*/
Point QueryString : : GetCaretPosition ( const Window * w , int wid ) const
{
const NWidgetLeaf * wi = w - > GetWidget < NWidgetLeaf > ( wid ) ;
assert ( ( wi - > type & WWT_MASK ) = = WWT_EDITBOX ) ;
bool rtl = _current_text_dir = = TD_RTL ;
Dimension sprite_size = GetSpriteSize ( rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT ) ;
int clearbtn_width = sprite_size . width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT ;
int left = wi - > pos_x + ( rtl ? clearbtn_width : 0 ) ;
int right = wi - > pos_x + ( rtl ? wi - > current_x : wi - > current_x - clearbtn_width ) - 1 ;
/* Clamp caret position to be inside out current width. */
const Textbuf * tb = & this - > text ;
2021-01-08 10:16:18 +00:00
int delta = std : : min ( 0 , ( right - left ) - tb - > pixels - 10 ) ;
2013-08-05 20:37:14 +00:00
if ( tb - > caretxoffs + delta < 0 ) delta = - tb - > caretxoffs ;
2015-08-10 20:24:13 +00:00
Point pt = { left + WD_FRAMERECT_LEFT + tb - > caretxoffs + delta , ( int ) wi - > pos_y + WD_FRAMERECT_TOP } ;
2013-08-05 20:37:14 +00:00
return pt ;
}
2013-08-05 20:37:48 +00:00
/**
* Get the bounding rectangle for a range of the query string .
* @ param w Window the edit box is in .
* @ param wid Widget index .
* @ param from Start of the string range .
* @ param to End of the string range .
* @ return Rectangle encompassing the string range , relative to the window .
*/
Rect QueryString : : GetBoundingRect ( const Window * w , int wid , const char * from , const char * to ) const
{
const NWidgetLeaf * wi = w - > GetWidget < NWidgetLeaf > ( wid ) ;
assert ( ( wi - > type & WWT_MASK ) = = WWT_EDITBOX ) ;
bool rtl = _current_text_dir = = TD_RTL ;
Dimension sprite_size = GetSpriteSize ( rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT ) ;
int clearbtn_width = sprite_size . width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT ;
int left = wi - > pos_x + ( rtl ? clearbtn_width : 0 ) ;
int right = wi - > pos_x + ( rtl ? wi - > current_x : wi - > current_x - clearbtn_width ) - 1 ;
int top = wi - > pos_y + WD_FRAMERECT_TOP ;
int bottom = wi - > pos_y + wi - > current_y - 1 - WD_FRAMERECT_BOTTOM ;
/* Clamp caret position to be inside our current width. */
const Textbuf * tb = & this - > text ;
2021-01-08 10:16:18 +00:00
int delta = std : : min ( 0 , ( right - left ) - tb - > pixels - 10 ) ;
2013-08-05 20:37:48 +00:00
if ( tb - > caretxoffs + delta < 0 ) delta = - tb - > caretxoffs ;
/* Get location of first and last character. */
Point p1 = GetCharPosInString ( tb - > buf , from , FS_NORMAL ) ;
Point p2 = from ! = to ? GetCharPosInString ( tb - > buf , to , FS_NORMAL ) : p1 ;
Rect r = { Clamp ( left + p1 . x + delta + WD_FRAMERECT_LEFT , left , right ) , top , Clamp ( left + p2 . x + delta + WD_FRAMERECT_LEFT , left , right - WD_FRAMERECT_RIGHT ) , bottom } ;
return r ;
}
2013-08-05 20:37:53 +00:00
/**
* Get the character that is rendered at a position .
* @ param w Window the edit box is in .
* @ param wid Widget index .
* @ param pt Position to test .
2019-04-10 21:07:06 +00:00
* @ return Pointer to the character at the position or nullptr if no character is at the position .
2013-08-05 20:37:53 +00:00
*/
const char * QueryString : : GetCharAtPosition ( const Window * w , int wid , const Point & pt ) const
{
const NWidgetLeaf * wi = w - > GetWidget < NWidgetLeaf > ( wid ) ;
assert ( ( wi - > type & WWT_MASK ) = = WWT_EDITBOX ) ;
bool rtl = _current_text_dir = = TD_RTL ;
Dimension sprite_size = GetSpriteSize ( rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT ) ;
int clearbtn_width = sprite_size . width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT ;
int left = wi - > pos_x + ( rtl ? clearbtn_width : 0 ) ;
int right = wi - > pos_x + ( rtl ? wi - > current_x : wi - > current_x - clearbtn_width ) - 1 ;
int top = wi - > pos_y + WD_FRAMERECT_TOP ;
int bottom = wi - > pos_y + wi - > current_y - 1 - WD_FRAMERECT_BOTTOM ;
2019-04-10 21:07:06 +00:00
if ( ! IsInsideMM ( pt . y , top , bottom ) ) return nullptr ;
2013-08-05 20:37:53 +00:00
/* Clamp caret position to be inside our current width. */
const Textbuf * tb = & this - > text ;
2021-01-08 10:16:18 +00:00
int delta = std : : min ( 0 , ( right - left ) - tb - > pixels - 10 ) ;
2013-08-05 20:37:53 +00:00
if ( tb - > caretxoffs + delta < 0 ) delta = - tb - > caretxoffs ;
return : : GetCharAtPosition ( tb - > buf , pt . x - delta - left ) ;
}
2012-11-14 22:50:42 +00:00
void QueryString : : ClickEditBox ( Window * w , Point pt , int wid , int click_count , bool focus_changed )
{
2012-11-14 22:50:56 +00:00
const NWidgetLeaf * wi = w - > GetWidget < NWidgetLeaf > ( wid ) ;
assert ( ( wi - > type & WWT_MASK ) = = WWT_EDITBOX ) ;
bool rtl = _current_text_dir = = TD_RTL ;
int clearbtn_width = GetSpriteSize ( rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT ) . width ;
int clearbtn_left = wi - > pos_x + ( rtl ? 0 : wi - > current_x - clearbtn_width ) ;
if ( IsInsideBS ( pt . x , clearbtn_left , clearbtn_width ) ) {
if ( this - > text . bytes > 1 ) {
this - > text . DeleteAll ( ) ;
w - > HandleButtonClick ( wid ) ;
w - > OnEditboxChanged ( wid ) ;
}
return ;
}
2012-12-05 19:34:25 +00:00
if ( w - > window_class ! = WC_OSK & & _settings_client . gui . osk_activation ! = OSKA_DISABLED & &
( ! focus_changed | | _settings_client . gui . osk_activation = = OSKA_IMMEDIATELY ) & &
( click_count = = 2 | | _settings_client . gui . osk_activation ! = OSKA_DOUBLE_CLICK ) ) {
/* Open the OSK window */
2012-11-14 22:50:42 +00:00
ShowOnScreenKeyboard ( w , wid ) ;
}
}
2009-11-03 20:04:05 +00:00
/** Class for the string query window. */
2012-11-14 22:50:35 +00:00
struct QueryStringWindow : public Window
2004-08-09 17:04:08 +00:00
{
2012-11-14 22:50:35 +00:00
QueryString editbox ; ///< Editbox.
2009-11-03 20:04:05 +00:00
QueryStringFlags flags ; ///< Flags controlling behaviour of the window.
2019-03-31 14:08:00 +00:00
Dimension warning_size ; ///< How much space to use for the warning text
2009-11-03 20:04:05 +00:00
2013-05-26 19:23:42 +00:00
QueryStringWindow ( StringID str , StringID caption , uint max_bytes , uint max_chars , WindowDesc * desc , Window * parent , CharSetFilter afilter , QueryStringFlags flags ) :
Window ( desc ) , editbox ( max_bytes , max_chars )
2008-05-11 12:26:20 +00:00
{
2012-11-14 22:50:35 +00:00
char * last_of = & this - > editbox . text . buf [ this - > editbox . text . max_bytes - 1 ] ;
GetString ( this - > editbox . text . buf , str , last_of ) ;
2021-05-29 09:21:38 +00:00
StrMakeValidInPlace ( this - > editbox . text . buf , last_of , SVS_NONE ) ;
2009-11-03 20:04:05 +00:00
2010-12-21 09:29:01 +00:00
/* Make sure the name isn't too long for the text buffer in the number of
* characters ( not bytes ) . max_chars also counts the ' \0 ' characters . */
2012-11-14 22:50:35 +00:00
while ( Utf8StringLength ( this - > editbox . text . buf ) + 1 > this - > editbox . text . max_chars ) {
* Utf8PrevChar ( this - > editbox . text . buf + strlen ( this - > editbox . text . buf ) ) = ' \0 ' ;
2010-12-21 09:29:01 +00:00
}
2012-11-14 22:50:35 +00:00
this - > editbox . text . UpdateSize ( ) ;
2012-11-14 22:50:17 +00:00
2014-04-25 15:40:32 +00:00
if ( ( flags & QSF_ACCEPT_UNCHANGED ) = = 0 ) this - > editbox . orig = stredup ( this - > editbox . text . buf ) ;
2009-11-03 20:04:05 +00:00
2012-11-14 22:50:35 +00:00
this - > querystrings [ WID_QS_TEXT ] = & this - > editbox ;
this - > editbox . caption = caption ;
this - > editbox . cancel_button = WID_QS_CANCEL ;
this - > editbox . ok_button = WID_QS_OK ;
2013-03-17 13:04:10 +00:00
this - > editbox . text . afilter = afilter ;
2009-11-03 20:04:05 +00:00
this - > flags = flags ;
2013-05-26 19:23:42 +00:00
this - > InitNested ( WN_QUERY_STRING ) ;
2019-03-31 14:08:00 +00:00
this - > UpdateWarningStringSize ( ) ;
2009-11-03 20:04:05 +00:00
2008-05-14 19:08:09 +00:00
this - > parent = parent ;
2009-11-03 20:04:05 +00:00
2011-12-16 16:49:53 +00:00
this - > SetFocusedWidget ( WID_QS_TEXT ) ;
2009-11-03 20:04:05 +00:00
}
2005-05-17 23:25:18 +00:00
2019-03-31 14:08:00 +00:00
void UpdateWarningStringSize ( )
{
if ( this - > flags & QSF_PASSWORD ) {
assert ( this - > nested_root - > smallest_x > 0 ) ;
this - > warning_size . width = this - > nested_root - > current_x - ( WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT ) ;
this - > warning_size . height = GetStringHeight ( STR_WARNING_PASSWORD_SECURITY , this - > warning_size . width ) ;
this - > warning_size . height + = WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM ;
} else {
this - > warning_size = Dimension { 0 , 0 } ;
}
this - > ReInit ( ) ;
}
2019-03-04 07:49:37 +00:00
void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize ) override
2009-11-03 20:04:05 +00:00
{
2011-12-16 16:49:53 +00:00
if ( widget = = WID_QS_DEFAULT & & ( this - > flags & QSF_ENABLE_DEFAULT ) = = 0 ) {
2010-01-23 19:30:03 +00:00
/* We don't want this widget to show! */
fill - > width = 0 ;
resize - > width = 0 ;
2009-11-03 20:04:05 +00:00
size - > width = 0 ;
}
2019-01-12 21:27:19 +00:00
if ( widget = = WID_QS_WARNING ) {
2019-03-31 14:08:00 +00:00
* size = this - > warning_size ;
2019-01-12 21:27:19 +00:00
}
}
2019-04-25 15:28:59 +00:00
void DrawWidget ( const Rect & r , int widget ) const override
2019-01-12 21:27:19 +00:00
{
if ( widget ! = WID_QS_WARNING ) return ;
2019-03-31 14:08:00 +00:00
if ( this - > flags & QSF_PASSWORD ) {
DrawStringMultiLine ( r . left + WD_FRAMERECT_LEFT + WD_FRAMETEXT_LEFT , r . right - WD_FRAMETEXT_RIGHT - WD_FRAMERECT_RIGHT ,
r . top + WD_FRAMERECT_TOP + WD_FRAMETEXT_TOP , r . bottom - WD_FRAMERECT_BOTTOM - WD_FRAMETEXT_BOTTOM ,
STR_WARNING_PASSWORD_SECURITY , TC_FROMSTRING , SA_CENTER ) ;
}
2008-05-11 12:26:20 +00:00
}
2004-08-09 17:04:08 +00:00
2019-03-04 07:49:37 +00:00
void SetStringParameters ( int widget ) const override
2009-11-03 20:04:05 +00:00
{
2012-11-14 22:50:35 +00:00
if ( widget = = WID_QS_CAPTION ) SetDParam ( 0 , this - > editbox . caption ) ;
2009-11-03 20:04:05 +00:00
}
2008-05-11 12:26:20 +00:00
void OnOk ( )
{
2019-04-10 21:07:06 +00:00
if ( this - > editbox . orig = = nullptr | | strcmp ( this - > editbox . text . buf , this - > editbox . orig ) ! = 0 ) {
2021-01-05 17:06:48 +00:00
assert ( this - > parent ! = nullptr ) ;
this - > parent - > OnQueryTextFinished ( this - > editbox . text . buf ) ;
2012-11-14 22:50:35 +00:00
this - > editbox . handled = true ;
2008-05-11 12:26:20 +00:00
}
}
2004-08-09 17:04:08 +00:00
2019-03-04 07:49:37 +00:00
void OnClick ( Point pt , int widget , int click_count ) override
2008-05-11 12:26:20 +00:00
{
switch ( widget ) {
2011-12-16 16:49:53 +00:00
case WID_QS_DEFAULT :
2012-11-14 22:50:35 +00:00
this - > editbox . text . DeleteAll ( ) ;
2017-08-13 18:38:42 +00:00
FALLTHROUGH ;
2011-12-16 16:49:53 +00:00
case WID_QS_OK :
2008-05-11 12:26:20 +00:00
this - > OnOk ( ) ;
2017-08-13 18:38:42 +00:00
FALLTHROUGH ;
2011-12-16 16:49:53 +00:00
case WID_QS_CANCEL :
2021-05-15 21:12:25 +00:00
this - > Close ( ) ;
2008-05-11 12:26:20 +00:00
break ;
}
}
2004-08-09 17:04:08 +00:00
2021-05-15 21:12:25 +00:00
void Close ( ) override
2008-05-11 12:26:20 +00:00
{
2019-04-10 21:07:06 +00:00
if ( ! this - > editbox . handled & & this - > parent ! = nullptr ) {
2008-05-27 23:40:36 +00:00
Window * parent = this - > parent ;
2021-05-15 21:12:25 +00:00
this - > parent = nullptr ; // so parent doesn't try to close us again
2019-04-10 21:07:06 +00:00
parent - > OnQueryTextFinished ( nullptr ) ;
2008-05-11 12:26:20 +00:00
}
2021-05-15 21:12:25 +00:00
this - > Window : : Close ( ) ;
2008-05-11 12:26:20 +00:00
}
} ;
2004-08-09 17:04:08 +00:00
2009-04-11 19:14:34 +00:00
static const NWidgetPart _nested_query_string_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
2011-12-16 16:49:53 +00:00
NWidget ( WWT_CAPTION , COLOUR_GREY , WID_QS_CAPTION ) , SetDataTip ( STR_WHITE_STRING , STR_NULL ) ,
2009-04-11 19:14:34 +00:00
EndContainer ( ) ,
2009-11-24 21:13:36 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY ) ,
2011-12-16 16:49:53 +00:00
NWidget ( WWT_EDITBOX , COLOUR_GREY , WID_QS_TEXT ) , SetMinimalSize ( 256 , 12 ) , SetFill ( 1 , 1 ) , SetPadding ( 2 , 2 , 2 , 2 ) ,
2009-04-11 19:14:34 +00:00
EndContainer ( ) ,
2019-03-31 14:08:00 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY , WID_QS_WARNING ) , EndContainer ( ) ,
2009-11-03 20:25:19 +00:00
NWidget ( NWID_HORIZONTAL , NC_EQUALSIZE ) ,
2011-12-16 16:49:53 +00:00
NWidget ( WWT_TEXTBTN , COLOUR_GREY , WID_QS_DEFAULT ) , SetMinimalSize ( 87 , 12 ) , SetFill ( 1 , 1 ) , SetDataTip ( STR_BUTTON_DEFAULT , STR_NULL ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , WID_QS_CANCEL ) , SetMinimalSize ( 86 , 12 ) , SetFill ( 1 , 1 ) , SetDataTip ( STR_BUTTON_CANCEL , STR_NULL ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , WID_QS_OK ) , SetMinimalSize ( 87 , 12 ) , SetFill ( 1 , 1 ) , SetDataTip ( STR_BUTTON_OK , STR_NULL ) ,
2009-04-11 19:14:34 +00:00
EndContainer ( ) ,
} ;
2013-05-26 19:23:42 +00:00
static WindowDesc _query_string_desc (
2013-05-26 19:25:01 +00:00
WDP_CENTER , " query_string " , 0 , 0 ,
2007-02-01 15:49:12 +00:00
WC_QUERY_STRING , WC_NONE ,
2009-11-24 17:28:29 +00:00
0 ,
2009-11-15 10:26:01 +00:00
_nested_query_string_widgets , lengthof ( _nested_query_string_widgets )
2009-03-15 15:12:06 +00:00
) ;
2004-08-09 17:04:08 +00:00
2010-08-01 19:22:34 +00:00
/**
* Show a query popup window with a textbox in it .
2006-12-30 01:17:53 +00:00
* @ param str StringID for the text shown in the textbox
* @ param caption StringID of text shown in caption of querywindow
2010-12-05 22:22:54 +00:00
* @ param maxsize maximum size in bytes or characters ( including terminating ' \0 ' ) depending on flags
2021-01-05 17:06:48 +00:00
* @ param parent pointer to a Window that will handle the events ( ok / cancel ) of this window .
2008-09-15 16:29:40 +00:00
* @ param afilter filters out unwanted character input
* @ param flags various flags , @ see QueryStringFlags
*/
2011-04-17 18:42:17 +00:00
void ShowQueryString ( StringID str , StringID caption , uint maxsize , Window * parent , CharSetFilter afilter , QueryStringFlags flags )
2004-08-09 17:04:08 +00:00
{
2021-01-05 17:06:48 +00:00
assert ( parent ! = nullptr ) ;
2021-05-17 13:46:38 +00:00
CloseWindowByClass ( WC_QUERY_STRING ) ;
2011-04-17 18:42:17 +00:00
new QueryStringWindow ( str , caption , ( ( flags & QSF_LEN_IN_CHARS ) ? MAX_CHAR_LENGTH : 1 ) * maxsize , maxsize , & _query_string_desc , parent , afilter , flags ) ;
2004-08-09 17:04:08 +00:00
}
2008-05-11 06:59:51 +00:00
/**
* Window used for asking the user a YES / NO question .
*/
struct QueryWindow : public Window {
2008-05-19 19:17:56 +00:00
QueryCallbackProc * proc ; ///< callback function executed on closing of popup. Window* points to parent, bool is true if 'yes' clicked, false otherwise
2018-10-28 02:17:36 +00:00
uint64 params [ 10 ] ; ///< local copy of #_global_string_params
2008-05-19 19:17:56 +00:00
StringID message ; ///< message shown for query window
2009-09-30 15:14:34 +00:00
StringID caption ; ///< title of window
2006-12-29 17:54:47 +00:00
2013-05-26 19:23:42 +00:00
QueryWindow ( WindowDesc * desc , StringID caption , StringID message , Window * parent , QueryCallbackProc * callback ) : Window ( desc )
2008-05-11 06:59:51 +00:00
{
/* Create a backup of the variadic arguments to strings because it will be
2008-07-23 15:01:50 +00:00
* overridden pretty often . We will copy these back for drawing */
2008-05-11 06:59:51 +00:00
CopyOutDParam ( this - > params , 0 , lengthof ( this - > params ) ) ;
2009-09-30 15:14:34 +00:00
this - > caption = caption ;
this - > message = message ;
this - > proc = callback ;
2021-05-03 15:39:20 +00:00
this - > parent = parent ;
2008-05-11 11:41:18 +00:00
2013-05-26 19:23:42 +00:00
this - > InitNested ( WN_CONFIRM_POPUP_QUERY ) ;
2008-05-11 06:59:51 +00:00
}
2006-12-29 17:54:47 +00:00
2021-05-15 21:12:25 +00:00
void Close ( ) override
2008-05-11 06:59:51 +00:00
{
2019-04-10 21:07:06 +00:00
if ( this - > proc ! = nullptr ) this - > proc ( this - > parent , false ) ;
2021-05-15 21:12:25 +00:00
this - > Window : : Close ( ) ;
2008-05-11 06:59:51 +00:00
}
2006-12-29 17:54:47 +00:00
2021-05-03 15:39:20 +00:00
void FindWindowPlacementAndResize ( int def_width , int def_height ) override
{
/* Position query window over the calling window, ensuring it's within screen bounds. */
this - > left = Clamp ( parent - > left + ( parent - > width / 2 ) - ( this - > width / 2 ) , 0 , _screen . width - this - > width ) ;
this - > top = Clamp ( parent - > top + ( parent - > height / 2 ) - ( this - > height / 2 ) , 0 , _screen . height - this - > height ) ;
this - > SetDirty ( ) ;
}
2019-03-04 07:49:37 +00:00
void SetStringParameters ( int widget ) const override
2009-09-30 15:14:34 +00:00
{
switch ( widget ) {
2011-12-16 16:49:53 +00:00
case WID_Q_CAPTION :
2009-10-02 15:06:14 +00:00
CopyInDParam ( 1 , this - > params , lengthof ( this - > params ) ) ;
2009-09-30 15:14:34 +00:00
SetDParam ( 0 , this - > caption ) ;
break ;
2011-12-16 16:49:53 +00:00
case WID_Q_TEXT :
2009-09-30 15:14:34 +00:00
CopyInDParam ( 0 , this - > params , lengthof ( this - > params ) ) ;
break ;
}
}
2019-03-04 07:49:37 +00:00
void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize ) override
2009-09-30 15:14:34 +00:00
{
2011-12-16 16:49:53 +00:00
if ( widget ! = WID_Q_TEXT ) return ;
2009-09-30 15:14:34 +00:00
Dimension d = GetStringMultiLineBoundingBox ( this - > message , * size ) ;
2012-05-26 21:30:38 +00:00
d . width + = WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT ;
d . height + = WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM ;
2009-09-30 15:14:34 +00:00
* size = d ;
}
2019-03-04 07:49:37 +00:00
void DrawWidget ( const Rect & r , int widget ) const override
2009-09-30 15:14:34 +00:00
{
2011-12-16 16:49:53 +00:00
if ( widget ! = WID_Q_TEXT ) return ;
2009-09-30 15:14:34 +00:00
2012-05-26 21:30:38 +00:00
DrawStringMultiLine ( r . left + WD_FRAMETEXT_LEFT , r . right - WD_FRAMETEXT_RIGHT , r . top + WD_FRAMERECT_TOP , r . bottom - WD_FRAMERECT_BOTTOM ,
this - > message , TC_FROMSTRING , SA_CENTER ) ;
2009-09-30 15:14:34 +00:00
}
2019-03-04 07:49:37 +00:00
void OnClick ( Point pt , int widget , int click_count ) override
2008-05-11 06:59:51 +00:00
{
switch ( widget ) {
2011-12-16 16:49:53 +00:00
case WID_Q_YES : {
2008-05-19 19:17:56 +00:00
/* in the Generate New World window, clicking 'Yes' causes
2021-05-17 13:46:38 +00:00
* CloseNonVitalWindows ( ) to be called - we shouldn ' t be in a window then */
2008-05-19 19:17:56 +00:00
QueryCallbackProc * proc = this - > proc ;
Window * parent = this - > parent ;
2008-05-28 06:30:55 +00:00
/* Prevent the destructor calling the callback function */
2019-04-10 21:07:06 +00:00
this - > proc = nullptr ;
2021-05-15 21:12:25 +00:00
this - > Close ( ) ;
2019-04-10 21:07:06 +00:00
if ( proc ! = nullptr ) {
2008-05-19 19:17:56 +00:00
proc ( parent , true ) ;
2019-04-10 21:07:06 +00:00
proc = nullptr ;
2006-12-29 17:54:47 +00:00
}
2010-08-01 18:53:30 +00:00
break ;
}
2011-12-16 16:49:53 +00:00
case WID_Q_NO :
2021-05-15 21:12:25 +00:00
this - > Close ( ) ;
2008-05-11 06:59:51 +00:00
break ;
}
}
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 10:00:30 +00:00
2019-03-04 07:49:37 +00:00
EventState OnKeyPress ( WChar key , uint16 keycode ) override
2008-05-11 06:59:51 +00:00
{
/* ESC closes the window, Enter confirms the action */
switch ( keycode ) {
case WKC_RETURN :
case WKC_NUM_ENTER :
2019-04-10 21:07:06 +00:00
if ( this - > proc ! = nullptr ) {
2008-05-11 06:59:51 +00:00
this - > proc ( this - > parent , true ) ;
2019-04-10 21:07:06 +00:00
this - > proc = nullptr ;
2008-05-11 06:59:51 +00:00
}
2017-08-13 18:38:42 +00:00
FALLTHROUGH ;
2008-05-11 06:59:51 +00:00
case WKC_ESC :
2021-05-15 21:12:25 +00:00
this - > Close ( ) ;
2008-05-17 23:11:06 +00:00
return ES_HANDLED ;
2008-05-11 06:59:51 +00:00
}
2008-05-17 23:11:06 +00:00
return ES_NOT_HANDLED ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 10:00:30 +00:00
}
2008-05-11 06:59:51 +00:00
} ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 10:00:30 +00:00
2009-04-11 19:14:34 +00:00
static const NWidgetPart _nested_query_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_RED ) ,
2011-12-16 16:49:53 +00:00
NWidget ( WWT_CAPTION , COLOUR_RED , WID_Q_CAPTION ) , SetDataTip ( STR_JUST_STRING , STR_NULL ) ,
2009-04-11 19:14:34 +00:00
EndContainer ( ) ,
2009-11-24 21:13:36 +00:00
NWidget ( WWT_PANEL , COLOUR_RED ) , SetPIP ( 8 , 15 , 8 ) ,
2011-12-16 16:49:53 +00:00
NWidget ( WWT_TEXT , COLOUR_RED , WID_Q_TEXT ) , SetMinimalSize ( 200 , 12 ) ,
2009-09-30 15:14:34 +00:00
NWidget ( NWID_HORIZONTAL , NC_EQUALSIZE ) , SetPIP ( 20 , 29 , 20 ) ,
2014-09-26 16:15:50 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_YELLOW , WID_Q_NO ) , SetMinimalSize ( 71 , 12 ) , SetFill ( 1 , 1 ) , SetDataTip ( STR_QUIT_NO , STR_NULL ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_YELLOW , WID_Q_YES ) , SetMinimalSize ( 71 , 12 ) , SetFill ( 1 , 1 ) , SetDataTip ( STR_QUIT_YES , STR_NULL ) ,
2009-04-11 19:14:34 +00:00
EndContainer ( ) ,
EndContainer ( ) ,
} ;
2013-05-26 19:23:42 +00:00
static WindowDesc _query_desc (
2019-04-10 21:07:06 +00:00
WDP_CENTER , nullptr , 0 , 0 ,
2007-02-01 15:49:12 +00:00
WC_CONFIRM_POPUP_QUERY , WC_NONE ,
2012-11-11 16:10:43 +00:00
WDF_MODAL ,
2009-11-15 10:26:01 +00:00
_nested_query_widgets , lengthof ( _nested_query_widgets )
2009-03-15 15:12:06 +00:00
) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 10:00:30 +00:00
2010-08-01 19:22:34 +00:00
/**
* Show a modal confirmation window with standard ' yes ' and ' no ' buttons
2006-12-29 17:54:47 +00:00
* The window is aligned to the centre of its parent .
* @ param caption string shown as window caption
* @ param message string that will be shown for the window
2019-04-10 21:07:06 +00:00
* @ param parent pointer to parent window , if this pointer is nullptr the parent becomes
2006-12-29 17:54:47 +00:00
* the main window WC_MAIN_WINDOW
2008-07-23 15:01:50 +00:00
* @ param callback callback function pointer to set in the window descriptor
*/
2008-05-19 19:17:56 +00:00
void ShowQuery ( StringID caption , StringID message , Window * parent , QueryCallbackProc * callback )
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 10:00:30 +00:00
{
2019-04-10 21:07:06 +00:00
if ( parent = = nullptr ) parent = FindWindowById ( WC_MAIN_WINDOW , 0 ) ;
2010-12-11 20:38:37 +00:00
2021-05-15 21:12:25 +00:00
for ( Window * w : Window : : Iterate ( ) ) {
2010-12-11 20:38:37 +00:00
if ( w - > window_class ! = WC_CONFIRM_POPUP_QUERY ) continue ;
2021-05-15 21:12:25 +00:00
QueryWindow * qw = dynamic_cast < QueryWindow * > ( w ) ;
2010-12-11 20:38:37 +00:00
if ( qw - > parent ! = parent | | qw - > proc ! = callback ) continue ;
2021-05-15 21:12:25 +00:00
qw - > Close ( ) ;
2010-12-11 20:38:37 +00:00
break ;
}
2008-05-11 06:59:51 +00:00
new QueryWindow ( & _query_desc , caption , message , parent , callback ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 10:00:30 +00:00
}