Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/editor/project_manager/project_list.h
21423 views
1
/**************************************************************************/
2
/* project_list.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
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
#pragma once
32
33
#include "core/io/config_file.h"
34
#include "core/os/time.h"
35
#include "scene/gui/box_container.h"
36
#include "scene/gui/scroll_container.h"
37
38
class AcceptDialog;
39
class Button;
40
class Label;
41
class PopupMenu;
42
class ProjectList;
43
class TextureButton;
44
class TextureRect;
45
46
class ProjectListItemControl : public HBoxContainer {
47
GDCLASS(ProjectListItemControl, HBoxContainer)
48
49
VBoxContainer *main_vbox = nullptr;
50
TextureButton *favorite_button = nullptr;
51
Button *explore_button = nullptr;
52
53
TextureRect *project_icon = nullptr;
54
Label *project_title = nullptr;
55
Label *project_path = nullptr;
56
Label *last_edited_info = nullptr;
57
Label *project_version = nullptr;
58
TextureRect *project_unsupported_features = nullptr;
59
HBoxContainer *tag_container = nullptr;
60
Button *touch_menu_button = nullptr;
61
62
Color favorite_focus_color;
63
64
bool project_is_missing = false;
65
bool icon_needs_reload = true;
66
bool is_selected = false;
67
bool is_focus_hidden = false;
68
bool is_hovering = false;
69
bool is_favorite = false;
70
71
void _update_favorite_button_focus_color();
72
void _favorite_button_pressed();
73
void _explore_button_pressed();
74
void _request_menu();
75
76
ProjectList *get_list() const;
77
78
void _accessibility_action_open(const Variant &p_data);
79
void _accessibility_action_scroll_into_view(const Variant &p_data);
80
void _accessibility_action_focus(const Variant &p_data);
81
void _accessibility_action_blur(const Variant &p_data);
82
83
protected:
84
void _notification(int p_what);
85
static void _bind_methods();
86
87
public:
88
void set_project_title(const String &p_title);
89
void set_project_path(const String &p_path);
90
void set_tags(const PackedStringArray &p_tags, ProjectList *p_parent_list);
91
void set_project_icon(const Ref<Texture2D> &p_icon);
92
void set_last_edited_info(const String &p_info);
93
void set_project_version(const String &p_version);
94
void set_unsupported_features(PackedStringArray p_features);
95
96
bool should_load_project_icon() const;
97
void set_selected(bool p_selected, bool p_hide_focus = false);
98
99
void set_is_favorite(bool p_favorite);
100
void set_is_missing(bool p_missing);
101
void set_is_grayed(bool p_grayed);
102
103
ProjectListItemControl();
104
};
105
106
class ProjectList : public ScrollContainer {
107
GDCLASS(ProjectList, ScrollContainer)
108
109
friend class ProjectManager;
110
friend class ProjectListItemControl;
111
112
public:
113
enum FilterOption {
114
EDIT_DATE,
115
NAME,
116
PATH,
117
TAGS,
118
};
119
120
enum MenuOption {
121
MENU_EDIT,
122
MENU_EDIT_VERBOSE,
123
MENU_EDIT_RECOVERY,
124
MENU_RUN,
125
MENU_SHOW_IN_FILE_MANAGER,
126
MENU_COPY_PATH,
127
MENU_RENAME,
128
MENU_MANAGE_TAGS,
129
MENU_DUPLICATE,
130
MENU_REMOVE,
131
};
132
133
// Can often be passed by copy.
134
struct Item {
135
String project_name;
136
String description;
137
String project_version;
138
PackedStringArray tags;
139
String tag_sort_string;
140
String path;
141
String icon;
142
String main_scene;
143
PackedStringArray unsupported_features;
144
uint64_t last_edited = 0;
145
bool favorite = false;
146
bool grayed = false;
147
bool missing = false;
148
bool recovery_mode = false;
149
int version = 0;
150
151
ProjectListItemControl *control = nullptr;
152
153
Item() {}
154
155
Item(const String &p_name,
156
const String &p_description,
157
const String &p_project_version,
158
const PackedStringArray &p_tags,
159
const String &p_path,
160
const String &p_icon,
161
const String &p_main_scene,
162
const PackedStringArray &p_unsupported_features,
163
uint64_t p_last_edited,
164
bool p_favorite,
165
bool p_grayed,
166
bool p_missing,
167
bool p_recovery_mode,
168
int p_version) {
169
project_name = p_name;
170
description = p_description;
171
project_version = p_project_version;
172
tags = p_tags;
173
path = p_path;
174
icon = p_icon;
175
main_scene = p_main_scene;
176
unsupported_features = p_unsupported_features;
177
last_edited = p_last_edited;
178
favorite = p_favorite;
179
grayed = p_grayed;
180
missing = p_missing;
181
recovery_mode = p_recovery_mode;
182
version = p_version;
183
184
control = nullptr;
185
186
PackedStringArray sorted_tags = tags;
187
sorted_tags.sort();
188
tag_sort_string = String().join(sorted_tags);
189
}
190
191
_FORCE_INLINE_ bool operator==(const Item &l) const {
192
return path == l.path;
193
}
194
195
String get_last_edited_string() const {
196
if (missing) {
197
return TTR("Missing Date");
198
}
199
200
OS::TimeZoneInfo tz = OS::get_singleton()->get_time_zone_info();
201
return Time::get_singleton()->get_datetime_string_from_unix_time(last_edited + tz.bias * 60, true);
202
}
203
};
204
205
private:
206
String _config_path;
207
ConfigFile _config;
208
209
Vector<Item> _projects;
210
211
int _icon_load_index = 0;
212
bool project_opening_initiated = false;
213
214
String _search_term;
215
FilterOption _order_option = FilterOption::EDIT_DATE;
216
HashSet<String> _selected_project_paths;
217
String _last_clicked; // Project key
218
219
VBoxContainer *project_list_vbox = nullptr;
220
PopupMenu *project_context_menu = nullptr;
221
222
// Projects scan.
223
224
struct ScanData {
225
Thread *thread = nullptr;
226
PackedStringArray paths_to_scan;
227
List<String> found_projects;
228
SafeFlag scan_in_progress;
229
};
230
ScanData *scan_data = nullptr;
231
AcceptDialog *scan_progress = nullptr;
232
233
static void _scan_thread(void *p_scan_data);
234
void _scan_finished();
235
236
// Initialization & loading.
237
238
void _migrate_config();
239
240
static Item load_project_data(const String &p_property_key, bool p_favorite);
241
void _update_icons_async();
242
void _load_project_icon(int p_index);
243
244
// Project list updates.
245
246
static void _scan_folder_recursive(const String &p_path, List<String> *r_projects, const SafeFlag &p_scan_active);
247
248
// Project list items.
249
250
void _create_project_item_control(int p_index);
251
void _toggle_project(int p_index);
252
void _remove_project(int p_index, bool p_update_settings);
253
254
void _list_item_input(const Ref<InputEvent> &p_ev, Control *p_hb);
255
void _on_favorite_pressed(Node *p_hb);
256
void _on_explore_pressed(const String &p_path);
257
258
void _open_menu(const Vector2 &p_at, Control *p_hb);
259
void _menu_option(int p_option);
260
void _update_menu_icons();
261
262
// Project list selection.
263
264
void _clear_project_selection();
265
void _select_project_nocheck(int p_index, bool p_hide_focus = false);
266
void _deselect_project_nocheck(int p_index);
267
void _select_project_range(int p_begin, int p_end);
268
269
// Global menu integration.
270
271
void _global_menu_new_window(const Variant &p_tag);
272
void _global_menu_open_project(const Variant &p_tag);
273
274
protected:
275
void _notification(int p_what);
276
static void _bind_methods();
277
278
public:
279
static inline const char *SIGNAL_LIST_CHANGED = "list_changed";
280
static inline const char *SIGNAL_SELECTION_CHANGED = "selection_changed";
281
static inline const char *SIGNAL_PROJECT_ASK_OPEN = "project_ask_open";
282
static inline const char *SIGNAL_MENU_OPTION_SELECTED = "menu_option_selected";
283
284
static bool project_feature_looks_like_version(const String &p_feature);
285
286
// Initialization & loading.
287
288
void save_config();
289
290
// Project list updates.
291
292
void load_project_list();
293
void update_project_list();
294
void sort_projects();
295
int get_project_count() const;
296
297
void find_projects(const String &p_path);
298
void find_projects_multiple(const PackedStringArray &p_paths);
299
300
// Project list items.
301
302
void add_project(const String &dir_path, bool favorite);
303
void set_project_version(const String &p_project_path, int version);
304
int refresh_project(const String &dir_path);
305
void ensure_project_visible(int p_index);
306
int get_index(const ProjectListItemControl *p_control) const;
307
308
// Project list selection.
309
310
void select_project(int p_index, bool p_hide_focus = false);
311
void deselect_project(int p_index);
312
void select_first_visible_project();
313
void select_all_visible_projects();
314
void deselect_all_visible_projects();
315
Vector<Item> get_selected_projects() const;
316
const HashSet<String> &get_selected_project_keys() const;
317
int get_single_selected_index() const;
318
void erase_selected_projects(bool p_delete_project_contents);
319
320
// Missing projects.
321
322
bool is_any_project_missing() const;
323
void erase_missing_projects();
324
325
// Project list sorting and filtering.
326
327
void set_search_term(String p_search_term);
328
void add_search_tag(const String &p_tag);
329
void set_order_option(int p_option, bool p_save);
330
331
// Global menu integration.
332
333
void update_dock_menu();
334
335
ProjectList();
336
};
337
338