Jonathan Higgins 7 месяцев назад
Родитель
Сommit
141d1bc454

+ 84 - 0
scenes/Nodes/breakfilemaker.gd

@@ -0,0 +1,84 @@
+extends Control
+
+const FIXED_POINT_COUNT := 2
+
+var points := []        # Stores Vector2 points
+var point_size := 10
+var dragged_point_index := -1
+signal automation_updated(values: Array)
+
+
+func _ready():
+	set_process_unhandled_input(true)
+	# these two are fixed: only Y-movable, not deletable
+	var window = get_window().size
+	points.append(Vector2(0, (window.y / 2) - 22))
+	points.append(Vector2(window.x, (window.y / 2) - 22))
+	
+
+func _unhandled_input(event):
+	var pos = get_local_mouse_position()
+
+	if event is InputEventMouseButton:
+		# --- double-click: delete only if not fixed, otherwise add new --
+		if event.button_index == MOUSE_BUTTON_LEFT and event.double_click:
+			var idx = get_point_at_pos(pos)
+			if idx >= FIXED_POINT_COUNT:
+				points.remove_at(idx)
+			elif idx == -1:
+				points.append(pos)
+			queue_redraw()
+
+		# --- begin drag on press ---
+		elif event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
+			dragged_point_index = get_point_at_pos(pos)
+
+		# --- end drag on release ---
+		elif event.button_index == MOUSE_BUTTON_LEFT and not event.pressed:
+			dragged_point_index = -1
+
+	elif event is InputEventMouseMotion and dragged_point_index != -1:
+		# if it’s one of the first two, constrain to Y only:
+		if dragged_point_index < FIXED_POINT_COUNT:
+			points[dragged_point_index].y = clamp(pos.y, 0, get_window().size.y -45)
+		else:
+			points[dragged_point_index].x = clamp(pos.x, 0, get_window().size.x)
+			points[dragged_point_index].y = clamp(pos.y, 0, get_window().size.y - 45)
+		queue_redraw()
+
+func _draw():
+	var sorted = []
+	sorted = points.duplicate()
+	sorted.sort_custom(sort_points)
+	for i in range(points.size() - 1):
+		draw_dashed_line(sorted[i], sorted[i + 1], Color(0.1, 0.1, 0.1, 0.6), 2.0, 6.0, true, true)
+	
+	for point in points:
+		draw_rect(Rect2(point.x - (point_size / 2), point.y - (point_size / 2), point_size, point_size), Color(0.1, 0.1, 0.1, 0.8))
+
+
+func sort_points(a, b):
+	return a.x < b.x
+
+func get_point_at_pos(pos: Vector2) -> int:
+	# find any point within radius + padding
+	for i in range(points.size()):
+		if points[i].distance_to(pos) <= point_size + 2:
+			return i
+	return -1
+	
+func emit_automation_data():
+	emit_signal("automation_updated", points)
+
+
+func _on_save_automation_button_down() -> void:
+	emit_automation_data()
+
+func read_automation(stored_points: Array):
+	points = stored_points.duplicate()
+
+func reset_automation():
+	points = []
+	var window = get_window().size
+	points.append(Vector2(0, (window.y / 2) - 22))
+	points.append(Vector2(window.x, (window.y / 2) - 22))

+ 1 - 0
scenes/Nodes/breakfilemaker.gd.uid

@@ -0,0 +1 @@
+uid://duykdpsfmfw38

+ 12 - 0
scenes/Nodes/breakfilemaker.tscn

@@ -0,0 +1,12 @@
+[gd_scene load_steps=2 format=3 uid="uid://bbdiosx6cdim0"]
+
+[ext_resource type="Script" uid="uid://duykdpsfmfw38" path="res://scenes/Nodes/breakfilemaker.gd" id="1_wgmi6"]
+
+[node name="Control" type="Control"]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("1_wgmi6")

Разница между файлами не показана из-за своего большого размера
+ 463 - 0
scenes/Nodes/nodes.tscn


+ 50 - 8
scenes/Nodes/valueslider.gd

@@ -1,10 +1,15 @@
 extends VBoxContainer
 
+@onready var window := $BreakFileMaker
+@onready var editor := window.get_node("AutomationEditor")
+
 
 #Called when the node enters the scene tree for the first time.
 func _ready() -> void:
 	#$HSplitContainer/ValueLabel.text = str($HSplitContainer/HSlider.value) # initial value
 	$HSplitContainer/LineEdit.text = str($HSplitContainer/HSlider.value) # initial value
+	$BreakFileMaker.hide()
+	editor.connect("automation_updated", Callable(self, "_on_automation_data_received"))
 
 
 func _on_h_slider_value_changed(value: float) -> void:
@@ -43,11 +48,48 @@ func _on_line_edit_focus_exited() -> void:
 		
 
 
-#func _on_h_slider_gui_input(event: InputEvent) -> void:
-	#if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_RIGHT and event.pressed and $HSplitContainer/HSlider.has_meta("brk"):
-		#var local_pos = to_local(get_global_mouse_position())
-		## Show popup at global mouse position
-		#$HSplitContainer/HSlider/PopupMenu.popup()
-		#$HSplitContainer/HSlider/PopupMenu.set_position(get_viewport().get_mouse_position())
-		## Prevent default context menu or input propagation if needed
-		#accept_event()
+func _on_h_slider_gui_input(event: InputEvent) -> void:
+	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_RIGHT and event.pressed and $HSplitContainer/HSlider.has_meta("brk"):
+		var local_pos = DisplayServer.mouse_get_position()
+		# Show popup at global mouse position
+		$HSplitContainer/HSlider/PopupMenu.popup()
+		$HSplitContainer/HSlider/PopupMenu.set_position(local_pos)
+		# Prevent default context menu or input propagation if needed
+		accept_event()
+
+
+func _on_popup_menu_index_pressed(index: int) -> void:
+	match index:
+		0:
+			$BreakFileMaker.position = DisplayServer.mouse_get_position()
+			$BreakFileMaker.show()
+			if $HSplitContainer/HSlider.has_meta("brk_data"):
+				$BreakFileMaker/AutomationEditor.read_automation($HSplitContainer/HSlider.get_meta("brk_data"))
+				
+		1:
+			$HSplitContainer/HSlider.set_meta("brk_data", null)
+			$BreakFileMaker/AutomationEditor.reset_automation()
+			$HSplitContainer/HSlider.editable = true
+			$HSplitContainer/HSlider/PopupMenu.set_item_text(0, "Add Automation")
+			$HSplitContainer/HSlider/PopupMenu.remove_item(1)
+
+func _on_automation_data_received(data):
+	$HSplitContainer/HSlider.set_meta("brk_data", data)
+	print($HSplitContainer/HSlider.get_meta("brk_data"))
+	$HSplitContainer/HSlider.editable = false
+	$HSplitContainer/HSlider/PopupMenu.set_item_text(0, "Edit Automation")
+	if $HSplitContainer/HSlider/PopupMenu.get_item_count() <= 1:
+		$HSplitContainer/HSlider/PopupMenu.add_item("Remove Automation", 1)
+
+
+
+func _on_save_automation_button_down() -> void:
+	$BreakFileMaker.hide()
+
+
+func _on_save_automation_2_button_down() -> void:
+	$BreakFileMaker.hide()
+
+
+func _on_break_file_maker_close_requested() -> void:
+	$BreakFileMaker.hide()

+ 54 - 4
scenes/Nodes/valueslider.tscn

@@ -1,11 +1,12 @@
-[gd_scene load_steps=2 format=3 uid="uid://dya5kxx132fgp"]
+[gd_scene load_steps=3 format=3 uid="uid://dya5kxx132fgp"]
 
 [ext_resource type="Script" uid="uid://bco7hof3wqck4" path="res://scenes/Nodes/valueslider.gd" id="1_4kxw6"]
+[ext_resource type="Script" uid="uid://duykdpsfmfw38" path="res://scenes/Nodes/breakfilemaker.gd" id="2_6ltu5"]
 
 [node name="VBoxContainer" type="VBoxContainer"]
 custom_minimum_size = Vector2(270, 0)
-offset_right = 40.0
-offset_bottom = 40.0
+offset_right = 270.0
+offset_bottom = 57.0
 script = ExtResource("1_4kxw6")
 
 [node name="Label" type="Label" parent="."]
@@ -26,7 +27,7 @@ value = 10.0
 [node name="PopupMenu" type="PopupMenu" parent="HSplitContainer/HSlider"]
 size = Vector2i(200, 100)
 item_count = 1
-item_0/text = "Automation Settings"
+item_0/text = "Add Automation Settings"
 item_0/id = 0
 
 [node name="LineEdit" type="LineEdit" parent="HSplitContainer"]
@@ -40,7 +41,56 @@ flat = true
 layout_mode = 2
 theme_override_constants/margin_bottom = 3
 
+[node name="BreakFileMaker" type="Window" parent="."]
+title = "Add Automation"
+position = Vector2i(340, 210)
+size = Vector2i(700, 300)
+visible = false
+exclusive = true
+unresizable = true
+
+[node name="Label" type="Label" parent="BreakFileMaker"]
+offset_left = 319.0
+offset_top = 255.0
+offset_right = 693.0
+offset_bottom = 300.0
+text = "Double click to add/remove automation"
+horizontal_alignment = 2
+vertical_alignment = 1
+
+[node name="ColorRect" type="ColorRect" parent="BreakFileMaker"]
+offset_left = -20.0
+offset_top = 255.0
+offset_right = 716.0
+offset_bottom = 300.0
+mouse_filter = 2
+color = Color(0.101961, 0.101961, 0.101961, 0.329412)
+
+[node name="AutomationEditor" type="Control" parent="BreakFileMaker"]
+layout_mode = 3
+anchors_preset = 0
+script = ExtResource("2_6ltu5")
+
+[node name="SaveAutomationButton" type="Button" parent="BreakFileMaker/AutomationEditor"]
+offset_left = 7.0
+offset_top = 262.0
+offset_right = 152.0
+offset_bottom = 295.0
+text = "Save Automation"
+
+[node name="CancelButton" type="Button" parent="BreakFileMaker/AutomationEditor"]
+offset_left = 159.0
+offset_top = 262.0
+offset_right = 304.0
+offset_bottom = 295.0
+text = "Cancel"
+
 [connection signal="gui_input" from="HSplitContainer/HSlider" to="." method="_on_h_slider_gui_input"]
 [connection signal="value_changed" from="HSplitContainer/HSlider" to="." method="_on_h_slider_value_changed"]
+[connection signal="index_pressed" from="HSplitContainer/HSlider/PopupMenu" to="." method="_on_popup_menu_index_pressed"]
 [connection signal="focus_exited" from="HSplitContainer/LineEdit" to="." method="_on_line_edit_focus_exited"]
 [connection signal="text_submitted" from="HSplitContainer/LineEdit" to="." method="_on_line_edit_text_submitted"]
+[connection signal="close_requested" from="BreakFileMaker" to="." method="_on_break_file_maker_close_requested"]
+[connection signal="button_down" from="BreakFileMaker/AutomationEditor/SaveAutomationButton" to="." method="_on_save_automation_button_down"]
+[connection signal="button_down" from="BreakFileMaker/AutomationEditor/SaveAutomationButton" to="BreakFileMaker/AutomationEditor" method="_on_save_automation_button_down"]
+[connection signal="button_down" from="BreakFileMaker/AutomationEditor/CancelButton" to="." method="_on_save_automation_2_button_down"]

+ 49 - 5
scenes/main/control.gd

@@ -939,11 +939,16 @@ func _get_slider_values_ordered(node: Node) -> Array:
 		if child is Range:
 			var flag = child.get_meta("flag") if child.has_meta("flag") else ""
 			var time
+			var brk_data = []
+			var min_slider = child.min_value
+			var max_slider = child.max_value
 			if child.has_meta("time"):
 				time = child.get_meta("time")
 			else:
 				time = false
-			results.append([flag, child.value, time])
+			if child.has_meta("brk_data"):
+				brk_data = child.get_meta("brk_data")
+			results.append([flag, child.value, time, brk_data, min_slider, max_slider])
 		elif child.get_child_count() > 0:
 			var nested := _get_slider_values_ordered(child)
 			results.append_array(nested)
@@ -966,18 +971,57 @@ func make_process(node: Node, process_count: int, current_infile: String, slider
 	var line = "%s/%s \"%s\" \"%s\" " % [cdpprogs_location, command_name, current_infile, output_file]
 
 	# Append parameter values from the sliders, include flags if present
+	var slider_count = 0
 	for entry in slider_data:
 		var flag = entry[0]
 		var value = entry[1]
 		var time = entry[2] #checks if slider is a time percentage slider
-		if time == true:
+		var brk_data = entry[3]
+		var min_slider = entry[4]
+		var max_slider = entry[5]
+		if brk_data.size() > 0: #if breakpoint data is present on slider
+			#Sort all points by time
+			var sorted_brk_data = []
+			sorted_brk_data = brk_data.duplicate()
+			sorted_brk_data.sort_custom(sort_points)
+			
+			var calculated_brk = []
+			
+			#get length of input file in seconds
 			var infile_length = run_command(cdpprogs_location + "/sfprops -d " + "\"%s\"" % current_infile)
 			infile_length = float(infile_length[0].strip_edges())
-			value = infile_length * (value / 100) #calculate percentage time of the input file
-		line += ("%s%.2f " % [flag, value]) if flag.begins_with("-") else ("%.2f " % value)
-	
+			
+			#scale values from automation window to the right length for file and correct slider values
+			for point in sorted_brk_data:
+				var new_x = infile_length * (point.x / 700)
+				var new_y = remap(point.y, 255, 0, min_slider, max_slider)
+				calculated_brk.append(Vector2(new_x, new_y))
+			
+			write_breakfile(calculated_brk, output_file.get_basename() + "_" + slider_count + ".txt")
+			
+		else:
+			if time == true:
+				var infile_length = run_command(cdpprogs_location + "/sfprops -d " + "\"%s\"" % current_infile)
+				infile_length = float(infile_length[0].strip_edges())
+				value = infile_length * (value / 100) #calculate percentage time of the input file
+			line += ("%s%.2f " % [flag, value]) if flag.begins_with("-") else ("%.2f " % value)
+		
+		slider_count += 1
 	return [line.strip_edges(), output_file]
 
+func sort_points(a, b):
+	return a.x < b.x
+	
+func write_breakfile(points: Array, path: String):
+	var file = FileAccess.open(path, FileAccess.WRITE)
+	if file:
+		for point in points:
+			var line = str(point.x) + " " + str(point.y) + "\n"
+			file.store_string(line)
+		file.close()
+	else:
+		print("Failed to open file for writing.")
+
 func run_command(command: String) -> Array:
 	var is_windows = OS.get_name() == "Windows"
 

+ 4 - 1
theme/main_theme.tres

@@ -1,4 +1,4 @@
-[gd_resource type="Theme" load_steps=54 format=3 uid="uid://cefwkdcoxihro"]
+[gd_resource type="Theme" load_steps=55 format=3 uid="uid://cefwkdcoxihro"]
 
 [ext_resource type="Texture2D" uid="uid://b4o8vm5o4uptk" path="res://theme/images/toggle_checked.png" id="1_cibxr"]
 [ext_resource type="Texture2D" uid="uid://d0dubcywvqtkw" path="res://theme/images/toggle_unchecked.png" id="2_adhqp"]
@@ -239,6 +239,8 @@ expand_margin_top = 2.0
 expand_margin_right = 2.0
 expand_margin_bottom = 2.0
 
+[sub_resource type="ImageTexture" id="ImageTexture_ftk8o"]
+
 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_2u8nx"]
 content_margin_left = 4.0
 content_margin_top = 4.0
@@ -459,6 +461,7 @@ HScrollBar/styles/grabber_pressed = SubResource("StyleBoxFlat_m8g5i")
 HScrollBar/styles/scroll = SubResource("StyleBoxFlat_a7tdx")
 HScrollBar/styles/scroll_focus = SubResource("StyleBoxFlat_6sc48")
 HSlider/icons/grabber = ExtResource("4_m8g5i")
+HSlider/icons/grabber_disabled = SubResource("ImageTexture_ftk8o")
 HSlider/icons/grabber_highlight = ExtResource("5_a7tdx")
 HSlider/styles/grabber_area = SubResource("StyleBoxFlat_2u8nx")
 HSlider/styles/grabber_area_highlight = SubResource("StyleBoxFlat_nxip8")

Некоторые файлы не были показаны из-за большого количества измененных файлов