material-maker/addons/material_maker/widgets/linked_widgets/linked_control_base.gd

151 lines
4.4 KiB
GDScript

tool
extends VBoxContainer
var label = null
var buttons = null
var linked_widgets = []
var links = null
const Link = preload("res://addons/material_maker/widgets/linked_widgets/link.gd")
const WIDGETS = {
SpinBox={ attrs=[ "min_value", "max_value", "step" ], value_attr="value", sig="value_changed", sig_handler="_on_value_changed" },
HSlider={ attrs=[ "min_value", "max_value", "step" ], value_attr="value", sig="value_changed", sig_handler="_on_value_changed" },
ColorPickerButton={ attrs=[ "edit_alpha", ], value_attr="color", sig="color_changed", sig_handler="_on_color_changed" },
OptionButton={ attrs=[ ], value_attr="selected", sig="item_selected", sig_handler="_on_item_selected" },
GradientEditor={ attrs=[ ], value_attr="value", sig="updated", sig_handler="_on_gradient_updated" }
}
func get_widget_type(widget):
if widget is SpinBox:
return "SpinBox"
elif widget is ColorPickerButton:
return "ColorPickerButton"
elif widget is Control && widget.filename == "res://addons/material_maker/widgets/gradient_editor.tscn":
return "GradientEditor"
elif widget is HSlider:
return "HSlider"
elif widget is OptionButton:
return "OptionButton"
else:
return null
func _ready():
set_process_input(false)
func can_link_to(c):
return c != null
func get_associated_controls():
label = preload("res://addons/material_maker/widgets/linked_widgets/editable_label.tscn").instance()
label.set_text("Unnamed")
buttons = preload("res://addons/material_maker/widgets/linked_widgets/linked_control_buttons.tscn").instance()
buttons.control = self
return { label=label, buttons=buttons }
func delete():
var parent = get_parent()
label.queue_free()
buttons.queue_free()
queue_free()
func _on_mouse_entered():
_on_mouse_exited()
get_graph_edit()
if graph_edit == null:
return
links = []
var viewport = get_viewport()
for w in linked_widgets:
var link = Link.new()
link.clip(graph_edit.rect_global_position, graph_edit.rect_size)
link.source = self
link.target = w.widget
graph_edit.add_child(link)
links.append(link)
func _on_mouse_exited():
if links != null:
for l in links:
l.queue_free()
links = null
# Capture mouse to link to a control
var link = null
var graph_edit = null
var pointed_control = null
func get_graph_edit():
graph_edit = get_parent()
while graph_edit != null && !(graph_edit is GraphEdit):
graph_edit = graph_edit.get_parent()
func find_control(gp):
for c in graph_edit.get_children():
if c is GraphNode:
if c.get("property_widgets") != null:
for w in c.property_widgets:
if Rect2(w.rect_global_position, w.rect_size*w.get_global_transform().get_scale()).has_point(gp):
return { node=c, widget=w }
return null
func _input(event):
if event is InputEventKey:
if event.scancode == KEY_ESCAPE:
set_process_input(false)
link.queue_free()
link = null
elif event is InputEventMouseMotion:
var control = find_control(event.global_position)
link.end = event.global_position
link.target = control.widget if control != null && can_link_to(control.widget) else null
link.update()
elif event is InputEventMouseButton:
if event.pressed:
if event.button_index == BUTTON_LEFT:
var control = find_control(event.global_position)
if control != null:
add_linked(control.node, control.widget)
set_process_input(false)
link.queue_free()
link = null
get_tree().set_input_as_handled()
func pick_linked():
# Verify we are in a graph edit
get_graph_edit()
if graph_edit == null:
return
# Create line that will be shown when looking for a target
var viewport = get_viewport()
link = Link.new()
link.clip(graph_edit.rect_global_position, graph_edit.rect_size)
link.source = self
link.end = rect_global_position+0.5*rect_size*get_global_transform().get_scale()
graph_edit.add_child(link)
set_process_input(true)
pointed_control = null
func serialize():
var data = { label=label.text, linked_widgets=[] }
for w in linked_widgets:
data.linked_widgets.append( { node=w.node.name, widget=w.widget.name } )
return data
func deserialize(data):
if data.has("label"):
label.text = data.label
if !data.has("linked_widgets"):
return
var graph_edit = get_parent()
while !(graph_edit is GraphEdit):
graph_edit = graph_edit.get_parent()
for w in data.linked_widgets:
var node = graph_edit.get_node(w.node)
if node != null && node.get("property_widgets") != null:
for widget in node.property_widgets:
if widget.name == w.widget:
add_linked(node, widget)