Skip to content

Godot:Examples:FileOpenScene

GDScript를 사용하여 파일 오픈 대화상자 구현

FileOpenDialog.tscn

[gd_scene load_steps=16 format=2]

[ext_resource path="res://Assets/Font/NanumBarunGothic.ttf" type="DynamicFontData" id=3]
[ext_resource path="res://Scene/Component/FileOpenDialog.gd" type="Script" id=5]
[ext_resource path="res://Assets/SVG/OrangeSearch.svg" type="Texture" id=8]
[ext_resource path="res://Assets/SVG/SearchEdit.svg" type="Texture" id=9]

[sub_resource type="StyleBoxFlat" id=6]
bg_color = Color( 0.14902, 0.172549, 0.231373, 1 )

[sub_resource type="StyleBoxEmpty" id=1]
content_margin_left = 20.0

[sub_resource type="StyleBoxEmpty" id=2]
content_margin_left = 20.0

[sub_resource type="StyleBoxEmpty" id=3]
content_margin_left = 20.0

[sub_resource type="DynamicFont" id=4]
size = 30
use_filter = true
font_data = ExtResource( 3 )

[sub_resource type="DynamicFont" id=5]
size = 30
use_filter = true
font_data = ExtResource( 3 )

[sub_resource type="StyleBoxFlat" id=11]

[sub_resource type="StyleBoxFlat" id=8]
bg_color = Color( 0.933333, 0.596078, 0.235294, 1 )

[sub_resource type="DynamicFont" id=7]
size = 30
use_filter = true
font_data = ExtResource( 3 )

[sub_resource type="StyleBoxFlat" id=9]
bg_color = Color( 0.933333, 0.596078, 0.235294, 1 )

[sub_resource type="DynamicFont" id=10]
size = 30
use_filter = true
font_data = ExtResource( 3 )

[node name="MarginContainer" type="MarginContainer"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 5 )
__meta__ = {
"_edit_lock_": true,
"_edit_use_anchors_": false
}

[node name="Panel" type="Panel" parent="."]
margin_right = 1920.0
margin_bottom = 1080.0
custom_styles/panel = SubResource( 6 )

[node name="VBoxContainer" type="VBoxContainer" parent="."]
margin_right = 1920.0
margin_bottom = 1080.0
size_flags_horizontal = 3

[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer"]
margin_right = 1920.0
margin_bottom = 72.0

[node name="Panel" type="Panel" parent="VBoxContainer/MarginContainer"]
margin_right = 1920.0
margin_bottom = 72.0

[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/MarginContainer"]
margin_right = 1920.0
margin_bottom = 72.0
size_flags_vertical = 4
custom_constants/separation = 20
alignment = 2

[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/MarginContainer/HBoxContainer"]
margin_right = 1809.0
margin_bottom = 72.0
size_flags_horizontal = 3

[node name="TextureRect" type="TextureRect" parent="VBoxContainer/MarginContainer/HBoxContainer/MarginContainer"]
margin_right = 1809.0
margin_bottom = 72.0
texture = ExtResource( 9 )
expand = true

[node name="LineEdit" type="LineEdit" parent="VBoxContainer/MarginContainer/HBoxContainer/MarginContainer"]
margin_right = 1809.0
margin_bottom = 72.0
custom_styles/read_only = SubResource( 1 )
custom_styles/focus = SubResource( 2 )
custom_styles/normal = SubResource( 3 )
custom_fonts/font = SubResource( 4 )
custom_colors/font_color = Color( 0.666667, 0.666667, 0.666667, 1 )

[node name="TextureButton" type="TextureButton" parent="VBoxContainer/MarginContainer/HBoxContainer"]
margin_left = 1829.0
margin_right = 1920.0
margin_bottom = 72.0
texture_normal = ExtResource( 8 )

[node name="ItemList" type="ItemList" parent="VBoxContainer"]
margin_top = 76.0
margin_right = 1920.0
margin_bottom = 1001.0
size_flags_vertical = 3
custom_fonts/font = SubResource( 5 )

[node name="CenterContainer" type="CenterContainer" parent="VBoxContainer"]
margin_top = 1005.0
margin_right = 1920.0
margin_bottom = 1080.0
__meta__ = {
"_edit_use_anchors_": false
}

[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/CenterContainer"]
margin_left = 824.0
margin_right = 1096.0
margin_bottom = 75.0
custom_constants/separation = 12

[node name="OkButton" type="Button" parent="VBoxContainer/CenterContainer/HBoxContainer"]
margin_right = 130.0
margin_bottom = 75.0
rect_min_size = Vector2( 130, 75 )
custom_styles/disabled = SubResource( 11 )
custom_styles/normal = SubResource( 8 )
custom_fonts/font = SubResource( 7 )
custom_colors/font_color = Color( 0, 0, 0, 1 )
disabled = true
text = "확인"

[node name="CancelButton" type="Button" parent="VBoxContainer/CenterContainer/HBoxContainer"]
margin_left = 142.0
margin_right = 272.0
margin_bottom = 75.0
rect_min_size = Vector2( 130, 75 )
custom_styles/normal = SubResource( 9 )
custom_fonts/font = SubResource( 10 )
custom_colors/font_color = Color( 0, 0, 0, 1 )
text = "취소"
[connection signal="text_changed" from="VBoxContainer/MarginContainer/HBoxContainer/MarginContainer/LineEdit" to="." method="_on_LineEdit_text_changed"]
[connection signal="item_selected" from="VBoxContainer/ItemList" to="." method="_on_ItemList_item_selected"]
[connection signal="pressed" from="VBoxContainer/CenterContainer/HBoxContainer/OkButton" to="." method="_on_OkButton_pressed"]
[connection signal="pressed" from="VBoxContainer/CenterContainer/HBoxContainer/CancelButton" to="." method="_on_CancelButton_pressed"]

FileOpenDialog.gd

extends MarginContainer

signal on_ok(file)
signal on_cancel()

# Declare member variables here. Examples:
# var a = 2
# var b = "text"

func list_mxl_files(directory_path: String) -> Array:
    var files = []
    var dir = Directory.new()

    var error = dir.open(directory_path)
    if error != OK:
        print("Failed to open directory: " + directory_path)
        return files

    dir.list_dir_begin()
    var file_name = dir.get_next()
    while file_name != "":
        if file_name == "." or file_name == "..":
            file_name = dir.get_next()
            continue

        if dir.current_is_dir():
            for f in list_mxl_files(directory_path + "/" + file_name):
                files.append(f)
            file_name = dir.get_next()
            continue

        if file_name.ends_with(".mxl"):
            files.append(directory_path + "/" + file_name)

        file_name = dir.get_next()

    return files


func load_svg(file):
    var width = 64
    var height = 64

    # ImageTexture 생성 및 SVG 렌더링
    var image = Image.new()
    image.load(file)
    image.resize(width, height, Image.INTERPOLATE_CUBIC)

    var texture = ImageTexture.new()
    texture.create_from_image(image)

    return texture


func convert_filename_map(files: Array) -> Dictionary:
    var dic = {}
    for f in _files:
        var filename = f.substr(f.find_last("/") + 1)
        dic[filename] = f
    return dic


onready var _files = list_mxl_files(OS.get_system_dir(OS.SYSTEM_DIR_DOWNLOADS))
onready var _items = $VBoxContainer/ItemList
onready var _ok = $VBoxContainer/CenterContainer/HBoxContainer/OkButton
onready var _icon = load_svg("res://Assets/SVG/BiFileEarmarkMusic.svg")
onready var _filename_map = convert_filename_map(_files)
onready var _selected_index = -1;

# Called when the node enters the scene tree for the first time.
func _ready():
    for file in _files:
        _items.add_item(file, _icon)


# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
#    pass


func _on_LineEdit_text_changed(new_text: String):
    if new_text == "":
        for file in _files:
            _items.add_item(file, _icon)
        return

    _items.clear()
    for file in _files:
        if file.find(new_text) != -1:
            _items.add_item(file, _icon)


func _on_ItemList_item_selected(index: int):
    _selected_index = index;
    _ok.disabled = false;


func _on_OkButton_pressed():
    emit_signal("on_ok", _items.get_item_text(_selected_index))


func _on_CancelButton_pressed():
    emit_signal("on_cancel")

See also