2023-01-05 13:25:55 +01:00
/**************************************************************************/
/* editor_settings.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
2018-01-05 00:50:27 +01:00
2014-02-10 02:10:30 +01:00
# include "editor_settings.h"
2017-01-16 08:04:19 +01:00
2020-11-07 23:33:38 +01:00
# include "core/config/project_settings.h"
2022-02-14 14:00:03 +01:00
# include "core/input/input_event.h"
2020-12-07 12:31:51 +01:00
# include "core/input/input_map.h"
2022-02-14 14:00:03 +01:00
# include "core/input/shortcut.h"
2018-09-15 14:45:54 +02:00
# include "core/io/certs_compressed.gen.h"
2021-06-11 14:51:48 +02:00
# include "core/io/dir_access.h"
# include "core/io/file_access.h"
2019-12-24 08:17:23 +01:00
# include "core/io/ip.h"
2017-08-26 17:46:49 +02:00
# include "core/io/resource_loader.h"
# include "core/io/resource_saver.h"
2022-02-14 14:00:03 +01:00
# include "core/object/class_db.h"
2017-08-26 17:46:49 +02:00
# include "core/os/keyboard.h"
# include "core/os/os.h"
2024-08-15 09:00:47 +02:00
# include "core/string/translation_server.h"
2017-08-26 17:46:49 +02:00
# include "core/version.h"
# include "editor/editor_node.h"
2022-02-14 14:00:03 +01:00
# include "editor/editor_paths.h"
2024-02-16 00:18:28 +01:00
# include "editor/editor_property_name_processor.h"
2021-12-15 16:01:06 +01:00
# include "editor/editor_translation.h"
2023-04-11 01:14:18 +02:00
# include "editor/engine_update_label.h"
2024-02-16 00:18:28 +01:00
# include "scene/gui/color_picker.h"
2017-03-05 16:44:50 +01:00
# include "scene/main/node.h"
2017-06-27 03:58:03 +02:00
# include "scene/main/scene_tree.h"
2020-03-04 02:51:12 +01:00
# include "scene/main/window.h"
2014-02-10 02:10:30 +01:00
2017-10-28 15:40:55 +02:00
// PRIVATE METHODS
2014-02-10 02:10:30 +01:00
2020-04-02 01:20:12 +02:00
Ref < EditorSettings > EditorSettings : : singleton = nullptr ;
2014-02-10 02:10:30 +01:00
2017-10-28 15:40:55 +02:00
// Properties
2014-02-10 02:10:30 +01:00
2018-01-06 12:40:43 +01:00
bool EditorSettings : : _set ( const StringName & p_name , const Variant & p_value ) {
_THREAD_SAFE_METHOD_
bool changed = _set_only ( p_name , p_value ) ;
2024-08-17 19:23:06 +02:00
if ( changed & & initialized ) {
2021-10-15 14:34:11 +02:00
changed_settings . insert ( p_name ) ;
2021-07-17 23:22:52 +02:00
emit_signal ( SNAME ( " settings_changed " ) ) ;
2018-01-06 12:40:43 +01:00
}
return true ;
}
bool EditorSettings : : _set_only ( const StringName & p_name , const Variant & p_value ) {
2014-02-10 02:10:30 +01:00
_THREAD_SAFE_METHOD_
2016-06-05 02:31:29 +02:00
2020-12-07 12:31:51 +01:00
if ( p_name = = " shortcuts " ) {
2017-03-05 16:44:50 +01:00
Array arr = p_value ;
2021-06-21 03:34:50 +02:00
for ( int i = 0 ; i < arr . size ( ) ; i + + ) {
Dictionary dict = arr [ i ] ;
2022-09-29 11:53:28 +02:00
String shortcut_name = dict [ " name " ] ;
2021-06-21 03:34:50 +02:00
Array shortcut_events = dict [ " shortcuts " ] ;
2016-06-05 02:31:29 +02:00
2020-09-09 21:53:24 +02:00
Ref < Shortcut > sc ;
2021-06-18 00:03:09 +02:00
sc . instantiate ( ) ;
2021-06-21 03:34:50 +02:00
sc - > set_events ( shortcut_events ) ;
2022-09-29 11:53:28 +02:00
add_shortcut ( shortcut_name , sc ) ;
2016-06-05 02:31:29 +02:00
}
2020-12-07 12:31:51 +01:00
return false ;
} else if ( p_name = = " builtin_action_overrides " ) {
Array actions_arr = p_value ;
for ( int i = 0 ; i < actions_arr . size ( ) ; i + + ) {
Dictionary action_dict = actions_arr [ i ] ;
2022-09-29 11:53:28 +02:00
String action_name = action_dict [ " name " ] ;
2020-12-07 12:31:51 +01:00
Array events = action_dict [ " events " ] ;
InputMap * im = InputMap : : get_singleton ( ) ;
2022-09-29 11:53:28 +02:00
im - > action_erase_events ( action_name ) ;
2020-12-07 12:31:51 +01:00
2022-09-29 11:53:28 +02:00
builtin_action_overrides [ action_name ] . clear ( ) ;
2020-12-07 12:31:51 +01:00
for ( int ev_idx = 0 ; ev_idx < events . size ( ) ; ev_idx + + ) {
2022-09-29 11:53:28 +02:00
im - > action_add_event ( action_name , events [ ev_idx ] ) ;
builtin_action_overrides [ action_name ] . push_back ( events [ ev_idx ] ) ;
2020-12-07 12:31:51 +01:00
}
}
2018-01-06 12:40:43 +01:00
return false ;
2016-06-05 02:31:29 +02:00
}
2017-12-29 11:03:29 +01:00
bool changed = false ;
2017-11-30 04:11:53 +01:00
if ( p_value . get_type ( ) = = Variant : : NIL ) {
2017-12-29 11:03:29 +01:00
if ( props . has ( p_name ) ) {
props . erase ( p_name ) ;
changed = true ;
}
2017-11-30 04:11:53 +01:00
} else {
2017-12-29 11:03:29 +01:00
if ( props . has ( p_name ) ) {
if ( p_value ! = props [ p_name ] . variant ) {
props [ p_name ] . variant = p_value ;
changed = true ;
}
} else {
2017-03-05 16:44:50 +01:00
props [ p_name ] = VariantContainer ( p_value , last_order + + ) ;
2017-12-29 11:03:29 +01:00
changed = true ;
}
2016-06-12 02:16:14 +02:00
if ( save_changed_setting ) {
2019-06-26 15:08:25 +02:00
if ( ! props [ p_name ] . save ) {
2017-12-29 11:03:29 +01:00
props [ p_name ] . save = true ;
changed = true ;
}
2016-06-12 02:16:14 +02:00
}
2014-02-10 02:10:30 +01:00
}
2018-01-06 12:40:43 +01:00
return changed ;
2014-02-10 02:10:30 +01:00
}
2017-08-26 17:46:49 +02:00
2017-03-05 16:44:50 +01:00
bool EditorSettings : : _get ( const StringName & p_name , Variant & r_ret ) const {
2014-02-10 02:10:30 +01:00
_THREAD_SAFE_METHOD_
2020-12-07 12:31:51 +01:00
if ( p_name = = " shortcuts " ) {
2021-06-21 03:34:50 +02:00
Array save_array ;
2022-05-08 10:09:19 +02:00
const HashMap < String , List < Ref < InputEvent > > > & builtin_list = InputMap : : get_singleton ( ) - > get_builtins ( ) ;
2021-06-21 03:34:50 +02:00
for ( const KeyValue < String , Ref < Shortcut > > & shortcut_definition : shortcuts ) {
Ref < Shortcut > sc = shortcut_definition . value ;
2016-06-05 02:31:29 +02:00
2021-10-13 04:33:53 +02:00
if ( builtin_list . has ( shortcut_definition . key ) ) {
2020-12-07 12:31:51 +01:00
// This shortcut was auto-generated from built in actions: don't save.
Fix various typos
Found via ` codespell -q 3 -S ./thirdparty,*.po,./DONORS.md -L ackward,ang,ans,ba,beng,cas,childs,childrens,dof,doubleclick,expct,fave,findn,gird,hist,inout,leapyear,lod,nd,numer,ois,ony,paket,seeked,sinc,switchs,te,uint,varn`
Update editor/import/resource_importer_layered_texture.cpp
Co-authored-by: Raul Santos <raulsntos@gmail.com>
Update doc/classes/TileSetScenesCollectionSource.xml
Co-authored-by: Raul Santos <raulsntos@gmail.com>
Update scene/gui/graph_edit.cpp
Co-authored-by: Raul Santos <raulsntos@gmail.com>
Update scene/resources/animation.cpp
Co-authored-by: Raul Santos <raulsntos@gmail.com>
Update scene/resources/animation.cpp
Co-authored-by: Raul Santos <raulsntos@gmail.com>
Update scene/resources/animation.cpp
Co-authored-by: Raul Santos <raulsntos@gmail.com>
Update scene/gui/rich_text_label.cpp
Co-authored-by: Raul Santos <raulsntos@gmail.com>
Revert previously committed change
2022-01-02 07:03:58 +01:00
// If the builtin is overridden, it will be saved in the "builtin_action_overrides" section below.
2020-12-07 12:31:51 +01:00
continue ;
}
2021-10-13 04:33:53 +02:00
Array shortcut_events = sc - > get_events ( ) ;
Dictionary dict ;
dict [ " name " ] = shortcut_definition . key ;
dict [ " shortcuts " ] = shortcut_events ;
if ( ! sc - > has_meta ( " original " ) ) {
// Getting the meta when it doesn't exist will return an empty array. If the 'shortcut_events' have been cleared,
2022-11-01 15:29:38 +01:00
// we still want save the shortcut in this case so that shortcuts that the user has customized are not reset,
2021-10-13 04:33:53 +02:00
// even if the 'original' has not been populated yet. This can happen when calling save() from the Project Manager.
save_array . push_back ( dict ) ;
continue ;
2021-06-21 03:34:50 +02:00
}
2016-07-04 00:13:45 +02:00
2021-06-21 03:34:50 +02:00
Array original_events = sc - > get_meta ( " original " ) ;
bool is_same = Shortcut : : is_event_array_equal ( original_events , shortcut_events ) ;
if ( is_same ) {
continue ; // Not changed from default; don't save.
2016-07-04 00:13:45 +02:00
}
2021-06-21 03:34:50 +02:00
save_array . push_back ( dict ) ;
2016-06-05 02:31:29 +02:00
}
2021-06-21 03:34:50 +02:00
r_ret = save_array ;
2016-06-05 02:31:29 +02:00
return true ;
2020-12-07 12:31:51 +01:00
} else if ( p_name = = " builtin_action_overrides " ) {
Array actions_arr ;
2021-06-21 03:34:50 +02:00
for ( const KeyValue < String , List < Ref < InputEvent > > > & action_override : builtin_action_overrides ) {
List < Ref < InputEvent > > events = action_override . value ;
2020-12-07 12:31:51 +01:00
Dictionary action_dict ;
2021-06-21 03:34:50 +02:00
action_dict [ " name " ] = action_override . key ;
2020-12-07 12:31:51 +01:00
2021-06-21 03:34:50 +02:00
// Convert the list to an array, and only keep key events as this is for the editor.
2020-12-07 12:31:51 +01:00
Array events_arr ;
2021-06-21 03:34:50 +02:00
for ( const Ref < InputEvent > & ie : events ) {
Ref < InputEventKey > iek = ie ;
if ( iek . is_valid ( ) ) {
events_arr . append ( iek ) ;
}
2020-12-07 12:31:51 +01:00
}
2021-06-21 03:34:50 +02:00
Array defaults_arr ;
List < Ref < InputEvent > > defaults = InputMap : : get_singleton ( ) - > get_builtins ( ) [ action_override . key ] ;
for ( const Ref < InputEvent > & default_input_event : defaults ) {
if ( default_input_event . is_valid ( ) ) {
defaults_arr . append ( default_input_event ) ;
}
}
bool same = Shortcut : : is_event_array_equal ( events_arr , defaults_arr ) ;
2020-12-07 12:31:51 +01:00
2021-06-21 03:34:50 +02:00
// Don't save if same as default.
if ( same ) {
continue ;
}
action_dict [ " events " ] = events_arr ;
2020-12-07 12:31:51 +01:00
actions_arr . push_back ( action_dict ) ;
}
r_ret = actions_arr ;
return true ;
2016-06-05 02:31:29 +02:00
}
2017-03-05 16:44:50 +01:00
const VariantContainer * v = props . getptr ( p_name ) ;
2017-01-05 23:41:36 +01:00
if ( ! v ) {
2019-11-07 09:44:15 +01:00
WARN_PRINT ( " EditorSettings::_get - Property not found: " + String ( p_name ) ) ;
2014-02-10 02:10:30 +01:00
return false ;
2017-01-05 23:41:36 +01:00
}
2014-02-10 02:10:30 +01:00
r_ret = v - > variant ;
return true ;
}
2017-09-25 05:26:41 +02:00
void EditorSettings : : _initial_set ( const StringName & p_name , const Variant & p_value ) {
set ( p_name , p_value ) ;
props [ p_name ] . initial = p_value ;
2017-11-20 18:34:13 +01:00
props [ p_name ] . has_default_value = true ;
2017-09-25 05:26:41 +02:00
}
2014-02-10 02:10:30 +01:00
struct _EVCSort {
String name ;
2020-11-24 10:12:55 +01:00
Variant : : Type type = Variant : : Type : : NIL ;
int order = 0 ;
bool save = false ;
bool restart_if_changed = false ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
bool operator < ( const _EVCSort & p_vcs ) const { return order < p_vcs . order ; }
2014-02-10 02:10:30 +01:00
} ;
void EditorSettings : : _get_property_list ( List < PropertyInfo > * p_list ) const {
_THREAD_SAFE_METHOD_
2022-05-13 15:04:37 +02:00
RBSet < _EVCSort > vclist ;
2014-02-10 02:10:30 +01:00
2022-05-08 10:09:19 +02:00
for ( const KeyValue < String , VariantContainer > & E : props ) {
const VariantContainer * v = & E . value ;
2014-02-10 02:10:30 +01:00
2020-05-14 16:41:43 +02:00
if ( v - > hide_from_editor ) {
2014-02-10 02:10:30 +01:00
continue ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
_EVCSort vc ;
2022-05-08 10:09:19 +02:00
vc . name = E . key ;
2017-03-05 16:44:50 +01:00
vc . order = v - > order ;
vc . type = v - > variant . get_type ( ) ;
vc . save = v - > save ;
2019-03-06 16:10:36 +01:00
/*if (vc.save) { this should be implemented, but lets do after 3.1 is out.
if ( v - > initial . get_type ( ) ! = Variant : : NIL & & v - > initial = = v - > variant ) {
vc . save = false ;
}
} */
2018-07-19 23:58:15 +02:00
vc . restart_if_changed = v - > restart_if_changed ;
2014-02-10 02:10:30 +01:00
vclist . insert ( vc ) ;
}
2022-05-19 01:43:40 +02:00
for ( const _EVCSort & E : vclist ) {
2021-07-01 03:24:34 +02:00
uint32_t pusage = PROPERTY_USAGE_NONE ;
2022-05-19 01:43:40 +02:00
if ( E . save | | ! optimize_save ) {
2021-07-01 03:24:34 +02:00
pusage | = PROPERTY_USAGE_STORAGE ;
2016-06-12 02:16:14 +02:00
}
2022-05-19 01:43:40 +02:00
if ( ! E . name . begins_with ( " _ " ) & & ! E . name . begins_with ( " projects/ " ) ) {
2021-07-01 03:24:34 +02:00
pusage | = PROPERTY_USAGE_EDITOR ;
2016-06-12 02:16:14 +02:00
} else {
2021-07-01 03:24:34 +02:00
pusage | = PROPERTY_USAGE_STORAGE ; //hiddens must always be saved
2016-06-12 02:16:14 +02:00
}
2014-02-10 02:10:30 +01:00
2022-05-19 01:43:40 +02:00
PropertyInfo pi ( E . type , E . name ) ;
2021-07-01 03:24:34 +02:00
pi . usage = pusage ;
2022-05-19 01:43:40 +02:00
if ( hints . has ( E . name ) ) {
pi = hints [ E . name ] ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
2022-05-19 01:43:40 +02:00
if ( E . restart_if_changed ) {
2018-07-19 23:58:15 +02:00
pi . usage | = PROPERTY_USAGE_RESTART_IF_CHANGED ;
}
2017-03-05 16:44:50 +01:00
p_list - > push_back ( pi ) ;
2014-02-10 02:10:30 +01:00
}
2016-06-05 02:31:29 +02:00
2021-11-03 23:06:17 +01:00
p_list - > push_back ( PropertyInfo ( Variant : : ARRAY , " shortcuts " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL ) ) ; //do not edit
p_list - > push_back ( PropertyInfo ( Variant : : ARRAY , " builtin_action_overrides " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-10-28 15:40:55 +02:00
void EditorSettings : : _add_property_info_bind ( const Dictionary & p_info ) {
ERR_FAIL_COND ( ! p_info . has ( " name " ) ) ;
ERR_FAIL_COND ( ! p_info . has ( " type " ) ) ;
2017-10-05 20:34:34 +02:00
2017-10-28 15:40:55 +02:00
PropertyInfo pinfo ;
pinfo . name = p_info [ " name " ] ;
ERR_FAIL_COND ( ! props . has ( pinfo . name ) ) ;
pinfo . type = Variant : : Type ( p_info [ " type " ] . operator int ( ) ) ;
ERR_FAIL_INDEX ( pinfo . type , Variant : : VARIANT_MAX ) ;
2014-02-10 02:10:30 +01:00
2020-05-14 16:41:43 +02:00
if ( p_info . has ( " hint " ) ) {
2017-10-28 15:40:55 +02:00
pinfo . hint = PropertyHint ( p_info [ " hint " ] . operator int ( ) ) ;
2020-05-14 16:41:43 +02:00
}
if ( p_info . has ( " hint_string " ) ) {
2017-10-28 15:40:55 +02:00
pinfo . hint_string = p_info [ " hint_string " ] ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
2017-10-28 15:40:55 +02:00
add_property_hint ( pinfo ) ;
2014-02-10 02:10:30 +01:00
}
2017-10-28 15:40:55 +02:00
// Default configs
2017-10-28 23:25:28 +02:00
bool EditorSettings : : has_default_value ( const String & p_setting ) const {
_THREAD_SAFE_METHOD_
2020-05-14 16:41:43 +02:00
if ( ! props . has ( p_setting ) ) {
2017-10-28 23:25:28 +02:00
return false ;
2020-05-14 16:41:43 +02:00
}
2017-11-20 18:34:13 +01:00
return props [ p_setting ] . has_default_value ;
2017-10-28 23:25:28 +02:00
}
2014-02-10 02:10:30 +01:00
2024-08-17 19:23:06 +02:00
void EditorSettings : : _set_initialized ( ) {
initialized = true ;
}
2017-10-28 15:40:55 +02:00
void EditorSettings : : _load_defaults ( Ref < ConfigFile > p_extra_config ) {
2014-02-10 02:10:30 +01:00
_THREAD_SAFE_METHOD_
2021-08-16 07:30:24 +02:00
// Sets up the editor setting with a default value and hint PropertyInfo.
# define EDITOR_SETTING(m_type, m_property_hint, m_name, m_default_value, m_hint_string) \
_initial_set ( m_name , m_default_value ) ; \
hints [ m_name ] = PropertyInfo ( m_type , m_name , m_property_hint , m_hint_string ) ;
# define EDITOR_SETTING_USAGE(m_type, m_property_hint, m_name, m_default_value, m_hint_string, m_usage) \
_initial_set ( m_name , m_default_value ) ; \
hints [ m_name ] = PropertyInfo ( m_type , m_name , m_property_hint , m_hint_string , m_usage ) ;
2014-02-10 02:10:30 +01:00
2018-12-12 08:18:24 +01:00
/* Languages */
2017-10-28 15:40:55 +02:00
{
String lang_hint = " en " ;
String host_lang = OS : : get_singleton ( ) - > get_locale ( ) ;
2014-02-10 02:10:30 +01:00
2020-09-03 13:22:16 +02:00
// Skip locales if Text server lack required features.
Vector < String > locales_to_skip ;
if ( ! TS - > has_feature ( TextServer : : FEATURE_BIDI_LAYOUT ) | | ! TS - > has_feature ( TextServer : : FEATURE_SHAPING ) ) {
locales_to_skip . push_back ( " ar " ) ; // Arabic
locales_to_skip . push_back ( " fa " ) ; // Persian
locales_to_skip . push_back ( " ur " ) ; // Urdu
}
if ( ! TS - > has_feature ( TextServer : : FEATURE_BIDI_LAYOUT ) ) {
locales_to_skip . push_back ( " he " ) ; // Hebrew
}
if ( ! TS - > has_feature ( TextServer : : FEATURE_SHAPING ) ) {
locales_to_skip . push_back ( " bn " ) ; // Bengali
locales_to_skip . push_back ( " hi " ) ; // Hindi
locales_to_skip . push_back ( " ml " ) ; // Malayalam
locales_to_skip . push_back ( " si " ) ; // Sinhala
locales_to_skip . push_back ( " ta " ) ; // Tamil
locales_to_skip . push_back ( " te " ) ; // Telugu
}
2019-05-21 14:32:01 +02:00
2020-12-15 13:04:21 +01:00
if ( ! locales_to_skip . is_empty ( ) ) {
2020-09-03 13:22:16 +02:00
WARN_PRINT ( " Some locales are not properly supported by selected Text Server and are disabled. " ) ;
}
2017-09-25 05:26:41 +02:00
2020-09-03 13:22:16 +02:00
String best ;
2021-09-23 13:08:50 +02:00
int best_score = 0 ;
2021-12-15 16:01:06 +01:00
for ( const String & locale : get_editor_locales ( ) ) {
2019-05-21 14:32:01 +02:00
// Skip locales which we can't render properly (see above comment).
// Test against language code without regional variants (e.g. ur_PK).
String lang_code = locale . get_slice ( " _ " , 0 ) ;
2022-02-01 19:19:13 +01:00
if ( locales_to_skip . has ( lang_code ) ) {
2019-05-21 14:32:01 +02:00
continue ;
}
2017-10-28 15:40:55 +02:00
lang_hint + = " , " ;
lang_hint + = locale ;
2014-02-10 02:10:30 +01:00
2021-09-23 13:08:50 +02:00
int score = TranslationServer : : get_singleton ( ) - > compare_locales ( host_lang , locale ) ;
2022-01-24 17:58:16 +01:00
if ( score > 0 & & score > = best_score ) {
2017-10-28 15:40:55 +02:00
best = locale ;
2021-09-23 13:08:50 +02:00
best_score = score ;
2017-10-28 15:40:55 +02:00
}
}
2021-09-23 13:08:50 +02:00
if ( best_score = = 0 ) {
2017-10-28 15:40:55 +02:00
best = " en " ;
}
2017-08-03 18:23:46 +02:00
2021-08-16 07:30:24 +02:00
EDITOR_SETTING_USAGE ( Variant : : STRING , PROPERTY_HINT_ENUM , " interface/editor/editor_language " , best , lang_hint , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED ) ;
2017-10-28 15:40:55 +02:00
}
2017-08-03 18:23:46 +02:00
2018-12-12 08:18:24 +01:00
/* Interface */
// Editor
2024-02-16 00:18:28 +01:00
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/editor/localize_settings " , true , " " )
2024-04-20 06:43:19 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/dock_tab_style " , 0 , " Text Only,Icon Only,Text and Icon " )
2024-02-16 00:18:28 +01:00
EDITOR_SETTING_USAGE ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/ui_layout_direction " , 0 , " Based on Application Locale,Left-to-Right,Right-to-Left,Based on System Locale " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2021-01-18 02:39:46 +01:00
// Display what the Auto display scale setting effectively corresponds to.
2021-08-16 07:30:24 +02:00
const String display_scale_hint_string = vformat ( " Auto (%d%%),75%%,100%%,125%%,150%%,175%%,200%%,Custom " , Math : : round ( get_auto_display_scale ( ) * 100 ) ) ;
EDITOR_SETTING_USAGE ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/display_scale " , 0 , display_scale_hint_string , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2024-02-16 00:18:28 +01:00
EDITOR_SETTING_USAGE ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " interface/editor/custom_display_scale " , 1.0 , " 0.5,3,0.01 " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2023-11-17 07:54:07 +01:00
2023-03-21 12:08:46 +01:00
String ed_screen_hints = " Screen With Mouse Pointer:-4,Screen With Keyboard Focus:-3,Primary Screen:-2 " ; // Note: Main Window Screen:-1 is not used for the main window.
for ( int i = 0 ; i < DisplayServer : : get_singleton ( ) - > get_screen_count ( ) ; i + + ) {
ed_screen_hints + = " ,Screen " + itos ( i + 1 ) + " : " + itos ( i ) ;
}
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/editor_screen " , - 2 , ed_screen_hints )
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/project_manager_screen " , - 2 , ed_screen_hints )
2023-04-11 01:14:18 +02:00
{
EngineUpdateLabel : : UpdateMode default_update_mode = EngineUpdateLabel : : UpdateMode : : NEWEST_UNSTABLE ;
if ( String ( VERSION_STATUS ) = = String ( " stable " ) ) {
default_update_mode = EngineUpdateLabel : : UpdateMode : : NEWEST_STABLE ;
}
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " network/connection/engine_version_update_mode " , int ( default_update_mode ) , " Disable Update Checks,Check Newest Preview,Check Newest Stable,Check Newest Patch " ) ; // Uses EngineUpdateLabel::UpdateMode.
}
2022-08-01 11:28:16 +02:00
EDITOR_SETTING_USAGE ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/editor/use_embedded_menu " , false , " " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2024-03-21 09:42:38 +01:00
EDITOR_SETTING_USAGE ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/editor/use_native_file_dialogs " , false , " " , PROPERTY_USAGE_DEFAULT )
2022-08-23 12:40:48 +02:00
EDITOR_SETTING_USAGE ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/editor/expand_to_title " , true , " " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2021-08-08 17:07:57 +02:00
2022-03-21 07:20:09 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " interface/editor/main_font_size " , 14 , " 8,48,1 " )
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " interface/editor/code_font_size " , 14 , " 8,48,1 " )
2022-11-12 18:55:57 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/code_font_contextual_ligatures " , 1 , " Enabled,Disable Contextual Alternates (Coding Ligatures),Use Custom OpenType Feature Set " )
2020-09-03 13:22:16 +02:00
_initial_set ( " interface/editor/code_font_custom_opentype_features " , " " ) ;
2020-10-22 18:40:18 +02:00
_initial_set ( " interface/editor/code_font_custom_variations " , " " ) ;
2022-11-03 18:37:21 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/font_antialiasing " , 1 , " None,Grayscale,LCD Subpixel " )
2022-07-20 08:28:22 +02:00
# ifdef MACOS_ENABLED
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/font_hinting " , 0 , " Auto (None),None,Light,Normal " )
2021-01-18 02:39:46 +01:00
# else
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/font_hinting " , 0 , " Auto (Light),None,Light,Normal " )
2021-01-18 02:39:46 +01:00
# endif
2022-11-03 18:37:21 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/font_subpixel_positioning " , 1 , " Disabled,Auto,One Half of a Pixel,One Quarter of a Pixel " )
2024-05-14 08:26:22 +02:00
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/editor/font_disable_embedded_bitmaps " , true , " " ) ;
2024-08-07 08:19:49 +02:00
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/editor/font_allow_msdf " , true , " " )
2022-01-10 09:13:22 +01:00
2022-03-25 09:54:32 +01:00
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_GLOBAL_FILE , " interface/editor/main_font " , " " , " *.ttf,*.otf,*.woff,*.woff2,*.pfb,*.pfm " )
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_GLOBAL_FILE , " interface/editor/main_font_bold " , " " , " *.ttf,*.otf,*.woff,*.woff2,*.pfb,*.pfm " )
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_GLOBAL_FILE , " interface/editor/code_font " , " " , " *.ttf,*.otf,*.woff,*.woff2,*.pfb,*.pfm " )
2017-10-28 15:40:55 +02:00
_initial_set ( " interface/editor/separate_distraction_mode " , false ) ;
2019-07-23 07:05:29 +02:00
_initial_set ( " interface/editor/automatically_open_screenshots " , true ) ;
2021-08-16 07:30:24 +02:00
EDITOR_SETTING_USAGE ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/editor/single_window_mode " , false , " " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2023-04-15 13:19:05 +02:00
_initial_set ( " interface/editor/remember_window_size_and_position " , true ) ;
2020-03-08 17:32:49 +01:00
_initial_set ( " interface/editor/mouse_extra_buttons_navigate_history " , true ) ;
2017-10-28 15:40:55 +02:00
_initial_set ( " interface/editor/save_each_scene_on_quit " , true ) ; // Regression
2024-02-16 00:18:28 +01:00
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/editor/save_on_focus_loss " , false , " " )
2022-03-21 10:55:18 +01:00
EDITOR_SETTING_USAGE ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/accept_dialog_cancel_ok_buttons " , 0 ,
vformat ( " Auto (%s),Cancel First,OK First " , DisplayServer : : get_singleton ( ) - > get_swap_cancel_ok ( ) ? " OK First " : " Cancel First " ) ,
PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED ) ;
2022-01-08 02:32:53 +01:00
# ifdef DEV_ENABLED
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/show_internal_errors_in_toast_notifications " , 0 , " Auto (Enabled),Enabled,Disabled " )
2024-02-08 15:13:15 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/show_update_spinner " , 0 , " Auto (Enabled),Enabled,Disabled " )
2022-01-08 02:32:53 +01:00
# else
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/show_internal_errors_in_toast_notifications " , 0 , " Auto (Disabled),Enabled,Disabled " )
2024-02-08 15:13:15 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/show_update_spinner " , 0 , " Auto (Disabled),Enabled,Disabled " )
2022-01-08 02:32:53 +01:00
# endif
2017-07-12 20:46:08 +02:00
2024-08-02 03:44:29 +02:00
_initial_set ( " interface/editor/keep_screen_on " , false ) ;
2024-02-16 00:18:28 +01:00
EDITOR_SETTING_USAGE ( Variant : : INT , PROPERTY_HINT_RANGE , " interface/editor/low_processor_mode_sleep_usec " , 6900 , " 1,100000,1 " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
// Default unfocused usec sleep is for 10 FPS. Allow an unfocused FPS limit
// as low as 1 FPS for those who really need low power usage (but don't need
// to preview particles or shaders while the editor is unfocused). With very
// low FPS limits, the editor can take a small while to become usable after
// being focused again, so this should be used at the user's discretion.
EDITOR_SETTING_USAGE ( Variant : : INT , PROPERTY_HINT_RANGE , " interface/editor/unfocused_low_processor_mode_sleep_usec " , 100000 , " 1,1000000,1 " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2023-05-12 07:24:40 +02:00
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/editor/import_resources_when_unfocused " , false , " " )
2024-02-16 00:18:28 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/editor/vsync_mode " , 1 , " Disabled,Enabled,Adaptive,Mailbox " )
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/editor/update_continuously " , false , " " )
2021-01-01 19:41:11 +01:00
// Inspector
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " interface/inspector/max_array_dictionary_items_per_page " , 20 , " 10,100,1 " )
2022-05-09 11:47:10 +02:00
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/inspector/show_low_level_opentype_features " , false , " " )
2021-07-21 00:45:29 +02:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " interface/inspector/float_drag_speed " , 5.0 , " 0.1,100,0.01 " )
2024-04-25 23:16:18 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/inspector/nested_color_mode " , 0 , " Containers & Resources,Resources,External Resources " )
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/inspector/delimitate_all_container_and_resources " , true , " " )
2024-06-02 01:14:03 +02:00
EDITOR_SETTING_USAGE ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/inspector/default_property_name_style " , EditorPropertyNameProcessor : : STYLE_CAPITALIZED , " Raw (e.g. \" z_index \" ),Capitalized (e.g. \" Z Index \" ),Localized (e.g. \" Z Index \" ) " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED ) ;
2024-02-16 00:18:28 +01:00
// The lowest value is equal to the minimum float step for 32-bit floats.
// The step must be set manually, as changing this setting should not change the step here.
EDITOR_SETTING_USAGE ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " interface/inspector/default_float_step " , 0.001 , " 0.0000001,1,0.0000001 " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED ) ;
EDITOR_SETTING_USAGE ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/inspector/disable_folding " , false , " " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED ) ;
EDITOR_SETTING_USAGE ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/inspector/auto_unfold_foreign_scenes " , true , " " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/inspector/horizontal_vector2_editing " , false , " " )
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/inspector/horizontal_vector_types_editing " , true , " " )
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/inspector/open_resources_in_current_inspector " , true , " " )
PackedStringArray open_in_new_inspector_defaults ;
// Required for the script editor to work.
open_in_new_inspector_defaults . push_back ( " Script " ) ;
// Required for the GridMap editor to work.
open_in_new_inspector_defaults . push_back ( " MeshLibrary " ) ;
_initial_set ( " interface/inspector/resources_to_open_in_new_inspector " , open_in_new_inspector_defaults ) ;
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/inspector/default_color_picker_mode " , ( int32_t ) ColorPicker : : MODE_RGB , " RGB,HSV,RAW,OKHSL " )
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/inspector/default_color_picker_shape " , ( int32_t ) ColorPicker : : SHAPE_OKHSL_CIRCLE , " HSV Rectangle,HSV Rectangle Wheel,VHS Circle,OKHSL Circle " )
2021-01-01 19:41:11 +01:00
2018-12-12 08:18:24 +01:00
// Theme
2024-02-14 21:13:30 +01:00
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_ENUM , " interface/theme/follow_system_theme " , false , " " )
2022-01-29 00:09:44 +01:00
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_ENUM , " interface/theme/preset " , " Default " , " Default,Breeze Dark,Godot 2,Gray,Light,Solarized (Dark),Solarized (Light),Black (OLED),Custom " )
2024-01-15 13:14:55 +01:00
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_ENUM , " interface/theme/spacing_preset " , " Default " , " Compact,Default,Spacious,Custom " )
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/theme/icon_and_font_color " , 0 , " Auto,Dark,Light " )
EDITOR_SETTING ( Variant : : COLOR , PROPERTY_HINT_NONE , " interface/theme/base_color " , Color ( 0.2 , 0.23 , 0.31 ) , " " )
EDITOR_SETTING ( Variant : : COLOR , PROPERTY_HINT_NONE , " interface/theme/accent_color " , Color ( 0.41 , 0.61 , 0.91 ) , " " )
2024-02-14 21:13:30 +01:00
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/theme/use_system_accent_color " , false , " " )
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " interface/theme/contrast " , 0.3 , " -1,1,0.01 " )
2022-01-29 00:09:44 +01:00
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/theme/draw_extra_borders " , false , " " )
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " interface/theme/icon_saturation " , 1.0 , " 0,2,0.01 " )
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " interface/theme/relationship_line_opacity " , 0.1 , " 0.00,1,0.01 " )
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " interface/theme/border_size " , 0 , " 0,2,1 " )
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " interface/theme/corner_radius " , 3 , " 0,6,1 " )
2024-01-15 13:14:55 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " interface/theme/base_spacing " , 4 , " 0,8,1 " )
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " interface/theme/additional_spacing " , 0 , " 0,8,1 " )
2021-08-16 07:30:24 +02:00
EDITOR_SETTING_USAGE ( Variant : : STRING , PROPERTY_HINT_GLOBAL_FILE , " interface/theme/custom_theme " , " " , " *.res,*.tres,*.theme " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2017-08-03 18:23:46 +02:00
2023-02-21 18:18:08 +01:00
// Touchscreen
bool has_touchscreen_ui = DisplayServer : : get_singleton ( ) - > is_touchscreen_available ( ) ;
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/touchscreen/increase_scrollbar_touch_area " , has_touchscreen_ui , " " )
2024-07-17 11:30:30 +02:00
set_restart_if_changed ( " interface/touchscreen/increase_scrollbar_touch_area " , true ) ;
2023-02-21 18:18:08 +01:00
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/touchscreen/enable_long_press_as_right_click " , has_touchscreen_ui , " " )
set_restart_if_changed ( " interface/touchscreen/enable_long_press_as_right_click " , true ) ;
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/touchscreen/enable_pan_and_scale_gestures " , has_touchscreen_ui , " " )
set_restart_if_changed ( " interface/touchscreen/enable_pan_and_scale_gestures " , true ) ;
2023-04-05 22:04:00 +02:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " interface/touchscreen/scale_gizmo_handles " , has_touchscreen_ui ? 3 : 1 , " 1,5,1 " )
2024-07-17 11:30:30 +02:00
set_restart_if_changed ( " interface/touchscreen/scale_gizmo_handles " , true ) ;
2023-02-21 18:18:08 +01:00
2018-12-12 08:18:24 +01:00
// Scene tabs
2022-03-13 02:03:26 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " interface/scene_tabs/display_close_button " , 1 , " Never,If Tab Active,Always " ) ; // TabBar::CloseButtonDisplayPolicy
2017-10-28 15:40:55 +02:00
_initial_set ( " interface/scene_tabs/show_thumbnail_on_hover " , true ) ;
2022-02-03 06:45:31 +01:00
EDITOR_SETTING_USAGE ( Variant : : INT , PROPERTY_HINT_RANGE , " interface/scene_tabs/maximum_width " , 350 , " 0,9999,1 " , PROPERTY_USAGE_DEFAULT )
2018-12-12 08:18:24 +01:00
_initial_set ( " interface/scene_tabs/show_script_button " , false ) ;
2024-02-16 00:18:28 +01:00
EDITOR_SETTING_USAGE ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/scene_tabs/restore_scenes_on_load " , true , " " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2017-08-03 18:23:46 +02:00
2022-11-02 15:23:25 +01:00
// Multi Window
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/multi_window/enable " , true , " " ) ;
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/multi_window/restore_windows_on_load " , true , " " ) ;
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " interface/multi_window/maximize_window " , false , " " ) ;
set_restart_if_changed ( " interface/multi_window/enable " , true ) ;
2018-12-12 08:18:24 +01:00
/* Filesystem */
2022-11-10 22:26:40 +01:00
// External Programs
2023-01-26 13:16:55 +01:00
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_GLOBAL_FILE , " filesystem/external_programs/raster_image_editor " , " " , " " )
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_GLOBAL_FILE , " filesystem/external_programs/vector_image_editor " , " " , " " )
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_GLOBAL_FILE , " filesystem/external_programs/audio_editor " , " " , " " )
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_GLOBAL_FILE , " filesystem/external_programs/3d_model_editor " , " " , " " )
2023-06-16 09:24:32 +02:00
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_GLOBAL_FILE , " filesystem/external_programs/terminal_emulator " , " " , " " )
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_PLACEHOLDER_TEXT , " filesystem/external_programs/terminal_emulator_flags " , " " , " Call flags with placeholder: {directory}. " ) ;
2022-11-10 22:26:40 +01:00
2018-12-12 08:18:24 +01:00
// Directories
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_GLOBAL_DIR , " filesystem/directories/autoscan_project_path " , " " , " " )
const String fs_dir_default_project_path = OS : : get_singleton ( ) - > has_environment ( " HOME " ) ? OS : : get_singleton ( ) - > get_environment ( " HOME " ) : OS : : get_singleton ( ) - > get_system_dir ( OS : : SYSTEM_DIR_DOCUMENTS ) ;
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_GLOBAL_DIR , " filesystem/directories/default_project_path " , fs_dir_default_project_path , " " )
2017-07-12 20:46:08 +02:00
2018-12-12 08:18:24 +01:00
// On save
_initial_set ( " filesystem/on_save/compress_binary_resources " , true ) ;
_initial_set ( " filesystem/on_save/safe_save_on_backup_then_rename " , true ) ;
// File dialog
_initial_set ( " filesystem/file_dialog/show_hidden_files " , false ) ;
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " filesystem/file_dialog/display_mode " , 0 , " Thumbnails,List " )
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " filesystem/file_dialog/thumbnail_size " , 64 , " 32,128,16 " )
2018-12-12 08:18:24 +01:00
2023-08-14 11:38:44 +02:00
// Import (for glft module)
2023-11-28 10:56:04 +01:00
EDITOR_SETTING_USAGE ( Variant : : STRING , PROPERTY_HINT_GLOBAL_FILE , " filesystem/import/blender/blender_path " , " " , " " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2023-08-14 11:38:44 +02:00
EDITOR_SETTING_USAGE ( Variant : : INT , PROPERTY_HINT_RANGE , " filesystem/import/blender/rpc_port " , 6011 , " 0,65535,1 " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
EDITOR_SETTING_USAGE ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " filesystem/import/blender/rpc_server_uptime " , 5 , " 0,300,1,or_greater,suffix:s " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2024-05-30 23:42:11 +02:00
EDITOR_SETTING_USAGE ( Variant : : STRING , PROPERTY_HINT_GLOBAL_FILE , " filesystem/import/fbx/fbx2gltf_path " , " " , " " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2023-08-14 11:38:44 +02:00
2023-10-04 21:32:39 +02:00
// Tools (denoise)
EDITOR_SETTING_USAGE ( Variant : : STRING , PROPERTY_HINT_GLOBAL_DIR , " filesystem/tools/oidn/oidn_denoise_path " , " " , " " , PROPERTY_USAGE_DEFAULT )
2018-12-12 08:18:24 +01:00
/* Docks */
// SceneTree
_initial_set ( " docks/scene_tree/start_create_dialog_fully_expanded " , false ) ;
2021-08-09 19:14:06 +02:00
_initial_set ( " docks/scene_tree/auto_expand_to_selected " , true ) ;
2023-11-17 02:58:23 +01:00
_initial_set ( " docks/scene_tree/center_node_on_reparent " , false ) ;
2018-12-12 08:18:24 +01:00
// FileSystem
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " docks/filesystem/thumbnail_size " , 64 , " 32,128,16 " )
2018-12-12 08:18:24 +01:00
_initial_set ( " docks/filesystem/always_show_folders " , true ) ;
2023-09-13 20:44:15 +02:00
_initial_set ( " docks/filesystem/textfile_extensions " , " txt,md,cfg,ini,log,json,yml,yaml,toml,xml " ) ;
2018-12-12 08:18:24 +01:00
// Property editor
2023-08-25 01:02:47 +02:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " docks/property_editor/auto_refresh_interval " , 0.2 , " 0.01,1,0.001 " ) ; // Update 5 times per second by default.
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " docks/property_editor/subresource_hue_tint " , 0.75 , " 0,1,0.01 " )
2018-12-12 08:18:24 +01:00
/* Text editor */
// Theme
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_ENUM , " text_editor/theme/color_theme " , " Default " , " Default,Godot 2,Custom " )
2014-02-10 02:10:30 +01:00
2021-08-15 19:14:46 +02:00
// Theme: Highlighting
2021-05-27 10:22:36 +02:00
_load_godot2_text_editor_theme ( ) ;
2014-02-10 02:10:30 +01:00
2019-09-01 13:28:57 +02:00
// Appearance
2021-08-15 19:14:46 +02:00
// Appearance: Caret
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " text_editor/appearance/caret/type " , 0 , " Line,Block " )
2021-08-15 19:14:46 +02:00
_initial_set ( " text_editor/appearance/caret/caret_blink " , true ) ;
2022-08-13 14:52:35 +02:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " text_editor/appearance/caret/caret_blink_interval " , 0.5 , " 0.1,10,0.01 " )
2021-08-15 19:14:46 +02:00
_initial_set ( " text_editor/appearance/caret/highlight_current_line " , true ) ;
_initial_set ( " text_editor/appearance/caret/highlight_all_occurrences " , true ) ;
// Appearance: Guidelines
_initial_set ( " text_editor/appearance/guidelines/show_line_length_guidelines " , true ) ;
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " text_editor/appearance/guidelines/line_length_guideline_soft_column " , 80 , " 20,160,1 " )
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " text_editor/appearance/guidelines/line_length_guideline_hard_column " , 100 , " 20,160,1 " )
2021-08-15 19:14:46 +02:00
// Appearance: Gutters
_initial_set ( " text_editor/appearance/gutters/show_line_numbers " , true ) ;
_initial_set ( " text_editor/appearance/gutters/line_numbers_zero_padded " , false ) ;
_initial_set ( " text_editor/appearance/gutters/highlight_type_safe_lines " , true ) ;
_initial_set ( " text_editor/appearance/gutters/show_info_gutter " , true ) ;
// Appearance: Minimap
_initial_set ( " text_editor/appearance/minimap/show_minimap " , true ) ;
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " text_editor/appearance/minimap/minimap_width " , 80 , " 50,250,1 " )
2021-08-15 19:14:46 +02:00
// Appearance: Lines
_initial_set ( " text_editor/appearance/lines/code_folding " , true ) ;
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " text_editor/appearance/lines/word_wrap " , 0 , " None,Boundary " )
2023-03-12 12:21:00 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " text_editor/appearance/lines/autowrap_mode " , 3 , " Arbitrary:1,Word:2,Word (Smart):3 " )
2021-08-15 19:14:46 +02:00
// Appearance: Whitespace
_initial_set ( " text_editor/appearance/whitespace/draw_tabs " , true ) ;
_initial_set ( " text_editor/appearance/whitespace/draw_spaces " , false ) ;
2022-03-21 02:00:58 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " text_editor/appearance/whitespace/line_spacing " , 4 , " 0,50,1 " )
2021-08-15 19:14:46 +02:00
// Behavior
// Behavior: Navigation
_initial_set ( " text_editor/behavior/navigation/move_caret_on_right_click " , true ) ;
_initial_set ( " text_editor/behavior/navigation/scroll_past_end_of_file " , false ) ;
_initial_set ( " text_editor/behavior/navigation/smooth_scrolling " , true ) ;
2022-02-12 14:40:49 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " text_editor/behavior/navigation/v_scroll_speed " , 80 , " 1,10000,1 " )
2022-06-19 16:55:13 +02:00
_initial_set ( " text_editor/behavior/navigation/drag_and_drop_selection " , true ) ;
2022-07-23 14:29:30 +02:00
_initial_set ( " text_editor/behavior/navigation/stay_in_script_editor_on_node_selected " , true ) ;
2024-03-07 14:28:26 +01:00
_initial_set ( " text_editor/behavior/navigation/open_script_when_connecting_signal_to_existing_method " , true ) ;
2024-05-29 13:06:43 +02:00
_initial_set ( " text_editor/behavior/navigation/use_default_word_separators " , true ) ; // Includes ´ `~$^=+|<> General punctuation and CJK punctuation.
_initial_set ( " text_editor/behavior/navigation/use_custom_word_separators " , false ) ;
_initial_set ( " text_editor/behavior/navigation/custom_word_separators " , " " ) ; // Custom word separators.
2021-08-15 19:14:46 +02:00
// Behavior: Indent
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " text_editor/behavior/indent/type " , 0 , " Tabs,Spaces " )
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " text_editor/behavior/indent/size " , 4 , " 1,64,1 " ) // size of 0 crashes.
2021-08-15 19:14:46 +02:00
_initial_set ( " text_editor/behavior/indent/auto_indent " , true ) ;
2024-02-19 12:41:12 +01:00
_initial_set ( " text_editor/behavior/indent/indent_wrapped_lines " , true ) ;
2021-08-15 19:14:46 +02:00
// Behavior: Files
_initial_set ( " text_editor/behavior/files/trim_trailing_whitespace_on_save " , false ) ;
2024-01-12 06:32:13 +01:00
_initial_set ( " text_editor/behavior/files/trim_final_newlines_on_save " , true ) ;
2021-08-15 19:14:46 +02:00
_initial_set ( " text_editor/behavior/files/autosave_interval_secs " , 0 ) ;
_initial_set ( " text_editor/behavior/files/restore_scripts_on_load " , true ) ;
_initial_set ( " text_editor/behavior/files/convert_indent_on_save " , true ) ;
2022-03-06 21:39:19 +01:00
_initial_set ( " text_editor/behavior/files/auto_reload_scripts_on_external_change " , false ) ;
2019-09-01 13:28:57 +02:00
// Script list
_initial_set ( " text_editor/script_list/show_members_overview " , true ) ;
2021-08-15 19:14:46 +02:00
_initial_set ( " text_editor/script_list/sort_members_outline_alphabetically " , false ) ;
2014-02-10 02:10:30 +01:00
2018-12-12 08:18:24 +01:00
// Completion
2022-06-08 16:46:25 +02:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " text_editor/completion/idle_parse_delay " , 1.5 , " 0.1,10,0.01 " )
2019-07-18 21:34:28 +02:00
_initial_set ( " text_editor/completion/auto_brace_complete " , true ) ;
2022-11-01 20:03:43 +01:00
_initial_set ( " text_editor/completion/code_complete_enabled " , true ) ;
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " text_editor/completion/code_complete_delay " , 0.3 , " 0.01,5,0.01,or_greater " )
2018-01-06 12:40:43 +01:00
_initial_set ( " text_editor/completion/put_callhint_tooltip_below_current_line " , true ) ;
2017-10-28 15:40:55 +02:00
_initial_set ( " text_editor/completion/complete_file_paths " , true ) ;
2024-02-06 19:35:52 +01:00
_initial_set ( " text_editor/completion/add_type_hints " , true ) ;
2022-10-06 22:08:01 +02:00
_initial_set ( " text_editor/completion/add_string_name_literals " , false ) ;
_initial_set ( " text_editor/completion/add_node_path_literals " , false ) ;
2018-12-18 02:53:54 +01:00
_initial_set ( " text_editor/completion/use_single_quotes " , false ) ;
2023-03-12 08:33:38 +01:00
_initial_set ( " text_editor/completion/colorize_suggestions " , true ) ;
2014-02-10 02:10:30 +01:00
2018-12-12 08:18:24 +01:00
// Help
_initial_set ( " text_editor/help/show_help_index " , true ) ;
2023-02-11 17:35:10 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " text_editor/help/help_font_size " , 16 , " 8,48,1 " )
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " text_editor/help/help_source_font_size " , 15 , " 8,48,1 " )
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " text_editor/help/help_title_font_size " , 23 , " 8,64,1 " )
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " text_editor/help/class_reference_examples " , 0 , " GDScript,C#,GDScript and C# " )
2018-12-12 08:18:24 +01:00
/* Editors */
2014-02-10 02:10:30 +01:00
2018-12-12 08:18:24 +01:00
// GridMap
2017-10-28 15:40:55 +02:00
_initial_set ( " editors/grid_map/pick_distance " , 5000.0 ) ;
2014-02-10 02:10:30 +01:00
2018-12-12 08:18:24 +01:00
// 3D
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : COLOR , PROPERTY_HINT_NONE , " editors/3d/primary_grid_color " , Color ( 0.56 , 0.56 , 0.56 , 0.5 ) , " " )
EDITOR_SETTING ( Variant : : COLOR , PROPERTY_HINT_NONE , " editors/3d/secondary_grid_color " , Color ( 0.38 , 0.38 , 0.38 , 0.5 ) , " " )
2018-04-30 01:43:20 +02:00
2020-12-29 07:35:59 +01:00
// Use a similar color to the 2D editor selection.
2021-08-16 07:30:24 +02:00
EDITOR_SETTING_USAGE ( Variant : : COLOR , PROPERTY_HINT_NONE , " editors/3d/selection_box_color " , Color ( 1.0 , 0.5 , 0 ) , " " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2023-10-06 09:02:03 +02:00
EDITOR_SETTING_USAGE ( Variant : : COLOR , PROPERTY_HINT_NONE , " editors/3d_gizmos/gizmo_colors/instantiated " , Color ( 0.7 , 0.7 , 0.7 , 0.6 ) , " " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
EDITOR_SETTING_USAGE ( Variant : : COLOR , PROPERTY_HINT_NONE , " editors/3d_gizmos/gizmo_colors/joint " , Color ( 0.5 , 0.8 , 1 ) , " " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2024-03-15 21:10:15 +01:00
EDITOR_SETTING_USAGE ( Variant : : COLOR , PROPERTY_HINT_NONE , " editors/3d_gizmos/gizmo_colors/aabb " , Color ( 0.28 , 0.8 , 0.82 ) , " " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2020-12-29 07:35:59 +01:00
2019-04-21 12:15:45 +02:00
// If a line is a multiple of this, it uses the primary grid color.
2020-11-21 21:35:23 +01:00
// Use a power of 2 value by default as it's more common to use powers of 2 in level design.
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " editors/3d/primary_grid_steps " , 8 , " 1,100,1 " )
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " editors/3d/grid_size " , 200 , " 1,2000,1 " )
2019-04-21 12:15:45 +02:00
// Higher values produce graphical artifacts when far away unless View Z-Far
// is increased significantly more than it really should need to be.
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " editors/3d/grid_division_level_max " , 2 , " -1,3,1 " )
2019-04-21 12:15:45 +02:00
// Lower values produce graphical artifacts regardless of view clipping planes, so limit to -2 as a lower bound.
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " editors/3d/grid_division_level_min " , 0 , " -2,2,1 " )
2019-04-21 12:15:45 +02:00
// -0.2 seems like a sensible default. -1.0 gives Blender-like behavior, 0.5 gives huge grids.
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/3d/grid_division_level_bias " , - 0.2 , " -1.0,0.5,0.1 " )
2019-04-21 12:15:45 +02:00
_initial_set ( " editors/3d/grid_xz_plane " , true ) ;
_initial_set ( " editors/3d/grid_xy_plane " , false ) ;
_initial_set ( " editors/3d/grid_yz_plane " , false ) ;
2014-02-10 02:10:30 +01:00
2019-10-31 14:32:46 +01:00
// Use a lower default FOV for the 3D camera compared to the
// Camera3D node as the 3D viewport doesn't span the whole screen.
// This means it's technically viewed from a further distance, which warrants a narrower FOV.
2021-12-03 01:09:19 +01:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/3d/default_fov " , 70.0 , " 1,179,0.1,degrees " )
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/3d/default_z_near " , 0.05 , " 0.01,10,0.01,or_greater,suffix:m " )
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/3d/default_z_far " , 4000.0 , " 0.1,4000,0.1,or_greater,suffix:m " )
2017-10-28 15:40:55 +02:00
2018-12-12 08:18:24 +01:00
// 3D: Navigation
2020-08-15 13:18:01 +02:00
_initial_set ( " editors/3d/navigation/invert_x_axis " , false ) ;
2021-08-16 07:30:24 +02:00
_initial_set ( " editors/3d/navigation/invert_y_axis " , false ) ;
2023-11-24 21:40:54 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " editors/3d/navigation/navigation_scheme " , 0 , " Godot,Maya,Modo,Custom " )
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " editors/3d/navigation/orbit_mouse_button " , 1 , " Left Mouse,Middle Mouse,Right Mouse " )
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " editors/3d/navigation/pan_mouse_button " , 1 , " Left Mouse,Middle Mouse,Right Mouse " )
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " editors/3d/navigation/zoom_mouse_button " , 1 , " Left Mouse,Middle Mouse,Right Mouse " )
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " editors/3d/navigation/zoom_style " , 0 , " Vertical,Horizontal " )
2017-10-28 15:40:55 +02:00
2021-07-02 09:27:12 +02:00
_initial_set ( " editors/3d/navigation/emulate_numpad " , false ) ;
2017-10-28 15:40:55 +02:00
_initial_set ( " editors/3d/navigation/emulate_3_button_mouse " , false ) ;
_initial_set ( " editors/3d/navigation/warped_mouse_panning " , true ) ;
2018-12-12 08:18:24 +01:00
// 3D: Navigation feel
2020-01-14 00:26:26 +01:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/3d/navigation_feel/orbit_sensitivity " , 0.25 , " 0.01,2,0.001 " )
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/3d/navigation_feel/orbit_inertia " , 0.0 , " 0,1,0.001 " )
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/3d/navigation_feel/translation_inertia " , 0.05 , " 0,1,0.001 " )
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/3d/navigation_feel/zoom_inertia " , 0.05 , " 0,1,0.001 " )
2017-10-28 15:40:55 +02:00
2018-12-12 08:18:24 +01:00
// 3D: Freelook
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " editors/3d/freelook/freelook_navigation_scheme " , 0 , " Default,Partially Axis-Locked (id Tech),Fully Axis-Locked (Minecraft) " )
2020-01-14 00:26:26 +01:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/3d/freelook/freelook_sensitivity " , 0.25 , " 0.01,2,0.001 " )
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/3d/freelook/freelook_inertia " , 0.0 , " 0,1,0.001 " )
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/3d/freelook/freelook_base_speed " , 5.0 , " 0,10,0.01 " )
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " editors/3d/freelook/freelook_activation_modifier " , 0 , " None,Shift,Alt,Meta,Ctrl " )
2017-10-28 15:40:55 +02:00
_initial_set ( " editors/3d/freelook/freelook_speed_zoom_link " , false ) ;
2018-12-12 08:18:24 +01:00
// 2D
2018-08-18 17:32:09 +02:00
_initial_set ( " editors/2d/grid_color " , Color ( 1.0 , 1.0 , 1.0 , 0.07 ) ) ;
2017-12-05 21:42:33 +01:00
_initial_set ( " editors/2d/guides_color " , Color ( 0.6 , 0.0 , 0.8 ) ) ;
2019-04-05 10:18:21 +02:00
_initial_set ( " editors/2d/smart_snapping_line_color " , Color ( 0.9 , 0.1 , 0.1 ) ) ;
2023-07-13 20:02:39 +02:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/2d/bone_width " , 5.0 , " 0.01,20,0.01,or_greater " )
New and improved IK system for Skeleton2D
This PR and commit adds a new IK system for 2D with the Skeleton2D node
that adds several new IK solvers, a way to control bones in a Skeleton2D
node similar to that in Skeleton3D. It also adds additional changes
and functionality.
This work was sponsored by GSoC 2020 and TwistedTwigleg.
Full list of changes:
* Adds a SkeletonModifier2D resource
* This resource is the base where all IK code is written and executed
* Has a function for clamping angles, since it is so commonly used
* Modifiers are unique when duplicated so it works with instancing
* Adds a SkeletonModifierStack2D resource
* This resource manages a series of SkeletonModification2Ds
* This is what the Skeleton2D directly interfaces with to make IK possible
* Adds SkeletonModifier2D resources for LookAt, CCDIK, FABRIK, Jiggle, and TwoBoneIK
* Each modification is in its own file
* There is also a SkeletonModifier2D resource that acts as a stack for using multiple stacks together
* Adds a PhysicalBone2D node
* Works similar to the PhysicalBone3D node, but uses a RigidBody2D node
* Changes to Skeleton2D listed below:
* Skeleton2D now holds a single SkeletonModificationStack2D for IK
* Skeleton2D now has a local_pose_override, which overrides the Bone2D position similar to how the overrides work in Skeleton3D
* Changes to Bone2D listed below:
* The default_length property has been changed to length. Length is the length of the bone to its child bone node
* New bone_angle property, which is the angle the bone has to its first child bone node
* Bone2D caches its transform when not modified by IK for IK interpolation purposes
* Bone2D draws its own editor gizmo, though this is stated to change in the future
* Changes to CanvasItemEditor listed below:
* Bone2D gizmo drawing code removed
* The 2D IK code is removed. Now Bone2D is the only bone system for 2D
* Transform2D now has a looking_at function for rotating to face a position
* Two new node notifications: NOTIFICATION_EDITOR_PRE_SAVE and NOTIFICATION_EDITOR_POST_SAVE
* These notifications only are called in the editor right before and after saving a scene
* Needed for not saving the IK position when executing IK in the editor
* Documentation for all the changes listed above.
2020-08-03 20:02:24 +02:00
_initial_set ( " editors/2d/bone_color1 " , Color ( 1.0 , 1.0 , 1.0 , 0.7 ) ) ;
_initial_set ( " editors/2d/bone_color2 " , Color ( 0.6 , 0.6 , 0.6 , 0.7 ) ) ;
_initial_set ( " editors/2d/bone_selected_color " , Color ( 0.9 , 0.45 , 0.45 , 0.7 ) ) ;
_initial_set ( " editors/2d/bone_ik_color " , Color ( 0.9 , 0.9 , 0.45 , 0.7 ) ) ;
_initial_set ( " editors/2d/bone_outline_color " , Color ( 0.35 , 0.35 , 0.35 , 0.5 ) ) ;
2023-07-13 20:02:39 +02:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/2d/bone_outline_size " , 2.0 , " 0.01,8,0.01,or_greater " )
2018-09-24 15:16:40 +02:00
_initial_set ( " editors/2d/viewport_border_color " , Color ( 0.4 , 0.4 , 1.0 , 0.4 ) ) ;
2023-06-20 03:22:54 +02:00
_initial_set ( " editors/2d/use_integer_zoom_by_default " , false ) ;
2024-08-21 15:23:01 +02:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/2d/zoom_speed_factor " , 1.1 , " 1.01,2,0.01 " )
2022-01-19 19:59:12 +01:00
// Panning
// Enum should be in sync with ControlScheme in ViewPanner.
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " editors/panning/2d_editor_panning_scheme " , 0 , " Scroll Zooms,Scroll Pans " ) ;
2022-01-23 13:49:53 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " editors/panning/sub_editors_panning_scheme " , 0 , " Scroll Zooms,Scroll Pans " ) ;
2022-01-19 19:59:12 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " editors/panning/animation_editors_panning_scheme " , 1 , " Scroll Zooms,Scroll Pans " ) ;
_initial_set ( " editors/panning/simple_panning " , false ) ;
_initial_set ( " editors/panning/warped_mouse_panning " , true ) ;
_initial_set ( " editors/panning/2d_editor_pan_speed " , 20 ) ;
2017-10-28 15:40:55 +02:00
2021-05-21 17:28:28 +02:00
// Tiles editor
_initial_set ( " editors/tiles_editor/display_grid " , true ) ;
2024-03-05 13:55:23 +01:00
_initial_set ( " editors/tiles_editor/highlight_selected_layer " , true ) ;
2021-05-21 17:28:28 +02:00
_initial_set ( " editors/tiles_editor/grid_color " , Color ( 1.0 , 0.5 , 0.2 , 0.5 ) ) ;
2018-12-12 08:18:24 +01:00
// Polygon editor
2023-04-05 22:04:00 +02:00
_initial_set ( " editors/polygon_editor/point_grab_radius " , has_touchscreen_ui ? 32 : 8 ) ;
2021-08-23 17:59:19 +02:00
_initial_set ( " editors/polygon_editor/show_previous_outline " , true ) ;
2023-12-03 18:27:17 +01:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/polygon_editor/auto_bake_delay " , 1.5 , " -1.0,10.0,0.01 " ) ;
2017-10-28 15:40:55 +02:00
2018-12-12 08:18:24 +01:00
// Animation
_initial_set ( " editors/animation/autorename_animation_tracks " , true ) ;
2024-06-10 17:47:59 +02:00
_initial_set ( " editors/animation/confirm_insert_track " , true ) ;
2020-12-20 11:46:44 +01:00
_initial_set ( " editors/animation/default_create_bezier_tracks " , false ) ;
_initial_set ( " editors/animation/default_create_reset_tracks " , true ) ;
2018-12-12 08:18:24 +01:00
_initial_set ( " editors/animation/onion_layers_past_color " , Color ( 1 , 0 , 0 ) ) ;
_initial_set ( " editors/animation/onion_layers_future_color " , Color ( 0 , 1 , 0 ) ) ;
2023-05-11 04:17:03 +02:00
// Shader editor
_initial_set ( " editors/shader_editor/behavior/files/restore_shaders_on_load " , true ) ;
2021-01-25 15:37:05 +01:00
// Visual editors
2024-02-09 15:02:58 +01:00
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_ENUM , " editors/visual_editors/color_theme " , " Default " , " Default,Legacy,Custom " )
_load_default_visual_shader_editor_theme ( ) ;
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/visual_editors/minimap_opacity " , 0.85 , " 0.0,1.0,0.01 " )
2022-05-30 15:38:13 +02:00
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " editors/visual_editors/lines_curvature " , 0.5 , " 0.0,1.0,0.01 " )
2024-02-09 15:02:58 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " editors/visual_editors/grid_pattern " , 1 , " Lines,Dots " )
2022-08-03 11:38:29 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " editors/visual_editors/visual_shader/port_preview_size " , 160 , " 100,400,0.01 " )
2021-01-25 15:37:05 +01:00
2018-12-12 08:18:24 +01:00
/* Run */
// Window placement
2023-05-31 04:04:38 +02:00
# ifndef ANDROID_ENABLED
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " run/window_placement/rect " , 1 , " Top Left,Centered,Custom Position,Force Maximized,Force Fullscreen " )
2023-01-04 23:00:02 +01:00
// Keep the enum values in sync with the `DisplayServer::SCREEN_` enum.
2023-03-21 12:08:46 +01:00
String screen_hints = " Same as Editor:-5,Previous Screen:-4,Next Screen:-3,Primary Screen:-2 " ; // Note: Main Window Screen:-1 is not used for the main window.
2020-03-03 14:36:29 +01:00
for ( int i = 0 ; i < DisplayServer : : get_singleton ( ) - > get_screen_count ( ) ; i + + ) {
2023-03-21 12:08:46 +01:00
screen_hints + = " ,Screen " + itos ( i + 1 ) + " : " + itos ( i ) ;
2017-10-28 15:40:55 +02:00
}
_initial_set ( " run/window_placement/rect_custom_position " , Vector2 ( ) ) ;
2023-01-04 23:00:02 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " run/window_placement/screen " , - 5 , screen_hints )
2023-05-31 04:04:38 +02:00
# endif
// Should match the ANDROID_WINDOW_* constants in 'platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt'
String android_window_hints = " Auto (based on screen size):0,Same as Editor:1,Side-by-side with Editor:2 " ;
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " run/window_placement/android_window " , 0 , android_window_hints )
2017-10-28 15:40:55 +02:00
2024-03-08 04:16:25 +01:00
int default_play_window_pip_mode = 0 ;
# ifdef ANDROID_ENABLED
default_play_window_pip_mode = 2 ;
# endif
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " run/window_placement/play_window_pip_mode " , default_play_window_pip_mode , " Disabled:0,Enabled:1,Enabled when Play window is same as Editor:2 " )
2018-12-12 08:18:24 +01:00
// Auto save
2017-10-28 15:40:55 +02:00
_initial_set ( " run/auto_save/save_before_running " , true ) ;
2018-12-12 08:18:24 +01:00
2024-04-23 01:22:06 +02:00
// Bottom panel
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " run/bottom_panel/action_on_play " , EditorNode : : ACTION_ON_PLAY_OPEN_OUTPUT , " Do Nothing,Open Output,Open Debugger " )
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " run/bottom_panel/action_on_stop " , EditorNode : : ACTION_ON_STOP_DO_NOTHING , " Do Nothing,Close Bottom Panel " )
2018-12-12 08:18:24 +01:00
// Output
2021-08-16 07:30:24 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " run/output/font_size " , 13 , " 8,48,1 " )
2017-10-28 15:40:55 +02:00
_initial_set ( " run/output/always_clear_output_on_play " , true ) ;
2023-11-20 13:06:54 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " run/output/max_lines " , 10000 , " 100,100000,1 " )
Add Wayland support
Not everything is yet implemented, either for Godot or personal
limitations (I don't have all hardware in the world). A brief list of
the most important issues follows:
- Single-window only: the `DisplayServer` API doesn't expose enough
information for properly creating XDG shell windows.
- Very dumb rendering loop: this is very complicated, just know that
the low consumption mode is forced to 2000 Hz and some clever hacks are
in place to overcome a specific Wayland limitation. This will be
improved to the extent possible both downstream and upstream.
- Features to implement yet: IME, touch input, native file dialog,
drawing tablet (commented out due to a refactor), screen recording.
- Mouse passthrough can't be implement through a poly API, we need a
rect-based one.
- The cursor doesn't yet support fractional scaling.
- Auto scale is rounded up when using fractional scaling as we don't
have a per-window scale query API (basically we need
`DisplayServer::window_get_scale`).
- Building with `x11=no wayland=yes opengl=yes openxr=yes` fails.
This also adds a new project property and editor setting for selecting the
default DisplayServer to start, to allow this backend to start first in
exported projects (X11 is still the default for now). The editor setting
always overrides the project setting.
Special thanks to Drew Devault, toger5, Sebastian Krzyszkowiak, Leandro
Benedet Garcia, Subhransu, Yury Zhuravlev and Mara Huldra.
2023-12-15 02:55:34 +01:00
// Platform
_initial_set ( " run/platforms/linuxbsd/prefer_wayland " , false ) ;
set_restart_if_changed ( " run/platforms/linuxbsd/prefer_wayland " , true ) ;
2019-08-21 17:05:06 +02:00
/* Network */
2024-01-30 17:35:46 +01:00
// General
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " network/connection/network_mode " , 0 , " Offline,Online " ) ;
2019-08-21 17:05:06 +02:00
2024-01-30 17:35:46 +01:00
// HTTP Proxy
_initial_set ( " network/http_proxy/host " , " " ) ;
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " network/http_proxy/port " , 8080 , " 1,65535,1 " )
2019-08-21 17:05:06 +02:00
// SSL
2022-09-07 08:25:47 +02:00
EDITOR_SETTING_USAGE ( Variant : : STRING , PROPERTY_HINT_GLOBAL_FILE , " network/tls/editor_tls_certificates " , _SYSTEM_CERTS_PATH , " *.crt,*.pem " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED ) ;
2019-08-21 17:05:06 +02:00
2024-01-30 17:35:46 +01:00
// Debug
_initial_set ( " network/debug/remote_host " , " 127.0.0.1 " ) ; // Hints provided in setup_network
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " network/debug/remote_port " , 6007 , " 1,65535,1 " )
/* Debugger/profiler */
2023-03-22 01:05:53 +01:00
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " debugger/auto_switch_to_remote_scene_tree " , false , " " )
2022-05-28 01:03:32 +02:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " debugger/profiler_frame_history_size " , 3600 , " 60,10000,1 " )
2023-03-22 01:05:53 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_RANGE , " debugger/profiler_frame_max_functions " , 64 , " 16,512,1 " )
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " debugger/remote_scene_tree_refresh_interval " , 1.0 , " 0.1,10,0.01,or_greater " )
EDITOR_SETTING ( Variant : : FLOAT , PROPERTY_HINT_RANGE , " debugger/remote_inspect_refresh_interval " , 0.2 , " 0.02,10,0.01,or_greater " )
2023-03-05 13:37:11 +01:00
EDITOR_SETTING ( Variant : : BOOL , PROPERTY_HINT_NONE , " debugger/profile_native_calls " , false , " " )
2022-03-06 21:39:19 +01:00
2018-12-12 08:18:24 +01:00
/* Extra config */
2017-10-28 15:40:55 +02:00
2024-07-07 23:16:29 +02:00
EDITOR_SETTING_USAGE ( Variant : : BOOL , PROPERTY_HINT_NONE , " input/buffering/agile_event_flushing " , false , " " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
EDITOR_SETTING_USAGE ( Variant : : BOOL , PROPERTY_HINT_NONE , " input/buffering/use_accumulated_input " , true , " " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED )
2022-06-08 11:42:51 +02:00
// TRANSLATORS: Project Manager here refers to the tool used to create/manage Godot projects.
2021-11-07 22:50:29 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " project_manager/sorting_order " , 0 , " Last Edited,Name,Path " )
2024-02-22 14:27:04 +01:00
EDITOR_SETTING ( Variant : : INT , PROPERTY_HINT_ENUM , " project_manager/directory_naming_convention " , 1 , " No convention,kebab-case,snake_case,camelCase,PascalCase,Title Case " )
2023-01-31 17:23:59 +01:00
# if defined(WEB_ENABLED)
// Web platform only supports `gl_compatibility`.
2023-04-22 01:51:57 +02:00
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_ENUM , " project_manager/default_renderer " , " gl_compatibility " , " forward_plus,mobile,gl_compatibility " )
2023-01-31 17:23:59 +01:00
# elif defined(ANDROID_ENABLED)
// Use more suitable rendering method by default.
2023-04-22 01:51:57 +02:00
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_ENUM , " project_manager/default_renderer " , " mobile " , " forward_plus,mobile,gl_compatibility " )
2023-01-31 17:23:59 +01:00
# else
2023-04-22 01:51:57 +02:00
EDITOR_SETTING ( Variant : : STRING , PROPERTY_HINT_ENUM , " project_manager/default_renderer " , " forward_plus " , " forward_plus,mobile,gl_compatibility " )
2023-01-31 17:23:59 +01:00
# endif
2018-12-12 21:12:41 +01:00
2017-10-28 15:40:55 +02:00
if ( p_extra_config . is_valid ( ) ) {
if ( p_extra_config - > has_section ( " init_projects " ) & & p_extra_config - > has_section_key ( " init_projects " , " list " ) ) {
Vector < String > list = p_extra_config - > get_value ( " init_projects " , " list " ) ;
for ( int i = 0 ; i < list . size ( ) ; i + + ) {
2022-09-29 11:53:28 +02:00
String proj_name = list [ i ] . replace ( " / " , " :: " ) ;
set ( " projects/ " + proj_name , list [ i ] ) ;
2021-06-09 10:47:32 +02:00
}
}
2017-10-28 15:40:55 +02:00
if ( p_extra_config - > has_section ( " presets " ) ) {
List < String > keys ;
p_extra_config - > get_section_keys ( " presets " , & keys ) ;
2021-07-24 15:46:25 +02:00
for ( const String & key : keys ) {
2017-10-28 15:40:55 +02:00
Variant val = p_extra_config - > get_value ( " presets " , key ) ;
set ( key , val ) ;
2021-06-09 10:47:32 +02:00
}
}
}
2017-10-28 15:40:55 +02:00
}
2021-05-27 10:22:36 +02:00
void EditorSettings : : _load_godot2_text_editor_theme ( ) {
// Godot 2 is only a dark theme; it doesn't have a light theme counterpart.
2021-08-15 19:14:46 +02:00
_initial_set ( " text_editor/theme/highlighting/symbol_color " , Color ( 0.73 , 0.87 , 1.0 ) ) ;
_initial_set ( " text_editor/theme/highlighting/keyword_color " , Color ( 1.0 , 1.0 , 0.7 ) ) ;
_initial_set ( " text_editor/theme/highlighting/control_flow_keyword_color " , Color ( 1.0 , 0.85 , 0.7 ) ) ;
_initial_set ( " text_editor/theme/highlighting/base_type_color " , Color ( 0.64 , 1.0 , 0.83 ) ) ;
_initial_set ( " text_editor/theme/highlighting/engine_type_color " , Color ( 0.51 , 0.83 , 1.0 ) ) ;
_initial_set ( " text_editor/theme/highlighting/user_type_color " , Color ( 0.42 , 0.67 , 0.93 ) ) ;
_initial_set ( " text_editor/theme/highlighting/comment_color " , Color ( 0.4 , 0.4 , 0.4 ) ) ;
2023-02-05 10:01:01 +01:00
_initial_set ( " text_editor/theme/highlighting/doc_comment_color " , Color ( 0.5 , 0.6 , 0.7 ) ) ;
2021-08-15 19:14:46 +02:00
_initial_set ( " text_editor/theme/highlighting/string_color " , Color ( 0.94 , 0.43 , 0.75 ) ) ;
_initial_set ( " text_editor/theme/highlighting/background_color " , Color ( 0.13 , 0.12 , 0.15 ) ) ;
_initial_set ( " text_editor/theme/highlighting/completion_background_color " , Color ( 0.17 , 0.16 , 0.2 ) ) ;
_initial_set ( " text_editor/theme/highlighting/completion_selected_color " , Color ( 0.26 , 0.26 , 0.27 ) ) ;
2021-09-21 17:59:01 +02:00
_initial_set ( " text_editor/theme/highlighting/completion_existing_color " , Color ( 0.87 , 0.87 , 0.87 , 0.13 ) ) ;
2022-02-14 14:41:22 +01:00
_initial_set ( " text_editor/theme/highlighting/completion_scroll_color " , Color ( 1 , 1 , 1 , 0.29 ) ) ;
2022-06-27 11:27:17 +02:00
_initial_set ( " text_editor/theme/highlighting/completion_scroll_hovered_color " , Color ( 1 , 1 , 1 , 0.4 ) ) ;
2021-08-15 19:14:46 +02:00
_initial_set ( " text_editor/theme/highlighting/completion_font_color " , Color ( 0.67 , 0.67 , 0.67 ) ) ;
_initial_set ( " text_editor/theme/highlighting/text_color " , Color ( 0.67 , 0.67 , 0.67 ) ) ;
_initial_set ( " text_editor/theme/highlighting/line_number_color " , Color ( 0.67 , 0.67 , 0.67 , 0.4 ) ) ;
_initial_set ( " text_editor/theme/highlighting/safe_line_number_color " , Color ( 0.67 , 0.78 , 0.67 , 0.6 ) ) ;
_initial_set ( " text_editor/theme/highlighting/caret_color " , Color ( 0.67 , 0.67 , 0.67 ) ) ;
_initial_set ( " text_editor/theme/highlighting/caret_background_color " , Color ( 0 , 0 , 0 ) ) ;
2022-10-26 00:46:06 +02:00
_initial_set ( " text_editor/theme/highlighting/text_selected_color " , Color ( 0 , 0 , 0 , 0 ) ) ;
2021-08-15 19:14:46 +02:00
_initial_set ( " text_editor/theme/highlighting/selection_color " , Color ( 0.41 , 0.61 , 0.91 , 0.35 ) ) ;
_initial_set ( " text_editor/theme/highlighting/brace_mismatch_color " , Color ( 1 , 0.2 , 0.2 ) ) ;
_initial_set ( " text_editor/theme/highlighting/current_line_color " , Color ( 0.3 , 0.5 , 0.8 , 0.15 ) ) ;
_initial_set ( " text_editor/theme/highlighting/line_length_guideline_color " , Color ( 0.3 , 0.5 , 0.8 , 0.1 ) ) ;
_initial_set ( " text_editor/theme/highlighting/word_highlighted_color " , Color ( 0.8 , 0.9 , 0.9 , 0.15 ) ) ;
_initial_set ( " text_editor/theme/highlighting/number_color " , Color ( 0.92 , 0.58 , 0.2 ) ) ;
_initial_set ( " text_editor/theme/highlighting/function_color " , Color ( 0.4 , 0.64 , 0.81 ) ) ;
_initial_set ( " text_editor/theme/highlighting/member_variable_color " , Color ( 0.9 , 0.31 , 0.35 ) ) ;
_initial_set ( " text_editor/theme/highlighting/mark_color " , Color ( 1.0 , 0.4 , 0.4 , 0.4 ) ) ;
_initial_set ( " text_editor/theme/highlighting/bookmark_color " , Color ( 0.08 , 0.49 , 0.98 ) ) ;
_initial_set ( " text_editor/theme/highlighting/breakpoint_color " , Color ( 0.9 , 0.29 , 0.3 ) ) ;
_initial_set ( " text_editor/theme/highlighting/executing_line_color " , Color ( 0.98 , 0.89 , 0.27 ) ) ;
_initial_set ( " text_editor/theme/highlighting/code_folding_color " , Color ( 0.8 , 0.8 , 0.8 , 0.8 ) ) ;
2023-03-12 17:48:37 +01:00
_initial_set ( " text_editor/theme/highlighting/folded_code_region_color " , Color ( 0.68 , 0.46 , 0.77 , 0.2 ) ) ;
2021-08-15 19:14:46 +02:00
_initial_set ( " text_editor/theme/highlighting/search_result_color " , Color ( 0.05 , 0.25 , 0.05 , 1 ) ) ;
_initial_set ( " text_editor/theme/highlighting/search_result_border_color " , Color ( 0.41 , 0.61 , 0.91 , 0.38 ) ) ;
2017-10-28 15:40:55 +02:00
}
2024-02-09 15:02:58 +01:00
void EditorSettings : : _load_default_visual_shader_editor_theme ( ) {
// Connection type colors
_initial_set ( " editors/visual_editors/connection_colors/scalar_color " , Color ( 0.55 , 0.55 , 0.55 ) ) ;
_initial_set ( " editors/visual_editors/connection_colors/vector2_color " , Color ( 0.44 , 0.43 , 0.64 ) ) ;
_initial_set ( " editors/visual_editors/connection_colors/vector3_color " , Color ( 0.337 , 0.314 , 0.71 ) ) ;
_initial_set ( " editors/visual_editors/connection_colors/vector4_color " , Color ( 0.7 , 0.65 , 0.147 ) ) ;
_initial_set ( " editors/visual_editors/connection_colors/boolean_color " , Color ( 0.243 , 0.612 , 0.349 ) ) ;
_initial_set ( " editors/visual_editors/connection_colors/transform_color " , Color ( 0.71 , 0.357 , 0.64 ) ) ;
_initial_set ( " editors/visual_editors/connection_colors/sampler_color " , Color ( 0.659 , 0.4 , 0.137 ) ) ;
// Node category colors (used for the node headers)
_initial_set ( " editors/visual_editors/category_colors/output_color " , Color ( 0.26 , 0.10 , 0.15 ) ) ;
_initial_set ( " editors/visual_editors/category_colors/color_color " , Color ( 0.5 , 0.5 , 0.1 ) ) ;
_initial_set ( " editors/visual_editors/category_colors/conditional_color " , Color ( 0.208 , 0.522 , 0.298 ) ) ;
_initial_set ( " editors/visual_editors/category_colors/input_color " , Color ( 0.502 , 0.2 , 0.204 ) ) ;
_initial_set ( " editors/visual_editors/category_colors/scalar_color " , Color ( 0.1 , 0.5 , 0.6 ) ) ;
_initial_set ( " editors/visual_editors/category_colors/textures_color " , Color ( 0.5 , 0.3 , 0.1 ) ) ;
_initial_set ( " editors/visual_editors/category_colors/transform_color " , Color ( 0.5 , 0.3 , 0.5 ) ) ;
_initial_set ( " editors/visual_editors/category_colors/utility_color " , Color ( 0.2 , 0.2 , 0.2 ) ) ;
_initial_set ( " editors/visual_editors/category_colors/vector_color " , Color ( 0.2 , 0.2 , 0.5 ) ) ;
_initial_set ( " editors/visual_editors/category_colors/special_color " , Color ( 0.098 , 0.361 , 0.294 ) ) ;
_initial_set ( " editors/visual_editors/category_colors/particle_color " , Color ( 0.12 , 0.358 , 0.8 ) ) ;
}
2024-02-15 17:25:58 +01:00
bool EditorSettings : : _save_text_editor_theme ( const String & p_file ) {
2017-10-28 15:40:55 +02:00
String theme_section = " color_theme " ;
Ref < ConfigFile > cf = memnew ( ConfigFile ) ; // hex is better?
2018-06-10 14:06:24 +02:00
List < String > keys ;
2022-05-08 10:09:19 +02:00
for ( const KeyValue < String , VariantContainer > & E : props ) {
keys . push_back ( E . key ) ;
}
2018-06-10 14:06:24 +02:00
keys . sort ( ) ;
2021-07-16 05:45:57 +02:00
for ( const String & key : keys ) {
2024-05-06 16:20:20 +02:00
if ( key . begins_with ( " text_editor/theme/highlighting/ " ) & & key . contains ( " color " ) ) {
2021-08-15 19:14:46 +02:00
cf - > set_value ( theme_section , key . replace ( " text_editor/theme/highlighting/ " , " " ) , ( ( Color ) props [ key ] . variant ) . to_html ( ) ) ;
2018-06-10 14:06:24 +02:00
}
}
2018-04-12 23:26:15 +02:00
2017-10-28 15:40:55 +02:00
Error err = cf - > save ( p_file ) ;
2019-06-26 15:08:25 +02:00
return err = = OK ;
2017-10-28 15:40:55 +02:00
}
2024-02-15 17:25:58 +01:00
bool EditorSettings : : _is_default_text_editor_theme ( const String & p_theme_name ) {
2021-05-27 10:22:36 +02:00
return p_theme_name = = " default " | | p_theme_name = = " godot 2 " | | p_theme_name = = " custom " ;
2019-05-23 17:18:24 +02:00
}
2023-07-22 13:36:51 +02:00
const String EditorSettings : : _get_project_metadata_path ( ) const {
return EditorPaths : : get_singleton ( ) - > get_project_settings_dir ( ) . path_join ( " project_metadata.cfg " ) ;
}
2024-07-30 00:24:19 +02:00
# ifndef DISABLE_DEPRECATED
void EditorSettings : : _remove_deprecated_settings ( ) {
erase ( " run/output/always_open_output_on_play " ) ;
erase ( " run/output/always_close_output_on_stop " ) ;
}
# endif
2017-10-28 15:40:55 +02:00
// PUBLIC METHODS
EditorSettings * EditorSettings : : get_singleton ( ) {
return singleton . ptr ( ) ;
}
2024-04-19 00:09:15 +02:00
String EditorSettings : : get_existing_settings_path ( ) {
const String config_dir = EditorPaths : : get_singleton ( ) - > get_config_dir ( ) ;
int minor = VERSION_MINOR ;
String filename ;
do {
if ( VERSION_MAJOR = = 4 & & minor < 3 ) {
// Minor version is used since 4.3, so special case to load older settings.
filename = vformat ( " editor_settings-%d.tres " , VERSION_MAJOR ) ;
minor = - 1 ;
} else {
filename = vformat ( " editor_settings-%d.%d.tres " , VERSION_MAJOR , minor ) ;
minor - - ;
}
} while ( minor > = 0 & & ! FileAccess : : exists ( config_dir . path_join ( filename ) ) ) ;
return config_dir . path_join ( filename ) ;
}
String EditorSettings : : get_newest_settings_path ( ) {
const String config_file_name = vformat ( " editor_settings-%d.%d.tres " , VERSION_MAJOR , VERSION_MINOR ) ;
return EditorPaths : : get_singleton ( ) - > get_config_dir ( ) . path_join ( config_file_name ) ;
}
2017-10-28 15:40:55 +02:00
void EditorSettings : : create ( ) {
2021-06-09 10:47:32 +02:00
// IMPORTANT: create() *must* create a valid EditorSettings singleton,
// as the rest of the engine code will assume it. As such, it should never
// return (incl. via ERR_FAIL) without initializing the singleton member.
2020-05-14 16:41:43 +02:00
if ( singleton . ptr ( ) ) {
2021-06-09 10:47:32 +02:00
ERR_PRINT ( " Can't recreate EditorSettings as it already exists. " ) ;
return ;
2020-05-14 16:41:43 +02:00
}
2017-10-28 15:40:55 +02:00
2021-06-09 10:47:32 +02:00
String config_file_path ;
2017-10-28 15:40:55 +02:00
Ref < ConfigFile > extra_config = memnew ( ConfigFile ) ;
2021-06-09 10:47:32 +02:00
if ( ! EditorPaths : : get_singleton ( ) ) {
ERR_PRINT ( " Bug (please report): EditorPaths haven't been initialized, EditorSettings cannot be created properly. " ) ;
goto fail ;
}
2021-05-25 02:25:11 +02:00
if ( EditorPaths : : get_singleton ( ) - > is_self_contained ( ) ) {
Error err = extra_config - > load ( EditorPaths : : get_singleton ( ) - > get_self_contained_file ( ) ) ;
2019-08-07 12:54:30 +02:00
if ( err ! = OK ) {
2021-06-09 10:47:32 +02:00
ERR_PRINT ( " Can't load extra config from path: " + EditorPaths : : get_singleton ( ) - > get_self_contained_file ( ) ) ;
2019-08-07 12:54:30 +02:00
}
2017-10-28 15:40:55 +02:00
}
2021-05-25 02:25:11 +02:00
if ( EditorPaths : : get_singleton ( ) - > are_paths_valid ( ) ) {
2021-06-09 10:47:32 +02:00
// Validate editor config file.
2024-04-19 00:09:15 +02:00
ERR_FAIL_COND ( ! DirAccess : : dir_exists_absolute ( EditorPaths : : get_singleton ( ) - > get_config_dir ( ) ) ) ;
2023-09-26 04:07:43 +02:00
2024-04-19 00:09:15 +02:00
config_file_path = get_existing_settings_path ( ) ;
if ( ! FileAccess : : exists ( config_file_path ) ) {
config_file_path = get_newest_settings_path ( ) ;
2017-01-05 23:41:36 +01:00
goto fail ;
2014-02-10 02:10:30 +01:00
}
2017-11-17 15:50:18 +01:00
singleton = ResourceLoader : : load ( config_file_path , " EditorSettings " ) ;
2014-02-10 02:10:30 +01:00
if ( singleton . is_null ( ) ) {
2021-06-09 10:47:32 +02:00
ERR_PRINT ( " Could not load editor settings from path: " + config_file_path ) ;
2024-07-21 19:26:15 +02:00
config_file_path = get_newest_settings_path ( ) ;
2014-02-10 02:10:30 +01:00
goto fail ;
}
2024-07-21 19:26:15 +02:00
singleton - > set_path ( get_newest_settings_path ( ) ) ; // Settings can be loaded from older version file, so make sure it's newest.
2017-03-05 16:44:50 +01:00
singleton - > save_changed_setting = true ;
2014-02-10 02:10:30 +01:00
2018-08-24 08:47:34 +02:00
print_verbose ( " EditorSettings: Load OK! " ) ;
2014-02-10 02:10:30 +01:00
2016-05-28 00:58:28 +02:00
singleton - > setup_language ( ) ;
2015-08-06 07:37:40 +02:00
singleton - > setup_network ( ) ;
2022-02-03 01:21:52 +01:00
singleton - > load_favorites_and_recent_dirs ( ) ;
2016-04-12 16:45:31 +02:00
singleton - > list_text_editor_themes ( ) ;
2024-07-30 00:24:19 +02:00
# ifndef DISABLE_DEPRECATED
singleton - > _remove_deprecated_settings ( ) ;
# endif
2014-02-10 02:10:30 +01:00
return ;
}
2017-10-28 15:40:55 +02:00
fail :
// patch init projects
2021-05-25 02:25:11 +02:00
String exe_path = OS : : get_singleton ( ) - > get_executable_path ( ) . get_base_dir ( ) ;
2017-10-28 15:40:55 +02:00
if ( extra_config - > has_section ( " init_projects " ) ) {
Vector < String > list = extra_config - > get_value ( " init_projects " , " list " ) ;
for ( int i = 0 ; i < list . size ( ) ; i + + ) {
2022-08-30 02:34:01 +02:00
list . write [ i ] = exe_path . path_join ( list [ i ] ) ;
2021-06-09 10:47:32 +02:00
}
2017-10-28 15:40:55 +02:00
extra_config - > set_value ( " init_projects " , " list " , list ) ;
2021-06-09 10:47:32 +02:00
}
2017-01-05 23:41:36 +01:00
2017-10-28 15:40:55 +02:00
singleton = Ref < EditorSettings > ( memnew ( EditorSettings ) ) ;
2022-06-03 01:33:42 +02:00
singleton - > set_path ( config_file_path , true ) ;
2017-10-28 15:40:55 +02:00
singleton - > save_changed_setting = true ;
singleton - > _load_defaults ( extra_config ) ;
singleton - > setup_language ( ) ;
singleton - > setup_network ( ) ;
singleton - > list_text_editor_themes ( ) ;
}
2017-01-05 23:41:36 +01:00
2017-10-28 15:40:55 +02:00
void EditorSettings : : setup_language ( ) {
String lang = get ( " interface/editor/editor_language " ) ;
2020-05-14 16:41:43 +02:00
if ( lang = = " en " ) {
2020-03-18 18:34:36 +01:00
return ; // Default, nothing to do.
2020-05-14 16:41:43 +02:00
}
2020-03-18 18:34:36 +01:00
// Load editor translation for configured/detected locale.
2021-12-15 16:01:06 +01:00
load_editor_translations ( lang ) ;
2022-12-27 03:58:01 +01:00
load_property_translations ( lang ) ;
2020-03-18 18:34:36 +01:00
// Load class reference translation.
2021-12-15 16:01:06 +01:00
load_doc_translations ( lang ) ;
2023-12-16 00:56:06 +01:00
// Load extractable translation for projects.
load_extractable_translations ( lang ) ;
2017-10-28 15:40:55 +02:00
}
2017-09-19 02:30:48 +02:00
2017-10-28 15:40:55 +02:00
void EditorSettings : : setup_network ( ) {
2021-05-06 02:48:18 +02:00
List < IPAddress > local_ip ;
2017-10-28 15:40:55 +02:00
IP : : get_singleton ( ) - > get_local_addresses ( & local_ip ) ;
String hint ;
String current = has_setting ( " network/debug/remote_host " ) ? get ( " network/debug/remote_host " ) : " " ;
2019-08-21 17:05:06 +02:00
String selected = " 127.0.0.1 " ;
2017-01-05 23:41:36 +01:00
2019-08-21 17:05:06 +02:00
// Check that current remote_host is a valid interface address and populate hints.
2021-07-24 15:46:25 +02:00
for ( const IPAddress & ip : local_ip ) {
2017-10-28 15:40:55 +02:00
// link-local IPv6 addresses don't work, skipping them
2021-07-16 05:45:57 +02:00
if ( String ( ip ) . begins_with ( " fe80:0:0:0: " ) ) { // fe80::/64
2017-10-28 15:40:55 +02:00
continue ;
2020-05-14 16:41:43 +02:00
}
2019-03-31 16:57:23 +02:00
// Same goes for IPv4 link-local (APIPA) addresses.
2021-07-16 05:45:57 +02:00
if ( String ( ip ) . begins_with ( " 169.254. " ) ) { // 169.254.0.0/16
2019-03-31 16:57:23 +02:00
continue ;
2020-05-14 16:41:43 +02:00
}
2019-08-21 17:05:06 +02:00
// Select current IP (found)
2020-05-14 16:41:43 +02:00
if ( ip = = current ) {
2019-08-21 17:05:06 +02:00
selected = ip ;
2020-05-14 16:41:43 +02:00
}
2021-12-09 10:42:46 +01:00
if ( ! hint . is_empty ( ) ) {
2017-10-28 15:40:55 +02:00
hint + = " , " ;
2020-05-14 16:41:43 +02:00
}
2017-10-28 15:40:55 +02:00
hint + = ip ;
}
2017-05-01 20:57:35 +02:00
2019-08-21 17:05:06 +02:00
// Add hints with valid IP addresses to remote_host property.
2017-10-28 15:40:55 +02:00
add_property_hint ( PropertyInfo ( Variant : : STRING , " network/debug/remote_host " , PROPERTY_HINT_ENUM , hint ) ) ;
2019-08-21 17:05:06 +02:00
// Fix potentially invalid remote_host due to network change.
set ( " network/debug/remote_host " , selected ) ;
2017-10-28 15:40:55 +02:00
}
2017-04-25 14:18:08 +02:00
2017-10-28 15:40:55 +02:00
void EditorSettings : : save ( ) {
//_THREAD_SAFE_METHOD_
2014-02-10 02:10:30 +01:00
2020-05-14 16:41:43 +02:00
if ( ! singleton . ptr ( ) ) {
2017-10-28 15:40:55 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
2022-06-03 01:33:42 +02:00
Error err = ResourceSaver : : save ( singleton ) ;
2016-08-16 18:25:42 +02:00
2017-10-28 15:40:55 +02:00
if ( err ! = OK ) {
2022-06-03 01:33:42 +02:00
ERR_PRINT ( " Error saving editor settings to " + singleton - > get_path ( ) ) ;
2018-08-24 08:47:34 +02:00
} else {
2021-10-15 14:34:11 +02:00
singleton - > changed_settings . clear ( ) ;
2018-08-24 08:47:34 +02:00
print_verbose ( " EditorSettings: Save OK! " ) ;
2017-10-28 15:40:55 +02:00
}
}
2014-02-10 02:10:30 +01:00
2022-08-05 03:41:48 +02:00
PackedStringArray EditorSettings : : get_changed_settings ( ) const {
PackedStringArray arr ;
2021-10-15 14:34:11 +02:00
for ( const String & setting : changed_settings ) {
arr . push_back ( setting ) ;
}
return arr ;
}
bool EditorSettings : : check_changed_settings_in_group ( const String & p_setting_prefix ) const {
for ( const String & setting : changed_settings ) {
if ( setting . begins_with ( p_setting_prefix ) ) {
return true ;
}
}
return false ;
}
void EditorSettings : : mark_setting_changed ( const String & p_setting ) {
changed_settings . insert ( p_setting ) ;
}
2017-10-28 15:40:55 +02:00
void EditorSettings : : destroy ( ) {
2020-05-14 16:41:43 +02:00
if ( ! singleton . ptr ( ) ) {
2017-10-28 15:40:55 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2017-10-28 15:40:55 +02:00
save ( ) ;
singleton = Ref < EditorSettings > ( ) ;
}
2014-02-10 02:10:30 +01:00
2017-10-28 15:40:55 +02:00
void EditorSettings : : set_optimize_save ( bool p_optimize ) {
optimize_save = p_optimize ;
}
2016-05-27 19:18:40 +02:00
2017-10-28 15:40:55 +02:00
// Properties
2016-02-22 00:15:47 +01:00
2017-10-28 15:40:55 +02:00
void EditorSettings : : set_setting ( const String & p_setting , const Variant & p_value ) {
_THREAD_SAFE_METHOD_
set ( p_setting , p_value ) ;
}
2016-02-27 16:11:40 +01:00
2017-10-28 15:40:55 +02:00
Variant EditorSettings : : get_setting ( const String & p_setting ) const {
_THREAD_SAFE_METHOD_
return get ( p_setting ) ;
}
2016-02-27 16:11:40 +01:00
2017-10-31 15:24:35 +01:00
bool EditorSettings : : has_setting ( const String & p_setting ) const {
2017-10-28 15:40:55 +02:00
_THREAD_SAFE_METHOD_
2016-02-27 16:11:40 +01:00
2017-10-31 15:24:35 +01:00
return props . has ( p_setting ) ;
2017-10-28 15:40:55 +02:00
}
2016-02-27 16:11:40 +01:00
2017-10-31 15:24:35 +01:00
void EditorSettings : : erase ( const String & p_setting ) {
2017-10-28 15:40:55 +02:00
_THREAD_SAFE_METHOD_
2017-10-31 15:24:35 +01:00
props . erase ( p_setting ) ;
2016-04-12 16:45:31 +02:00
}
2017-10-31 15:24:35 +01:00
void EditorSettings : : raise_order ( const String & p_setting ) {
2017-10-28 15:40:55 +02:00
_THREAD_SAFE_METHOD_
2017-10-31 15:24:35 +01:00
ERR_FAIL_COND ( ! props . has ( p_setting ) ) ;
props [ p_setting ] . order = + + last_order ;
2014-02-10 02:10:30 +01:00
}
2018-07-19 23:58:15 +02:00
void EditorSettings : : set_restart_if_changed ( const StringName & p_setting , bool p_restart ) {
_THREAD_SAFE_METHOD_
2020-05-14 16:41:43 +02:00
if ( ! props . has ( p_setting ) ) {
2018-07-19 23:58:15 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2018-07-19 23:58:15 +02:00
props [ p_setting ] . restart_if_changed = p_restart ;
}
2018-01-09 16:52:46 +01:00
void EditorSettings : : set_initial_value ( const StringName & p_setting , const Variant & p_value , bool p_update_current ) {
2017-11-30 04:11:53 +01:00
_THREAD_SAFE_METHOD_
2020-05-14 16:41:43 +02:00
if ( ! props . has ( p_setting ) ) {
2017-11-17 21:22:27 +01:00
return ;
2020-05-14 16:41:43 +02:00
}
2018-01-07 20:39:38 +01:00
props [ p_setting ] . initial = p_value ;
props [ p_setting ] . has_default_value = true ;
2018-01-09 16:52:46 +01:00
if ( p_update_current ) {
2018-01-07 20:39:38 +01:00
set ( p_setting , p_value ) ;
}
2017-10-28 15:40:55 +02:00
}
2014-02-10 02:10:30 +01:00
2018-07-19 23:58:15 +02:00
Variant _EDITOR_DEF ( const String & p_setting , const Variant & p_default , bool p_restart_if_changed ) {
2021-10-21 22:21:41 +02:00
ERR_FAIL_NULL_V_MSG ( EditorSettings : : get_singleton ( ) , p_default , " EditorSettings not instantiated yet. " ) ;
2017-10-28 23:25:28 +02:00
Variant ret = p_default ;
2018-07-19 23:58:15 +02:00
if ( EditorSettings : : get_singleton ( ) - > has_setting ( p_setting ) ) {
2022-10-18 16:43:37 +02:00
ret = EDITOR_GET ( p_setting ) ;
2018-07-19 23:58:15 +02:00
} else {
2017-11-30 04:11:53 +01:00
EditorSettings : : get_singleton ( ) - > set_manually ( p_setting , p_default ) ;
2018-07-19 23:58:15 +02:00
}
2023-10-06 09:02:03 +02:00
EditorSettings : : get_singleton ( ) - > set_restart_if_changed ( p_setting , p_restart_if_changed ) ;
2017-11-30 04:11:53 +01:00
2018-07-19 23:58:15 +02:00
if ( ! EditorSettings : : get_singleton ( ) - > has_default_value ( p_setting ) ) {
2017-11-20 18:34:13 +01:00
EditorSettings : : get_singleton ( ) - > set_initial_value ( p_setting , p_default ) ;
2018-07-19 23:58:15 +02:00
}
2014-02-10 02:10:30 +01:00
2017-10-28 23:25:28 +02:00
return ret ;
2017-10-28 15:40:55 +02:00
}
2014-02-10 02:10:30 +01:00
2017-10-31 15:24:35 +01:00
Variant _EDITOR_GET ( const String & p_setting ) {
2021-10-21 22:21:41 +02:00
ERR_FAIL_COND_V ( ! EditorSettings : : get_singleton ( ) | | ! EditorSettings : : get_singleton ( ) - > has_setting ( p_setting ) , Variant ( ) ) ;
2017-10-31 15:24:35 +01:00
return EditorSettings : : get_singleton ( ) - > get ( p_setting ) ;
2014-02-10 02:10:30 +01:00
}
2022-08-12 20:43:14 +02:00
bool EditorSettings : : _property_can_revert ( const StringName & p_name ) const {
if ( ! props . has ( p_name ) ) {
2017-10-28 15:40:55 +02:00
return false ;
2020-05-14 16:41:43 +02:00
}
2016-08-16 22:10:53 +02:00
2022-08-12 20:43:14 +02:00
if ( ! props [ p_name ] . has_default_value ) {
2017-11-30 04:11:53 +01:00
return false ;
2020-05-14 16:41:43 +02:00
}
2017-11-30 04:11:53 +01:00
2022-08-12 20:43:14 +02:00
return props [ p_name ] . initial ! = props [ p_name ] . variant ;
2017-10-28 15:40:55 +02:00
}
2016-08-16 22:10:53 +02:00
2022-08-12 20:43:14 +02:00
bool EditorSettings : : _property_get_revert ( const StringName & p_name , Variant & r_property ) const {
if ( ! props . has ( p_name ) | | ! props [ p_name ] . has_default_value ) {
return false ;
2020-05-14 16:41:43 +02:00
}
2017-10-28 15:40:55 +02:00
2022-08-12 20:43:14 +02:00
r_property = props [ p_name ] . initial ;
return true ;
2016-08-16 22:10:53 +02:00
}
2017-03-05 16:44:50 +01:00
void EditorSettings : : add_property_hint ( const PropertyInfo & p_hint ) {
2014-02-10 02:10:30 +01:00
_THREAD_SAFE_METHOD_
2017-03-05 16:44:50 +01:00
hints [ p_hint . name ] = p_hint ;
2014-02-10 02:10:30 +01:00
}
Add initial support for the XDG Base Directory spec
Spec version 0.7 from https://standards.freedesktop.org/basedir-spec/basedir-spec-0.7.html
(latest as of this commit).
Three virtual methods are added to OS for the various XDG paths we will use:
- OS::get_data_path gives XDG_DATA_HOME, or if missing:
~/.local/share on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_config_path gives XDG_CONFIG_HOME, or if missing:
~/.config on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_cache_path gives XDG_CACHE_HOME, or if missing:
~/.cache on X11, ~/Library/Caches on macOS and %APPDATA% on Windows
So for Windows there are no changes, for Linux we follow the full split spec
and for macOS stuff will move from ~/.godot to ~/Library/Application Support/Godot.
Support for system-wide installation of templates on Unix was removed for now,
as it's a bit hackish and I don't think anyone uses it.
user:// will still be OS::get_data_path() + "/godot/app_userdata/$name" by
default, but when using the application/config/use_shared_user_dir option
it will now use XDG_DATA_HOME/$name, e.g. ~/.local/share/MyGame.
For now everything still goes in EditorSettings::get_settings_dir(), but
this will be changed in a later commit to make use of the new splitting
where relevant.
Part of #3513.
2017-11-17 17:11:41 +01:00
// Metadata
2024-02-15 17:25:58 +01:00
void EditorSettings : : set_project_metadata ( const String & p_section , const String & p_key , const Variant & p_data ) {
2023-07-22 13:36:51 +02:00
const String path = _get_project_metadata_path ( ) ;
if ( project_metadata . is_null ( ) ) {
project_metadata . instantiate ( ) ;
Error err = project_metadata - > load ( path ) ;
if ( err ! = OK & & err ! = ERR_FILE_NOT_FOUND ) {
ERR_PRINT ( " Cannot load project metadata from file ' " + path + " '. " ) ;
}
}
project_metadata - > set_value ( p_section , p_key , p_data ) ;
Error err = project_metadata - > save ( path ) ;
ERR_FAIL_COND_MSG ( err ! = OK , " Cannot save project metadata to file ' " + path + " '. " ) ;
2017-10-28 15:40:55 +02:00
}
2024-02-15 17:25:58 +01:00
Variant EditorSettings : : get_project_metadata ( const String & p_section , const String & p_key , const Variant & p_default ) const {
2023-07-22 13:36:51 +02:00
if ( project_metadata . is_null ( ) ) {
project_metadata . instantiate ( ) ;
const String path = _get_project_metadata_path ( ) ;
Error err = project_metadata - > load ( path ) ;
ERR_FAIL_COND_V_MSG ( err ! = OK & & err ! = ERR_FILE_NOT_FOUND , p_default , " Cannot load project metadata from file ' " + path + " '. " ) ;
2017-10-28 15:40:55 +02:00
}
2023-07-22 13:36:51 +02:00
return project_metadata - > get_value ( p_section , p_key , p_default ) ;
2017-10-28 15:40:55 +02:00
}
2018-09-18 14:02:59 +02:00
void EditorSettings : : set_favorites ( const Vector < String > & p_favorites ) {
favorites = p_favorites ;
2022-02-03 01:21:52 +01:00
String favorites_file ;
if ( Engine : : get_singleton ( ) - > is_project_manager_hint ( ) ) {
2022-08-30 02:34:01 +02:00
favorites_file = EditorPaths : : get_singleton ( ) - > get_config_dir ( ) . path_join ( " favorite_dirs " ) ;
2022-02-03 01:21:52 +01:00
} else {
2022-08-30 02:34:01 +02:00
favorites_file = EditorPaths : : get_singleton ( ) - > get_project_settings_dir ( ) . path_join ( " favorites " ) ;
2022-02-03 01:21:52 +01:00
}
2022-03-23 10:08:58 +01:00
Ref < FileAccess > f = FileAccess : : open ( favorites_file , FileAccess : : WRITE ) ;
if ( f . is_valid ( ) ) {
2020-05-14 16:41:43 +02:00
for ( int i = 0 ; i < favorites . size ( ) ; i + + ) {
2018-09-18 14:02:59 +02:00
f - > store_line ( favorites [ i ] ) ;
2020-05-14 16:41:43 +02:00
}
2015-06-06 14:44:38 +02:00
}
}
2018-09-18 14:02:59 +02:00
Vector < String > EditorSettings : : get_favorites ( ) const {
return favorites ;
2015-06-06 14:44:38 +02:00
}
2017-08-12 18:52:50 +02:00
void EditorSettings : : set_recent_dirs ( const Vector < String > & p_recent_dirs ) {
recent_dirs = p_recent_dirs ;
2022-02-03 01:21:52 +01:00
String recent_dirs_file ;
if ( Engine : : get_singleton ( ) - > is_project_manager_hint ( ) ) {
2022-08-30 02:34:01 +02:00
recent_dirs_file = EditorPaths : : get_singleton ( ) - > get_config_dir ( ) . path_join ( " recent_dirs " ) ;
2022-02-03 01:21:52 +01:00
} else {
2022-08-30 02:34:01 +02:00
recent_dirs_file = EditorPaths : : get_singleton ( ) - > get_project_settings_dir ( ) . path_join ( " recent_dirs " ) ;
2022-02-03 01:21:52 +01:00
}
2022-03-23 10:08:58 +01:00
Ref < FileAccess > f = FileAccess : : open ( recent_dirs_file , FileAccess : : WRITE ) ;
if ( f . is_valid ( ) ) {
2020-05-14 16:41:43 +02:00
for ( int i = 0 ; i < recent_dirs . size ( ) ; i + + ) {
2015-06-06 14:44:38 +02:00
f - > store_line ( recent_dirs [ i ] ) ;
2020-05-14 16:41:43 +02:00
}
2015-06-06 14:44:38 +02:00
}
}
Vector < String > EditorSettings : : get_recent_dirs ( ) const {
return recent_dirs ;
}
2022-02-03 01:21:52 +01:00
void EditorSettings : : load_favorites_and_recent_dirs ( ) {
String favorites_file ;
String recent_dirs_file ;
if ( Engine : : get_singleton ( ) - > is_project_manager_hint ( ) ) {
2022-08-30 02:34:01 +02:00
favorites_file = EditorPaths : : get_singleton ( ) - > get_config_dir ( ) . path_join ( " favorite_dirs " ) ;
recent_dirs_file = EditorPaths : : get_singleton ( ) - > get_config_dir ( ) . path_join ( " recent_dirs " ) ;
2022-02-03 01:21:52 +01:00
} else {
2022-08-30 02:34:01 +02:00
favorites_file = EditorPaths : : get_singleton ( ) - > get_project_settings_dir ( ) . path_join ( " favorites " ) ;
recent_dirs_file = EditorPaths : : get_singleton ( ) - > get_project_settings_dir ( ) . path_join ( " recent_dirs " ) ;
2022-02-03 01:21:52 +01:00
}
2022-03-23 10:08:58 +01:00
Ref < FileAccess > f = FileAccess : : open ( favorites_file , FileAccess : : READ ) ;
if ( f . is_valid ( ) ) {
2015-06-06 14:44:38 +02:00
String line = f - > get_line ( ) . strip_edges ( ) ;
2021-12-09 10:42:46 +01:00
while ( ! line . is_empty ( ) ) {
2018-09-18 14:02:59 +02:00
favorites . push_back ( line ) ;
2015-06-06 14:44:38 +02:00
line = f - > get_line ( ) . strip_edges ( ) ;
}
}
2022-02-03 01:21:52 +01:00
f = FileAccess : : open ( recent_dirs_file , FileAccess : : READ ) ;
2022-03-23 10:08:58 +01:00
if ( f . is_valid ( ) ) {
2015-06-06 14:44:38 +02:00
String line = f - > get_line ( ) . strip_edges ( ) ;
2021-12-09 10:42:46 +01:00
while ( ! line . is_empty ( ) ) {
2015-06-06 14:44:38 +02:00
recent_dirs . push_back ( line ) ;
line = f - > get_line ( ) . strip_edges ( ) ;
}
}
}
2016-04-12 16:45:31 +02:00
void EditorSettings : : list_text_editor_themes ( ) {
2021-05-27 10:22:36 +02:00
String themes = " Default,Godot 2,Custom " ;
2018-09-22 10:02:20 +02:00
2022-07-29 02:36:26 +02:00
Ref < DirAccess > d = DirAccess : : open ( EditorPaths : : get_singleton ( ) - > get_text_editor_themes_dir ( ) ) ;
2022-03-23 10:08:58 +01:00
if ( d . is_valid ( ) ) {
2018-09-22 10:02:20 +02:00
List < String > custom_themes ;
2016-04-12 16:45:31 +02:00
d - > list_dir_begin ( ) ;
String file = d - > get_next ( ) ;
2021-12-09 10:42:46 +01:00
while ( ! file . is_empty ( ) ) {
2019-05-23 17:18:24 +02:00
if ( file . get_extension ( ) = = " tet " & & ! _is_default_text_editor_theme ( file . get_basename ( ) . to_lower ( ) ) ) {
2018-09-22 10:02:20 +02:00
custom_themes . push_back ( file . get_basename ( ) ) ;
2016-04-12 16:45:31 +02:00
}
file = d - > get_next ( ) ;
}
d - > list_dir_end ( ) ;
2018-09-22 10:02:20 +02:00
custom_themes . sort ( ) ;
2021-07-24 15:46:25 +02:00
for ( const String & E : custom_themes ) {
2021-07-16 05:45:57 +02:00
themes + = " , " + E ;
2018-09-22 10:02:20 +02:00
}
2016-04-12 16:45:31 +02:00
}
2017-03-05 16:44:50 +01:00
add_property_hint ( PropertyInfo ( Variant : : STRING , " text_editor/theme/color_theme " , PROPERTY_HINT_ENUM , themes ) ) ;
2016-04-12 16:45:31 +02:00
}
void EditorSettings : : load_text_editor_theme ( ) {
2019-05-23 17:18:24 +02:00
String p_file = get ( " text_editor/theme/color_theme " ) ;
if ( _is_default_text_editor_theme ( p_file . get_file ( ) . to_lower ( ) ) ) {
2021-05-27 10:22:36 +02:00
if ( p_file = = " Godot 2 " ) {
_load_godot2_text_editor_theme ( ) ;
2018-01-06 12:40:43 +01:00
}
return ; // sorry for "Settings changed" console spam
2016-04-12 16:45:31 +02:00
}
2022-08-30 02:34:01 +02:00
String theme_path = EditorPaths : : get_singleton ( ) - > get_text_editor_themes_dir ( ) . path_join ( p_file + " .tet " ) ;
2016-04-12 16:45:31 +02:00
2017-03-05 16:44:50 +01:00
Ref < ConfigFile > cf = memnew ( ConfigFile ) ;
2016-04-12 16:45:31 +02:00
Error err = cf - > load ( theme_path ) ;
if ( err ! = OK ) {
return ;
}
List < String > keys ;
cf - > get_section_keys ( " color_theme " , & keys ) ;
2021-07-24 15:46:25 +02:00
for ( const String & key : keys ) {
2016-04-12 16:45:31 +02:00
String val = cf - > get_value ( " color_theme " , key ) ;
// don't load if it's not already there!
2021-08-15 19:14:46 +02:00
if ( has_setting ( " text_editor/theme/highlighting/ " + key ) ) {
2016-04-12 16:45:31 +02:00
// make sure it is actually a color
2024-05-06 16:20:20 +02:00
if ( val . is_valid_html_color ( ) & & key . contains ( " color " ) ) {
2021-08-15 19:14:46 +02:00
props [ " text_editor/theme/highlighting/ " + key ] . variant = Color : : html ( val ) ; // change manually to prevent "Settings changed" console spam
2016-04-12 16:45:31 +02:00
}
}
}
2021-07-17 23:22:52 +02:00
emit_signal ( SNAME ( " settings_changed " ) ) ;
2016-04-12 16:45:31 +02:00
// if it doesn't load just use what is currently loaded
}
2024-02-15 17:25:58 +01:00
bool EditorSettings : : import_text_editor_theme ( const String & p_file ) {
2016-04-12 16:45:31 +02:00
if ( ! p_file . ends_with ( " .tet " ) ) {
return false ;
} else {
if ( p_file . get_file ( ) . to_lower ( ) = = " default.tet " ) {
return false ;
}
2022-07-29 02:36:26 +02:00
Ref < DirAccess > d = DirAccess : : open ( EditorPaths : : get_singleton ( ) - > get_text_editor_themes_dir ( ) ) ;
2022-03-23 10:08:58 +01:00
if ( d . is_valid ( ) ) {
2022-08-30 02:34:01 +02:00
d - > copy ( p_file , EditorPaths : : get_singleton ( ) - > get_text_editor_themes_dir ( ) . path_join ( p_file . get_file ( ) ) ) ;
2016-04-12 16:45:31 +02:00
return true ;
}
}
return false ;
}
bool EditorSettings : : save_text_editor_theme ( ) {
2017-01-05 23:41:36 +01:00
String p_file = get ( " text_editor/theme/color_theme " ) ;
2016-04-12 16:45:31 +02:00
2019-05-23 17:18:24 +02:00
if ( _is_default_text_editor_theme ( p_file . get_file ( ) . to_lower ( ) ) ) {
2016-04-12 16:45:31 +02:00
return false ;
}
2022-08-30 02:34:01 +02:00
String theme_path = EditorPaths : : get_singleton ( ) - > get_text_editor_themes_dir ( ) . path_join ( p_file + " .tet " ) ;
2016-04-12 16:45:31 +02:00
return _save_text_editor_theme ( theme_path ) ;
}
bool EditorSettings : : save_text_editor_theme_as ( String p_file ) {
if ( ! p_file . ends_with ( " .tet " ) ) {
p_file + = " .tet " ;
}
2019-05-23 17:18:24 +02:00
if ( _is_default_text_editor_theme ( p_file . get_file ( ) . to_lower ( ) . trim_suffix ( " .tet " ) ) ) {
2016-04-12 16:45:31 +02:00
return false ;
}
2017-03-05 16:44:50 +01:00
if ( _save_text_editor_theme ( p_file ) ) {
2016-04-12 16:45:31 +02:00
// switch to theme is saved in the theme directory
list_text_editor_themes ( ) ;
String theme_name = p_file . substr ( 0 , p_file . length ( ) - 4 ) . get_file ( ) ;
2022-07-29 02:36:26 +02:00
if ( p_file . get_base_dir ( ) = = EditorPaths : : get_singleton ( ) - > get_text_editor_themes_dir ( ) ) {
2017-09-25 05:26:41 +02:00
_initial_set ( " text_editor/theme/color_theme " , theme_name ) ;
2016-04-12 16:45:31 +02:00
load_text_editor_theme ( ) ;
}
return true ;
}
return false ;
}
2019-05-23 17:18:24 +02:00
bool EditorSettings : : is_default_text_editor_theme ( ) {
String p_file = get ( " text_editor/theme/color_theme " ) ;
return _is_default_text_editor_theme ( p_file . get_file ( ) . to_lower ( ) ) ;
}
2019-08-22 17:59:43 +02:00
Vector < String > EditorSettings : : get_script_templates ( const String & p_extension , const String & p_custom_path ) {
2017-06-13 22:03:08 +02:00
Vector < String > templates ;
2022-07-29 02:36:26 +02:00
String template_dir = EditorPaths : : get_singleton ( ) - > get_script_templates_dir ( ) ;
2020-12-15 13:04:21 +01:00
if ( ! p_custom_path . is_empty ( ) ) {
2019-08-22 17:59:43 +02:00
template_dir = p_custom_path ;
}
2022-03-23 10:08:58 +01:00
Ref < DirAccess > d = DirAccess : : open ( template_dir ) ;
if ( d . is_valid ( ) ) {
2017-06-13 22:03:08 +02:00
d - > list_dir_begin ( ) ;
String file = d - > get_next ( ) ;
2021-12-09 10:42:46 +01:00
while ( ! file . is_empty ( ) ) {
2017-06-13 22:03:08 +02:00
if ( file . get_extension ( ) = = p_extension ) {
templates . push_back ( file . get_basename ( ) ) ;
}
file = d - > get_next ( ) ;
}
d - > list_dir_end ( ) ;
}
return templates ;
}
2017-11-17 21:48:24 +01:00
String EditorSettings : : get_editor_layouts_config ( ) const {
2022-08-30 02:34:01 +02:00
return EditorPaths : : get_singleton ( ) - > get_config_dir ( ) . path_join ( " editor_layouts.cfg " ) ;
2017-11-17 21:48:24 +01:00
}
2021-06-16 14:36:09 +02:00
float EditorSettings : : get_auto_display_scale ( ) const {
Add Wayland support
Not everything is yet implemented, either for Godot or personal
limitations (I don't have all hardware in the world). A brief list of
the most important issues follows:
- Single-window only: the `DisplayServer` API doesn't expose enough
information for properly creating XDG shell windows.
- Very dumb rendering loop: this is very complicated, just know that
the low consumption mode is forced to 2000 Hz and some clever hacks are
in place to overcome a specific Wayland limitation. This will be
improved to the extent possible both downstream and upstream.
- Features to implement yet: IME, touch input, native file dialog,
drawing tablet (commented out due to a refactor), screen recording.
- Mouse passthrough can't be implement through a poly API, we need a
rect-based one.
- The cursor doesn't yet support fractional scaling.
- Auto scale is rounded up when using fractional scaling as we don't
have a per-window scale query API (basically we need
`DisplayServer::window_get_scale`).
- Building with `x11=no wayland=yes opengl=yes openxr=yes` fails.
This also adds a new project property and editor setting for selecting the
default DisplayServer to start, to allow this backend to start first in
exported projects (X11 is still the default for now). The editor setting
always overrides the project setting.
Special thanks to Drew Devault, toger5, Sebastian Krzyszkowiak, Leandro
Benedet Garcia, Subhransu, Yury Zhuravlev and Mara Huldra.
2023-12-15 02:55:34 +01:00
# ifdef LINUXBSD_ENABLED
if ( DisplayServer : : get_singleton ( ) - > get_name ( ) = = " Wayland " ) {
2024-03-16 14:48:11 +01:00
float main_window_scale = DisplayServer : : get_singleton ( ) - > screen_get_scale ( DisplayServer : : SCREEN_OF_MAIN_WINDOW ) ;
if ( DisplayServer : : get_singleton ( ) - > get_screen_count ( ) = = 1 | | Math : : fract ( main_window_scale ) ! = 0 ) {
// If we have a single screen or the screen of the window is fractional, all
// bets are off. At this point, let's just return the current's window scale,
// which is special-cased to the scale of `SCREEN_OF_MAIN_WINDOW`.
return main_window_scale ;
}
// If the above branch didn't fire, fractional scaling isn't going to work
// properly anyways (we're need the ability to change the UI scale at runtime).
// At this point it's more convenient to "supersample" like we do with other
// platforms, hoping that the user is only using integer-scaled screens.
Add Wayland support
Not everything is yet implemented, either for Godot or personal
limitations (I don't have all hardware in the world). A brief list of
the most important issues follows:
- Single-window only: the `DisplayServer` API doesn't expose enough
information for properly creating XDG shell windows.
- Very dumb rendering loop: this is very complicated, just know that
the low consumption mode is forced to 2000 Hz and some clever hacks are
in place to overcome a specific Wayland limitation. This will be
improved to the extent possible both downstream and upstream.
- Features to implement yet: IME, touch input, native file dialog,
drawing tablet (commented out due to a refactor), screen recording.
- Mouse passthrough can't be implement through a poly API, we need a
rect-based one.
- The cursor doesn't yet support fractional scaling.
- Auto scale is rounded up when using fractional scaling as we don't
have a per-window scale query API (basically we need
`DisplayServer::window_get_scale`).
- Building with `x11=no wayland=yes opengl=yes openxr=yes` fails.
This also adds a new project property and editor setting for selecting the
default DisplayServer to start, to allow this backend to start first in
exported projects (X11 is still the default for now). The editor setting
always overrides the project setting.
Special thanks to Drew Devault, toger5, Sebastian Krzyszkowiak, Leandro
Benedet Garcia, Subhransu, Yury Zhuravlev and Mara Huldra.
2023-12-15 02:55:34 +01:00
return DisplayServer : : get_singleton ( ) - > screen_get_max_scale ( ) ;
}
# endif
2022-07-20 08:28:22 +02:00
# if defined(MACOS_ENABLED) || defined(ANDROID_ENABLED)
2021-06-16 14:36:09 +02:00
return DisplayServer : : get_singleton ( ) - > screen_get_max_scale ( ) ;
# else
const int screen = DisplayServer : : get_singleton ( ) - > window_get_current_screen ( ) ;
2022-02-21 09:17:28 +01:00
if ( DisplayServer : : get_singleton ( ) - > screen_get_size ( screen ) = = Vector2i ( ) ) {
// Invalid screen size, skip.
return 1.0 ;
}
Fix various typos with codespell
Found via `codespell -q 3 -S ./thirdparty,*.po,./DONORS.md -L ackward,ang,ans,ba,beng,cas,childs,childrens,dof,doubleclick,fave,findn,hist,inout,leapyear,lod,nd,numer,ois,ony,paket,seeked,sinc,switchs,te,uint`
2021-07-07 17:17:32 +02:00
// Use the smallest dimension to use a correct display scale on portrait displays.
2021-06-16 14:36:09 +02:00
const int smallest_dimension = MIN ( DisplayServer : : get_singleton ( ) - > screen_get_size ( screen ) . x , DisplayServer : : get_singleton ( ) - > screen_get_size ( screen ) . y ) ;
if ( DisplayServer : : get_singleton ( ) - > screen_get_dpi ( screen ) > = 192 & & smallest_dimension > = 1400 ) {
// hiDPI display.
return 2.0 ;
} else if ( smallest_dimension > = 1700 ) {
// Likely a hiDPI display, but we aren't certain due to the returned DPI.
// Use an intermediate scale to handle this situation.
return 1.5 ;
} else if ( smallest_dimension < = 800 ) {
// Small loDPI display. Use a smaller display scale so that editor elements fit more easily.
// Icons won't look great, but this is better than having editor elements overflow from its window.
return 0.75 ;
}
return 1.0 ;
# endif
}
2017-10-28 15:40:55 +02:00
// Shortcuts
2014-02-10 02:10:30 +01:00
2023-02-21 07:08:53 +01:00
void EditorSettings : : _add_shortcut_default ( const String & p_name , const Ref < Shortcut > & p_shortcut ) {
shortcuts [ p_name ] = p_shortcut ;
}
2022-04-05 12:40:26 +02:00
void EditorSettings : : add_shortcut ( const String & p_name , const Ref < Shortcut > & p_shortcut ) {
2017-03-05 16:44:50 +01:00
shortcuts [ p_name ] = p_shortcut ;
2023-02-21 07:08:53 +01:00
shortcuts [ p_name ] - > set_meta ( " customized " , true ) ;
2016-06-05 02:31:29 +02:00
}
2017-05-20 17:38:03 +02:00
bool EditorSettings : : is_shortcut ( const String & p_name , const Ref < InputEvent > & p_event ) const {
2022-05-13 15:04:37 +02:00
HashMap < String , Ref < Shortcut > > : : ConstIterator E = shortcuts . find ( p_name ) ;
2019-08-15 04:57:49 +02:00
ERR_FAIL_COND_V_MSG ( ! E , false , " Unknown Shortcut: " + p_name + " . " ) ;
2016-06-05 02:31:29 +02:00
2022-05-13 15:04:37 +02:00
return E - > value - > matches_event ( p_event ) ;
2016-06-05 02:31:29 +02:00
}
2020-09-09 21:53:24 +02:00
Ref < Shortcut > EditorSettings : : get_shortcut ( const String & p_name ) const {
2022-05-13 15:04:37 +02:00
HashMap < String , Ref < Shortcut > > : : ConstIterator SC = shortcuts . find ( p_name ) ;
2020-12-07 12:31:51 +01:00
if ( SC ) {
2022-05-13 15:04:37 +02:00
return SC - > value ;
2020-12-07 12:31:51 +01:00
}
// If no shortcut with the provided name is found in the list, check the built-in shortcuts.
// Use the first item in the action list for the shortcut event, since a shortcut can only have 1 linked event.
Ref < Shortcut > sc ;
2022-05-13 15:04:37 +02:00
HashMap < String , List < Ref < InputEvent > > > : : ConstIterator builtin_override = builtin_action_overrides . find ( p_name ) ;
2020-12-07 12:31:51 +01:00
if ( builtin_override ) {
2021-06-18 00:03:09 +02:00
sc . instantiate ( ) ;
2022-05-13 15:04:37 +02:00
sc - > set_events_list ( & builtin_override - > value ) ;
2020-12-07 12:31:51 +01:00
sc - > set_name ( InputMap : : get_singleton ( ) - > get_builtin_display_name ( p_name ) ) ;
}
// If there was no override, check the default builtins to see if it has an InputEvent for the provided name.
if ( sc . is_null ( ) ) {
2022-05-13 15:04:37 +02:00
HashMap < String , List < Ref < InputEvent > > > : : ConstIterator builtin_default = InputMap : : get_singleton ( ) - > get_builtins_with_feature_overrides_applied ( ) . find ( p_name ) ;
2020-12-07 12:31:51 +01:00
if ( builtin_default ) {
2021-06-18 00:03:09 +02:00
sc . instantiate ( ) ;
2022-05-08 10:09:19 +02:00
sc - > set_events_list ( & builtin_default - > value ) ;
2020-12-07 12:31:51 +01:00
sc - > set_name ( InputMap : : get_singleton ( ) - > get_builtin_display_name ( p_name ) ) ;
}
}
if ( sc . is_valid ( ) ) {
// Add the shortcut to the list.
shortcuts [ p_name ] = sc ;
return sc ;
2020-05-14 16:41:43 +02:00
}
2016-06-05 02:31:29 +02:00
2020-12-07 12:31:51 +01:00
return Ref < Shortcut > ( ) ;
2016-06-05 02:31:29 +02:00
}
void EditorSettings : : get_shortcut_list ( List < String > * r_shortcuts ) {
2021-08-09 22:13:42 +02:00
for ( const KeyValue < String , Ref < Shortcut > > & E : shortcuts ) {
r_shortcuts - > push_back ( E . key ) ;
2016-06-05 02:31:29 +02:00
}
}
2020-09-09 21:53:24 +02:00
Ref < Shortcut > ED_GET_SHORTCUT ( const String & p_path ) {
2021-10-21 22:21:41 +02:00
ERR_FAIL_NULL_V_MSG ( EditorSettings : : get_singleton ( ) , nullptr , " EditorSettings not instantiated yet. " ) ;
2019-06-01 15:42:22 +02:00
2020-09-09 21:53:24 +02:00
Ref < Shortcut > sc = EditorSettings : : get_singleton ( ) - > get_shortcut ( p_path ) ;
2019-08-15 04:57:49 +02:00
2024-02-23 20:49:13 +01:00
ERR_FAIL_COND_V_MSG ( ! sc . is_valid ( ) , sc , " Used ED_GET_SHORTCUT with invalid shortcut: " + p_path ) ;
2017-10-28 15:40:55 +02:00
return sc ;
2016-07-04 00:13:45 +02:00
}
2016-06-05 02:31:29 +02:00
2023-02-20 23:11:57 +01:00
void ED_SHORTCUT_OVERRIDE ( const String & p_path , const String & p_feature , Key p_keycode , bool p_physical ) {
2024-05-03 16:34:53 +02:00
if ( ! EditorSettings : : get_singleton ( ) ) {
return ;
}
2021-10-21 22:21:41 +02:00
2021-08-08 05:52:00 +02:00
Ref < Shortcut > sc = EditorSettings : : get_singleton ( ) - > get_shortcut ( p_path ) ;
2024-02-23 20:49:13 +01:00
ERR_FAIL_COND_MSG ( ! sc . is_valid ( ) , " Used ED_SHORTCUT_OVERRIDE with invalid shortcut: " + p_path ) ;
2021-08-08 05:52:00 +02:00
2021-06-21 03:34:50 +02:00
PackedInt32Array arr ;
2021-08-13 23:31:57 +02:00
arr . push_back ( ( int32_t ) p_keycode ) ;
2021-06-21 03:34:50 +02:00
2023-02-20 23:11:57 +01:00
ED_SHORTCUT_OVERRIDE_ARRAY ( p_path , p_feature , arr , p_physical ) ;
2021-06-21 03:34:50 +02:00
}
2023-02-20 23:11:57 +01:00
void ED_SHORTCUT_OVERRIDE_ARRAY ( const String & p_path , const String & p_feature , const PackedInt32Array & p_keycodes , bool p_physical ) {
2024-05-03 16:34:53 +02:00
if ( ! EditorSettings : : get_singleton ( ) ) {
return ;
}
2021-10-21 22:21:41 +02:00
2021-06-21 03:34:50 +02:00
Ref < Shortcut > sc = EditorSettings : : get_singleton ( ) - > get_shortcut ( p_path ) ;
2024-02-23 20:49:13 +01:00
ERR_FAIL_COND_MSG ( ! sc . is_valid ( ) , " Used ED_SHORTCUT_OVERRIDE_ARRAY with invalid shortcut: " + p_path ) ;
2021-06-21 03:34:50 +02:00
2021-08-08 05:52:00 +02:00
// Only add the override if the OS supports the provided feature.
2021-06-21 03:34:50 +02:00
if ( ! OS : : get_singleton ( ) - > has_feature ( p_feature ) ) {
2022-11-14 15:27:26 +01:00
if ( ! ( p_feature = = " macos " & & ( OS : : get_singleton ( ) - > has_feature ( " web_macos " ) | | OS : : get_singleton ( ) - > has_feature ( " web_ios " ) ) ) ) {
return ;
}
2021-06-21 03:34:50 +02:00
}
Array events ;
for ( int i = 0 ; i < p_keycodes . size ( ) ; i + + ) {
Key keycode = ( Key ) p_keycodes [ i ] ;
2022-11-14 15:27:26 +01:00
if ( OS : : get_singleton ( ) - > has_feature ( " macos " ) | | OS : : get_singleton ( ) - > has_feature ( " web_macos " ) | | OS : : get_singleton ( ) - > has_feature ( " web_ios " ) ) {
// Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS
if ( keycode = = Key : : KEY_DELETE ) {
keycode = KeyModifierMask : : META | Key : : BACKSPACE ;
}
2021-08-08 05:52:00 +02:00
}
2022-09-02 11:37:48 +02:00
2021-06-21 03:34:50 +02:00
Ref < InputEventKey > ie ;
2021-08-13 23:31:57 +02:00
if ( keycode ! = Key : : NONE ) {
2023-02-20 23:11:57 +01:00
ie = InputEventKey : : create_reference ( keycode , p_physical ) ;
2021-06-21 03:34:50 +02:00
events . push_back ( ie ) ;
}
2021-08-08 05:52:00 +02:00
}
2021-06-21 03:34:50 +02:00
2023-02-21 07:08:53 +01:00
// Override the existing shortcut only if it wasn't customized by the user.
if ( ! sc - > has_meta ( " customized " ) ) {
2022-08-17 07:04:38 +02:00
sc - > set_events ( events ) ;
}
2023-02-16 10:28:04 +01:00
sc - > set_meta ( " original " , events . duplicate ( true ) ) ;
2021-08-08 05:52:00 +02:00
}
2023-02-20 23:11:57 +01:00
Ref < Shortcut > ED_SHORTCUT ( const String & p_path , const String & p_name , Key p_keycode , bool p_physical ) {
2021-06-21 03:34:50 +02:00
PackedInt32Array arr ;
2021-08-13 23:31:57 +02:00
arr . push_back ( ( int32_t ) p_keycode ) ;
2023-02-20 23:11:57 +01:00
return ED_SHORTCUT_ARRAY ( p_path , p_name , arr , p_physical ) ;
2021-06-21 03:34:50 +02:00
}
2023-02-20 23:11:57 +01:00
Ref < Shortcut > ED_SHORTCUT_ARRAY ( const String & p_path , const String & p_name , const PackedInt32Array & p_keycodes , bool p_physical ) {
2021-06-21 03:34:50 +02:00
Array events ;
for ( int i = 0 ; i < p_keycodes . size ( ) ; i + + ) {
Key keycode = ( Key ) p_keycodes [ i ] ;
2022-11-14 15:27:26 +01:00
if ( OS : : get_singleton ( ) - > has_feature ( " macos " ) | | OS : : get_singleton ( ) - > has_feature ( " web_macos " ) | | OS : : get_singleton ( ) - > has_feature ( " web_ios " ) ) {
// Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS
if ( keycode = = Key : : KEY_DELETE ) {
keycode = KeyModifierMask : : META | Key : : BACKSPACE ;
}
2021-06-21 03:34:50 +02:00
}
2017-12-26 07:30:36 +01:00
2021-06-21 03:34:50 +02:00
Ref < InputEventKey > ie ;
2021-08-13 23:31:57 +02:00
if ( keycode ! = Key : : NONE ) {
2023-02-20 23:11:57 +01:00
ie = InputEventKey : : create_reference ( keycode , p_physical ) ;
2021-06-21 03:34:50 +02:00
events . push_back ( ie ) ;
}
2016-10-12 22:23:48 +02:00
}
2019-06-01 15:42:22 +02:00
if ( ! EditorSettings : : get_singleton ( ) ) {
2020-09-09 21:53:24 +02:00
Ref < Shortcut > sc ;
2021-06-18 00:03:09 +02:00
sc . instantiate ( ) ;
2019-06-01 15:42:22 +02:00
sc - > set_name ( p_name ) ;
2021-06-21 03:34:50 +02:00
sc - > set_events ( events ) ;
2021-10-13 04:33:53 +02:00
sc - > set_meta ( " original " , events . duplicate ( true ) ) ;
2019-06-01 15:42:22 +02:00
return sc ;
}
2020-09-09 21:53:24 +02:00
Ref < Shortcut > sc = EditorSettings : : get_singleton ( ) - > get_shortcut ( p_path ) ;
2017-10-28 15:40:55 +02:00
if ( sc . is_valid ( ) ) {
sc - > set_name ( p_name ) ; //keep name (the ones that come from disk have no name)
2023-02-21 07:08:53 +01:00
sc - > set_meta ( " original " , events . duplicate ( true ) ) ; //to compare against changes
2017-10-28 15:40:55 +02:00
return sc ;
}
2017-09-25 05:26:41 +02:00
2021-06-18 00:03:09 +02:00
sc . instantiate ( ) ;
2017-10-28 15:40:55 +02:00
sc - > set_name ( p_name ) ;
2021-06-21 03:34:50 +02:00
sc - > set_events ( events ) ;
2021-10-13 04:33:53 +02:00
sc - > set_meta ( " original " , events . duplicate ( true ) ) ; //to compare against changes
2023-02-21 07:08:53 +01:00
EditorSettings : : get_singleton ( ) - > _add_shortcut_default ( p_path , sc ) ;
2017-09-25 05:26:41 +02:00
2017-10-28 15:40:55 +02:00
return sc ;
2017-09-25 05:26:41 +02:00
}
2022-08-31 19:24:04 +02:00
void EditorSettings : : set_builtin_action_override ( const String & p_name , const TypedArray < InputEvent > & p_events ) {
2020-12-07 12:31:51 +01:00
List < Ref < InputEvent > > event_list ;
// Override the whole list, since events may have their order changed or be added, removed or edited.
InputMap : : get_singleton ( ) - > action_erase_events ( p_name ) ;
for ( int i = 0 ; i < p_events . size ( ) ; i + + ) {
event_list . push_back ( p_events [ i ] ) ;
InputMap : : get_singleton ( ) - > action_add_event ( p_name , p_events [ i ] ) ;
}
// Check if the provided event array is same as built-in. If it is, it does not need to be added to the overrides.
// Note that event order must also be the same.
bool same_as_builtin = true ;
2022-05-08 10:09:19 +02:00
HashMap < String , List < Ref < InputEvent > > > : : ConstIterator builtin_default = InputMap : : get_singleton ( ) - > get_builtins_with_feature_overrides_applied ( ) . find ( p_name ) ;
2020-12-07 12:31:51 +01:00
if ( builtin_default ) {
2022-05-08 10:09:19 +02:00
const List < Ref < InputEvent > > & builtin_events = builtin_default - > value ;
2020-12-07 12:31:51 +01:00
2021-08-06 08:30:15 +02:00
// In the editor we only care about key events.
List < Ref < InputEventKey > > builtin_key_events ;
for ( Ref < InputEventKey > iek : builtin_events ) {
if ( iek . is_valid ( ) ) {
builtin_key_events . push_back ( iek ) ;
}
}
if ( p_events . size ( ) = = builtin_key_events . size ( ) ) {
2020-12-07 12:31:51 +01:00
int event_idx = 0 ;
// Check equality of each event.
2021-08-06 08:30:15 +02:00
for ( const Ref < InputEventKey > & E : builtin_key_events ) {
2021-07-16 05:45:57 +02:00
if ( ! E - > is_match ( p_events [ event_idx ] ) ) {
2020-12-07 12:31:51 +01:00
same_as_builtin = false ;
break ;
}
event_idx + + ;
}
} else {
same_as_builtin = false ;
}
}
if ( same_as_builtin & & builtin_action_overrides . has ( p_name ) ) {
builtin_action_overrides . erase ( p_name ) ;
} else {
builtin_action_overrides [ p_name ] = event_list ;
}
// Update the shortcut (if it is used somewhere in the editor) to be the first event of the new list.
if ( shortcuts . has ( p_name ) ) {
2021-06-21 03:34:50 +02:00
shortcuts [ p_name ] - > set_events_list ( & event_list ) ;
2020-12-07 12:31:51 +01:00
}
}
const Array EditorSettings : : get_builtin_action_overrides ( const String & p_name ) const {
2022-05-13 15:04:37 +02:00
HashMap < String , List < Ref < InputEvent > > > : : ConstIterator AO = builtin_action_overrides . find ( p_name ) ;
2020-12-07 12:31:51 +01:00
if ( AO ) {
Array event_array ;
2022-05-13 15:04:37 +02:00
List < Ref < InputEvent > > events_list = AO - > value ;
2021-07-26 17:50:35 +02:00
for ( const Ref < InputEvent > & E : events_list ) {
2021-07-16 05:45:57 +02:00
event_array . push_back ( E ) ;
2020-12-07 12:31:51 +01:00
}
return event_array ;
}
return Array ( ) ;
}
2017-10-28 15:40:55 +02:00
void EditorSettings : : notify_changes ( ) {
_THREAD_SAFE_METHOD_
2017-09-25 05:26:41 +02:00
2017-10-28 15:40:55 +02:00
SceneTree * sml = Object : : cast_to < SceneTree > ( OS : : get_singleton ( ) - > get_main_loop ( ) ) ;
2017-09-25 05:26:41 +02:00
2017-10-28 15:40:55 +02:00
if ( ! sml ) {
return ;
}
2017-09-25 05:26:41 +02:00
2017-10-28 15:40:55 +02:00
Node * root = sml - > get_root ( ) - > get_child ( 0 ) ;
if ( ! root ) {
return ;
}
root - > propagate_notification ( NOTIFICATION_EDITOR_SETTINGS_CHANGED ) ;
2017-09-25 05:26:41 +02:00
}
2024-03-01 14:58:19 +01:00
# ifdef TOOLS_ENABLED
void EditorSettings : : get_argument_options ( const StringName & p_function , int p_idx , List < String > * r_options ) const {
const String pf = p_function ;
if ( p_idx = = 0 ) {
if ( pf = = " has_setting " | | pf = = " set_setting " | | pf = = " get_setting " | | pf = = " erase " | |
pf = = " set_initial_value " | | pf = = " set_as_basic " | | pf = = " mark_setting_changed " ) {
for ( const KeyValue < String , VariantContainer > & E : props ) {
if ( E . value . hide_from_editor ) {
continue ;
}
r_options - > push_back ( E . key . quote ( ) ) ;
}
} else if ( pf = = " get_project_metadata " & & project_metadata . is_valid ( ) ) {
List < String > sections ;
project_metadata - > get_sections ( & sections ) ;
for ( const String & section : sections ) {
r_options - > push_back ( section . quote ( ) ) ;
}
} else if ( pf = = " set_builtin_action_override " ) {
for ( const StringName & action : InputMap : : get_singleton ( ) - > get_actions ( ) ) {
r_options - > push_back ( String ( action ) . quote ( ) ) ;
}
}
}
Object : : get_argument_options ( p_function , p_idx , r_options ) ;
}
# endif
2014-02-10 02:10:30 +01:00
void EditorSettings : : _bind_methods ( ) {
2017-10-05 20:34:34 +02:00
ClassDB : : bind_method ( D_METHOD ( " has_setting " , " name " ) , & EditorSettings : : has_setting ) ;
ClassDB : : bind_method ( D_METHOD ( " set_setting " , " name " , " value " ) , & EditorSettings : : set_setting ) ;
ClassDB : : bind_method ( D_METHOD ( " get_setting " , " name " ) , & EditorSettings : : get_setting ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " erase " , " property " ) , & EditorSettings : : erase ) ;
2018-01-09 16:52:46 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_initial_value " , " name " , " value " , " update_current " ) , & EditorSettings : : set_initial_value ) ;
2017-10-28 15:40:55 +02:00
ClassDB : : bind_method ( D_METHOD ( " add_property_info " , " info " ) , & EditorSettings : : _add_property_info_bind ) ;
2018-05-16 17:23:20 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_project_metadata " , " section " , " key " , " data " ) , & EditorSettings : : set_project_metadata ) ;
ClassDB : : bind_method ( D_METHOD ( " get_project_metadata " , " section " , " key " , " default " ) , & EditorSettings : : get_project_metadata , DEFVAL ( Variant ( ) ) ) ;
2018-09-18 14:02:59 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_favorites " , " dirs " ) , & EditorSettings : : set_favorites ) ;
ClassDB : : bind_method ( D_METHOD ( " get_favorites " ) , & EditorSettings : : get_favorites ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_recent_dirs " , " dirs " ) , & EditorSettings : : set_recent_dirs ) ;
ClassDB : : bind_method ( D_METHOD ( " get_recent_dirs " ) , & EditorSettings : : get_recent_dirs ) ;
2016-02-27 04:32:00 +01:00
2020-12-07 12:31:51 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_builtin_action_override " , " name " , " actions_list " ) , & EditorSettings : : set_builtin_action_override ) ;
2021-10-15 14:34:11 +02:00
ClassDB : : bind_method ( D_METHOD ( " check_changed_settings_in_group " , " setting_prefix " ) , & EditorSettings : : check_changed_settings_in_group ) ;
ClassDB : : bind_method ( D_METHOD ( " get_changed_settings " ) , & EditorSettings : : get_changed_settings ) ;
ClassDB : : bind_method ( D_METHOD ( " mark_setting_changed " , " setting " ) , & EditorSettings : : mark_setting_changed ) ;
2014-02-10 02:10:30 +01:00
ADD_SIGNAL ( MethodInfo ( " settings_changed " ) ) ;
2019-07-03 09:44:53 +02:00
BIND_CONSTANT ( NOTIFICATION_EDITOR_SETTINGS_CHANGED ) ;
2014-02-10 02:10:30 +01:00
}
EditorSettings : : EditorSettings ( ) {
2017-03-05 16:44:50 +01:00
last_order = 0 ;
2016-05-28 00:58:28 +02:00
2014-02-10 02:10:30 +01:00
_load_defaults ( ) ;
2024-08-17 19:23:06 +02:00
callable_mp ( this , & EditorSettings : : _set_initialized ) . call_deferred ( ) ;
2014-02-10 02:10:30 +01:00
}