diff options
author | Twarit <wtwarit@gmail.com> | 2019-09-03 19:58:32 +0530 |
---|---|---|
committer | Twarit <wtwarit@gmail.com> | 2019-09-03 19:58:32 +0530 |
commit | 07e3be3debe968dcffd3b62202e3862edb9a7d27 (patch) | |
tree | 3c53077c3a943d5bcc335c829cdb949004a5892d | |
parent | 0985d5fa991d14f5393ced5783b69b967a69f4f5 (diff) |
Add version control editor plugin
Provides the editor with all the VCS GUI and extracts the data from the
upcoming VCS API to cater to the project with VCS interaction.
-rw-r--r-- | editor/plugins/version_control_editor_plugin.cpp | 565 | ||||
-rw-r--r-- | editor/plugins/version_control_editor_plugin.h | 116 |
2 files changed, 681 insertions, 0 deletions
diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp new file mode 100644 index 0000000000..d2873fb8f1 --- /dev/null +++ b/editor/plugins/version_control_editor_plugin.cpp @@ -0,0 +1,565 @@ +#include "version_control_editor_plugin.h" +#include "core/script_language.h" +#include "editor/editor_file_system.h" +#include "editor/editor_node.h" + +VersionControlEditorPlugin *VersionControlEditorPlugin::singleton = NULL; + +void VersionControlEditorPlugin::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_selected_a_vcs"), &VersionControlEditorPlugin::_selected_a_vcs); + ClassDB::bind_method(D_METHOD("_initialize_vcs"), &VersionControlEditorPlugin::_initialize_vcs); + ClassDB::bind_method(D_METHOD("_send_commit_msg"), &VersionControlEditorPlugin::_send_commit_msg); + ClassDB::bind_method(D_METHOD("_refresh_stage_area"), &VersionControlEditorPlugin::_refresh_stage_area); + ClassDB::bind_method(D_METHOD("_stage_all"), &VersionControlEditorPlugin::_stage_all); + ClassDB::bind_method(D_METHOD("_stage_selected"), &VersionControlEditorPlugin::_stage_selected); + ClassDB::bind_method(D_METHOD("_view_file_diff"), &VersionControlEditorPlugin::_view_file_diff); + ClassDB::bind_method(D_METHOD("_refresh_file_diff"), &VersionControlEditorPlugin::_refresh_file_diff); + ClassDB::bind_method(D_METHOD("popup_vcs_set_up_dialog"), &VersionControlEditorPlugin::popup_vcs_set_up_dialog); + + // Used to track the status of files in the staging area + BIND_ENUM_CONSTANT(CHANGE_TYPE_NEW); + BIND_ENUM_CONSTANT(CHANGE_TYPE_MODIFIED); + BIND_ENUM_CONSTANT(CHANGE_TYPE_RENAMED); + BIND_ENUM_CONSTANT(CHANGE_TYPE_DELETED); + BIND_ENUM_CONSTANT(CHANGE_TYPE_TYPECHANGE); +} + +void VersionControlEditorPlugin::_selected_a_vcs(int p_id) { + + List<StringName> available_addons = get_available_vcs_names(); + const StringName selected_vcs = set_up_choice->get_item_text(p_id); + + if (available_addons.find(selected_vcs) != NULL) { + + set_up_init_button->set_disabled(false); + } else { + + set_up_init_button->set_disabled(true); + } +} + +void VersionControlEditorPlugin::_populate_available_vcs_names() { + + static bool called = false; + + if (!called) { + + set_up_choice->add_item("Select an available VCS"); + + fetch_available_vcs_addon_names(); + List<StringName> available_addons = get_available_vcs_names(); + for (int i = 0; i < available_addons.size(); i++) { + + set_up_choice->add_item(available_addons[i]); + } + + called = true; + } +} + +VersionControlEditorPlugin *VersionControlEditorPlugin::get_singleton() { + + return singleton ? singleton : memnew(VersionControlEditorPlugin); +} + +void VersionControlEditorPlugin::popup_vcs_set_up_dialog(const Control *p_gui_base) { + + Size2 popup_size = Size2(400, 100); + Size2 window_size = p_gui_base->get_viewport_rect().size; + popup_size.x = MIN(window_size.x * 0.5, popup_size.x); + popup_size.y = MIN(window_size.y * 0.5, popup_size.y); + + if (get_is_vcs_intialized()) { + + set_up_init_button->set_disabled(true); + } + + _populate_available_vcs_names(); + + set_up_dialog->popup_centered_clamped(popup_size * EDSCALE); +} + +void VersionControlEditorPlugin::_initialize_vcs() { + + register_editor(); + + if (EditorVCSInterface::get_singleton()) { + + ERR_EXPLAIN(EditorVCSInterface::get_singleton()->get_vcs_name() + " is already active"); + return; + } + + int id = set_up_choice->get_selected_id(); + String selected_addon = set_up_choice->get_item_text(id); + + String path = ScriptServer::get_global_class_path(selected_addon); + Ref<Script> script = ResourceLoader::load(path); + if (!script.is_valid()) { + + ERR_EXPLAIN("VCS Addon path is invalid"); + } + + EditorVCSInterface *vcs_interface = memnew(EditorVCSInterface); + ScriptInstance *addon_script_instance = script->instance_create(vcs_interface); + if (!addon_script_instance) { + + ERR_FAIL_NULL(addon_script_instance); + return; + } + + // The addon is attached as a script to the VCS interface as a proxy end-point + vcs_interface->set_script_and_instance(script.get_ref_ptr(), addon_script_instance); + + EditorVCSInterface::set_singleton(vcs_interface); + EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "_refresh_stage_area"); + + String res_dir = OS::get_singleton()->get_resource_dir(); + if (!EditorVCSInterface::get_singleton()->initialize(res_dir)) { + + ERR_EXPLAIN("VCS was not initialized"); + } + + _refresh_stage_area(); +} + +void VersionControlEditorPlugin::_send_commit_msg() { + + String msg = commit_message->get_text(); + if (msg == "") { + + commit_status->set_text(TTR("No commit message was provided")); + return; + } + + if (EditorVCSInterface::get_singleton()) { + + if (staged_files_count == 0) { + + commit_status->set_text(TTR("No files added to stage")); + return; + } + + EditorVCSInterface::get_singleton()->commit(msg); + + commit_message->set_text(""); + version_control_dock_button->set_pressed(false); + } else { + + WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu"); + } + + _update_commit_status(); + _refresh_stage_area(); + _clear_file_diff(); +} + +void VersionControlEditorPlugin::_refresh_stage_area() { + + if (EditorVCSInterface::get_singleton()) { + + staged_files_count = 0; + clear_stage_area(); + + Dictionary modified_file_paths = EditorVCSInterface::get_singleton()->get_modified_files_data(); + String file_path; + for (int i = 0; i < modified_file_paths.size(); i++) { + + file_path = modified_file_paths.get_key_at_index(i); + TreeItem *found = stage_files->search_item_text(file_path, 0, true); + if (!found) { + + ChangeType change_index = (ChangeType)(int)modified_file_paths.get_value_at_index(i); + String change_text = file_path + " (" + change_type_to_strings[change_index] + ")"; + Color &change_color = change_type_to_color[change_index]; + TreeItem *new_item = stage_files->create_item(stage_files->get_root()); + new_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); + new_item->set_text(0, change_text); + new_item->set_metadata(0, file_path); + new_item->set_custom_color(0, change_color); + new_item->set_checked(0, true); + new_item->set_editable(0, true); + } else { + + if (found->get_metadata(0) == diff_file_name->get_text()) { + + _refresh_file_diff(); + } + } + commit_status->set_text("New changes detected"); + } + } else { + + WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu.") + } +} + +void VersionControlEditorPlugin::_stage_selected() { + + if (!EditorVCSInterface::get_singleton()) { + + WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu"); + return; + } + + staged_files_count = 0; + TreeItem *root = stage_files->get_root(); + if (root) { + + TreeItem *file_entry = root->get_children(); + while (file_entry) { + + if (file_entry->is_checked(0)) { + + EditorVCSInterface::get_singleton()->stage_file(file_entry->get_metadata(0)); + file_entry->set_icon_modulate(0, EditorNode::get_singleton()->get_gui_base()->get_color("success_color", "Editor")); + staged_files_count++; + } else { + + EditorVCSInterface::get_singleton()->unstage_file(file_entry->get_metadata(0)); + file_entry->set_icon_modulate(0, EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor")); + } + + file_entry = file_entry->get_next(); + } + } + + _update_stage_status(); +} + +void VersionControlEditorPlugin::_stage_all() { + + if (!EditorVCSInterface::get_singleton()) { + + WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu"); + return; + } + + staged_files_count = 0; + TreeItem *root = stage_files->get_root(); + if (root) { + + TreeItem *file_entry = root->get_children(); + while (file_entry) { + + EditorVCSInterface::get_singleton()->stage_file(file_entry->get_metadata(0)); + file_entry->set_icon_modulate(0, EditorNode::get_singleton()->get_gui_base()->get_color("success_color", "Editor")); + file_entry->set_checked(0, true); + staged_files_count++; + + file_entry = file_entry->get_next(); + } + } + + _update_stage_status(); +} + +void VersionControlEditorPlugin::_view_file_diff() { + + version_control_dock_button->set_pressed(true); + + String file_path = stage_files->get_selected()->get_metadata(0); + + _display_file_diff(file_path); +} + +void VersionControlEditorPlugin::_display_file_diff(String p_file_path) { + + Array diff_content = EditorVCSInterface::get_singleton()->get_file_diff(p_file_path); + + diff_file_name->set_text(p_file_path); + + diff->clear(); + diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_font("source", "EditorFonts")); + for (int i = 0; i < diff_content.size(); i++) { + + Dictionary line_result = diff_content[i]; + + if (line_result["status"] == "+") { + + diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_color("success_color", "Editor")); + } else if (line_result["status"] == "-") { + + diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor")); + } else { + + diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_color("font_color", "Label")); + } + + diff->add_text((String)line_result["content"]); + + diff->pop(); + } + diff->pop(); +} + +void VersionControlEditorPlugin::_refresh_file_diff() { + + String open_file = diff_file_name->get_text(); + if (open_file != "") { + + _display_file_diff(diff_file_name->get_text()); + } +} + +void VersionControlEditorPlugin::_clear_file_diff() { + + diff->clear(); + diff_file_name->set_text(""); + version_control_dock_button->set_pressed(false); +} + +void VersionControlEditorPlugin::_update_stage_status() { + + String status; + if (staged_files_count == 1) { + + status = "Stage contains 1 file"; + } else { + + status = "Stage contains " + String::num_int64(staged_files_count) + " files"; + } + commit_status->set_text(status); +} + +void VersionControlEditorPlugin::_update_commit_status() { + + String status; + if (staged_files_count == 1) { + + status = "Committed 1 file"; + } else { + + status = "Committed " + String::num_int64(staged_files_count) + " files "; + } + commit_status->set_text(status); + staged_files_count = 0; +} + +void VersionControlEditorPlugin::register_editor() { + + if (!EditorVCSInterface::get_singleton()) { + + EditorNode::get_singleton()->add_control_to_dock(EditorNode::DOCK_SLOT_RIGHT_UL, version_commit_dock); + TabContainer *dock_vbc = (TabContainer *)version_commit_dock->get_parent_control(); + dock_vbc->set_tab_title(version_commit_dock->get_index(), TTR("Commit")); + + ToolButton *vc = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Version Control"), version_control_dock); + set_version_control_tool_button(vc); + } +} + +void VersionControlEditorPlugin::fetch_available_vcs_addon_names() { + + ScriptServer::get_global_class_list(&available_addons); +} + +void VersionControlEditorPlugin::clear_stage_area() { + + stage_files->get_root()->clear_children(); +} + +void VersionControlEditorPlugin::shut_down() { + + if (EditorVCSInterface::get_singleton()) { + + EditorFileSystem::get_singleton()->disconnect("filesystem_changed", this, "_refresh_stage_area"); + EditorVCSInterface::get_singleton()->shut_down(); + memdelete(EditorVCSInterface::get_singleton()); + EditorVCSInterface::set_singleton(NULL); + + EditorNode::get_singleton()->remove_control_from_dock(version_commit_dock); + EditorNode::get_singleton()->remove_bottom_panel_item(version_control_dock); + } +} + +bool VersionControlEditorPlugin::get_is_vcs_intialized() const { + + return EditorVCSInterface::get_singleton() ? EditorVCSInterface::get_singleton()->get_is_vcs_intialized() : false; +} + +const String VersionControlEditorPlugin::get_vcs_name() const { + + return EditorVCSInterface::get_singleton() ? EditorVCSInterface::get_singleton()->get_vcs_name() : ""; +} + +VersionControlEditorPlugin::VersionControlEditorPlugin() { + + singleton = this; + staged_files_count = 0; + + version_control_actions = memnew(PopupMenu); + version_control_actions->set_v_size_flags(BoxContainer::SIZE_SHRINK_CENTER); + + set_up_dialog = memnew(AcceptDialog); + set_up_dialog->set_title(TTR("Set Up Version Control")); + set_up_dialog->set_custom_minimum_size(Size2(400, 100)); + version_control_actions->add_child(set_up_dialog); + + set_up_ok_button = set_up_dialog->get_ok(); + set_up_ok_button->set_disabled(false); + set_up_ok_button->set_text(TTR("Close")); + + set_up_vbc = memnew(VBoxContainer); + set_up_vbc->set_alignment(VBoxContainer::ALIGN_CENTER); + set_up_dialog->add_child(set_up_vbc); + + set_up_hbc = memnew(HBoxContainer); + set_up_hbc->set_h_size_flags(HBoxContainer::SIZE_EXPAND_FILL); + set_up_vbc->add_child(set_up_hbc); + + set_up_vcs_status = memnew(RichTextLabel); + set_up_vcs_status->set_text(TTR("VCS Addon is not initialized")); + set_up_vbc->add_child(set_up_vcs_status); + + set_up_vcs_label = memnew(Label); + set_up_vcs_label->set_text(TTR("Version Control System")); + set_up_hbc->add_child(set_up_vcs_label); + + set_up_choice = memnew(OptionButton); + set_up_choice->set_h_size_flags(HBoxContainer::SIZE_EXPAND_FILL); + set_up_choice->connect("item_selected", this, "_selected_a_vcs"); + set_up_hbc->add_child(set_up_choice); + + set_up_init_settings = NULL; + + set_up_init_button = memnew(Button); + set_up_init_button->set_disabled(true); + set_up_init_button->set_text(TTR("Initialize")); + set_up_init_button->connect("pressed", this, "_initialize_vcs"); + set_up_vbc->add_child(set_up_init_button); + + version_control_actions->set_v_size_flags(PopupMenu::SIZE_EXPAND_FILL); + version_control_actions->set_h_size_flags(PopupMenu::SIZE_EXPAND_FILL); + + version_commit_dock = memnew(VBoxContainer); + version_commit_dock->set_visible(false); + + commit_box_vbc = memnew(VBoxContainer); + commit_box_vbc->set_alignment(VBoxContainer::ALIGN_BEGIN); + commit_box_vbc->set_h_size_flags(VBoxContainer::SIZE_EXPAND_FILL); + commit_box_vbc->set_v_size_flags(VBoxContainer::SIZE_EXPAND_FILL); + version_commit_dock->add_child(commit_box_vbc); + + stage_tools = memnew(HSplitContainer); + stage_tools->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN_COLLAPSED); + commit_box_vbc->add_child(stage_tools); + + staging_area_label = memnew(Label); + staging_area_label->set_h_size_flags(Label::SIZE_EXPAND_FILL); + staging_area_label->set_text(TTR("Staging area")); + stage_tools->add_child(staging_area_label); + + refresh_button = memnew(Button); + refresh_button->set_tooltip(TTR("Detect new changes")); + refresh_button->set_text(TTR("Refresh")); + refresh_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("Reload", "EditorIcons")); + refresh_button->connect("pressed", this, "_refresh_stage_area"); + stage_tools->add_child(refresh_button); + + stage_files = memnew(Tree); + stage_files->set_h_size_flags(Tree::SIZE_EXPAND_FILL); + stage_files->set_v_size_flags(Tree::SIZE_EXPAND_FILL); + stage_files->set_columns(1); + stage_files->set_column_title(0, TTR("Changes")); + stage_files->set_column_titles_visible(true); + stage_files->set_allow_reselect(true); + stage_files->set_allow_rmb_select(true); + stage_files->set_select_mode(Tree::SelectMode::SELECT_MULTI); + stage_files->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true); + stage_files->connect("cell_selected", this, "_view_file_diff"); + stage_files->create_item(); + stage_files->set_hide_root(true); + commit_box_vbc->add_child(stage_files); + + change_type_to_strings[CHANGE_TYPE_NEW] = TTR("New"); + change_type_to_strings[CHANGE_TYPE_MODIFIED] = TTR("Modified"); + change_type_to_strings[CHANGE_TYPE_RENAMED] = TTR("Renamed"); + change_type_to_strings[CHANGE_TYPE_DELETED] = TTR("Deleted"); + change_type_to_strings[CHANGE_TYPE_TYPECHANGE] = TTR("Typechange"); + + change_type_to_color[CHANGE_TYPE_NEW] = EditorNode::get_singleton()->get_gui_base()->get_color("success_color", "Editor"); + change_type_to_color[CHANGE_TYPE_MODIFIED] = EditorNode::get_singleton()->get_gui_base()->get_color("warning_color", "Editor"); + change_type_to_color[CHANGE_TYPE_RENAMED] = EditorNode::get_singleton()->get_gui_base()->get_color("disabled_font_color", "Editor"); + change_type_to_color[CHANGE_TYPE_DELETED] = EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"); + change_type_to_color[CHANGE_TYPE_TYPECHANGE] = EditorNode::get_singleton()->get_gui_base()->get_color("font_color", "Editor"); + + stage_buttons = memnew(HSplitContainer); + stage_buttons->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN_COLLAPSED); + commit_box_vbc->add_child(stage_buttons); + + stage_selected_button = memnew(Button); + stage_selected_button->set_h_size_flags(Button::SIZE_EXPAND_FILL); + stage_selected_button->set_text(TTR("Stage Selected")); + stage_selected_button->connect("pressed", this, "_stage_selected"); + stage_buttons->add_child(stage_selected_button); + + stage_all_button = memnew(Button); + stage_all_button->set_text(TTR("Stage All")); + stage_all_button->connect("pressed", this, "_stage_all"); + stage_buttons->add_child(stage_all_button); + + commit_box_vbc->add_child(memnew(HSeparator)); + + commit_message = memnew(TextEdit); + commit_message->set_h_size_flags(Control::SIZE_EXPAND_FILL); + commit_message->set_h_grow_direction(Control::GrowDirection::GROW_DIRECTION_BEGIN); + commit_message->set_v_grow_direction(Control::GrowDirection::GROW_DIRECTION_END); + commit_message->set_custom_minimum_size(Size2(200, 100)); + commit_message->set_wrap_enabled(true); + commit_message->set_text(TTR("Add a commit message")); + commit_box_vbc->add_child(commit_message); + + commit_button = memnew(Button); + commit_button->set_text(TTR("Commit Changes")); + commit_button->connect("pressed", this, "_send_commit_msg"); + commit_box_vbc->add_child(commit_button); + + commit_status = memnew(Label); + commit_status->set_align(Label::ALIGN_CENTER); + commit_box_vbc->add_child(commit_status); + + version_control_dock = memnew(PanelContainer); + version_control_dock->set_v_size_flags(Control::SIZE_EXPAND_FILL); + version_control_dock->hide(); + + diff_vbc = memnew(VBoxContainer); + diff_vbc->set_h_size_flags(HBoxContainer::SIZE_FILL); + diff_vbc->set_v_size_flags(HBoxContainer::SIZE_FILL); + version_control_dock->add_child(diff_vbc); + + diff_hbc = memnew(HBoxContainer); + diff_hbc->set_h_size_flags(HBoxContainer::SIZE_FILL); + diff_vbc->add_child(diff_hbc); + + diff_heading = memnew(Label); + diff_heading->set_text(TTR("Status")); + diff_heading->set_tooltip(TTR("View file diffs before commiting them to the latest version")); + diff_hbc->add_child(diff_heading); + + diff_file_name = memnew(Label); + diff_file_name->set_text(TTR("No file diff is active")); + diff_file_name->set_h_size_flags(Label::SIZE_EXPAND_FILL); + diff_file_name->set_align(Label::ALIGN_RIGHT); + diff_hbc->add_child(diff_file_name); + + diff_refresh_button = memnew(Button); + diff_refresh_button->set_tooltip(TTR("Detect changes in file diff")); + diff_refresh_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("Reload", "EditorIcons")); + diff_refresh_button->connect("pressed", this, "_refresh_file_diff"); + diff_hbc->add_child(diff_refresh_button); + + diff = memnew(RichTextLabel); + diff->set_h_size_flags(TextEdit::SIZE_EXPAND_FILL); + diff->set_v_size_flags(TextEdit::SIZE_EXPAND_FILL); + diff->set_selection_enabled(true); + diff_vbc->add_child(diff); +} + +VersionControlEditorPlugin::~VersionControlEditorPlugin() { + + shut_down(); + memdelete(version_control_dock); + memdelete(version_commit_dock); + memdelete(version_control_actions); +} diff --git a/editor/plugins/version_control_editor_plugin.h b/editor/plugins/version_control_editor_plugin.h new file mode 100644 index 0000000000..dd7660d587 --- /dev/null +++ b/editor/plugins/version_control_editor_plugin.h @@ -0,0 +1,116 @@ +#ifndef VERSION_CONTROL_EDITOR_PLUGIN_H +#define VERSION_CONTROL_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_vcs_interface.h" +#include "scene/gui/container.h" +#include "scene/gui/rich_text_label.h" +#include "scene/gui/text_edit.h" +#include "scene/gui/tree.h" + +class VersionControlEditorPlugin : public EditorPlugin { + + GDCLASS(VersionControlEditorPlugin, EditorPlugin) + +public: + enum ChangeType { + + CHANGE_TYPE_NEW = 0, + CHANGE_TYPE_MODIFIED = 1, + CHANGE_TYPE_RENAMED = 2, + CHANGE_TYPE_DELETED = 3, + CHANGE_TYPE_TYPECHANGE = 4 + }; + +private: + static VersionControlEditorPlugin *singleton; + + int staged_files_count; + List<StringName> available_addons; + + PopupMenu *version_control_actions; + AcceptDialog *set_up_dialog; + VBoxContainer *set_up_vbc; + HBoxContainer *set_up_hbc; + Label *set_up_vcs_label; + OptionButton *set_up_choice; + PanelContainer *set_up_init_settings; + Button *set_up_init_button; + RichTextLabel *set_up_vcs_status; + Button *set_up_ok_button; + + HashMap<ChangeType, String> change_type_to_strings; + HashMap<ChangeType, Color> change_type_to_color; + + VBoxContainer *version_commit_dock; + VBoxContainer *commit_box_vbc; + HSplitContainer *stage_tools; + Tree *stage_files; + TreeItem *new_files; + TreeItem *modified_files; + TreeItem *renamed_files; + TreeItem *deleted_files; + TreeItem *typechange_files; + Label *staging_area_label; + HSplitContainer *stage_buttons; + Button *stage_all_button; + Button *stage_selected_button; + Button *refresh_button; + TextEdit *commit_message; + Button *commit_button; + Label *commit_status; + + PanelContainer *version_control_dock; + ToolButton *version_control_dock_button; + VBoxContainer *diff_vbc; + HBoxContainer *diff_hbc; + Button *diff_refresh_button; + Label *diff_file_name; + Label *diff_heading; + RichTextLabel *diff; + + void _populate_available_vcs_names(); + void _selected_a_vcs(int p_id); + void _initialize_vcs(); + void _send_commit_msg(); + void _refresh_stage_area(); + void _stage_selected(); + void _stage_all(); + void _view_file_diff(); + void _display_file_diff(String p_file_path); + void _refresh_file_diff(); + void _clear_file_diff(); + void _update_stage_status(); + void _update_commit_status(); + + friend class EditorVCSInterface; + +protected: + static void _bind_methods(); + +public: + static VersionControlEditorPlugin *get_singleton(); + + void popup_vcs_set_up_dialog(const Control *p_gui_base); + void set_version_control_tool_button(ToolButton *p_button) { version_control_dock_button = p_button; } + + PopupMenu *get_version_control_actions_panel() const { return version_control_actions; } + VBoxContainer *get_version_commit_dock() const { return version_commit_dock; } + PanelContainer *get_version_control_dock() const { return version_control_dock; } + + List<StringName> get_available_vcs_names() const { return available_addons; } + bool get_is_vcs_intialized() const; + const String get_vcs_name() const; + + void register_editor(); + void fetch_available_vcs_addon_names(); + void clear_stage_area(); + void shut_down(); + + VersionControlEditorPlugin(); + ~VersionControlEditorPlugin(); +}; + +VARIANT_ENUM_CAST(VersionControlEditorPlugin::ChangeType); + +#endif // !VERSION_CONTROL_EDITOR_PLUGIN_H |