2009-08-21 21:21:05 +01: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 16:11:33 +01:00
/** @file settings_gui.cpp GUI for settings. */
2007-04-04 02:35:16 +01:00
2004-08-09 18:04:08 +01:00
# include "stdafx.h"
2005-08-06 15:59:54 +01:00
# include "currency.h"
2011-12-10 13:54:10 +00:00
# include "error.h"
2012-06-01 11:44:45 +01:00
# include "settings_gui.h"
2007-12-19 20:45:46 +00:00
# include "textbuf_gui.h"
2007-12-21 21:50:46 +00:00
# include "command_func.h"
2007-01-02 17:34:03 +00:00
# include "network/network.h"
2004-12-31 18:57:24 +00:00
# include "town.h"
2008-01-07 00:19:09 +00:00
# include "settings_internal.h"
2007-12-21 19:49:27 +00:00
# include "strings_func.h"
2007-12-25 11:26:07 +00:00
# include "window_func.h"
2008-01-07 14:23:25 +00:00
# include "string_func.h"
2008-01-17 00:21:43 +00:00
# include "widgets/dropdown_type.h"
2008-01-14 16:10:58 +00:00
# include "widgets/dropdown_func.h"
2021-04-04 09:04:06 +01:00
# include "widgets/slider_func.h"
2009-01-03 18:44:20 +00:00
# include "highscore.h"
2009-08-09 17:54:03 +01:00
# include "base_media_base.h"
2009-05-26 12:40:14 +01:00
# include "company_base.h"
# include "company_func.h"
2009-12-13 19:33:07 +00:00
# include "viewport_func.h"
2010-01-15 16:41:15 +00:00
# include "core/geometry_func.hpp"
2010-01-21 23:19:50 +00:00
# include "ai/ai.hpp"
2012-01-08 16:58:10 +00:00
# include "blitter/factory.hpp"
2010-11-13 11:25:58 +00:00
# include "language.h"
2012-03-17 15:45:37 +00:00
# include "textfile_gui.h"
2012-10-27 16:26:17 +01:00
# include "stringfilter_type.h"
# include "querystring_gui.h"
2019-02-23 08:27:46 +00:00
# include "fontcache.h"
2019-04-23 21:55:27 +01:00
# include "zoom_func.h"
2021-04-11 12:56:24 +01:00
# include "rev.h"
2021-03-08 14:42:39 +00:00
# include "video/video_driver.hpp"
2021-04-04 10:22:13 +01:00
# include "music/music_driver.hpp"
2022-11-08 18:21:52 +00:00
# include "gui.h"
2022-12-10 15:51:45 +00:00
# include "mixer.h"
2023-10-02 13:43:10 +01:00
# include "newgrf_config.h"
2023-04-25 18:43:45 +01:00
# include "network/core/config.h"
# include "network/network_gui.h"
# include "network/network_survey.h"
2023-06-18 18:46:53 +01:00
# include "video/video_driver.hpp"
2014-06-01 12:51:24 +01:00
2014-04-23 21:13:33 +01:00
# include "safeguards.h"
2008-01-13 01:21:35 +00:00
2004-08-09 18:04:08 +01:00
static const StringID _autosave_dropdown [ ] = {
2009-04-22 00:40:56 +01:00
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF ,
2023-04-27 16:21:29 +01:00
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_10_MINUTES ,
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_30_MINUTES ,
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_60_MINUTES ,
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_120_MINUTES ,
2004-08-09 18:04:08 +01:00
INVALID_STRING_ID ,
} ;
2023-07-19 10:26:50 +01:00
/** Available settings for autosave intervals. */
static const std : : chrono : : minutes _autosave_dropdown_to_minutes [ ] = {
std : : chrono : : minutes : : zero ( ) , ///< never
std : : chrono : : minutes ( 10 ) ,
std : : chrono : : minutes ( 30 ) ,
std : : chrono : : minutes ( 60 ) ,
std : : chrono : : minutes ( 120 ) ,
} ;
2014-10-04 21:34:43 +01:00
static Dimension _circle_size ; ///< Dimension of the circle +/- icon. This is here as not all users are within the class of the settings window.
2021-05-24 09:42:02 +01:00
static const void * ResolveObject ( const GameSettings * settings_ptr , const IntSettingDesc * sd ) ;
2012-10-29 19:53:13 +00:00
2010-12-11 15:14:28 +00:00
/**
* Get index of the current screen resolution .
2019-04-12 17:46:49 +01:00
* @ return Index of the current screen resolution if it is a known resolution , _resolutions . size ( ) otherwise .
2010-12-11 15:14:28 +00:00
*/
2021-03-09 09:58:33 +00:00
static uint GetCurrentResolutionIndex ( )
2004-08-09 18:04:08 +01:00
{
2021-03-09 09:58:33 +00:00
auto it = std : : find ( _resolutions . begin ( ) , _resolutions . end ( ) , Dimension ( _screen . width , _screen . height ) ) ;
return std : : distance ( _resolutions . begin ( ) , it ) ;
2004-08-09 18:04:08 +01:00
}
2008-05-18 13:17:52 +01:00
static void ShowCustCurrency ( ) ;
2008-01-17 00:21:43 +00:00
2012-03-17 15:45:37 +00:00
/** Window for displaying the textfile of a BaseSet. */
template < class TBaseSet >
struct BaseSetTextfileWindow : public TextfileWindow {
const TBaseSet * baseset ; ///< View the textfile of this BaseSet.
StringID content_type ; ///< STR_CONTENT_TYPE_xxx for title.
BaseSetTextfileWindow ( TextfileType file_type , const TBaseSet * baseset , StringID content_type ) : TextfileWindow ( file_type ) , baseset ( baseset ) , content_type ( content_type )
{
2023-05-04 23:04:52 +01:00
auto textfile = this - > baseset - > GetTextfile ( file_type ) ;
this - > LoadTextfile ( textfile . value ( ) , BASESET_DIR ) ;
2012-03-17 15:45:37 +00:00
}
2019-03-03 22:25:13 +00:00
void SetStringParameters ( int widget ) const override
2012-03-17 15:45:37 +00:00
{
if ( widget = = WID_TF_CAPTION ) {
SetDParam ( 0 , content_type ) ;
2021-04-27 19:58:17 +01:00
SetDParamStr ( 1 , this - > baseset - > name ) ;
2012-03-17 15:45:37 +00:00
}
}
} ;
/**
* Open the BaseSet version of the textfile window .
* @ param file_type The type of textfile to display .
* @ param baseset The BaseSet to use .
* @ param content_type STR_CONTENT_TYPE_xxx for title .
*/
template < class TBaseSet >
void ShowBaseSetTextfileWindow ( TextfileType file_type , const TBaseSet * baseset , StringID content_type )
{
2021-05-17 14:46:38 +01:00
CloseWindowById ( WC_TEXTFILE , file_type ) ;
2012-03-17 15:45:37 +00:00
new BaseSetTextfileWindow < TBaseSet > ( file_type , baseset , content_type ) ;
}
2021-03-09 09:22:52 +00:00
std : : set < int > _refresh_rates = { 30 , 60 , 75 , 90 , 100 , 120 , 144 , 240 } ;
/**
* Add the refresh rate from the config and the refresh rates from all the monitors to
* our list of refresh rates shown in the GUI .
*/
2021-03-10 12:37:35 +00:00
static void AddCustomRefreshRates ( )
2021-03-09 09:22:52 +00:00
{
/* Add the refresh rate as selected in the config. */
_refresh_rates . insert ( _settings_client . gui . refresh_rate ) ;
/* Add all the refresh rates of all monitors connected to the machine. */
std : : vector < int > monitorRates = VideoDriver : : GetInstance ( ) - > GetListOfMonitorRefreshRates ( ) ;
std : : copy ( monitorRates . begin ( ) , monitorRates . end ( ) , std : : inserter ( _refresh_rates , _refresh_rates . end ( ) ) ) ;
}
2021-04-20 11:49:20 +01:00
static const std : : map < int , StringID > _scale_labels = {
{ 100 , STR_GAME_OPTIONS_GUI_SCALE_1X } ,
{ 125 , STR_NULL } ,
{ 150 , STR_NULL } ,
{ 175 , STR_NULL } ,
{ 200 , STR_GAME_OPTIONS_GUI_SCALE_2X } ,
{ 225 , STR_NULL } ,
{ 250 , STR_NULL } ,
{ 275 , STR_NULL } ,
{ 300 , STR_GAME_OPTIONS_GUI_SCALE_3X } ,
{ 325 , STR_NULL } ,
{ 350 , STR_NULL } ,
{ 375 , STR_NULL } ,
{ 400 , STR_GAME_OPTIONS_GUI_SCALE_4X } ,
{ 425 , STR_NULL } ,
{ 450 , STR_NULL } ,
{ 475 , STR_NULL } ,
{ 500 , STR_GAME_OPTIONS_GUI_SCALE_5X } ,
} ;
2023-05-01 12:58:22 +01:00
static const std : : map < int , StringID > _volume_labels = {
{ 0 , STR_GAME_OPTIONS_VOLUME_0 } ,
{ 15 , STR_NULL } ,
{ 31 , STR_GAME_OPTIONS_VOLUME_25 } ,
{ 47 , STR_NULL } ,
{ 63 , STR_GAME_OPTIONS_VOLUME_50 } ,
{ 79 , STR_NULL } ,
{ 95 , STR_GAME_OPTIONS_VOLUME_75 } ,
{ 111 , STR_NULL } ,
{ 127 , STR_GAME_OPTIONS_VOLUME_100 } ,
} ;
2008-05-18 13:17:52 +01:00
struct GameOptionsWindow : Window {
2008-05-29 16:13:28 +01:00
GameSettings * opt ;
2009-02-07 01:01:02 +00:00
bool reload ;
2021-04-20 11:49:20 +01:00
int gui_scale ;
2008-05-25 13:57:39 +01:00
2013-05-26 20:23:42 +01:00
GameOptionsWindow ( WindowDesc * desc ) : Window ( desc )
2008-05-18 13:17:52 +01:00
{
2011-01-02 00:34:21 +00:00
this - > opt = & GetGameSettings ( ) ;
2009-02-07 01:01:02 +00:00
this - > reload = false ;
2021-04-20 11:49:20 +01:00
this - > gui_scale = _gui_scale ;
2009-07-25 16:10:52 +01:00
2021-03-10 12:37:35 +00:00
AddCustomRefreshRates ( ) ;
2021-03-09 09:22:52 +00:00
2013-05-26 20:23:42 +01:00
this - > InitNested ( WN_GAME_OPTIONS_GAME_OPTIONS ) ;
2009-07-25 16:10:52 +01:00
this - > OnInvalidateData ( 0 ) ;
2023-05-01 12:58:22 +01:00
this - > SetTab ( WID_GO_TAB_GENERAL ) ;
2023-04-25 18:43:45 +01:00
if constexpr ( ! NetworkSurveyHandler : : IsSurveyPossible ( ) ) this - > GetWidget < NWidgetStacked > ( WID_GO_SURVEY_SEL ) - > SetDisplayedPlane ( SZSP_NONE ) ;
2008-01-17 00:21:43 +00:00
}
2023-10-13 12:59:15 +01:00
void Close ( [[maybe_unused]] int data = 0 ) override
2008-05-18 13:17:52 +01:00
{
2021-05-17 14:46:38 +01:00
CloseWindowById ( WC_CUSTOM_CURRENCY , 0 ) ;
CloseWindowByClass ( WC_TEXTFILE ) ;
2009-02-07 01:01:02 +00:00
if ( this - > reload ) _switch_mode = SM_MENU ;
2021-05-15 22:12:25 +01:00
this - > Window : : Close ( ) ;
2008-05-18 13:17:52 +01:00
}
2008-01-17 00:21:43 +00:00
2011-04-10 16:30:08 +01:00
/**
* Build the dropdown list for a specific widget .
* @ param widget Widget to build list for
* @ param selected_index Currently selected item
2019-04-10 22:07:06 +01:00
* @ return the built dropdown list , or nullptr if the widget has no dropdown menu .
2011-04-10 16:30:08 +01:00
*/
2019-04-02 20:31:24 +01:00
DropDownList BuildDropDownList ( int widget , int * selected_index ) const
2011-04-10 16:30:08 +01:00
{
2019-04-02 20:31:24 +01:00
DropDownList list ;
2011-04-10 16:30:08 +01:00
switch ( widget ) {
2011-12-16 18:27:50 +00:00
case WID_GO_CURRENCY_DROPDOWN : { // Setup currencies dropdown
2011-04-10 16:30:08 +01:00
* selected_index = this - > opt - > locale . currency ;
2023-05-08 18:01:06 +01:00
uint64_t disabled = _game_mode = = GM_MENU ? 0LL : ~ GetMaskOfAllowedCurrencies ( ) ;
2011-04-10 16:30:08 +01:00
/* Add non-custom currencies; sorted naturally */
2023-06-23 00:11:11 +01:00
for ( const CurrencySpec & currency : _currency_specs ) {
int i = & currency - _currency_specs ;
2013-03-09 16:23:22 +00:00
if ( i = = CURRENCY_CUSTOM ) continue ;
2023-06-23 00:11:11 +01:00
if ( currency . code . empty ( ) ) {
2023-10-20 18:40:48 +01:00
list . push_back ( std : : make_unique < DropDownListStringItem > ( currency . name , i , HasBit ( disabled , i ) ) ) ;
2023-06-23 00:11:11 +01:00
} else {
SetDParam ( 0 , currency . name ) ;
SetDParamStr ( 1 , currency . code ) ;
2023-10-20 18:40:48 +01:00
list . push_back ( std : : make_unique < DropDownListStringItem > ( STR_GAME_OPTIONS_CURRENCY_CODE , i , HasBit ( disabled , i ) ) ) ;
2023-06-23 00:11:11 +01:00
}
2011-04-10 16:30:08 +01:00
}
2019-04-02 20:31:24 +01:00
std : : sort ( list . begin ( ) , list . end ( ) , DropDownListStringItem : : NatSortFunc ) ;
2011-04-10 16:30:08 +01:00
/* Append custom currency at the end */
2023-10-20 18:40:48 +01:00
list . push_back ( std : : make_unique < DropDownListItem > ( - 1 , false ) ) ; // separator line
list . push_back ( std : : make_unique < DropDownListStringItem > ( STR_GAME_OPTIONS_CURRENCY_CUSTOM , CURRENCY_CUSTOM , HasBit ( disabled , CURRENCY_CUSTOM ) ) ) ;
2011-04-10 16:30:08 +01:00
break ;
}
2011-12-16 18:27:50 +00:00
case WID_GO_AUTOSAVE_DROPDOWN : { // Setup autosave dropdown
2023-07-19 10:26:50 +01:00
int index = 0 ;
for ( auto & minutes : _autosave_dropdown_to_minutes ) {
index + + ;
if ( _settings_client . gui . autosave_interval < = minutes ) break ;
}
* selected_index = index - 1 ;
2011-04-10 16:30:08 +01:00
const StringID * items = _autosave_dropdown ;
for ( uint i = 0 ; * items ! = INVALID_STRING_ID ; items + + , i + + ) {
2023-10-20 18:40:48 +01:00
list . push_back ( std : : make_unique < DropDownListStringItem > ( * items , i , false ) ) ;
2011-04-10 16:30:08 +01:00
}
break ;
}
2011-12-16 18:27:50 +00:00
case WID_GO_LANG_DROPDOWN : { // Setup interface language dropdown
2018-09-23 12:23:54 +01:00
for ( uint i = 0 ; i < _languages . size ( ) ; i + + ) {
2021-04-11 16:28:47 +01:00
bool hide_language = IsReleasedVersion ( ) & & ! _languages [ i ] . IsReasonablyFinished ( ) ;
if ( hide_language ) continue ;
2021-04-11 12:56:24 +01:00
bool hide_percentage = IsReleasedVersion ( ) | | _languages [ i ] . missing < _settings_client . gui . missing_strings_threshold ;
2021-03-09 09:58:33 +00:00
if ( & _languages [ i ] = = _current_language ) {
* selected_index = i ;
2023-06-23 09:30:13 +01:00
SetDParamStr ( 0 , _languages [ i ] . own_name ) ;
2021-03-09 09:58:33 +00:00
} else {
/* Especially with sprite-fonts, not all localized
* names can be rendered . So instead , we use the
* international names for anything but the current
* selected language . This avoids showing a few ? ? ? ?
* entries in the dropdown list . */
2023-06-23 09:30:13 +01:00
SetDParamStr ( 0 , _languages [ i ] . name ) ;
2021-03-09 09:58:33 +00:00
}
2023-06-23 09:30:13 +01:00
SetDParam ( 1 , ( LANGUAGE_TOTAL_STRINGS - _languages [ i ] . missing ) * 100 / LANGUAGE_TOTAL_STRINGS ) ;
2023-10-20 18:40:48 +01:00
list . push_back ( std : : make_unique < DropDownListStringItem > ( hide_percentage ? STR_JUST_RAW_STRING : STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE , i , false ) ) ;
2011-04-10 16:30:08 +01:00
}
2019-04-02 20:31:24 +01:00
std : : sort ( list . begin ( ) , list . end ( ) , DropDownListStringItem : : NatSortFunc ) ;
2011-04-10 16:30:08 +01:00
break ;
}
2011-12-16 18:27:50 +00:00
case WID_GO_RESOLUTION_DROPDOWN : // Setup resolution dropdown
2019-04-12 17:46:49 +01:00
if ( _resolutions . empty ( ) ) break ;
2014-06-05 18:14:16 +01:00
2021-03-09 09:58:33 +00:00
* selected_index = GetCurrentResolutionIndex ( ) ;
2019-04-12 17:46:49 +01:00
for ( uint i = 0 ; i < _resolutions . size ( ) ; i + + ) {
2023-06-23 09:30:13 +01:00
SetDParam ( 0 , _resolutions [ i ] . width ) ;
SetDParam ( 1 , _resolutions [ i ] . height ) ;
2023-10-20 18:40:48 +01:00
list . push_back ( std : : make_unique < DropDownListStringItem > ( STR_GAME_OPTIONS_RESOLUTION_ITEM , i , false ) ) ;
2011-04-10 16:30:08 +01:00
}
break ;
2021-03-09 09:22:52 +00:00
case WID_GO_REFRESH_RATE_DROPDOWN : // Setup refresh rate dropdown
for ( auto it = _refresh_rates . begin ( ) ; it ! = _refresh_rates . end ( ) ; it + + ) {
auto i = std : : distance ( _refresh_rates . begin ( ) , it ) ;
if ( * it = = _settings_client . gui . refresh_rate ) * selected_index = i ;
2023-06-23 09:30:13 +01:00
SetDParam ( 0 , * it ) ;
2023-10-20 18:40:48 +01:00
list . push_back ( std : : make_unique < DropDownListStringItem > ( STR_GAME_OPTIONS_REFRESH_RATE_ITEM , i , false ) ) ;
2021-03-09 09:22:52 +00:00
}
break ;
2011-12-16 18:27:50 +00:00
case WID_GO_BASE_GRF_DROPDOWN :
2023-07-01 12:57:06 +01:00
list = BuildSetDropDownList < BaseGraphics > ( selected_index ) ;
2011-04-10 16:30:08 +01:00
break ;
2011-12-16 18:27:50 +00:00
case WID_GO_BASE_SFX_DROPDOWN :
2023-07-01 12:57:06 +01:00
list = BuildSetDropDownList < BaseSounds > ( selected_index ) ;
2011-04-10 16:30:08 +01:00
break ;
2011-12-16 18:27:50 +00:00
case WID_GO_BASE_MUSIC_DROPDOWN :
2023-07-01 12:57:06 +01:00
list = BuildSetDropDownList < BaseMusic > ( selected_index ) ;
2011-04-10 16:30:08 +01:00
break ;
}
return list ;
}
2019-03-04 07:49:37 +00:00
void SetStringParameters ( int widget ) const override
2008-05-18 13:17:52 +01:00
{
2009-07-25 16:10:52 +01:00
switch ( widget ) {
2023-06-23 00:11:11 +01:00
case WID_GO_CURRENCY_DROPDOWN : {
const CurrencySpec & currency = _currency_specs [ this - > opt - > locale . currency ] ;
if ( currency . code . empty ( ) ) {
SetDParam ( 0 , currency . name ) ;
} else {
SetDParam ( 0 , STR_GAME_OPTIONS_CURRENCY_CODE ) ;
SetDParam ( 1 , currency . name ) ;
SetDParamStr ( 2 , currency . code ) ;
}
break ;
}
2023-07-19 10:26:50 +01:00
case WID_GO_AUTOSAVE_DROPDOWN : {
int index = 0 ;
for ( auto & minutes : _autosave_dropdown_to_minutes ) {
index + + ;
if ( _settings_client . gui . autosave_interval < = minutes ) break ;
}
SetDParam ( 0 , _autosave_dropdown [ index - 1 ] ) ;
break ;
}
2021-03-09 09:22:52 +00:00
case WID_GO_LANG_DROPDOWN : SetDParamStr ( 0 , _current_language - > own_name ) ; break ;
2021-04-27 19:58:17 +01:00
case WID_GO_BASE_GRF_DROPDOWN : SetDParamStr ( 0 , BaseGraphics : : GetUsedSet ( ) - > name ) ; break ;
2021-03-09 09:22:52 +00:00
case WID_GO_BASE_GRF_STATUS : SetDParam ( 0 , BaseGraphics : : GetUsedSet ( ) - > GetNumInvalid ( ) ) ; break ;
2021-04-27 19:58:17 +01:00
case WID_GO_BASE_SFX_DROPDOWN : SetDParamStr ( 0 , BaseSounds : : GetUsedSet ( ) - > name ) ; break ;
case WID_GO_BASE_MUSIC_DROPDOWN : SetDParamStr ( 0 , BaseMusic : : GetUsedSet ( ) - > name ) ; break ;
2021-03-09 09:22:52 +00:00
case WID_GO_BASE_MUSIC_STATUS : SetDParam ( 0 , BaseMusic : : GetUsedSet ( ) - > GetNumInvalid ( ) ) ; break ;
case WID_GO_REFRESH_RATE_DROPDOWN : SetDParam ( 0 , _settings_client . gui . refresh_rate ) ; break ;
2021-03-09 09:58:33 +00:00
case WID_GO_RESOLUTION_DROPDOWN : {
auto current_resolution = GetCurrentResolutionIndex ( ) ;
if ( current_resolution = = _resolutions . size ( ) ) {
SetDParam ( 0 , STR_GAME_OPTIONS_RESOLUTION_OTHER ) ;
} else {
SetDParam ( 0 , STR_GAME_OPTIONS_RESOLUTION_ITEM ) ;
SetDParam ( 1 , _resolutions [ current_resolution ] . width ) ;
SetDParam ( 2 , _resolutions [ current_resolution ] . height ) ;
}
break ;
}
2009-07-25 16:10:52 +01:00
}
}
2008-05-18 13:17:52 +01:00
2019-03-04 07:49:37 +00:00
void DrawWidget ( const Rect & r , int widget ) const override
2009-07-25 16:10:52 +01:00
{
2009-08-09 20:50:44 +01:00
switch ( widget ) {
2011-12-16 18:27:50 +00:00
case WID_GO_BASE_GRF_DESCRIPTION :
2009-10-17 21:34:09 +01:00
SetDParamStr ( 0 , BaseGraphics : : GetUsedSet ( ) - > GetDescription ( GetCurrentLanguageIsoCode ( ) ) ) ;
2023-04-25 18:01:58 +01:00
DrawStringMultiLine ( r . left , r . right , r . top , UINT16_MAX , STR_JUST_RAW_STRING , TC_BLACK ) ;
2009-08-09 20:50:44 +01:00
break ;
2009-05-17 19:21:21 +01:00
2011-12-16 18:27:50 +00:00
case WID_GO_BASE_SFX_DESCRIPTION :
2009-10-17 21:34:09 +01:00
SetDParamStr ( 0 , BaseSounds : : GetUsedSet ( ) - > GetDescription ( GetCurrentLanguageIsoCode ( ) ) ) ;
2023-04-25 18:01:58 +01:00
DrawStringMultiLine ( r . left , r . right , r . top , UINT16_MAX , STR_JUST_RAW_STRING , TC_BLACK ) ;
2009-08-09 20:50:44 +01:00
break ;
2009-12-22 21:40:29 +00:00
2011-12-16 18:27:50 +00:00
case WID_GO_BASE_MUSIC_DESCRIPTION :
2009-12-22 21:40:29 +00:00
SetDParamStr ( 0 , BaseMusic : : GetUsedSet ( ) - > GetDescription ( GetCurrentLanguageIsoCode ( ) ) ) ;
2023-04-25 18:01:58 +01:00
DrawStringMultiLine ( r . left , r . right , r . top , UINT16_MAX , STR_JUST_RAW_STRING , TC_BLACK ) ;
2009-12-22 21:40:29 +00:00
break ;
2021-04-04 10:22:13 +01:00
2021-04-20 11:49:20 +01:00
case WID_GO_GUI_SCALE :
DrawSliderWidget ( r , MIN_INTERFACE_SCALE , MAX_INTERFACE_SCALE , this - > gui_scale , _scale_labels ) ;
break ;
2023-04-19 01:50:36 +01:00
case WID_GO_VIDEO_DRIVER_INFO :
SetDParamStr ( 0 , VideoDriver : : GetInstance ( ) - > GetInfoString ( ) ) ;
DrawStringMultiLine ( r , STR_GAME_OPTIONS_VIDEO_DRIVER_INFO ) ;
break ;
2021-04-04 10:22:13 +01:00
case WID_GO_BASE_SFX_VOLUME :
2023-05-01 12:58:22 +01:00
DrawSliderWidget ( r , 0 , INT8_MAX , _settings_client . music . effect_vol , _volume_labels ) ;
2021-04-04 10:22:13 +01:00
break ;
case WID_GO_BASE_MUSIC_VOLUME :
2023-05-01 12:58:22 +01:00
DrawSliderWidget ( r , 0 , INT8_MAX , _settings_client . music . music_vol , _volume_labels ) ;
2021-04-04 10:22:13 +01:00
break ;
2009-08-09 20:50:44 +01:00
}
2009-07-25 16:10:52 +01:00
}
2023-05-01 12:58:22 +01:00
void SetTab ( int widget )
{
2023-09-16 20:56:09 +01:00
this - > SetWidgetsLoweredState ( false , WID_GO_TAB_GENERAL , WID_GO_TAB_GRAPHICS , WID_GO_TAB_SOUND ) ;
2023-05-01 12:58:22 +01:00
this - > LowerWidget ( widget ) ;
int pane = 0 ;
if ( widget = = WID_GO_TAB_GRAPHICS ) pane = 1 ;
else if ( widget = = WID_GO_TAB_SOUND ) pane = 2 ;
this - > GetWidget < NWidgetStacked > ( WID_GO_TAB_SELECTION ) - > SetDisplayedPlane ( pane ) ;
this - > SetDirty ( ) ;
}
2023-04-19 01:43:11 +01:00
void OnResize ( ) override
{
bool changed = false ;
NWidgetResizeBase * wid = this - > GetWidget < NWidgetResizeBase > ( WID_GO_BASE_GRF_DESCRIPTION ) ;
int y = 0 ;
for ( int i = 0 ; i < BaseGraphics : : GetNumSets ( ) ; i + + ) {
SetDParamStr ( 0 , BaseGraphics : : GetSet ( i ) - > GetDescription ( GetCurrentLanguageIsoCode ( ) ) ) ;
2023-04-25 18:01:58 +01:00
y = std : : max ( y , GetStringHeight ( STR_JUST_RAW_STRING , wid - > current_x ) ) ;
2023-04-19 01:43:11 +01:00
}
changed | = wid - > UpdateVerticalSize ( y ) ;
wid = this - > GetWidget < NWidgetResizeBase > ( WID_GO_BASE_SFX_DESCRIPTION ) ;
y = 0 ;
for ( int i = 0 ; i < BaseSounds : : GetNumSets ( ) ; i + + ) {
SetDParamStr ( 0 , BaseSounds : : GetSet ( i ) - > GetDescription ( GetCurrentLanguageIsoCode ( ) ) ) ;
2023-04-25 18:01:58 +01:00
y = std : : max ( y , GetStringHeight ( STR_JUST_RAW_STRING , wid - > current_x ) ) ;
2023-04-19 01:43:11 +01:00
}
changed | = wid - > UpdateVerticalSize ( y ) ;
wid = this - > GetWidget < NWidgetResizeBase > ( WID_GO_BASE_MUSIC_DESCRIPTION ) ;
y = 0 ;
for ( int i = 0 ; i < BaseMusic : : GetNumSets ( ) ; i + + ) {
SetDParamStr ( 0 , BaseMusic : : GetSet ( i ) - > GetDescription ( GetCurrentLanguageIsoCode ( ) ) ) ;
2023-04-25 18:01:58 +01:00
y = std : : max ( y , GetStringHeight ( STR_JUST_RAW_STRING , wid - > current_x ) ) ;
2023-04-19 01:43:11 +01:00
}
changed | = wid - > UpdateVerticalSize ( y ) ;
2023-04-19 01:50:36 +01:00
wid = this - > GetWidget < NWidgetResizeBase > ( WID_GO_VIDEO_DRIVER_INFO ) ;
SetDParamStr ( 0 , VideoDriver : : GetInstance ( ) - > GetInfoString ( ) ) ;
y = GetStringHeight ( STR_GAME_OPTIONS_VIDEO_DRIVER_INFO , wid - > current_x ) ;
changed | = wid - > UpdateVerticalSize ( y ) ;
2023-05-01 12:58:22 +01:00
if ( changed ) this - > ReInit ( 0 , 0 , this - > flags & WF_CENTERED ) ;
2023-04-19 01:43:11 +01:00
}
2023-09-16 21:20:53 +01:00
void UpdateWidgetSize ( int widget , Dimension * size , [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension * resize ) override
2009-07-25 16:10:52 +01:00
{
2009-08-09 20:50:44 +01:00
switch ( widget ) {
2011-12-16 18:27:50 +00:00
case WID_GO_BASE_GRF_STATUS :
2009-08-13 20:54:18 +01:00
/* Find the biggest description for the default size. */
for ( int i = 0 ; i < BaseGraphics : : GetNumSets ( ) ; i + + ) {
2009-08-20 18:02:44 +01:00
uint invalid_files = BaseGraphics : : GetSet ( i ) - > GetNumInvalid ( ) ;
if ( invalid_files = = 0 ) continue ;
2009-08-13 20:54:18 +01:00
2009-08-20 18:02:44 +01:00
SetDParam ( 0 , invalid_files ) ;
2009-08-13 20:54:18 +01:00
* size = maxdim ( * size , GetStringBoundingBox ( STR_GAME_OPTIONS_BASE_GRF_STATUS ) ) ;
}
break ;
2011-12-16 18:27:50 +00:00
case WID_GO_BASE_MUSIC_STATUS :
2009-12-22 21:40:29 +00:00
/* Find the biggest description for the default size. */
for ( int i = 0 ; i < BaseMusic : : GetNumSets ( ) ; i + + ) {
uint invalid_files = BaseMusic : : GetSet ( i ) - > GetNumInvalid ( ) ;
if ( invalid_files = = 0 ) continue ;
SetDParam ( 0 , invalid_files ) ;
* size = maxdim ( * size , GetStringBoundingBox ( STR_GAME_OPTIONS_BASE_MUSIC_STATUS ) ) ;
}
break ;
2011-04-10 16:30:08 +01:00
2023-05-01 12:58:22 +01:00
case WID_GO_TEXT_SFX_VOLUME :
case WID_GO_TEXT_MUSIC_VOLUME : {
Dimension d = maxdim ( GetStringBoundingBox ( STR_GAME_OPTIONS_SFX_VOLUME ) , GetStringBoundingBox ( STR_GAME_OPTIONS_MUSIC_VOLUME ) ) ;
d . width + = padding . width ;
d . height + = padding . height ;
* size = maxdim ( * size , d ) ;
break ;
}
2011-04-10 16:30:08 +01:00
default : {
int selected ;
2019-04-02 20:31:24 +01:00
DropDownList list = this - > BuildDropDownList ( widget , & selected ) ;
if ( ! list . empty ( ) ) {
2011-04-10 16:30:08 +01:00
/* Find the biggest item for the default size. */
2019-04-02 20:31:24 +01:00
for ( const auto & ddli : list ) {
2011-04-10 16:30:08 +01:00
Dimension string_dim ;
2019-02-17 11:20:52 +00:00
int width = ddli - > Width ( ) ;
2013-10-13 20:18:30 +01:00
string_dim . width = width + padding . width ;
2023-09-18 23:47:47 +01:00
string_dim . height = ddli - > Height ( ) + padding . height ;
2011-04-10 16:30:08 +01:00
* size = maxdim ( * size , string_dim ) ;
}
}
}
2009-05-17 19:21:21 +01:00
}
2008-05-18 13:17:52 +01:00
}
2006-01-05 12:40:50 +00:00
2023-09-16 21:20:53 +01:00
void OnClick ( [[maybe_unused]] Point pt, int widget, [[maybe_unused]] int click_count ) override
2008-05-18 13:17:52 +01:00
{
2023-04-25 18:43:45 +01:00
if ( widget > = WID_GO_BASE_GRF_TEXTFILE & & widget < WID_GO_BASE_GRF_TEXTFILE + TFT_CONTENT_END ) {
2019-04-10 22:07:06 +01:00
if ( BaseGraphics : : GetUsedSet ( ) = = nullptr ) return ;
2012-03-17 15:45:37 +00:00
ShowBaseSetTextfileWindow ( ( TextfileType ) ( widget - WID_GO_BASE_GRF_TEXTFILE ) , BaseGraphics : : GetUsedSet ( ) , STR_CONTENT_TYPE_BASE_GRAPHICS ) ;
return ;
}
2023-04-25 18:43:45 +01:00
if ( widget > = WID_GO_BASE_SFX_TEXTFILE & & widget < WID_GO_BASE_SFX_TEXTFILE + TFT_CONTENT_END ) {
2019-04-10 22:07:06 +01:00
if ( BaseSounds : : GetUsedSet ( ) = = nullptr ) return ;
2012-03-17 15:45:37 +00:00
ShowBaseSetTextfileWindow ( ( TextfileType ) ( widget - WID_GO_BASE_SFX_TEXTFILE ) , BaseSounds : : GetUsedSet ( ) , STR_CONTENT_TYPE_BASE_SOUNDS ) ;
return ;
}
2023-04-25 18:43:45 +01:00
if ( widget > = WID_GO_BASE_MUSIC_TEXTFILE & & widget < WID_GO_BASE_MUSIC_TEXTFILE + TFT_CONTENT_END ) {
2019-04-10 22:07:06 +01:00
if ( BaseMusic : : GetUsedSet ( ) = = nullptr ) return ;
2012-03-17 15:45:37 +00:00
ShowBaseSetTextfileWindow ( ( TextfileType ) ( widget - WID_GO_BASE_MUSIC_TEXTFILE ) , BaseMusic : : GetUsedSet ( ) , STR_CONTENT_TYPE_BASE_MUSIC ) ;
return ;
}
2008-05-18 13:17:52 +01:00
switch ( widget ) {
2023-05-01 12:58:22 +01:00
case WID_GO_TAB_GENERAL :
case WID_GO_TAB_GRAPHICS :
case WID_GO_TAB_SOUND :
this - > SetTab ( widget ) ;
break ;
2023-04-25 18:43:45 +01:00
case WID_GO_SURVEY_PARTICIPATE_BUTTON :
switch ( _settings_client . network . participate_survey ) {
case PS_ASK :
case PS_NO :
_settings_client . network . participate_survey = PS_YES ;
break ;
case PS_YES :
_settings_client . network . participate_survey = PS_NO ;
break ;
}
this - > SetWidgetLoweredState ( WID_GO_SURVEY_PARTICIPATE_BUTTON , _settings_client . network . participate_survey = = PS_YES ) ;
this - > SetWidgetDirty ( WID_GO_SURVEY_PARTICIPATE_BUTTON ) ;
break ;
case WID_GO_SURVEY_LINK_BUTTON :
OpenBrowser ( NETWORK_SURVEY_DETAILS_LINK . c_str ( ) ) ;
break ;
case WID_GO_SURVEY_PREVIEW_BUTTON :
ShowSurveyResultTextfileWindow ( ) ;
break ;
2011-12-16 18:27:50 +00:00
case WID_GO_FULLSCREEN_BUTTON : // Click fullscreen on/off
2008-05-18 13:17:52 +01:00
/* try to toggle full-screen on/off */
if ( ! ToggleFullScreen ( ! _fullscreen ) ) {
2010-02-24 14:46:15 +00:00
ShowErrorMessage ( STR_ERROR_FULLSCREEN_FAILED , INVALID_STRING_ID , WL_ERROR ) ;
2008-05-18 13:17:52 +01:00
}
2011-12-16 18:27:50 +00:00
this - > SetWidgetLoweredState ( WID_GO_FULLSCREEN_BUTTON , _fullscreen ) ;
2021-05-06 01:36:56 +01:00
this - > SetWidgetDirty ( WID_GO_FULLSCREEN_BUTTON ) ;
2008-05-18 13:17:52 +01:00
break ;
2021-03-08 14:42:39 +00:00
case WID_GO_VIDEO_ACCEL_BUTTON :
_video_hw_accel = ! _video_hw_accel ;
ShowErrorMessage ( STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART , INVALID_STRING_ID , WL_INFO ) ;
this - > SetWidgetLoweredState ( WID_GO_VIDEO_ACCEL_BUTTON , _video_hw_accel ) ;
2021-05-06 01:36:56 +01:00
this - > SetWidgetDirty ( WID_GO_VIDEO_ACCEL_BUTTON ) ;
2021-04-10 13:53:26 +01:00
# ifndef __APPLE__
this - > SetWidgetDisabledState ( WID_GO_VIDEO_VSYNC_BUTTON , ! _video_hw_accel ) ;
2021-05-06 01:36:56 +01:00
this - > SetWidgetDirty ( WID_GO_VIDEO_VSYNC_BUTTON ) ;
2021-04-10 13:53:26 +01:00
# endif
break ;
case WID_GO_VIDEO_VSYNC_BUTTON :
if ( ! _video_hw_accel ) break ;
_video_vsync = ! _video_vsync ;
VideoDriver : : GetInstance ( ) - > ToggleVsync ( _video_vsync ) ;
this - > SetWidgetLoweredState ( WID_GO_VIDEO_VSYNC_BUTTON , _video_vsync ) ;
2021-05-06 01:36:56 +01:00
this - > SetWidgetDirty ( WID_GO_VIDEO_VSYNC_BUTTON ) ;
2021-10-17 18:24:04 +01:00
this - > SetWidgetDisabledState ( WID_GO_REFRESH_RATE_DROPDOWN , _video_vsync ) ;
this - > SetWidgetDirty ( WID_GO_REFRESH_RATE_DROPDOWN ) ;
2021-03-08 14:42:39 +00:00
break ;
2022-09-23 09:34:46 +01:00
case WID_GO_GUI_SCALE_BEVEL_BUTTON : {
_settings_client . gui . scale_bevels = ! _settings_client . gui . scale_bevels ;
this - > SetWidgetLoweredState ( WID_GO_GUI_SCALE_BEVEL_BUTTON , _settings_client . gui . scale_bevels ) ;
this - > SetDirty ( ) ;
SetupWidgetDimensions ( ) ;
ReInitAllWindows ( true ) ;
break ;
}
2021-04-20 11:49:20 +01:00
case WID_GO_GUI_SCALE :
if ( ClickSliderWidget ( this - > GetWidget < NWidgetBase > ( widget ) - > GetCurrentRect ( ) , pt , MIN_INTERFACE_SCALE , MAX_INTERFACE_SCALE , this - > gui_scale ) ) {
if ( ! _ctrl_pressed ) this - > gui_scale = ( ( this - > gui_scale + 12 ) / 25 ) * 25 ;
this - > SetWidgetDirty ( widget ) ;
}
if ( click_count > 0 ) this - > mouse_capture_widget = widget ;
break ;
case WID_GO_GUI_SCALE_AUTO :
{
if ( _gui_scale_cfg = = - 1 ) {
_gui_scale_cfg = _gui_scale ;
this - > SetWidgetLoweredState ( WID_GO_GUI_SCALE_AUTO , false ) ;
} else {
_gui_scale_cfg = - 1 ;
this - > SetWidgetLoweredState ( WID_GO_GUI_SCALE_AUTO , true ) ;
if ( AdjustGUIZoom ( false ) ) ReInitAllWindows ( true ) ;
this - > gui_scale = _gui_scale ;
}
this - > SetWidgetDirty ( widget ) ;
break ;
}
2023-10-02 13:43:10 +01:00
case WID_GO_BASE_GRF_PARAMETERS : {
auto * used_set = BaseGraphics : : GetUsedSet ( ) ;
if ( used_set = = nullptr | | ! used_set - > IsConfigurable ( ) ) break ;
GRFConfig & extra_cfg = used_set - > GetOrCreateExtraConfig ( ) ;
if ( extra_cfg . num_params = = 0 ) extra_cfg . SetParameterDefaults ( ) ;
OpenGRFParameterWindow ( true , & extra_cfg , _game_mode = = GM_MENU ) ;
if ( _game_mode = = GM_MENU ) this - > reload = true ;
break ;
}
2021-04-04 10:22:13 +01:00
case WID_GO_BASE_SFX_VOLUME :
case WID_GO_BASE_MUSIC_VOLUME : {
byte & vol = ( widget = = WID_GO_BASE_MUSIC_VOLUME ) ? _settings_client . music . music_vol : _settings_client . music . effect_vol ;
2022-10-23 15:35:35 +01:00
if ( ClickSliderWidget ( this - > GetWidget < NWidgetBase > ( widget ) - > GetCurrentRect ( ) , pt , 0 , INT8_MAX , vol ) ) {
2022-12-10 15:51:45 +00:00
if ( widget = = WID_GO_BASE_MUSIC_VOLUME ) {
MusicDriver : : GetInstance ( ) - > SetVolume ( vol ) ;
} else {
SetEffectVolume ( vol ) ;
}
2021-05-06 01:36:56 +01:00
this - > SetWidgetDirty ( widget ) ;
2021-04-04 10:22:13 +01:00
SetWindowClassesDirty ( WC_MUSIC_WINDOW ) ;
}
if ( click_count > 0 ) this - > mouse_capture_widget = widget ;
break ;
}
2022-11-08 18:21:52 +00:00
case WID_GO_BASE_MUSIC_JUKEBOX : {
ShowMusicWindow ( ) ;
break ;
}
2011-04-10 16:30:08 +01:00
default : {
int selected ;
2019-04-02 20:31:24 +01:00
DropDownList list = this - > BuildDropDownList ( widget , & selected ) ;
if ( ! list . empty ( ) ) {
ShowDropDownList ( this , std : : move ( list ) , selected , widget ) ;
2014-06-05 18:14:16 +01:00
} else {
if ( widget = = WID_GO_RESOLUTION_DROPDOWN ) ShowErrorMessage ( STR_ERROR_RESOLUTION_LIST_FAILED , INVALID_STRING_ID , WL_ERROR ) ;
2011-04-10 16:30:08 +01:00
}
2009-12-22 21:40:29 +00:00
break ;
2011-04-10 16:30:08 +01:00
}
2008-05-18 13:17:52 +01:00
}
}
2008-01-04 02:32:58 +00:00
2021-04-20 11:49:20 +01:00
void OnMouseLoop ( ) override
{
if ( _left_button_down | | this - > gui_scale = = _gui_scale ) return ;
_gui_scale_cfg = this - > gui_scale ;
if ( AdjustGUIZoom ( false ) ) {
ReInitAllWindows ( true ) ;
this - > SetWidgetLoweredState ( WID_GO_GUI_SCALE_AUTO , false ) ;
this - > SetDirty ( ) ;
}
}
2019-03-04 07:49:37 +00:00
void OnDropdownSelect ( int widget , int index ) override
2008-05-18 13:17:52 +01:00
{
switch ( widget ) {
2011-12-16 18:27:50 +00:00
case WID_GO_CURRENCY_DROPDOWN : // Currency
2013-03-09 16:16:17 +00:00
if ( index = = CURRENCY_CUSTOM ) ShowCustCurrency ( ) ;
2008-06-05 12:26:38 +01:00
this - > opt - > locale . currency = index ;
2021-04-05 18:43:12 +01:00
ReInitAllWindows ( false ) ;
2008-05-18 13:17:52 +01:00
break ;
2011-12-16 18:27:50 +00:00
case WID_GO_AUTOSAVE_DROPDOWN : // Autosave options
2023-07-19 10:26:50 +01:00
_settings_client . gui . autosave_interval = _autosave_dropdown_to_minutes [ index ] ;
2023-04-27 16:21:29 +01:00
ChangeAutosaveFrequency ( false ) ;
2008-05-18 13:17:52 +01:00
this - > SetDirty ( ) ;
break ;
2011-12-16 18:27:50 +00:00
case WID_GO_LANG_DROPDOWN : // Change interface language
2010-11-13 12:09:30 +00:00
ReadLanguagePack ( & _languages [ index ] ) ;
2021-05-17 14:46:38 +01:00
CloseWindowByClass ( WC_QUERY_STRING ) ;
2011-11-20 11:52:11 +00:00
CheckForMissingGlyphs ( ) ;
2020-01-06 20:40:31 +00:00
ClearAllCachedNames ( ) ;
2009-12-13 19:33:07 +00:00
UpdateAllVirtCoords ( ) ;
2021-02-23 19:54:50 +00:00
CheckBlitter ( ) ;
2021-04-05 18:43:12 +01:00
ReInitAllWindows ( false ) ;
2008-05-18 13:17:52 +01:00
break ;
2011-12-16 18:27:50 +00:00
case WID_GO_RESOLUTION_DROPDOWN : // Change resolution
2019-04-12 17:46:49 +01:00
if ( ( uint ) index < _resolutions . size ( ) & & ChangeResInGame ( _resolutions [ index ] . width , _resolutions [ index ] . height ) ) {
2008-05-18 13:17:52 +01:00
this - > SetDirty ( ) ;
}
break ;
2021-03-09 09:22:52 +00:00
case WID_GO_REFRESH_RATE_DROPDOWN : {
_settings_client . gui . refresh_rate = * std : : next ( _refresh_rates . begin ( ) , index ) ;
if ( _settings_client . gui . refresh_rate > 60 ) {
/* Show warning to the user that this refresh rate might not be suitable on
* larger maps with many NewGRFs and vehicles . */
ShowErrorMessage ( STR_GAME_OPTIONS_REFRESH_RATE_WARNING , INVALID_STRING_ID , WL_INFO ) ;
}
break ;
}
2011-12-16 18:27:50 +00:00
case WID_GO_BASE_GRF_DROPDOWN :
2023-10-02 12:29:32 +01:00
if ( _game_mode = = GM_MENU ) {
2023-10-02 13:43:10 +01:00
CloseWindowByClass ( WC_GRF_PARAMETERS ) ;
2023-10-02 12:29:32 +01:00
auto * set = BaseGraphics : : GetSet ( index ) ;
2023-10-02 13:17:32 +01:00
BaseGraphics : : SetSet ( set ) ;
2023-10-02 12:29:32 +01:00
this - > reload = true ;
this - > InvalidateData ( ) ;
}
2009-08-09 20:50:44 +01:00
break ;
2009-02-07 01:01:02 +00:00
2011-12-16 18:27:50 +00:00
case WID_GO_BASE_SFX_DROPDOWN :
2023-10-02 12:29:32 +01:00
if ( _game_mode = = GM_MENU ) {
auto * set = BaseSounds : : GetSet ( index ) ;
BaseSounds : : ini_set = set - > name ;
2023-10-02 13:17:32 +01:00
BaseSounds : : SetSet ( set ) ;
2023-10-02 12:29:32 +01:00
this - > reload = true ;
this - > InvalidateData ( ) ;
}
2009-02-07 01:01:02 +00:00
break ;
2009-12-22 21:40:29 +00:00
2011-12-16 18:27:50 +00:00
case WID_GO_BASE_MUSIC_DROPDOWN :
2018-03-20 16:06:39 +00:00
ChangeMusicSet ( index ) ;
2009-12-22 21:40:29 +00:00
break ;
2008-05-18 13:17:52 +01:00
}
2004-08-09 18:04:08 +01:00
}
2011-03-13 21:31:29 +00:00
/**
* Some data on this window has become invalid .
2011-07-02 13:49:44 +01:00
* @ param data Information about the changed data . @ see GameOptionsInvalidationData
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 .
*/
2023-09-16 21:20:53 +01:00
void OnInvalidateData ( [[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true ) override
2009-07-25 16:10:52 +01:00
{
2011-03-13 21:31:29 +00:00
if ( ! gui_scope ) return ;
2023-04-25 18:43:45 +01:00
this - > SetWidgetLoweredState ( WID_GO_SURVEY_PARTICIPATE_BUTTON , _settings_client . network . participate_survey = = PS_YES ) ;
2011-12-16 18:27:50 +00:00
this - > SetWidgetLoweredState ( WID_GO_FULLSCREEN_BUTTON , _fullscreen ) ;
2021-03-08 14:42:39 +00:00
this - > SetWidgetLoweredState ( WID_GO_VIDEO_ACCEL_BUTTON , _video_hw_accel ) ;
2021-10-17 18:24:04 +01:00
this - > SetWidgetDisabledState ( WID_GO_REFRESH_RATE_DROPDOWN , _video_vsync ) ;
2009-07-25 16:10:52 +01:00
2021-04-10 13:53:26 +01:00
# ifndef __APPLE__
this - > SetWidgetLoweredState ( WID_GO_VIDEO_VSYNC_BUTTON , _video_vsync ) ;
this - > SetWidgetDisabledState ( WID_GO_VIDEO_VSYNC_BUTTON , ! _video_hw_accel ) ;
# endif
2021-04-20 11:49:20 +01:00
this - > SetWidgetLoweredState ( WID_GO_GUI_SCALE_AUTO , _gui_scale_cfg = = - 1 ) ;
2022-09-23 09:34:46 +01:00
this - > SetWidgetLoweredState ( WID_GO_GUI_SCALE_BEVEL_BUTTON , _settings_client . gui . scale_bevels ) ;
2023-07-01 12:57:06 +01:00
this - > SetWidgetDisabledState ( WID_GO_BASE_GRF_DROPDOWN , _game_mode ! = GM_MENU ) ;
this - > SetWidgetDisabledState ( WID_GO_BASE_SFX_DROPDOWN , _game_mode ! = GM_MENU ) ;
2009-08-09 17:54:03 +01:00
bool missing_files = BaseGraphics : : GetUsedSet ( ) - > GetNumMissing ( ) = = 0 ;
2011-12-16 18:27:50 +00:00
this - > GetWidget < NWidgetCore > ( WID_GO_BASE_GRF_STATUS ) - > SetDataTip ( missing_files ? STR_EMPTY : STR_GAME_OPTIONS_BASE_GRF_STATUS , STR_NULL ) ;
2009-12-22 21:40:29 +00:00
2023-10-02 13:43:10 +01:00
this - > SetWidgetDisabledState ( WID_GO_BASE_GRF_PARAMETERS , BaseGraphics : : GetUsedSet ( ) = = nullptr | | ! BaseGraphics : : GetUsedSet ( ) - > IsConfigurable ( ) ) ;
2023-04-25 18:43:45 +01:00
for ( TextfileType tft = TFT_CONTENT_BEGIN ; tft < TFT_CONTENT_END ; tft + + ) {
2023-05-04 23:04:52 +01:00
this - > SetWidgetDisabledState ( WID_GO_BASE_GRF_TEXTFILE + tft , BaseGraphics : : GetUsedSet ( ) = = nullptr | | ! BaseGraphics : : GetUsedSet ( ) - > GetTextfile ( tft ) . has_value ( ) ) ;
this - > SetWidgetDisabledState ( WID_GO_BASE_SFX_TEXTFILE + tft , BaseSounds : : GetUsedSet ( ) = = nullptr | | ! BaseSounds : : GetUsedSet ( ) - > GetTextfile ( tft ) . has_value ( ) ) ;
this - > SetWidgetDisabledState ( WID_GO_BASE_MUSIC_TEXTFILE + tft , BaseMusic : : GetUsedSet ( ) = = nullptr | | ! BaseMusic : : GetUsedSet ( ) - > GetTextfile ( tft ) . has_value ( ) ) ;
2012-03-17 15:45:37 +00:00
}
2009-12-22 21:40:29 +00:00
missing_files = BaseMusic : : GetUsedSet ( ) - > GetNumInvalid ( ) = = 0 ;
2011-12-16 18:27:50 +00:00
this - > GetWidget < NWidgetCore > ( WID_GO_BASE_MUSIC_STATUS ) - > SetDataTip ( missing_files ? STR_EMPTY : STR_GAME_OPTIONS_BASE_MUSIC_STATUS , STR_NULL ) ;
2009-07-25 16:10:52 +01:00
}
2004-08-09 18:04:08 +01:00
} ;
2009-03-28 11:17:38 +00:00
static const NWidgetPart _nested_game_options_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
NWidget ( WWT_CAPTION , COLOUR_GREY ) , SetDataTip ( STR_GAME_OPTIONS_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2009-03-28 11:17:38 +00:00
EndContainer ( ) ,
2023-05-01 12:58:22 +01:00
NWidget ( WWT_PANEL , COLOUR_GREY ) ,
NWidget ( NWID_HORIZONTAL , NC_EQUALSIZE ) , SetPadding ( 5 , 10 , 5 , 10 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_YELLOW , WID_GO_TAB_GENERAL ) , SetMinimalTextLines ( 2 , 0 ) , SetDataTip ( STR_GAME_OPTIONS_TAB_GENERAL , STR_GAME_OPTIONS_TAB_GENERAL_TT ) , SetFill ( 1 , 0 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_YELLOW , WID_GO_TAB_GRAPHICS ) , SetMinimalTextLines ( 2 , 0 ) , SetDataTip ( STR_GAME_OPTIONS_TAB_GRAPHICS , STR_GAME_OPTIONS_TAB_GRAPHICS_TT ) , SetFill ( 1 , 0 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_YELLOW , WID_GO_TAB_SOUND ) , SetMinimalTextLines ( 2 , 0 ) , SetDataTip ( STR_GAME_OPTIONS_TAB_SOUND , STR_GAME_OPTIONS_TAB_SOUND_TT ) , SetFill ( 1 , 0 ) ,
EndContainer ( ) ,
EndContainer ( ) ,
NWidget ( WWT_PANEL , COLOUR_GREY ) ,
NWidget ( NWID_SELECTION , INVALID_COLOUR , WID_GO_TAB_SELECTION ) ,
/* General tab */
NWidget ( NWID_VERTICAL ) , SetPadding ( 10 ) , SetPIP ( 0 , WidgetDimensions : : unscaled . vsep_wide , 0 ) ,
NWidget ( WWT_FRAME , COLOUR_GREY ) , SetDataTip ( STR_GAME_OPTIONS_LANGUAGE , STR_NULL ) ,
2023-04-25 18:01:58 +01:00
NWidget ( WWT_DROPDOWN , COLOUR_GREY , WID_GO_LANG_DROPDOWN ) , SetMinimalSize ( 100 , 12 ) , SetDataTip ( STR_JUST_RAW_STRING , STR_GAME_OPTIONS_LANGUAGE_TOOLTIP ) , SetFill ( 1 , 0 ) ,
2023-05-01 12:58:22 +01:00
EndContainer ( ) ,
2009-11-24 21:13:36 +00:00
NWidget ( WWT_FRAME , COLOUR_GREY ) , SetDataTip ( STR_GAME_OPTIONS_AUTOSAVE_FRAME , STR_NULL ) ,
2023-04-25 10:03:48 +01:00
NWidget ( WWT_DROPDOWN , COLOUR_GREY , WID_GO_AUTOSAVE_DROPDOWN ) , SetMinimalSize ( 100 , 12 ) , SetDataTip ( STR_JUST_STRING , STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP ) , SetFill ( 1 , 0 ) ,
2009-03-28 11:17:38 +00:00
EndContainer ( ) ,
2023-05-01 12:58:22 +01:00
2021-03-09 09:22:52 +00:00
NWidget ( WWT_FRAME , COLOUR_GREY ) , SetDataTip ( STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME , STR_NULL ) ,
2023-06-23 00:11:11 +01:00
NWidget ( WWT_DROPDOWN , COLOUR_GREY , WID_GO_CURRENCY_DROPDOWN ) , SetMinimalSize ( 100 , 12 ) , SetDataTip ( STR_JUST_STRING2 , STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP ) , SetFill ( 1 , 0 ) ,
2009-03-28 11:17:38 +00:00
EndContainer ( ) ,
2023-04-25 18:43:45 +01:00
NWidget ( NWID_SELECTION , INVALID_COLOUR , WID_GO_SURVEY_SEL ) ,
NWidget ( WWT_FRAME , COLOUR_GREY ) , SetDataTip ( STR_GAME_OPTIONS_PARTICIPATE_SURVEY_FRAME , STR_NULL ) , SetPIP ( 0 , WidgetDimensions : : unscaled . vsep_normal , 0 ) ,
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( WWT_TEXT , COLOUR_GREY ) , SetMinimalSize ( 0 , 12 ) , SetDataTip ( STR_GAME_OPTIONS_PARTICIPATE_SURVEY , STR_NULL ) ,
NWidget ( NWID_SPACER ) , SetMinimalSize ( 1 , 0 ) , SetFill ( 1 , 0 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , WID_GO_SURVEY_PARTICIPATE_BUTTON ) , SetMinimalSize ( 21 , 9 ) , SetDataTip ( STR_EMPTY , STR_GAME_OPTIONS_PARTICIPATE_SURVEY_TOOLTIP ) ,
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL , NC_EQUALSIZE ) , SetPIP ( 7 , 0 , 7 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , WID_GO_SURVEY_PREVIEW_BUTTON ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) , SetDataTip ( STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW , STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW_TOOLTIP ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , WID_GO_SURVEY_LINK_BUTTON ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) , SetDataTip ( STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK , STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK_TOOLTIP ) ,
EndContainer ( ) ,
EndContainer ( ) ,
EndContainer ( ) ,
2009-03-28 11:17:38 +00:00
EndContainer ( ) ,
2023-05-01 12:58:22 +01:00
/* Graphics tab */
NWidget ( NWID_VERTICAL ) , SetPadding ( 10 ) , SetPIP ( 0 , WidgetDimensions : : unscaled . vsep_wide , 0 ) ,
2021-04-20 11:49:20 +01:00
NWidget ( WWT_FRAME , COLOUR_GREY ) , SetDataTip ( STR_GAME_OPTIONS_GUI_SCALE_FRAME , STR_NULL ) ,
NWidget ( NWID_VERTICAL ) , SetPIP ( 0 , WidgetDimensions : : unscaled . vsep_normal , 0 ) ,
NWidget ( WWT_EMPTY , COLOUR_GREY , WID_GO_GUI_SCALE ) , SetMinimalSize ( 67 , 0 ) , SetMinimalTextLines ( 1 , 12 + WidgetDimensions : : unscaled . vsep_normal , FS_SMALL ) , SetFill ( 0 , 0 ) , SetDataTip ( 0x0 , STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP ) ,
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( WWT_TEXT , COLOUR_GREY ) , SetMinimalSize ( 0 , 12 ) , SetDataTip ( STR_GAME_OPTIONS_GUI_SCALE_AUTO , STR_NULL ) ,
NWidget ( NWID_SPACER ) , SetMinimalSize ( 1 , 0 ) , SetFill ( 1 , 0 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , WID_GO_GUI_SCALE_AUTO ) , SetMinimalSize ( 21 , 9 ) , SetDataTip ( STR_EMPTY , STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP ) ,
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( WWT_TEXT , COLOUR_GREY ) , SetMinimalSize ( 0 , 12 ) , SetDataTip ( STR_GAME_OPTIONS_GUI_SCALE_BEVELS , STR_NULL ) ,
NWidget ( NWID_SPACER ) , SetMinimalSize ( 1 , 0 ) , SetFill ( 1 , 0 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , WID_GO_GUI_SCALE_BEVEL_BUTTON ) , SetMinimalSize ( 21 , 9 ) , SetDataTip ( STR_EMPTY , STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP ) ,
EndContainer ( ) ,
EndContainer ( ) ,
2019-02-23 08:27:46 +00:00
EndContainer ( ) ,
2009-05-17 19:21:21 +01:00
2023-05-01 12:58:22 +01:00
NWidget ( WWT_FRAME , COLOUR_GREY ) , SetDataTip ( STR_GAME_OPTIONS_GRAPHICS , STR_NULL ) ,
NWidget ( NWID_VERTICAL ) , SetPIP ( 0 , WidgetDimensions : : unscaled . vsep_normal , 0 ) ,
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( WWT_TEXT , COLOUR_GREY ) , SetMinimalSize ( 0 , 12 ) , SetDataTip ( STR_GAME_OPTIONS_RESOLUTION , STR_NULL ) ,
NWidget ( NWID_SPACER ) , SetMinimalSize ( 1 , 0 ) , SetFill ( 1 , 0 ) ,
2023-06-13 19:00:26 +01:00
NWidget ( WWT_DROPDOWN , COLOUR_GREY , WID_GO_RESOLUTION_DROPDOWN ) , SetMinimalSize ( 100 , 12 ) , SetDataTip ( STR_JUST_STRING2 , STR_GAME_OPTIONS_RESOLUTION_TOOLTIP ) ,
2023-05-01 12:58:22 +01:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( WWT_TEXT , COLOUR_GREY ) , SetMinimalSize ( 0 , 12 ) , SetDataTip ( STR_GAME_OPTIONS_REFRESH_RATE , STR_NULL ) ,
NWidget ( NWID_SPACER ) , SetMinimalSize ( 1 , 0 ) , SetFill ( 1 , 0 ) ,
NWidget ( WWT_DROPDOWN , COLOUR_GREY , WID_GO_REFRESH_RATE_DROPDOWN ) , SetMinimalSize ( 100 , 12 ) , SetDataTip ( STR_GAME_OPTIONS_REFRESH_RATE_ITEM , STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP ) ,
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( WWT_TEXT , COLOUR_GREY ) , SetMinimalSize ( 0 , 12 ) , SetDataTip ( STR_GAME_OPTIONS_FULLSCREEN , STR_NULL ) ,
NWidget ( NWID_SPACER ) , SetMinimalSize ( 1 , 0 ) , SetFill ( 1 , 0 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , WID_GO_FULLSCREEN_BUTTON ) , SetMinimalSize ( 21 , 9 ) , SetDataTip ( STR_EMPTY , STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP ) ,
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( WWT_TEXT , COLOUR_GREY ) , SetMinimalSize ( 0 , 12 ) , SetDataTip ( STR_GAME_OPTIONS_VIDEO_ACCELERATION , STR_NULL ) ,
NWidget ( NWID_SPACER ) , SetMinimalSize ( 1 , 0 ) , SetFill ( 1 , 0 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , WID_GO_VIDEO_ACCEL_BUTTON ) , SetMinimalSize ( 21 , 9 ) , SetDataTip ( STR_EMPTY , STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP ) ,
EndContainer ( ) ,
2021-04-10 13:53:26 +01:00
# ifndef __APPLE__
2023-05-01 12:58:22 +01:00
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( WWT_TEXT , COLOUR_GREY ) , SetMinimalSize ( 0 , 12 ) , SetDataTip ( STR_GAME_OPTIONS_VIDEO_VSYNC , STR_NULL ) ,
NWidget ( NWID_SPACER ) , SetMinimalSize ( 1 , 0 ) , SetFill ( 1 , 0 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , WID_GO_VIDEO_VSYNC_BUTTON ) , SetMinimalSize ( 21 , 9 ) , SetDataTip ( STR_EMPTY , STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP ) ,
EndContainer ( ) ,
2021-04-10 13:53:26 +01:00
# endif
2023-05-01 12:58:22 +01:00
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( WWT_EMPTY , INVALID_COLOUR , WID_GO_VIDEO_DRIVER_INFO ) , SetMinimalTextLines ( 1 , 0 ) , SetFill ( 1 , 0 ) ,
EndContainer ( ) ,
2022-04-30 13:52:39 +01:00
EndContainer ( ) ,
2021-03-09 09:22:52 +00:00
EndContainer ( ) ,
2023-05-01 12:58:22 +01:00
NWidget ( WWT_FRAME , COLOUR_GREY ) , SetDataTip ( STR_GAME_OPTIONS_BASE_GRF , STR_NULL ) ,
NWidget ( NWID_HORIZONTAL ) , SetPIP ( 0 , 30 , 0 ) ,
2023-04-25 18:01:58 +01:00
NWidget ( WWT_DROPDOWN , COLOUR_GREY , WID_GO_BASE_GRF_DROPDOWN ) , SetMinimalSize ( 100 , 12 ) , SetDataTip ( STR_JUST_RAW_STRING , STR_GAME_OPTIONS_BASE_GRF_TOOLTIP ) ,
2023-05-01 12:58:22 +01:00
NWidget ( WWT_TEXT , COLOUR_GREY , WID_GO_BASE_GRF_STATUS ) , SetMinimalSize ( 100 , 12 ) , SetDataTip ( STR_EMPTY , STR_NULL ) , SetFill ( 1 , 0 ) ,
2023-10-02 13:43:10 +01:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_GO_BASE_GRF_PARAMETERS ) , SetDataTip ( STR_NEWGRF_SETTINGS_SET_PARAMETERS , STR_NULL ) ,
2023-05-01 12:58:22 +01:00
EndContainer ( ) ,
NWidget ( WWT_TEXT , COLOUR_GREY , WID_GO_BASE_GRF_DESCRIPTION ) , SetMinimalSize ( 200 , 0 ) , SetDataTip ( STR_EMPTY , STR_GAME_OPTIONS_BASE_GRF_DESCRIPTION_TOOLTIP ) , SetFill ( 1 , 0 ) , SetPadding ( 6 , 0 , 6 , 0 ) ,
NWidget ( NWID_HORIZONTAL , NC_EQUALSIZE ) , SetPIP ( 7 , 0 , 7 ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_GO_BASE_GRF_TEXTFILE + TFT_README ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) , SetDataTip ( STR_TEXTFILE_VIEW_README , STR_NULL ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_GO_BASE_GRF_TEXTFILE + TFT_CHANGELOG ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) , SetDataTip ( STR_TEXTFILE_VIEW_CHANGELOG , STR_NULL ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_GO_BASE_GRF_TEXTFILE + TFT_LICENSE ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) , SetDataTip ( STR_TEXTFILE_VIEW_LICENCE , STR_NULL ) ,
EndContainer ( ) ,
EndContainer ( ) ,
2012-03-17 15:45:37 +00:00
EndContainer ( ) ,
2009-08-09 20:50:44 +01:00
2023-05-01 12:58:22 +01:00
/* Sound/Music tab */
NWidget ( NWID_VERTICAL ) , SetPadding ( 10 ) , SetPIP ( 0 , WidgetDimensions : : unscaled . vsep_wide , 0 ) ,
NWidget ( WWT_FRAME , COLOUR_GREY ) , SetDataTip ( STR_GAME_OPTIONS_VOLUME , STR_NULL ) ,
NWidget ( NWID_VERTICAL ) , SetPIP ( 0 , WidgetDimensions : : unscaled . vsep_wide , 0 ) ,
NWidget ( NWID_HORIZONTAL ) , SetPIP ( 0 , WidgetDimensions : : unscaled . hsep_wide , 0 ) ,
NWidget ( WWT_TEXT , COLOUR_GREY , WID_GO_TEXT_SFX_VOLUME ) , SetMinimalSize ( 0 , 12 ) , SetDataTip ( STR_GAME_OPTIONS_SFX_VOLUME , STR_NULL ) ,
NWidget ( WWT_EMPTY , COLOUR_GREY , WID_GO_BASE_SFX_VOLUME ) , SetMinimalSize ( 67 , 0 ) , SetMinimalTextLines ( 1 , 12 + WidgetDimensions : : unscaled . vsep_normal , FS_SMALL ) , SetFill ( 1 , 0 ) , SetDataTip ( 0x0 , STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC ) ,
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) , SetPIP ( 0 , WidgetDimensions : : unscaled . hsep_wide , 0 ) ,
NWidget ( WWT_TEXT , COLOUR_GREY , WID_GO_TEXT_MUSIC_VOLUME ) , SetMinimalSize ( 0 , 12 ) , SetDataTip ( STR_GAME_OPTIONS_MUSIC_VOLUME , STR_NULL ) ,
NWidget ( WWT_EMPTY , COLOUR_GREY , WID_GO_BASE_MUSIC_VOLUME ) , SetMinimalSize ( 67 , 0 ) , SetMinimalTextLines ( 1 , 12 + WidgetDimensions : : unscaled . vsep_normal , FS_SMALL ) , SetFill ( 1 , 0 ) , SetDataTip ( 0x0 , STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC ) ,
EndContainer ( ) ,
EndContainer ( ) ,
EndContainer ( ) ,
2009-12-22 21:40:29 +00:00
2023-05-01 12:58:22 +01:00
NWidget ( WWT_FRAME , COLOUR_GREY ) , SetDataTip ( STR_GAME_OPTIONS_BASE_SFX , STR_NULL ) ,
NWidget ( NWID_HORIZONTAL ) , SetPIP ( 0 , 30 , 7 ) ,
2023-04-25 18:01:58 +01:00
NWidget ( WWT_DROPDOWN , COLOUR_GREY , WID_GO_BASE_SFX_DROPDOWN ) , SetMinimalSize ( 100 , 12 ) , SetDataTip ( STR_JUST_RAW_STRING , STR_GAME_OPTIONS_BASE_SFX_TOOLTIP ) ,
2023-05-01 12:58:22 +01:00
NWidget ( NWID_SPACER ) , SetMinimalSize ( 100 , 12 ) , SetFill ( 1 , 0 ) ,
EndContainer ( ) ,
NWidget ( WWT_EMPTY , INVALID_COLOUR , WID_GO_BASE_SFX_DESCRIPTION ) , SetMinimalSize ( 200 , 0 ) , SetMinimalTextLines ( 1 , 0 ) , SetDataTip ( STR_NULL , STR_GAME_OPTIONS_BASE_SFX_DESCRIPTION_TOOLTIP ) , SetFill ( 1 , 0 ) , SetPadding ( 6 , 0 , 6 , 0 ) ,
NWidget ( NWID_HORIZONTAL , NC_EQUALSIZE ) , SetPIP ( 7 , 0 , 7 ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_GO_BASE_SFX_TEXTFILE + TFT_README ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) , SetDataTip ( STR_TEXTFILE_VIEW_README , STR_NULL ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_GO_BASE_SFX_TEXTFILE + TFT_CHANGELOG ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) , SetDataTip ( STR_TEXTFILE_VIEW_CHANGELOG , STR_NULL ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_GO_BASE_SFX_TEXTFILE + TFT_LICENSE ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) , SetDataTip ( STR_TEXTFILE_VIEW_LICENCE , STR_NULL ) ,
EndContainer ( ) ,
EndContainer ( ) ,
NWidget ( WWT_FRAME , COLOUR_GREY ) , SetDataTip ( STR_GAME_OPTIONS_BASE_MUSIC , STR_NULL ) ,
NWidget ( NWID_HORIZONTAL ) , SetPIP ( 0 , 30 , 7 ) ,
2023-04-25 18:01:58 +01:00
NWidget ( WWT_DROPDOWN , COLOUR_GREY , WID_GO_BASE_MUSIC_DROPDOWN ) , SetMinimalSize ( 100 , 12 ) , SetDataTip ( STR_JUST_RAW_STRING , STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP ) ,
2023-05-01 12:58:22 +01:00
NWidget ( WWT_TEXT , COLOUR_GREY , WID_GO_BASE_MUSIC_STATUS ) , SetMinimalSize ( 100 , 12 ) , SetDataTip ( STR_EMPTY , STR_NULL ) , SetFill ( 1 , 0 ) ,
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) , SetPIP ( 0 , 30 , 7 ) ,
NWidget ( WWT_EMPTY , INVALID_COLOUR , WID_GO_BASE_MUSIC_DESCRIPTION ) , SetMinimalSize ( 200 , 0 ) , SetMinimalTextLines ( 1 , 0 ) , SetDataTip ( STR_NULL , STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP ) , SetFill ( 1 , 0 ) , SetPadding ( 6 , 0 , 6 , 0 ) ,
NWidget ( NWID_VERTICAL ) , SetPIP ( 0 , 0 , 0 ) ,
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_GO_BASE_MUSIC_JUKEBOX ) , SetMinimalSize ( 22 , 22 ) , SetDataTip ( SPR_IMG_MUSIC , STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW ) , SetPadding ( 6 , 0 , 6 , 0 ) ,
EndContainer ( ) ,
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL , NC_EQUALSIZE ) , SetPIP ( 7 , 0 , 7 ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_GO_BASE_MUSIC_TEXTFILE + TFT_README ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) , SetDataTip ( STR_TEXTFILE_VIEW_README , STR_NULL ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_GO_BASE_MUSIC_TEXTFILE + TFT_CHANGELOG ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) , SetDataTip ( STR_TEXTFILE_VIEW_CHANGELOG , STR_NULL ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_GO_BASE_MUSIC_TEXTFILE + TFT_LICENSE ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) , SetDataTip ( STR_TEXTFILE_VIEW_LICENCE , STR_NULL ) ,
EndContainer ( ) ,
2022-11-08 18:21:52 +00:00
EndContainer ( ) ,
2012-03-17 15:45:37 +00:00
EndContainer ( ) ,
2009-12-22 21:40:29 +00:00
EndContainer ( ) ,
2009-03-28 11:17:38 +00:00
EndContainer ( ) ,
} ;
2013-05-26 20:23:42 +01:00
static WindowDesc _game_options_desc (
2023-07-13 16:41:06 +01:00
WDP_CENTER , nullptr , 0 , 0 ,
2007-02-01 15:49:12 +00:00
WC_GAME_OPTIONS , WC_NONE ,
2012-11-11 16:10:43 +00:00
0 ,
2023-09-03 21:54:13 +01:00
std : : begin ( _nested_game_options_widgets ) , std : : end ( _nested_game_options_widgets )
2009-03-15 15:12:06 +00:00
) ;
2004-08-09 18:04:08 +01:00
2010-12-11 15:14:28 +00:00
/** Open the game options window. */
2007-03-07 11:47:46 +00:00
void ShowGameOptions ( )
2004-08-09 18:04:08 +01:00
{
2021-05-17 14:46:38 +01:00
CloseWindowByClass ( WC_GAME_OPTIONS ) ;
2008-05-18 13:17:52 +01:00
new GameOptionsWindow ( & _game_options_desc ) ;
2004-08-09 18:04:08 +01:00
}
2009-10-25 21:18:12 +00:00
static int SETTING_HEIGHT = 11 ; ///< Height of a single setting in the tree view in pixels
2009-01-03 10:53:49 +00:00
2009-01-10 16:42:28 +00:00
/**
2009-02-08 12:25:13 +00:00
* Flags for # SettingEntry
* @ note The # SEF_BUTTONS_MASK matches expectations of the formal parameter ' state ' of # DrawArrowButtons
2009-01-10 16:42:28 +00:00
*/
2009-02-08 12:25:13 +00:00
enum SettingEntryFlags {
SEF_LEFT_DEPRESSED = 0x01 , ///< Of a numeric setting entry, the left button is depressed
SEF_RIGHT_DEPRESSED = 0x02 , ///< Of a numeric setting entry, the right button is depressed
SEF_BUTTONS_MASK = ( SEF_LEFT_DEPRESSED | SEF_RIGHT_DEPRESSED ) , ///< Bit-mask for button flags
2009-01-10 16:42:28 +00:00
2009-02-08 12:25:13 +00:00
SEF_LAST_FIELD = 0x04 , ///< This entry is the last one in a (sub-)page
2012-10-27 16:26:17 +01:00
SEF_FILTERED = 0x08 , ///< Entry is hidden by the string filter
2009-01-10 16:39:18 +00:00
} ;
2012-10-29 19:53:13 +00:00
/** How the list of advanced settings is filtered. */
enum RestrictionMode {
2012-11-08 10:04:00 +00:00
RM_BASIC , ///< Display settings associated to the "basic" list.
RM_ADVANCED , ///< Display settings associated to the "advanced" list.
2012-10-29 19:53:13 +00:00
RM_ALL , ///< List all settings regardless of the default/newgame/... values.
RM_CHANGED_AGAINST_DEFAULT , ///< Show only settings which are different compared to default values.
RM_CHANGED_AGAINST_NEW , ///< Show only settings which are different compared to the user's new game setting values.
RM_END , ///< End for iteration.
} ;
2014-02-09 13:05:46 +00:00
DECLARE_POSTFIX_INCREMENT ( RestrictionMode )
2012-10-29 19:53:13 +00:00
2012-12-26 17:44:42 +00:00
/** Filter for settings list. */
struct SettingFilter {
StringFilter string ; ///< Filter string.
2014-02-09 13:05:46 +00:00
RestrictionMode min_cat ; ///< Minimum category needed to display all filtered strings (#RM_BASIC, #RM_ADVANCED, or #RM_ALL).
bool type_hides ; ///< Whether the type hides filtered strings.
2012-12-26 17:44:42 +00:00
RestrictionMode mode ; ///< Filter based on category.
2014-02-09 13:05:46 +00:00
SettingType type ; ///< Filter based on type.
2012-12-26 17:44:42 +00:00
} ;
2009-02-08 12:25:13 +00:00
/** Data structure describing a single setting in a tab */
2014-06-01 13:14:32 +01:00
struct BaseSettingEntry {
2009-02-08 12:25:13 +00:00
byte flags ; ///< Flags of the setting entry. @see SettingEntryFlags
byte level ; ///< Nesting level of this setting entry
2009-01-10 16:29:31 +00:00
2014-06-01 13:14:32 +01:00
BaseSettingEntry ( ) : flags ( 0 ) , level ( 0 ) { }
2023-05-14 22:31:03 +01:00
virtual ~ BaseSettingEntry ( ) = default ;
2009-01-10 16:39:18 +00:00
2014-06-01 13:14:32 +01:00
virtual void Init ( byte level = 0 ) ;
virtual void FoldAll ( ) { }
virtual void UnFoldAll ( ) { }
2021-04-06 11:47:44 +01:00
virtual void ResetAll ( ) = 0 ;
2009-01-10 16:44:51 +00:00
2012-10-27 16:26:17 +01:00
/**
* Set whether this is the last visible entry of the parent node .
* @ param last_field Value to set
*/
void SetLastField ( bool last_field ) { if ( last_field ) SETBITS ( this - > flags , SEF_LAST_FIELD ) ; else CLRBITS ( this - > flags , SEF_LAST_FIELD ) ; }
2014-06-01 13:14:32 +01:00
virtual uint Length ( ) const = 0 ;
2023-09-16 21:20:53 +01:00
virtual void GetFoldingState ( [[maybe_unused]] bool &all_folded, [[maybe_unused]] bool & all_unfolded ) const { }
2014-06-01 13:14:32 +01:00
virtual bool IsVisible ( const BaseSettingEntry * item ) const ;
virtual BaseSettingEntry * FindEntry ( uint row , uint * cur_row ) ;
2023-09-16 21:20:53 +01:00
virtual uint GetMaxHelpHeight ( [[maybe_unused]] int maxw ) { return 0 ; }
2009-01-10 16:51:27 +00:00
2014-06-01 13:14:32 +01:00
/**
* Check whether an entry is hidden due to filters
* @ return true if hidden .
*/
bool IsFiltered ( ) const { return ( this - > flags & SEF_FILTERED ) ! = 0 ; }
virtual bool UpdateFilterState ( SettingFilter & filter , bool force_visible ) = 0 ;
virtual uint Draw ( GameSettings * settings_ptr , int left , int right , int y , uint first_row , uint max_row , BaseSettingEntry * selected , uint cur_row = 0 , uint parent_last = 0 ) const ;
protected :
virtual void DrawSetting ( GameSettings * settings_ptr , int left , int right , int y , bool highlight ) const = 0 ;
} ;
/** Standard setting */
struct SettingEntry : BaseSettingEntry {
2021-05-23 10:37:56 +01:00
const char * name ; ///< Name of the setting
const IntSettingDesc * setting ; ///< Setting description of the setting
2012-10-27 16:26:17 +01:00
2014-06-01 13:14:32 +01:00
SettingEntry ( const char * name ) ;
2023-04-13 07:23:18 +01:00
void Init ( byte level = 0 ) override ;
void ResetAll ( ) override ;
uint Length ( ) const override ;
uint GetMaxHelpHeight ( int maxw ) override ;
bool UpdateFilterState ( SettingFilter & filter , bool force_visible ) override ;
2014-06-01 13:14:32 +01:00
void SetButtons ( byte new_val ) ;
2009-01-10 16:51:27 +00:00
2012-05-12 11:11:41 +01:00
/**
* Get the help text of a single setting .
* @ return The requested help text .
*/
2014-06-01 13:14:32 +01:00
inline StringID GetHelpText ( ) const
2012-05-12 11:11:41 +01:00
{
2021-05-23 08:51:33 +01:00
return this - > setting - > str_help ;
2012-05-12 11:11:41 +01:00
}
2023-05-08 18:01:06 +01:00
void SetValueDParams ( uint first_param , int32_t value ) const ;
2014-06-01 13:14:32 +01:00
protected :
2023-04-13 07:23:18 +01:00
void DrawSetting ( GameSettings * settings_ptr , int left , int right , int y , bool highlight ) const override ;
2012-05-28 14:32:38 +01:00
2009-01-10 16:51:27 +00:00
private :
2012-10-29 19:53:13 +00:00
bool IsVisibleByRestrictionMode ( RestrictionMode mode ) const ;
2009-01-03 11:24:27 +00:00
} ;
2014-06-01 13:14:32 +01:00
/** Containers for BaseSettingEntry */
struct SettingsContainer {
typedef std : : vector < BaseSettingEntry * > EntryVector ;
2014-06-01 12:51:24 +01:00
EntryVector entries ; ///< Settings on this page
template < typename T >
T * Add ( T * item )
{
this - > entries . push_back ( item ) ;
return item ;
}
2009-01-10 16:39:18 +00:00
void Init ( byte level = 0 ) ;
2021-04-06 11:47:44 +01:00
void ResetAll ( ) ;
2009-01-10 17:27:11 +00:00
void FoldAll ( ) ;
2012-10-27 16:25:57 +01:00
void UnFoldAll ( ) ;
2009-01-10 16:44:51 +00:00
uint Length ( ) const ;
2012-10-27 16:25:57 +01:00
void GetFoldingState ( bool & all_folded , bool & all_unfolded ) const ;
2014-06-01 13:14:32 +01:00
bool IsVisible ( const BaseSettingEntry * item ) const ;
BaseSettingEntry * FindEntry ( uint row , uint * cur_row ) ;
2012-05-12 11:11:41 +01:00
uint GetMaxHelpHeight ( int maxw ) ;
2009-01-10 17:13:41 +00:00
2012-12-26 17:44:42 +00:00
bool UpdateFilterState ( SettingFilter & filter , bool force_visible ) ;
2012-10-27 16:26:17 +01:00
2014-06-01 13:14:32 +01:00
uint Draw ( GameSettings * settings_ptr , int left , int right , int y , uint first_row , uint max_row , BaseSettingEntry * selected , uint cur_row = 0 , uint parent_last = 0 ) const ;
2009-01-03 11:24:27 +00:00
} ;
2014-06-01 13:14:32 +01:00
/** Data structure describing one page of settings in the settings window. */
struct SettingsPage : BaseSettingEntry , SettingsContainer {
StringID title ; ///< Title of the sub-page
bool folded ; ///< Sub-page is folded (not visible except for its title)
2009-01-03 11:24:27 +00:00
2014-06-01 13:14:32 +01:00
SettingsPage ( StringID title ) ;
2023-04-13 07:23:18 +01:00
void Init ( byte level = 0 ) override ;
void ResetAll ( ) override ;
void FoldAll ( ) override ;
void UnFoldAll ( ) override ;
2014-06-01 13:14:32 +01:00
2023-04-13 07:23:18 +01:00
uint Length ( ) const override ;
void GetFoldingState ( bool & all_folded , bool & all_unfolded ) const override ;
bool IsVisible ( const BaseSettingEntry * item ) const override ;
BaseSettingEntry * FindEntry ( uint row , uint * cur_row ) override ;
uint GetMaxHelpHeight ( int maxw ) override { return SettingsContainer : : GetMaxHelpHeight ( maxw ) ; }
2014-06-01 13:14:32 +01:00
2023-04-13 07:23:18 +01:00
bool UpdateFilterState ( SettingFilter & filter , bool force_visible ) override ;
2014-06-01 13:14:32 +01:00
2023-04-13 07:23:18 +01:00
uint Draw ( GameSettings * settings_ptr , int left , int right , int y , uint first_row , uint max_row , BaseSettingEntry * selected , uint cur_row = 0 , uint parent_last = 0 ) const override ;
2014-06-01 13:14:32 +01:00
protected :
2023-04-13 07:23:18 +01:00
void DrawSetting ( GameSettings * settings_ptr , int left , int right , int y , bool highlight ) const override ;
2014-06-01 13:14:32 +01:00
} ;
/* == BaseSettingEntry methods == */
2009-01-10 16:29:31 +00:00
/**
2014-06-01 13:14:32 +01:00
* Initialization of a setting entry
* @ param level Page nesting level of this entry
2009-01-10 16:29:31 +00:00
*/
2014-06-01 13:14:32 +01:00
void BaseSettingEntry : : Init ( byte level )
2009-01-10 16:29:31 +00:00
{
2014-06-01 13:14:32 +01:00
this - > level = level ;
2009-01-10 16:39:18 +00:00
}
/**
2014-06-01 13:14:32 +01:00
* Check whether an entry is visible and not folded or filtered away .
* Note : This does not consider the scrolling range ; it might still require scrolling to make the setting really visible .
* @ param item Entry to search for .
* @ return true if entry is visible .
2009-01-10 16:39:18 +00:00
*/
2014-06-01 13:14:32 +01:00
bool BaseSettingEntry : : IsVisible ( const BaseSettingEntry * item ) const
2009-01-10 16:39:18 +00:00
{
2014-06-01 13:14:32 +01:00
if ( this - > IsFiltered ( ) ) return false ;
2021-06-16 22:21:21 +01:00
return this = = item ;
2009-01-10 16:39:18 +00:00
}
/**
2014-06-01 13:14:32 +01:00
* Find setting entry at row \ a row_num
* @ param row_num Index of entry to return
* @ param cur_row Current row number
2019-04-10 22:07:06 +01:00
* @ return The requested setting entry or \ c nullptr if it not found ( folded or filtered )
2009-01-10 16:39:18 +00:00
*/
2014-06-01 13:14:32 +01:00
BaseSettingEntry * BaseSettingEntry : : FindEntry ( uint row_num , uint * cur_row )
2009-01-10 16:39:18 +00:00
{
2019-04-10 22:07:06 +01:00
if ( this - > IsFiltered ( ) ) return nullptr ;
2014-06-01 13:14:32 +01:00
if ( row_num = = * cur_row ) return this ;
( * cur_row ) + + ;
2019-04-10 22:07:06 +01:00
return nullptr ;
2009-01-10 16:39:18 +00:00
}
2014-06-01 13:14:32 +01:00
/**
* Draw a row in the settings panel .
*
* The scrollbar uses rows of the page , while the page data structure is a tree of # SettingsPage and # SettingEntry objects .
* As a result , the drawing routing traverses the tree from top to bottom , counting rows in \ a cur_row until it reaches \ a first_row .
* Then it enables drawing rows while traversing until \ a max_row is reached , at which point drawing is terminated .
*
* The \ a parent_last parameter ensures that the vertical lines at the left are
* only drawn when another entry follows , that it prevents output like
* \ verbatim
* | - - setting
* | - - ( - ) - Title
* | | - - setting
* | | - - setting
* \ endverbatim
* The left - most vertical line is not wanted . It is prevented by setting the
* appropriate bit in the \ a parent_last parameter .
*
* @ param settings_ptr Pointer to current values of all settings
* @ param left Left - most position in window / panel to start drawing \ a first_row
* @ param right Right - most x position to draw strings at .
* @ param y Upper - most position in window / panel to start drawing \ a first_row
* @ param first_row First row number to draw
* @ param max_row Row - number to stop drawing ( the row - number of the row below the last row to draw )
* @ param selected Selected entry by the user .
* @ param cur_row Current row number ( internal variable )
* @ param parent_last Last - field booleans of parent page level ( page level \ e i sets bit \ e i to 1 if it is its last field )
* @ return Row number of the next row to draw
*/
uint BaseSettingEntry : : Draw ( GameSettings * settings_ptr , int left , int right , int y , uint first_row , uint max_row , BaseSettingEntry * selected , uint cur_row , uint parent_last ) const
2009-01-10 17:27:11 +00:00
{
2014-06-01 13:14:32 +01:00
if ( this - > IsFiltered ( ) ) return cur_row ;
if ( cur_row > = max_row ) return cur_row ;
2009-01-10 17:27:11 +00:00
2014-06-01 13:14:32 +01:00
bool rtl = _current_text_dir = = TD_RTL ;
2023-06-25 19:32:53 +01:00
int offset = ( rtl ? - ( int ) _circle_size . width : ( int ) _circle_size . width ) / 2 ;
2022-09-23 09:36:22 +01:00
int level_width = rtl ? - WidgetDimensions : : scaled . hsep_indent : WidgetDimensions : : scaled . hsep_indent ;
2009-01-10 17:27:11 +00:00
2014-06-01 13:14:32 +01:00
int x = rtl ? right : left ;
if ( cur_row > = first_row ) {
int colour = _colour_gradient [ COLOUR_ORANGE ] [ 4 ] ;
y + = ( cur_row - first_row ) * SETTING_HEIGHT ; // Compute correct y start position
2012-10-27 16:25:57 +01:00
2014-06-01 13:14:32 +01:00
/* Draw vertical for parent nesting levels */
for ( uint lvl = 0 ; lvl < this - > level ; lvl + + ) {
if ( ! HasBit ( parent_last , lvl ) ) GfxDrawLine ( x + offset , y , x + offset , y + SETTING_HEIGHT - 1 , colour ) ;
x + = level_width ;
}
/* draw own |- prefix */
int halfway_y = y + SETTING_HEIGHT / 2 ;
int bottom_y = ( flags & SEF_LAST_FIELD ) ? halfway_y : y + SETTING_HEIGHT - 1 ;
GfxDrawLine ( x + offset , y , x + offset , bottom_y , colour ) ;
/* Small horizontal line from the last vertical line */
2023-06-25 19:32:53 +01:00
GfxDrawLine ( x + offset , halfway_y , x + level_width - ( rtl ? - WidgetDimensions : : scaled . hsep_normal : WidgetDimensions : : scaled . hsep_normal ) , halfway_y , colour ) ;
2014-06-01 13:14:32 +01:00
x + = level_width ;
2012-10-27 16:25:57 +01:00
2014-06-01 13:14:32 +01:00
this - > DrawSetting ( settings_ptr , rtl ? left : x , rtl ? x : right , y , this = = selected ) ;
2012-10-27 16:25:57 +01:00
}
2014-06-01 13:14:32 +01:00
cur_row + + ;
return cur_row ;
2012-10-27 16:25:57 +01:00
}
2014-06-01 13:14:32 +01:00
/* == SettingEntry methods == */
2012-10-27 16:25:57 +01:00
/**
2014-06-01 13:14:32 +01:00
* Constructor for a single setting in the ' advanced settings ' window
* @ param name Name of the setting in the setting table
2012-10-27 16:25:57 +01:00
*/
2014-06-01 13:14:32 +01:00
SettingEntry : : SettingEntry ( const char * name )
2012-10-27 16:25:57 +01:00
{
2014-06-01 13:14:32 +01:00
this - > name = name ;
2019-04-10 22:07:06 +01:00
this - > setting = nullptr ;
2012-10-27 16:25:57 +01:00
}
/**
2014-06-01 13:14:32 +01:00
* Initialization of a setting entry
* @ param level Page nesting level of this entry
2012-10-27 16:25:57 +01:00
*/
2014-06-01 13:14:32 +01:00
void SettingEntry : : Init ( byte level )
2012-10-27 16:25:57 +01:00
{
2014-06-01 13:14:32 +01:00
BaseSettingEntry : : Init ( level ) ;
2021-05-23 10:37:56 +01:00
this - > setting = GetSettingFromName ( this - > name ) - > AsIntSetting ( ) ;
2012-10-27 16:25:57 +01:00
}
2009-01-10 17:27:11 +00:00
2021-04-06 11:47:44 +01:00
/* Sets the given setting entry to its default value */
void SettingEntry : : ResetAll ( )
{
2021-05-22 20:09:30 +01:00
SetSettingValue ( this - > setting , this - > setting - > def ) ;
2021-04-06 11:47:44 +01:00
}
2009-01-10 16:42:28 +00:00
/**
2009-02-08 12:25:13 +00:00
* Set the button - depressed flags ( # SEF_LEFT_DEPRESSED and # SEF_RIGHT_DEPRESSED ) to a specified value
2009-01-10 16:42:28 +00:00
* @ param new_val New value for the button flags
2009-02-08 12:25:13 +00:00
* @ see SettingEntryFlags
2009-01-10 16:42:28 +00:00
*/
2009-02-08 12:25:13 +00:00
void SettingEntry : : SetButtons ( byte new_val )
2009-01-10 16:42:28 +00:00
{
2009-02-08 12:25:13 +00:00
assert ( ( new_val & ~ SEF_BUTTONS_MASK ) = = 0 ) ; // Should not touch any flags outside the buttons
this - > flags = ( this - > flags & ~ SEF_BUTTONS_MASK ) | new_val ;
2009-01-10 16:42:28 +00:00
}
2014-06-01 13:14:32 +01:00
/** Return number of rows needed to display the (filtered) entry */
2009-02-08 12:25:13 +00:00
uint SettingEntry : : Length ( ) const
2009-01-10 16:44:51 +00:00
{
2014-06-01 13:14:32 +01:00
return this - > IsFiltered ( ) ? 0 : 1 ;
2009-01-10 16:49:30 +00:00
}
2012-05-12 11:11:41 +01:00
/**
* Get the biggest height of the help text ( s ) , if the width is at least \ a maxw . Help text gets wrapped if needed .
* @ param maxw Maximal width of a line help text .
* @ return Biggest height needed to display any help text of this node ( and its descendants ) .
*/
uint SettingEntry : : GetMaxHelpHeight ( int maxw )
{
2014-06-01 13:14:32 +01:00
return GetStringHeight ( this - > GetHelpText ( ) , maxw ) ;
2012-10-27 16:26:17 +01:00
}
2012-10-29 19:53:13 +00:00
/**
* Checks whether an entry shall be made visible based on the restriction mode .
* @ param mode The current status of the restriction drop down box .
* @ return true if the entry shall be visible .
*/
bool SettingEntry : : IsVisibleByRestrictionMode ( RestrictionMode mode ) const
{
/* There shall not be any restriction, i.e. all settings shall be visible. */
if ( mode = = RM_ALL ) return true ;
2021-05-23 10:37:56 +01:00
const IntSettingDesc * sd = this - > setting ;
2012-10-29 19:53:13 +00:00
2021-05-23 08:51:33 +01:00
if ( mode = = RM_BASIC ) return ( this - > setting - > cat & SC_BASIC_LIST ) ! = 0 ;
if ( mode = = RM_ADVANCED ) return ( this - > setting - > cat & SC_ADVANCED_LIST ) ! = 0 ;
2012-11-08 10:04:00 +00:00
2012-10-29 19:53:13 +00:00
/* Read the current value. */
2021-05-24 09:42:02 +01:00
const void * object = ResolveObject ( & GetGameSettings ( ) , sd ) ;
2023-05-08 18:01:06 +01:00
int64_t current_value = sd - > Read ( object ) ;
int64_t filter_value ;
2012-10-29 19:53:13 +00:00
2012-12-26 17:48:25 +00:00
if ( mode = = RM_CHANGED_AGAINST_DEFAULT ) {
2012-10-29 19:53:13 +00:00
/* This entry shall only be visible, if the value deviates from its default value. */
/* Read the default value. */
2021-05-22 20:09:30 +01:00
filter_value = sd - > def ;
2012-10-29 19:53:13 +00:00
} else {
assert ( mode = = RM_CHANGED_AGAINST_NEW ) ;
/* This entry shall only be visible, if the value deviates from
* its value is used when starting a new game . */
/* Make sure we're not comparing the new game settings against itself. */
2021-05-24 09:42:02 +01:00
assert ( & GetGameSettings ( ) ! = & _settings_newgame ) ;
2012-10-29 19:53:13 +00:00
/* Read the new game's value. */
2021-05-24 09:42:02 +01:00
filter_value = sd - > Read ( ResolveObject ( & _settings_newgame , sd ) ) ;
2012-10-29 19:53:13 +00:00
}
return current_value ! = filter_value ;
}
2012-10-27 16:26:17 +01:00
/**
* Update the filter state .
2012-12-26 17:44:42 +00:00
* @ param filter Filter
2012-10-29 19:53:13 +00:00
* @ param force_visible Whether to force all items visible , no matter what ( due to filter text ; not affected by restriction drop down box ) .
2012-10-27 16:26:17 +01:00
* @ return true if item remains visible
*/
2012-12-26 17:44:42 +00:00
bool SettingEntry : : UpdateFilterState ( SettingFilter & filter , bool force_visible )
2012-10-27 16:26:17 +01:00
{
CLRBITS ( this - > flags , SEF_FILTERED ) ;
bool visible = true ;
2021-05-23 10:37:56 +01:00
const IntSettingDesc * sd = this - > setting ;
2014-06-01 13:14:32 +01:00
if ( ! force_visible & & ! filter . string . IsEmpty ( ) ) {
/* Process the search text filter for this item. */
filter . string . ResetState ( ) ;
2012-10-27 16:26:17 +01:00
2014-06-01 13:14:32 +01:00
SetDParam ( 0 , STR_EMPTY ) ;
2021-05-23 09:29:38 +01:00
filter . string . AddLine ( sd - > str ) ;
2014-06-01 13:14:32 +01:00
filter . string . AddLine ( this - > GetHelpText ( ) ) ;
visible = filter . string . GetState ( ) ;
}
if ( visible ) {
if ( filter . type ! = ST_ALL & & sd - > GetType ( ) ! = filter . type ) {
filter . type_hides = true ;
visible = false ;
2012-10-27 16:26:17 +01:00
}
2014-06-01 13:14:32 +01:00
if ( ! this - > IsVisibleByRestrictionMode ( filter . mode ) ) {
while ( filter . min_cat < RM_ALL & & ( filter . min_cat = = filter . mode | | ! this - > IsVisibleByRestrictionMode ( filter . min_cat ) ) ) filter . min_cat + + ;
visible = false ;
2012-10-27 16:26:17 +01:00
}
}
if ( ! visible ) SETBITS ( this - > flags , SEF_FILTERED ) ;
return visible ;
}
2021-05-24 09:42:02 +01:00
static const void * ResolveObject ( const GameSettings * settings_ptr , const IntSettingDesc * sd )
2009-05-26 12:40:14 +01:00
{
2021-06-03 20:18:29 +01:00
if ( ( sd - > flags & SF_PER_COMPANY ) ! = 0 ) {
2009-05-26 12:40:14 +01:00
if ( Company : : IsValidID ( _local_company ) & & _game_mode ! = GM_MENU ) {
2021-05-24 09:42:02 +01:00
return & Company : : Get ( _local_company ) - > settings ;
2009-05-26 12:40:14 +01:00
}
2021-05-24 09:42:02 +01:00
return & _settings_client . company ;
2009-05-26 12:40:14 +01:00
}
2021-05-24 09:42:02 +01:00
return settings_ptr ;
2009-05-26 12:40:14 +01:00
}
2012-05-28 14:32:38 +01:00
/**
* Set the DParams for drawing the value of a setting .
* @ param first_param First DParam to use
* @ param value Setting value to set params for .
*/
2023-05-08 18:01:06 +01:00
void SettingEntry : : SetValueDParams ( uint first_param , int32_t value ) const
2012-05-28 14:32:38 +01:00
{
2021-05-23 18:27:46 +01:00
if ( this - > setting - > IsBoolSetting ( ) ) {
2012-05-28 14:32:38 +01:00
SetDParam ( first_param + + , value ! = 0 ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF ) ;
} else {
2021-06-03 20:18:29 +01:00
if ( ( this - > setting - > flags & SF_GUI_DROPDOWN ) ! = 0 ) {
2021-05-23 09:29:38 +01:00
SetDParam ( first_param + + , this - > setting - > str_val - this - > setting - > min + value ) ;
2021-06-03 20:18:29 +01:00
} else if ( ( this - > setting - > flags & SF_GUI_NEGATIVE_IS_SPECIAL ) ! = 0 ) {
2021-05-23 09:29:38 +01:00
SetDParam ( first_param + + , this - > setting - > str_val + ( ( value > = 0 ) ? 1 : 0 ) ) ;
2012-05-28 14:32:38 +01:00
value = abs ( value ) ;
} else {
2021-06-03 20:18:29 +01:00
SetDParam ( first_param + + , this - > setting - > str_val + ( ( value = = 0 & & ( this - > setting - > flags & SF_GUI_0_IS_SPECIAL ) ! = 0 ) ? 1 : 0 ) ) ;
2012-05-28 14:32:38 +01:00
}
SetDParam ( first_param + + , value ) ;
}
}
2009-01-10 16:51:27 +00:00
/**
2014-06-01 13:14:32 +01:00
* Function to draw setting value ( button + text + current value )
2009-02-08 12:25:13 +00:00
* @ param settings_ptr Pointer to current values of all settings
2009-11-20 14:52:55 +00:00
* @ param left Left - most position in window / panel to start drawing
* @ param right Right - most position in window / panel to draw
2009-02-08 12:25:13 +00:00
* @ param y Upper - most position in window / panel to start drawing
2012-05-12 11:17:20 +01:00
* @ param highlight Highlight entry .
2009-01-10 16:51:27 +00:00
*/
2014-06-01 13:14:32 +01:00
void SettingEntry : : DrawSetting ( GameSettings * settings_ptr , int left , int right , int y , bool highlight ) const
2009-01-10 16:51:27 +00:00
{
2021-05-23 10:37:56 +01:00
const IntSettingDesc * sd = this - > setting ;
2014-06-01 13:14:32 +01:00
int state = this - > flags & SEF_BUTTONS_MASK ;
2009-01-10 16:51:27 +00:00
2010-11-13 09:56:25 +00:00
bool rtl = _current_text_dir = = TD_RTL ;
2012-06-01 15:41:09 +01:00
uint buttons_left = rtl ? right + 1 - SETTING_BUTTON_WIDTH : left ;
2022-09-23 09:36:22 +01:00
uint text_left = left + ( rtl ? 0 : SETTING_BUTTON_WIDTH + WidgetDimensions : : scaled . hsep_wide ) ;
uint text_right = right - ( rtl ? SETTING_BUTTON_WIDTH + WidgetDimensions : : scaled . hsep_wide : 0 ) ;
2012-06-01 15:41:09 +01:00
uint button_y = y + ( SETTING_HEIGHT - SETTING_BUTTON_HEIGHT ) / 2 ;
2009-11-20 14:52:55 +00:00
2009-01-10 16:51:27 +00:00
/* We do not allow changes of some items when we are a client in a networkgame */
2012-12-05 19:35:09 +00:00
bool editable = sd - > IsEditable ( ) ;
2009-01-10 16:51:27 +00:00
2023-04-28 00:24:04 +01:00
SetDParam ( 0 , STR_CONFIG_SETTING_VALUE ) ;
2023-05-08 18:01:06 +01:00
int32_t value = sd - > Read ( ResolveObject ( settings_ptr , sd ) ) ;
2021-05-23 18:27:46 +01:00
if ( sd - > IsBoolSetting ( ) ) {
2009-01-10 16:51:27 +00:00
/* Draw checkbox for boolean-value either on/off */
2012-05-28 14:32:38 +01:00
DrawBoolButton ( buttons_left , button_y , value ! = 0 , editable ) ;
2021-06-03 20:18:29 +01:00
} else if ( ( sd - > flags & SF_GUI_DROPDOWN ) ! = 0 ) {
2012-06-01 16:19:38 +01:00
/* Draw [v] button for settings of an enum-type */
DrawDropDownButton ( buttons_left , button_y , COLOUR_YELLOW , state ! = 0 , editable ) ;
2009-01-10 16:51:27 +00:00
} else {
/* Draw [<][>] boxes for settings of an integer-type */
2012-05-06 15:59:26 +01:00
DrawArrowButtons ( buttons_left , button_y , COLOUR_YELLOW , state ,
2023-05-08 18:01:06 +01:00
editable & & value ! = ( sd - > flags & SF_GUI_0_IS_SPECIAL ? 0 : sd - > min ) , editable & & ( uint32_t ) value ! = sd - > max ) ;
2009-01-10 16:51:27 +00:00
}
2012-05-28 14:32:38 +01:00
this - > SetValueDParams ( 1 , value ) ;
2021-05-23 09:29:38 +01:00
DrawString ( text_left , text_right , y + ( SETTING_HEIGHT - FONT_HEIGHT_NORMAL ) / 2 , sd - > str , highlight ? TC_WHITE : TC_LIGHT_BLUE ) ;
2009-01-10 16:51:27 +00:00
}
2014-06-01 13:14:32 +01:00
/* == SettingsContainer methods == */
2009-01-10 16:39:18 +00:00
/**
* Initialization of an entire setting page
* @ param level Nesting level of this page ( internal variable , do not provide a value for it when calling )
*/
2014-06-01 13:14:32 +01:00
void SettingsContainer : : Init ( byte level )
2009-01-10 16:39:18 +00:00
{
2023-05-07 12:09:54 +01:00
for ( auto & it : this - > entries ) {
it - > Init ( level ) ;
2009-01-10 16:39:18 +00:00
}
2009-01-10 16:29:31 +00:00
}
2021-04-06 11:47:44 +01:00
/** Resets all settings to their default values */
void SettingsContainer : : ResetAll ( )
{
for ( auto settings_entry : this - > entries ) {
settings_entry - > ResetAll ( ) ;
}
}
2009-01-10 17:27:11 +00:00
/** Recursively close all folds of sub-pages */
2014-06-01 13:14:32 +01:00
void SettingsContainer : : FoldAll ( )
2009-01-10 17:27:11 +00:00
{
2023-05-07 12:09:54 +01:00
for ( auto & it : this - > entries ) {
it - > FoldAll ( ) ;
2009-01-10 17:27:11 +00:00
}
}
2012-10-27 16:25:57 +01:00
/** Recursively open all folds of sub-pages */
2014-06-01 13:14:32 +01:00
void SettingsContainer : : UnFoldAll ( )
2012-10-27 16:25:57 +01:00
{
2023-05-07 12:09:54 +01:00
for ( auto & it : this - > entries ) {
it - > UnFoldAll ( ) ;
2012-10-27 16:25:57 +01:00
}
}
/**
* Recursively accumulate the folding state of the tree .
* @ param [ in , out ] all_folded Set to false , if one entry is not folded .
* @ param [ in , out ] all_unfolded Set to false , if one entry is folded .
*/
2014-06-01 13:14:32 +01:00
void SettingsContainer : : GetFoldingState ( bool & all_folded , bool & all_unfolded ) const
2012-10-27 16:25:57 +01:00
{
2023-05-07 12:09:54 +01:00
for ( auto & it : this - > entries ) {
it - > GetFoldingState ( all_folded , all_unfolded ) ;
2012-10-27 16:25:57 +01:00
}
}
/**
2012-10-27 16:26:17 +01:00
* Update the filter state .
2012-12-26 17:44:42 +00:00
* @ param filter Filter
2012-10-27 16:26:17 +01:00
* @ param force_visible Whether to force all items visible , no matter what
* @ return true if item remains visible
*/
2014-06-01 13:14:32 +01:00
bool SettingsContainer : : UpdateFilterState ( SettingFilter & filter , bool force_visible )
2012-10-27 16:26:17 +01:00
{
2012-10-29 19:53:13 +00:00
bool visible = false ;
2012-10-27 16:26:17 +01:00
bool first_visible = true ;
2014-06-01 12:51:24 +01:00
for ( EntryVector : : reverse_iterator it = this - > entries . rbegin ( ) ; it ! = this - > entries . rend ( ) ; + + it ) {
visible | = ( * it ) - > UpdateFilterState ( filter , force_visible ) ;
( * it ) - > SetLastField ( first_visible ) ;
2012-10-27 16:26:17 +01:00
if ( visible & & first_visible ) first_visible = false ;
}
return visible ;
}
/**
* Check whether an entry is visible and not folded or filtered away .
2014-06-01 13:14:32 +01:00
* Note : This does not consider the scrolling range ; it might still require scrolling to make the setting really visible .
2012-10-27 16:25:57 +01:00
* @ param item Entry to search for .
* @ return true if entry is visible .
*/
2014-06-01 13:14:32 +01:00
bool SettingsContainer : : IsVisible ( const BaseSettingEntry * item ) const
2012-10-27 16:25:57 +01:00
{
2023-05-07 12:09:54 +01:00
for ( const auto & it : this - > entries ) {
if ( it - > IsVisible ( item ) ) return true ;
2012-10-27 16:25:57 +01:00
}
return false ;
}
2009-01-10 16:44:51 +00:00
/** Return number of rows needed to display the whole page */
2014-06-01 13:14:32 +01:00
uint SettingsContainer : : Length ( ) const
2009-01-10 16:44:51 +00:00
{
uint length = 0 ;
2023-05-07 12:09:54 +01:00
for ( const auto & it : this - > entries ) {
length + = it - > Length ( ) ;
2009-01-10 16:44:51 +00:00
}
return length ;
}
2009-01-10 16:49:30 +00:00
/**
2009-02-08 12:25:13 +00:00
* Find the setting entry at row number \ a row_num
2009-01-10 16:49:30 +00:00
* @ param row_num Index of entry to return
* @ param cur_row Variable used for keeping track of the current row number . Should point to memory initialized to \ c 0 when first called .
2019-04-10 22:07:06 +01:00
* @ return The requested setting entry or \ c nullptr if it does not exist
2009-01-10 16:49:30 +00:00
*/
2014-06-01 13:14:32 +01:00
BaseSettingEntry * SettingsContainer : : FindEntry ( uint row_num , uint * cur_row )
2009-01-10 16:49:30 +00:00
{
2019-04-10 22:07:06 +01:00
BaseSettingEntry * pe = nullptr ;
2023-05-07 12:09:54 +01:00
for ( const auto & it : this - > entries ) {
pe = it - > FindEntry ( row_num , cur_row ) ;
2019-04-10 22:07:06 +01:00
if ( pe ! = nullptr ) {
2009-01-10 16:49:30 +00:00
break ;
}
}
return pe ;
}
2012-05-12 11:11:41 +01:00
/**
* Get the biggest height of the help texts , if the width is at least \ a maxw . Help text gets wrapped if needed .
* @ param maxw Maximal width of a line help text .
* @ return Biggest height needed to display any help text of this ( sub - ) tree .
*/
2014-06-01 13:14:32 +01:00
uint SettingsContainer : : GetMaxHelpHeight ( int maxw )
2012-05-12 11:11:41 +01:00
{
uint biggest = 0 ;
2023-05-07 12:09:54 +01:00
for ( const auto & it : this - > entries ) {
biggest = std : : max ( biggest , it - > GetMaxHelpHeight ( maxw ) ) ;
2012-05-12 11:11:41 +01:00
}
return biggest ;
}
2014-06-01 13:14:32 +01:00
2009-01-10 17:13:41 +00:00
/**
2014-06-01 13:14:32 +01:00
* Draw a row in the settings panel .
2009-01-10 17:13:41 +00:00
*
2009-02-08 12:25:13 +00:00
* @ param settings_ptr Pointer to current values of all settings
2014-06-01 13:14:32 +01:00
* @ param left Left - most position in window / panel to start drawing \ a first_row
* @ param right Right - most x position to draw strings at .
* @ param y Upper - most position in window / panel to start drawing \ a first_row
* @ param first_row First row number to draw
2009-02-08 12:25:13 +00:00
* @ param max_row Row - number to stop drawing ( the row - number of the row below the last row to draw )
2014-06-01 13:14:32 +01:00
* @ param selected Selected entry by the user .
2009-02-08 12:25:13 +00:00
* @ param cur_row Current row number ( internal variable )
* @ param parent_last Last - field booleans of parent page level ( page level \ e i sets bit \ e i to 1 if it is its last field )
2009-01-10 17:13:41 +00:00
* @ return Row number of the next row to draw
*/
2014-06-01 13:14:32 +01:00
uint SettingsContainer : : Draw ( GameSettings * settings_ptr , int left , int right , int y , uint first_row , uint max_row , BaseSettingEntry * selected , uint cur_row , uint parent_last ) const
2009-01-10 17:13:41 +00:00
{
2023-05-07 12:09:54 +01:00
for ( const auto & it : this - > entries ) {
cur_row = it - > Draw ( settings_ptr , left , right , y , first_row , max_row , selected , cur_row , parent_last ) ;
if ( cur_row > = max_row ) break ;
2009-01-10 17:13:41 +00:00
}
return cur_row ;
}
2014-06-01 13:14:32 +01:00
/* == SettingsPage methods == */
/**
* Constructor for a sub - page in the ' advanced settings ' window
* @ param title Title of the sub - page
*/
SettingsPage : : SettingsPage ( StringID title )
{
this - > title = title ;
this - > folded = true ;
}
/**
* Initialization of an entire setting page
* @ param level Nesting level of this page ( internal variable , do not provide a value for it when calling )
*/
void SettingsPage : : Init ( byte level )
{
BaseSettingEntry : : Init ( level ) ;
SettingsContainer : : Init ( level + 1 ) ;
}
2021-04-06 11:47:44 +01:00
/** Resets all settings to their default values */
void SettingsPage : : ResetAll ( )
{
for ( auto settings_entry : this - > entries ) {
settings_entry - > ResetAll ( ) ;
}
}
2014-06-01 13:14:32 +01:00
/** Recursively close all (filtered) folds of sub-pages */
void SettingsPage : : FoldAll ( )
{
if ( this - > IsFiltered ( ) ) return ;
this - > folded = true ;
SettingsContainer : : FoldAll ( ) ;
}
/** Recursively open all (filtered) folds of sub-pages */
void SettingsPage : : UnFoldAll ( )
{
if ( this - > IsFiltered ( ) ) return ;
this - > folded = false ;
SettingsContainer : : UnFoldAll ( ) ;
}
/**
* Recursively accumulate the folding state of the ( filtered ) tree .
* @ param [ in , out ] all_folded Set to false , if one entry is not folded .
* @ param [ in , out ] all_unfolded Set to false , if one entry is folded .
*/
void SettingsPage : : GetFoldingState ( bool & all_folded , bool & all_unfolded ) const
{
if ( this - > IsFiltered ( ) ) return ;
if ( this - > folded ) {
all_unfolded = false ;
} else {
all_folded = false ;
}
SettingsContainer : : GetFoldingState ( all_folded , all_unfolded ) ;
}
/**
* Update the filter state .
* @ param filter Filter
* @ param force_visible Whether to force all items visible , no matter what ( due to filter text ; not affected by restriction drop down box ) .
* @ return true if item remains visible
*/
bool SettingsPage : : UpdateFilterState ( SettingFilter & filter , bool force_visible )
{
if ( ! force_visible & & ! filter . string . IsEmpty ( ) ) {
filter . string . ResetState ( ) ;
filter . string . AddLine ( this - > title ) ;
force_visible = filter . string . GetState ( ) ;
}
bool visible = SettingsContainer : : UpdateFilterState ( filter , force_visible ) ;
if ( visible ) {
CLRBITS ( this - > flags , SEF_FILTERED ) ;
} else {
SETBITS ( this - > flags , SEF_FILTERED ) ;
}
return visible ;
}
/**
* Check whether an entry is visible and not folded or filtered away .
* Note : This does not consider the scrolling range ; it might still require scrolling to make the setting really visible .
* @ param item Entry to search for .
* @ return true if entry is visible .
*/
bool SettingsPage : : IsVisible ( const BaseSettingEntry * item ) const
{
if ( this - > IsFiltered ( ) ) return false ;
if ( this = = item ) return true ;
if ( this - > folded ) return false ;
return SettingsContainer : : IsVisible ( item ) ;
}
/** Return number of rows needed to display the (filtered) entry */
uint SettingsPage : : Length ( ) const
{
if ( this - > IsFiltered ( ) ) return 0 ;
if ( this - > folded ) return 1 ; // Only displaying the title
return 1 + SettingsContainer : : Length ( ) ;
}
/**
* Find setting entry at row \ a row_num
* @ param row_num Index of entry to return
* @ param cur_row Current row number
2019-04-10 22:07:06 +01:00
* @ return The requested setting entry or \ c nullptr if it not found ( folded or filtered )
2014-06-01 13:14:32 +01:00
*/
BaseSettingEntry * SettingsPage : : FindEntry ( uint row_num , uint * cur_row )
{
2019-04-10 22:07:06 +01:00
if ( this - > IsFiltered ( ) ) return nullptr ;
2014-06-01 13:14:32 +01:00
if ( row_num = = * cur_row ) return this ;
( * cur_row ) + + ;
2019-04-10 22:07:06 +01:00
if ( this - > folded ) return nullptr ;
2014-06-01 13:14:32 +01:00
return SettingsContainer : : FindEntry ( row_num , cur_row ) ;
}
/**
* Draw a row in the settings panel .
*
* @ param settings_ptr Pointer to current values of all settings
* @ param left Left - most position in window / panel to start drawing \ a first_row
* @ param right Right - most x position to draw strings at .
* @ param y Upper - most position in window / panel to start drawing \ a first_row
* @ param first_row First row number to draw
* @ param max_row Row - number to stop drawing ( the row - number of the row below the last row to draw )
* @ param selected Selected entry by the user .
* @ param cur_row Current row number ( internal variable )
* @ param parent_last Last - field booleans of parent page level ( page level \ e i sets bit \ e i to 1 if it is its last field )
* @ return Row number of the next row to draw
*/
uint SettingsPage : : Draw ( GameSettings * settings_ptr , int left , int right , int y , uint first_row , uint max_row , BaseSettingEntry * selected , uint cur_row , uint parent_last ) const
{
if ( this - > IsFiltered ( ) ) return cur_row ;
if ( cur_row > = max_row ) return cur_row ;
cur_row = BaseSettingEntry : : Draw ( settings_ptr , left , right , y , first_row , max_row , selected , cur_row , parent_last ) ;
if ( ! this - > folded ) {
if ( this - > flags & SEF_LAST_FIELD ) {
assert ( this - > level < 8 * sizeof ( parent_last ) ) ;
SetBit ( parent_last , this - > level ) ; // Add own last-field state
}
cur_row = SettingsContainer : : Draw ( settings_ptr , left , right , y , first_row , max_row , selected , cur_row , parent_last ) ;
}
return cur_row ;
}
/**
* Function to draw setting value ( button + text + current value )
* @ param left Left - most position in window / panel to start drawing
* @ param right Right - most position in window / panel to draw
* @ param y Upper - most position in window / panel to start drawing
*/
2023-09-16 21:20:53 +01:00
void SettingsPage : : DrawSetting ( GameSettings * , int left , int right , int y , bool ) const
2014-06-01 13:14:32 +01:00
{
bool rtl = _current_text_dir = = TD_RTL ;
2014-10-04 21:34:43 +01:00
DrawSprite ( ( this - > folded ? SPR_CIRCLE_FOLDED : SPR_CIRCLE_UNFOLDED ) , PAL_NONE , rtl ? right - _circle_size . width : left , y + ( SETTING_HEIGHT - _circle_size . height ) / 2 ) ;
2023-06-25 15:48:15 +01:00
DrawString ( rtl ? left : left + _circle_size . width + WidgetDimensions : : scaled . hsep_normal , rtl ? right - _circle_size . width - WidgetDimensions : : scaled . hsep_normal : right , y + ( SETTING_HEIGHT - FONT_HEIGHT_NORMAL ) / 2 , this - > title , TC_ORANGE ) ;
2014-06-01 13:14:32 +01:00
}
2009-01-10 16:29:31 +00:00
2014-06-01 12:51:24 +01:00
/** Construct settings tree */
2014-06-01 13:14:32 +01:00
static SettingsContainer & GetSettingsTree ( )
2014-06-01 12:51:24 +01:00
{
2019-04-10 22:07:06 +01:00
static SettingsContainer * main = nullptr ;
2014-06-01 13:14:32 +01:00
2019-04-10 22:07:06 +01:00
if ( main = = nullptr )
2014-06-01 12:51:24 +01:00
{
/* Build up the dynamic settings-array only once per OpenTTD session */
2014-06-01 13:14:32 +01:00
main = new SettingsContainer ( ) ;
2014-06-01 12:51:24 +01:00
2014-06-01 13:14:32 +01:00
SettingsPage * localisation = main - > Add ( new SettingsPage ( STR_CONFIG_SETTING_LOCALISATION ) ) ;
2014-06-01 12:51:24 +01:00
{
localisation - > Add ( new SettingEntry ( " locale.units_velocity " ) ) ;
2023-04-08 17:26:13 +01:00
localisation - > Add ( new SettingEntry ( " locale.units_velocity_nautical " ) ) ;
2014-06-01 12:51:24 +01:00
localisation - > Add ( new SettingEntry ( " locale.units_power " ) ) ;
localisation - > Add ( new SettingEntry ( " locale.units_weight " ) ) ;
localisation - > Add ( new SettingEntry ( " locale.units_volume " ) ) ;
localisation - > Add ( new SettingEntry ( " locale.units_force " ) ) ;
localisation - > Add ( new SettingEntry ( " locale.units_height " ) ) ;
localisation - > Add ( new SettingEntry ( " gui.date_format_in_default_names " ) ) ;
}
2014-06-01 13:14:32 +01:00
SettingsPage * graphics = main - > Add ( new SettingsPage ( STR_CONFIG_SETTING_GRAPHICS ) ) ;
2014-06-01 12:51:24 +01:00
{
graphics - > Add ( new SettingEntry ( " gui.zoom_min " ) ) ;
graphics - > Add ( new SettingEntry ( " gui.zoom_max " ) ) ;
2021-03-13 09:00:53 +00:00
graphics - > Add ( new SettingEntry ( " gui.sprite_zoom_min " ) ) ;
2014-06-01 12:51:24 +01:00
graphics - > Add ( new SettingEntry ( " gui.smallmap_land_colour " ) ) ;
2022-04-25 18:32:55 +01:00
graphics - > Add ( new SettingEntry ( " gui.linkgraph_colours " ) ) ;
2014-06-01 12:51:24 +01:00
graphics - > Add ( new SettingEntry ( " gui.graph_line_thickness " ) ) ;
}
2014-06-01 13:14:32 +01:00
SettingsPage * sound = main - > Add ( new SettingsPage ( STR_CONFIG_SETTING_SOUND ) ) ;
2014-06-01 12:51:24 +01:00
{
sound - > Add ( new SettingEntry ( " sound.click_beep " ) ) ;
sound - > Add ( new SettingEntry ( " sound.confirm " ) ) ;
sound - > Add ( new SettingEntry ( " sound.news_ticker " ) ) ;
sound - > Add ( new SettingEntry ( " sound.news_full " ) ) ;
sound - > Add ( new SettingEntry ( " sound.new_year " ) ) ;
sound - > Add ( new SettingEntry ( " sound.disaster " ) ) ;
sound - > Add ( new SettingEntry ( " sound.vehicle " ) ) ;
sound - > Add ( new SettingEntry ( " sound.ambient " ) ) ;
}
2014-06-01 13:14:32 +01:00
SettingsPage * interface = main - > Add ( new SettingsPage ( STR_CONFIG_SETTING_INTERFACE ) ) ;
2014-06-01 12:51:24 +01:00
{
2014-06-01 13:14:32 +01:00
SettingsPage * general = interface - > Add ( new SettingsPage ( STR_CONFIG_SETTING_INTERFACE_GENERAL ) ) ;
2014-06-01 12:51:24 +01:00
{
general - > Add ( new SettingEntry ( " gui.osk_activation " ) ) ;
2014-09-13 14:30:31 +01:00
general - > Add ( new SettingEntry ( " gui.hover_delay_ms " ) ) ;
2014-06-01 12:51:24 +01:00
general - > Add ( new SettingEntry ( " gui.errmsg_duration " ) ) ;
general - > Add ( new SettingEntry ( " gui.window_snap_radius " ) ) ;
general - > Add ( new SettingEntry ( " gui.window_soft_limit " ) ) ;
2023-07-19 22:24:22 +01:00
general - > Add ( new SettingEntry ( " gui.right_click_wnd_close " ) ) ;
2014-06-01 12:51:24 +01:00
}
2014-06-01 13:14:32 +01:00
SettingsPage * viewports = interface - > Add ( new SettingsPage ( STR_CONFIG_SETTING_INTERFACE_VIEWPORTS ) ) ;
2014-06-01 12:51:24 +01:00
{
viewports - > Add ( new SettingEntry ( " gui.auto_scrolling " ) ) ;
2018-04-28 22:27:14 +01:00
viewports - > Add ( new SettingEntry ( " gui.scroll_mode " ) ) ;
2014-06-01 12:51:24 +01:00
viewports - > Add ( new SettingEntry ( " gui.smooth_scroll " ) ) ;
/* While the horizontal scrollwheel scrolling is written as general code, only
* the cocoa ( OSX ) driver generates input for it .
* Since it ' s also able to completely disable the scrollwheel will we display it on all platforms anyway */
viewports - > Add ( new SettingEntry ( " gui.scrollwheel_scrolling " ) ) ;
viewports - > Add ( new SettingEntry ( " gui.scrollwheel_multiplier " ) ) ;
2007-08-29 09:20:04 +01:00
# ifdef __APPLE__
2014-06-01 12:51:24 +01:00
/* We might need to emulate a right mouse button on mac */
viewports - > Add ( new SettingEntry ( " gui.right_mouse_btn_emulation " ) ) ;
2007-08-29 09:20:04 +01:00
# endif
2014-06-01 12:51:24 +01:00
viewports - > Add ( new SettingEntry ( " gui.population_in_label " ) ) ;
viewports - > Add ( new SettingEntry ( " gui.liveries " ) ) ;
viewports - > Add ( new SettingEntry ( " construction.train_signal_side " ) ) ;
viewports - > Add ( new SettingEntry ( " gui.measure_tooltip " ) ) ;
viewports - > Add ( new SettingEntry ( " gui.loading_indicators " ) ) ;
viewports - > Add ( new SettingEntry ( " gui.show_track_reservation " ) ) ;
}
2014-04-27 21:52:56 +01:00
2014-06-01 13:14:32 +01:00
SettingsPage * construction = interface - > Add ( new SettingsPage ( STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION ) ) ;
2014-06-01 12:51:24 +01:00
{
construction - > Add ( new SettingEntry ( " gui.link_terraform_toolbar " ) ) ;
construction - > Add ( new SettingEntry ( " gui.persistent_buildingtools " ) ) ;
construction - > Add ( new SettingEntry ( " gui.quick_goto " ) ) ;
construction - > Add ( new SettingEntry ( " gui.default_rail_type " ) ) ;
}
2014-04-27 21:52:56 +01:00
2021-02-28 14:41:03 +00:00
interface - > Add ( new SettingEntry ( " gui.fast_forward_speed_limit " ) ) ;
2014-06-01 12:51:24 +01:00
interface - > Add ( new SettingEntry ( " gui.toolbar_pos " ) ) ;
interface - > Add ( new SettingEntry ( " gui.statusbar_pos " ) ) ;
interface - > Add ( new SettingEntry ( " gui.prefer_teamchat " ) ) ;
interface - > Add ( new SettingEntry ( " gui.advanced_vehicle_list " ) ) ;
interface - > Add ( new SettingEntry ( " gui.timetable_in_ticks " ) ) ;
interface - > Add ( new SettingEntry ( " gui.timetable_arrival_departure " ) ) ;
2019-04-04 22:06:38 +01:00
interface - > Add ( new SettingEntry ( " gui.show_newgrf_name " ) ) ;
2022-11-24 20:58:10 +00:00
interface - > Add ( new SettingEntry ( " gui.show_cargo_in_vehicle_lists " ) ) ;
2014-06-01 12:51:24 +01:00
}
2009-02-08 12:25:13 +00:00
2014-06-01 13:14:32 +01:00
SettingsPage * advisors = main - > Add ( new SettingsPage ( STR_CONFIG_SETTING_ADVISORS ) ) ;
2014-06-01 12:51:24 +01:00
{
advisors - > Add ( new SettingEntry ( " gui.coloured_news_year " ) ) ;
advisors - > Add ( new SettingEntry ( " news_display.general " ) ) ;
advisors - > Add ( new SettingEntry ( " news_display.new_vehicles " ) ) ;
advisors - > Add ( new SettingEntry ( " news_display.accident " ) ) ;
2021-11-07 18:54:50 +00:00
advisors - > Add ( new SettingEntry ( " news_display.accident_other " ) ) ;
2014-06-01 12:51:24 +01:00
advisors - > Add ( new SettingEntry ( " news_display.company_info " ) ) ;
advisors - > Add ( new SettingEntry ( " news_display.acceptance " ) ) ;
advisors - > Add ( new SettingEntry ( " news_display.arrival_player " ) ) ;
advisors - > Add ( new SettingEntry ( " news_display.arrival_other " ) ) ;
advisors - > Add ( new SettingEntry ( " news_display.advice " ) ) ;
advisors - > Add ( new SettingEntry ( " gui.order_review_system " ) ) ;
advisors - > Add ( new SettingEntry ( " gui.vehicle_income_warn " ) ) ;
advisors - > Add ( new SettingEntry ( " gui.lost_vehicle_warn " ) ) ;
advisors - > Add ( new SettingEntry ( " gui.show_finances " ) ) ;
advisors - > Add ( new SettingEntry ( " news_display.economy " ) ) ;
advisors - > Add ( new SettingEntry ( " news_display.subsidies " ) ) ;
advisors - > Add ( new SettingEntry ( " news_display.open " ) ) ;
advisors - > Add ( new SettingEntry ( " news_display.close " ) ) ;
advisors - > Add ( new SettingEntry ( " news_display.production_player " ) ) ;
advisors - > Add ( new SettingEntry ( " news_display.production_other " ) ) ;
advisors - > Add ( new SettingEntry ( " news_display.production_nobody " ) ) ;
}
2014-04-27 21:52:56 +01:00
2014-06-01 13:14:32 +01:00
SettingsPage * company = main - > Add ( new SettingsPage ( STR_CONFIG_SETTING_COMPANY ) ) ;
2014-06-01 12:51:24 +01:00
{
company - > Add ( new SettingEntry ( " gui.semaphore_build_before " ) ) ;
company - > Add ( new SettingEntry ( " gui.cycle_signal_types " ) ) ;
2021-09-05 19:22:27 +01:00
company - > Add ( new SettingEntry ( " gui.signal_gui_mode " ) ) ;
2014-06-01 12:51:24 +01:00
company - > Add ( new SettingEntry ( " gui.drag_signals_fixed_distance " ) ) ;
2021-01-07 09:17:05 +00:00
company - > Add ( new SettingEntry ( " gui.auto_remove_signals " ) ) ;
2014-06-01 12:51:24 +01:00
company - > Add ( new SettingEntry ( " gui.new_nonstop " ) ) ;
company - > Add ( new SettingEntry ( " gui.stop_location " ) ) ;
2019-01-10 09:45:38 +00:00
company - > Add ( new SettingEntry ( " gui.starting_colour " ) ) ;
2023-06-24 21:50:04 +01:00
company - > Add ( new SettingEntry ( " gui.starting_colour_secondary " ) ) ;
2014-06-01 12:51:24 +01:00
company - > Add ( new SettingEntry ( " company.engine_renew " ) ) ;
company - > Add ( new SettingEntry ( " company.engine_renew_months " ) ) ;
company - > Add ( new SettingEntry ( " company.engine_renew_money " ) ) ;
company - > Add ( new SettingEntry ( " vehicle.servint_ispercent " ) ) ;
company - > Add ( new SettingEntry ( " vehicle.servint_trains " ) ) ;
company - > Add ( new SettingEntry ( " vehicle.servint_roadveh " ) ) ;
company - > Add ( new SettingEntry ( " vehicle.servint_ships " ) ) ;
company - > Add ( new SettingEntry ( " vehicle.servint_aircraft " ) ) ;
}
2009-01-10 17:35:19 +00:00
2014-06-01 13:14:32 +01:00
SettingsPage * accounting = main - > Add ( new SettingsPage ( STR_CONFIG_SETTING_ACCOUNTING ) ) ;
2014-06-01 12:51:24 +01:00
{
accounting - > Add ( new SettingEntry ( " economy.inflation " ) ) ;
accounting - > Add ( new SettingEntry ( " difficulty.initial_interest " ) ) ;
accounting - > Add ( new SettingEntry ( " difficulty.max_loan " ) ) ;
accounting - > Add ( new SettingEntry ( " difficulty.subsidy_multiplier " ) ) ;
2021-04-22 18:54:32 +01:00
accounting - > Add ( new SettingEntry ( " difficulty.subsidy_duration " ) ) ;
2014-06-01 12:51:24 +01:00
accounting - > Add ( new SettingEntry ( " economy.feeder_payment_share " ) ) ;
accounting - > Add ( new SettingEntry ( " economy.infrastructure_maintenance " ) ) ;
accounting - > Add ( new SettingEntry ( " difficulty.vehicle_costs " ) ) ;
accounting - > Add ( new SettingEntry ( " difficulty.construction_cost " ) ) ;
}
2014-06-01 13:14:32 +01:00
SettingsPage * vehicles = main - > Add ( new SettingsPage ( STR_CONFIG_SETTING_VEHICLES ) ) ;
2014-06-01 12:51:24 +01:00
{
2014-06-01 13:14:32 +01:00
SettingsPage * physics = vehicles - > Add ( new SettingsPage ( STR_CONFIG_SETTING_VEHICLES_PHYSICS ) ) ;
2014-06-01 12:51:24 +01:00
{
physics - > Add ( new SettingEntry ( " vehicle.train_acceleration_model " ) ) ;
physics - > Add ( new SettingEntry ( " vehicle.train_slope_steepness " ) ) ;
physics - > Add ( new SettingEntry ( " vehicle.wagon_speed_limits " ) ) ;
physics - > Add ( new SettingEntry ( " vehicle.freight_trains " ) ) ;
physics - > Add ( new SettingEntry ( " vehicle.roadveh_acceleration_model " ) ) ;
physics - > Add ( new SettingEntry ( " vehicle.roadveh_slope_steepness " ) ) ;
physics - > Add ( new SettingEntry ( " vehicle.smoke_amount " ) ) ;
physics - > Add ( new SettingEntry ( " vehicle.plane_speed " ) ) ;
}
2014-06-01 13:14:32 +01:00
SettingsPage * routing = vehicles - > Add ( new SettingsPage ( STR_CONFIG_SETTING_VEHICLES_ROUTING ) ) ;
2014-06-01 12:51:24 +01:00
{
routing - > Add ( new SettingEntry ( " pf.pathfinder_for_trains " ) ) ;
routing - > Add ( new SettingEntry ( " difficulty.line_reverse_mode " ) ) ;
routing - > Add ( new SettingEntry ( " pf.reverse_at_signals " ) ) ;
routing - > Add ( new SettingEntry ( " pf.forbid_90_deg " ) ) ;
routing - > Add ( new SettingEntry ( " pf.pathfinder_for_roadvehs " ) ) ;
routing - > Add ( new SettingEntry ( " pf.pathfinder_for_ships " ) ) ;
}
vehicles - > Add ( new SettingEntry ( " order.no_servicing_if_no_breakdowns " ) ) ;
vehicles - > Add ( new SettingEntry ( " order.serviceathelipad " ) ) ;
}
2014-06-01 13:14:32 +01:00
SettingsPage * limitations = main - > Add ( new SettingsPage ( STR_CONFIG_SETTING_LIMITATIONS ) ) ;
2014-06-01 12:51:24 +01:00
{
limitations - > Add ( new SettingEntry ( " construction.command_pause_level " ) ) ;
limitations - > Add ( new SettingEntry ( " construction.autoslope " ) ) ;
limitations - > Add ( new SettingEntry ( " construction.extra_dynamite " ) ) ;
2021-03-24 08:42:54 +00:00
limitations - > Add ( new SettingEntry ( " construction.map_height_limit " ) ) ;
2014-06-01 12:51:24 +01:00
limitations - > Add ( new SettingEntry ( " construction.max_bridge_length " ) ) ;
2014-09-21 12:40:11 +01:00
limitations - > Add ( new SettingEntry ( " construction.max_bridge_height " ) ) ;
2014-06-01 12:51:24 +01:00
limitations - > Add ( new SettingEntry ( " construction.max_tunnel_length " ) ) ;
limitations - > Add ( new SettingEntry ( " station.never_expire_airports " ) ) ;
limitations - > Add ( new SettingEntry ( " vehicle.never_expire_vehicles " ) ) ;
limitations - > Add ( new SettingEntry ( " vehicle.max_trains " ) ) ;
limitations - > Add ( new SettingEntry ( " vehicle.max_roadveh " ) ) ;
limitations - > Add ( new SettingEntry ( " vehicle.max_aircraft " ) ) ;
limitations - > Add ( new SettingEntry ( " vehicle.max_ships " ) ) ;
limitations - > Add ( new SettingEntry ( " vehicle.max_train_length " ) ) ;
limitations - > Add ( new SettingEntry ( " station.station_spread " ) ) ;
limitations - > Add ( new SettingEntry ( " station.distant_join_stations " ) ) ;
limitations - > Add ( new SettingEntry ( " construction.road_stop_on_town_road " ) ) ;
limitations - > Add ( new SettingEntry ( " construction.road_stop_on_competitor_road " ) ) ;
2023-09-02 11:46:24 +01:00
limitations - > Add ( new SettingEntry ( " construction.crossing_with_competitor " ) ) ;
2014-06-01 12:51:24 +01:00
limitations - > Add ( new SettingEntry ( " vehicle.disable_elrails " ) ) ;
}
2014-06-01 13:14:32 +01:00
SettingsPage * disasters = main - > Add ( new SettingsPage ( STR_CONFIG_SETTING_ACCIDENTS ) ) ;
2014-06-01 12:51:24 +01:00
{
disasters - > Add ( new SettingEntry ( " difficulty.disasters " ) ) ;
disasters - > Add ( new SettingEntry ( " difficulty.economy " ) ) ;
disasters - > Add ( new SettingEntry ( " difficulty.vehicle_breakdowns " ) ) ;
disasters - > Add ( new SettingEntry ( " vehicle.plane_crashes " ) ) ;
}
2014-06-01 13:14:32 +01:00
SettingsPage * genworld = main - > Add ( new SettingsPage ( STR_CONFIG_SETTING_GENWORLD ) ) ;
2014-06-01 12:51:24 +01:00
{
genworld - > Add ( new SettingEntry ( " game_creation.landscape " ) ) ;
genworld - > Add ( new SettingEntry ( " game_creation.land_generator " ) ) ;
genworld - > Add ( new SettingEntry ( " difficulty.terrain_type " ) ) ;
genworld - > Add ( new SettingEntry ( " game_creation.tgen_smoothness " ) ) ;
genworld - > Add ( new SettingEntry ( " game_creation.variety " ) ) ;
2021-03-24 13:48:12 +00:00
genworld - > Add ( new SettingEntry ( " game_creation.snow_coverage " ) ) ;
2014-06-01 12:51:24 +01:00
genworld - > Add ( new SettingEntry ( " game_creation.snow_line_height " ) ) ;
2021-03-24 15:38:36 +00:00
genworld - > Add ( new SettingEntry ( " game_creation.desert_coverage " ) ) ;
2014-06-01 12:51:24 +01:00
genworld - > Add ( new SettingEntry ( " game_creation.amount_of_rivers " ) ) ;
genworld - > Add ( new SettingEntry ( " game_creation.tree_placer " ) ) ;
genworld - > Add ( new SettingEntry ( " vehicle.road_side " ) ) ;
genworld - > Add ( new SettingEntry ( " economy.larger_towns " ) ) ;
genworld - > Add ( new SettingEntry ( " economy.initial_city_size " ) ) ;
genworld - > Add ( new SettingEntry ( " economy.town_layout " ) ) ;
genworld - > Add ( new SettingEntry ( " difficulty.industry_density " ) ) ;
genworld - > Add ( new SettingEntry ( " gui.pause_on_newgame " ) ) ;
2019-09-18 19:18:45 +01:00
genworld - > Add ( new SettingEntry ( " game_creation.ending_year " ) ) ;
2014-06-01 12:51:24 +01:00
}
2014-06-01 13:14:32 +01:00
SettingsPage * environment = main - > Add ( new SettingsPage ( STR_CONFIG_SETTING_ENVIRONMENT ) ) ;
2014-06-01 12:51:24 +01:00
{
2014-06-01 13:14:32 +01:00
SettingsPage * authorities = environment - > Add ( new SettingsPage ( STR_CONFIG_SETTING_ENVIRONMENT_AUTHORITIES ) ) ;
2014-06-01 12:51:24 +01:00
{
authorities - > Add ( new SettingEntry ( " difficulty.town_council_tolerance " ) ) ;
authorities - > Add ( new SettingEntry ( " economy.bribe " ) ) ;
authorities - > Add ( new SettingEntry ( " economy.exclusive_rights " ) ) ;
authorities - > Add ( new SettingEntry ( " economy.fund_roads " ) ) ;
authorities - > Add ( new SettingEntry ( " economy.fund_buildings " ) ) ;
authorities - > Add ( new SettingEntry ( " economy.station_noise_level " ) ) ;
}
2014-06-01 13:14:32 +01:00
SettingsPage * towns = environment - > Add ( new SettingsPage ( STR_CONFIG_SETTING_ENVIRONMENT_TOWNS ) ) ;
2014-06-01 12:51:24 +01:00
{
towns - > Add ( new SettingEntry ( " economy.town_growth_rate " ) ) ;
towns - > Add ( new SettingEntry ( " economy.allow_town_roads " ) ) ;
towns - > Add ( new SettingEntry ( " economy.allow_town_level_crossings " ) ) ;
towns - > Add ( new SettingEntry ( " economy.found_town " ) ) ;
2018-11-07 18:06:39 +00:00
towns - > Add ( new SettingEntry ( " economy.town_cargogen_mode " ) ) ;
2014-06-01 12:51:24 +01:00
}
2014-06-01 13:14:32 +01:00
SettingsPage * industries = environment - > Add ( new SettingsPage ( STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES ) ) ;
2014-06-01 12:51:24 +01:00
{
industries - > Add ( new SettingEntry ( " construction.raw_industry_construction " ) ) ;
industries - > Add ( new SettingEntry ( " construction.industry_platform " ) ) ;
industries - > Add ( new SettingEntry ( " economy.multiple_industry_per_town " ) ) ;
industries - > Add ( new SettingEntry ( " game_creation.oil_refinery_limit " ) ) ;
2020-12-14 22:35:07 +00:00
industries - > Add ( new SettingEntry ( " economy.type " ) ) ;
2019-03-08 18:30:44 +00:00
industries - > Add ( new SettingEntry ( " station.serve_neutral_industries " ) ) ;
2014-06-01 12:51:24 +01:00
}
2004-08-09 18:04:08 +01:00
2014-06-01 13:14:32 +01:00
SettingsPage * cdist = environment - > Add ( new SettingsPage ( STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST ) ) ;
2014-06-01 12:51:24 +01:00
{
cdist - > Add ( new SettingEntry ( " linkgraph.recalc_time " ) ) ;
cdist - > Add ( new SettingEntry ( " linkgraph.recalc_interval " ) ) ;
cdist - > Add ( new SettingEntry ( " linkgraph.distribution_pax " ) ) ;
cdist - > Add ( new SettingEntry ( " linkgraph.distribution_mail " ) ) ;
cdist - > Add ( new SettingEntry ( " linkgraph.distribution_armoured " ) ) ;
cdist - > Add ( new SettingEntry ( " linkgraph.distribution_default " ) ) ;
cdist - > Add ( new SettingEntry ( " linkgraph.accuracy " ) ) ;
cdist - > Add ( new SettingEntry ( " linkgraph.demand_distance " ) ) ;
cdist - > Add ( new SettingEntry ( " linkgraph.demand_size " ) ) ;
cdist - > Add ( new SettingEntry ( " linkgraph.short_path_saturation " ) ) ;
}
environment - > Add ( new SettingEntry ( " station.modified_catchment " ) ) ;
environment - > Add ( new SettingEntry ( " construction.extra_tree_placement " ) ) ;
}
2014-06-01 13:14:32 +01:00
SettingsPage * ai = main - > Add ( new SettingsPage ( STR_CONFIG_SETTING_AI ) ) ;
2014-06-01 12:51:24 +01:00
{
2014-06-01 13:14:32 +01:00
SettingsPage * npc = ai - > Add ( new SettingsPage ( STR_CONFIG_SETTING_AI_NPC ) ) ;
2014-06-01 12:51:24 +01:00
{
npc - > Add ( new SettingEntry ( " script.settings_profile " ) ) ;
npc - > Add ( new SettingEntry ( " script.script_max_opcode_till_suspend " ) ) ;
2019-04-15 18:49:30 +01:00
npc - > Add ( new SettingEntry ( " script.script_max_memory_megabytes " ) ) ;
2014-06-01 12:51:24 +01:00
npc - > Add ( new SettingEntry ( " difficulty.competitor_speed " ) ) ;
npc - > Add ( new SettingEntry ( " ai.ai_in_multiplayer " ) ) ;
npc - > Add ( new SettingEntry ( " ai.ai_disable_veh_train " ) ) ;
npc - > Add ( new SettingEntry ( " ai.ai_disable_veh_roadveh " ) ) ;
npc - > Add ( new SettingEntry ( " ai.ai_disable_veh_aircraft " ) ) ;
npc - > Add ( new SettingEntry ( " ai.ai_disable_veh_ship " ) ) ;
}
ai - > Add ( new SettingEntry ( " economy.give_money " ) ) ;
}
2021-05-05 09:47:01 +01:00
SettingsPage * network = main - > Add ( new SettingsPage ( STR_CONFIG_SETTING_NETWORK ) ) ;
{
network - > Add ( new SettingEntry ( " network.use_relay_service " ) ) ;
}
2014-06-01 12:51:24 +01:00
main - > Init ( ) ;
}
return * main ;
}
2009-01-10 17:14:59 +00:00
2012-10-29 19:53:13 +00:00
static const StringID _game_settings_restrict_dropdown [ ] = {
2012-11-08 10:04:00 +00:00
STR_CONFIG_SETTING_RESTRICT_BASIC , // RM_BASIC
STR_CONFIG_SETTING_RESTRICT_ADVANCED , // RM_ADVANCED
2012-10-29 19:53:13 +00:00
STR_CONFIG_SETTING_RESTRICT_ALL , // RM_ALL
STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_DEFAULT , // RM_CHANGED_AGAINST_DEFAULT
STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_NEW , // RM_CHANGED_AGAINST_NEW
} ;
2020-12-27 10:44:22 +00:00
static_assert ( lengthof ( _game_settings_restrict_dropdown ) = = RM_END ) ;
2012-10-29 19:53:13 +00:00
2014-02-09 13:05:46 +00:00
/** Warnings about hidden search results. */
enum WarnHiddenResult {
WHR_NONE , ///< Nothing was filtering matches away.
WHR_CATEGORY , ///< Category setting filtered matches away.
WHR_TYPE , ///< Type setting filtered matches away.
WHR_CATEGORY_TYPE , ///< Both category and type settings filtered matches away.
} ;
2021-04-06 11:47:44 +01:00
/**
* Callback function for the reset all settings button
* @ param w Window which is calling this callback
* @ param confirmed boolean value , true when yes was clicked , false otherwise
*/
static void ResetAllSettingsConfirmationCallback ( Window * w , bool confirmed )
{
if ( confirmed ) {
GetSettingsTree ( ) . ResetAll ( ) ;
GetSettingsTree ( ) . FoldAll ( ) ;
w - > InvalidateData ( ) ;
}
}
2014-02-09 13:05:46 +00:00
/** Window to edit settings of the game. */
2012-11-14 22:50:35 +00:00
struct GameSettingsWindow : Window {
2012-05-12 11:13:03 +01:00
static GameSettings * settings_ptr ; ///< Pointer to the game settings being displayed and modified.
2006-03-02 01:41:25 +00:00
2019-04-10 22:07:06 +01:00
SettingEntry * valuewindow_entry ; ///< If non-nullptr, pointer to setting for which a value-entering window has been opened.
SettingEntry * clicked_entry ; ///< If non-nullptr, pointer to a clicked numeric setting (with a depressed left or right button).
SettingEntry * last_clicked ; ///< If non-nullptr, pointer to the last clicked setting.
SettingEntry * valuedropdown_entry ; ///< If non-nullptr, pointer to the value for which a dropdown window is currently opened.
2012-06-01 16:19:38 +01:00
bool closing_dropdown ; ///< True, if the dropdown list is currently closing.
2006-03-17 22:47:52 +00:00
2012-12-26 17:44:42 +00:00
SettingFilter filter ; ///< Filter for the list.
2012-11-14 22:50:35 +00:00
QueryString filter_editbox ; ///< Filter editbox;
2012-10-27 16:26:34 +01:00
bool manually_changed_folding ; ///< Whether the user expanded/collapsed something manually.
2014-02-09 13:05:46 +00:00
WarnHiddenResult warn_missing ; ///< Whether and how to warn about missing search results.
int warn_lines ; ///< Number of lines used for warning about missing search results.
2012-10-27 16:26:17 +01:00
2010-08-12 09:37:01 +01:00
Scrollbar * vscroll ;
2013-05-26 20:23:42 +01:00
GameSettingsWindow ( WindowDesc * desc ) : Window ( desc ) , filter_editbox ( 50 )
2008-05-15 22:48:47 +01:00
{
2014-02-09 13:05:46 +00:00
this - > warn_missing = WHR_NONE ;
this - > warn_lines = 0 ;
this - > filter . mode = ( RestrictionMode ) _settings_client . gui . settings_restriction_mode ;
this - > filter . min_cat = RM_ALL ;
this - > filter . type = ST_ALL ;
this - > filter . type_hides = false ;
this - > settings_ptr = & GetGameSettings ( ) ;
2006-03-17 22:47:52 +00:00
2014-06-01 12:51:24 +01:00
GetSettingsTree ( ) . FoldAll ( ) ; // Close all sub-pages
2008-02-18 12:36:10 +00:00
2019-04-10 22:07:06 +01:00
this - > valuewindow_entry = nullptr ; // No setting entry for which a entry window is opened
this - > clicked_entry = nullptr ; // No numeric setting buttons are depressed
this - > last_clicked = nullptr ;
this - > valuedropdown_entry = nullptr ;
2012-06-01 16:19:38 +01:00
this - > closing_dropdown = false ;
2012-10-27 16:26:34 +01:00
this - > manually_changed_folding = false ;
2009-10-25 21:18:12 +00:00
2013-05-26 20:23:42 +01:00
this - > CreateNestedTree ( ) ;
2011-12-16 18:27:50 +00:00
this - > vscroll = this - > GetScrollbar ( WID_GS_SCROLLBAR ) ;
2013-05-26 20:23:42 +01:00
this - > FinishInitNested ( WN_GAME_OPTIONS_GAME_SETTINGS ) ;
2009-10-25 21:18:12 +00:00
2012-11-14 22:50:35 +00:00
this - > querystrings [ WID_GS_FILTER ] = & this - > filter_editbox ;
2012-11-14 22:50:39 +00:00
this - > filter_editbox . cancel_button = QueryString : : ACTION_CLEAR ;
2012-10-27 16:26:17 +01:00
this - > SetFocusedWidget ( WID_GS_FILTER ) ;
2012-10-27 16:25:57 +01:00
this - > InvalidateData ( ) ;
2009-10-25 21:18:12 +00:00
}
2022-09-27 22:39:35 +01:00
void OnInit ( ) override
{
_circle_size = maxdim ( GetSpriteSize ( SPR_CIRCLE_FOLDED ) , GetSpriteSize ( SPR_CIRCLE_UNFOLDED ) ) ;
}
2023-09-16 21:20:53 +01:00
void UpdateWidgetSize ( int widget , Dimension * size , [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension * resize ) override
2009-10-25 21:18:12 +00:00
{
2012-05-12 11:13:03 +01:00
switch ( widget ) {
case WID_GS_OPTIONSPANEL :
2022-09-23 09:36:22 +01:00
resize - > height = SETTING_HEIGHT = std : : max ( { ( int ) _circle_size . height , SETTING_BUTTON_HEIGHT , FONT_HEIGHT_NORMAL } ) + WidgetDimensions : : scaled . vsep_normal ;
resize - > width = 1 ;
2004-08-09 18:04:08 +01:00
2022-09-23 09:36:22 +01:00
size - > height = 5 * resize - > height + WidgetDimensions : : scaled . framerect . Vertical ( ) ;
2012-05-12 11:13:03 +01:00
break ;
2004-08-09 18:04:08 +01:00
2012-07-17 21:18:18 +01:00
case WID_GS_HELP_TEXT : {
static const StringID setting_types [ ] = {
STR_CONFIG_SETTING_TYPE_CLIENT ,
STR_CONFIG_SETTING_TYPE_COMPANY_MENU , STR_CONFIG_SETTING_TYPE_COMPANY_INGAME ,
STR_CONFIG_SETTING_TYPE_GAME_MENU , STR_CONFIG_SETTING_TYPE_GAME_INGAME ,
} ;
for ( uint i = 0 ; i < lengthof ( setting_types ) ; i + + ) {
SetDParam ( 0 , setting_types [ i ] ) ;
2023-06-05 09:27:04 +01:00
size - > width = std : : max ( size - > width , GetStringBoundingBox ( STR_CONFIG_SETTING_TYPE ) . width + padding . width ) ;
2012-07-17 21:18:18 +01:00
}
2022-09-23 09:36:22 +01:00
size - > height = 2 * FONT_HEIGHT_NORMAL + WidgetDimensions : : scaled . vsep_normal +
2021-01-08 10:16:18 +00:00
std : : max ( size - > height , GetSettingsTree ( ) . GetMaxHelpHeight ( size - > width ) ) ;
2012-05-12 11:13:03 +01:00
break ;
2012-07-17 21:18:18 +01:00
}
2012-05-12 11:13:03 +01:00
2014-02-09 13:04:50 +00:00
case WID_GS_RESTRICT_CATEGORY :
case WID_GS_RESTRICT_TYPE :
2021-01-08 10:16:18 +00:00
size - > width = std : : max ( GetStringBoundingBox ( STR_CONFIG_SETTING_RESTRICT_CATEGORY ) . width , GetStringBoundingBox ( STR_CONFIG_SETTING_RESTRICT_TYPE ) . width ) ;
2014-02-09 13:04:50 +00:00
break ;
2012-05-12 11:13:03 +01:00
default :
break ;
}
2009-10-25 21:18:12 +00:00
}
2019-03-04 07:49:37 +00:00
void OnPaint ( ) override
2012-06-01 16:19:38 +01:00
{
if ( this - > closing_dropdown ) {
this - > closing_dropdown = false ;
2019-04-10 22:07:06 +01:00
assert ( this - > valuedropdown_entry ! = nullptr ) ;
2012-06-01 16:19:38 +01:00
this - > valuedropdown_entry - > SetButtons ( 0 ) ;
2019-04-10 22:07:06 +01:00
this - > valuedropdown_entry = nullptr ;
2012-06-01 16:19:38 +01:00
}
2014-02-09 13:05:46 +00:00
/* Reserve the correct number of lines for the 'some search results are hidden' notice in the central settings display panel. */
2022-09-23 09:36:22 +01:00
const Rect panel = this - > GetWidget < NWidgetBase > ( WID_GS_OPTIONSPANEL ) - > GetCurrentRect ( ) . Shrink ( WidgetDimensions : : scaled . frametext ) ;
2014-02-09 13:05:46 +00:00
StringID warn_str = STR_CONFIG_SETTING_CATEGORY_HIDES - 1 + this - > warn_missing ;
int new_warn_lines ;
if ( this - > warn_missing = = WHR_NONE ) {
new_warn_lines = 0 ;
} else {
SetDParam ( 0 , _game_settings_restrict_dropdown [ this - > filter . min_cat ] ) ;
2022-10-17 19:23:11 +01:00
new_warn_lines = GetStringLineCount ( warn_str , panel . Width ( ) ) ;
2014-02-09 13:05:46 +00:00
}
if ( this - > warn_lines ! = new_warn_lines ) {
this - > vscroll - > SetCount ( this - > vscroll - > GetCount ( ) - this - > warn_lines + new_warn_lines ) ;
this - > warn_lines = new_warn_lines ;
}
2012-06-01 16:19:38 +01:00
this - > DrawWidgets ( ) ;
2014-02-09 13:05:46 +00:00
/* Draw the 'some search results are hidden' notice. */
if ( this - > warn_missing ! = WHR_NONE ) {
SetDParam ( 0 , _game_settings_restrict_dropdown [ this - > filter . min_cat ] ) ;
2022-10-17 19:23:11 +01:00
DrawStringMultiLine ( panel . WithHeight ( this - > warn_lines * FONT_HEIGHT_NORMAL ) , warn_str , TC_FROMSTRING , SA_CENTER ) ;
2014-02-09 13:05:46 +00:00
}
2012-06-01 16:19:38 +01:00
}
2019-03-04 07:49:37 +00:00
void SetStringParameters ( int widget ) const override
2012-10-29 19:53:13 +00:00
{
switch ( widget ) {
case WID_GS_RESTRICT_DROPDOWN :
2012-12-26 17:44:42 +00:00
SetDParam ( 0 , _game_settings_restrict_dropdown [ this - > filter . mode ] ) ;
2012-10-29 19:53:13 +00:00
break ;
2012-12-26 17:47:02 +00:00
case WID_GS_TYPE_DROPDOWN :
switch ( this - > filter . type ) {
case ST_GAME : SetDParam ( 0 , _game_mode = = GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME ) ; break ;
case ST_COMPANY : SetDParam ( 0 , _game_mode = = GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME ) ; break ;
case ST_CLIENT : SetDParam ( 0 , STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT ) ; break ;
default : SetDParam ( 0 , STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL ) ; break ;
}
break ;
2012-10-29 19:53:13 +00:00
}
}
2019-04-02 20:31:24 +01:00
DropDownList BuildDropDownList ( int widget ) const
2012-10-29 19:53:13 +00:00
{
2019-04-02 20:31:24 +01:00
DropDownList list ;
2012-10-29 19:53:13 +00:00
switch ( widget ) {
case WID_GS_RESTRICT_DROPDOWN :
for ( int mode = 0 ; mode ! = RM_END ; mode + + ) {
/* If we are in adv. settings screen for the new game's settings,
* we don ' t want to allow comparing with new game ' s settings . */
bool disabled = mode = = RM_CHANGED_AGAINST_NEW & & settings_ptr = = & _settings_newgame ;
2023-10-20 18:40:48 +01:00
list . push_back ( std : : make_unique < DropDownListStringItem > ( _game_settings_restrict_dropdown [ mode ] , mode , disabled ) ) ;
2012-10-29 19:53:13 +00:00
}
break ;
2012-12-26 17:47:02 +00:00
case WID_GS_TYPE_DROPDOWN :
2023-10-20 18:40:48 +01:00
list . push_back ( std : : make_unique < DropDownListStringItem > ( STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL , ST_ALL , false ) ) ;
list . push_back ( std : : make_unique < DropDownListStringItem > ( _game_mode = = GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME , ST_GAME , false ) ) ;
list . push_back ( std : : make_unique < DropDownListStringItem > ( _game_mode = = GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME , ST_COMPANY , false ) ) ;
list . push_back ( std : : make_unique < DropDownListStringItem > ( STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT , ST_CLIENT , false ) ) ;
2012-12-26 17:47:02 +00:00
break ;
2012-10-29 19:53:13 +00:00
}
return list ;
}
2019-03-04 07:49:37 +00:00
void DrawWidget ( const Rect & r , int widget ) const override
2009-10-25 21:18:12 +00:00
{
2012-05-12 11:13:03 +01:00
switch ( widget ) {
2014-02-09 13:05:46 +00:00
case WID_GS_OPTIONSPANEL : {
2022-09-23 09:36:22 +01:00
Rect tr = r . Shrink ( WidgetDimensions : : scaled . frametext , WidgetDimensions : : scaled . framerect ) ;
2022-10-17 19:23:11 +01:00
tr . top + = this - > warn_lines * SETTING_HEIGHT ;
2014-02-09 13:05:46 +00:00
uint last_row = this - > vscroll - > GetPosition ( ) + this - > vscroll - > GetCapacity ( ) - this - > warn_lines ;
2022-10-17 19:23:11 +01:00
int next_row = GetSettingsTree ( ) . Draw ( settings_ptr , tr . left , tr . right , tr . top ,
2014-02-09 13:05:46 +00:00
this - > vscroll - > GetPosition ( ) , last_row , this - > last_clicked ) ;
2022-10-17 19:23:11 +01:00
if ( next_row = = 0 ) DrawString ( tr , STR_CONFIG_SETTINGS_NONE ) ;
2012-05-12 11:13:03 +01:00
break ;
2014-02-09 13:05:46 +00:00
}
2012-05-12 11:13:03 +01:00
case WID_GS_HELP_TEXT :
2019-04-10 22:07:06 +01:00
if ( this - > last_clicked ! = nullptr ) {
2021-05-23 10:37:56 +01:00
const IntSettingDesc * sd = this - > last_clicked - > setting ;
2012-05-28 14:34:46 +01:00
2022-10-17 19:23:11 +01:00
Rect tr = r ;
2012-12-26 17:43:35 +00:00
switch ( sd - > GetType ( ) ) {
case ST_COMPANY : SetDParam ( 0 , _game_mode = = GM_MENU ? STR_CONFIG_SETTING_TYPE_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_COMPANY_INGAME ) ; break ;
case ST_CLIENT : SetDParam ( 0 , STR_CONFIG_SETTING_TYPE_CLIENT ) ; break ;
case ST_GAME : SetDParam ( 0 , _game_mode = = GM_MENU ? STR_CONFIG_SETTING_TYPE_GAME_MENU : STR_CONFIG_SETTING_TYPE_GAME_INGAME ) ; break ;
default : NOT_REACHED ( ) ;
2012-07-17 21:18:18 +01:00
}
2022-10-17 19:23:11 +01:00
DrawString ( tr , STR_CONFIG_SETTING_TYPE ) ;
tr . top + = FONT_HEIGHT_NORMAL ;
2012-07-17 21:18:18 +01:00
2021-05-22 20:09:30 +01:00
this - > last_clicked - > SetValueDParams ( 0 , sd - > def ) ;
2022-10-17 19:23:11 +01:00
DrawString ( tr , STR_CONFIG_SETTING_DEFAULT_VALUE ) ;
2022-09-23 09:36:22 +01:00
tr . top + = FONT_HEIGHT_NORMAL + WidgetDimensions : : scaled . vsep_normal ;
2012-05-28 14:34:46 +01:00
2022-10-17 19:23:11 +01:00
DrawStringMultiLine ( tr , this - > last_clicked - > GetHelpText ( ) , TC_WHITE ) ;
2012-05-12 11:13:03 +01:00
}
break ;
2009-10-25 21:18:12 +00:00
2012-05-12 11:13:03 +01:00
default :
break ;
}
}
/**
* Set the entry that should have its help text displayed , and mark the window dirty so it gets repainted .
2019-04-10 22:07:06 +01:00
* @ param pe Setting to display help text of , use \ c nullptr to stop displaying help of the currently displayed setting .
2012-05-12 11:13:03 +01:00
*/
void SetDisplayedHelpText ( SettingEntry * pe )
{
if ( this - > last_clicked ! = pe ) this - > SetDirty ( ) ;
this - > last_clicked = pe ;
2008-05-15 22:48:47 +01:00
}
2006-03-02 01:41:25 +00:00
2023-09-16 21:20:53 +01:00
void OnClick ( [[maybe_unused]] Point pt, int widget, [[maybe_unused]] int click_count ) override
2008-05-15 22:48:47 +01:00
{
2012-10-27 16:25:57 +01:00
switch ( widget ) {
case WID_GS_EXPAND_ALL :
2012-10-27 16:26:34 +01:00
this - > manually_changed_folding = true ;
2014-06-01 12:51:24 +01:00
GetSettingsTree ( ) . UnFoldAll ( ) ;
2012-10-27 16:25:57 +01:00
this - > InvalidateData ( ) ;
break ;
case WID_GS_COLLAPSE_ALL :
2012-10-27 16:26:34 +01:00
this - > manually_changed_folding = true ;
2014-06-01 12:51:24 +01:00
GetSettingsTree ( ) . FoldAll ( ) ;
2012-10-27 16:25:57 +01:00
this - > InvalidateData ( ) ;
break ;
2012-10-29 19:53:13 +00:00
2021-04-06 11:47:44 +01:00
case WID_GS_RESET_ALL :
ShowQuery (
STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_CAPTION ,
STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_TEXT ,
this ,
ResetAllSettingsConfirmationCallback
) ;
break ;
2012-10-29 19:53:13 +00:00
case WID_GS_RESTRICT_DROPDOWN : {
2019-04-02 20:31:24 +01:00
DropDownList list = this - > BuildDropDownList ( widget ) ;
if ( ! list . empty ( ) ) {
ShowDropDownList ( this , std : : move ( list ) , this - > filter . mode , widget ) ;
2012-10-29 19:53:13 +00:00
}
2012-12-26 17:47:02 +00:00
break ;
}
case WID_GS_TYPE_DROPDOWN : {
2019-04-02 20:31:24 +01:00
DropDownList list = this - > BuildDropDownList ( widget ) ;
if ( ! list . empty ( ) ) {
ShowDropDownList ( this , std : : move ( list ) , this - > filter . type , widget ) ;
2012-12-26 17:47:02 +00:00
}
break ;
2012-10-29 19:53:13 +00:00
}
2012-10-27 16:25:57 +01:00
}
2011-12-16 18:27:50 +00:00
if ( widget ! = WID_GS_OPTIONSPANEL ) return ;
2008-05-15 22:48:47 +01:00
2022-09-23 09:36:22 +01:00
uint btn = this - > vscroll - > GetScrolledRowFromWidget ( pt . y , this , WID_GS_OPTIONSPANEL , WidgetDimensions : : scaled . framerect . top ) ;
2014-02-09 13:05:46 +00:00
if ( btn = = INT_MAX | | ( int ) btn < this - > warn_lines ) return ;
btn - = this - > warn_lines ;
2009-01-03 11:03:53 +00:00
2009-01-10 19:22:05 +00:00
uint cur_row = 0 ;
2014-06-01 13:14:32 +01:00
BaseSettingEntry * clicked_entry = GetSettingsTree ( ) . FindEntry ( btn , & cur_row ) ;
2008-05-15 22:48:47 +01:00
2019-04-10 22:07:06 +01:00
if ( clicked_entry = = nullptr ) return ; // Clicked below the last setting of the page
2009-01-10 17:13:41 +00:00
2022-09-23 09:36:22 +01:00
int x = ( _current_text_dir = = TD_RTL ? this - > width - 1 - pt . x : pt . x ) - WidgetDimensions : : scaled . frametext . left - ( clicked_entry - > level + 1 ) * WidgetDimensions : : scaled . hsep_indent ; // Shift x coordinate
2009-01-10 19:22:05 +00:00
if ( x < 0 ) return ; // Clicked left of the entry
2009-01-10 16:51:27 +00:00
2014-06-01 13:14:32 +01:00
SettingsPage * clicked_page = dynamic_cast < SettingsPage * > ( clicked_entry ) ;
2019-04-10 22:07:06 +01:00
if ( clicked_page ! = nullptr ) {
this - > SetDisplayedHelpText ( nullptr ) ;
2014-06-01 13:14:32 +01:00
clicked_page - > folded = ! clicked_page - > folded ; // Flip 'folded'-ness of the sub-page
2009-01-10 16:51:27 +00:00
2012-10-27 16:26:34 +01:00
this - > manually_changed_folding = true ;
2012-10-27 16:25:57 +01:00
this - > InvalidateData ( ) ;
2009-01-10 19:22:05 +00:00
return ;
}
2008-01-04 03:11:36 +00:00
2014-06-01 13:14:32 +01:00
SettingEntry * pe = dynamic_cast < SettingEntry * > ( clicked_entry ) ;
2019-04-10 22:07:06 +01:00
assert ( pe ! = nullptr ) ;
2021-05-23 10:37:56 +01:00
const IntSettingDesc * sd = pe - > setting ;
2008-05-15 22:48:47 +01:00
2009-01-10 19:22:05 +00:00
/* return if action is only active in network, or only settable by server */
2012-12-05 19:35:09 +00:00
if ( ! sd - > IsEditable ( ) ) {
2012-05-12 11:13:03 +01:00
this - > SetDisplayedHelpText ( pe ) ;
return ;
}
2009-01-10 19:22:05 +00:00
2023-05-08 18:01:06 +01:00
int32_t value = sd - > Read ( ResolveObject ( settings_ptr , sd ) ) ;
2009-01-10 19:22:05 +00:00
2012-06-01 16:19:38 +01:00
/* clicked on the icon on the left side. Either scroller, bool on/off or dropdown */
2021-06-03 20:18:29 +01:00
if ( x < SETTING_BUTTON_WIDTH & & ( sd - > flags & SF_GUI_DROPDOWN ) ) {
2012-06-01 16:19:38 +01:00
this - > SetDisplayedHelpText ( pe ) ;
if ( this - > valuedropdown_entry = = pe ) {
/* unclick the dropdown */
2023-06-02 14:27:06 +01:00
this - > CloseChildWindows ( WC_DROPDOWN_MENU ) ;
2012-06-01 16:19:38 +01:00
this - > closing_dropdown = false ;
this - > valuedropdown_entry - > SetButtons ( 0 ) ;
2019-04-10 22:07:06 +01:00
this - > valuedropdown_entry = nullptr ;
2012-06-01 16:19:38 +01:00
} else {
2019-04-10 22:07:06 +01:00
if ( this - > valuedropdown_entry ! = nullptr ) this - > valuedropdown_entry - > SetButtons ( 0 ) ;
2012-06-01 16:19:38 +01:00
this - > closing_dropdown = false ;
const NWidgetBase * wid = this - > GetWidget < NWidgetBase > ( WID_GS_OPTIONSPANEL ) ;
2023-05-12 18:02:51 +01:00
int rel_y = ( pt . y - wid - > pos_y - WidgetDimensions : : scaled . framerect . top ) % wid - > resize_y ;
2012-06-01 16:19:38 +01:00
Rect wi_rect ;
wi_rect . left = pt . x - ( _current_text_dir = = TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x ) ;
wi_rect . right = wi_rect . left + SETTING_BUTTON_WIDTH - 1 ;
wi_rect . top = pt . y - rel_y + ( SETTING_HEIGHT - SETTING_BUTTON_HEIGHT ) / 2 ;
wi_rect . bottom = wi_rect . top + SETTING_BUTTON_HEIGHT - 1 ;
/* For dropdowns we also have to check the y position thoroughly, the mouse may not above the just opening dropdown */
if ( pt . y > = wi_rect . top & & pt . y < = wi_rect . bottom ) {
this - > valuedropdown_entry = pe ;
this - > valuedropdown_entry - > SetButtons ( SEF_LEFT_DEPRESSED ) ;
2019-04-02 20:31:24 +01:00
DropDownList list ;
2021-05-23 09:29:38 +01:00
for ( int i = sd - > min ; i < = ( int ) sd - > max ; i + + ) {
2023-10-20 18:40:48 +01:00
list . push_back ( std : : make_unique < DropDownListStringItem > ( sd - > str_val + i - sd - > min , i , false ) ) ;
2012-06-01 16:19:38 +01:00
}
2023-09-20 20:26:42 +01:00
ShowDropDownListAt ( this , std : : move ( list ) , value , WID_GS_SETTING_DROPDOWN , wi_rect , COLOUR_ORANGE ) ;
2012-06-01 16:19:38 +01:00
}
}
this - > SetDirty ( ) ;
} else if ( x < SETTING_BUTTON_WIDTH ) {
2012-05-12 11:13:03 +01:00
this - > SetDisplayedHelpText ( pe ) ;
2023-05-08 18:01:06 +01:00
int32_t oldvalue = value ;
2009-01-10 19:22:05 +00:00
2021-05-23 18:27:46 +01:00
if ( sd - > IsBoolSetting ( ) ) {
value ^ = 1 ;
} else {
/* Add a dynamic step-size to the scroller. In a maximum of
* 50 - steps you should be able to get from min to max ,
* unless specified otherwise in the ' interval ' variable
* of the current setting . */
2023-05-08 18:01:06 +01:00
uint32_t step = ( sd - > interval = = 0 ) ? ( ( sd - > max - sd - > min ) / 50 ) : sd - > interval ;
2021-05-23 18:27:46 +01:00
if ( step = = 0 ) step = 1 ;
/* don't allow too fast scrolling */
if ( ( this - > flags & WF_TIMEOUT ) & & this - > timeout_timer > 1 ) {
_left_button_clicked = false ;
return ;
}
2004-08-16 22:02:06 +01:00
2021-05-23 18:27:46 +01:00
/* Increase or decrease the value and clamp it to extremes */
if ( x > = SETTING_BUTTON_WIDTH / 2 ) {
value + = step ;
if ( sd - > min < 0 ) {
2023-05-08 18:01:06 +01:00
assert ( ( int32_t ) sd - > max > = 0 ) ;
if ( value > ( int32_t ) sd - > max ) value = ( int32_t ) sd - > max ;
2009-01-10 19:22:05 +00:00
} else {
2023-05-08 18:01:06 +01:00
if ( ( uint32_t ) value > sd - > max ) value = ( int32_t ) sd - > max ;
2008-05-15 22:48:47 +01:00
}
2021-05-23 18:27:46 +01:00
if ( value < sd - > min ) value = sd - > min ; // skip between "disabled" and minimum
} else {
value - = step ;
2021-06-03 20:18:29 +01:00
if ( value < sd - > min ) value = ( sd - > flags & SF_GUI_0_IS_SPECIAL ) ? 0 : sd - > min ;
2021-05-23 18:27:46 +01:00
}
2009-01-10 19:22:05 +00:00
2021-05-23 18:27:46 +01:00
/* Set up scroller timeout for numeric values */
if ( value ! = oldvalue ) {
if ( this - > clicked_entry ! = nullptr ) { // Release previous buttons if any
this - > clicked_entry - > SetButtons ( 0 ) ;
2008-05-15 22:48:47 +01:00
}
2021-05-23 18:27:46 +01:00
this - > clicked_entry = pe ;
this - > clicked_entry - > SetButtons ( ( x > = SETTING_BUTTON_WIDTH / 2 ) ! = ( _current_text_dir = = TD_RTL ) ? SEF_RIGHT_DEPRESSED : SEF_LEFT_DEPRESSED ) ;
this - > SetTimeout ( ) ;
_left_button_clicked = false ;
2010-08-01 19:53:30 +01:00
}
2009-01-10 19:22:05 +00:00
}
if ( value ! = oldvalue ) {
2021-05-18 19:57:44 +01:00
SetSettingValue ( sd , value ) ;
2009-01-10 19:22:05 +00:00
this - > SetDirty ( ) ;
}
} else {
2012-05-12 11:13:03 +01:00
/* Only open editbox if clicked for the second time, and only for types where it is sensible for. */
2021-06-03 20:18:29 +01:00
if ( this - > last_clicked = = pe & & ! sd - > IsBoolSetting ( ) & & ! ( sd - > flags & SF_GUI_DROPDOWN ) ) {
2023-05-08 18:01:06 +01:00
int64_t value64 = value ;
2009-01-10 19:22:05 +00:00
/* Show the correct currency-translated value */
2021-06-03 20:18:29 +01:00
if ( sd - > flags & SF_GUI_CURRENCY ) value64 * = _currency - > rate ;
2009-01-10 19:22:05 +00:00
2022-11-02 19:54:07 +00:00
CharSetFilter charset_filter = CS_NUMERAL ; //default, only numeric input allowed
if ( sd - > min < 0 ) charset_filter = CS_NUMERAL_SIGNED ; // special case, also allow '-' sign for negative input
2009-01-10 19:22:05 +00:00
this - > valuewindow_entry = pe ;
2020-12-16 20:56:32 +00:00
SetDParam ( 0 , value64 ) ;
/* Limit string length to 14 so that MAX_INT32 * max currency rate doesn't exceed MAX_INT64. */
2022-11-02 19:54:07 +00:00
ShowQueryString ( STR_JUST_INT , STR_CONFIG_SETTING_QUERY_CAPTION , 15 , this , charset_filter , QSF_ENABLE_DEFAULT ) ;
2009-01-10 19:22:05 +00:00
}
2012-05-12 11:13:03 +01:00
this - > SetDisplayedHelpText ( pe ) ;
2008-05-15 22:48:47 +01:00
}
}
2004-08-09 18:04:08 +01:00
2019-03-04 07:49:37 +00:00
void OnTimeout ( ) override
2008-05-15 22:48:47 +01:00
{
2019-04-10 22:07:06 +01:00
if ( this - > clicked_entry ! = nullptr ) { // On timeout, release any depressed buttons
2009-01-10 16:42:28 +00:00
this - > clicked_entry - > SetButtons ( 0 ) ;
2019-04-10 22:07:06 +01:00
this - > clicked_entry = nullptr ;
2009-01-10 16:42:28 +00:00
this - > SetDirty ( ) ;
}
2008-05-15 22:48:47 +01:00
}
2004-08-09 18:04:08 +01:00
2019-03-04 07:49:37 +00:00
void OnQueryTextFinished ( char * str ) override
2008-05-15 22:48:47 +01:00
{
2010-01-23 19:33:18 +00:00
/* The user pressed cancel */
2019-04-10 22:07:06 +01:00
if ( str = = nullptr ) return ;
2010-01-23 19:33:18 +00:00
2019-04-10 22:07:06 +01:00
assert ( this - > valuewindow_entry ! = nullptr ) ;
2021-05-23 10:37:56 +01:00
const IntSettingDesc * sd = this - > valuewindow_entry - > setting ;
2010-01-23 19:33:18 +00:00
2023-05-08 18:01:06 +01:00
int32_t value ;
2008-05-15 22:48:47 +01:00
if ( ! StrEmpty ( str ) ) {
2020-12-16 20:56:32 +00:00
long long llvalue = atoll ( str ) ;
2006-03-02 01:41:25 +00:00
2008-05-15 22:48:47 +01:00
/* Save the correct currency-translated value */
2021-06-03 20:18:29 +01:00
if ( sd - > flags & SF_GUI_CURRENCY ) llvalue / = _currency - > rate ;
2020-12-16 20:56:32 +00:00
2023-04-29 08:25:51 +01:00
value = ClampTo < int32_t > ( llvalue ) ;
2010-01-23 19:33:18 +00:00
} else {
2021-05-22 20:09:30 +01:00
value = sd - > def ;
2010-01-23 19:33:18 +00:00
}
2004-08-09 18:04:08 +01:00
2021-05-18 19:57:44 +01:00
SetSettingValue ( this - > valuewindow_entry - > setting , value ) ;
2010-01-23 19:33:18 +00:00
this - > SetDirty ( ) ;
2004-08-09 18:04:08 +01:00
}
2009-01-03 11:24:27 +00:00
2019-03-04 07:49:37 +00:00
void OnDropdownSelect ( int widget , int index ) override
2012-06-01 16:19:38 +01:00
{
2012-12-26 17:42:29 +00:00
switch ( widget ) {
case WID_GS_RESTRICT_DROPDOWN :
2012-12-26 17:44:42 +00:00
this - > filter . mode = ( RestrictionMode ) index ;
if ( this - > filter . mode = = RM_CHANGED_AGAINST_DEFAULT | |
this - > filter . mode = = RM_CHANGED_AGAINST_NEW ) {
2012-12-26 17:42:29 +00:00
if ( ! this - > manually_changed_folding ) {
/* Expand all when selecting 'changes'. Update the filter state first, in case it becomes less restrictive in some cases. */
2014-06-01 12:51:24 +01:00
GetSettingsTree ( ) . UpdateFilterState ( this - > filter , false ) ;
GetSettingsTree ( ) . UnFoldAll ( ) ;
2012-12-26 17:42:29 +00:00
}
} else {
/* Non-'changes' filter. Save as default. */
2012-12-26 17:44:42 +00:00
_settings_client . gui . settings_restriction_mode = this - > filter . mode ;
2012-11-08 11:20:32 +00:00
}
2012-12-26 17:42:29 +00:00
this - > InvalidateData ( ) ;
break ;
2012-10-29 19:53:13 +00:00
2012-12-26 17:47:02 +00:00
case WID_GS_TYPE_DROPDOWN :
this - > filter . type = ( SettingType ) index ;
this - > InvalidateData ( ) ;
break ;
2023-09-20 20:26:42 +01:00
case WID_GS_SETTING_DROPDOWN :
/* Deal with drop down boxes on the panel. */
assert ( this - > valuedropdown_entry ! = nullptr ) ;
const IntSettingDesc * sd = this - > valuedropdown_entry - > setting ;
assert ( sd - > flags & SF_GUI_DROPDOWN ) ;
2012-12-26 17:42:29 +00:00
2023-09-20 20:26:42 +01:00
SetSettingValue ( sd , index ) ;
this - > SetDirty ( ) ;
2012-12-26 17:42:29 +00:00
break ;
2012-06-01 16:19:38 +01:00
}
}
2019-03-04 07:49:37 +00:00
void OnDropdownClose ( Point pt , int widget , int index , bool instant_close ) override
2012-06-01 16:19:38 +01:00
{
2023-09-20 20:26:42 +01:00
if ( widget ! = WID_GS_SETTING_DROPDOWN ) {
2012-10-29 19:53:13 +00:00
/* Normally the default implementation of OnDropdownClose() takes care of
2012-12-26 17:42:29 +00:00
* a few things . We want that behaviour here too , but only for
* " normal " dropdown boxes . The special dropdown boxes added for every
2012-10-29 19:53:13 +00:00
* setting that needs one can ' t have this call . */
Window : : OnDropdownClose ( pt , widget , index , instant_close ) ;
2012-12-26 17:42:29 +00:00
} else {
/* We cannot raise the dropdown button just yet. OnClick needs some hint, whether
* the same dropdown button was clicked again , and then not open the dropdown again .
* So , we only remember that it was closed , and process it on the next OnPaint , which is
* after OnClick . */
2019-04-10 22:07:06 +01:00
assert ( this - > valuedropdown_entry ! = nullptr ) ;
2012-12-26 17:42:29 +00:00
this - > closing_dropdown = true ;
this - > SetDirty ( ) ;
2012-10-29 19:53:13 +00:00
}
2012-06-01 16:19:38 +01:00
}
2023-09-16 21:20:53 +01:00
void OnInvalidateData ( [[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true ) override
2012-10-27 16:25:57 +01:00
{
if ( ! gui_scope ) return ;
2014-02-09 13:05:46 +00:00
/* Update which settings are to be visible. */
RestrictionMode min_level = ( this - > filter . mode < = RM_ALL ) ? this - > filter . mode : RM_BASIC ;
this - > filter . min_cat = min_level ;
this - > filter . type_hides = false ;
2014-06-01 12:51:24 +01:00
GetSettingsTree ( ) . UpdateFilterState ( this - > filter , false ) ;
2012-10-27 16:26:17 +01:00
2014-02-09 13:05:46 +00:00
if ( this - > filter . string . IsEmpty ( ) ) {
this - > warn_missing = WHR_NONE ;
} else if ( min_level < this - > filter . min_cat ) {
this - > warn_missing = this - > filter . type_hides ? WHR_CATEGORY_TYPE : WHR_CATEGORY ;
} else {
this - > warn_missing = this - > filter . type_hides ? WHR_TYPE : WHR_NONE ;
}
2014-06-01 12:51:24 +01:00
this - > vscroll - > SetCount ( GetSettingsTree ( ) . Length ( ) + this - > warn_lines ) ;
2012-10-27 16:25:57 +01:00
2019-04-10 22:07:06 +01:00
if ( this - > last_clicked ! = nullptr & & ! GetSettingsTree ( ) . IsVisible ( this - > last_clicked ) ) {
this - > SetDisplayedHelpText ( nullptr ) ;
2012-10-27 16:25:57 +01:00
}
bool all_folded = true ;
bool all_unfolded = true ;
2014-06-01 12:51:24 +01:00
GetSettingsTree ( ) . GetFoldingState ( all_folded , all_unfolded ) ;
2012-10-27 16:25:57 +01:00
this - > SetWidgetDisabledState ( WID_GS_EXPAND_ALL , all_unfolded ) ;
this - > SetWidgetDisabledState ( WID_GS_COLLAPSE_ALL , all_folded ) ;
}
2019-03-04 07:49:37 +00:00
void OnEditboxChanged ( int wid ) override
2012-10-27 16:26:17 +01:00
{
2012-11-13 21:46:40 +00:00
if ( wid = = WID_GS_FILTER ) {
2012-12-26 17:44:42 +00:00
this - > filter . string . SetFilterTerm ( this - > filter_editbox . text . buf ) ;
if ( ! this - > filter . string . IsEmpty ( ) & & ! this - > manually_changed_folding ) {
2012-11-13 21:46:40 +00:00
/* User never expanded/collapsed single pages and entered a filter term.
* Expand everything , to save weird expand clicks , */
2014-06-01 12:51:24 +01:00
GetSettingsTree ( ) . UnFoldAll ( ) ;
2012-11-13 21:46:40 +00:00
}
this - > InvalidateData ( ) ;
2012-10-27 16:26:34 +01:00
}
2012-10-27 16:26:17 +01:00
}
2019-03-04 07:49:37 +00:00
void OnResize ( ) override
2009-01-03 11:24:27 +00:00
{
2022-09-23 09:36:22 +01:00
this - > vscroll - > SetCapacityFromWidget ( this , WID_GS_OPTIONSPANEL , WidgetDimensions : : scaled . framerect . Vertical ( ) ) ;
2009-01-03 11:24:27 +00:00
}
2008-05-15 22:48:47 +01:00
} ;
2019-04-10 22:07:06 +01:00
GameSettings * GameSettingsWindow : : settings_ptr = nullptr ;
2004-08-09 18:04:08 +01:00
2009-04-26 08:43:19 +01:00
static const NWidgetPart _nested_settings_selection_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_MAUVE ) ,
2014-10-09 22:16:29 +01:00
NWidget ( WWT_CAPTION , COLOUR_MAUVE ) , SetDataTip ( STR_CONFIG_SETTING_TREE_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2013-05-26 20:30:07 +01:00
NWidget ( WWT_DEFSIZEBOX , COLOUR_MAUVE ) ,
2009-04-26 08:43:19 +01:00
EndContainer ( ) ,
2012-10-27 16:26:17 +01:00
NWidget ( WWT_PANEL , COLOUR_MAUVE ) ,
2022-09-23 09:36:22 +01:00
NWidget ( NWID_VERTICAL ) , SetPIP ( WidgetDimensions : : unscaled . frametext . top , WidgetDimensions : : unscaled . vsep_normal , WidgetDimensions : : unscaled . frametext . bottom ) ,
NWidget ( NWID_HORIZONTAL ) , SetPIP ( WidgetDimensions : : unscaled . frametext . left , WidgetDimensions : : unscaled . hsep_wide , WidgetDimensions : : unscaled . frametext . right ) ,
2014-02-09 13:04:50 +00:00
NWidget ( WWT_TEXT , COLOUR_MAUVE , WID_GS_RESTRICT_CATEGORY ) , SetDataTip ( STR_CONFIG_SETTING_RESTRICT_CATEGORY , STR_NULL ) ,
2023-04-25 10:03:48 +01:00
NWidget ( WWT_DROPDOWN , COLOUR_MAUVE , WID_GS_RESTRICT_DROPDOWN ) , SetMinimalSize ( 100 , 12 ) , SetDataTip ( STR_JUST_STRING , STR_CONFIG_SETTING_RESTRICT_DROPDOWN_HELPTEXT ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) ,
2014-02-09 13:04:50 +00:00
EndContainer ( ) ,
2022-09-23 09:36:22 +01:00
NWidget ( NWID_HORIZONTAL ) , SetPIP ( WidgetDimensions : : unscaled . frametext . left , WidgetDimensions : : unscaled . hsep_wide , WidgetDimensions : : unscaled . frametext . right ) ,
2014-02-09 13:04:50 +00:00
NWidget ( WWT_TEXT , COLOUR_MAUVE , WID_GS_RESTRICT_TYPE ) , SetDataTip ( STR_CONFIG_SETTING_RESTRICT_TYPE , STR_NULL ) ,
2023-04-25 10:03:48 +01:00
NWidget ( WWT_DROPDOWN , COLOUR_MAUVE , WID_GS_TYPE_DROPDOWN ) , SetMinimalSize ( 100 , 12 ) , SetDataTip ( STR_JUST_STRING , STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) ,
2012-12-26 17:47:02 +00:00
EndContainer ( ) ,
2022-09-23 09:36:22 +01:00
NWidget ( NWID_HORIZONTAL ) , SetPIP ( WidgetDimensions : : unscaled . frametext . left , WidgetDimensions : : unscaled . hsep_wide , WidgetDimensions : : unscaled . frametext . right ) ,
2022-10-02 16:04:16 +01:00
NWidget ( WWT_TEXT , COLOUR_MAUVE ) , SetFill ( 0 , 1 ) , SetDataTip ( STR_CONFIG_SETTING_FILTER_TITLE , STR_NULL ) ,
NWidget ( WWT_EDITBOX , COLOUR_MAUVE , WID_GS_FILTER ) , SetMinimalSize ( 50 , 12 ) , SetDataTip ( STR_LIST_FILTER_OSKTITLE , STR_LIST_FILTER_TOOLTIP ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) ,
EndContainer ( ) ,
2012-10-27 16:26:17 +01:00
EndContainer ( ) ,
EndContainer ( ) ,
2009-04-26 08:43:19 +01:00
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 18:27:50 +00:00
NWidget ( WWT_PANEL , COLOUR_MAUVE , WID_GS_OPTIONSPANEL ) , SetMinimalSize ( 400 , 174 ) , SetScrollbar ( WID_GS_SCROLLBAR ) , EndContainer ( ) ,
2014-07-08 21:06:45 +01:00
NWidget ( NWID_VSCROLLBAR , COLOUR_MAUVE , WID_GS_SCROLLBAR ) ,
2012-05-12 11:13:03 +01:00
EndContainer ( ) ,
2022-10-02 16:04:16 +01:00
NWidget ( WWT_PANEL , COLOUR_MAUVE ) ,
2012-05-12 11:13:03 +01:00
NWidget ( WWT_EMPTY , INVALID_COLOUR , WID_GS_HELP_TEXT ) , SetMinimalSize ( 300 , 25 ) , SetFill ( 1 , 1 ) , SetResize ( 1 , 0 ) ,
2022-09-23 09:36:22 +01:00
SetPadding ( WidgetDimensions : : unscaled . frametext ) ,
2014-09-20 11:23:38 +01:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_MAUVE , WID_GS_EXPAND_ALL ) , SetDataTip ( STR_CONFIG_SETTING_EXPAND_ALL , STR_NULL ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_MAUVE , WID_GS_COLLAPSE_ALL ) , SetDataTip ( STR_CONFIG_SETTING_COLLAPSE_ALL , STR_NULL ) ,
2021-04-06 11:47:44 +01:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_MAUVE , WID_GS_RESET_ALL ) , SetDataTip ( STR_CONFIG_SETTING_RESET_ALL , STR_NULL ) ,
2014-09-20 11:23:38 +01:00
NWidget ( WWT_PANEL , COLOUR_MAUVE ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) ,
2009-04-26 08:43:19 +01:00
EndContainer ( ) ,
2014-09-20 11:23:38 +01:00
NWidget ( WWT_RESIZEBOX , COLOUR_MAUVE ) ,
2009-04-26 08:43:19 +01:00
EndContainer ( ) ,
} ;
2013-05-26 20:23:42 +01:00
static WindowDesc _settings_selection_desc (
2013-05-26 20:25:01 +01:00
WDP_CENTER , " settings " , 510 , 450 ,
2007-02-01 15:49:12 +00:00
WC_GAME_OPTIONS , WC_NONE ,
2012-11-11 16:10:43 +00:00
0 ,
2023-09-03 21:54:13 +01:00
std : : begin ( _nested_settings_selection_widgets ) , std : : end ( _nested_settings_selection_widgets )
2009-03-15 15:12:06 +00:00
) ;
2004-08-09 18:04:08 +01:00
2010-12-11 15:14:28 +00:00
/** Open advanced settings window. */
2009-02-08 12:25:13 +00:00
void ShowGameSettings ( )
2004-08-09 18:04:08 +01:00
{
2021-05-17 14:46:38 +01:00
CloseWindowByClass ( WC_GAME_OPTIONS ) ;
2009-02-08 12:25:13 +00:00
new GameSettingsWindow ( & _settings_selection_desc ) ;
2004-08-09 18:04:08 +01:00
}
2004-11-21 22:44:13 +00:00
2006-08-02 19:36:53 +01:00
/**
* Draw [ < ] [ > ] boxes .
* @ param x the x position to draw
* @ param y the y position to draw
2008-08-08 04:37:00 +01:00
* @ param button_colour the colour of the button
2006-08-02 19:36:53 +01:00
* @ param state 0 = none clicked , 1 = first clicked , 2 = second clicked
* @ param clickable_left is the left button clickable ?
* @ param clickable_right is the right button clickable ?
*/
2008-08-08 07:02:06 +01:00
void DrawArrowButtons ( int x , int y , Colours button_colour , byte state , bool clickable_left , bool clickable_right )
2004-12-22 13:19:26 +00:00
{
2008-11-23 12:35:02 +00:00
int colour = _colour_gradient [ button_colour ] [ 2 ] ;
2014-10-04 21:34:43 +01:00
Dimension dim = NWidgetScrollbar : : GetHorizontalDimension ( ) ;
2006-08-02 19:36:53 +01:00
2022-09-23 09:36:22 +01:00
Rect lr = { x , y , x + ( int ) dim . width - 1 , y + ( int ) dim . height - 1 } ;
Rect rr = { x + ( int ) dim . width , y , x + ( int ) dim . width * 2 - 1 , y + ( int ) dim . height - 1 } ;
DrawFrameRect ( lr , button_colour , ( state = = 1 ) ? FR_LOWERED : FR_NONE ) ;
DrawFrameRect ( rr , button_colour , ( state = = 2 ) ? FR_LOWERED : FR_NONE ) ;
2022-11-14 22:27:30 +00:00
DrawSpriteIgnorePadding ( SPR_ARROW_LEFT , PAL_NONE , lr , ( state = = 1 ) , SA_CENTER ) ;
DrawSpriteIgnorePadding ( SPR_ARROW_RIGHT , PAL_NONE , rr , ( state = = 2 ) , SA_CENTER ) ;
2006-08-02 19:36:53 +01:00
/* Grey out the buttons that aren't clickable */
2010-11-13 09:56:25 +00:00
bool rtl = _current_text_dir = = TD_RTL ;
2009-11-20 14:52:55 +00:00
if ( rtl ? ! clickable_right : ! clickable_left ) {
2022-09-23 09:36:22 +01:00
GfxFillRect ( lr . Shrink ( WidgetDimensions : : scaled . bevel ) , colour , FILLRECT_CHECKER ) ;
2008-08-08 07:02:06 +01:00
}
2009-11-20 14:52:55 +00:00
if ( rtl ? ! clickable_left : ! clickable_right ) {
2022-09-23 09:36:22 +01:00
GfxFillRect ( rr . Shrink ( WidgetDimensions : : scaled . bevel ) , colour , FILLRECT_CHECKER ) ;
2008-08-08 07:02:06 +01:00
}
2004-12-22 13:19:26 +00:00
}
2012-06-01 15:41:47 +01:00
/**
* Draw a dropdown button .
* @ param x the x position to draw
* @ param y the y position to draw
* @ param button_colour the colour of the button
* @ param state true = lowered
* @ param clickable is the button clickable ?
*/
void DrawDropDownButton ( int x , int y , Colours button_colour , bool state , bool clickable )
{
int colour = _colour_gradient [ button_colour ] [ 2 ] ;
2022-09-23 09:36:22 +01:00
Rect r = { x , y , x + SETTING_BUTTON_WIDTH - 1 , y + SETTING_BUTTON_HEIGHT - 1 } ;
DrawFrameRect ( r , button_colour , state ? FR_LOWERED : FR_NONE ) ;
2022-11-14 22:27:30 +00:00
DrawSpriteIgnorePadding ( SPR_ARROW_DOWN , PAL_NONE , r , state , SA_CENTER ) ;
2012-06-01 15:41:47 +01:00
if ( ! clickable ) {
2022-09-23 09:36:22 +01:00
GfxFillRect ( r . Shrink ( WidgetDimensions : : scaled . bevel ) , colour , FILLRECT_CHECKER ) ;
2012-06-01 15:41:47 +01:00
}
}
2012-01-05 19:32:51 +00:00
/**
* Draw a toggle button .
* @ param x the x position to draw
* @ param y the y position to draw
* @ param state true = lowered
* @ param clickable is the button clickable ?
*/
void DrawBoolButton ( int x , int y , bool state , bool clickable )
{
static const Colours _bool_ctabs [ 2 ] [ 2 ] = { { COLOUR_CREAM , COLOUR_RED } , { COLOUR_DARK_GREEN , COLOUR_GREEN } } ;
2022-09-23 09:36:22 +01:00
Rect r = { x , y , x + SETTING_BUTTON_WIDTH - 1 , y + SETTING_BUTTON_HEIGHT - 1 } ;
DrawFrameRect ( r , _bool_ctabs [ state ] [ clickable ] , state ? FR_LOWERED : FR_NONE ) ;
2012-01-05 19:32:51 +00:00
}
2008-05-15 22:48:47 +01:00
struct CustomCurrencyWindow : Window {
int query_widget ;
2004-12-22 13:19:26 +00:00
2013-05-26 20:23:42 +01:00
CustomCurrencyWindow ( WindowDesc * desc ) : Window ( desc )
2008-05-15 22:48:47 +01:00
{
2013-05-26 20:23:42 +01:00
this - > InitNested ( ) ;
2009-04-25 18:51:10 +01:00
SetButtonState ( ) ;
2008-05-15 22:48:47 +01:00
}
2006-08-31 15:12:08 +01:00
2009-04-25 18:51:10 +01:00
void SetButtonState ( )
2008-05-15 22:48:47 +01:00
{
2011-12-16 18:27:50 +00:00
this - > SetWidgetDisabledState ( WID_CC_RATE_DOWN , _custom_currency . rate = = 1 ) ;
this - > SetWidgetDisabledState ( WID_CC_RATE_UP , _custom_currency . rate = = UINT16_MAX ) ;
this - > SetWidgetDisabledState ( WID_CC_YEAR_DOWN , _custom_currency . to_euro = = CF_NOEURO ) ;
2023-08-16 14:43:31 +01:00
this - > SetWidgetDisabledState ( WID_CC_YEAR_UP , _custom_currency . to_euro = = CalendarTime : : MAX_YEAR ) ;
2009-04-25 18:51:10 +01:00
}
2004-12-27 18:18:44 +00:00
2019-03-04 07:49:37 +00:00
void SetStringParameters ( int widget ) const override
2009-04-25 18:51:10 +01:00
{
2009-09-26 11:06:48 +01:00
switch ( widget ) {
2011-12-16 18:27:50 +00:00
case WID_CC_RATE : SetDParam ( 0 , 1 ) ; SetDParam ( 1 , 1 ) ; break ;
case WID_CC_SEPARATOR : SetDParamStr ( 0 , _custom_currency . separator ) ; break ;
case WID_CC_PREFIX : SetDParamStr ( 0 , _custom_currency . prefix ) ; break ;
case WID_CC_SUFFIX : SetDParamStr ( 0 , _custom_currency . suffix ) ; break ;
case WID_CC_YEAR :
2009-09-26 11:06:48 +01:00
SetDParam ( 0 , ( _custom_currency . to_euro ! = CF_NOEURO ) ? STR_CURRENCY_SWITCH_TO_EURO : STR_CURRENCY_SWITCH_TO_EURO_NEVER ) ;
SetDParam ( 1 , _custom_currency . to_euro ) ;
break ;
2011-12-16 18:27:50 +00:00
case WID_CC_PREVIEW :
2009-09-26 11:06:48 +01:00
SetDParam ( 0 , 10000 ) ;
break ;
2009-09-26 11:01:53 +01:00
}
}
2023-09-16 21:20:53 +01:00
void UpdateWidgetSize ( int widget , Dimension * size , [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension * resize ) override
2009-09-26 11:01:53 +01:00
{
switch ( widget ) {
/* Set the appropriate width for the edit 'buttons' */
2011-12-16 18:27:50 +00:00
case WID_CC_SEPARATOR_EDIT :
case WID_CC_PREFIX_EDIT :
case WID_CC_SUFFIX_EDIT :
size - > width = this - > GetWidget < NWidgetBase > ( WID_CC_RATE_DOWN ) - > smallest_x + this - > GetWidget < NWidgetBase > ( WID_CC_RATE_UP ) - > smallest_x ;
2009-09-26 11:01:53 +01:00
break ;
2009-09-26 11:06:48 +01:00
/* Make sure the window is wide enough for the widest exchange rate */
2011-12-16 18:27:50 +00:00
case WID_CC_RATE :
2009-09-26 11:06:48 +01:00
SetDParam ( 0 , 1 ) ;
SetDParam ( 1 , INT32_MAX ) ;
* size = GetStringBoundingBox ( STR_CURRENCY_EXCHANGE_RATE ) ;
break ;
2009-09-26 11:01:53 +01:00
}
}
2023-09-16 21:20:53 +01:00
void OnClick ( [[maybe_unused]] Point pt, int widget, [[maybe_unused]] int click_count ) override
2008-05-15 22:48:47 +01:00
{
2009-04-25 18:51:10 +01:00
int line = 0 ;
2008-05-15 22:48:47 +01:00
int len = 0 ;
StringID str = 0 ;
CharSetFilter afilter = CS_ALPHANUMERAL ;
2009-04-25 18:51:10 +01:00
switch ( widget ) {
2011-12-16 18:27:50 +00:00
case WID_CC_RATE_DOWN :
2009-04-25 18:51:10 +01:00
if ( _custom_currency . rate > 1 ) _custom_currency . rate - - ;
2011-12-16 18:27:50 +00:00
if ( _custom_currency . rate = = 1 ) this - > DisableWidget ( WID_CC_RATE_DOWN ) ;
this - > EnableWidget ( WID_CC_RATE_UP ) ;
2009-04-25 18:51:10 +01:00
break ;
2011-12-16 18:27:50 +00:00
case WID_CC_RATE_UP :
2009-04-25 18:51:10 +01:00
if ( _custom_currency . rate < UINT16_MAX ) _custom_currency . rate + + ;
2011-12-16 18:27:50 +00:00
if ( _custom_currency . rate = = UINT16_MAX ) this - > DisableWidget ( WID_CC_RATE_UP ) ;
this - > EnableWidget ( WID_CC_RATE_DOWN ) ;
2009-04-25 18:51:10 +01:00
break ;
2011-12-16 18:27:50 +00:00
case WID_CC_RATE :
2009-04-25 18:51:10 +01:00
SetDParam ( 0 , _custom_currency . rate ) ;
2009-07-23 20:31:50 +01:00
str = STR_JUST_INT ;
2009-04-25 18:51:10 +01:00
len = 5 ;
2011-12-16 18:27:50 +00:00
line = WID_CC_RATE ;
2009-04-25 18:51:10 +01:00
afilter = CS_NUMERAL ;
2008-05-15 22:48:47 +01:00
break ;
2005-11-14 19:48:04 +00:00
2011-12-16 18:27:50 +00:00
case WID_CC_SEPARATOR_EDIT :
case WID_CC_SEPARATOR :
2009-04-25 21:16:56 +01:00
SetDParamStr ( 0 , _custom_currency . separator ) ;
2008-07-17 14:47:04 +01:00
str = STR_JUST_RAW_STRING ;
2021-04-28 15:46:24 +01:00
len = 7 ;
2011-12-16 18:27:50 +00:00
line = WID_CC_SEPARATOR ;
2008-05-15 22:48:47 +01:00
break ;
2005-11-14 19:48:04 +00:00
2011-12-16 18:27:50 +00:00
case WID_CC_PREFIX_EDIT :
case WID_CC_PREFIX :
2008-07-17 14:47:04 +01:00
SetDParamStr ( 0 , _custom_currency . prefix ) ;
str = STR_JUST_RAW_STRING ;
2021-04-28 15:46:24 +01:00
len = 15 ;
2011-12-16 18:27:50 +00:00
line = WID_CC_PREFIX ;
2008-05-15 22:48:47 +01:00
break ;
2005-11-14 19:48:04 +00:00
2011-12-16 18:27:50 +00:00
case WID_CC_SUFFIX_EDIT :
case WID_CC_SUFFIX :
2008-07-17 14:47:04 +01:00
SetDParamStr ( 0 , _custom_currency . suffix ) ;
str = STR_JUST_RAW_STRING ;
2021-04-28 15:46:24 +01:00
len = 15 ;
2011-12-16 18:27:50 +00:00
line = WID_CC_SUFFIX ;
2008-05-15 22:48:47 +01:00
break ;
2004-12-27 18:18:44 +00:00
2011-12-16 18:27:50 +00:00
case WID_CC_YEAR_DOWN :
2023-08-11 14:32:42 +01:00
_custom_currency . to_euro = ( _custom_currency . to_euro < = MIN_EURO_YEAR ) ? CF_NOEURO : _custom_currency . to_euro - 1 ;
2011-12-16 18:27:50 +00:00
if ( _custom_currency . to_euro = = CF_NOEURO ) this - > DisableWidget ( WID_CC_YEAR_DOWN ) ;
this - > EnableWidget ( WID_CC_YEAR_UP ) ;
2009-04-25 18:51:10 +01:00
break ;
2011-12-16 18:27:50 +00:00
case WID_CC_YEAR_UP :
2023-08-16 14:43:31 +01:00
_custom_currency . to_euro = Clamp ( _custom_currency . to_euro + 1 , MIN_EURO_YEAR , CalendarTime : : MAX_YEAR ) ;
if ( _custom_currency . to_euro = = CalendarTime : : MAX_YEAR ) this - > DisableWidget ( WID_CC_YEAR_UP ) ;
2011-12-16 18:27:50 +00:00
this - > EnableWidget ( WID_CC_YEAR_DOWN ) ;
2009-04-25 18:51:10 +01:00
break ;
2011-12-16 18:27:50 +00:00
case WID_CC_YEAR :
2009-04-25 18:51:10 +01:00
SetDParam ( 0 , _custom_currency . to_euro ) ;
2009-07-23 20:31:50 +01:00
str = STR_JUST_INT ;
2009-04-25 18:51:10 +01:00
len = 7 ;
2011-12-16 18:27:50 +00:00
line = WID_CC_YEAR ;
2009-04-25 18:51:10 +01:00
afilter = CS_NUMERAL ;
2008-05-15 22:48:47 +01:00
break ;
}
2004-12-27 18:18:44 +00:00
2008-05-15 22:48:47 +01:00
if ( len ! = 0 ) {
this - > query_widget = line ;
2011-04-17 19:42:17 +01:00
ShowQueryString ( str , STR_CURRENCY_CHANGE_PARAMETER , len + 1 , this , afilter , QSF_NONE ) ;
2008-05-15 22:48:47 +01:00
}
2004-12-22 13:19:26 +00:00
2011-12-15 19:54:23 +00:00
this - > SetTimeout ( ) ;
2008-05-15 22:48:47 +01:00
this - > SetDirty ( ) ;
}
2008-05-10 09:58:52 +01:00
2019-03-04 07:49:37 +00:00
void OnQueryTextFinished ( char * str ) override
2008-05-15 22:48:47 +01:00
{
2019-04-10 22:07:06 +01:00
if ( str = = nullptr ) return ;
2004-12-22 13:19:26 +00:00
2008-05-15 22:48:47 +01:00
switch ( this - > query_widget ) {
2011-12-16 18:27:50 +00:00
case WID_CC_RATE :
2008-12-29 15:46:14 +00:00
_custom_currency . rate = Clamp ( atoi ( str ) , 1 , UINT16_MAX ) ;
2008-05-15 22:48:47 +01:00
break ;
2006-08-31 15:12:08 +01:00
2013-01-08 22:46:42 +00:00
case WID_CC_SEPARATOR : // Thousands separator
2021-04-28 15:46:24 +01:00
_custom_currency . separator = str ;
2008-05-15 22:48:47 +01:00
break ;
2006-08-31 15:12:08 +01:00
2011-12-16 18:27:50 +00:00
case WID_CC_PREFIX :
2021-04-28 15:46:24 +01:00
_custom_currency . prefix = str ;
2008-05-15 22:48:47 +01:00
break ;
2006-08-31 15:12:08 +01:00
2011-12-16 18:27:50 +00:00
case WID_CC_SUFFIX :
2021-04-28 15:46:24 +01:00
_custom_currency . suffix = str ;
2008-05-15 22:48:47 +01:00
break ;
2006-08-31 15:12:08 +01:00
2011-12-16 18:27:50 +00:00
case WID_CC_YEAR : { // Year to switch to euro
2023-08-11 14:32:42 +01:00
TimerGameCalendar : : Year val = atoi ( str ) ;
2006-08-31 15:12:08 +01:00
2023-08-16 14:43:31 +01:00
_custom_currency . to_euro = ( val < MIN_EURO_YEAR ? CF_NOEURO : std : : min ( val , CalendarTime : : MAX_YEAR ) ) ;
2008-05-15 22:48:47 +01:00
break ;
2008-01-04 02:32:58 +00:00
}
2008-05-15 22:48:47 +01:00
}
MarkWholeScreenDirty ( ) ;
2009-04-25 18:51:10 +01:00
SetButtonState ( ) ;
2008-05-15 22:48:47 +01:00
}
2006-08-31 15:12:08 +01:00
2019-03-04 07:49:37 +00:00
void OnTimeout ( ) override
2008-05-15 22:48:47 +01:00
{
this - > SetDirty ( ) ;
2004-12-22 13:19:26 +00:00
}
2008-05-15 22:48:47 +01:00
} ;
2004-12-22 13:19:26 +00:00
2009-04-26 08:43:19 +01:00
static const NWidgetPart _nested_cust_currency_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
NWidget ( WWT_CAPTION , COLOUR_GREY ) , SetDataTip ( STR_CURRENCY_WINDOW , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2009-04-26 08:43:19 +01:00
EndContainer ( ) ,
2009-11-24 21:13:36 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY ) ,
2009-09-26 11:01:53 +01:00
NWidget ( NWID_VERTICAL , NC_EQUALSIZE ) , SetPIP ( 7 , 3 , 0 ) ,
NWidget ( NWID_HORIZONTAL ) , SetPIP ( 10 , 0 , 5 ) ,
2011-12-16 18:27:50 +00:00
NWidget ( WWT_PUSHARROWBTN , COLOUR_YELLOW , WID_CC_RATE_DOWN ) , SetDataTip ( AWV_DECREASE , STR_CURRENCY_DECREASE_EXCHANGE_RATE_TOOLTIP ) ,
NWidget ( WWT_PUSHARROWBTN , COLOUR_YELLOW , WID_CC_RATE_UP ) , SetDataTip ( AWV_INCREASE , STR_CURRENCY_INCREASE_EXCHANGE_RATE_TOOLTIP ) ,
2009-09-26 11:01:53 +01:00
NWidget ( NWID_SPACER ) , SetMinimalSize ( 5 , 0 ) ,
2011-12-16 18:27:50 +00:00
NWidget ( WWT_TEXT , COLOUR_BLUE , WID_CC_RATE ) , SetDataTip ( STR_CURRENCY_EXCHANGE_RATE , STR_CURRENCY_SET_EXCHANGE_RATE_TOOLTIP ) , SetFill ( 1 , 0 ) ,
2009-09-26 11:01:53 +01:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) , SetPIP ( 10 , 0 , 5 ) ,
2011-12-16 18:27:50 +00:00
NWidget ( WWT_PUSHBTN , COLOUR_DARK_BLUE , WID_CC_SEPARATOR_EDIT ) , SetDataTip ( 0x0 , STR_CURRENCY_SET_CUSTOM_CURRENCY_SEPARATOR_TOOLTIP ) , SetFill ( 0 , 1 ) ,
2009-09-26 11:01:53 +01:00
NWidget ( NWID_SPACER ) , SetMinimalSize ( 5 , 0 ) ,
2011-12-16 18:27:50 +00:00
NWidget ( WWT_TEXT , COLOUR_BLUE , WID_CC_SEPARATOR ) , SetDataTip ( STR_CURRENCY_SEPARATOR , STR_CURRENCY_SET_CUSTOM_CURRENCY_SEPARATOR_TOOLTIP ) , SetFill ( 1 , 0 ) ,
2009-09-26 11:01:53 +01:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) , SetPIP ( 10 , 0 , 5 ) ,
2011-12-16 18:27:50 +00:00
NWidget ( WWT_PUSHBTN , COLOUR_DARK_BLUE , WID_CC_PREFIX_EDIT ) , SetDataTip ( 0x0 , STR_CURRENCY_SET_CUSTOM_CURRENCY_PREFIX_TOOLTIP ) , SetFill ( 0 , 1 ) ,
2009-09-26 11:01:53 +01:00
NWidget ( NWID_SPACER ) , SetMinimalSize ( 5 , 0 ) ,
2011-12-16 18:27:50 +00:00
NWidget ( WWT_TEXT , COLOUR_BLUE , WID_CC_PREFIX ) , SetDataTip ( STR_CURRENCY_PREFIX , STR_CURRENCY_SET_CUSTOM_CURRENCY_PREFIX_TOOLTIP ) , SetFill ( 1 , 0 ) ,
2009-09-26 11:01:53 +01:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) , SetPIP ( 10 , 0 , 5 ) ,
2011-12-16 18:27:50 +00:00
NWidget ( WWT_PUSHBTN , COLOUR_DARK_BLUE , WID_CC_SUFFIX_EDIT ) , SetDataTip ( 0x0 , STR_CURRENCY_SET_CUSTOM_CURRENCY_SUFFIX_TOOLTIP ) , SetFill ( 0 , 1 ) ,
2009-09-26 11:01:53 +01:00
NWidget ( NWID_SPACER ) , SetMinimalSize ( 5 , 0 ) ,
2011-12-16 18:27:50 +00:00
NWidget ( WWT_TEXT , COLOUR_BLUE , WID_CC_SUFFIX ) , SetDataTip ( STR_CURRENCY_SUFFIX , STR_CURRENCY_SET_CUSTOM_CURRENCY_SUFFIX_TOOLTIP ) , SetFill ( 1 , 0 ) ,
2009-09-26 11:01:53 +01:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) , SetPIP ( 10 , 0 , 5 ) ,
2011-12-16 18:27:50 +00:00
NWidget ( WWT_PUSHARROWBTN , COLOUR_YELLOW , WID_CC_YEAR_DOWN ) , SetDataTip ( AWV_DECREASE , STR_CURRENCY_DECREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP ) ,
NWidget ( WWT_PUSHARROWBTN , COLOUR_YELLOW , WID_CC_YEAR_UP ) , SetDataTip ( AWV_INCREASE , STR_CURRENCY_INCREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP ) ,
2009-09-26 11:01:53 +01:00
NWidget ( NWID_SPACER ) , SetMinimalSize ( 5 , 0 ) ,
2023-06-13 19:00:26 +01:00
NWidget ( WWT_TEXT , COLOUR_BLUE , WID_CC_YEAR ) , SetDataTip ( STR_JUST_STRING1 , STR_CURRENCY_SET_CUSTOM_CURRENCY_TO_EURO_TOOLTIP ) , SetFill ( 1 , 0 ) ,
2009-09-26 11:01:53 +01:00
EndContainer ( ) ,
2009-04-26 08:43:19 +01:00
EndContainer ( ) ,
2011-12-16 18:27:50 +00:00
NWidget ( WWT_LABEL , COLOUR_BLUE , WID_CC_PREVIEW ) ,
2009-08-05 18:59:21 +01:00
SetDataTip ( STR_CURRENCY_PREVIEW , STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP ) , SetPadding ( 15 , 1 , 18 , 2 ) ,
2009-04-26 08:43:19 +01:00
EndContainer ( ) ,
} ;
2013-05-26 20:23:42 +01:00
static WindowDesc _cust_currency_desc (
2019-04-10 22:07:06 +01:00
WDP_CENTER , nullptr , 0 , 0 ,
2007-02-01 15:49:12 +00:00
WC_CUSTOM_CURRENCY , WC_NONE ,
2012-11-11 16:10:43 +00:00
0 ,
2023-09-03 21:54:13 +01:00
std : : begin ( _nested_cust_currency_widgets ) , std : : end ( _nested_cust_currency_widgets )
2009-03-15 15:12:06 +00:00
) ;
2004-12-22 13:19:26 +00:00
2010-12-11 15:14:28 +00:00
/** Open custom currency window. */
2007-03-07 11:47:46 +00:00
static void ShowCustCurrency ( )
2004-12-22 13:19:26 +00:00
{
2021-05-17 14:46:38 +01:00
CloseWindowById ( WC_CUSTOM_CURRENCY , 0 ) ;
2008-05-15 22:48:47 +01:00
new CustomCurrencyWindow ( & _cust_currency_desc ) ;
2004-12-22 13:19:26 +00:00
}