commit ed4db35724ec5ec5649379892cbf6efe5f28663b Author: limil Date: Sun Dec 14 17:54:08 2025 +0800 init diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f28239b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +charset = utf-8 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1163577 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +# Godot 4+ specific ignores +.godot/ +/android/ +.idea/ diff --git a/FileDirSelector.cs b/FileDirSelector.cs new file mode 100644 index 0000000..65ba971 --- /dev/null +++ b/FileDirSelector.cs @@ -0,0 +1,50 @@ +using System.Threading.Tasks; +using Godot; + +public partial class FileDirSelector : FileDialog +{ + private bool _isRequestPending; + + public override void _Ready() + { + FileMode = FileModeEnum.OpenDir; + Title = "请选择一个文件夹"; + Access = AccessEnum.Filesystem; + } + + public async Task SelectFolderAsync() + { + if (_isRequestPending) + { + GD.PrintErr("错误:另一个文件对话框请求正在进行中。本次请求被忽略。"); + return null; // 直接返回 null 或抛出异常 + } + + _isRequestPending = true; + + var tcs = new TaskCompletionSource(); + + void OnDirSelected(string dir) + { + DirSelected -= OnDirSelected; + Canceled -= OnCanceled; + tcs.SetResult(dir); + _isRequestPending = false; + } + + void OnCanceled() + { + DirSelected -= OnDirSelected; + Canceled -= OnCanceled; + tcs.SetResult(null); + _isRequestPending = false; + } + + DirSelected += OnDirSelected; + Canceled += OnCanceled; + + PopupCentered(); + + return await tcs.Task; + } +} diff --git a/FileDirSelector.cs.uid b/FileDirSelector.cs.uid new file mode 100644 index 0000000..a5eb20a --- /dev/null +++ b/FileDirSelector.cs.uid @@ -0,0 +1 @@ +uid://hbu73fxqen34 diff --git a/Learn.csproj b/Learn.csproj new file mode 100644 index 0000000..65eb1f8 --- /dev/null +++ b/Learn.csproj @@ -0,0 +1,7 @@ + + + net8.0 + net9.0 + true + + \ No newline at end of file diff --git a/Learn.sln b/Learn.sln new file mode 100644 index 0000000..cf725df --- /dev/null +++ b/Learn.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Learn", "Learn.csproj", "{2CE4AF17-0A6F-460B-B390-8DDC199A1E87}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + ExportDebug|Any CPU = ExportDebug|Any CPU + ExportRelease|Any CPU = ExportRelease|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2CE4AF17-0A6F-460B-B390-8DDC199A1E87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2CE4AF17-0A6F-460B-B390-8DDC199A1E87}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2CE4AF17-0A6F-460B-B390-8DDC199A1E87}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU + {2CE4AF17-0A6F-460B-B390-8DDC199A1E87}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU + {2CE4AF17-0A6F-460B-B390-8DDC199A1E87}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU + {2CE4AF17-0A6F-460B-B390-8DDC199A1E87}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU + EndGlobalSection +EndGlobal diff --git a/LearnTree.cs b/LearnTree.cs new file mode 100644 index 0000000..67b3453 --- /dev/null +++ b/LearnTree.cs @@ -0,0 +1,28 @@ +using Godot; + +public partial class LearnTree : Tree +{ + [Export] + private FileDirSelector _dirSelector; + + public override void _Ready() + { + ItemSelected += OnItemSelected; + } + + private void OnItemSelected() + { + TreeItem selected = GetSelected(); + if (selected != null) + { + GD.Print($"选中了: {selected.GetText(0)}"); + } + } + + private async void Open() + { + var path = await _dirSelector.SelectFolderAsync() ?? "None"; + if (string.IsNullOrEmpty(path)) return; + + } +} diff --git a/LearnTree.cs.uid b/LearnTree.cs.uid new file mode 100644 index 0000000..eebd837 --- /dev/null +++ b/LearnTree.cs.uid @@ -0,0 +1 @@ +uid://bngqk8kje5m2k diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..c6bbb7d --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..6e1e863 --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://xageaxkh5k1g" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..9e5279f --- /dev/null +++ b/project.godot @@ -0,0 +1,20 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="Learn" +run/main_scene="res://tree.tscn" +config/features=PackedStringArray("4.5", "C#", "Forward Plus") +config/icon="res://icon.svg" + +[dotnet] + +project/assembly_name="Learn" diff --git a/tree.tscn b/tree.tscn new file mode 100644 index 0000000..4aeea53 --- /dev/null +++ b/tree.tscn @@ -0,0 +1,43 @@ +[gd_scene load_steps=3 format=3 uid="uid://b3ypva4l8wfoh"] + +[ext_resource type="Script" uid="uid://bngqk8kje5m2k" path="res://LearnTree.cs" id="1_brfkd"] +[ext_resource type="Script" uid="uid://hbu73fxqen34" path="res://FileDirSelector.cs" id="2_nnvrw"] + +[node name="Control" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Toolbar" type="HBoxContainer" parent="VBoxContainer"] +layout_mode = 2 + +[node name="Button" type="Button" parent="VBoxContainer/Toolbar"] +layout_mode = 2 +size_flags_vertical = 4 +text = "打开文件夹" + +[node name="Content" type="HBoxContainer" parent="VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="Tree" type="Tree" parent="VBoxContainer/Content" node_paths=PackedStringArray("_dirSelector")] +layout_mode = 2 +size_flags_horizontal = 3 +script = ExtResource("1_brfkd") +_dirSelector = NodePath("../../../FileDirDialog") + +[node name="FileDirDialog" type="FileDialog" parent="."] +script = ExtResource("2_nnvrw") + +[connection signal="pressed" from="VBoxContainer/Toolbar/Button" to="VBoxContainer/Content/Tree" method="Open"]