input (slider, number, file)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user