Skip to content

Commit cc52112

Browse files
committed
Merge pull request godotengine#96643 from bruvzg/fs_links
[FileSystem Dock] Add symlink indicator and tooltip.
2 parents 6b9f441 + da4f5fb commit cc52112

File tree

6 files changed

+66
-0
lines changed

6 files changed

+66
-0
lines changed

doc/classes/TreeItem.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,13 @@
223223
Returns the [Color] modulating the column's icon.
224224
</description>
225225
</method>
226+
<method name="get_icon_overlay" qualifiers="const">
227+
<return type="Texture2D" />
228+
<param index="0" name="column" type="int" />
229+
<description>
230+
Returns the given column's icon overlay [Texture2D].
231+
</description>
232+
</method>
226233
<method name="get_icon_region" qualifiers="const">
227234
<return type="Rect2" />
228235
<param index="0" name="column" type="int" />
@@ -662,6 +669,14 @@
662669
Modulates the given column's icon with [param modulate].
663670
</description>
664671
</method>
672+
<method name="set_icon_overlay">
673+
<return type="void" />
674+
<param index="0" name="column" type="int" />
675+
<param index="1" name="texture" type="Texture2D" />
676+
<description>
677+
Sets the given cell's icon overlay [Texture2D]. The cell has to be in [constant CELL_MODE_ICON] mode, and icon has to be set. Overlay is drawn on top of icon, in the bottom left corner.
678+
</description>
679+
</method>
665680
<method name="set_icon_region">
666681
<return type="void" />
667682
<param index="0" name="column" type="int" />

drivers/unix/dir_access_unix.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,9 @@ Error DirAccessUnix::remove(String p_path) {
419419
}
420420

421421
p_path = fix_path(p_path);
422+
if (p_path.ends_with("/")) {
423+
p_path = p_path.left(-1);
424+
}
422425

423426
struct stat flags = {};
424427
if ((stat(p_path.utf8().get_data(), &flags) != 0)) {
@@ -438,6 +441,9 @@ bool DirAccessUnix::is_link(String p_file) {
438441
}
439442

440443
p_file = fix_path(p_file);
444+
if (p_file.ends_with("/")) {
445+
p_file = p_file.left(-1);
446+
}
441447

442448
struct stat flags = {};
443449
if ((lstat(p_file.utf8().get_data(), &flags) != 0)) {
@@ -453,6 +459,9 @@ String DirAccessUnix::read_link(String p_file) {
453459
}
454460

455461
p_file = fix_path(p_file);
462+
if (p_file.ends_with("/")) {
463+
p_file = p_file.left(-1);
464+
}
456465

457466
char buf[256];
458467
memset(buf, 0, 256);

editor/filesystem_dock.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
216216
// Set custom folder color (if applicable).
217217
bool has_custom_color = assigned_folder_colors.has(lpath);
218218
Color custom_color = has_custom_color ? folder_colors[assigned_folder_colors[lpath]] : Color();
219+
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
219220

220221
if (has_custom_color) {
221222
subdirectory_item->set_icon_modulate(0, editor_is_dark_theme ? custom_color : custom_color * ITEM_COLOR_SCALE);
@@ -237,6 +238,10 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
237238
subdirectory_item->set_text(0, dname);
238239
subdirectory_item->set_structured_text_bidi_override(0, TextServer::STRUCTURED_TEXT_FILE);
239240
subdirectory_item->set_icon(0, get_editor_theme_icon(SNAME("Folder")));
241+
if (da->is_link(lpath)) {
242+
subdirectory_item->set_icon_overlay(0, get_editor_theme_icon(SNAME("LinkOverlay")));
243+
subdirectory_item->set_tooltip_text(0, vformat(TTR("Link to: %s"), da->read_link(lpath)));
244+
}
240245
subdirectory_item->set_selectable(0, true);
241246
subdirectory_item->set_metadata(0, lpath);
242247
if (!p_select_in_favorites && (current_path == lpath || ((display_mode != DISPLAY_MODE_TREE_ONLY) && current_path.get_base_dir() == lpath))) {
@@ -309,6 +314,10 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
309314
file_item->set_text(0, fi.name);
310315
file_item->set_structured_text_bidi_override(0, TextServer::STRUCTURED_TEXT_FILE);
311316
file_item->set_icon(0, _get_tree_item_icon(!fi.import_broken, fi.type, fi.icon_path));
317+
if (da->is_link(file_metadata)) {
318+
file_item->set_icon_overlay(0, get_editor_theme_icon(SNAME("LinkOverlay")));
319+
file_item->set_tooltip_text(0, vformat(TTR("Link to: %s"), da->read_link(file_metadata)));
320+
}
312321
file_item->set_icon_max_width(0, icon_size);
313322
Color parent_bg_color = subdirectory_item->get_custom_bg_color(0);
314323
if (has_custom_color) {

editor/icons/LinkOverlay.svg

Lines changed: 1 addition & 0 deletions
Loading

scene/gui/tree.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,15 @@ void TreeItem::Cell::draw_icon(const RID &p_where, const Point2 &p_pos, const Si
6262

6363
if (icon_region == Rect2i()) {
6464
icon->draw_rect_region(p_where, Rect2(p_pos, dsize), Rect2(Point2(), icon->get_size()), p_color);
65+
if (icon_overlay.is_valid()) {
66+
Vector2 offset = icon->get_size() - icon_overlay->get_size();
67+
icon_overlay->draw_rect_region(p_where, Rect2(p_pos + offset, dsize), Rect2(Point2(), icon_overlay->get_size()), p_color);
68+
}
6569
} else {
6670
icon->draw_rect_region(p_where, Rect2(p_pos, dsize), icon_region, p_color);
71+
if (icon_overlay.is_valid()) {
72+
icon_overlay->draw_rect_region(p_where, Rect2(p_pos, dsize), icon_region, p_color);
73+
}
6774
}
6875
}
6976

@@ -477,6 +484,24 @@ Ref<Texture2D> TreeItem::get_icon(int p_column) const {
477484
return cells[p_column].icon;
478485
}
479486

487+
void TreeItem::set_icon_overlay(int p_column, const Ref<Texture2D> &p_icon_overlay) {
488+
ERR_FAIL_INDEX(p_column, cells.size());
489+
490+
if (cells[p_column].icon_overlay == p_icon_overlay) {
491+
return;
492+
}
493+
494+
cells.write[p_column].icon_overlay = p_icon_overlay;
495+
cells.write[p_column].cached_minimum_size_dirty = true;
496+
497+
_changed_notify(p_column);
498+
}
499+
500+
Ref<Texture2D> TreeItem::get_icon_overlay(int p_column) const {
501+
ERR_FAIL_INDEX_V(p_column, cells.size(), Ref<Texture2D>());
502+
return cells[p_column].icon_overlay;
503+
}
504+
480505
void TreeItem::set_icon_region(int p_column, const Rect2 &p_icon_region) {
481506
ERR_FAIL_INDEX(p_column, cells.size());
482507

@@ -1633,6 +1658,9 @@ void TreeItem::_bind_methods() {
16331658
ClassDB::bind_method(D_METHOD("set_icon", "column", "texture"), &TreeItem::set_icon);
16341659
ClassDB::bind_method(D_METHOD("get_icon", "column"), &TreeItem::get_icon);
16351660

1661+
ClassDB::bind_method(D_METHOD("set_icon_overlay", "column", "texture"), &TreeItem::set_icon_overlay);
1662+
ClassDB::bind_method(D_METHOD("get_icon_overlay", "column"), &TreeItem::get_icon_overlay);
1663+
16361664
ClassDB::bind_method(D_METHOD("set_icon_region", "column", "region"), &TreeItem::set_icon_region);
16371665
ClassDB::bind_method(D_METHOD("get_icon_region", "column"), &TreeItem::get_icon_region);
16381666

scene/gui/tree.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class TreeItem : public Object {
6060
TreeCellMode mode = TreeItem::CELL_MODE_STRING;
6161

6262
Ref<Texture2D> icon;
63+
Ref<Texture2D> icon_overlay;
6364
Rect2i icon_region;
6465
String text;
6566
String xl_text;
@@ -257,6 +258,9 @@ class TreeItem : public Object {
257258
void set_icon(int p_column, const Ref<Texture2D> &p_icon);
258259
Ref<Texture2D> get_icon(int p_column) const;
259260

261+
void set_icon_overlay(int p_column, const Ref<Texture2D> &p_icon_overlay);
262+
Ref<Texture2D> get_icon_overlay(int p_column) const;
263+
260264
void set_icon_region(int p_column, const Rect2 &p_icon_region);
261265
Rect2 get_icon_region(int p_column) const;
262266

0 commit comments

Comments
 (0)