1 /*************************************************************************/ 2 /* editor_inspector.h */ 3 /*************************************************************************/ 4 /* This file is part of: */ 5 /* GODOT ENGINE */ 6 /* https://godotengine.org */ 7 /*************************************************************************/ 8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ 9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ 10 /* */ 11 /* Permission is hereby granted, free of charge, to any person obtaining */ 12 /* a copy of this software and associated documentation files (the */ 13 /* "Software"), to deal in the Software without restriction, including */ 14 /* without limitation the rights to use, copy, modify, merge, publish, */ 15 /* distribute, sublicense, and/or sell copies of the Software, and to */ 16 /* permit persons to whom the Software is furnished to do so, subject to */ 17 /* the following conditions: */ 18 /* */ 19 /* The above copyright notice and this permission notice shall be */ 20 /* included in all copies or substantial portions of the Software. */ 21 /* */ 22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 29 /*************************************************************************/ 30 31 #ifndef EDITOR_INSPECTOR_H 32 #define EDITOR_INSPECTOR_H 33 34 #include "scene/gui/box_container.h" 35 #include "scene/gui/line_edit.h" 36 #include "scene/gui/scroll_container.h" 37 38 class UndoRedo; 39 40 class EditorPropertyRevert { 41 public: 42 static bool may_node_be_in_instance(Node *p_node); 43 static bool get_instanced_node_original_property(Node *p_node, const StringName &p_prop, Variant &value); 44 static bool is_node_property_different(Node *p_node, const Variant &p_current, const Variant &p_orig); 45 46 static bool can_property_revert(Object *p_object, const StringName &p_property); 47 }; 48 49 class EditorProperty : public Container { 50 51 GDCLASS(EditorProperty, Container); 52 53 private: 54 String label; 55 int text_size; 56 friend class EditorInspector; 57 Object *object; 58 StringName property; 59 60 int property_usage; 61 62 bool read_only; 63 bool checkable; 64 bool checked; 65 bool draw_red; 66 bool keying; 67 68 Rect2 right_child_rect; 69 Rect2 bottom_child_rect; 70 71 Rect2 keying_rect; 72 bool keying_hover; 73 Rect2 revert_rect; 74 bool revert_hover; 75 Rect2 check_rect; 76 bool check_hover; 77 78 bool can_revert; 79 80 bool use_folding; 81 bool draw_top_bg; 82 83 bool _is_property_different(const Variant &p_current, const Variant &p_orig); 84 bool _get_instanced_node_original_property(const StringName &p_prop, Variant &value); 85 void _focusable_focused(int p_index); 86 87 bool selectable; 88 bool selected; 89 int selected_focusable; 90 91 float split_ratio; 92 93 Vector<Control *> focusables; 94 Control *label_reference; 95 Control *bottom_editor; 96 97 mutable String tooltip_text; 98 99 protected: 100 void _notification(int p_what); 101 static void _bind_methods(); 102 103 void _gui_input(const Ref<InputEvent> &p_event); 104 105 public: 106 void emit_changed(const StringName &p_property, const Variant &p_value, const StringName &p_field = StringName(), bool p_changing = false); 107 108 virtual Size2 get_minimum_size() const; 109 110 void set_label(const String &p_label); 111 String get_label() const; 112 113 void set_read_only(bool p_read_only); 114 bool is_read_only() const; 115 116 Object *get_edited_object(); 117 StringName get_edited_property(); 118 119 virtual void update_property(); 120 void update_reload_status(); 121 122 virtual bool use_keying_next() const; 123 124 void set_checkable(bool p_checkable); 125 bool is_checkable() const; 126 127 void set_checked(bool p_checked); 128 bool is_checked() const; 129 130 void set_draw_red(bool p_draw_red); 131 bool is_draw_red() const; 132 133 void set_keying(bool p_keying); 134 bool is_keying() const; 135 136 void add_focusable(Control *p_control); 137 void select(int p_focusable = -1); 138 void deselect(); 139 bool is_selected() const; 140 141 void set_label_reference(Control *p_control); 142 void set_bottom_editor(Control *p_control); 143 144 void set_use_folding(bool p_use_folding); 145 bool is_using_folding() const; 146 147 virtual void expand_all_folding(); 148 virtual void collapse_all_folding(); 149 150 virtual Variant get_drag_data(const Point2 &p_point); 151 152 void set_selectable(bool p_selectable); 153 bool is_selectable() const; 154 155 void set_name_split_ratio(float p_ratio); 156 float get_name_split_ratio() const; 157 158 void set_object_and_property(Object *p_object, const StringName &p_property); 159 virtual Control *make_custom_tooltip(const String &p_text) const; 160 161 String get_tooltip_text() const; 162 set_draw_top_bg(bool p_draw)163 void set_draw_top_bg(bool p_draw) { draw_top_bg = p_draw; } 164 can_revert_to_default()165 bool can_revert_to_default() const { return can_revert; } 166 167 EditorProperty(); 168 }; 169 170 class EditorInspectorPlugin : public Reference { 171 GDCLASS(EditorInspectorPlugin, Reference); 172 173 friend class EditorInspector; 174 struct AddedEditor { 175 Control *property_editor; 176 Vector<String> properties; 177 String label; 178 }; 179 180 List<AddedEditor> added_editors; 181 182 protected: 183 static void _bind_methods(); 184 185 public: 186 void add_custom_control(Control *control); 187 void add_property_editor(const String &p_for_property, Control *p_prop); 188 void add_property_editor_for_multiple_properties(const String &p_label, const Vector<String> &p_properties, Control *p_prop); 189 190 virtual bool can_handle(Object *p_object); 191 virtual void parse_begin(Object *p_object); 192 virtual void parse_category(Object *p_object, const String &p_parse_category); 193 virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage); 194 virtual void parse_end(); 195 }; 196 197 class EditorInspectorCategory : public Control { 198 GDCLASS(EditorInspectorCategory, Control); 199 200 friend class EditorInspector; 201 Ref<Texture> icon; 202 String label; 203 Color bg_color; 204 mutable String tooltip_text; 205 206 protected: 207 void _notification(int p_what); 208 static void _bind_methods(); 209 210 public: 211 virtual Size2 get_minimum_size() const; 212 virtual Control *make_custom_tooltip(const String &p_text) const; 213 214 String get_tooltip_text() const; 215 216 EditorInspectorCategory(); 217 }; 218 219 class EditorInspectorSection : public Container { 220 GDCLASS(EditorInspectorSection, Container); 221 222 String label; 223 String section; 224 Object *object; 225 VBoxContainer *vbox; 226 bool vbox_added; //optimization 227 Color bg_color; 228 bool foldable; 229 230 void _test_unfold(); 231 232 protected: 233 void _notification(int p_what); 234 static void _bind_methods(); 235 void _gui_input(const Ref<InputEvent> &p_event); 236 237 public: 238 virtual Size2 get_minimum_size() const; 239 240 void setup(const String &p_section, const String &p_label, Object *p_object, const Color &p_bg_color, bool p_foldable); 241 VBoxContainer *get_vbox(); 242 void unfold(); 243 void fold(); 244 245 Object *get_edited_object(); 246 247 EditorInspectorSection(); 248 ~EditorInspectorSection(); 249 }; 250 251 class EditorInspector : public ScrollContainer { 252 GDCLASS(EditorInspector, ScrollContainer); 253 254 UndoRedo *undo_redo; 255 enum { 256 MAX_PLUGINS = 1024 257 }; 258 static Ref<EditorInspectorPlugin> inspector_plugins[MAX_PLUGINS]; 259 static int inspector_plugin_count; 260 261 VBoxContainer *main_vbox; 262 263 //map use to cache the instanced editors 264 Map<StringName, List<EditorProperty *> > editor_property_map; 265 List<EditorInspectorSection *> sections; 266 Set<StringName> pending; 267 268 void _clear(); 269 Object *object; 270 271 // 272 273 LineEdit *search_box; 274 bool show_categories; 275 bool hide_script; 276 bool use_doc_hints; 277 bool capitalize_paths; 278 bool use_filter; 279 bool autoclear; 280 bool use_folding; 281 int changing; 282 bool update_all_pending; 283 bool read_only; 284 bool keying; 285 bool sub_inspector; 286 287 float refresh_countdown; 288 bool update_tree_pending; 289 StringName _prop_edited; 290 StringName property_selected; 291 int property_focusable; 292 int update_scroll_request; 293 294 Map<StringName, Map<StringName, String> > descr_cache; 295 Map<StringName, String> class_descr_cache; 296 Set<StringName> restart_request_props; 297 298 Map<ObjectID, int> scroll_cache; 299 300 String property_prefix; //used for sectioned inspector 301 String object_class; 302 303 void _edit_set(const String &p_name, const Variant &p_value, bool p_refresh_all, const String &p_changed_field); 304 305 void _property_changed(const String &p_path, const Variant &p_value, const String &p_name = "", bool changing = false); 306 void _property_changed_update_all(const String &p_path, const Variant &p_value, const String &p_name = "", bool p_changing = false); 307 void _multiple_properties_changed(Vector<String> p_paths, Array p_values); 308 void _property_keyed(const String &p_path, bool p_advance); 309 void _property_keyed_with_value(const String &p_path, const Variant &p_value, bool p_advance); 310 311 void _property_checked(const String &p_path, bool p_checked); 312 313 void _resource_selected(const String &p_path, RES p_resource); 314 void _property_selected(const String &p_path, int p_focusable); 315 void _object_id_selected(const String &p_path, ObjectID p_id); 316 317 void _node_removed(Node *p_node); 318 319 void _changed_callback(Object *p_changed, const char *p_prop); 320 void _edit_request_change(Object *p_object, const String &p_prop); 321 322 void _filter_changed(const String &p_text); 323 void _parse_added_editors(VBoxContainer *current_vbox, Ref<EditorInspectorPlugin> ped); 324 325 void _vscroll_changed(double); 326 327 void _feature_profile_changed(); 328 329 bool _is_property_disabled_by_feature_profile(const StringName &p_property); 330 331 protected: 332 static void _bind_methods(); 333 void _notification(int p_what); 334 335 public: 336 static void add_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin); 337 static void remove_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin); 338 static void cleanup_plugins(); 339 340 static EditorProperty *instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage); 341 342 void set_undo_redo(UndoRedo *p_undo_redo); 343 344 String get_selected_path() const; 345 346 void update_tree(); 347 void update_property(const String &p_prop); 348 349 void refresh(); 350 351 void edit(Object *p_object); 352 Object *get_edited_object(); 353 354 void set_keying(bool p_active); 355 void set_read_only(bool p_read_only); 356 357 bool is_capitalize_paths_enabled() const; 358 void set_enable_capitalize_paths(bool p_capitalize); 359 void set_autoclear(bool p_enable); 360 361 void set_show_categories(bool p_show); 362 void set_use_doc_hints(bool p_enable); 363 void set_hide_script(bool p_hide); 364 365 void set_use_filter(bool p_use); 366 void register_text_enter(Node *p_line_edit); 367 368 void set_use_folding(bool p_enable); 369 bool is_using_folding(); 370 371 void collapse_all_folding(); 372 void expand_all_folding(); 373 374 void set_scroll_offset(int p_offset); 375 int get_scroll_offset() const; 376 377 void set_property_prefix(const String &p_prefix); 378 String get_property_prefix() const; 379 380 void set_object_class(const String &p_class); 381 String get_object_class() const; 382 383 void set_sub_inspector(bool p_enable); 384 385 EditorInspector(); 386 }; 387 388 #endif // INSPECTOR_H 389