Path: blob/master/editor/project_manager/project_list.h
9902 views
/**************************************************************************/1/* project_list.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "core/io/config_file.h"33#include "core/os/time.h"34#include "scene/gui/box_container.h"35#include "scene/gui/scroll_container.h"3637class AcceptDialog;38class Button;39class Label;40class ProjectList;41class TextureButton;42class TextureRect;4344class ProjectListItemControl : public HBoxContainer {45GDCLASS(ProjectListItemControl, HBoxContainer)4647VBoxContainer *main_vbox = nullptr;48TextureButton *favorite_button = nullptr;49Button *explore_button = nullptr;5051TextureRect *project_icon = nullptr;52Label *project_title = nullptr;53Label *project_path = nullptr;54Label *last_edited_info = nullptr;55Label *project_version = nullptr;56TextureRect *project_unsupported_features = nullptr;57HBoxContainer *tag_container = nullptr;5859bool project_is_missing = false;60bool icon_needs_reload = true;61bool is_selected = false;62bool is_hovering = false;6364void _favorite_button_pressed();65void _explore_button_pressed();6667ProjectList *get_list() const;6869void _accessibility_action_open(const Variant &p_data);70void _accessibility_action_scroll_into_view(const Variant &p_data);71void _accessibility_action_focus(const Variant &p_data);72void _accessibility_action_blur(const Variant &p_data);7374protected:75void _notification(int p_what);76static void _bind_methods();7778public:79void set_project_title(const String &p_title);80void set_project_path(const String &p_path);81void set_tags(const PackedStringArray &p_tags, ProjectList *p_parent_list);82void set_project_icon(const Ref<Texture2D> &p_icon);83void set_last_edited_info(const String &p_info);84void set_project_version(const String &p_version);85void set_unsupported_features(PackedStringArray p_features);8687bool should_load_project_icon() const;88void set_selected(bool p_selected);8990void set_is_favorite(bool p_favorite);91void set_is_missing(bool p_missing);92void set_is_grayed(bool p_grayed);9394ProjectListItemControl();95};9697class ProjectList : public ScrollContainer {98GDCLASS(ProjectList, ScrollContainer)99100friend class ProjectManager;101friend class ProjectListItemControl;102103public:104enum FilterOption {105EDIT_DATE,106NAME,107PATH,108TAGS,109};110111// Can often be passed by copy.112struct Item {113String project_name;114String description;115String project_version;116PackedStringArray tags;117String tag_sort_string;118String path;119String icon;120String main_scene;121PackedStringArray unsupported_features;122uint64_t last_edited = 0;123bool favorite = false;124bool grayed = false;125bool missing = false;126bool recovery_mode = false;127int version = 0;128129ProjectListItemControl *control = nullptr;130131Item() {}132133Item(const String &p_name,134const String &p_description,135const String &p_project_version,136const PackedStringArray &p_tags,137const String &p_path,138const String &p_icon,139const String &p_main_scene,140const PackedStringArray &p_unsupported_features,141uint64_t p_last_edited,142bool p_favorite,143bool p_grayed,144bool p_missing,145bool p_recovery_mode,146int p_version) {147project_name = p_name;148description = p_description;149project_version = p_project_version;150tags = p_tags;151path = p_path;152icon = p_icon;153main_scene = p_main_scene;154unsupported_features = p_unsupported_features;155last_edited = p_last_edited;156favorite = p_favorite;157grayed = p_grayed;158missing = p_missing;159recovery_mode = p_recovery_mode;160version = p_version;161162control = nullptr;163164PackedStringArray sorted_tags = tags;165sorted_tags.sort();166tag_sort_string = String().join(sorted_tags);167}168169_FORCE_INLINE_ bool operator==(const Item &l) const {170return path == l.path;171}172173String get_last_edited_string() const {174if (missing) {175return TTR("Missing Date");176}177178OS::TimeZoneInfo tz = OS::get_singleton()->get_time_zone_info();179return Time::get_singleton()->get_datetime_string_from_unix_time(last_edited + tz.bias * 60, true);180}181};182183private:184String _config_path;185ConfigFile _config;186187Vector<Item> _projects;188189int _icon_load_index = 0;190bool project_opening_initiated = false;191192String _search_term;193FilterOption _order_option = FilterOption::EDIT_DATE;194HashSet<String> _selected_project_paths;195String _last_clicked; // Project key196197VBoxContainer *project_list_vbox = nullptr;198199// Projects scan.200201struct ScanData {202Thread *thread = nullptr;203PackedStringArray paths_to_scan;204List<String> found_projects;205SafeFlag scan_in_progress;206};207ScanData *scan_data = nullptr;208AcceptDialog *scan_progress = nullptr;209210static void _scan_thread(void *p_scan_data);211void _scan_finished();212213// Initialization & loading.214215void _migrate_config();216217static Item load_project_data(const String &p_property_key, bool p_favorite);218void _update_icons_async();219void _load_project_icon(int p_index);220221// Project list updates.222223static void _scan_folder_recursive(const String &p_path, List<String> *r_projects, const SafeFlag &p_scan_active);224225// Project list items.226227void _create_project_item_control(int p_index);228void _toggle_project(int p_index);229void _remove_project(int p_index, bool p_update_settings);230231void _list_item_input(const Ref<InputEvent> &p_ev, Node *p_hb);232void _on_favorite_pressed(Node *p_hb);233void _on_explore_pressed(const String &p_path);234235// Project list selection.236237void _clear_project_selection();238void _select_project_nocheck(int p_index);239void _deselect_project_nocheck(int p_index);240void _select_project_range(int p_begin, int p_end);241242// Global menu integration.243244void _global_menu_new_window(const Variant &p_tag);245void _global_menu_open_project(const Variant &p_tag);246247protected:248void _notification(int p_what);249static void _bind_methods();250251public:252static const char *SIGNAL_LIST_CHANGED;253static const char *SIGNAL_SELECTION_CHANGED;254static const char *SIGNAL_PROJECT_ASK_OPEN;255256static bool project_feature_looks_like_version(const String &p_feature);257258// Initialization & loading.259260void save_config();261262// Project list updates.263264void load_project_list();265void update_project_list();266void sort_projects();267int get_project_count() const;268269void find_projects(const String &p_path);270void find_projects_multiple(const PackedStringArray &p_paths);271272// Project list items.273274void add_project(const String &dir_path, bool favorite);275void set_project_version(const String &p_project_path, int version);276int refresh_project(const String &dir_path);277void ensure_project_visible(int p_index);278int get_index(const ProjectListItemControl *p_control) const;279280// Project list selection.281282void select_project(int p_index);283void deselect_project(int p_index);284void select_first_visible_project();285Vector<Item> get_selected_projects() const;286const HashSet<String> &get_selected_project_keys() const;287int get_single_selected_index() const;288void erase_selected_projects(bool p_delete_project_contents);289290// Missing projects.291292bool is_any_project_missing() const;293void erase_missing_projects();294295// Project list sorting and filtering.296297void set_search_term(String p_search_term);298void add_search_tag(const String &p_tag);299void set_order_option(int p_option);300301// Global menu integration.302303void update_dock_menu();304305ProjectList();306};307308309