| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- extends GraphNode
- @export var min_gap: float = 0.5 # editable value in inspector for the minimum gap between min and max
- var undo_redo: UndoRedo
- var button_states = {}
- signal open_help
- signal inlet_removed
- signal node_moved
- func _ready() -> void:
- var sliders := _get_all_hsliders(self) #finds all sliders
- #links sliders to this script
- for slider in sliders:
- slider.value_changed.connect(_on_slider_value_changed.bind(slider))
-
- #link all buttons for undo redo
- get_all_buttons()
- #add button to title bar
- var titlebar = self.get_titlebar_hbox()
-
- #add randomise button
- if sliders.size() > 0:
- var rnd_btn = Button.new()
- rnd_btn.text = "!"
- rnd_btn.tooltip_text = "Randomise Slider Values"
- rnd_btn.connect("pressed", Callable(self, "_randomise_sliders")) #pass key (process name) when button is pressed
- titlebar.add_child(rnd_btn)
-
- #add help button
- var btn = Button.new()
- btn.text = "?"
- btn.tooltip_text = "Open help for " + self.title
- btn.connect("pressed", Callable(self, "_open_help")) #pass key (process name) when button is pressed
- titlebar.add_child(btn)
- await get_tree().process_frame
- #reset_size()
-
- self.position_offset_changed.connect(_on_position_offset_changed)
-
- if self.has_node("addremoveinlets"):
- var addremove = self.get_node("addremoveinlets")
- addremove.add_inlet.connect(add_inlet_to_node)
- addremove.remove_inlet.connect(remove_inlet_from_node)
-
- func _get_all_hsliders(node: Node) -> Array:
- #moves through all children recusively to find nested sliders
- var result: Array = []
- for child in node.get_children():
- if child is HSlider:
- result.append(child)
- elif child.has_method("get_children"):
- result += _get_all_hsliders(child)
- return result
- func get_all_buttons() -> void:
- for child in get_children():
- if child is OptionButton:
- button_states[child] = child.selected
- child.item_selected.connect(button_changed.bind(child))
- elif child is CheckButton:
- button_states[child] = child.button_pressed
- child.toggled.connect(button_changed.bind(child))
-
- func _on_slider_value_changed(value: float, changed_slider: HSlider) -> void:
- #checks if the slider moved has min or max meta data
- var is_min = changed_slider.get_meta("min")
- var is_max = changed_slider.get_meta("max")
- var is_outputduration = false
-
- if changed_slider.has_meta("outputduration"):
- is_outputduration = changed_slider.get_meta("outputduration")
-
- #if not exits function
- if not is_min and not is_max:
- return
- var sliders := _get_all_hsliders(self)
- for other_slider in sliders:
- if other_slider == changed_slider:
- continue
-
- if is_min and other_slider.get_meta("max"):
- var max_value: float = other_slider.value
- if changed_slider.value > max_value - min_gap:
- changed_slider.value = max_value - min_gap
-
- elif is_max and other_slider.get_meta("min"):
- var min_value: float = other_slider.value
- if changed_slider.value < min_value + min_gap:
- changed_slider.value = min_value + min_gap
-
- #set output duration meta if this is the output duration slider
- if is_outputduration:
- set_meta("outputduration", value)
- func _open_help():
- open_help.emit(self.get_meta("command"), self.title)
- func add_inlet_to_node():
- #called when the + button is pressed on an addremoveinlets node in the graphnode
- var inlet_count = self.get_input_port_count()
- var child_count = self.get_child_count()
-
- #check if the number of children is less than the new inlet count
- if child_count < inlet_count + 1:
- #if so add a new control node for the inlet to connect to
- var control = Control.new()
- control.custom_minimum_size.y = 57
- #give it this meta so it can be found and removed later if needed
- control.set_meta("dummynode", true)
- add_child(control)
- #move the ui for adding/removing inlets to the bottom of the node
- move_child(get_node("addremoveinlets"), get_child_count() - 1)
-
- #add the inlet using the same parameters as the first inlet
- set_slot(inlet_count, true, get_input_port_type(0), get_input_port_color(0), false, 0, get_input_port_color(0))
-
- func remove_inlet_from_node():
- var inlet_count = self.get_input_port_count()
- var child_count = self.get_child_count()
-
- #emit a signal to the graphedit script to remove any connections to this inlet
- inlet_removed.emit(self.get_name(), inlet_count - 1)
- #remove the inlet note inlet idx starts at 0 hence inlet_count -1
- set_slot(inlet_count - 1, false, get_input_port_type(0), get_input_port_color(0), false, 0, get_input_port_color(0))
-
- #check if a dummy control node has been added to make this inlet -2 because bottom node is the ui for adding removing inlets and idx starts at 0
- if get_child(child_count - 2).has_meta("dummynode"):
- #remove the dummy node
- get_child(child_count - 2).queue_free()
- #wait a frame for it to be removed
- await get_tree().process_frame
- #update the size of the graphnode to shrink to fit smaller ui
- update_minimum_size()
- size.y = get_combined_minimum_size().y
- func _on_position_offset_changed():
- node_moved.emit(self, Rect2(position, size))
-
-
- func _randomise_sliders():
- undo_redo.create_action("Randomise Sliders")
- var sliders := _get_all_hsliders(self) #finds all sliders
- #links sliders to this script
- for slider in sliders:
- var minimum = slider.min_value
- var maximum = slider.max_value
- var expo = slider.exp_edit
-
- var rnd = randf()
- var rnd_value
- if expo:
- rnd_value = minimum * pow(maximum / minimum, rnd)
- else:
- rnd_value = (rnd * (maximum - minimum)) + minimum
-
-
- undo_redo.add_do_method(set_slider_value.bind(slider, rnd_value))
- undo_redo.add_undo_method(set_slider_value.bind(slider, slider.value))
-
- undo_redo.commit_action()
- func set_slider_value(slider: HSlider, value: float) -> void:
- slider.value = value
- func button_changed(value, button) -> void:
- if button_states[button] != value:
- undo_redo.create_action("Change Button Value")
- undo_redo.add_do_method(set_button_value.bind(value, button))
- undo_redo.add_undo_method(set_button_value.bind(button_states[button], button))
- undo_redo.commit_action()
-
- func set_button_value(value, button) -> void:
- if button is OptionButton:
- button.selected = value
- elif button is CheckButton:
- button.set_pressed_no_signal(value)
-
- button_states[button] = value
|