2014-02-10 02:10:30 +01:00
/**************************************************************************/
/* editor_data.h */
/**************************************************************************/
/* 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
# ifndef EDITOR_DATA_H
# define EDITOR_DATA_H
2020-11-07 23:33:38 +01:00
# include "core/templates/list.h"
2014-02-10 02:10:30 +01:00
# include "scene/resources/texture.h"
2022-02-14 14:00:03 +01:00
class ConfigFile ;
class EditorPlugin ;
2022-03-25 18:06:46 +01:00
class EditorUndoRedoManager ;
2024-07-21 10:43:53 +02:00
class EditorContextMenuPlugin ;
class PopupMenu ;
2022-02-14 14:00:03 +01:00
2022-03-30 20:12:26 +02:00
/**
* Stores the history of objects which have been selected for editing in the Editor & the Inspector .
*
* Used in the editor to set & access the currently edited object , as well as the history of objects which have been edited .
*/
class EditorSelectionHistory {
// Stores the object & property (if relevant).
struct _Object {
2022-05-03 01:43:50 +02:00
Ref < RefCounted > ref ;
2014-02-10 02:10:30 +01:00
ObjectID object ;
String property ;
2020-11-24 10:12:55 +01:00
bool inspector_only = false ;
2014-02-10 02:10:30 +01:00
} ;
2022-03-30 20:12:26 +02:00
// Represents the selection of an object for editing.
struct HistoryElement {
// The sub-resources of the parent object (first in the path) that have been edited.
// For example, Node2D -> nested resource -> nested resource, if edited each individually in their own inspector.
Vector < _Object > path ;
// The current point in the path. This is always equal to the last item in the path - it is never decremented.
2020-11-24 10:12:55 +01:00
int level = 0 ;
2014-02-10 02:10:30 +01:00
} ;
2015-06-22 05:03:19 +02:00
friend class EditorData ;
2014-02-10 02:10:30 +01:00
2022-03-30 20:12:26 +02:00
Vector < HistoryElement > history ;
int current_elem_idx ; // The current history element being edited.
2014-02-10 02:10:30 +01:00
public :
2018-01-08 06:50:51 +01:00
void cleanup_history ( ) ;
2017-09-01 17:54:57 +02:00
bool is_at_beginning ( ) const ;
2015-09-01 05:49:47 +02:00
bool is_at_end ( ) const ;
2022-03-30 20:12:26 +02:00
// Adds an object to the selection history. A property name can be passed if the target is a subresource of the given object.
// If the object should not change the main screen plugin, it can be set as inspector only.
void add_object ( ObjectID p_object , const String & p_property = String ( ) , bool p_inspector_only = false ) ;
2024-08-02 22:50:22 +02:00
void replace_object ( ObjectID p_old_object , ObjectID p_new_object ) ;
2014-02-10 02:10:30 +01:00
2015-09-01 05:49:47 +02:00
int get_history_len ( ) ;
int get_history_pos ( ) ;
2022-03-30 20:12:26 +02:00
// Gets an object from the history. The most recent object would be the object with p_obj = get_history_len() - 1.
2015-09-01 05:49:47 +02:00
ObjectID get_history_obj ( int p_obj ) const ;
2014-02-10 02:10:30 +01:00
bool next ( ) ;
bool previous ( ) ;
ObjectID get_current ( ) ;
2018-06-19 03:10:48 +02:00
bool is_current_inspector_only ( ) const ;
2014-02-10 02:10:30 +01:00
2022-03-30 20:12:26 +02:00
// Gets the size of the path of the current history item.
2014-02-10 02:10:30 +01:00
int get_path_size ( ) const ;
2022-03-30 20:12:26 +02:00
// Gets the object of the current history item, if valid.
2014-02-10 02:10:30 +01:00
ObjectID get_path_object ( int p_index ) const ;
2022-03-30 20:12:26 +02:00
// Gets the property of the current history item.
2014-02-10 02:10:30 +01:00
String get_path_property ( int p_index ) const ;
void clear ( ) ;
2022-03-30 20:12:26 +02:00
EditorSelectionHistory ( ) ;
2014-02-10 02:10:30 +01:00
} ;
2015-06-22 05:03:19 +02:00
class EditorSelection ;
2014-02-10 02:10:30 +01:00
class EditorData {
public :
struct CustomType {
String name ;
Ref < Script > script ;
2019-06-11 20:43:37 +02:00
Ref < Texture2D > icon ;
2014-02-10 02:10:30 +01:00
} ;
2017-07-06 09:18:20 +02:00
struct EditedScene {
2020-11-24 10:12:55 +01:00
Node * root = nullptr ;
2019-08-15 19:47:21 +02:00
String path ;
2021-01-17 01:09:17 +01:00
uint64_t file_modified_time = 0 ;
2017-07-06 09:18:20 +02:00
Dictionary editor_states ;
List < Node * > selection ;
2022-03-30 20:12:26 +02:00
Vector < EditorSelectionHistory : : HistoryElement > history_stored ;
2020-11-24 10:12:55 +01:00
int history_current = 0 ;
2017-07-06 09:18:20 +02:00
Dictionary custom_state ;
NodePath live_edit_root ;
2022-03-25 18:06:46 +01:00
int history_id = 0 ;
uint64_t last_checked_version = 0 ;
2017-07-06 09:18:20 +02:00
} ;
2024-07-21 10:43:53 +02:00
enum ContextMenuSlot {
CONTEXT_SLOT_SCENE_TREE ,
CONTEXT_SLOT_FILESYSTEM ,
CONTEXT_SLOT_SCRIPT_EDITOR ,
CONTEXT_SUBMENU_SLOT_FILESYSTEM_CREATE ,
} ;
inline static constexpr int CONTEXT_MENU_ITEM_ID_BASE = 1000 ;
struct ContextMenu {
int p_slot ;
Ref < EditorContextMenuPlugin > plugin ;
} ;
Vector < ContextMenu > context_menu_plugins ;
2017-03-05 16:44:50 +01:00
private :
2014-02-10 02:10:30 +01:00
Vector < EditorPlugin * > editor_plugins ;
2023-05-11 23:46:53 +02:00
HashMap < StringName , EditorPlugin * > extension_editor_plugins ;
2014-02-10 02:10:30 +01:00
struct PropertyData {
String name ;
Variant value ;
} ;
2022-05-13 15:04:37 +02:00
HashMap < String , Vector < CustomType > > custom_types ;
2014-02-10 02:10:30 +01:00
List < PropertyData > clipboard ;
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo_manager ;
2021-04-28 17:39:57 +02:00
Vector < Callable > undo_redo_callbacks ;
2022-05-13 15:04:37 +02:00
HashMap < StringName , Callable > move_element_functions ;
2014-02-10 02:10:30 +01:00
2015-06-22 05:03:19 +02:00
Vector < EditedScene > edited_scene ;
2022-03-25 18:06:46 +01:00
int current_edited_scene = - 1 ;
int last_created_scene = 1 ;
2014-02-10 02:10:30 +01:00
2022-05-19 17:00:06 +02:00
bool _find_updated_instances ( Node * p_root , Node * p_node , HashSet < String > & checked_paths ) ;
2015-12-14 00:39:01 +01:00
2018-07-29 05:36:43 +02:00
HashMap < StringName , String > _script_class_icon_paths ;
2018-09-02 23:40:51 +02:00
HashMap < String , StringName > _script_class_file_to_path ;
2023-03-31 21:17:59 +02:00
HashMap < Ref < Script > , Ref < Texture > > _script_icon_cache ;
2023-03-31 21:17:59 +02:00
Ref < Texture2D > _load_script_icon ( const String & p_path ) const ;
2018-07-29 05:36:43 +02:00
2014-02-10 02:10:30 +01:00
public :
2023-08-11 15:55:47 +02:00
EditorPlugin * get_handling_main_editor ( Object * p_object ) ;
Vector < EditorPlugin * > get_handling_sub_editors ( Object * p_object ) ;
2024-02-15 17:25:58 +01:00
EditorPlugin * get_editor_by_name ( const String & p_name ) ;
2014-02-10 02:10:30 +01:00
void copy_object_params ( Object * p_object ) ;
void paste_object_params ( Object * p_object ) ;
2023-05-11 04:17:03 +02:00
Dictionary get_editor_plugin_states ( ) const ;
2016-07-08 18:36:57 +02:00
Dictionary get_scene_editor_states ( int p_idx ) const ;
2023-05-11 04:17:03 +02:00
void set_editor_plugin_states ( const Dictionary & p_states ) ;
2014-02-10 02:10:30 +01:00
void get_editor_breakpoints ( List < String > * p_breakpoints ) ;
void clear_editor_states ( ) ;
void save_editor_external_data ( ) ;
void apply_changes_in_editors ( ) ;
void add_editor_plugin ( EditorPlugin * p_plugin ) ;
void remove_editor_plugin ( EditorPlugin * p_plugin ) ;
2016-02-28 03:10:44 +01:00
int get_editor_plugin_count ( ) const ;
EditorPlugin * get_editor_plugin ( int p_idx ) ;
2023-05-11 23:46:53 +02:00
void add_extension_editor_plugin ( const StringName & p_class_name , EditorPlugin * p_plugin ) ;
void remove_extension_editor_plugin ( const StringName & p_class_name ) ;
bool has_extension_editor_plugin ( const StringName & p_class_name ) ;
EditorPlugin * get_extension_editor_plugin ( const StringName & p_class_name ) ;
2024-07-21 10:43:53 +02:00
// Context menu plugin.
void add_context_menu_plugin ( ContextMenuSlot p_slot , const Ref < EditorContextMenuPlugin > & p_plugin ) ;
void remove_context_menu_plugin ( ContextMenuSlot p_slot , const Ref < EditorContextMenuPlugin > & p_plugin ) ;
int match_context_menu_shortcut ( ContextMenuSlot p_slot , const Ref < InputEvent > & p_event ) ;
void add_options_from_plugins ( PopupMenu * p_popup , ContextMenuSlot p_slot , const Vector < String > & p_paths ) ;
void filesystem_options_pressed ( ContextMenuSlot p_slot , int p_option , const Vector < String > & p_selected ) ;
void scene_tree_options_pressed ( ContextMenuSlot p_slot , int p_option , const List < Node * > & p_selected ) ;
void script_editor_options_pressed ( ContextMenuSlot p_slot , int p_option , const Ref < Resource > & p_script ) ;
template < typename T >
void invoke_plugin_callback ( ContextMenuSlot p_slot , int p_option , const T & p_arg ) ;
2023-05-11 23:46:53 +02:00
2021-08-31 10:48:45 +02:00
void add_undo_redo_inspector_hook_callback ( Callable p_callable ) ; // Callbacks should have this signature: void (Object* undo_redo, Object *modified_object, String property, Variant new_value)
2021-04-28 17:39:57 +02:00
void remove_undo_redo_inspector_hook_callback ( Callable p_callable ) ;
const Vector < Callable > get_undo_redo_inspector_hook_callback ( ) ;
2014-02-10 02:10:30 +01:00
2021-08-31 10:48:45 +02:00
void add_move_array_element_function ( const StringName & p_class , Callable p_callable ) ; // Function should have this signature: void (Object* undo_redo, Object *modified_object, String array_prefix, int element_index, int new_position)
void remove_move_array_element_function ( const StringName & p_class ) ;
Callable get_move_array_element_function ( const StringName & p_class ) const ;
2014-02-10 02:10:30 +01:00
void save_editor_global_states ( ) ;
2019-06-11 20:43:37 +02:00
void add_custom_type ( const String & p_type , const String & p_inherits , const Ref < Script > & p_script , const Ref < Texture2D > & p_icon ) ;
2022-11-16 00:13:39 +01:00
Variant instantiate_custom_type ( const String & p_type , const String & p_inherits ) ;
2014-02-10 02:10:30 +01:00
void remove_custom_type ( const String & p_type ) ;
2022-05-13 15:04:37 +02:00
const HashMap < String , Vector < CustomType > > & get_custom_types ( ) const { return custom_types ; }
2022-02-28 01:57:34 +01:00
const CustomType * get_custom_type_by_name ( const String & p_name ) const ;
const CustomType * get_custom_type_by_path ( const String & p_path ) const ;
bool is_type_recognized ( const String & p_type ) const ;
2015-06-22 05:03:19 +02:00
2020-10-22 21:02:57 +02:00
void instantiate_object_properties ( Object * p_object ) ;
2015-06-22 05:03:19 +02:00
int add_edited_scene ( int p_at_pos ) ;
void move_edited_scene_index ( int p_idx , int p_to_idx ) ;
void remove_scene ( int p_idx ) ;
void set_edited_scene ( int p_idx ) ;
void set_edited_scene_root ( Node * p_root ) ;
int get_edited_scene ( ) const ;
2023-04-12 21:02:28 +02:00
int get_edited_scene_from_path ( const String & p_path ) const ;
2016-06-26 05:54:17 +02:00
Node * get_edited_scene_root ( int p_idx = - 1 ) ;
2015-06-22 05:03:19 +02:00
int get_edited_scene_count ( ) const ;
2017-07-06 09:18:20 +02:00
Vector < EditedScene > get_edited_scenes ( ) const ;
2023-04-12 21:02:28 +02:00
2020-01-19 18:48:59 +01:00
String get_scene_title ( int p_idx , bool p_always_strip_extension = false ) const ;
2015-06-22 05:03:19 +02:00
String get_scene_path ( int p_idx ) const ;
2015-07-24 19:18:02 +02:00
String get_scene_type ( int p_idx ) const ;
2017-12-26 20:32:12 +01:00
void set_scene_path ( int p_idx , const String & p_path ) ;
2015-07-26 15:44:10 +02:00
Ref < Script > get_scene_root_script ( int p_idx ) const ;
2019-08-28 19:42:27 +02:00
void set_scene_modified_time ( int p_idx , uint64_t p_time ) ;
uint64_t get_scene_modified_time ( int p_idx ) const ;
2015-06-22 05:03:19 +02:00
void clear_edited_scenes ( ) ;
2015-08-02 17:29:37 +02:00
void set_edited_scene_live_edit_root ( const NodePath & p_root ) ;
NodePath get_edited_scene_live_edit_root ( ) ;
2015-12-14 00:39:01 +01:00
bool check_and_update_scene ( int p_idx ) ;
2016-01-23 22:28:30 +01:00
void move_edited_scene_to_index ( int p_idx ) ;
2023-04-12 21:02:28 +02:00
2018-01-08 16:55:22 +01:00
bool call_build ( ) ;
2015-06-22 05:03:19 +02:00
2022-03-25 18:06:46 +01:00
void set_scene_as_saved ( int p_idx ) ;
bool is_scene_changed ( int p_idx ) ;
int get_scene_history_id_from_path ( const String & p_path ) const ;
int get_current_edited_scene_history_id ( ) const ;
int get_scene_history_id ( int p_idx ) const ;
2015-06-22 05:03:19 +02:00
void set_plugin_window_layout ( Ref < ConfigFile > p_layout ) ;
void get_plugin_window_layout ( Ref < ConfigFile > p_layout ) ;
2022-03-30 20:12:26 +02:00
void save_edited_scene_state ( EditorSelection * p_selection , EditorSelectionHistory * p_history , const Dictionary & p_custom ) ;
Dictionary restore_edited_scene_state ( EditorSelection * p_selection , EditorSelectionHistory * p_history ) ;
2015-12-09 13:08:41 +01:00
void notify_edited_scene_changed ( ) ;
2018-01-12 22:43:29 +01:00
void notify_resource_saved ( const Ref < Resource > & p_resource ) ;
2024-01-18 13:06:48 +01:00
void notify_scene_saved ( const String & p_path ) ;
2015-06-22 05:03:19 +02:00
2018-07-25 21:43:17 +02:00
bool script_class_is_parent ( const String & p_class , const String & p_inherits ) ;
2018-09-02 23:40:51 +02:00
StringName script_class_get_base ( const String & p_class ) const ;
2021-01-06 20:25:05 +01:00
Variant script_class_instance ( const String & p_class ) ;
2018-09-02 23:40:51 +02:00
2019-11-06 13:10:25 +01:00
Ref < Script > script_class_load_script ( const String & p_class ) const ;
2018-09-02 23:40:51 +02:00
StringName script_class_get_name ( const String & p_path ) const ;
void script_class_set_name ( const String & p_path , const StringName & p_class ) ;
String script_class_get_icon_path ( const String & p_class ) const ;
void script_class_set_icon_path ( const String & p_class , const String & p_icon_path ) ;
2018-07-29 05:36:43 +02:00
void script_class_clear_icon_paths ( ) { _script_class_icon_paths . clear ( ) ; }
void script_class_save_icon_paths ( ) ;
void script_class_load_icon_paths ( ) ;
2018-07-25 21:43:17 +02:00
2023-03-31 21:17:59 +02:00
Ref < Texture2D > extension_class_get_icon ( const String & p_class ) const ;
2023-03-31 21:17:59 +02:00
Ref < Texture2D > get_script_icon ( const Ref < Script > & p_script ) ;
void clear_script_icon_cache ( ) ;
2014-02-10 02:10:30 +01:00
EditorData ( ) ;
2022-12-23 23:53:16 +01:00
~ EditorData ( ) ;
2014-02-10 02:10:30 +01:00
} ;
2022-03-30 20:12:26 +02:00
/**
* Stores and provides access to the nodes currently selected in the editor .
*
* This provides a central location for storing " selected " nodes , as a selection can be triggered from multiple places ,
* such as the SceneTreeDock or a main screen editor plugin ( e . g . CanvasItemEditor ) .
*/
2014-02-10 02:10:30 +01:00
class EditorSelection : public Object {
2017-01-03 03:03:46 +01:00
GDCLASS ( EditorSelection , Object ) ;
2014-02-10 02:10:30 +01:00
2022-03-30 20:12:26 +02:00
// Contains the selected nodes and corresponding metadata.
// Metadata objects come from calling _get_editor_data on the editor_plugins, passing the selected node.
2022-05-13 15:04:37 +02:00
HashMap < Node * , Object * > selection ;
2014-02-10 02:10:30 +01:00
2022-03-30 20:12:26 +02:00
// Tracks whether the selection change signal has been emitted.
// Prevents multiple signals being called in one frame.
2022-02-15 15:56:58 +01:00
bool emitted = false ;
2022-03-30 20:12:26 +02:00
2022-02-15 15:56:58 +01:00
bool changed = false ;
2022-03-30 20:12:26 +02:00
bool node_list_changed = false ;
2014-02-10 02:10:30 +01:00
void _node_removed ( Node * p_node ) ;
2022-03-30 20:12:26 +02:00
// Editor plugins which are related to selection.
2014-02-10 02:10:30 +01:00
List < Object * > editor_plugins ;
List < Node * > selected_node_list ;
2022-03-30 20:12:26 +02:00
void _update_node_list ( ) ;
2022-08-05 03:41:48 +02:00
TypedArray < Node > _get_transformable_selected_nodes ( ) ;
2017-12-18 14:12:57 +01:00
void _emit_change ( ) ;
2016-09-10 22:50:20 +02:00
2014-02-10 02:10:30 +01:00
protected :
static void _bind_methods ( ) ;
2017-03-05 16:44:50 +01:00
public :
2014-02-10 02:10:30 +01:00
void add_node ( Node * p_node ) ;
void remove_node ( Node * p_node ) ;
2022-03-30 20:12:26 +02:00
bool is_selected ( Node * p_node ) const ;
2014-02-10 02:10:30 +01:00
template < typename T >
T * get_node_editor_data ( Node * p_node ) {
2020-05-14 16:41:43 +02:00
if ( ! selection . has ( p_node ) ) {
2020-04-02 01:20:12 +02:00
return nullptr ;
2020-05-14 16:41:43 +02:00
}
2017-08-24 22:58:51 +02:00
return Object : : cast_to < T > ( selection [ p_node ] ) ;
2014-02-10 02:10:30 +01:00
}
2022-03-30 20:12:26 +02:00
// Adds an editor plugin which can provide metadata for selected nodes.
2014-02-10 02:10:30 +01:00
void add_editor_plugin ( Object * p_object ) ;
void update ( ) ;
void clear ( ) ;
2022-03-30 20:12:26 +02:00
// Returns all the selected nodes.
TypedArray < Node > get_selected_nodes ( ) ;
// Returns only the top level selected nodes.
// That is, if the selection includes some node and a child of that node, only the parent is returned.
2014-02-10 02:10:30 +01:00
List < Node * > & get_selected_node_list ( ) ;
2022-03-30 20:12:26 +02:00
// Returns all the selected nodes (list version of "get_selected_nodes").
2019-11-04 16:45:16 +01:00
List < Node * > get_full_selected_node_list ( ) ;
2022-03-30 20:12:26 +02:00
// Returns the map of selected objects and their metadata.
2022-05-13 15:04:37 +02:00
HashMap < Node * , Object * > & get_selection ( ) { return selection ; }
2014-02-10 02:10:30 +01:00
EditorSelection ( ) ;
~ EditorSelection ( ) ;
} ;
# endif // EDITOR_DATA_H