1 /*************************************************************************/ 2 /* script_editor_plugin.h */ 3 /*************************************************************************/ 4 /* This file is part of: */ 5 /* GODOT ENGINE */ 6 /* https://godotengine.org */ 7 /*************************************************************************/ 8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ 9 /* Copyright (c) 2014-2019 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 #ifndef SCRIPT_EDITOR_PLUGIN_H 31 #define SCRIPT_EDITOR_PLUGIN_H 32 33 #include "editor/code_editor.h" 34 #include "editor/editor_help.h" 35 #include "editor/editor_plugin.h" 36 #include "editor/script_create_dialog.h" 37 #include "scene/gui/item_list.h" 38 #include "scene/gui/menu_button.h" 39 #include "scene/gui/split_container.h" 40 #include "scene/gui/tab_container.h" 41 #include "scene/gui/text_edit.h" 42 #include "scene/gui/tool_button.h" 43 #include "scene/gui/tree.h" 44 #include "scene/main/timer.h" 45 #include "script_language.h" 46 47 class ScriptEditorQuickOpen : public ConfirmationDialog { 48 49 OBJ_TYPE(ScriptEditorQuickOpen, ConfirmationDialog) 50 51 LineEdit *search_box; 52 Tree *search_options; 53 String function; 54 55 void _update_search(); 56 57 void _sbox_input(const InputEvent &p_ie); 58 Vector<String> functions; 59 60 void _confirmed(); 61 void _text_changed(const String &p_newtext); 62 63 protected: 64 void _notification(int p_what); 65 static void _bind_methods(); 66 67 public: 68 void popup(const Vector<String> &p_base, bool p_dontclear = false); 69 ScriptEditorQuickOpen(); 70 }; 71 72 class ScriptEditorDebugger; 73 74 class ScriptTextEditor : public CodeTextEditor { 75 76 OBJ_TYPE(ScriptTextEditor, CodeTextEditor); 77 78 Ref<Script> script; 79 80 Vector<String> functions; 81 82 protected: 83 virtual void _validate_script(); 84 virtual void _code_complete_script(const String &p_code, List<String> *r_options); 85 virtual void _load_theme_settings(); 86 void _notification(int p_what); 87 static void _bind_methods(); 88 89 public: 90 virtual void apply_code(); 91 Ref<Script> get_edited_script() const; 92 Vector<String> get_functions(); 93 void set_edited_script(const Ref<Script> &p_script); 94 void reload_text(); 95 String get_name(); 96 Ref<Texture> get_icon(); 97 bool is_unsaved(); 98 ScriptTextEditor(); 99 }; 100 101 class EditorScriptCodeCompletionCache; 102 103 class ScriptEditor : public VBoxContainer { 104 105 OBJ_TYPE(ScriptEditor, VBoxContainer); 106 107 EditorNode *editor; 108 enum { 109 FILE_NEW, 110 FILE_OPEN, 111 FILE_SAVE, 112 FILE_SAVE_AS, 113 FILE_SAVE_ALL, 114 FILE_IMPORT_THEME, 115 FILE_RELOAD_THEME, 116 FILE_SAVE_THEME, 117 FILE_SAVE_THEME_AS, 118 FILE_CLOSE, 119 FILE_CLOSE_OTHERS, 120 FILE_CLOSE_ALL, 121 FILE_COPY_SCRIPT_PATH, 122 CLOSE_DOCS, 123 EDIT_UNDO, 124 EDIT_REDO, 125 EDIT_CUT, 126 EDIT_COPY, 127 EDIT_PASTE, 128 EDIT_SELECT_ALL, 129 EDIT_UPPERCASE, 130 EDIT_LOWERCASE, 131 EDIT_COMPLETE, 132 EDIT_AUTO_INDENT, 133 EDIT_TRIM_TRAILING_WHITESAPCE, 134 EDIT_TOGGLE_COMMENT, 135 EDIT_MOVE_LINE_UP, 136 EDIT_MOVE_LINE_DOWN, 137 EDIT_INDENT_RIGHT, 138 EDIT_INDENT_LEFT, 139 EDIT_CLONE_DOWN, 140 FILE_TOOL_RELOAD, 141 FILE_TOOL_RELOAD_SOFT, 142 SEARCH_FIND, 143 SEARCH_FIND_NEXT, 144 SEARCH_FIND_PREV, 145 SEARCH_REPLACE, 146 SEARCH_LOCATE_FUNCTION, 147 SEARCH_GOTO_LINE, 148 SEARCH_HELP, 149 SEARCH_CLASSES, 150 SEARCH_WEBSITE, 151 DEBUG_TOGGLE_BREAKPOINT, 152 DEBUG_REMOVE_ALL_BREAKPOINTS, 153 DEBUG_GOTO_NEXT_BREAKPOINT, 154 DEBUG_GOTO_PREV_BREAKPOINT, 155 DEBUG_NEXT, 156 DEBUG_STEP, 157 DEBUG_BREAK, 158 DEBUG_CONTINUE, 159 DEBUG_SHOW, 160 DEBUG_SHOW_KEEP_OPEN, 161 HELP_CONTEXTUAL, 162 WINDOW_MOVE_LEFT, 163 WINDOW_MOVE_RIGHT, 164 WINDOW_NEXT, 165 WINDOW_PREV, 166 WINDOW_SELECT_BASE = 100 167 }; 168 169 enum ScriptSortBy { 170 SORT_BY_NAME, 171 SORT_BY_PATH, 172 }; 173 174 enum ScriptListName { 175 DISPLAY_NAME, 176 DISPLAY_DIR_AND_NAME, 177 DISPLAY_FULL_PATH, 178 }; 179 180 HBoxContainer *menu_hb; 181 MenuButton *file_menu; 182 MenuButton *edit_menu; 183 MenuButton *search_menu; 184 MenuButton *script_search_menu; 185 MenuButton *debug_menu; 186 MenuButton *help_menu; 187 Timer *autosave_timer; 188 uint64_t idle; 189 190 Button *help_search; 191 Button *site_search; 192 Button *class_search; 193 EditorHelpSearch *help_search_dialog; 194 195 ItemList *script_list; 196 PopupMenu *script_list_menu; 197 HSplitContainer *script_split; 198 ItemList *members_overview; 199 bool members_overview_enabled; 200 VSplitContainer *list_split; 201 TabContainer *tab_container; 202 EditorFileDialog *file_dialog; 203 GotoLineDialog *goto_line_dialog; 204 ConfirmationDialog *erase_tab_confirm; 205 ScriptCreateDialog *script_create_dialog; 206 ScriptEditorDebugger *debugger; 207 ToolButton *scripts_visible; 208 209 String current_theme; 210 211 TextureFrame *script_icon; 212 Label *script_name_label; 213 214 ToolButton *script_back; 215 ToolButton *script_forward; 216 217 struct ScriptHistory { 218 219 Control *control; 220 int scroll_pos; 221 int cursor_column; 222 int cursor_row; 223 }; 224 225 Vector<ScriptHistory> history; 226 int history_pos; 227 228 EditorHelpIndex *help_index; 229 230 void _tab_changed(int p_which); 231 void _menu_option(int p_optin); 232 233 Tree *disk_changed_list; 234 ConfirmationDialog *disk_changed; 235 236 bool restoring_layout; 237 238 String _get_debug_tooltip(const String &p_text, Node *_ste); 239 240 void _resave_scripts(const String &p_str); 241 void _reload_scripts(); 242 243 bool _test_script_times_on_disk(Ref<Script> p_for_script = Ref<Script>()); 244 245 void _close_tab(int p_idx); 246 247 void _close_current_tab(); 248 void _close_other_tabs(int idx); 249 void _close_all_tab(int except); 250 void _close_docs_tab(); 251 void _copy_script_path(); 252 253 bool grab_focus_block; 254 255 bool pending_auto_reload; 256 bool auto_reload_running_scripts; 257 void _live_auto_reload_running_scripts(); 258 259 ScriptEditorQuickOpen *quick_open; 260 261 EditorScriptCodeCompletionCache *completion_cache; 262 263 void _editor_play(); 264 void _editor_pause(); 265 void _editor_stop(); 266 267 int edit_pass; 268 269 void _add_callback(Object *p_obj, const String &p_function, const StringArray &p_args); 270 void _res_saved_callback(const Ref<Resource> &p_res); 271 272 bool trim_trailing_whitespace_on_save; 273 274 void _trim_trailing_whitespace(TextEdit *tx); 275 276 void _goto_script_line2(int p_line); 277 void _goto_script_line(REF p_script, int p_line); 278 void _breaked(bool p_breaked, bool p_can_debug); 279 void _show_debugger(bool p_show); 280 void _update_window_menu(); 281 void _script_created(Ref<Script> p_script); 282 283 void _save_layout(); 284 void _editor_settings_changed(); 285 void _autosave_scripts(); 286 287 void _update_members_overview_visibility(); 288 void _update_members_overview(); 289 void _members_overview_selected(int p_idx); 290 291 void _update_script_names(); 292 293 void _script_selected(int p_idx); 294 295 void _script_rmb_selected(int p_idx, const Vector2 &p_pos); 296 297 void _find_scripts(Node *p_base, Node *p_current, Set<Ref<Script> > &used); 298 299 void _tree_changed(); 300 301 void _script_split_dragged(float); 302 303 void _unhandled_input(const InputEvent &p_event); 304 305 void _history_forward(); 306 void _history_back(); 307 308 bool waiting_update_names; 309 310 void _help_class_open(const String &p_class); 311 void _help_class_goto(const String &p_desc); 312 void _update_history_arrows(); 313 void _go_to_tab(int p_idx); 314 void _update_history_pos(int p_new_pos); 315 void _update_script_colors(); 316 void _update_modified_scripts_for_external_editor(Ref<Script> p_for_script = Ref<Script>()); 317 318 int file_dialog_option; 319 void _file_dialog_action(String p_file); 320 321 static ScriptEditor *script_editor; 322 323 protected: 324 void _notification(int p_what); 325 static void _bind_methods(); 326 327 public: get_singleton()328 static ScriptEditor *get_singleton() { return script_editor; } 329 330 void ensure_focus_current(); 331 void apply_scripts() const; 332 333 void ensure_select_current(); 334 void edit(const Ref<Script> &p_script); 335 336 Dictionary get_state() const; 337 void set_state(const Dictionary &p_state); 338 void clear(); 339 340 void get_breakpoints(List<String> *p_breakpoints); 341 342 void swap_lines(TextEdit *tx, int line1, int line2); 343 void _breakpoint_toggled(const int p_row); 344 345 void save_all_scripts(); 346 347 void set_window_layout(Ref<ConfigFile> p_layout); 348 void get_window_layout(Ref<ConfigFile> p_layout); 349 350 void set_scene_root_script(Ref<Script> p_script); 351 352 bool script_go_to_method(Ref<Script> p_script, const String &p_method); 353 354 virtual void edited_scene_changed(); 355 356 void close_builtin_scripts_from_scene(const String &p_scene); 357 goto_help(const String & p_desc)358 void goto_help(const String &p_desc) { _help_class_goto(p_desc); } 359 get_debugger()360 ScriptEditorDebugger *get_debugger() { return debugger; } 361 void set_live_auto_reload_running_scripts(bool p_enabled); 362 363 ScriptEditor(EditorNode *p_editor); 364 ~ScriptEditor(); 365 }; 366 367 class ScriptEditorPlugin : public EditorPlugin { 368 369 OBJ_TYPE(ScriptEditorPlugin, EditorPlugin); 370 371 ScriptEditor *script_editor; 372 EditorNode *editor; 373 374 public: get_name()375 virtual String get_name() const { return "Script"; } has_main_screen()376 bool has_main_screen() const { return true; } 377 virtual void edit(Object *p_node); 378 virtual bool handles(Object *p_node) const; 379 virtual void make_visible(bool p_visible); 380 virtual void selected_notify(); 381 382 Dictionary get_state() const; 383 virtual void set_state(const Dictionary &p_state); 384 virtual void clear(); 385 386 virtual void save_external_data(); 387 virtual void apply_changes(); 388 389 virtual void restore_global_state(); 390 virtual void save_global_state(); 391 392 virtual void set_window_layout(Ref<ConfigFile> p_layout); 393 virtual void get_window_layout(Ref<ConfigFile> p_layout); 394 395 virtual void get_breakpoints(List<String> *p_breakpoints); 396 397 virtual void edited_scene_changed(); 398 399 ScriptEditorPlugin(EditorNode *p_node); 400 ~ScriptEditorPlugin(); 401 }; 402 403 #endif // SCRIPT_EDITOR_PLUGIN_H 404