فهرست منبع

Merge pull request #61 from j-p-higgins/CDP-OS.execute_with_pipe

Cdp os.execute with pipe
Jonathan Higgins 7 ماه پیش
والد
کامیت
a0f4a154cd
6فایلهای تغییر یافته به همراه258 افزوده شده و 99 حذف شده
  1. 1 0
      config_handler.gd
  2. 159 85
      scenes/main/control.gd
  3. 50 10
      scenes/main/control.tscn
  4. 5 0
      scenes/main/settings.gd
  5. 15 3
      scenes/main/settings.tscn
  6. 28 1
      theme/main_theme.tres

+ 1 - 0
config_handler.gd

@@ -12,6 +12,7 @@ func _ready():
 	# Set defaults only if not present
 	# Set defaults only if not present
 	ensure_setting("cdpprogs", "location", "no_location")
 	ensure_setting("cdpprogs", "location", "no_location")
 	ensure_setting("interface_settings", "disable_pvoc_warning", false)
 	ensure_setting("interface_settings", "disable_pvoc_warning", false)
+	ensure_setting("interface_settings", "disable_progress_bar", false)
 	ensure_setting("interface_settings", "auto_close_console", false)
 	ensure_setting("interface_settings", "auto_close_console", false)
 	ensure_setting("interface_settings", "console_on_top", true)
 	ensure_setting("interface_settings", "console_on_top", true)
 	ensure_setting("interface_settings", "theme", 0)
 	ensure_setting("interface_settings", "theme", 0)

+ 159 - 85
scenes/main/control.gd

@@ -25,6 +25,9 @@ var process_successful #tracks if the last run process was successful
 var help_data := {} #stores help data for each node to display in help popup
 var help_data := {} #stores help data for each node to display in help popup
 var HelpWindowScene = preload("res://scenes/main/help_window.tscn")
 var HelpWindowScene = preload("res://scenes/main/help_window.tscn")
 var uiscale = 1.0 #tracks scaling for retina screens
 var uiscale = 1.0 #tracks scaling for retina screens
+var process_info = {} #tracks the data of the currently running process
+var process_running := false #tracks if a process is currently running
+var process_cancelled = false #checks if the currently running process has been cancelled
 
 
 # Called when the node enters the scene tree for the first time.
 # Called when the node enters the scene tree for the first time.
 func _ready() -> void:
 func _ready() -> void:
@@ -41,6 +44,7 @@ func _ready() -> void:
 	$AudioDevicePopup.hide()
 	$AudioDevicePopup.hide()
 	$SearchMenu.hide()
 	$SearchMenu.hide()
 	$Settings.hide()
 	$Settings.hide()
+	$ProgressWindow.hide()
 	
 	
 	$SaveDialog.access = FileDialog.ACCESS_FILESYSTEM
 	$SaveDialog.access = FileDialog.ACCESS_FILESYSTEM
 	$SaveDialog.file_mode = FileDialog.FILE_MODE_SAVE_FILE
 	$SaveDialog.file_mode = FileDialog.FILE_MODE_SAVE_FILE
@@ -644,12 +648,16 @@ func _run_process() -> void:
 func _on_file_dialog_dir_selected(dir: String) -> void:
 func _on_file_dialog_dir_selected(dir: String) -> void:
 	lastoutputfolder = dir
 	lastoutputfolder = dir
 	console_output.clear()
 	console_output.clear()
-	if $Console.is_visible():
-		$Console.hide()
-		await get_tree().process_frame  # Wait a frame to allow hide to complete
-		$Console.popup_centered()
+	var interface_settings = ConfigHandler.load_interface_settings()
+	if interface_settings.disable_progress_bar == false:
+		$ProgressWindow.show()
 	else:
 	else:
-		$Console.popup_centered()
+		if $Console.is_visible():
+			$Console.hide()
+			await get_tree().process_frame  # Wait a frame to allow hide to complete
+			$Console.popup_centered()
+		else:
+			$Console.popup_centered()
 	await get_tree().process_frame
 	await get_tree().process_frame
 	log_console("Generating processing queue", true)
 	log_console("Generating processing queue", true)
 	await get_tree().process_frame
 	await get_tree().process_frame
@@ -668,6 +676,8 @@ func _on_file_dialog_dir_selected(dir: String) -> void:
 	run_thread_with_branches()
 	run_thread_with_branches()
 	
 	
 func run_thread_with_branches():
 func run_thread_with_branches():
+	process_cancelled = false
+	process_successful = true
 	# Detect platform: Determine if the OS is Windows
 	# Detect platform: Determine if the OS is Windows
 	var is_windows := OS.get_name() == "Windows"
 	var is_windows := OS.get_name() == "Windows"
 	
 	
@@ -708,8 +718,21 @@ func run_thread_with_branches():
 				graph[name] = []
 				graph[name] = []
 				reverse_graph[name] = []
 				reverse_graph[name] = []
 				indegree[name] = 0  # Start with zero incoming edges
 				indegree[name] = 0  # Start with zero incoming edges
+	#do calculations for progress bar
+	var progress_step
+	if Global.trim_infile == true:
+		progress_step = 100 / (graph.size() + 4)
+	else:
+		progress_step = 100 / (graph.size() + 3)
+	
 
 
 	# Step 2: Build graph relationships from connections
 	# Step 2: Build graph relationships from connections
+	if process_cancelled:
+		$ProgressWindow/ProgressLabel.text = "Thread Stopped"
+		log_console("[b]Thread Stopped[/b]", true)
+		return
+	else:
+		$ProgressWindow/ProgressLabel.text = "Building Thread"
 	for conn in connections:
 	for conn in connections:
 		var from = str(conn["from_node"])
 		var from = str(conn["from_node"])
 		var to = str(conn["to_node"])
 		var to = str(conn["to_node"])
@@ -739,7 +762,7 @@ func run_thread_with_branches():
 		log_console("[color=#9c2828][b]Error: Thread not valid[/b][/color]", true)
 		log_console("[color=#9c2828][b]Error: Thread not valid[/b][/color]", true)
 		log_console("Threads cannot contain loops.", true)
 		log_console("Threads cannot contain loops.", true)
 		return
 		return
-
+	$ProgressWindow/ProgressBar.value = progress_step
 	# Step 4: Start processing audio
 	# Step 4: Start processing audio
 	var batch_lines = []        # Holds all batch file commands
 	var batch_lines = []        # Holds all batch file commands
 	var intermediate_files = [] # Files to delete later
 	var intermediate_files = [] # Files to delete later
@@ -752,20 +775,32 @@ func run_thread_with_branches():
 	# Start with the original input file
 	# Start with the original input file
 	var starting_infile = Global.infile
 	var starting_infile = Global.infile
 	
 	
+	
 	#If trim is enabled trim input audio
 	#If trim is enabled trim input audio
 	if Global.trim_infile == true:
 	if Global.trim_infile == true:
-		run_command(cdpprogs_location + "/sfedit", ["cut", "1", starting_infile, "%s_trimmed.wav" % Global.outfile, str(Global.infile_start), str(Global.infile_stop)])
+		if process_cancelled:
+			$ProgressWindow/ProgressLabel.text = "Thread Stopped"
+			log_console("[b]Thread Stopped[/b]", true)
+			return
+		else:
+			$ProgressWindow/ProgressLabel.text = "Trimming input audio"
+		await run_command(cdpprogs_location + "/sfedit", ["cut", "1", starting_infile, "%s_trimmed.wav" % Global.outfile, str(Global.infile_start), str(Global.infile_stop)])
 		starting_infile = Global.outfile + "_trimmed.wav"
 		starting_infile = Global.outfile + "_trimmed.wav"
 		# Mark trimmed file for cleanup if needed
 		# Mark trimmed file for cleanup if needed
 		if delete_intermediate_outputs:
 		if delete_intermediate_outputs:
 			intermediate_files.append(Global.outfile + "_trimmed.wav")
 			intermediate_files.append(Global.outfile + "_trimmed.wav")
-			
+		$ProgressWindow/ProgressBar.value += progress_step
 	var current_infile = starting_infile
 	var current_infile = starting_infile
 
 
 	# Iterate over the processing nodes in topological order
 	# Iterate over the processing nodes in topological order
 	for node_name in sorted:
 	for node_name in sorted:
 		var node = all_nodes[node_name]
 		var node = all_nodes[node_name]
-		
+		if process_cancelled:
+			$ProgressWindow/ProgressLabel.text = "Thread Stopped"
+			log_console("[b]Thread Stopped[/b]", true)
+			break
+		else:
+			$ProgressWindow/ProgressLabel.text = "Running process: " + node.get_title()
 		# Find upstream nodes connected to the current node
 		# Find upstream nodes connected to the current node
 		var inputs = reverse_graph[node_name]
 		var inputs = reverse_graph[node_name]
 		var input_files = []
 		var input_files = []
@@ -775,7 +810,7 @@ func run_thread_with_branches():
 		# Merge inputs if this node has more than one input
 		# Merge inputs if this node has more than one input
 		if input_files.size() > 1:
 		if input_files.size() > 1:
 			# Prepare final merge output file name
 			# Prepare final merge output file name
-			var runmerge = merge_many_files(process_count, input_files)
+			var runmerge = await merge_many_files(process_count, input_files)
 			var merge_output = runmerge[0]
 			var merge_output = runmerge[0]
 			var converted_files = runmerge[1]
 			var converted_files = runmerge[1]
 
 
@@ -805,9 +840,9 @@ func run_thread_with_branches():
 				var pvoc_stereo_files = []
 				var pvoc_stereo_files = []
 				
 				
 				for infile in current_infile:
 				for infile in current_infile:
-					var makeprocess = make_process(node, process_count, infile, slider_data)
+					var makeprocess = await make_process(node, process_count, infile, slider_data)
 					# run the command
 					# run the command
-					run_command(makeprocess[0], makeprocess[3])
+					await run_command(makeprocess[0], makeprocess[3])
 					await get_tree().process_frame
 					await get_tree().process_frame
 					var output_file = makeprocess[1]
 					var output_file = makeprocess[1]
 					pvoc_stereo_files.append(output_file)
 					pvoc_stereo_files.append(output_file)
@@ -822,20 +857,20 @@ func run_thread_with_branches():
 					
 					
 				output_files[node_name] = pvoc_stereo_files
 				output_files[node_name] = pvoc_stereo_files
 			else:
 			else:
-				var input_stereo = is_stereo(current_infile)
+				var input_stereo = await is_stereo(current_infile)
 				if input_stereo == true: 
 				if input_stereo == true: 
 					#audio file is stereo and needs to be split for pvoc processing
 					#audio file is stereo and needs to be split for pvoc processing
 					var pvoc_stereo_files = []
 					var pvoc_stereo_files = []
 					##Split stereo to c1/c2
 					##Split stereo to c1/c2
-					run_command(cdpprogs_location + "/housekeep",["chans", "2", current_infile])
+					await run_command(cdpprogs_location + "/housekeep",["chans", "2", current_infile])
 			
 			
 					# Process left and right seperately
 					# Process left and right seperately
 					for channel in ["c1", "c2"]:
 					for channel in ["c1", "c2"]:
 						var dual_mono_file = current_infile.get_basename() + "_%s.wav" % channel
 						var dual_mono_file = current_infile.get_basename() + "_%s.wav" % channel
 						
 						
-						var makeprocess = make_process(node, process_count, dual_mono_file, slider_data)
+						var makeprocess = await make_process(node, process_count, dual_mono_file, slider_data)
 						# run the command
 						# run the command
-						run_command(makeprocess[0], makeprocess[3])
+						await run_command(makeprocess[0], makeprocess[3])
 						await get_tree().process_frame
 						await get_tree().process_frame
 						var output_file = makeprocess[1]
 						var output_file = makeprocess[1]
 						pvoc_stereo_files.append(output_file)
 						pvoc_stereo_files.append(output_file)
@@ -850,16 +885,16 @@ func run_thread_with_branches():
 						#with this stereo process CDP will throw errors in the console even though its fine
 						#with this stereo process CDP will throw errors in the console even though its fine
 						if is_windows:
 						if is_windows:
 							dual_mono_file = dual_mono_file.replace("/", "\\")
 							dual_mono_file = dual_mono_file.replace("/", "\\")
-						run_command(delete_cmd, [dual_mono_file])
+						await run_command(delete_cmd, [dual_mono_file])
 						process_count += 1
 						process_count += 1
 						
 						
 						# Store output file path for this node
 						# Store output file path for this node
 					output_files[node_name] = pvoc_stereo_files
 					output_files[node_name] = pvoc_stereo_files
 				else: 
 				else: 
 					#input file is mono run through process
 					#input file is mono run through process
-					var makeprocess = make_process(node, process_count, current_infile, slider_data)
+					var makeprocess = await make_process(node, process_count, current_infile, slider_data)
 					# run the command
 					# run the command
-					run_command(makeprocess[0], makeprocess[3])
+					await run_command(makeprocess[0], makeprocess[3])
 					await get_tree().process_frame
 					await get_tree().process_frame
 					var output_file = makeprocess[1]
 					var output_file = makeprocess[1]
 
 
@@ -885,9 +920,9 @@ func run_thread_with_branches():
 				var pvoc_stereo_files = []
 				var pvoc_stereo_files = []
 				
 				
 				for infile in current_infile:
 				for infile in current_infile:
-					var makeprocess = make_process(node, process_count, infile, slider_data)
+					var makeprocess = await make_process(node, process_count, infile, slider_data)
 					# run the command
 					# run the command
-					run_command(makeprocess[0], makeprocess[3])
+					await run_command(makeprocess[0], makeprocess[3])
 					await get_tree().process_frame
 					await get_tree().process_frame
 					var output_file = makeprocess[1]
 					var output_file = makeprocess[1]
 					pvoc_stereo_files.append(output_file)
 					pvoc_stereo_files.append(output_file)
@@ -903,7 +938,7 @@ func run_thread_with_branches():
 					
 					
 				#interleave left and right
 				#interleave left and right
 				var output_file = Global.outfile.get_basename() + str(process_count) + "_interleaved.wav"
 				var output_file = Global.outfile.get_basename() + str(process_count) + "_interleaved.wav"
-				run_command(cdpprogs_location + "/submix", ["interleave", pvoc_stereo_files[0], pvoc_stereo_files[1], output_file])
+				await run_command(cdpprogs_location + "/submix", ["interleave", pvoc_stereo_files[0], pvoc_stereo_files[1], output_file])
 				# Store output file path for this node
 				# Store output file path for this node
 				output_files[node_name] = output_file
 				output_files[node_name] = output_file
 				
 				
@@ -913,12 +948,12 @@ func run_thread_with_branches():
 
 
 			else:
 			else:
 				#Detect if input file is mono or stereo
 				#Detect if input file is mono or stereo
-				var input_stereo = is_stereo(current_infile)
+				var input_stereo = await is_stereo(current_infile)
 				if input_stereo == true:
 				if input_stereo == true:
 					if node.get_meta("stereo_input") == true: #audio file is stereo and process is stereo, run file through process
 					if node.get_meta("stereo_input") == true: #audio file is stereo and process is stereo, run file through process
-						var makeprocess = make_process(node, process_count, current_infile, slider_data)
+						var makeprocess = await make_process(node, process_count, current_infile, slider_data)
 						# run the command
 						# run the command
-						run_command(makeprocess[0], makeprocess[3])
+						await run_command(makeprocess[0], makeprocess[3])
 						await get_tree().process_frame
 						await get_tree().process_frame
 						var output_file = makeprocess[1]
 						var output_file = makeprocess[1]
 						
 						
@@ -933,16 +968,16 @@ func run_thread_with_branches():
 
 
 					else: #audio file is stereo and process is mono, split stereo, process and recombine
 					else: #audio file is stereo and process is mono, split stereo, process and recombine
 						##Split stereo to c1/c2
 						##Split stereo to c1/c2
-						run_command(cdpprogs_location + "/housekeep",["chans", "2", current_infile])
+						await run_command(cdpprogs_location + "/housekeep",["chans", "2", current_infile])
 				
 				
 						# Process left and right seperately
 						# Process left and right seperately
 						var dual_mono_output = []
 						var dual_mono_output = []
 						for channel in ["c1", "c2"]:
 						for channel in ["c1", "c2"]:
 							var dual_mono_file = current_infile.get_basename() + "_%s.wav" % channel
 							var dual_mono_file = current_infile.get_basename() + "_%s.wav" % channel
 							
 							
-							var makeprocess = make_process(node, process_count, dual_mono_file, slider_data)
+							var makeprocess = await make_process(node, process_count, dual_mono_file, slider_data)
 							# run the command
 							# run the command
-							run_command(makeprocess[0], makeprocess[3])
+							await run_command(makeprocess[0], makeprocess[3])
 							await get_tree().process_frame
 							await get_tree().process_frame
 							var output_file = makeprocess[1]
 							var output_file = makeprocess[1]
 							dual_mono_output.append(output_file)
 							dual_mono_output.append(output_file)
@@ -957,12 +992,12 @@ func run_thread_with_branches():
 							#with this stereo process CDP will throw errors in the console even though its fine
 							#with this stereo process CDP will throw errors in the console even though its fine
 							if is_windows:
 							if is_windows:
 								dual_mono_file = dual_mono_file.replace("/", "\\")
 								dual_mono_file = dual_mono_file.replace("/", "\\")
-							run_command(delete_cmd, [dual_mono_file])
+							await run_command(delete_cmd, [dual_mono_file])
 							process_count += 1
 							process_count += 1
 						
 						
 						
 						
 						var output_file = Global.outfile.get_basename() + str(process_count) + "_interleaved.wav"
 						var output_file = Global.outfile.get_basename() + str(process_count) + "_interleaved.wav"
-						run_command(cdpprogs_location + "/submix", ["interleave", dual_mono_output[0], dual_mono_output[1], output_file])
+						await run_command(cdpprogs_location + "/submix", ["interleave", dual_mono_output[0], dual_mono_output[1], output_file])
 						
 						
 						# Store output file path for this node
 						# Store output file path for this node
 						output_files[node_name] = output_file
 						output_files[node_name] = output_file
@@ -972,9 +1007,9 @@ func run_thread_with_branches():
 							intermediate_files.append(output_file)
 							intermediate_files.append(output_file)
 
 
 				else: #audio file is mono, run through the process
 				else: #audio file is mono, run through the process
-					var makeprocess = make_process(node, process_count, current_infile, slider_data)
+					var makeprocess = await make_process(node, process_count, current_infile, slider_data)
 					# run the command
 					# run the command
-					run_command(makeprocess[0], makeprocess[3])
+					await run_command(makeprocess[0], makeprocess[3])
 					await get_tree().process_frame
 					await get_tree().process_frame
 					var output_file = makeprocess[1]
 					var output_file = makeprocess[1]
 					
 					
@@ -990,10 +1025,16 @@ func run_thread_with_branches():
 
 
 			# Increase the process step count
 			# Increase the process step count
 			process_count += 1
 			process_count += 1
-
+		$ProgressWindow/ProgressBar.value += progress_step
 	# FINAL OUTPUT STAGE
 	# FINAL OUTPUT STAGE
 
 
 	# Collect all nodes that are connected to the outputfile node
 	# Collect all nodes that are connected to the outputfile node
+	if process_cancelled:
+		$ProgressWindow/ProgressLabel.text = "Thread Stopped"
+		log_console("[b]Thread Stopped[/b]", true)
+		return
+	else:
+		$ProgressWindow/ProgressLabel.text = "Finalising output"
 	var output_inputs := []
 	var output_inputs := []
 	for conn in connections:
 	for conn in connections:
 		var to_node = str(conn["to_node"])
 		var to_node = str(conn["to_node"])
@@ -1008,7 +1049,7 @@ func run_thread_with_branches():
 
 
 	# If multiple outputs go to the outputfile node, merge them
 	# If multiple outputs go to the outputfile node, merge them
 	if final_outputs.size() > 1:
 	if final_outputs.size() > 1:
-		var runmerge = merge_many_files(process_count, final_outputs)
+		var runmerge = await merge_many_files(process_count, final_outputs)
 		final_output_dir = runmerge[0]
 		final_output_dir = runmerge[0]
 		var converted_files = runmerge[1]
 		var converted_files = runmerge[1]
 		
 		
@@ -1022,15 +1063,21 @@ func run_thread_with_branches():
 		var single_output = final_outputs[0]
 		var single_output = final_outputs[0]
 		final_output_dir = single_output
 		final_output_dir = single_output
 		intermediate_files.erase(single_output)
 		intermediate_files.erase(single_output)
-
+	$ProgressWindow/ProgressBar.value += progress_step
 	# CLEANUP: Delete intermediate files after processing and rename final output
 	# CLEANUP: Delete intermediate files after processing and rename final output
-	log_console("Cleaning up intermediate files.", true)
+	if process_cancelled:
+		$ProgressWindow/ProgressLabel.text = "Thread Stopped"
+		log_console("[b]Thread Stopped[/b]", true)
+		return
+	else:
+		log_console("Cleaning up intermediate files.", true)
+		$ProgressWindow/ProgressLabel.text = "Cleaning up"
 	for file_path in intermediate_files:
 	for file_path in intermediate_files:
 		# Adjust file path format for Windows if needed
 		# Adjust file path format for Windows if needed
 		var fixed_path = file_path
 		var fixed_path = file_path
 		if is_windows:
 		if is_windows:
 			fixed_path = fixed_path.replace("/", "\\")
 			fixed_path = fixed_path.replace("/", "\\")
-		run_command(delete_cmd, [fixed_path])
+		await run_command(delete_cmd, [fixed_path])
 		await get_tree().process_frame
 		await get_tree().process_frame
 	#delete break files 
 	#delete break files 
 	for file_path in breakfiles:
 	for file_path in breakfiles:
@@ -1038,29 +1085,30 @@ func run_thread_with_branches():
 		var fixed_path = file_path
 		var fixed_path = file_path
 		if is_windows:
 		if is_windows:
 			fixed_path = fixed_path.replace("/", "\\")
 			fixed_path = fixed_path.replace("/", "\\")
-		run_command(delete_cmd, [fixed_path])
+		await run_command(delete_cmd, [fixed_path])
 		await get_tree().process_frame
 		await get_tree().process_frame
 		
 		
 	var final_filename = "%s.wav" % Global.outfile
 	var final_filename = "%s.wav" % Global.outfile
 	var final_output_dir_fixed_path = final_output_dir
 	var final_output_dir_fixed_path = final_output_dir
 	if is_windows:
 	if is_windows:
 		final_output_dir_fixed_path = final_output_dir_fixed_path.replace("/", "\\")
 		final_output_dir_fixed_path = final_output_dir_fixed_path.replace("/", "\\")
-		run_command(rename_cmd, [final_output_dir_fixed_path, final_filename.get_file()])
+		await run_command(rename_cmd, [final_output_dir_fixed_path, final_filename.get_file()])
 	else:
 	else:
-		run_command(rename_cmd, [final_output_dir_fixed_path, "%s.wav" % Global.outfile])
+		await run_command(rename_cmd, [final_output_dir_fixed_path, "%s.wav" % Global.outfile])
 	final_output_dir = Global.outfile + ".wav"
 	final_output_dir = Global.outfile + ".wav"
 	
 	
 	output_audio_player.play_outfile(final_output_dir)
 	output_audio_player.play_outfile(final_output_dir)
 	outfile = final_output_dir
 	outfile = final_output_dir
-			
+	$ProgressWindow/ProgressBar.value = 100.0
 	var interface_settings = ConfigHandler.load_interface_settings() #checks if close console is enabled and closes console on a success
 	var interface_settings = ConfigHandler.load_interface_settings() #checks if close console is enabled and closes console on a success
+	$ProgressWindow.hide()
 	if interface_settings.auto_close_console and process_successful == true:
 	if interface_settings.auto_close_console and process_successful == true:
 		$Console.hide()
 		$Console.hide()
 
 
 
 
 func is_stereo(file: String) -> bool:
 func is_stereo(file: String) -> bool:
-	var output = run_command(cdpprogs_location + "/sfprops", ["-c", file])
-	output = int(output[0].strip_edges()) #convert output from cmd to clean int
+	var output = await run_command(cdpprogs_location + "/sfprops", ["-c", file])
+	output = int(output.strip_edges()) #convert output from cmd to clean int
 	if output == 1:
 	if output == 1:
 		return false
 		return false
 	elif output == 2:
 	elif output == 2:
@@ -1081,7 +1129,7 @@ func merge_many_files(process_count: int, input_files: Array) -> Array:
 
 
 	# STEP 1: Check each file's channel count
 	# STEP 1: Check each file's channel count
 	for f in input_files:
 	for f in input_files:
-		var stereo = is_stereo(f)
+		var stereo = await is_stereo(f)
 		if stereo == false:
 		if stereo == false:
 			mono_files.append(f)
 			mono_files.append(f)
 		elif stereo == true:
 		elif stereo == true:
@@ -1092,7 +1140,7 @@ func merge_many_files(process_count: int, input_files: Array) -> Array:
 	if mono_files.size() > 0 and stereo_files.size() > 0:
 	if mono_files.size() > 0 and stereo_files.size() > 0:
 		for mono_file in mono_files:
 		for mono_file in mono_files:
 			var stereo_file = "%s_stereo.wav" % mono_file.get_basename()
 			var stereo_file = "%s_stereo.wav" % mono_file.get_basename()
-			run_command(cdpprogs_location + "/submix", ["interleave", mono_file, mono_file, stereo_file])
+			await run_command(cdpprogs_location + "/submix", ["interleave", mono_file, mono_file, stereo_file])
 			if process_successful == false:
 			if process_successful == false:
 				log_console("Failed to interleave mono file: %s" % mono_file, true)
 				log_console("Failed to interleave mono file: %s" % mono_file, true)
 			else:
 			else:
@@ -1110,7 +1158,7 @@ func merge_many_files(process_count: int, input_files: Array) -> Array:
 		quoted_inputs.append(f)
 		quoted_inputs.append(f)
 	quoted_inputs.insert(0, "mergemany")
 	quoted_inputs.insert(0, "mergemany")
 	quoted_inputs.append(merge_output)
 	quoted_inputs.append(merge_output)
-	run_command(cdpprogs_location + "/submix", quoted_inputs)
+	await run_command(cdpprogs_location + "/submix", quoted_inputs)
 
 
 	if process_successful == false:
 	if process_successful == false:
 		log_console("Failed to to merge files to" + merge_output, true)
 		log_console("Failed to to merge files to" + merge_output, true)
@@ -1184,8 +1232,8 @@ func make_process(node: Node, process_count: int, current_infile: String, slider
 			var calculated_brk = []
 			var calculated_brk = []
 			
 			
 			#get length of input file in seconds
 			#get length of input file in seconds
-			var infile_length = run_command(cdpprogs_location + "/sfprops", ["-d", current_infile])
-			infile_length = float(infile_length[0].strip_edges())
+			var infile_length = await run_command(cdpprogs_location + "/sfprops", ["-d", current_infile])
+			infile_length = float(infile_length.strip_edges())
 			
 			
 			#scale values from automation window to the right length for file and correct slider values
 			#scale values from automation window to the right length for file and correct slider values
 			#need to check how time is handled in all files that accept it, zigzag is x = outfile position, y = infile position
 			#need to check how time is handled in all files that accept it, zigzag is x = outfile position, y = infile position
@@ -1214,8 +1262,8 @@ func make_process(node: Node, process_count: int, current_infile: String, slider
 			cleanup.append(brk_file_path)
 			cleanup.append(brk_file_path)
 		else:
 		else:
 			if time == true:
 			if time == true:
-				var infile_length = run_command(cdpprogs_location + "/sfprops", ["-d", current_infile])
-				infile_length = float(infile_length[0].strip_edges())
+				var infile_length = await run_command(cdpprogs_location + "/sfprops", ["-d", current_infile])
+				infile_length = float(infile_length.strip_edges())
 				value = infile_length * (value / 100) #calculate percentage time of the input file
 				value = infile_length * (value / 100) #calculate percentage time of the input file
 			line += ("%s%.2f " % [flag, value]) if flag.begins_with("-") else ("%.2f " % value)
 			line += ("%s%.2f " % [flag, value]) if flag.begins_with("-") else ("%.2f " % value)
 			args.append(("%s%.2f " % [flag, value]) if flag.begins_with("-") else ("%.2f " % value))
 			args.append(("%s%.2f " % [flag, value]) if flag.begins_with("-") else ("%.2f " % value))
@@ -1237,61 +1285,86 @@ func write_breakfile(points: Array, path: String):
 	else:
 	else:
 		print("Failed to open file for writing.")
 		print("Failed to open file for writing.")
 
 
-func run_command(command: String, args: Array) -> Array:
+func run_command(command: String, args: Array) -> String:
 	var is_windows = OS.get_name() == "Windows"
 	var is_windows = OS.get_name() == "Windows"
 
 
-	var output: Array = []
-	var error: Array = []
-
-	var exit_code := 0
+	console_output.append_text(command + " " + " ".join(args) + "\n")
+	console_output.scroll_to_line(console_output.get_line_count() - 1)
+	await get_tree().process_frame
+	
 	if is_windows:
 	if is_windows:
 		#exit_code = OS.execute("cmd.exe", ["/C", command], output, true, false)
 		#exit_code = OS.execute("cmd.exe", ["/C", command], output, true, false)
 		args.insert(0, command)
 		args.insert(0, command)
 		args.insert(0, "/C")
 		args.insert(0, "/C")
-		exit_code = OS.execute("cmd.exe", args, output, true, false)
+		process_info = OS.execute_with_pipe("cmd.exe", args, false)
 	else:
 	else:
-		exit_code = OS.execute(command, args, output, true, false)
-
-	var output_str := ""
-	for item in output:
-		output_str += item + "\n"
+		process_info = OS.execute_with_pipe(command, args, false)
+	# Check if the process was successfully started
+	if !process_info.has("pid"):
+		print("Failed to start process.")
+		return ""
+	
+	process_running = true
+	
+	# Start monitoring the process output and status
+	return await monitor_process(process_info["pid"], process_info["stdio"], process_info["stderr"])
 
 
-	var error_str := ""
-	for item in error:
-		error_str += item + "\n"
+func monitor_process(pid: int, stdout: FileAccess, stderr: FileAccess) -> String:
+	var output := ""
 	
 	
-	if is_windows:
-		args.remove_at(0)
-		console_output.append_text(" ".join(args) + "\n")
-	else:
-		console_output.append_text(command + " " + " ".join(args) + "\n")
-	console_output.scroll_to_line(console_output.get_line_count() - 1)
+	while OS.is_process_running(pid):
+		await get_tree().process_frame
+		
+		while stdout.get_position() < stdout.get_length():
+			var line = stdout.get_line()
+			output += line
+			console_output.append_text(line + "\n")
+			console_output.scroll_to_line(console_output.get_line_count() - 1)
+		while stderr.get_position() < stderr.get_length():
+			var line = stderr.get_line()
+			output += line
+			console_output.append_text(line + "\n")
+			console_output.scroll_to_line(console_output.get_line_count() - 1)
 	
 	
+	var exit_code = OS.get_process_exit_code(pid)
 	if exit_code == 0:
 	if exit_code == 0:
-		if output_str.contains("ERROR:"): #checks if CDP reported an error but passed exit code 0 anyway
-			console_output.append_text("[color=#9c2828][b]Processes failed[/b][/color]\n")
+		if output.contains("ERROR:"): #checks if CDP reported an error but passed exit code 0 anyway
+			console_output.append_text("[color=#9c2828][b]Processes failed[/b][/color]\n\n")
 			console_output.scroll_to_line(console_output.get_line_count() - 1)
 			console_output.scroll_to_line(console_output.get_line_count() - 1)
-			console_output.append_text(output_str + "\n")
 			process_successful = false
 			process_successful = false
+			if process_cancelled == false:
+				$ProgressWindow.hide()
+				if !$Console.visible:
+					$Console.popup_centered()
 		else:
 		else:
-			console_output.append_text("[color=#638382]Processes ran successfully[/color]\n")
+			console_output.append_text("[color=#638382]Processes ran successfully[/color]\n\n")
 			console_output.scroll_to_line(console_output.get_line_count() - 1)
 			console_output.scroll_to_line(console_output.get_line_count() - 1)
-			console_output.append_text(output_str + "\n")
-			process_successful = true
-			
 	else:
 	else:
-		console_output.append_text("[color=#9c2828][b]Processes failed with exit code: %d[/b][/color]\n" % exit_code)
+		console_output.append_text("[color=#9c2828][b]Processes failed with exit code: %d[/b][/color]\n" % exit_code + "\n")
 		console_output.scroll_to_line(console_output.get_line_count() - 1)
 		console_output.scroll_to_line(console_output.get_line_count() - 1)
-		console_output.append_text(output_str + "\n")
-		console_output.append_text(error_str + "\n")
-		if output_str.contains("as an internal or external command"): #check for cdprogs location error on windows
-			console_output.append_text("[color=#9c2828][b]Please make sure your cdprogs folder is set to the correct location in the Settings menu. The default location is C:\\CDPR8\\_cdp\\_cdprogs[/b][/color]\n")
-		if output_str.contains("command not found"): #check for cdprogs location error on unix systems
-			console_output.append_text("[color=#9c2828][b]Please make sure your cdprogs folder is set to the correct location in the Settings menu. The default location is ~/cdpr8/_cdp/_cdprogs[/b][/color]\n")
 		process_successful = false
 		process_successful = false
-	
+		if process_cancelled == false:
+			$ProgressWindow.hide()
+			if !$Console.visible:
+				$Console.popup_centered()
+		if output.contains("as an internal or external command"): #check for cdprogs location error on windows
+			console_output.append_text("[color=#9c2828][b]Please make sure your cdprogs folder is set to the correct location in the Settings menu. The default location is C:\\CDPR8\\_cdp\\_cdprogs[/b][/color]\n\n")
+			console_output.scroll_to_line(console_output.get_line_count() - 1)
+		if output.contains("command not found"): #check for cdprogs location error on unix systems
+			console_output.append_text("[color=#9c2828][b]Please make sure your cdprogs folder is set to the correct location in the Settings menu. The default location is ~/cdpr8/_cdp/_cdprogs[/b][/color]\n\n")
+			console_output.scroll_to_line(console_output.get_line_count() - 1)
+			
+	process_running = false
 	return output
 	return output
 
 
+func _on_kill_process_button_down() -> void:
+	if process_running and process_info.has("pid"):
+		$ProgressWindow.hide()
+		# Terminate the process by PID
+		OS.kill(process_info["pid"])
+		process_running = false
+		print("Process cancelled.")
+		process_cancelled = true
 
 
 	
 	
 func path_exists_through_all_nodes() -> bool:
 func path_exists_through_all_nodes() -> bool:
@@ -1737,6 +1810,7 @@ func _on_dont_save_changes_button_down() -> void:
 	
 	
 func _notification(what):
 func _notification(what):
 	if what == NOTIFICATION_WM_CLOSE_REQUEST:
 	if what == NOTIFICATION_WM_CLOSE_REQUEST:
+		_on_kill_process_button_down()
 		$Console.hide()
 		$Console.hide()
 		if changesmade == true:
 		if changesmade == true:
 			savestate = "quit"
 			savestate = "quit"

+ 50 - 10
scenes/main/control.tscn

@@ -194,22 +194,28 @@ always_on_top = true
 offset_left = 10.0
 offset_left = 10.0
 offset_top = 8.0
 offset_top = 8.0
 offset_right = 590.0
 offset_right = 590.0
-offset_bottom = 352.0
+offset_bottom = 344.0
 
 
 [node name="ConsoleOutput" type="RichTextLabel" parent="Console"]
 [node name="ConsoleOutput" type="RichTextLabel" parent="Console"]
-offset_left = 10.0
-offset_top = 12.0
-offset_right = 590.0
-offset_bottom = 351.0
-bbcode_enabled = true
+offset_left = 12.0
+offset_top = 8.0
+offset_right = 588.0
+offset_bottom = 344.0
 
 
 [node name="ConsoleOpenFolder" type="Button" parent="Console"]
 [node name="ConsoleOpenFolder" type="Button" parent="Console"]
-offset_left = -4.0
-offset_top = 360.0
-offset_right = 604.0
-offset_bottom = 401.0
+offset_left = 308.0
+offset_top = 352.0
+offset_right = 588.0
+offset_bottom = 393.0
 text = "Open Output Folder"
 text = "Open Output Folder"
 
 
+[node name="KillProcess" type="Button" parent="Console"]
+offset_left = 12.0
+offset_top = 352.0
+offset_right = 292.0
+offset_bottom = 393.0
+text = "Stop Running Thread"
+
 [node name="ColorRect" type="ColorRect" parent="."]
 [node name="ColorRect" type="ColorRect" parent="."]
 layout_mode = 1
 layout_mode = 1
 anchors_preset = 10
 anchors_preset = 10
@@ -397,6 +403,38 @@ text = "Get the update"
 [node name="Settings" parent="." instance=ExtResource("8_16l5g")]
 [node name="Settings" parent="." instance=ExtResource("8_16l5g")]
 visible = false
 visible = false
 
 
+[node name="ProgressWindow" type="Window" parent="."]
+initial_position = 2
+size = Vector2i(600, 110)
+visible = false
+transient = true
+exclusive = true
+borderless = true
+
+[node name="ProgressBar" type="ProgressBar" parent="ProgressWindow"]
+offset_left = 10.0
+offset_top = 11.0
+offset_right = 590.0
+offset_bottom = 51.0
+show_percentage = false
+
+[node name="ProgressLabel" type="Label" parent="ProgressWindow"]
+offset_left = 10.0
+offset_top = 11.0
+offset_right = 590.0
+offset_bottom = 51.0
+horizontal_alignment = 1
+vertical_alignment = 1
+clip_text = true
+text_overrun_behavior = 3
+
+[node name="KillProcess2" type="Button" parent="ProgressWindow"]
+offset_left = 8.0
+offset_top = 59.0
+offset_right = 592.0
+offset_bottom = 100.0
+text = "Stop Running Thread"
+
 [connection signal="connection_request" from="GraphEdit" to="." method="_on_graph_edit_connection_request"]
 [connection signal="connection_request" from="GraphEdit" to="." method="_on_graph_edit_connection_request"]
 [connection signal="delete_nodes_request" from="GraphEdit" to="." method="_on_graph_edit_delete_nodes_request"]
 [connection signal="delete_nodes_request" from="GraphEdit" to="." method="_on_graph_edit_delete_nodes_request"]
 [connection signal="disconnection_request" from="GraphEdit" to="." method="_on_graph_edit_disconnection_request"]
 [connection signal="disconnection_request" from="GraphEdit" to="." method="_on_graph_edit_disconnection_request"]
@@ -416,6 +454,7 @@ visible = false
 [connection signal="dir_selected" from="CdpLocationDialog" to="." method="_on_cdp_location_dialog_dir_selected"]
 [connection signal="dir_selected" from="CdpLocationDialog" to="." method="_on_cdp_location_dialog_dir_selected"]
 [connection signal="close_requested" from="Console" to="." method="_on_console_close_requested"]
 [connection signal="close_requested" from="Console" to="." method="_on_console_close_requested"]
 [connection signal="button_down" from="Console/ConsoleOpenFolder" to="." method="_on_console_open_folder_button_down"]
 [connection signal="button_down" from="Console/ConsoleOpenFolder" to="." method="_on_console_open_folder_button_down"]
+[connection signal="button_down" from="Console/KillProcess" to="." method="_on_kill_process_button_down"]
 [connection signal="index_pressed" from="MenuBar/FileButton" to="." method="_on_file_button_index_pressed"]
 [connection signal="index_pressed" from="MenuBar/FileButton" to="." method="_on_file_button_index_pressed"]
 [connection signal="index_pressed" from="MenuBar/SettingsButton" to="." method="_on_settings_button_index_pressed"]
 [connection signal="index_pressed" from="MenuBar/SettingsButton" to="." method="_on_settings_button_index_pressed"]
 [connection signal="index_pressed" from="MenuBar/HelpButton" to="." method="_on_help_button_index_pressed"]
 [connection signal="index_pressed" from="MenuBar/HelpButton" to="." method="_on_help_button_index_pressed"]
@@ -428,3 +467,4 @@ visible = false
 [connection signal="text_changed" from="SearchMenu/VBoxContainer/SearchBar" to="SearchMenu" method="_on_search_bar_text_changed"]
 [connection signal="text_changed" from="SearchMenu/VBoxContainer/SearchBar" to="SearchMenu" method="_on_search_bar_text_changed"]
 [connection signal="close_requested" from="CheckForUpdates/UpdatePopup" to="CheckForUpdates" method="_on_update_popup_close_requested"]
 [connection signal="close_requested" from="CheckForUpdates/UpdatePopup" to="CheckForUpdates" method="_on_update_popup_close_requested"]
 [connection signal="button_down" from="CheckForUpdates/UpdatePopup/OpenAudioSettings" to="CheckForUpdates" method="_on_open_audio_settings_button_down"]
 [connection signal="button_down" from="CheckForUpdates/UpdatePopup/OpenAudioSettings" to="CheckForUpdates" method="_on_open_audio_settings_button_down"]
+[connection signal="button_down" from="ProgressWindow/KillProcess2" to="." method="_on_kill_process_button_down"]

+ 5 - 0
scenes/main/settings.gd

@@ -22,6 +22,7 @@ func _on_about_to_popup() -> void:
 	$VBoxContainer/HBoxContainer5/ThemeList.select(interface_settings.theme, true)
 	$VBoxContainer/HBoxContainer5/ThemeList.select(interface_settings.theme, true)
 	$VBoxContainer/HBoxContainer/CustomColourPicker.color = Color(interface_settings.theme_custom_colour)
 	$VBoxContainer/HBoxContainer/CustomColourPicker.color = Color(interface_settings.theme_custom_colour)
 	$VBoxContainer/HBoxContainer2/PvocWarning.button_pressed = interface_settings.disable_pvoc_warning
 	$VBoxContainer/HBoxContainer2/PvocWarning.button_pressed = interface_settings.disable_pvoc_warning
+	$VBoxContainer/HBoxContainer6/ProgressBar.button_pressed = interface_settings.disable_progress_bar
 	$VBoxContainer/HBoxContainer3/AutoCloseConsole.button_pressed = interface_settings.auto_close_console
 	$VBoxContainer/HBoxContainer3/AutoCloseConsole.button_pressed = interface_settings.auto_close_console
 	$VBoxContainer/HBoxContainer4/ConsoleAlwaysOnTop.button_pressed = interface_settings.console_on_top
 	$VBoxContainer/HBoxContainer4/ConsoleAlwaysOnTop.button_pressed = interface_settings.console_on_top
 	
 	
@@ -29,6 +30,10 @@ func _on_about_to_popup() -> void:
 func _on_pvoc_warning_toggled(toggled_on: bool) -> void:
 func _on_pvoc_warning_toggled(toggled_on: bool) -> void:
 	ConfigHandler.save_interface_settings("disable_pvoc_warning", toggled_on)
 	ConfigHandler.save_interface_settings("disable_pvoc_warning", toggled_on)
 
 
+func _on_progress_bar_toggled(toggled_on: bool) -> void:
+	ConfigHandler.save_interface_settings("disable_progress_bar", toggled_on)
+
+
 
 
 func _on_auto_close_console_toggled(toggled_on: bool) -> void:
 func _on_auto_close_console_toggled(toggled_on: bool) -> void:
 	ConfigHandler.save_interface_settings("auto_close_console", toggled_on)
 	ConfigHandler.save_interface_settings("auto_close_console", toggled_on)

+ 15 - 3
scenes/main/settings.tscn

@@ -6,15 +6,15 @@
 auto_translate_mode = 1
 auto_translate_mode = 1
 title = "SoundThread Settings"
 title = "SoundThread Settings"
 initial_position = 2
 initial_position = 2
-size = Vector2i(500, 380)
+size = Vector2i(500, 410)
 transient = true
 transient = true
 unresizable = true
 unresizable = true
 always_on_top = true
 always_on_top = true
 script = ExtResource("1_uey6c")
 script = ExtResource("1_uey6c")
 
 
 [node name="ColorRect" type="ColorRect" parent="."]
 [node name="ColorRect" type="ColorRect" parent="."]
-offset_right = 604.0
-offset_bottom = 382.0
+offset_right = 506.0
+offset_bottom = 421.0
 color = Color(0.101961, 0.101961, 0.101961, 0.6)
 color = Color(0.101961, 0.101961, 0.101961, 0.6)
 
 
 [node name="VBoxContainer" type="VBoxContainer" parent="."]
 [node name="VBoxContainer" type="VBoxContainer" parent="."]
@@ -93,6 +93,17 @@ text = "Disable frequency domain multiple input warning:"
 layout_mode = 2
 layout_mode = 2
 size_flags_horizontal = 3
 size_flags_horizontal = 3
 
 
+[node name="HBoxContainer6" type="HBoxContainer" parent="VBoxContainer"]
+layout_mode = 2
+
+[node name="Label" type="Label" parent="VBoxContainer/HBoxContainer6"]
+layout_mode = 2
+text = "Show console instead of progress bar:"
+
+[node name="ProgressBar" type="CheckButton" parent="VBoxContainer/HBoxContainer6"]
+layout_mode = 2
+size_flags_horizontal = 3
+
 [node name="HBoxContainer3" type="HBoxContainer" parent="VBoxContainer"]
 [node name="HBoxContainer3" type="HBoxContainer" parent="VBoxContainer"]
 layout_mode = 2
 layout_mode = 2
 
 
@@ -121,5 +132,6 @@ size_flags_horizontal = 3
 [connection signal="item_selected" from="VBoxContainer/HBoxContainer5/ThemeList" to="." method="_on_theme_list_item_selected"]
 [connection signal="item_selected" from="VBoxContainer/HBoxContainer5/ThemeList" to="." method="_on_theme_list_item_selected"]
 [connection signal="color_changed" from="VBoxContainer/HBoxContainer/CustomColourPicker" to="." method="_on_custom_colour_picker_color_changed"]
 [connection signal="color_changed" from="VBoxContainer/HBoxContainer/CustomColourPicker" to="." method="_on_custom_colour_picker_color_changed"]
 [connection signal="toggled" from="VBoxContainer/HBoxContainer2/PvocWarning" to="." method="_on_pvoc_warning_toggled"]
 [connection signal="toggled" from="VBoxContainer/HBoxContainer2/PvocWarning" to="." method="_on_pvoc_warning_toggled"]
+[connection signal="toggled" from="VBoxContainer/HBoxContainer6/ProgressBar" to="." method="_on_progress_bar_toggled"]
 [connection signal="toggled" from="VBoxContainer/HBoxContainer3/AutoCloseConsole" to="." method="_on_auto_close_console_toggled"]
 [connection signal="toggled" from="VBoxContainer/HBoxContainer3/AutoCloseConsole" to="." method="_on_auto_close_console_toggled"]
 [connection signal="toggled" from="VBoxContainer/HBoxContainer4/ConsoleAlwaysOnTop" to="." method="_on_console_always_on_top_toggled"]
 [connection signal="toggled" from="VBoxContainer/HBoxContainer4/ConsoleAlwaysOnTop" to="." method="_on_console_always_on_top_toggled"]

+ 28 - 1
theme/main_theme.tres

@@ -1,4 +1,4 @@
-[gd_resource type="Theme" load_steps=64 format=3 uid="uid://cefwkdcoxihro"]
+[gd_resource type="Theme" load_steps=66 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://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"]
 [ext_resource type="Texture2D" uid="uid://d0dubcywvqtkw" path="res://theme/images/toggle_unchecked.png" id="2_adhqp"]
@@ -407,6 +407,31 @@ bg_color = Color(0.101961, 0.101961, 0.101961, 1)
 border_color = Color(0.175, 0.175, 0.175, 1)
 border_color = Color(0.175, 0.175, 0.175, 1)
 corner_detail = 5
 corner_detail = 5
 
 
+[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_g78kk"]
+content_margin_left = 2.0
+content_margin_top = 2.0
+content_margin_right = 2.0
+content_margin_bottom = 2.0
+bg_color = Color(0.101961, 0.101961, 0.101961, 0)
+border_width_left = 2
+border_width_top = 2
+border_width_right = 2
+border_width_bottom = 2
+border_color = Color(0.101961, 0.101961, 0.101961, 0.6)
+corner_detail = 6
+expand_margin_left = 2.0
+expand_margin_top = 2.0
+expand_margin_right = 2.0
+expand_margin_bottom = 2.0
+
+[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_m7qrk"]
+content_margin_left = 2.0
+content_margin_top = 2.0
+content_margin_right = 2.0
+content_margin_bottom = 2.0
+bg_color = Color(0.101961, 0.101961, 0.101961, 0.6)
+corner_detail = 6
+
 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ffxfl"]
 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ffxfl"]
 content_margin_left = 0.0
 content_margin_left = 0.0
 content_margin_top = 0.0
 content_margin_top = 0.0
@@ -576,6 +601,8 @@ PopupMenu/constants/item_end_padding = 20
 PopupMenu/constants/v_separation = 8
 PopupMenu/constants/v_separation = 8
 PopupMenu/styles/hover = SubResource("StyleBoxFlat_cibxr")
 PopupMenu/styles/hover = SubResource("StyleBoxFlat_cibxr")
 PopupMenu/styles/panel = SubResource("StyleBoxFlat_75705")
 PopupMenu/styles/panel = SubResource("StyleBoxFlat_75705")
+ProgressBar/styles/background = SubResource("StyleBoxFlat_g78kk")
+ProgressBar/styles/fill = SubResource("StyleBoxFlat_m7qrk")
 TabContainer/styles/panel = SubResource("StyleBoxFlat_ffxfl")
 TabContainer/styles/panel = SubResource("StyleBoxFlat_ffxfl")
 TabContainer/styles/tab_focus = SubResource("StyleBoxFlat_tpkcg")
 TabContainer/styles/tab_focus = SubResource("StyleBoxFlat_tpkcg")
 TabContainer/styles/tab_hovered = SubResource("StyleBoxFlat_xxa0j")
 TabContainer/styles/tab_hovered = SubResource("StyleBoxFlat_xxa0j")