You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-17 14:11:06 +00:00
Optimize scanning routines in the project manager
This commit is contained in:
@@ -1249,6 +1249,7 @@ struct ProjectListComparator {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char *ProjectList::SIGNAL_LIST_CHANGED = "list_changed";
|
||||||
const char *ProjectList::SIGNAL_SELECTION_CHANGED = "selection_changed";
|
const char *ProjectList::SIGNAL_SELECTION_CHANGED = "selection_changed";
|
||||||
const char *ProjectList::SIGNAL_PROJECT_ASK_OPEN = "project_ask_open";
|
const char *ProjectList::SIGNAL_PROJECT_ASK_OPEN = "project_ask_open";
|
||||||
|
|
||||||
@@ -1356,7 +1357,7 @@ ProjectList::Item ProjectList::load_project_data(const String &p_path, bool p_fa
|
|||||||
return Item(project_name, description, tags, p_path, icon, main_scene, unsupported_features, last_edited, p_favorite, grayed, missing, config_version);
|
return Item(project_name, description, tags, p_path, icon, main_scene, unsupported_features, last_edited, p_favorite, grayed, missing, config_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectList::migrate_config() {
|
void ProjectList::_migrate_config() {
|
||||||
// Proposal #1637 moved the project list from editor settings to a separate config file
|
// Proposal #1637 moved the project list from editor settings to a separate config file
|
||||||
// If the new config file doesn't exist, populate it from EditorSettings
|
// If the new config file doesn't exist, populate it from EditorSettings
|
||||||
if (FileAccess::exists(_config_path)) {
|
if (FileAccess::exists(_config_path)) {
|
||||||
@@ -1388,9 +1389,10 @@ void ProjectList::migrate_config() {
|
|||||||
save_config();
|
save_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectList::load_projects() {
|
void ProjectList::update_project_list() {
|
||||||
// This is a full, hard reload of the list. Don't call this unless really required, it's expensive.
|
// This is a full, hard reload of the list. Don't call this unless really required, it's expensive.
|
||||||
// If you have 150 projects, it may read through 150 files on your disk at once + load 150 icons.
|
// If you have 150 projects, it may read through 150 files on your disk at once + load 150 icons.
|
||||||
|
// FIXME: Does it really have to be a full, hard reload? Runtime updates should be made much cheaper.
|
||||||
|
|
||||||
// Clear whole list
|
// Clear whole list
|
||||||
for (int i = 0; i < _projects.size(); ++i) {
|
for (int i = 0; i < _projects.size(); ++i) {
|
||||||
@@ -1421,6 +1423,7 @@ void ProjectList::load_projects() {
|
|||||||
update_dock_menu();
|
update_dock_menu();
|
||||||
|
|
||||||
set_v_scroll(0);
|
set_v_scroll(0);
|
||||||
|
emit_signal(SNAME(SIGNAL_LIST_CHANGED));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectList::update_dock_menu() {
|
void ProjectList::update_dock_menu() {
|
||||||
@@ -1678,6 +1681,48 @@ void ProjectList::erase_missing_projects() {
|
|||||||
save_config();
|
save_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectList::_scan_folder_recursive(const String &p_path, List<String> *r_projects) {
|
||||||
|
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||||
|
Error error = da->change_dir(p_path);
|
||||||
|
ERR_FAIL_COND_MSG(error != OK, vformat("Failed to open the path \"%s\" for scanning (code %d).", p_path, error));
|
||||||
|
|
||||||
|
da->list_dir_begin();
|
||||||
|
String n = da->get_next();
|
||||||
|
while (!n.is_empty()) {
|
||||||
|
if (da->current_is_dir() && n[0] != '.') {
|
||||||
|
_scan_folder_recursive(da->get_current_dir().path_join(n), r_projects);
|
||||||
|
} else if (n == "project.godot") {
|
||||||
|
r_projects->push_back(da->get_current_dir());
|
||||||
|
}
|
||||||
|
n = da->get_next();
|
||||||
|
}
|
||||||
|
da->list_dir_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectList::find_projects(const String &p_path) {
|
||||||
|
PackedStringArray paths = { p_path };
|
||||||
|
find_projects_multiple(paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectList::find_projects_multiple(const PackedStringArray &p_paths) {
|
||||||
|
List<String> projects;
|
||||||
|
|
||||||
|
for (int i = 0; i < p_paths.size(); i++) {
|
||||||
|
const String &base_path = p_paths.get(i);
|
||||||
|
print_verbose(vformat("Scanning for projects in \"%s\".", base_path));
|
||||||
|
|
||||||
|
_scan_folder_recursive(base_path, &projects);
|
||||||
|
print_verbose(vformat("Found %d project(s).", projects.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const String &E : projects) {
|
||||||
|
add_project(E, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
save_config();
|
||||||
|
update_project_list();
|
||||||
|
}
|
||||||
|
|
||||||
int ProjectList::refresh_project(const String &dir_path) {
|
int ProjectList::refresh_project(const String &dir_path) {
|
||||||
// Reloads information about a specific project.
|
// Reloads information about a specific project.
|
||||||
// If it wasn't loaded and should be in the list, it is added (i.e new project).
|
// If it wasn't loaded and should be in the list, it is added (i.e new project).
|
||||||
@@ -1916,6 +1961,7 @@ void ProjectList::_show_project(const String &p_path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ProjectList::_bind_methods() {
|
void ProjectList::_bind_methods() {
|
||||||
|
ADD_SIGNAL(MethodInfo(SIGNAL_LIST_CHANGED));
|
||||||
ADD_SIGNAL(MethodInfo(SIGNAL_SELECTION_CHANGED));
|
ADD_SIGNAL(MethodInfo(SIGNAL_SELECTION_CHANGED));
|
||||||
ADD_SIGNAL(MethodInfo(SIGNAL_PROJECT_ASK_OPEN));
|
ADD_SIGNAL(MethodInfo(SIGNAL_PROJECT_ASK_OPEN));
|
||||||
}
|
}
|
||||||
@@ -1926,6 +1972,7 @@ ProjectList::ProjectList() {
|
|||||||
add_child(_scroll_children);
|
add_child(_scroll_children);
|
||||||
|
|
||||||
_config_path = EditorPaths::get_singleton()->get_data_dir().path_join("projects.cfg");
|
_config_path = EditorPaths::get_singleton()->get_data_dir().path_join("projects.cfg");
|
||||||
|
_migrate_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Project Manager.
|
/// Project Manager.
|
||||||
@@ -2183,15 +2230,6 @@ void ProjectManager::shortcut_input(const Ref<InputEvent> &p_ev) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectManager::_load_recent_projects() {
|
|
||||||
_project_list->set_search_term(search_box->get_text().strip_edges());
|
|
||||||
_project_list->load_projects();
|
|
||||||
|
|
||||||
_update_project_buttons();
|
|
||||||
|
|
||||||
tabs->set_current_tab(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProjectManager::_on_projects_updated() {
|
void ProjectManager::_on_projects_updated() {
|
||||||
Vector<ProjectList::Item> selected_projects = _project_list->get_selected_projects();
|
Vector<ProjectList::Item> selected_projects = _project_list->get_selected_projects();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@@ -2429,30 +2467,6 @@ void ProjectManager::_run_project() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectManager::_scan_dir(const String &path) {
|
|
||||||
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
|
||||||
Error error = da->change_dir(path);
|
|
||||||
ERR_FAIL_COND_MSG(error != OK, "Could not scan directory at: " + path);
|
|
||||||
da->list_dir_begin();
|
|
||||||
String n = da->get_next();
|
|
||||||
while (!n.is_empty()) {
|
|
||||||
if (da->current_is_dir() && !n.begins_with(".")) {
|
|
||||||
_scan_dir(da->get_current_dir().path_join(n));
|
|
||||||
} else if (n == "project.godot") {
|
|
||||||
_project_list->add_project(da->get_current_dir(), false);
|
|
||||||
}
|
|
||||||
n = da->get_next();
|
|
||||||
}
|
|
||||||
da->list_dir_end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProjectManager::_scan_begin(const String &p_base) {
|
|
||||||
print_line("Scanning projects at: " + p_base);
|
|
||||||
_scan_dir(p_base);
|
|
||||||
_project_list->save_config();
|
|
||||||
_load_recent_projects();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProjectManager::_scan_projects() {
|
void ProjectManager::_scan_projects() {
|
||||||
scan_dir->popup_file_dialog();
|
scan_dir->popup_file_dialog();
|
||||||
}
|
}
|
||||||
@@ -2652,54 +2666,26 @@ void ProjectManager::_install_project(const String &p_zip_path, const String &p_
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ProjectManager::_files_dropped(PackedStringArray p_files) {
|
void ProjectManager::_files_dropped(PackedStringArray p_files) {
|
||||||
|
// TODO: Support installing multiple ZIPs at the same time?
|
||||||
if (p_files.size() == 1 && p_files[0].ends_with(".zip")) {
|
if (p_files.size() == 1 && p_files[0].ends_with(".zip")) {
|
||||||
const String file = p_files[0].get_file();
|
const String &file = p_files[0];
|
||||||
_install_project(p_files[0], file.substr(0, file.length() - 4).capitalize());
|
_install_project(file, file.get_file().get_basename().capitalize());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HashSet<String> folders_set;
|
HashSet<String> folders_set;
|
||||||
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||||
for (int i = 0; i < p_files.size(); i++) {
|
for (int i = 0; i < p_files.size(); i++) {
|
||||||
String file = p_files[i];
|
const String &file = p_files[i];
|
||||||
folders_set.insert(da->dir_exists(file) ? file : file.get_base_dir());
|
folders_set.insert(da->dir_exists(file) ? file : file.get_base_dir());
|
||||||
}
|
}
|
||||||
if (folders_set.size() > 0) {
|
ERR_FAIL_COND(folders_set.size() == 0); // This can't really happen, we consume every dropped file path above.
|
||||||
PackedStringArray folders;
|
|
||||||
for (const String &E : folders_set) {
|
|
||||||
folders.push_back(E);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool confirm = true;
|
PackedStringArray folders;
|
||||||
if (folders.size() == 1) {
|
for (const String &E : folders_set) {
|
||||||
Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
folders.push_back(E);
|
||||||
if (dir->change_dir(folders[0]) == OK) {
|
|
||||||
dir->list_dir_begin();
|
|
||||||
String file = dir->get_next();
|
|
||||||
while (confirm && !file.is_empty()) {
|
|
||||||
if (!dir->current_is_dir() && file.ends_with("project.godot")) {
|
|
||||||
confirm = false;
|
|
||||||
}
|
|
||||||
file = dir->get_next();
|
|
||||||
}
|
|
||||||
dir->list_dir_end();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (confirm) {
|
|
||||||
multi_scan_ask->get_ok_button()->disconnect("pressed", callable_mp(this, &ProjectManager::_scan_multiple_folders));
|
|
||||||
multi_scan_ask->get_ok_button()->connect("pressed", callable_mp(this, &ProjectManager::_scan_multiple_folders).bind(folders));
|
|
||||||
multi_scan_ask->set_text(
|
|
||||||
vformat(TTR("Are you sure to scan %s folders for existing Godot projects?\nThis could take a while."), folders.size()));
|
|
||||||
multi_scan_ask->popup_centered();
|
|
||||||
} else {
|
|
||||||
_scan_multiple_folders(folders);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProjectManager::_scan_multiple_folders(PackedStringArray p_files) {
|
|
||||||
for (int i = 0; i < p_files.size(); i++) {
|
|
||||||
_scan_begin(p_files.get(i));
|
|
||||||
}
|
}
|
||||||
|
_project_list->find_projects_multiple(folders);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectManager::_on_order_option_changed(int p_idx) {
|
void ProjectManager::_on_order_option_changed(int p_idx) {
|
||||||
@@ -2740,11 +2726,6 @@ void ProjectManager::_on_search_term_submitted(const String &p_text) {
|
|||||||
_open_selected_projects_ask();
|
_open_selected_projects_ask();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectManager::_bind_methods() {
|
|
||||||
ClassDB::bind_method("_update_project_buttons", &ProjectManager::_update_project_buttons);
|
|
||||||
ClassDB::bind_method("_version_button_pressed", &ProjectManager::_version_button_pressed);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProjectManager::_open_asset_library() {
|
void ProjectManager::_open_asset_library() {
|
||||||
asset_library->disable_community_support();
|
asset_library->disable_community_support();
|
||||||
tabs->set_current_tab(1);
|
tabs->set_current_tab(1);
|
||||||
@@ -2870,8 +2851,8 @@ ProjectManager::ProjectManager() {
|
|||||||
vb->add_child(center_box);
|
vb->add_child(center_box);
|
||||||
|
|
||||||
tabs = memnew(TabContainer);
|
tabs = memnew(TabContainer);
|
||||||
center_box->add_child(tabs);
|
|
||||||
tabs->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
|
tabs->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
|
||||||
|
center_box->add_child(tabs);
|
||||||
tabs->connect("tab_changed", callable_mp(this, &ProjectManager::_on_tab_changed));
|
tabs->connect("tab_changed", callable_mp(this, &ProjectManager::_on_tab_changed));
|
||||||
|
|
||||||
local_projects_vb = memnew(VBoxContainer);
|
local_projects_vb = memnew(VBoxContainer);
|
||||||
@@ -2950,10 +2931,11 @@ ProjectManager::ProjectManager() {
|
|||||||
search_tree_hb->add_child(search_panel);
|
search_tree_hb->add_child(search_panel);
|
||||||
|
|
||||||
_project_list = memnew(ProjectList);
|
_project_list = memnew(ProjectList);
|
||||||
_project_list->connect(ProjectList::SIGNAL_SELECTION_CHANGED, callable_mp(this, &ProjectManager::_update_project_buttons));
|
|
||||||
_project_list->connect(ProjectList::SIGNAL_PROJECT_ASK_OPEN, callable_mp(this, &ProjectManager::_open_selected_projects_ask));
|
|
||||||
_project_list->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
|
_project_list->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
|
||||||
search_panel->add_child(_project_list);
|
search_panel->add_child(_project_list);
|
||||||
|
_project_list->connect(ProjectList::SIGNAL_LIST_CHANGED, callable_mp(this, &ProjectManager::_update_project_buttons));
|
||||||
|
_project_list->connect(ProjectList::SIGNAL_SELECTION_CHANGED, callable_mp(this, &ProjectManager::_update_project_buttons));
|
||||||
|
_project_list->connect(ProjectList::SIGNAL_PROJECT_ASK_OPEN, callable_mp(this, &ProjectManager::_open_selected_projects_ask));
|
||||||
|
|
||||||
// The side bar with the edit, run, rename, etc. buttons.
|
// The side bar with the edit, run, rename, etc. buttons.
|
||||||
VBoxContainer *tree_vb = memnew(VBoxContainer);
|
VBoxContainer *tree_vb = memnew(VBoxContainer);
|
||||||
@@ -3099,7 +3081,7 @@ ProjectManager::ProjectManager() {
|
|||||||
scan_dir->set_title(TTR("Select a Folder to Scan")); // must be after mode or it's overridden
|
scan_dir->set_title(TTR("Select a Folder to Scan")); // must be after mode or it's overridden
|
||||||
scan_dir->set_current_dir(EDITOR_GET("filesystem/directories/default_project_path"));
|
scan_dir->set_current_dir(EDITOR_GET("filesystem/directories/default_project_path"));
|
||||||
add_child(scan_dir);
|
add_child(scan_dir);
|
||||||
scan_dir->connect("dir_selected", callable_mp(this, &ProjectManager::_scan_begin));
|
scan_dir->connect("dir_selected", callable_mp(_project_list, &ProjectList::find_projects));
|
||||||
|
|
||||||
erase_missing_ask = memnew(ConfirmationDialog);
|
erase_missing_ask = memnew(ConfirmationDialog);
|
||||||
erase_missing_ask->set_ok_button_text(TTR("Remove All"));
|
erase_missing_ask->set_ok_button_text(TTR("Remove All"));
|
||||||
@@ -3133,10 +3115,6 @@ ProjectManager::ProjectManager() {
|
|||||||
multi_run_ask->get_ok_button()->connect("pressed", callable_mp(this, &ProjectManager::_run_project_confirm));
|
multi_run_ask->get_ok_button()->connect("pressed", callable_mp(this, &ProjectManager::_run_project_confirm));
|
||||||
add_child(multi_run_ask);
|
add_child(multi_run_ask);
|
||||||
|
|
||||||
multi_scan_ask = memnew(ConfirmationDialog);
|
|
||||||
multi_scan_ask->set_ok_button_text(TTR("Scan"));
|
|
||||||
add_child(multi_scan_ask);
|
|
||||||
|
|
||||||
ask_update_settings = memnew(ConfirmationDialog);
|
ask_update_settings = memnew(ConfirmationDialog);
|
||||||
ask_update_settings->set_autowrap(true);
|
ask_update_settings->set_autowrap(true);
|
||||||
ask_update_settings->get_ok_button()->connect("pressed", callable_mp(this, &ProjectManager::_confirm_update_settings));
|
ask_update_settings->get_ok_button()->connect("pressed", callable_mp(this, &ProjectManager::_confirm_update_settings));
|
||||||
@@ -3245,29 +3223,36 @@ ProjectManager::ProjectManager() {
|
|||||||
create_tag_btn->connect("pressed", callable_mp((Window *)create_tag_dialog, &Window::popup_centered).bind(Vector2i(500, 0) * EDSCALE));
|
create_tag_btn->connect("pressed", callable_mp((Window *)create_tag_dialog, &Window::popup_centered).bind(Vector2i(500, 0) * EDSCALE));
|
||||||
}
|
}
|
||||||
|
|
||||||
_project_list->migrate_config();
|
// Initialize project list.
|
||||||
_load_recent_projects();
|
{
|
||||||
|
Ref<DirAccess> dir_access = DirAccess::create(DirAccess::AccessType::ACCESS_FILESYSTEM);
|
||||||
|
|
||||||
Ref<DirAccess> dir_access = DirAccess::create(DirAccess::AccessType::ACCESS_FILESYSTEM);
|
String default_project_path = EDITOR_GET("filesystem/directories/default_project_path");
|
||||||
|
if (!default_project_path.is_empty() && !dir_access->dir_exists(default_project_path)) {
|
||||||
String default_project_path = EDITOR_GET("filesystem/directories/default_project_path");
|
Error error = dir_access->make_dir_recursive(default_project_path);
|
||||||
if (!dir_access->dir_exists(default_project_path)) {
|
|
||||||
Error error = dir_access->make_dir_recursive(default_project_path);
|
|
||||||
if (error != OK) {
|
|
||||||
ERR_PRINT("Could not create default project directory at: " + default_project_path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String autoscan_path = EDITOR_GET("filesystem/directories/autoscan_project_path");
|
|
||||||
if (!autoscan_path.is_empty()) {
|
|
||||||
if (dir_access->dir_exists(autoscan_path)) {
|
|
||||||
_scan_begin(autoscan_path);
|
|
||||||
} else {
|
|
||||||
Error error = dir_access->make_dir_recursive(autoscan_path);
|
|
||||||
if (error != OK) {
|
if (error != OK) {
|
||||||
ERR_PRINT("Could not create project autoscan directory at: " + autoscan_path);
|
ERR_PRINT("Could not create default project directory at: " + default_project_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool scanned_for_projects = false; // Scanning will update the list automatically.
|
||||||
|
|
||||||
|
String autoscan_path = EDITOR_GET("filesystem/directories/autoscan_project_path");
|
||||||
|
if (!autoscan_path.is_empty()) {
|
||||||
|
if (dir_access->dir_exists(autoscan_path)) {
|
||||||
|
_project_list->find_projects(autoscan_path);
|
||||||
|
scanned_for_projects = true;
|
||||||
|
} else {
|
||||||
|
Error error = dir_access->make_dir_recursive(autoscan_path);
|
||||||
|
if (error != OK) {
|
||||||
|
ERR_PRINT("Could not create project autoscan directory at: " + autoscan_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!scanned_for_projects) {
|
||||||
|
_project_list->update_project_list();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneTree::get_singleton()->get_root()->connect("files_dropped", callable_mp(this, &ProjectManager::_files_dropped));
|
SceneTree::get_singleton()->get_root()->connect("files_dropped", callable_mp(this, &ProjectManager::_files_dropped));
|
||||||
|
|||||||
@@ -267,6 +267,9 @@ private:
|
|||||||
void _favorite_pressed(Node *p_hb);
|
void _favorite_pressed(Node *p_hb);
|
||||||
void _show_project(const String &p_path);
|
void _show_project(const String &p_path);
|
||||||
|
|
||||||
|
void _migrate_config();
|
||||||
|
void _scan_folder_recursive(const String &p_path, List<String> *r_projects);
|
||||||
|
|
||||||
void _clear_project_selection();
|
void _clear_project_selection();
|
||||||
void _toggle_project(int p_index);
|
void _toggle_project(int p_index);
|
||||||
void _select_project_nocheck(int p_index);
|
void _select_project_nocheck(int p_index);
|
||||||
@@ -288,12 +291,15 @@ protected:
|
|||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const char *SIGNAL_LIST_CHANGED;
|
||||||
static const char *SIGNAL_SELECTION_CHANGED;
|
static const char *SIGNAL_SELECTION_CHANGED;
|
||||||
static const char *SIGNAL_PROJECT_ASK_OPEN;
|
static const char *SIGNAL_PROJECT_ASK_OPEN;
|
||||||
|
|
||||||
void load_projects();
|
void update_project_list();
|
||||||
int get_project_count() const;
|
int get_project_count() const;
|
||||||
|
|
||||||
|
void find_projects(const String &p_path);
|
||||||
|
void find_projects_multiple(const PackedStringArray &p_paths);
|
||||||
void sort_projects();
|
void sort_projects();
|
||||||
|
|
||||||
void add_project(const String &dir_path, bool favorite);
|
void add_project(const String &dir_path, bool favorite);
|
||||||
@@ -316,7 +322,6 @@ public:
|
|||||||
void set_order_option(int p_option);
|
void set_order_option(int p_option);
|
||||||
|
|
||||||
void update_dock_menu();
|
void update_dock_menu();
|
||||||
void migrate_config();
|
|
||||||
void save_config();
|
void save_config();
|
||||||
|
|
||||||
ProjectList();
|
ProjectList();
|
||||||
@@ -367,7 +372,6 @@ class ProjectManager : public Control {
|
|||||||
ConfirmationDialog *erase_missing_ask = nullptr;
|
ConfirmationDialog *erase_missing_ask = nullptr;
|
||||||
ConfirmationDialog *multi_open_ask = nullptr;
|
ConfirmationDialog *multi_open_ask = nullptr;
|
||||||
ConfirmationDialog *multi_run_ask = nullptr;
|
ConfirmationDialog *multi_run_ask = nullptr;
|
||||||
ConfirmationDialog *multi_scan_ask = nullptr;
|
|
||||||
ConfirmationDialog *ask_full_convert_dialog = nullptr;
|
ConfirmationDialog *ask_full_convert_dialog = nullptr;
|
||||||
ConfirmationDialog *ask_update_settings = nullptr;
|
ConfirmationDialog *ask_update_settings = nullptr;
|
||||||
ConfirmationDialog *open_templates = nullptr;
|
ConfirmationDialog *open_templates = nullptr;
|
||||||
@@ -423,12 +427,8 @@ class ProjectManager : public Control {
|
|||||||
void _set_new_tag_name(const String p_name);
|
void _set_new_tag_name(const String p_name);
|
||||||
void _create_new_tag();
|
void _create_new_tag();
|
||||||
|
|
||||||
void _load_recent_projects();
|
|
||||||
void _on_project_created(const String &dir);
|
void _on_project_created(const String &dir);
|
||||||
void _on_projects_updated();
|
void _on_projects_updated();
|
||||||
void _scan_multiple_folders(PackedStringArray p_files);
|
|
||||||
void _scan_begin(const String &p_base);
|
|
||||||
void _scan_dir(const String &path);
|
|
||||||
|
|
||||||
void _install_project(const String &p_zip_path, const String &p_title);
|
void _install_project(const String &p_zip_path, const String &p_title);
|
||||||
|
|
||||||
@@ -447,7 +447,6 @@ class ProjectManager : public Control {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
static void _bind_methods();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ProjectManager *get_singleton() { return singleton; }
|
static ProjectManager *get_singleton() { return singleton; }
|
||||||
|
|||||||
Reference in New Issue
Block a user