Jonathan Higgins преди 7 месеца
родител
ревизия
18ee908340
променени са 7 файла, в които са добавени 183 реда и са изтрити 53 реда
  1. 1 0
      config_handler.gd
  2. 69 21
      scenes/main/control.gd
  3. 35 4
      scenes/main/control.tscn
  4. 1 26
      scenes/main/process_help.json
  5. 2 2
      scenes/menu/menu.tscn
  6. 74 0
      scenes/menu/search_menu.gd
  7. 1 0
      scenes/menu/search_menu.gd.uid

+ 1 - 0
config_handler.gd

@@ -14,6 +14,7 @@ func _ready():
 	ensure_setting("interface_settings", "disable_pvoc_warning", false)
 	ensure_setting("interface_settings", "auto_close_console", false)
 	ensure_setting("interface_settings", "console_on_top", true)
+	ensure_setting("interface_settings", "use_search", false)
 	ensure_setting("audio_settings", "device", "Default")
 
 	# Only save if we added anything new

+ 69 - 21
scenes/main/control.gd

@@ -39,6 +39,7 @@ func _ready() -> void:
 	$MultipleConnectionsPopup.hide()
 	$AudioSettings.hide()
 	$AudioDevicePopup.hide()
+	$SearchMenu.hide()
 	
 	$SaveDialog.access = FileDialog.ACCESS_FILESYSTEM
 	$SaveDialog.file_mode = FileDialog.FILE_MODE_SAVE_FILE
@@ -54,6 +55,8 @@ func _ready() -> void:
 		if child is Button:
 			child.pressed.connect(_on_button_pressed.bind(child))
 	
+	get_node("SearchMenu").make_node.connect(_make_node_from_search_menu)
+	
 	check_cdp_location_set()
 	check_user_preferences()
 	new_patch()
@@ -145,6 +148,7 @@ func check_user_preferences():
 	$MenuBar/SettingsButton.set_item_checked(1, interface_settings.disable_pvoc_warning)
 	$MenuBar/SettingsButton.set_item_checked(2, interface_settings.auto_close_console)
 	$MenuBar/SettingsButton.set_item_checked(3, interface_settings.console_on_top)
+	$MenuBar/SettingsButton.set_item_checked(3, interface_settings.use_search)
 	$Console.always_on_top = interface_settings.console_on_top
 	if audio_devices.has(audio_settings.device):
 		AudioServer.set_output_device(audio_settings.device)
@@ -311,6 +315,27 @@ func simulate_mouse_click():
 	up_event.position = click_pos
 	Input.parse_input_event(up_event)
 
+func _make_node_from_search_menu(command: String):
+	#close menu
+	$SearchMenu.hide()
+	
+	#Find node with matching name to button and create a version of it in the graph edit
+	#and position it close to the origin right click to open the menu
+	var effect: GraphNode = Nodes.get_node(NodePath(command)).duplicate()
+	get_node("GraphEdit").add_child(effect, true)
+	effect.set_position_offset((effect_position + graph_edit.scroll_offset) / graph_edit.zoom) #set node to current mouse position in graph edit
+	_register_inputs_in_node(effect) #link sliders for changes tracking
+	_register_node_movement() #link nodes for tracking position changes for changes tracking
+
+	changesmade = true
+
+	# Remove node with UndoRedo
+	undo_redo.create_action("Add Node")
+	undo_redo.add_undo_method(Callable(graph_edit, "remove_child").bind(effect))
+	undo_redo.add_undo_method(Callable(effect, "queue_free"))
+	undo_redo.add_undo_method(Callable(self, "_track_changes"))
+	undo_redo.commit_action()
+	
 
 func _on_button_pressed(button: Button):
 	#close menu
@@ -324,7 +349,7 @@ func _on_button_pressed(button: Button):
 	effect.set_position_offset((effect_position + graph_edit.scroll_offset) / graph_edit.zoom) #set node to current mouse position in graph edit
 	_register_inputs_in_node(effect) #link sliders for changes tracking
 	_register_node_movement() #link nodes for tracking position changes for changes tracking
-	
+
 	changesmade = true
 
 
@@ -1364,15 +1389,21 @@ func _on_settings_button_index_pressed(index: int) -> void:
 				ConfigHandler.save_interface_settings("console_on_top", false)
 				$Console.always_on_top = false
 		4:
+			if interface_settings.use_search == false:
+				$MenuBar/SettingsButton.set_item_checked(index, true)
+				ConfigHandler.save_interface_settings("use_search", true)
+			else:
+				$MenuBar/SettingsButton.set_item_checked(index, false)
+				ConfigHandler.save_interface_settings("use_search", false)
+		5:
+			$AudioSettings.popup()
+		6:
 			if $Console.is_visible():
 				$Console.hide()
 				await get_tree().process_frame  # Wait a frame to allow hide to complete
 				$Console.popup()
 			else:
 				$Console.popup()
-		5:
-			#$AudioSettings.size = Vector2(600, $AudioSettings/Control/VBoxContainer.size.y + ($AudioSettings/Control/VBoxContainer/ItemList.item_count * 25) + 10)
-			$AudioSettings.popup()
 
 func _on_file_button_index_pressed(index: int) -> void:
 	match index:
@@ -1708,25 +1739,42 @@ func _on_rich_text_label_meta_clicked(meta: Variant) -> void:
 
 
 func _on_graph_edit_popup_request(at_position: Vector2) -> void:
-	effect_position = graph_edit.get_local_mouse_position()
+	var interface_settings = ConfigHandler.load_interface_settings()
 	
-	#get the mouse position in screen coordinates
-	var mouse_screen_pos = DisplayServer.mouse_get_position()  
-	#get the window position in screen coordinates
-	var window_screen_pos = get_window().position
-	#get the window size relative to its scaling for retina displays
-	var window_size = get_window().size * DisplayServer.screen_get_scale()
-	#get the size of the popup menu
-	var popup_size = $mainmenu.size
-
-	#calculate the xy position of the mouse clamped to the size of the window and menu so it doesn't go off the screen
-	var clamped_x = clamp(mouse_screen_pos.x, window_screen_pos.x, window_screen_pos.x + window_size.x - popup_size.x)
-	var clamped_y = clamp(mouse_screen_pos.y, window_screen_pos.y, window_screen_pos.y + window_size.y - popup_size.y)
+	effect_position = graph_edit.get_local_mouse_position()
 	
-	#position and show the menu
-	$mainmenu.position = Vector2(clamped_x, clamped_y)
-	$mainmenu.popup()
-
+	if interface_settings.use_search == false:
+		#get the mouse position in screen coordinates
+		var mouse_screen_pos = DisplayServer.mouse_get_position()  
+		#get the window position in screen coordinates
+		var window_screen_pos = get_window().position
+		#get the window size relative to its scaling for retina displays
+		var window_size = get_window().size * DisplayServer.screen_get_scale()
+		#get the size of the popup menu
+		var popup_size = $mainmenu.size
+
+		#calculate the xy position of the mouse clamped to the size of the window and menu so it doesn't go off the screen
+		var clamped_x = clamp(mouse_screen_pos.x, window_screen_pos.x, window_screen_pos.x + window_size.x - popup_size.x)
+		var clamped_y = clamp(mouse_screen_pos.y, window_screen_pos.y, window_screen_pos.y + window_size.y - popup_size.y)
+		
+		#position and show the menu
+		$mainmenu.position = Vector2(clamped_x, clamped_y)
+		$mainmenu.popup()
+	else:
+		#get the mouse position in screen coordinates
+		var mouse_screen_pos = DisplayServer.mouse_get_position()  
+		#get the window position in screen coordinates
+		var window_screen_pos = get_window().position
+		#get the window size relative to its scaling for retina displays
+		var window_size = get_window().size * DisplayServer.screen_get_scale()
+
+		#calculate the xy position of the mouse clamped to the size of the window and menu so it doesn't go off the screen
+		var clamped_x = clamp(mouse_screen_pos.x, window_screen_pos.x, window_screen_pos.x + window_size.x - $SearchMenu.size.x)
+		var clamped_y = clamp(mouse_screen_pos.y, window_screen_pos.y, window_screen_pos.y + window_size.y - (420 * DisplayServer.screen_get_scale()))
+		
+		#position and show the menu
+		$SearchMenu.position = Vector2(clamped_x, clamped_y)
+		$SearchMenu.popup()
 
 func _on_audio_settings_close_requested() -> void:
 	$AudioSettings.hide()

+ 35 - 4
scenes/main/control.tscn

@@ -1,10 +1,11 @@
-[gd_scene load_steps=6 format=3 uid="uid://bcs87y7ptx3ke"]
+[gd_scene load_steps=7 format=3 uid="uid://bcs87y7ptx3ke"]
 
 [ext_resource type="Script" uid="uid://bdlfvuljckmu1" path="res://scenes/main/control.gd" id="1_2f0aq"]
 [ext_resource type="Script" uid="uid://l2yejnjysupr" path="res://scenes/main/graph_edit.gd" id="2_3ioqo"]
 [ext_resource type="PackedScene" uid="uid://b0wdj8v6o0wq0" path="res://scenes/menu/menu.tscn" id="3_dtf4o"]
 [ext_resource type="Texture2D" uid="uid://cdwux1smquvpi" path="res://theme/images/logo.png" id="4_3ioqo"]
 [ext_resource type="PackedScene" uid="uid://dta7rfalv4uvd" path="res://scenes/main/audio_settings.tscn" id="5_dtf4o"]
+[ext_resource type="Script" uid="uid://dlcbmyu3s2phc" path="res://scenes/menu/search_menu.gd" id="6_fyarh"]
 
 [node name="Control" type="Control"]
 layout_mode = 3
@@ -241,7 +242,7 @@ item_3/id = 1
 
 [node name="SettingsButton" type="PopupMenu" parent="MenuBar"]
 title = "Settings"
-item_count = 6
+item_count = 7
 item_0/text = "Change CDP Folder Location"
 item_0/id = 0
 item_1/text = "Disable PVOC Multi Input Warning"
@@ -253,10 +254,13 @@ item_2/id = 2
 item_3/text = "Console Always on Top"
 item_3/checkable = 1
 item_3/id = 5
-item_4/text = "Open the Console"
-item_4/id = 3
+item_4/text = "Use Search Menu (Experimental)"
+item_4/checkable = 1
+item_4/id = 6
 item_5/text = "Audio Settings"
 item_5/id = 4
+item_6/text = "Open the Console"
+item_6/id = 3
 
 [node name="HelpButton" type="PopupMenu" parent="MenuBar"]
 auto_translate_mode = 1
@@ -341,6 +345,31 @@ text = "Don't Save"
 [node name="AudioSettings" parent="." groups=["popup_windows"] instance=ExtResource("5_dtf4o")]
 visible = false
 
+[node name="SearchMenu" type="PopupPanel" parent="." groups=["popup_windows"]]
+auto_translate_mode = 1
+position = Vector2i(100, 100)
+size = Vector2i(600, 49)
+script = ExtResource("6_fyarh")
+
+[node name="VBoxContainer" type="VBoxContainer" parent="SearchMenu"]
+offset_left = 4.0
+offset_top = 4.0
+offset_right = 596.0
+offset_bottom = 45.0
+
+[node name="SearchBar" type="LineEdit" parent="SearchMenu/VBoxContainer"]
+layout_mode = 2
+
+[node name="ScrollContainer" type="ScrollContainer" parent="SearchMenu/VBoxContainer"]
+custom_minimum_size = Vector2(0, 10)
+layout_mode = 2
+size_flags_vertical = 3
+horizontal_scroll_mode = 0
+
+[node name="ItemContainer" type="VBoxContainer" parent="SearchMenu/VBoxContainer/ScrollContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+
 [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="disconnection_request" from="GraphEdit" to="." method="_on_graph_edit_disconnection_request"]
@@ -368,3 +397,5 @@ visible = false
 [connection signal="button_down" from="SaveChangesPopup/SaveChanges" to="." method="_on_save_changes_button_down"]
 [connection signal="button_down" from="SaveChangesPopup/DontSaveChanges" to="." method="_on_dont_save_changes_button_down"]
 [connection signal="close_requested" from="AudioSettings" to="." method="_on_audio_settings_close_requested"]
+[connection signal="about_to_popup" from="SearchMenu" to="SearchMenu" method="_on_about_to_popup"]
+[connection signal="text_changed" from="SearchMenu/VBoxContainer/SearchBar" to="SearchMenu" method="_on_search_bar_text_changed"]

+ 1 - 26
scenes/main/process_help.json

@@ -74,7 +74,7 @@
   },
   "notes": {
 	"category": "utility",
-	"subcategory": "",
+	"subcategory": "utility",
 	"stereo": false,
 	"title": "Notes",
 	"parameters": {},
@@ -1803,30 +1803,5 @@
 	},
 	"short_description": "Oscillate between harmonic and inharmonic state",
 	"description": "Introduces an oscillation towards and away from inharmonicness in the spectrum of a sound. The program moves towards inharmonicness by means of the stretch factor. \n"
-  },
-  "processname": {
-	"category": "time",
-	"subcategory": "",
-	"stereo": false,
-	"title": "",
-	"parameters": {
-	  "param1": {
-		"paramname": "",
-		"paramdescription": "",
-		"automatable": true,
-		"time": false,
-		"min": false,
-		"max": false,
-		"flag": "",
-		"minrange": "",
-		"maxrange": "",
-		"step": "",
-		"value": "",
-		"exponential": false,
-		"uitype": "hslider"
-	  }
-	},
-	"short_description": "Short Description",
-	"description": "\n"
   }
 }

+ 2 - 2
scenes/menu/menu.tscn

@@ -32,11 +32,10 @@ current_tab = 0
 
 [node name="Time Domain" type="TabContainer" parent="Control/select_effect"]
 layout_mode = 2
-current_tab = 1
+current_tab = 0
 metadata/_tab_index = 0
 
 [node name="Distort" type="VBoxContainer" parent="Control/select_effect/Time Domain"]
-visible = false
 layout_mode = 2
 metadata/_tab_index = 0
 
@@ -293,6 +292,7 @@ layout_mode = 2
 text = "+"
 
 [node name="Extend" type="VBoxContainer" parent="Control/select_effect/Time Domain"]
+visible = false
 layout_mode = 2
 metadata/_tab_index = 1
 

+ 74 - 0
scenes/menu/search_menu.gd

@@ -0,0 +1,74 @@
+extends PopupPanel
+
+@onready var item_container: VBoxContainer = $VBoxContainer/ScrollContainer/ItemContainer
+@onready var scroll_container: ScrollContainer = $VBoxContainer/ScrollContainer
+@onready var search_bar = $VBoxContainer/SearchBar
+var node_data = {} #stores node data for each node to display in help popup
+signal make_node(command)
+
+
+func _ready() -> void:
+	#parse json
+	var file = FileAccess.open("res://scenes/main/process_help.json", FileAccess.READ)
+	if file:
+		var result = JSON.parse_string(file.get_as_text())
+		if typeof(result) == TYPE_DICTIONARY:
+			node_data = result
+		else:
+			push_error("Invalid JSON")
+				
+	#honestly not sure what of these is actually doing things
+	item_container.custom_minimum_size.x = scroll_container.size.x
+	scroll_container.size_flags_vertical = Control.SIZE_EXPAND_FILL
+	scroll_container.set("theme_override_constants/maximum_height", 400)
+
+
+
+func _on_about_to_popup() -> void:
+	display_items("") #populate menu when needed
+	search_bar.clear()
+	search_bar.grab_focus()
+
+func display_items(filter: String):
+	# Remove all existing items from the VBoxContainer
+	for child in item_container.get_children():
+		child.queue_free()
+	for key in node_data.keys():
+		var item = node_data[key]
+		var title = item.get("title", "")
+		
+		#filter out input and output nodes
+		if title == "Input File" or title == "Output File":
+			continue
+		
+		var category = item.get("category", "")
+		var subcategory = item.get("subcategory", "")
+		var short_desc = item.get("short_description", "")
+		
+		# If filter is not empty, skip non-matches populate all other buttons
+		if filter != "":
+			var filter_lc = filter.to_lower()
+			if not (filter_lc in title.to_lower() or filter_lc in short_desc.to_lower() or filter_lc in category.to_lower() or filter_lc in subcategory.to_lower()):
+				continue
+		
+		var btn = Button.new()
+		btn.size_flags_horizontal = Control.SIZE_EXPAND_FILL #make buttons wide
+		btn.alignment = 0 #left align text
+		btn.clip_text = true #clip off labels that are too long
+		btn.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS #and replace with ...
+		if category.to_lower() == "pvoc": #format node names correctly, only show the category for PVOC
+			btn.text = "%s %s: %s - %s" % [category.to_upper(), subcategory.to_pascal_case(), title, short_desc]
+		else:
+			btn.text = "%s: %s - %s" % [subcategory.to_pascal_case(), title, short_desc]
+		btn.connect("pressed", Callable(self, "_on_item_selected").bind(key)) #pass key (process name) when button is pressed
+		item_container.add_child(btn)
+	
+	#resize menu within certain bounds
+	await get_tree().process_frame
+	self.size.y = min(item_container.size.y + search_bar.size.y + 10, 410 * DisplayServer.screen_get_scale()) #i think this will scale for retina screens but might be wrong
+	
+func _on_search_bar_text_changed(new_text: String) -> void:
+	display_items(new_text)
+	
+func _on_item_selected(key: String):
+	make_node.emit(key) # send out signal to main patch

+ 1 - 0
scenes/menu/search_menu.gd.uid

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