mirror of
https://github.com/Relintai/material-maker.git
synced 2024-12-27 23:17:14 +01:00
130 lines
3.4 KiB
GDScript
130 lines
3.4 KiB
GDScript
extends LineEdit
|
|
class_name MMFloatEdit
|
|
|
|
export var value : float = 0.5 setget set_value
|
|
export var min_value : float = 0.0 setget set_min_value
|
|
export var max_value : float = 1.0 setget set_max_value
|
|
export var step : float = 0.0 setget set_step
|
|
export var float_only : bool = false
|
|
|
|
var sliding : bool = false
|
|
var start_position : float
|
|
var last_position : float
|
|
var start_value : float
|
|
var modifiers : int
|
|
var from_lower_bound : bool = false
|
|
var from_upper_bound : bool = false
|
|
|
|
onready var slider = $Slider
|
|
onready var cursor = $Slider/Cursor
|
|
|
|
signal value_changed(value)
|
|
|
|
func _ready() -> void:
|
|
do_update()
|
|
|
|
func set_value(v) -> void:
|
|
if v is float:
|
|
value = v
|
|
do_update()
|
|
$Slider.visible = true
|
|
elif v is String and !float_only:
|
|
text = v
|
|
$Slider.visible = false
|
|
|
|
func set_min_value(v : float) -> void:
|
|
min_value = v
|
|
do_update()
|
|
|
|
func set_max_value(v : float) -> void:
|
|
max_value = v
|
|
do_update()
|
|
|
|
func set_step(v : float) -> void:
|
|
step = v
|
|
do_update()
|
|
|
|
func do_update(update_text : bool = true) -> void:
|
|
if update_text and $Slider.visible:
|
|
text = str(value)
|
|
if cursor != null:
|
|
if max_value != min_value:
|
|
cursor.rect_position.x = (clamp(value, min_value, max_value)-min_value)*(slider.rect_size.x-cursor.rect_size.x)/(max_value-min_value)
|
|
else:
|
|
cursor.rect_position.x = 0
|
|
|
|
func get_modifiers(event):
|
|
var modifiers = 0
|
|
if event.shift:
|
|
modifiers |= 1
|
|
if event.control:
|
|
modifiers |= 2
|
|
if event.alt:
|
|
modifiers |= 4
|
|
return modifiers
|
|
|
|
func _on_LineEdit_gui_input(event : InputEvent) -> void:
|
|
if !$Slider.visible:
|
|
return
|
|
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
|
|
if event.is_pressed():
|
|
last_position = event.position.x
|
|
start_position = last_position
|
|
start_value = value
|
|
sliding = true
|
|
from_lower_bound = value <= min_value
|
|
from_upper_bound = value >= max_value
|
|
modifiers = get_modifiers(event)
|
|
else:
|
|
sliding = false
|
|
elif sliding and event is InputEventMouseMotion and event.button_mask == BUTTON_MASK_LEFT:
|
|
var new_modifiers = get_modifiers(event)
|
|
if new_modifiers != modifiers:
|
|
start_position = last_position
|
|
start_value = value
|
|
modifiers = new_modifiers
|
|
else:
|
|
last_position = event.position.x
|
|
var delta : float = last_position-start_position
|
|
var current_step = step
|
|
if event.control:
|
|
delta *= 0.2
|
|
elif event.shift:
|
|
delta *= 5.0
|
|
if event.alt:
|
|
current_step *= 0.01
|
|
var v : float = start_value+sign(delta)*pow(abs(delta)*0.005, 2)*abs(max_value - min_value)
|
|
if current_step != 0:
|
|
v = min_value+floor((v - min_value)/current_step)*current_step
|
|
if !from_lower_bound and v < min_value:
|
|
v = min_value
|
|
if !from_upper_bound and v > max_value:
|
|
v = max_value
|
|
set_value(v)
|
|
select(0, 0)
|
|
emit_signal("value_changed", value)
|
|
elif event is InputEventKey and !event.echo:
|
|
match event.scancode:
|
|
KEY_SHIFT, KEY_CONTROL, KEY_ALT:
|
|
start_position = last_position
|
|
start_value = value
|
|
modifiers = get_modifiers(event)
|
|
|
|
func _on_LineEdit_text_changed(new_text : String) -> void:
|
|
if new_text.is_valid_float():
|
|
value = new_text.to_float()
|
|
do_update(false)
|
|
|
|
func _on_LineEdit_text_entered(new_text : String) -> void:
|
|
if new_text.is_valid_float():
|
|
value = new_text.to_float()
|
|
do_update()
|
|
emit_signal("value_changed", value)
|
|
$Slider.visible = true
|
|
else:
|
|
emit_signal("value_changed", new_text)
|
|
$Slider.visible = false
|
|
|
|
func _on_LineEdit_focus_exited() -> void:
|
|
_on_LineEdit_text_entered(text)
|