2014-02-10 09:10:30 +08:00
/*************************************************************************/
/* editor_data.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 20:16:55 +08:00
/* https://godotengine.org */
2014-02-10 09:10:30 +08:00
/*************************************************************************/
2022-01-04 04:27:34 +08:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-10 09:10:30 +08: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 07:50:27 +08:00
2014-02-10 09:10:30 +08:00
# ifndef EDITOR_DATA_H
# define EDITOR_DATA_H
2020-11-08 06:33:38 +08:00
# include "core/templates/list.h"
2014-02-10 09:10:30 +08:00
# include "scene/resources/texture.h"
2022-02-14 21:00:03 +08:00
class ConfigFile ;
class EditorPlugin ;
2022-03-26 01:06:46 +08:00
class EditorUndoRedoManager ;
2022-02-14 21:00:03 +08:00
2022-03-31 02:12:26 +08: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 07:43:50 +08:00
Ref < RefCounted > ref ;
2014-02-10 09:10:30 +08:00
ObjectID object ;
String property ;
2020-11-24 17:12:55 +08:00
bool inspector_only = false ;
2014-02-10 09:10:30 +08:00
} ;
2022-03-31 02:12:26 +08: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 17:12:55 +08:00
int level = 0 ;
2014-02-10 09:10:30 +08:00
} ;
2015-06-22 11:03:19 +08:00
friend class EditorData ;
2014-02-10 09:10:30 +08:00
2022-03-31 02:12:26 +08:00
Vector < HistoryElement > history ;
int current_elem_idx ; // The current history element being edited.
2014-02-10 09:10:30 +08:00
public :
2018-01-08 13:50:51 +08:00
void cleanup_history ( ) ;
2017-09-01 23:54:57 +08:00
bool is_at_beginning ( ) const ;
2015-09-01 11:49:47 +08:00
bool is_at_end ( ) const ;
2022-03-31 02:12:26 +08: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 ) ;
2014-02-10 09:10:30 +08:00
2015-09-01 11:49:47 +08:00
int get_history_len ( ) ;
int get_history_pos ( ) ;
2022-03-31 02:12:26 +08: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 11:49:47 +08:00
ObjectID get_history_obj ( int p_obj ) const ;
2018-06-19 09:10:48 +08:00
bool is_history_obj_inspector_only ( int p_obj ) const ;
2015-09-01 11:49:47 +08:00
2014-02-10 09:10:30 +08:00
bool next ( ) ;
bool previous ( ) ;
ObjectID get_current ( ) ;
2018-06-19 09:10:48 +08:00
bool is_current_inspector_only ( ) const ;
2014-02-10 09:10:30 +08:00
2022-03-31 02:12:26 +08:00
// Gets the size of the path of the current history item.
2014-02-10 09:10:30 +08:00
int get_path_size ( ) const ;
2022-03-31 02:12:26 +08:00
// Gets the object of the current history item, if valid.
2014-02-10 09:10:30 +08:00
ObjectID get_path_object ( int p_index ) const ;
2022-03-31 02:12:26 +08:00
// Gets the property of the current history item.
2014-02-10 09:10:30 +08:00
String get_path_property ( int p_index ) const ;
void clear ( ) ;
2022-03-31 02:12:26 +08:00
EditorSelectionHistory ( ) ;
2014-02-10 09:10:30 +08:00
} ;
2015-06-22 11:03:19 +08:00
class EditorSelection ;
2014-02-10 09:10:30 +08:00
class EditorData {
public :
struct CustomType {
String name ;
Ref < Script > script ;
2019-06-12 02:43:37 +08:00
Ref < Texture2D > icon ;
2014-02-10 09:10:30 +08:00
} ;
2017-07-06 15:18:20 +08:00
struct EditedScene {
2020-11-24 17:12:55 +08:00
Node * root = nullptr ;
2019-08-16 01:47:21 +08:00
String path ;
2021-01-17 08:09:17 +08:00
uint64_t file_modified_time = 0 ;
2017-07-06 15:18:20 +08:00
Dictionary editor_states ;
List < Node * > selection ;
2022-03-31 02:12:26 +08:00
Vector < EditorSelectionHistory : : HistoryElement > history_stored ;
2020-11-24 17:12:55 +08:00
int history_current = 0 ;
2017-07-06 15:18:20 +08:00
Dictionary custom_state ;
NodePath live_edit_root ;
2022-03-26 01:06:46 +08:00
int history_id = 0 ;
uint64_t last_checked_version = 0 ;
2017-07-06 15:18:20 +08:00
} ;
2017-03-05 23:44:50 +08:00
private :
2014-02-10 09:10:30 +08:00
Vector < EditorPlugin * > editor_plugins ;
struct PropertyData {
String name ;
Variant value ;
} ;
2022-05-13 21:04:37 +08:00
HashMap < String , Vector < CustomType > > custom_types ;
2014-02-10 09:10:30 +08:00
List < PropertyData > clipboard ;
2022-03-26 01:06:46 +08:00
Ref < EditorUndoRedoManager > undo_redo_manager ;
2021-04-28 23:39:57 +08:00
Vector < Callable > undo_redo_callbacks ;
2022-05-13 21:04:37 +08:00
HashMap < StringName , Callable > move_element_functions ;
2014-02-10 09:10:30 +08:00
2015-06-22 11:03:19 +08:00
Vector < EditedScene > edited_scene ;
2022-03-26 01:06:46 +08:00
int current_edited_scene = - 1 ;
int last_created_scene = 1 ;
2014-02-10 09:10:30 +08:00
2022-05-19 23:00:06 +08:00
bool _find_updated_instances ( Node * p_root , Node * p_node , HashSet < String > & checked_paths ) ;
2015-12-14 07:39:01 +08:00
2018-07-29 11:36:43 +08:00
HashMap < StringName , String > _script_class_icon_paths ;
2018-09-03 05:40:51 +08:00
HashMap < String , StringName > _script_class_file_to_path ;
2018-07-29 11:36:43 +08:00
2014-02-10 09:10:30 +08:00
public :
EditorPlugin * get_editor ( Object * p_object ) ;
2016-03-30 07:02:53 +08:00
Vector < EditorPlugin * > get_subeditors ( Object * p_object ) ;
2014-02-10 09:10:30 +08:00
EditorPlugin * get_editor ( String p_name ) ;
void copy_object_params ( Object * p_object ) ;
void paste_object_params ( Object * p_object ) ;
Dictionary get_editor_states ( ) const ;
2016-07-09 00:36:57 +08:00
Dictionary get_scene_editor_states ( int p_idx ) const ;
2014-02-10 09:10:30 +08:00
void set_editor_states ( const Dictionary & p_states ) ;
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 10:10:44 +08:00
int get_editor_plugin_count ( ) const ;
EditorPlugin * get_editor_plugin ( int p_idx ) ;
2022-03-26 01:06:46 +08:00
Ref < EditorUndoRedoManager > & get_undo_redo ( ) ;
2021-08-31 16:48:45 +08: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 23:39:57 +08:00
void remove_undo_redo_inspector_hook_callback ( Callable p_callable ) ;
const Vector < Callable > get_undo_redo_inspector_hook_callback ( ) ;
2014-02-10 09:10:30 +08:00
2021-08-31 16:48:45 +08: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 09:10:30 +08:00
void save_editor_global_states ( ) ;
void restore_editor_global_states ( ) ;
2019-06-12 02:43:37 +08:00
void add_custom_type ( const String & p_type , const String & p_inherits , const Ref < Script > & p_script , const Ref < Texture2D > & p_icon ) ;
2021-01-07 03:25:05 +08:00
Variant instance_custom_type ( const String & p_type , const String & p_inherits ) ;
2014-02-10 09:10:30 +08:00
void remove_custom_type ( const String & p_type ) ;
2022-05-13 21:04:37 +08:00
const HashMap < String , Vector < CustomType > > & get_custom_types ( ) const { return custom_types ; }
2022-02-28 08:57:34 +08: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 11:03:19 +08:00
2020-10-23 03:02:57 +08:00
void instantiate_object_properties ( Object * p_object ) ;
2015-06-22 11:03:19 +08: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 ;
2016-06-26 11:54:17 +08:00
Node * get_edited_scene_root ( int p_idx = - 1 ) ;
2015-06-22 11:03:19 +08:00
int get_edited_scene_count ( ) const ;
2017-07-06 15:18:20 +08:00
Vector < EditedScene > get_edited_scenes ( ) const ;
2020-01-20 01:48:59 +08:00
String get_scene_title ( int p_idx , bool p_always_strip_extension = false ) const ;
2015-06-22 11:03:19 +08:00
String get_scene_path ( int p_idx ) const ;
2015-07-25 01:18:02 +08:00
String get_scene_type ( int p_idx ) const ;
2017-12-27 03:32:12 +08:00
void set_scene_path ( int p_idx , const String & p_path ) ;
2015-07-26 21:44:10 +08:00
Ref < Script > get_scene_root_script ( int p_idx ) const ;
2016-06-26 11:54:17 +08:00
void set_edited_scene_version ( uint64_t version , int p_scene_idx = - 1 ) ;
2019-08-29 01:42:27 +08: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 11:03:19 +08:00
void clear_edited_scenes ( ) ;
2015-08-02 23:29:37 +08:00
void set_edited_scene_live_edit_root ( const NodePath & p_root ) ;
NodePath get_edited_scene_live_edit_root ( ) ;
2015-12-14 07:39:01 +08:00
bool check_and_update_scene ( int p_idx ) ;
2016-01-24 05:28:30 +08:00
void move_edited_scene_to_index ( int p_idx ) ;
2018-01-08 23:55:22 +08:00
bool call_build ( ) ;
2015-06-22 11:03:19 +08:00
2022-03-26 01:06:46 +08: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 11:03:19 +08:00
void set_plugin_window_layout ( Ref < ConfigFile > p_layout ) ;
void get_plugin_window_layout ( Ref < ConfigFile > p_layout ) ;
2022-03-31 02:12:26 +08: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 20:08:41 +08:00
void notify_edited_scene_changed ( ) ;
2018-01-13 05:43:29 +08:00
void notify_resource_saved ( const Ref < Resource > & p_resource ) ;
2015-06-22 11:03:19 +08:00
2018-07-26 03:43:17 +08:00
bool script_class_is_parent ( const String & p_class , const String & p_inherits ) ;
2018-09-03 05:40:51 +08:00
StringName script_class_get_base ( const String & p_class ) const ;
2021-01-07 03:25:05 +08:00
Variant script_class_instance ( const String & p_class ) ;
2018-09-03 05:40:51 +08:00
2019-11-06 20:10:25 +08:00
Ref < Script > script_class_load_script ( const String & p_class ) const ;
2018-09-03 05:40:51 +08: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 11:36:43 +08: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-26 03:43:17 +08:00
2014-02-10 09:10:30 +08:00
EditorData ( ) ;
} ;
2022-03-31 02:12:26 +08: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 09:10:30 +08:00
class EditorSelection : public Object {
2017-01-03 10:03:46 +08:00
GDCLASS ( EditorSelection , Object ) ;
2014-02-10 09:10:30 +08:00
2022-03-31 02:12:26 +08: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 21:04:37 +08:00
HashMap < Node * , Object * > selection ;
2014-02-10 09:10:30 +08:00
2022-03-31 02:12:26 +08:00
// Tracks whether the selection change signal has been emitted.
// Prevents multiple signals being called in one frame.
2022-02-15 22:56:58 +08:00
bool emitted = false ;
2022-03-31 02:12:26 +08:00
2022-02-15 22:56:58 +08:00
bool changed = false ;
2022-03-31 02:12:26 +08:00
bool node_list_changed = false ;
2014-02-10 09:10:30 +08:00
void _node_removed ( Node * p_node ) ;
2022-03-31 02:12:26 +08:00
// Editor plugins which are related to selection.
2014-02-10 09:10:30 +08:00
List < Object * > editor_plugins ;
List < Node * > selected_node_list ;
2022-03-31 02:12:26 +08:00
void _update_node_list ( ) ;
2022-08-05 09:41:48 +08:00
TypedArray < Node > _get_transformable_selected_nodes ( ) ;
2017-12-18 21:12:57 +08:00
void _emit_change ( ) ;
2016-09-11 04:50:20 +08:00
2014-02-10 09:10:30 +08:00
protected :
static void _bind_methods ( ) ;
2017-03-05 23:44:50 +08:00
public :
2014-02-10 09:10:30 +08:00
void add_node ( Node * p_node ) ;
void remove_node ( Node * p_node ) ;
2022-03-31 02:12:26 +08:00
bool is_selected ( Node * p_node ) const ;
2014-02-10 09:10:30 +08:00
template < class T >
T * get_node_editor_data ( Node * p_node ) {
2020-05-14 22:41:43 +08:00
if ( ! selection . has ( p_node ) ) {
2020-04-02 07:20:12 +08:00
return nullptr ;
2020-05-14 22:41:43 +08:00
}
2017-08-25 04:58:51 +08:00
return Object : : cast_to < T > ( selection [ p_node ] ) ;
2014-02-10 09:10:30 +08:00
}
2022-03-31 02:12:26 +08:00
// Adds an editor plugin which can provide metadata for selected nodes.
2014-02-10 09:10:30 +08:00
void add_editor_plugin ( Object * p_object ) ;
void update ( ) ;
void clear ( ) ;
2022-03-31 02:12:26 +08: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 09:10:30 +08:00
List < Node * > & get_selected_node_list ( ) ;
2022-03-31 02:12:26 +08:00
// Returns all the selected nodes (list version of "get_selected_nodes").
2019-11-04 23:45:16 +08:00
List < Node * > get_full_selected_node_list ( ) ;
2022-03-31 02:12:26 +08:00
// Returns the map of selected objects and their metadata.
2022-05-13 21:04:37 +08:00
HashMap < Node * , Object * > & get_selection ( ) { return selection ; }
2014-02-10 09:10:30 +08:00
EditorSelection ( ) ;
~ EditorSelection ( ) ;
} ;
# endif // EDITOR_DATA_H