2014-02-10 02:10:30 +01:00
/*************************************************************************/
/* settings_config_dialog.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2014-02-10 02:10:30 +01:00
/*************************************************************************/
2021-01-01 20:13:46 +01:00
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-10 02:10:30 +01:00
/* */
/* 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 "settings_config_dialog.h"
2017-01-16 08:04:19 +01:00
2020-11-07 23:33:38 +01:00
# include "core/config/project_settings.h"
2020-10-02 15:12:20 +02:00
# include "core/input/input_map.h"
2018-09-11 18:13:45 +02:00
# include "core/os/keyboard.h"
2020-02-07 02:52:05 +01:00
# include "editor/debugger/editor_debugger_node.h"
2014-02-10 02:10:30 +01:00
# include "editor_file_system.h"
2019-12-24 08:17:23 +01:00
# include "editor_log.h"
2016-06-05 02:31:29 +02:00
# include "editor_node.h"
2019-12-24 08:17:23 +01:00
# include "editor_scale.h"
2017-03-05 16:44:50 +01:00
# include "editor_settings.h"
# include "scene/gui/margin_container.h"
2016-06-05 02:31:29 +02:00
2014-02-10 02:10:30 +01:00
void EditorSettingsDialog : : ok_pressed ( ) {
2020-05-14 16:41:43 +02:00
if ( ! EditorSettings : : get_singleton ( ) ) {
2014-02-10 02:10:30 +01:00
return ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
_settings_save ( ) ;
timer - > stop ( ) ;
}
void EditorSettingsDialog : : _settings_changed ( ) {
timer - > start ( ) ;
2016-07-18 23:46:16 +02:00
}
2017-03-05 16:44:50 +01:00
void EditorSettingsDialog : : _settings_property_edited ( const String & p_name ) {
2018-07-19 23:58:15 +02:00
String full_name = inspector - > get_full_item_path ( p_name ) ;
2016-07-18 23:46:16 +02:00
2018-09-15 20:22:09 +02:00
if ( full_name = = " interface/theme/accent_color " | | full_name = = " interface/theme/base_color " | | full_name = = " interface/theme/contrast " ) {
2018-06-23 11:05:12 +02:00
EditorSettings : : get_singleton ( ) - > set_manually ( " interface/theme/preset " , " Custom " ) ; // set preset to Custom
2017-12-26 20:41:08 +01:00
} else if ( full_name . begins_with ( " text_editor/highlighting " ) ) {
EditorSettings : : get_singleton ( ) - > set_manually ( " text_editor/theme/color_theme " , " Custom " ) ;
2016-07-18 23:46:16 +02:00
}
2014-02-10 02:10:30 +01:00
}
void EditorSettingsDialog : : _settings_save ( ) {
EditorSettings : : get_singleton ( ) - > notify_changes ( ) ;
EditorSettings : : get_singleton ( ) - > save ( ) ;
}
void EditorSettingsDialog : : cancel_pressed ( ) {
2020-05-14 16:41:43 +02:00
if ( ! EditorSettings : : get_singleton ( ) ) {
2014-02-10 02:10:30 +01:00
return ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
EditorSettings : : get_singleton ( ) - > notify_changes ( ) ;
}
void EditorSettingsDialog : : popup_edit_settings ( ) {
2020-05-14 16:41:43 +02:00
if ( ! EditorSettings : : get_singleton ( ) ) {
2014-02-10 02:10:30 +01:00
return ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
2016-04-12 16:45:31 +02:00
EditorSettings : : get_singleton ( ) - > list_text_editor_themes ( ) ; // make sure we have an up to date list of themes
2018-07-19 23:58:15 +02:00
inspector - > edit ( EditorSettings : : get_singleton ( ) ) ;
inspector - > get_inspector ( ) - > update_tree ( ) ;
2015-11-21 17:42:15 +01:00
2016-01-23 20:05:27 +01:00
search_box - > select_all ( ) ;
search_box - > grab_focus ( ) ;
2016-06-05 02:31:29 +02:00
_update_shortcuts ( ) ;
2017-10-15 13:36:36 +02:00
set_process_unhandled_input ( true ) ;
2014-02-10 02:10:30 +01:00
2017-03-02 22:43:56 +01:00
// Restore valid window bounds or pop up at default size.
2018-12-04 16:52:56 +01:00
Rect2 saved_size = EditorSettings : : get_singleton ( ) - > get_project_metadata ( " dialog_bounds " , " editor_settings " , Rect2 ( ) ) ;
if ( saved_size ! = Rect2 ( ) ) {
popup ( saved_size ) ;
2017-03-02 22:43:56 +01:00
} else {
2019-04-26 21:36:44 +02:00
popup_centered_clamped ( Size2 ( 900 , 700 ) * EDSCALE , 0.8 ) ;
2017-03-02 22:43:56 +01:00
}
2017-12-17 18:22:26 +01:00
_focus_current_search_box ( ) ;
2017-03-02 22:43:56 +01:00
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
void EditorSettingsDialog : : _filter_shortcuts ( const String & p_filter ) {
2016-07-03 15:07:16 +02:00
shortcut_filter = p_filter ;
_update_shortcuts ( ) ;
}
2017-10-15 13:36:36 +02:00
void EditorSettingsDialog : : _undo_redo_callback ( void * p_self , const String & p_name ) {
2019-09-20 01:56:09 +02:00
EditorNode : : get_log ( ) - > add_message ( p_name , EditorLog : : MSG_TYPE_EDITOR ) ;
2017-10-15 13:36:36 +02:00
}
2014-02-10 02:10:30 +01:00
void EditorSettingsDialog : : _notification ( int p_what ) {
2017-03-02 22:43:56 +01:00
switch ( p_what ) {
2020-03-06 18:00:16 +01:00
case NOTIFICATION_VISIBILITY_CHANGED : {
if ( ! is_visible ( ) ) {
EditorSettings : : get_singleton ( ) - > set_project_metadata ( " dialog_bounds " , " editor_settings " , Rect2 ( get_position ( ) , get_size ( ) ) ) ;
set_process_unhandled_input ( false ) ;
}
} break ;
2017-10-15 13:36:36 +02:00
case NOTIFICATION_READY : {
2020-04-02 01:20:12 +02:00
undo_redo - > set_method_notify_callback ( EditorDebuggerNode : : _method_changeds , nullptr ) ;
undo_redo - > set_property_notify_callback ( EditorDebuggerNode : : _property_changeds , nullptr ) ;
2017-10-15 13:36:36 +02:00
undo_redo - > set_commit_notify_callback ( _undo_redo_callback , this ) ;
} break ;
2017-03-02 22:43:56 +01:00
case NOTIFICATION_ENTER_TREE : {
2017-12-17 18:22:26 +01:00
_update_icons ( ) ;
2017-03-02 22:43:56 +01:00
} break ;
2017-12-17 18:22:26 +01:00
case EditorSettings : : NOTIFICATION_EDITOR_SETTINGS_CHANGED : {
_update_icons ( ) ;
// Update theme colors.
2018-07-19 23:58:15 +02:00
inspector - > update_category_list ( ) ;
2017-12-17 18:22:26 +01:00
_update_shortcuts ( ) ;
} break ;
2014-02-10 02:10:30 +01:00
}
}
2017-10-15 13:36:36 +02:00
void EditorSettingsDialog : : _unhandled_input ( const Ref < InputEvent > & p_event ) {
2021-04-05 08:52:21 +02:00
ERR_FAIL_COND ( p_event . is_null ( ) ) ;
2019-10-06 17:13:56 +02:00
const Ref < InputEventKey > k = p_event ;
2017-10-15 13:36:36 +02:00
2020-03-06 18:00:16 +01:00
if ( k . is_valid ( ) & & k - > is_pressed ( ) ) {
2019-10-06 17:13:56 +02:00
bool handled = false ;
2017-10-15 13:36:36 +02:00
2020-12-07 12:32:00 +01:00
if ( ED_IS_SHORTCUT ( " ui_undo " , p_event ) ) {
2019-10-06 17:13:56 +02:00
String action = undo_redo - > get_current_action_name ( ) ;
2020-05-14 16:41:43 +02:00
if ( action ! = " " ) {
2019-10-06 17:13:56 +02:00
EditorNode : : get_log ( ) - > add_message ( " Undo: " + action , EditorLog : : MSG_TYPE_EDITOR ) ;
2020-05-14 16:41:43 +02:00
}
2019-10-06 17:13:56 +02:00
undo_redo - > undo ( ) ;
handled = true ;
}
2017-10-15 13:36:36 +02:00
2020-12-07 12:32:00 +01:00
if ( ED_IS_SHORTCUT ( " ui_redo " , p_event ) ) {
2019-10-06 17:13:56 +02:00
undo_redo - > redo ( ) ;
String action = undo_redo - > get_current_action_name ( ) ;
2020-05-14 16:41:43 +02:00
if ( action ! = " " ) {
2019-10-06 17:13:56 +02:00
EditorNode : : get_log ( ) - > add_message ( " Redo: " + action , EditorLog : : MSG_TYPE_EDITOR ) ;
2020-05-14 16:41:43 +02:00
}
2019-10-06 17:13:56 +02:00
handled = true ;
}
2017-10-15 13:36:36 +02:00
2018-04-05 19:59:35 +02:00
if ( k - > get_keycode_with_modifiers ( ) = = ( KEY_MASK_CMD | KEY_F ) ) {
2019-10-06 17:13:56 +02:00
_focus_current_search_box ( ) ;
handled = true ;
}
if ( handled ) {
2020-03-06 18:00:16 +01:00
set_input_as_handled ( ) ;
2017-10-15 13:36:36 +02:00
}
}
}
2017-12-17 18:22:26 +01:00
void EditorSettingsDialog : : _update_icons ( ) {
2021-07-17 23:22:52 +02:00
search_box - > set_right_icon ( shortcuts - > get_theme_icon ( SNAME ( " Search " ) , SNAME ( " EditorIcons " ) ) ) ;
2018-07-26 13:45:38 +02:00
search_box - > set_clear_button_enabled ( true ) ;
2021-07-17 23:22:52 +02:00
shortcut_search_box - > set_right_icon ( shortcuts - > get_theme_icon ( SNAME ( " Search " ) , SNAME ( " EditorIcons " ) ) ) ;
2018-07-26 13:45:38 +02:00
shortcut_search_box - > set_clear_button_enabled ( true ) ;
2018-07-19 23:58:15 +02:00
2021-07-17 23:22:52 +02:00
restart_close_button - > set_icon ( shortcuts - > get_theme_icon ( SNAME ( " Close " ) , SNAME ( " EditorIcons " ) ) ) ;
restart_container - > add_theme_style_override ( " panel " , shortcuts - > get_theme_stylebox ( SNAME ( " bg " ) , SNAME ( " Tree " ) ) ) ;
restart_icon - > set_texture ( shortcuts - > get_theme_icon ( SNAME ( " StatusWarning " ) , SNAME ( " EditorIcons " ) ) ) ;
restart_label - > add_theme_color_override ( " font_color " , shortcuts - > get_theme_color ( SNAME ( " warning_color " ) , SNAME ( " Editor " ) ) ) ;
2017-12-17 18:22:26 +01:00
}
2020-10-02 15:12:20 +02:00
void EditorSettingsDialog : : _event_config_confirmed ( ) {
Ref < InputEventKey > k = shortcut_editor - > get_event ( ) ;
if ( k . is_null ( ) ) {
return ;
}
if ( editing_action ) {
if ( current_action_event_index = = - 1 ) {
// Add new event
current_action_events . push_back ( k ) ;
} else {
// Edit existing event
current_action_events [ current_action_event_index ] = k ;
}
_update_builtin_action ( current_action , current_action_events ) ;
} else {
k = k - > duplicate ( ) ;
Ref < Shortcut > current_sc = EditorSettings : : get_singleton ( ) - > get_shortcut ( shortcut_being_edited ) ;
undo_redo - > create_action ( TTR ( " Change Shortcut " ) + " ' " + shortcut_being_edited + " ' " ) ;
undo_redo - > add_do_method ( current_sc . ptr ( ) , " set_shortcut " , k ) ;
undo_redo - > add_undo_method ( current_sc . ptr ( ) , " set_shortcut " , current_sc - > get_shortcut ( ) ) ;
undo_redo - > add_do_method ( this , " _update_shortcuts " ) ;
undo_redo - > add_undo_method ( this , " _update_shortcuts " ) ;
undo_redo - > add_do_method ( this , " _settings_changed " ) ;
undo_redo - > add_undo_method ( this , " _settings_changed " ) ;
undo_redo - > commit_action ( ) ;
}
}
void EditorSettingsDialog : : _update_builtin_action ( const String & p_name , const Array & p_events ) {
Array old_input_array = EditorSettings : : get_singleton ( ) - > get_builtin_action_overrides ( current_action ) ;
undo_redo - > create_action ( TTR ( " Edit Built-in Action " ) ) ;
undo_redo - > add_do_method ( EditorSettings : : get_singleton ( ) , " set_builtin_action_override " , p_name , p_events ) ;
undo_redo - > add_undo_method ( EditorSettings : : get_singleton ( ) , " set_builtin_action_override " , p_name , old_input_array ) ;
undo_redo - > add_do_method ( this , " _settings_changed " ) ;
undo_redo - > add_undo_method ( this , " _settings_changed " ) ;
undo_redo - > commit_action ( ) ;
_update_shortcuts ( ) ;
}
2016-06-05 02:31:29 +02:00
void EditorSettingsDialog : : _update_shortcuts ( ) {
2020-10-02 15:12:20 +02:00
// Before clearing the tree, take note of which categories are collapsed so that this state can be maintained when the tree is repopulated.
2018-03-23 23:02:38 +01:00
Map < String , bool > collapsed ;
2021-03-07 21:07:30 +01:00
if ( shortcuts - > get_root ( ) & & shortcuts - > get_root ( ) - > get_first_child ( ) ) {
for ( TreeItem * item = shortcuts - > get_root ( ) - > get_first_child ( ) ; item ; item = item - > get_next ( ) ) {
2018-03-23 23:02:38 +01:00
collapsed [ item - > get_text ( 0 ) ] = item - > is_collapsed ( ) ;
}
}
2016-06-05 02:31:29 +02:00
shortcuts - > clear ( ) ;
TreeItem * root = shortcuts - > create_item ( ) ;
2017-03-05 16:44:50 +01:00
Map < String , TreeItem * > sections ;
2016-06-05 02:31:29 +02:00
2020-10-02 15:12:20 +02:00
// Set up section for Common/Built-in actions
TreeItem * common_section = shortcuts - > create_item ( root ) ;
sections [ " Common " ] = common_section ;
common_section - > set_text ( 0 , TTR ( " Common " ) ) ;
if ( collapsed . has ( " Common " ) ) {
common_section - > set_collapsed ( collapsed [ " Common " ] ) ;
}
2021-07-17 23:22:52 +02:00
common_section - > set_custom_bg_color ( 0 , shortcuts - > get_theme_color ( SNAME ( " prop_subsection " ) , SNAME ( " Editor " ) ) ) ;
common_section - > set_custom_bg_color ( 1 , shortcuts - > get_theme_color ( SNAME ( " prop_subsection " ) , SNAME ( " Editor " ) ) ) ;
2020-10-02 15:12:20 +02:00
// Get the action map for the editor, and add each item to the "Common" section.
OrderedHashMap < StringName , InputMap : : Action > action_map = InputMap : : get_singleton ( ) - > get_action_map ( ) ;
for ( OrderedHashMap < StringName , InputMap : : Action > : : Element E = action_map . front ( ) ; E ; E = E . next ( ) ) {
String action_name = E . key ( ) ;
InputMap : : Action action = E . get ( ) ;
Array events ; // Need to get the list of events into an array so it can be set as metadata on the item.
Vector < String > event_strings ;
2021-05-05 03:33:08 +02:00
List < Ref < InputEvent > > all_default_events = InputMap : : get_singleton ( ) - > get_builtins ( ) . find ( action_name ) . value ( ) ;
List < Ref < InputEventKey > > key_default_events ;
// Remove all non-key events from the defaults. Only check keys, since we are in the editor.
for ( List < Ref < InputEvent > > : : Element * I = all_default_events . front ( ) ; I ; I = I - > next ( ) ) {
2020-10-02 15:12:20 +02:00
Ref < InputEventKey > k = I - > get ( ) ;
2021-05-05 03:33:08 +02:00
if ( k . is_valid ( ) ) {
key_default_events . push_back ( k ) ;
2020-10-02 15:12:20 +02:00
}
}
2021-05-05 03:33:08 +02:00
bool same_as_defaults = key_default_events . size ( ) = = action . inputs . size ( ) ; // Initially this is set to just whether the arrays are equal. Later we check the events if needed.
2020-10-02 15:12:20 +02:00
int count = 0 ;
for ( List < Ref < InputEvent > > : : Element * I = action . inputs . front ( ) ; I ; I = I - > next ( ) ) {
// Add event and event text to respective arrays.
events . push_back ( I - > get ( ) ) ;
event_strings . push_back ( I - > get ( ) - > as_text ( ) ) ;
// Only check if the events have been the same so far - once one fails, we don't need to check any more.
2021-05-13 19:13:24 +02:00
if ( same_as_defaults & & ! key_default_events [ count ] - > is_match ( I - > get ( ) ) ) {
2021-05-05 03:33:08 +02:00
same_as_defaults = false ;
2020-10-02 15:12:20 +02:00
}
count + + ;
}
// Join the text of the events with a delimiter so they can all be displayed in one cell.
String events_display_string = event_strings . is_empty ( ) ? " None " : String ( " ; " ) . join ( event_strings ) ;
2021-06-04 01:31:55 +02:00
if ( ! shortcut_filter . is_subsequence_ofi ( action_name ) & & ( events_display_string = = " None " | | ! shortcut_filter . is_subsequence_ofi ( events_display_string ) ) ) {
continue ;
}
2020-10-02 15:12:20 +02:00
TreeItem * item = shortcuts - > create_item ( common_section ) ;
item - > set_text ( 0 , action_name ) ;
item - > set_text ( 1 , events_display_string ) ;
if ( ! same_as_defaults ) {
2021-07-17 23:22:52 +02:00
item - > add_button ( 1 , shortcuts - > get_theme_icon ( SNAME ( " Reload " ) , SNAME ( " EditorIcons " ) ) , 2 ) ;
2020-10-02 15:12:20 +02:00
}
if ( events_display_string = = " None " ) {
// Fade out unassigned shortcut labels for easier visual grepping.
2021-07-17 23:22:52 +02:00
item - > set_custom_color ( 1 , shortcuts - > get_theme_color ( SNAME ( " font_color " ) , SNAME ( " Label " ) ) * Color ( 1 , 1 , 1 , 0.5 ) ) ;
2020-10-02 15:12:20 +02:00
}
2021-07-17 23:22:52 +02:00
item - > add_button ( 1 , shortcuts - > get_theme_icon ( SNAME ( " Edit " ) , SNAME ( " EditorIcons " ) ) , 0 ) ;
item - > add_button ( 1 , shortcuts - > get_theme_icon ( SNAME ( " Close " ) , SNAME ( " EditorIcons " ) ) , 1 ) ;
2020-10-02 15:12:20 +02:00
item - > set_tooltip ( 0 , action_name ) ;
item - > set_tooltip ( 1 , events_display_string ) ;
item - > set_metadata ( 0 , " Common " ) ;
item - > set_metadata ( 1 , events ) ;
}
// Editor Shortcuts
List < String > slist ;
EditorSettings : : get_singleton ( ) - > get_shortcut_list ( & slist ) ;
2017-03-05 16:44:50 +01:00
for ( List < String > : : Element * E = slist . front ( ) ; E ; E = E - > next ( ) ) {
2020-09-09 21:53:24 +02:00
Ref < Shortcut > sc = EditorSettings : : get_singleton ( ) - > get_shortcut ( E - > get ( ) ) ;
2020-05-14 16:41:43 +02:00
if ( ! sc - > has_meta ( " original " ) ) {
2016-06-05 02:31:29 +02:00
continue ;
2020-05-14 16:41:43 +02:00
}
2016-06-05 02:31:29 +02:00
2017-05-20 17:38:03 +02:00
Ref < InputEvent > original = sc - > get_meta ( " original " ) ;
2016-06-05 02:31:29 +02:00
2017-03-05 16:44:50 +01:00
String section_name = E - > get ( ) . get_slice ( " / " , 0 ) ;
2016-06-05 02:31:29 +02:00
TreeItem * section ;
if ( sections . has ( section_name ) ) {
2017-03-05 16:44:50 +01:00
section = sections [ section_name ] ;
2016-06-05 02:31:29 +02:00
} else {
section = shortcuts - > create_item ( root ) ;
2018-03-23 23:02:38 +01:00
String item_name = section_name . capitalize ( ) ;
section - > set_text ( 0 , item_name ) ;
if ( collapsed . has ( item_name ) ) {
section - > set_collapsed ( collapsed [ item_name ] ) ;
}
2016-06-05 02:31:29 +02:00
2017-03-05 16:44:50 +01:00
sections [ section_name ] = section ;
2021-07-17 23:22:52 +02:00
section - > set_custom_bg_color ( 0 , shortcuts - > get_theme_color ( SNAME ( " prop_subsection " ) , SNAME ( " Editor " ) ) ) ;
section - > set_custom_bg_color ( 1 , shortcuts - > get_theme_color ( SNAME ( " prop_subsection " ) , SNAME ( " Editor " ) ) ) ;
2016-06-05 02:31:29 +02:00
}
2019-12-12 14:52:49 +01:00
// Don't match unassigned shortcuts when searching for assigned keys in search results.
// This prevents all unassigned shortcuts from appearing when searching a string like "no".
if ( shortcut_filter . is_subsequence_ofi ( sc - > get_name ( ) ) | | ( sc - > get_as_text ( ) ! = " None " & & shortcut_filter . is_subsequence_ofi ( sc - > get_as_text ( ) ) ) ) {
2016-07-03 15:07:16 +02:00
TreeItem * item = shortcuts - > create_item ( section ) ;
2017-03-05 16:44:50 +01:00
item - > set_text ( 0 , sc - > get_name ( ) ) ;
item - > set_text ( 1 , sc - > get_as_text ( ) ) ;
2019-12-12 14:52:49 +01:00
2017-05-20 17:38:03 +02:00
if ( ! sc - > is_shortcut ( original ) & & ! ( sc - > get_shortcut ( ) . is_null ( ) & & original . is_null ( ) ) ) {
2021-07-17 23:22:52 +02:00
item - > add_button ( 1 , shortcuts - > get_theme_icon ( SNAME ( " Reload " ) , SNAME ( " EditorIcons " ) ) , 2 ) ;
2016-07-03 15:07:16 +02:00
}
2019-12-12 14:52:49 +01:00
if ( sc - > get_as_text ( ) = = " None " ) {
// Fade out unassigned shortcut labels for easier visual grepping.
2021-07-17 23:22:52 +02:00
item - > set_custom_color ( 1 , shortcuts - > get_theme_color ( SNAME ( " font_color " ) , SNAME ( " Label " ) ) * Color ( 1 , 1 , 1 , 0.5 ) ) ;
2019-12-12 14:52:49 +01:00
}
2021-07-17 23:22:52 +02:00
item - > add_button ( 1 , shortcuts - > get_theme_icon ( SNAME ( " Edit " ) , SNAME ( " EditorIcons " ) ) , 0 ) ;
item - > add_button ( 1 , shortcuts - > get_theme_icon ( SNAME ( " Close " ) , SNAME ( " EditorIcons " ) ) , 1 ) ;
2017-03-05 16:44:50 +01:00
item - > set_tooltip ( 0 , E - > get ( ) ) ;
item - > set_metadata ( 0 , E - > get ( ) ) ;
2016-06-05 02:31:29 +02:00
}
}
2016-07-03 15:07:16 +02:00
// remove sections with no shortcuts
2017-03-05 16:44:50 +01:00
for ( Map < String , TreeItem * > : : Element * E = sections . front ( ) ; E ; E = E - > next ( ) ) {
2016-07-03 15:07:16 +02:00
TreeItem * section = E - > get ( ) ;
2021-03-07 21:07:30 +01:00
if ( section - > get_first_child ( ) = = nullptr ) {
2016-07-03 15:07:16 +02:00
root - > remove_child ( section ) ;
}
}
2016-06-05 02:31:29 +02:00
}
2017-03-05 16:44:50 +01:00
void EditorSettingsDialog : : _shortcut_button_pressed ( Object * p_item , int p_column , int p_idx ) {
2017-08-24 22:58:51 +02:00
TreeItem * ti = Object : : cast_to < TreeItem > ( p_item ) ;
2016-06-05 02:31:29 +02:00
ERR_FAIL_COND ( ! ti ) ;
2021-04-03 14:11:29 +02:00
button_idx = p_idx ;
2020-10-02 15:12:20 +02:00
if ( ti - > get_metadata ( 0 ) = = " Common " ) {
// Editing a Built-in action, which can have multiple bindings.
editing_action = true ;
current_action = ti - > get_text ( 0 ) ;
switch ( button_idx ) {
case SHORTCUT_REVERT : {
Array events ;
List < Ref < InputEvent > > defaults = InputMap : : get_singleton ( ) - > get_builtins ( ) [ current_action ] ;
// Convert the list to an array, and only keep key events as this is for the editor.
for ( List < Ref < InputEvent > > : : Element * E = defaults . front ( ) ; E ; E = E - > next ( ) ) {
Ref < InputEventKey > k = E - > get ( ) ;
if ( k . is_valid ( ) ) {
events . append ( E - > get ( ) ) ;
}
}
_update_builtin_action ( current_action , events ) ;
} break ;
case SHORTCUT_EDIT :
case SHORTCUT_ERASE : {
// For Edit end Delete, we will show a popup which displays each event so the user can select which one to edit/delete.
current_action_events = ti - > get_metadata ( 1 ) ;
action_popup - > clear ( ) ;
for ( int i = 0 ; i < current_action_events . size ( ) ; i + + ) {
Ref < InputEvent > ie = current_action_events [ i ] ;
action_popup - > add_item ( ie - > as_text ( ) ) ;
action_popup - > set_item_metadata ( i , ie ) ;
}
if ( button_idx = = SHORTCUT_EDIT ) {
// If editing, add a button which can be used to add an additional event.
2021-07-17 23:22:52 +02:00
action_popup - > add_icon_item ( get_theme_icon ( SNAME ( " Add " ) , SNAME ( " EditorIcons " ) ) , TTR ( " Add " ) ) ;
2020-10-02 15:12:20 +02:00
}
action_popup - > set_position ( get_position ( ) + get_mouse_position ( ) ) ;
action_popup - > take_mouse_focus ( ) ;
action_popup - > popup ( ) ;
action_popup - > set_as_minsize ( ) ;
} break ;
default :
break ;
2020-05-14 16:41:43 +02:00
}
2020-10-02 15:12:20 +02:00
} else {
// Editing an Editor Shortcut, which can only have 1 binding.
String item = ti - > get_metadata ( 0 ) ;
Ref < Shortcut > sc = EditorSettings : : get_singleton ( ) - > get_shortcut ( item ) ;
editing_action = false ;
switch ( button_idx ) {
case EditorSettingsDialog : : SHORTCUT_EDIT :
shortcut_editor - > popup_and_configure ( sc - > get_shortcut ( ) ) ;
shortcut_being_edited = item ;
break ;
case EditorSettingsDialog : : SHORTCUT_ERASE : {
if ( ! sc . is_valid ( ) ) {
return ; //pointless, there is nothing
}
undo_redo - > create_action ( TTR ( " Erase Shortcut " ) ) ;
undo_redo - > add_do_method ( sc . ptr ( ) , " set_shortcut " , Ref < InputEvent > ( ) ) ;
undo_redo - > add_undo_method ( sc . ptr ( ) , " set_shortcut " , sc - > get_shortcut ( ) ) ;
undo_redo - > add_do_method ( this , " _update_shortcuts " ) ;
undo_redo - > add_undo_method ( this , " _update_shortcuts " ) ;
undo_redo - > add_do_method ( this , " _settings_changed " ) ;
undo_redo - > add_undo_method ( this , " _settings_changed " ) ;
undo_redo - > commit_action ( ) ;
} break ;
case EditorSettingsDialog : : SHORTCUT_REVERT : {
if ( ! sc . is_valid ( ) ) {
return ; //pointless, there is nothing
}
Ref < InputEvent > original = sc - > get_meta ( " original " ) ;
undo_redo - > create_action ( TTR ( " Restore Shortcut " ) ) ;
undo_redo - > add_do_method ( sc . ptr ( ) , " set_shortcut " , original ) ;
undo_redo - > add_undo_method ( sc . ptr ( ) , " set_shortcut " , sc - > get_shortcut ( ) ) ;
undo_redo - > add_do_method ( this , " _update_shortcuts " ) ;
undo_redo - > add_undo_method ( this , " _update_shortcuts " ) ;
undo_redo - > add_do_method ( this , " _settings_changed " ) ;
undo_redo - > add_undo_method ( this , " _settings_changed " ) ;
undo_redo - > commit_action ( ) ;
} break ;
default :
break ;
2020-05-14 16:41:43 +02:00
}
2016-06-05 02:31:29 +02:00
}
}
2020-10-02 15:12:20 +02:00
void EditorSettingsDialog : : _builtin_action_popup_index_pressed ( int p_index ) {
switch ( button_idx ) {
case SHORTCUT_EDIT : {
if ( p_index = = action_popup - > get_item_count ( ) - 1 ) {
// Selected last item in list (Add button), therefore add new
current_action_event_index = - 1 ;
shortcut_editor - > popup_and_configure ( ) ;
} else {
// Configure existing
current_action_event_index = p_index ;
shortcut_editor - > popup_and_configure ( action_popup - > get_item_metadata ( p_index ) ) ;
}
} break ;
case SHORTCUT_ERASE : {
current_action_events . remove ( p_index ) ;
_update_builtin_action ( current_action , current_action_events ) ;
} break ;
default :
break ;
2020-05-14 16:41:43 +02:00
}
2016-06-05 02:31:29 +02:00
}
2017-12-17 18:22:26 +01:00
void EditorSettingsDialog : : _tabs_tab_changed ( int p_tab ) {
_focus_current_search_box ( ) ;
}
void EditorSettingsDialog : : _focus_current_search_box ( ) {
Control * tab = tabs - > get_current_tab_control ( ) ;
2020-04-02 01:20:12 +02:00
LineEdit * current_search_box = nullptr ;
2020-05-14 16:41:43 +02:00
if ( tab = = tab_general ) {
2017-12-17 18:22:26 +01:00
current_search_box = search_box ;
2020-05-14 16:41:43 +02:00
} else if ( tab = = tab_shortcuts ) {
2017-12-17 18:22:26 +01:00
current_search_box = shortcut_search_box ;
2020-05-14 16:41:43 +02:00
}
2017-12-17 18:22:26 +01:00
if ( current_search_box ) {
current_search_box - > grab_focus ( ) ;
current_search_box - > select_all ( ) ;
}
}
2018-07-19 23:58:15 +02:00
void EditorSettingsDialog : : _editor_restart ( ) {
2019-01-25 21:23:56 +01:00
EditorNode : : get_singleton ( ) - > save_all_scenes ( ) ;
EditorNode : : get_singleton ( ) - > restart_editor ( ) ;
2018-07-19 23:58:15 +02:00
}
void EditorSettingsDialog : : _editor_restart_request ( ) {
restart_container - > show ( ) ;
}
void EditorSettingsDialog : : _editor_restart_close ( ) {
restart_container - > hide ( ) ;
}
2014-02-10 02:10:30 +01:00
void EditorSettingsDialog : : _bind_methods ( ) {
2017-10-15 13:36:36 +02:00
ClassDB : : bind_method ( D_METHOD ( " _unhandled_input " ) , & EditorSettingsDialog : : _unhandled_input ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " _update_shortcuts " ) , & EditorSettingsDialog : : _update_shortcuts ) ;
2020-10-02 15:12:20 +02:00
ClassDB : : bind_method ( D_METHOD ( " _settings_changed " ) , & EditorSettingsDialog : : _settings_changed ) ;
2014-02-10 02:10:30 +01:00
}
EditorSettingsDialog : : EditorSettingsDialog ( ) {
2020-10-02 15:12:20 +02:00
action_popup = memnew ( PopupMenu ) ;
action_popup - > connect ( " index_pressed " , callable_mp ( this , & EditorSettingsDialog : : _builtin_action_popup_index_pressed ) ) ;
add_child ( action_popup ) ;
2016-05-04 03:25:37 +02:00
set_title ( TTR ( " Editor Settings " ) ) ;
2020-03-06 18:00:16 +01:00
2017-10-15 13:36:36 +02:00
undo_redo = memnew ( UndoRedo ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
tabs = memnew ( TabContainer ) ;
2017-05-02 22:13:12 +02:00
tabs - > set_tab_align ( TabContainer : : ALIGN_LEFT ) ;
2020-02-21 18:28:45 +01:00
tabs - > connect ( " tab_changed " , callable_mp ( this , & EditorSettingsDialog : : _tabs_tab_changed ) ) ;
2014-02-10 02:10:30 +01:00
add_child ( tabs ) ;
2017-12-17 18:22:26 +01:00
// General Tab
tab_general = memnew ( VBoxContainer ) ;
tabs - > add_child ( tab_general ) ;
tab_general - > set_name ( TTR ( " General " ) ) ;
2016-01-23 20:05:27 +01:00
2017-03-05 16:44:50 +01:00
HBoxContainer * hbc = memnew ( HBoxContainer ) ;
2016-01-23 20:05:27 +01:00
hbc - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2017-12-17 18:22:26 +01:00
tab_general - > add_child ( hbc ) ;
2016-01-23 20:05:27 +01:00
2017-03-05 16:44:50 +01:00
search_box = memnew ( LineEdit ) ;
2020-08-28 23:39:19 +02:00
search_box - > set_placeholder ( TTR ( " Search " ) ) ;
2016-01-23 20:05:27 +01:00
search_box - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
hbc - > add_child ( search_box ) ;
2018-07-19 23:58:15 +02:00
inspector = memnew ( SectionedInspector ) ;
inspector - > get_inspector ( ) - > set_use_filter ( true ) ;
inspector - > register_search_box ( search_box ) ;
inspector - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
inspector - > get_inspector ( ) - > set_undo_redo ( undo_redo ) ;
tab_general - > add_child ( inspector ) ;
2020-02-21 18:28:45 +01:00
inspector - > get_inspector ( ) - > connect ( " property_edited " , callable_mp ( this , & EditorSettingsDialog : : _settings_property_edited ) ) ;
inspector - > get_inspector ( ) - > connect ( " restart_requested " , callable_mp ( this , & EditorSettingsDialog : : _editor_restart_request ) ) ;
2018-07-19 23:58:15 +02:00
restart_container = memnew ( PanelContainer ) ;
tab_general - > add_child ( restart_container ) ;
HBoxContainer * restart_hb = memnew ( HBoxContainer ) ;
restart_container - > add_child ( restart_hb ) ;
restart_icon = memnew ( TextureRect ) ;
2020-03-06 18:00:16 +01:00
restart_icon - > set_v_size_flags ( Control : : SIZE_SHRINK_CENTER ) ;
2018-07-19 23:58:15 +02:00
restart_hb - > add_child ( restart_icon ) ;
restart_label = memnew ( Label ) ;
2019-03-25 01:54:29 +01:00
restart_label - > set_text ( TTR ( " The editor must be restarted for changes to take effect. " ) ) ;
2018-07-19 23:58:15 +02:00
restart_hb - > add_child ( restart_label ) ;
restart_hb - > add_spacer ( ) ;
Button * restart_button = memnew ( Button ) ;
2020-02-21 18:28:45 +01:00
restart_button - > connect ( " pressed " , callable_mp ( this , & EditorSettingsDialog : : _editor_restart ) ) ;
2018-07-19 23:58:15 +02:00
restart_hb - > add_child ( restart_button ) ;
restart_button - > set_text ( TTR ( " Save & Restart " ) ) ;
2020-06-19 20:49:04 +02:00
restart_close_button = memnew ( Button ) ;
restart_close_button - > set_flat ( true ) ;
2020-02-21 18:28:45 +01:00
restart_close_button - > connect ( " pressed " , callable_mp ( this , & EditorSettingsDialog : : _editor_restart_close ) ) ;
2018-07-19 23:58:15 +02:00
restart_hb - > add_child ( restart_close_button ) ;
restart_container - > hide ( ) ;
2014-02-10 02:10:30 +01:00
2017-12-17 18:22:26 +01:00
// Shortcuts Tab
tab_shortcuts = memnew ( VBoxContainer ) ;
2020-10-02 15:12:20 +02:00
2017-12-17 18:22:26 +01:00
tabs - > add_child ( tab_shortcuts ) ;
tab_shortcuts - > set_name ( TTR ( " Shortcuts " ) ) ;
2016-06-05 02:31:29 +02:00
2017-03-05 16:44:50 +01:00
shortcut_search_box = memnew ( LineEdit ) ;
2020-08-28 23:39:19 +02:00
shortcut_search_box - > set_placeholder ( TTR ( " Search " ) ) ;
2016-07-03 15:07:16 +02:00
shortcut_search_box - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2020-10-02 15:12:20 +02:00
tab_shortcuts - > add_child ( shortcut_search_box ) ;
2020-02-21 18:28:45 +01:00
shortcut_search_box - > connect ( " text_changed " , callable_mp ( this , & EditorSettingsDialog : : _filter_shortcuts ) ) ;
2016-07-03 15:07:16 +02:00
2017-03-05 16:44:50 +01:00
shortcuts = memnew ( Tree ) ;
2020-03-06 18:00:16 +01:00
shortcuts - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2016-06-05 02:31:29 +02:00
shortcuts - > set_columns ( 2 ) ;
shortcuts - > set_hide_root ( true ) ;
shortcuts - > set_column_titles_visible ( true ) ;
2017-12-02 10:58:58 +01:00
shortcuts - > set_column_title ( 0 , TTR ( " Name " ) ) ;
shortcuts - > set_column_title ( 1 , TTR ( " Binding " ) ) ;
2020-02-21 18:28:45 +01:00
shortcuts - > connect ( " button_pressed " , callable_mp ( this , & EditorSettingsDialog : : _shortcut_button_pressed ) ) ;
2020-10-02 15:12:20 +02:00
tab_shortcuts - > add_child ( shortcuts ) ;
2016-06-05 02:31:29 +02:00
2020-10-02 15:12:20 +02:00
// Adding event dialog
shortcut_editor = memnew ( InputEventConfigurationDialog ) ;
shortcut_editor - > connect ( " confirmed " , callable_mp ( this , & EditorSettingsDialog : : _event_config_confirmed ) ) ;
shortcut_editor - > set_allowed_input_types ( InputEventConfigurationDialog : : InputType : : INPUT_KEY ) ;
add_child ( shortcut_editor ) ;
2014-02-10 02:10:30 +01:00
set_hide_on_ok ( true ) ;
2017-03-05 16:44:50 +01:00
timer = memnew ( Timer ) ;
2018-07-03 19:33:06 +02:00
timer - > set_wait_time ( 1.5 ) ;
2020-02-21 18:28:45 +01:00
timer - > connect ( " timeout " , callable_mp ( this , & EditorSettingsDialog : : _settings_save ) ) ;
2014-02-10 02:10:30 +01:00
timer - > set_one_shot ( true ) ;
add_child ( timer ) ;
2020-02-21 18:28:45 +01:00
EditorSettings : : get_singleton ( ) - > connect ( " settings_changed " , callable_mp ( this , & EditorSettingsDialog : : _settings_changed ) ) ;
2020-12-14 19:37:30 +01:00
get_ok_button ( ) - > set_text ( TTR ( " Close " ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
updating = false ;
2014-02-10 02:10:30 +01:00
}
2017-10-15 13:36:36 +02:00
EditorSettingsDialog : : ~ EditorSettingsDialog ( ) {
memdelete ( undo_redo ) ;
}