input (slider, number, file)

This commit is contained in:
Face
2025-07-25 14:51:51 +03:00
parent 465200cd28
commit a8f77e1bd4
22 changed files with 617 additions and 3 deletions

View File

@@ -4,6 +4,8 @@ static var button_groups: Dictionary = {}
const BROWSER_TEXT: Theme = preload("res://Scenes/Styles/BrowserText.tres")
var custom_hex_input: LineEdit
var _file_text_content: String = ""
var _file_binary_content: PackedByteArray = PackedByteArray()
func init(element: HTMLParser.HTMLElement) -> void:
var color_picker_button: ColorPickerButton = $ColorPickerButton
@@ -50,6 +52,10 @@ func init(element: HTMLParser.HTMLElement) -> void:
var minlength = element.get_attribute("minlength")
var maxlength = element.get_attribute("maxlength")
var pattern = element.get_attribute("pattern")
var min_attr = element.get_attribute("min")
var max_attr = element.get_attribute("max")
var step_attr = element.get_attribute("step")
var accept = element.get_attribute("accept")
# Define which child should be active for each input type
var active_child_map = {
@@ -57,7 +63,10 @@ func init(element: HTMLParser.HTMLElement) -> void:
"radio": "RadioButton",
"color": "ColorPickerButton",
"password": "LineEdit",
"date": "DateButton"
"date": "DateButton",
"range": "HSlider",
"number": "SpinBox",
"file": "FileContainer"
}
var active_child_name = active_child_map.get(input_type, "LineEdit")
@@ -101,6 +110,18 @@ func init(element: HTMLParser.HTMLElement) -> void:
date_button.init_with_date(value)
else:
date_button.init()
"range":
var slider = active_child as HSlider
setup_range_input(slider, value, min_attr, max_attr, step_attr)
"number":
var spin_box = active_child as SpinBox
setup_number_input(spin_box, value, min_attr, max_attr, step_attr, placeholder)
"file":
var file_container = active_child as Control
setup_file_input(file_container, accept)
_: # Default case (text input)
var line_edit = active_child as LineEdit
@@ -168,3 +189,103 @@ func _on_custom_hex_submitted(new_text: String) -> void:
var picker = ($ColorPickerButton as ColorPickerButton).get_picker()
picker.set_pick_color(new_color)
$ColorPickerButton.color = new_color
func setup_range_input(slider: HSlider, value: String, min_attr: String, max_attr: String, step_attr: String) -> void:
var min_val = min_attr.to_float() if min_attr.length() > 0 else 0.0
var max_val = max_attr.to_float() if max_attr.length() > 0 else 100.0
var step_val = step_attr.to_float() if step_attr.length() > 0 else 1.0
slider.min_value = min_val
slider.max_value = max_val
slider.step = step_val
slider.value = value.to_float() if value.length() > 0 else min_val
func setup_number_input(spin_box: SpinBox, value: String, min_attr: String, max_attr: String, step_attr: String, placeholder: String) -> void:
var min_val = min_attr.to_float() if min_attr.length() > 0 else -99999.0
var max_val = max_attr.to_float() if max_attr.length() > 0 else 99999.0
var step_val = step_attr.to_float() if step_attr.length() > 0 else 1.0
spin_box.min_value = min_val
spin_box.max_value = max_val
spin_box.step = step_val
spin_box.value = value.to_float() if value.length() > 0 else min_val
var line_edit = spin_box.get_line_edit()
line_edit.placeholder_text = placeholder
func setup_file_input(file_container: Control, accept: String = "") -> void:
var file_button = file_container.get_node("FileButton") as Button
var file_label = file_container.get_node("FileLabel") as Label
var file_dialog = file_container.get_node("FileDialog") as FileDialog
if accept.length() > 0:
setup_file_filters(file_dialog, accept)
file_button.pressed.connect(_on_file_button_pressed)
file_dialog.file_selected.connect(_on_file_selected)
file_label.text = "No file chosen"
func setup_file_filters(file_dialog: FileDialog, accept: String) -> void:
file_dialog.clear_filters()
var filters = accept.split(",")
var image_extensions = ["jpg", "jpeg", "png", "gif", "bmp", "webp", "svg"]
var audio_extensions = ["mp3", "wav", "ogg", "m4a", "flac"]
var video_extensions = ["mp4", "avi", "mov", "wmv", "flv", "webm"]
for filter in filters:
filter = filter.strip_edges()
if filter == "image/*":
for ext in image_extensions:
file_dialog.add_filter("*." + ext, "Image Files")
elif filter == "audio/*":
for ext in audio_extensions:
file_dialog.add_filter("*." + ext, "Audio Files")
elif filter == "video/*":
for ext in video_extensions:
file_dialog.add_filter("*." + ext, "Video Files")
elif filter.begins_with("."):
# Individual file extension
var ext = filter.substr(1)
file_dialog.add_filter("*" + filter, ext.to_upper() + " Files")
elif filter.contains("/"):
# MIME type - convert to common extensions
match filter:
"text/plain":
file_dialog.add_filter("*.txt", "Text Files")
"application/pdf":
file_dialog.add_filter("*.pdf", "PDF Files")
"application/json":
file_dialog.add_filter("*.json", "JSON Files")
"text/html":
file_dialog.add_filter("*.html", "HTML Files")
"text/css":
file_dialog.add_filter("*.css", "CSS Files")
"application/javascript":
file_dialog.add_filter("*.js", "JavaScript Files")
# If no valid filters were added, allow all files
if file_dialog.filters.size() == 0:
file_dialog.add_filter("*", "All Files")
func _on_file_button_pressed() -> void:
var file_dialog = get_node("FileContainer/FileDialog") as FileDialog
file_dialog.popup_centered(Vector2i(800, 600))
func _on_file_selected(path: String) -> void:
var file_label = get_node("FileContainer/FileLabel") as Label
var file_name = path.get_file()
file_label.text = file_name
var file = FileAccess.open(path, FileAccess.READ)
if file:
_file_text_content = file.get_as_text()
file.close()
file = FileAccess.open(path, FileAccess.READ)
_file_binary_content = file.get_buffer(file.get_length())
file.close()
# TODO: when adding Lua, make these actually usable

View File

@@ -95,6 +95,15 @@ line breaks
<h2>Date</h2>
<input type=\"date\" value=\"2018-07-22\" />
<h2>Range Slider</h2>
<input type=\"range\" min=\"0\" max=\"100\" step=\"5\" value=\"50\" />
<h2>Number Input</h2>
<input type=\"number\" min=\"1\" max=\"10\" step=\"0.5\" value=\"5\" placeholder=\"Enter number\" />
<h2>File Upload</h2>
<input type=\"file\" accept=\".txt,.pdf,image/*\" />
<input type=\"password\" placeholder=\"your password...\" />
<button type=\"submit\">Submit</button>