Browse Source

added user customisable favourites to menu and search function

Jonathan Higgins 3 months ago
parent
commit
5f3110906a

+ 2 - 0
Global/config_handler.gd

@@ -27,7 +27,9 @@ func _ready():
 	ensure_setting("interface_settings", "last_used_output_folder", "no_file")
 	ensure_setting("interface_settings", "last_used_input_folder", "no_file")
 	ensure_setting("interface_settings", "autoplay", true)
+	ensure_setting("interface_settings", "favourites", [])
 	ensure_setting("audio_settings", "device", "Default")
+	
 
 	# Only save if we added anything new
 	if !file_exists or config_changed:

+ 152 - 1
scenes/menu/explore_menu.gd

@@ -4,6 +4,8 @@ var node_data = {} #stores node data for each node to display in help popup
 signal make_node(command)
 signal open_help(command)
 
+@onready var fav_button_logic = preload("res://scenes/menu/fav_button.gd")
+
 
 func _ready() -> void:
 	
@@ -21,7 +23,16 @@ func _ready() -> void:
 				
 	fill_menu()
 	
+	#chec user prefs fr favourites and load them
+	var interface_settings = ConfigHandler.load_interface_settings()
+	var favourites = interface_settings.favourites
+	
+	_load_favourites(favourites)
+	
 func fill_menu():
+	var interface_settings = ConfigHandler.load_interface_settings()
+	var favourites = interface_settings.favourites
+	
 	for key in node_data.keys():
 		var item = node_data[key]
 		var title = item.get("title", "")
@@ -75,6 +86,7 @@ func fill_menu():
 		
 		var hbox = HBoxContainer.new()
 		var label = RichTextLabel.new()
+		var favbtn = Button.new()
 		var helpbtn = Button.new()
 		var makebtn = Button.new()
 		var margin = MarginContainer.new()
@@ -86,6 +98,20 @@ func fill_menu():
 		label.set_v_size_flags(Control.SIZE_EXPAND_FILL)
 		label.fit_content = true
 		
+		favbtn.name = "fav_" + key
+		favbtn.add_theme_font_size_override("font_size", 20)
+		favbtn.tooltip_text = "Favourite " + title
+		favbtn.custom_minimum_size = Vector2(40, 40)
+		favbtn.set_h_size_flags(Control.SIZE_SHRINK_CENTER)
+		favbtn.toggle_mode = true
+		if favourites.has(key):
+			favbtn.text = "★"
+			favbtn.set_pressed_no_signal(true)
+		else:
+			favbtn.text = "☆"
+		favbtn.set_script(fav_button_logic)
+		favbtn.connect("toggled", Callable(self, "_favourite_process").bind(key, favourites)) #pass key (process name) when button is pressed
+		
 		helpbtn.text = "?"
 		helpbtn.tooltip_text = "Open help for " + title
 		helpbtn.custom_minimum_size = Vector2(40, 40)
@@ -102,6 +128,7 @@ func fill_menu():
 		
 		container.add_child(hbox)
 		hbox.add_child(label)
+		hbox.add_child(favbtn)
 		hbox.add_child(helpbtn)
 		hbox.add_child(makebtn)
 		container.add_child(margin)
@@ -118,6 +145,8 @@ func _on_about_to_popup() -> void:
 
 
 func fill_search(filter: String):
+	var interface_settings = ConfigHandler.load_interface_settings()
+	var favourites = interface_settings.favourites
 	# Remove all existing items from the VBoxContainer
 	var container = $"Control/select_effect/Search/Search for a process in SoundThread/MarginContainer/VBoxContainer/ScrollContainer/ItemContainer"
 	for child in container.get_children():
@@ -125,10 +154,15 @@ func fill_search(filter: String):
 		
 	var filters = filter.to_lower().split(" ", false)
 	
+	
 	for key in node_data.keys():
 		var item = node_data[key]
 		var title = item.get("title", "")
 		
+		if filters.has("*"):
+			if favourites.has(key) == false:
+				continue
+		
 		#filter out output node
 		if title == "Output File":
 			continue
@@ -146,6 +180,9 @@ func fill_search(filter: String):
 		if filter != "":
 			var match_all_words = true
 			for word in filters:
+				if word == "*":
+					continue
+				
 				if word != "" and not searchable_text.findn(word) != -1:
 					match_all_words = false
 					break
@@ -155,6 +192,7 @@ func fill_search(filter: String):
 		
 		var hbox = HBoxContainer.new()
 		var label = RichTextLabel.new()
+		var favbtn = Button.new()
 		var helpbtn = Button.new()
 		var makebtn = Button.new()
 		var margin = MarginContainer.new()
@@ -166,6 +204,22 @@ func fill_search(filter: String):
 		label.set_v_size_flags(Control.SIZE_EXPAND_FILL)
 		label.fit_content = true
 		
+		favbtn.name = "fav_" + key
+		favbtn.add_theme_font_size_override("font_size", 20)
+		favbtn.tooltip_text = "Favourite " + title
+		favbtn.custom_minimum_size = Vector2(40, 40)
+		favbtn.set_h_size_flags(Control.SIZE_SHRINK_CENTER)
+		favbtn.toggle_mode = true
+		if favourites.has(key):
+			favbtn.text = "★"
+			favbtn.set_pressed_no_signal(true)
+		else:
+			favbtn.text = "☆"
+		favbtn.set_script(fav_button_logic)
+		favbtn.connect("toggled", Callable(self, "_favourite_process").bind(key, favourites)) #pass key (process name) when button is pressed
+		
+		
+		
 		helpbtn.text = "?"
 		helpbtn.tooltip_text = "Open help for " + title
 		helpbtn.custom_minimum_size = Vector2(40, 40)
@@ -182,6 +236,7 @@ func fill_search(filter: String):
 		
 		container.add_child(hbox)
 		hbox.add_child(label)
+		hbox.add_child(favbtn)
 		hbox.add_child(helpbtn)
 		hbox.add_child(makebtn)
 		container.add_child(margin)
@@ -203,5 +258,101 @@ func _open_help(key: String, title: String):
 
 
 func _on_select_effect_tab_changed(tab: int) -> void:
-	if tab == 3:
+	if tab == 4:
 		$"Control/select_effect/Search/Search for a process in SoundThread/MarginContainer/VBoxContainer/SearchBar".grab_focus()
+
+func _favourite_process(toggled_on: bool, key: String, favourites: Array):
+	if toggled_on:
+		favourites.append(key)
+	else:
+		favourites.erase(key)
+	
+	ConfigHandler.save_interface_settings("favourites", favourites)
+	
+	#find all favourite buttons for this effect and set to the correct state if in serach of favourites window
+	if $Control/select_effect.current_tab == 3 or $Control/select_effect.current_tab == 4:
+		var button = $Control/select_effect.find_child("fav_" + key, true, false)
+		if button != null:
+			button.set_pressed_no_signal(toggled_on)
+			if toggled_on:
+				button.text = "★"
+			else:
+				button.text = "☆"
+	
+	_load_favourites(favourites)
+		
+func refresh_menu():
+	pass
+
+
+func _load_favourites(favourites: Array):
+	var container = $"Control/select_effect/Favourites/Browse Favourites/MarginContainer/VBoxContainer/ScrollContainer/ItemContainer"
+	for child in container.get_children():
+		child.queue_free()
+		
+	if favourites.size() > 0:
+		for key in node_data.keys():
+			var item = node_data[key]
+			var title = item.get("title", "")
+			
+			if favourites.has(key) == false:
+				continue
+				
+			var category = item.get("category", "")
+			var subcategory = item.get("subcategory", "")
+			var short_desc = item.get("short_description", "")
+			var command = key.replace("_", " ")
+			
+			var hbox = HBoxContainer.new()
+			var label = RichTextLabel.new()
+			var favbtn = Button.new()
+			var helpbtn = Button.new()
+			var makebtn = Button.new()
+			var margin = MarginContainer.new()
+			
+			hbox.size.x = container.size.x
+			label.bbcode_enabled = true
+			label.text = "[b]%s[/b]\n%s" % [title, short_desc]
+			label.set_h_size_flags(Control.SIZE_EXPAND_FILL)
+			label.set_v_size_flags(Control.SIZE_EXPAND_FILL)
+			label.fit_content = true
+			
+			favbtn.name = "fav_" + key
+			favbtn.add_theme_font_size_override("font_size", 20)
+			favbtn.tooltip_text = "Favourite " + title
+			favbtn.custom_minimum_size = Vector2(40, 40)
+			favbtn.set_h_size_flags(Control.SIZE_SHRINK_CENTER)
+			favbtn.toggle_mode = true
+			if favourites.has(key):
+				favbtn.text = "★"
+				favbtn.set_pressed_no_signal(true)
+			else:
+				favbtn.text = "☆"
+			favbtn.set_script(fav_button_logic)
+			favbtn.connect("toggled", Callable(self, "_favourite_process").bind(key, favourites)) #pass key (process name) when button is pressed
+			
+			helpbtn.text = "?"
+			helpbtn.tooltip_text = "Open help for " + title
+			helpbtn.custom_minimum_size = Vector2(40, 40)
+			helpbtn.set_h_size_flags(Control.SIZE_SHRINK_CENTER)
+			helpbtn.connect("pressed", Callable(self, "_open_help").bind(key, title)) #pass key (process name) when button is pressed
+			
+			makebtn.text = "+"
+			makebtn.tooltip_text = "Add " + title + " to thread"
+			makebtn.custom_minimum_size = Vector2(40, 40)
+			makebtn.set_h_size_flags(Control.SIZE_SHRINK_CENTER)
+			makebtn.connect("pressed", Callable(self, "_make_node").bind(key)) #pass key (process name) when button is pressed
+			
+			margin.add_theme_constant_override("margin_bottom", 3)
+			
+			container.add_child(hbox)
+			hbox.add_child(label)
+			hbox.add_child(favbtn)
+			hbox.add_child(helpbtn)
+			hbox.add_child(makebtn)
+			container.add_child(margin)
+	else:
+		var label = RichTextLabel.new()
+		label.text = "Press the star next to a process in the explore menu to add a favourite."
+		label.fit_content = true
+		container.add_child(label)

+ 14 - 0
scenes/menu/fav_button.gd

@@ -0,0 +1,14 @@
+extends Button
+
+
+# Called when the node enters the scene tree for the first time.
+func _ready() -> void:
+	connect("toggled", Callable(self, "_on_toggle"))
+
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _on_toggle(toggled_on: bool):
+	if toggled_on:
+		text = "★"
+	else:
+		text = "☆"

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

@@ -0,0 +1 @@
+uid://7vfoh5kr4ftq

+ 93 - 53
scenes/menu/menu.tscn

@@ -4,7 +4,7 @@
 
 [node name="Window" type="Window"]
 transparent_bg = true
-size = Vector2i(650, 500)
+size = Vector2i(690, 500)
 borderless = true
 transparent = true
 popup_window = true
@@ -25,22 +25,20 @@ anchor_left = 0.5
 anchor_top = 0.5
 anchor_right = 0.5
 anchor_bottom = 0.5
-offset_left = -325.0
+offset_left = -345.0
 offset_top = -250.0
-offset_right = 325.0
+offset_right = 345.0
 offset_bottom = 250.0
 grow_horizontal = 2
 grow_vertical = 2
-current_tab = 1
+current_tab = 0
 
 [node name="Time Domain" type="TabContainer" parent="Control/select_effect"]
-visible = false
 layout_mode = 2
-current_tab = 5
+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
 
@@ -52,17 +50,17 @@ theme_override_constants/margin_right = 5
 theme_override_constants/margin_bottom = 10
 
 [node name="ScrollContainer" type="ScrollContainer" parent="Control/select_effect/Time Domain/Distort/MarginContainer"]
-custom_minimum_size = Vector2(620, 425)
+custom_minimum_size = Vector2(660, 425)
 layout_mode = 2
 size_flags_horizontal = 0
 horizontal_scroll_mode = 0
 
 [node name="DistortContainer" type="VBoxContainer" parent="Control/select_effect/Time Domain/Distort/MarginContainer/ScrollContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 
 [node name="Label" type="Label" parent="Control/select_effect/Time Domain/Distort/MarginContainer/ScrollContainer/DistortContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 size_flags_horizontal = 4
 text = "Processes that modify and distort the waveshape of a sound. Many of these distortions find points where the sound crosses zero twice (pseudo-wavecycles) and applies modifications to each wavecycle individually."
@@ -85,17 +83,17 @@ theme_override_constants/margin_right = 5
 theme_override_constants/margin_bottom = 10
 
 [node name="ScrollContainer" type="ScrollContainer" parent="Control/select_effect/Time Domain/Extend/MarginContainer"]
-custom_minimum_size = Vector2(620, 425)
+custom_minimum_size = Vector2(660, 425)
 layout_mode = 2
 size_flags_horizontal = 0
 horizontal_scroll_mode = 0
 
 [node name="ExtendContainer" type="VBoxContainer" parent="Control/select_effect/Time Domain/Extend/MarginContainer/ScrollContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 
 [node name="Label" type="Label" parent="Control/select_effect/Time Domain/Extend/MarginContainer/ScrollContainer/ExtendContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 size_flags_horizontal = 4
 text = "Processes adjust the length of a sound through some form of repetition. Many of these processes invovle some aspect of randomness and so running them multiple times will yeild different results."
@@ -118,17 +116,17 @@ theme_override_constants/margin_right = 5
 theme_override_constants/margin_bottom = 10
 
 [node name="ScrollContainer" type="ScrollContainer" parent="Control/select_effect/Time Domain/Filter/MarginContainer"]
-custom_minimum_size = Vector2(620, 425)
+custom_minimum_size = Vector2(660, 425)
 layout_mode = 2
 size_flags_horizontal = 0
 horizontal_scroll_mode = 0
 
 [node name="FilterContainer" type="VBoxContainer" parent="Control/select_effect/Time Domain/Filter/MarginContainer/ScrollContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 
 [node name="Label" type="Label" parent="Control/select_effect/Time Domain/Filter/MarginContainer/ScrollContainer/FilterContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 size_flags_horizontal = 4
 text = "Filters remove some frequencies from a sound while emphasising others. Many of these processes are filter banks which contain multiple bandpass filters. These can 'tune' a sound by emphasising specified frequencies."
@@ -151,17 +149,17 @@ theme_override_constants/margin_right = 5
 theme_override_constants/margin_bottom = 10
 
 [node name="ScrollContainer" type="ScrollContainer" parent="Control/select_effect/Time Domain/Granulate/MarginContainer"]
-custom_minimum_size = Vector2(620, 425)
+custom_minimum_size = Vector2(660, 425)
 layout_mode = 2
 size_flags_horizontal = 0
 horizontal_scroll_mode = 0
 
 [node name="GranulateContainer" type="VBoxContainer" parent="Control/select_effect/Time Domain/Granulate/MarginContainer/ScrollContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 
 [node name="Label" type="Label" parent="Control/select_effect/Time Domain/Granulate/MarginContainer/ScrollContainer/GranulateContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 size_flags_horizontal = 4
 text = "Processes that split sounds into tiny chunks (grains) and processes each grain individually, Depending on how grains are processed, ordered and layerd many different effects can be achieved. "
@@ -184,23 +182,28 @@ theme_override_constants/margin_right = 5
 theme_override_constants/margin_bottom = 10
 
 [node name="ScrollContainer" type="ScrollContainer" parent="Control/select_effect/Time Domain/Misc/MarginContainer"]
-custom_minimum_size = Vector2(620, 425)
+custom_minimum_size = Vector2(660, 425)
 layout_mode = 2
 size_flags_horizontal = 0
 horizontal_scroll_mode = 0
 
 [node name="MiscContainer" type="VBoxContainer" parent="Control/select_effect/Time Domain/Misc/MarginContainer/ScrollContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 
 [node name="Label" type="Label" parent="Control/select_effect/Time Domain/Misc/MarginContainer/ScrollContainer/MiscContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 size_flags_horizontal = 4
 text = "These time domain processes do not fit neatly into other categories. Many of these are utilities for editing a soundfile however, several are also transformation processes that manipulate the audio in unique ways."
 autowrap_mode = 3
 
+[node name="MarginContainer4" type="MarginContainer" parent="Control/select_effect/Time Domain/Misc/MarginContainer/ScrollContainer/MiscContainer"]
+layout_mode = 2
+theme_override_constants/margin_bottom = 5
+
 [node name="Reverb and Delay" type="VBoxContainer" parent="Control/select_effect/Time Domain"]
+visible = false
 layout_mode = 2
 metadata/_tab_index = 5
 
@@ -212,22 +215,26 @@ theme_override_constants/margin_right = 5
 theme_override_constants/margin_bottom = 10
 
 [node name="ScrollContainer" type="ScrollContainer" parent="Control/select_effect/Time Domain/Reverb and Delay/MarginContainer"]
-custom_minimum_size = Vector2(620, 425)
+custom_minimum_size = Vector2(660, 425)
 layout_mode = 2
 size_flags_horizontal = 0
 horizontal_scroll_mode = 0
 
 [node name="ReverbContainer" type="VBoxContainer" parent="Control/select_effect/Time Domain/Reverb and Delay/MarginContainer/ScrollContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 
 [node name="Label" type="Label" parent="Control/select_effect/Time Domain/Reverb and Delay/MarginContainer/ScrollContainer/ReverbContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 size_flags_horizontal = 4
 text = "These processes apply simple time-based effects to the sound such as reverb and delay. These are commonly used to emulate or give the impression of an acoustic space on a sound."
 autowrap_mode = 3
 
+[node name="MarginContainer4" type="MarginContainer" parent="Control/select_effect/Time Domain/Reverb and Delay/MarginContainer/ScrollContainer/ReverbContainer"]
+layout_mode = 2
+theme_override_constants/margin_bottom = 5
+
 [node name="Synthesis" type="VBoxContainer" parent="Control/select_effect/Time Domain"]
 visible = false
 layout_mode = 2
@@ -241,17 +248,17 @@ theme_override_constants/margin_right = 5
 theme_override_constants/margin_bottom = 10
 
 [node name="ScrollContainer" type="ScrollContainer" parent="Control/select_effect/Time Domain/Synthesis/MarginContainer"]
-custom_minimum_size = Vector2(620, 425)
+custom_minimum_size = Vector2(660, 425)
 layout_mode = 2
 size_flags_horizontal = 0
 horizontal_scroll_mode = 0
 
 [node name="SynthesisContainer" type="VBoxContainer" parent="Control/select_effect/Time Domain/Synthesis/MarginContainer/ScrollContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 
 [node name="Label" type="Label" parent="Control/select_effect/Time Domain/Synthesis/MarginContainer/ScrollContainer/SynthesisContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 size_flags_horizontal = 4
 text = "Unlike the other nodes in SoundThread that all process sound, these processes synthesis sounds. These can be used as alternative sound sources but are also very useful as sound sources for testing out various other processes to get a feel for what they do."
@@ -262,8 +269,9 @@ layout_mode = 2
 theme_override_constants/margin_bottom = 5
 
 [node name="Frequency Domain" type="TabContainer" parent="Control/select_effect"]
+visible = false
 layout_mode = 2
-current_tab = 2
+current_tab = 5
 metadata/_tab_index = 1
 
 [node name="Convert" type="VBoxContainer" parent="Control/select_effect/Frequency Domain"]
@@ -279,17 +287,17 @@ theme_override_constants/margin_right = 5
 theme_override_constants/margin_bottom = 10
 
 [node name="ScrollContainer" type="ScrollContainer" parent="Control/select_effect/Frequency Domain/Convert/MarginContainer"]
-custom_minimum_size = Vector2(620, 425)
+custom_minimum_size = Vector2(660, 425)
 layout_mode = 2
 size_flags_horizontal = 0
 horizontal_scroll_mode = 0
 
 [node name="PVOCConvertContainer" type="VBoxContainer" parent="Control/select_effect/Frequency Domain/Convert/MarginContainer/ScrollContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 
 [node name="Label" type="Label" parent="Control/select_effect/Frequency Domain/Convert/MarginContainer/ScrollContainer/PVOCConvertContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 size_flags_horizontal = 4
 text = "To use the frequency domain processes you must first convert the sound using Analyse and then once you have processed the frequency domain data convert it back to audio again using Resynthesise. For more information on the frequency domain processes, see Help > Tutorials > Frequency Domain."
@@ -312,17 +320,17 @@ theme_override_constants/margin_right = 5
 theme_override_constants/margin_bottom = 10
 
 [node name="ScrollContainer" type="ScrollContainer" parent="Control/select_effect/Frequency Domain/Amplitude and Pitch/MarginContainer"]
-custom_minimum_size = Vector2(620, 425)
+custom_minimum_size = Vector2(660, 425)
 layout_mode = 2
 size_flags_horizontal = 0
 horizontal_scroll_mode = 0
 
 [node name="PVOCAmplitudePitchContainer" type="VBoxContainer" parent="Control/select_effect/Frequency Domain/Amplitude and Pitch/MarginContainer/ScrollContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 
 [node name="Label" type="Label" parent="Control/select_effect/Frequency Domain/Amplitude and Pitch/MarginContainer/ScrollContainer/PVOCAmplitudePitchContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 size_flags_horizontal = 4
 text = "These processes operate on frequency domain analysis data to alter the loudness and/or pitch of some or all of the sound."
@@ -333,6 +341,7 @@ layout_mode = 2
 theme_override_constants/margin_bottom = 5
 
 [node name="Combine" type="VBoxContainer" parent="Control/select_effect/Frequency Domain"]
+visible = false
 layout_mode = 2
 metadata/_tab_index = 2
 
@@ -344,17 +353,17 @@ theme_override_constants/margin_right = 5
 theme_override_constants/margin_bottom = 10
 
 [node name="ScrollContainer" type="ScrollContainer" parent="Control/select_effect/Frequency Domain/Combine/MarginContainer"]
-custom_minimum_size = Vector2(620, 425)
+custom_minimum_size = Vector2(660, 425)
 layout_mode = 2
 size_flags_horizontal = 0
 horizontal_scroll_mode = 0
 
 [node name="PVOCCombineContainer" type="VBoxContainer" parent="Control/select_effect/Frequency Domain/Combine/MarginContainer/ScrollContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 
 [node name="Label" type="Label" parent="Control/select_effect/Frequency Domain/Combine/MarginContainer/ScrollContainer/PVOCCombineContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 size_flags_horizontal = 4
 text = "These processes take multiple inputs and combine them into one output. This is not mixing in the conventional sense, instead these processes can be used to morph between sounds or create hybrids of sounds."
@@ -377,17 +386,17 @@ theme_override_constants/margin_right = 5
 theme_override_constants/margin_bottom = 10
 
 [node name="ScrollContainer" type="ScrollContainer" parent="Control/select_effect/Frequency Domain/Formants/MarginContainer"]
-custom_minimum_size = Vector2(620, 425)
+custom_minimum_size = Vector2(660, 425)
 layout_mode = 2
 size_flags_horizontal = 0
 horizontal_scroll_mode = 0
 
 [node name="PVOCFormantsContainer" type="VBoxContainer" parent="Control/select_effect/Frequency Domain/Formants/MarginContainer/ScrollContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 
 [node name="Label" type="Label" parent="Control/select_effect/Frequency Domain/Formants/MarginContainer/ScrollContainer/PVOCFormantsContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 size_flags_horizontal = 4
 text = "These processes operate on frequency domain analysis data to manipulate or add formants to a sound. Formants are prominent peaks in the frequency spectrum that give sounds part of their timbre. They are essential in speech for discerning different vowel sounds."
@@ -410,17 +419,17 @@ theme_override_constants/margin_right = 5
 theme_override_constants/margin_bottom = 10
 
 [node name="ScrollContainer" type="ScrollContainer" parent="Control/select_effect/Frequency Domain/Time/MarginContainer"]
-custom_minimum_size = Vector2(620, 425)
+custom_minimum_size = Vector2(660, 425)
 layout_mode = 2
 size_flags_horizontal = 0
 horizontal_scroll_mode = 0
 
 [node name="PVOCTimeContainer" type="VBoxContainer" parent="Control/select_effect/Frequency Domain/Time/MarginContainer/ScrollContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 
 [node name="Label" type="Label" parent="Control/select_effect/Frequency Domain/Time/MarginContainer/ScrollContainer/PVOCTimeContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 size_flags_horizontal = 4
 text = "These processes operate on frequency domain analysis data to transform something about how a sound evolves over time."
@@ -431,7 +440,6 @@ layout_mode = 2
 theme_override_constants/margin_bottom = 5
 
 [node name="Spectrum" type="VBoxContainer" parent="Control/select_effect/Frequency Domain"]
-visible = false
 layout_mode = 2
 metadata/_tab_index = 5
 
@@ -443,17 +451,17 @@ theme_override_constants/margin_right = 5
 theme_override_constants/margin_bottom = 10
 
 [node name="ScrollContainer" type="ScrollContainer" parent="Control/select_effect/Frequency Domain/Spectrum/MarginContainer"]
-custom_minimum_size = Vector2(620, 425)
+custom_minimum_size = Vector2(660, 425)
 layout_mode = 2
 size_flags_horizontal = 0
 horizontal_scroll_mode = 0
 
 [node name="PVOCSpectrumContainer" type="VBoxContainer" parent="Control/select_effect/Frequency Domain/Spectrum/MarginContainer/ScrollContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 
 [node name="Label" type="Label" parent="Control/select_effect/Frequency Domain/Spectrum/MarginContainer/ScrollContainer/PVOCSpectrumContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 size_flags_horizontal = 4
 text = "These processes operate on frequency domain analysis data to alter the spectral content of a sound. This can include removing certain frequencies or adding additional frequencies into the sound."
@@ -481,17 +489,17 @@ theme_override_constants/margin_right = 5
 theme_override_constants/margin_bottom = 10
 
 [node name="ScrollContainer" type="ScrollContainer" parent="Control/select_effect/Utilities/SoundThread/MarginContainer"]
-custom_minimum_size = Vector2(620, 425)
+custom_minimum_size = Vector2(660, 425)
 layout_mode = 2
 size_flags_horizontal = 0
 horizontal_scroll_mode = 0
 
 [node name="UtilityContainer" type="VBoxContainer" parent="Control/select_effect/Utilities/SoundThread/MarginContainer/ScrollContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 
 [node name="Label" type="Label" parent="Control/select_effect/Utilities/SoundThread/MarginContainer/ScrollContainer/UtilityContainer"]
-custom_minimum_size = Vector2(620, 0)
+custom_minimum_size = Vector2(660, 0)
 layout_mode = 2
 size_flags_horizontal = 4
 text = "The nodes in this section are not part of the Composers Desktop Project. They are small utilities that have been added to SoundThread to help make using CDP slightly easier."
@@ -501,12 +509,44 @@ autowrap_mode = 3
 layout_mode = 2
 theme_override_constants/margin_bottom = 5
 
-[node name="Search" type="TabContainer" parent="Control/select_effect"]
+[node name="Favourites" type="TabContainer" parent="Control/select_effect"]
 visible = false
 layout_mode = 2
 current_tab = 0
 metadata/_tab_index = 3
 
+[node name="Browse Favourites" type="VBoxContainer" parent="Control/select_effect/Favourites"]
+layout_mode = 2
+metadata/_tab_index = 0
+
+[node name="MarginContainer" type="MarginContainer" parent="Control/select_effect/Favourites/Browse Favourites"]
+layout_mode = 2
+theme_override_constants/margin_left = 15
+theme_override_constants/margin_top = 10
+theme_override_constants/margin_right = 5
+theme_override_constants/margin_bottom = 10
+
+[node name="VBoxContainer" type="VBoxContainer" parent="Control/select_effect/Favourites/Browse Favourites/MarginContainer"]
+custom_minimum_size = Vector2(660, 420)
+layout_mode = 2
+size_flags_horizontal = 0
+
+[node name="ScrollContainer" type="ScrollContainer" parent="Control/select_effect/Favourites/Browse Favourites/MarginContainer/VBoxContainer"]
+custom_minimum_size = Vector2(0, 10)
+layout_mode = 2
+size_flags_vertical = 3
+horizontal_scroll_mode = 0
+
+[node name="ItemContainer" type="VBoxContainer" parent="Control/select_effect/Favourites/Browse Favourites/MarginContainer/VBoxContainer/ScrollContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+
+[node name="Search" type="TabContainer" parent="Control/select_effect"]
+visible = false
+layout_mode = 2
+current_tab = 0
+metadata/_tab_index = 4
+
 [node name="Search for a process in SoundThread" type="VBoxContainer" parent="Control/select_effect/Search"]
 layout_mode = 2
 metadata/_tab_index = 0
@@ -519,7 +559,7 @@ theme_override_constants/margin_right = 5
 theme_override_constants/margin_bottom = 10
 
 [node name="VBoxContainer" type="VBoxContainer" parent="Control/select_effect/Search/Search for a process in SoundThread/MarginContainer"]
-custom_minimum_size = Vector2(620, 420)
+custom_minimum_size = Vector2(660, 420)
 layout_mode = 2
 size_flags_horizontal = 0
 

+ 19 - 3
scenes/menu/search_menu.gd

@@ -9,6 +9,7 @@ var node_to_replace
 var connect_to_node = false
 var node_to_connect_to
 var uiscale
+var favourites
 signal make_node(command)
 signal swap_node(node_to_replace, command)
 signal connect_to_clicked_node(node_to_connect_to, command)
@@ -32,9 +33,12 @@ func _ready() -> void:
 
 
 func _on_about_to_popup() -> void:
+	var interface_settings = ConfigHandler.load_interface_settings()
+	favourites = interface_settings.favourites
 	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
@@ -47,6 +51,11 @@ func display_items(filter: String):
 		var item = node_data[key]
 		var title = item.get("title", "")
 		
+		#check if searching for favourites
+		if filters.has("*"):
+			if favourites.has(key) == false:
+				continue
+		
 		#filter out output node
 		if title == "Output File":
 			continue
@@ -65,6 +74,9 @@ func display_items(filter: String):
 		if filter != "":
 			var match_all_words = true
 			for word in filters:
+				if word == "*":
+					continue
+					
 				if word != "" and not searchable_text.findn(word) != -1:
 					match_all_words = false
 					break
@@ -76,12 +88,16 @@ func display_items(filter: String):
 		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 ...
+		var button_text = ""
+		if favourites.has(key):
+			button_text += "★ "
 		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]
+			button_text += "%s %s: %s - %s" % [category.to_upper(), subcategory.to_pascal_case(), title, short_desc]
 		elif title.to_lower() == "input file":
-			btn.text = "%s - %s" % [title, short_desc]
+			button_text += "%s - %s" % [title, short_desc]
 		else:
-			btn.text = "%s: %s - %s" % [subcategory.to_pascal_case(), title, short_desc]
+			button_text += "%s: %s - %s" % [subcategory.to_pascal_case(), title, short_desc]
+		btn.text = button_text
 		btn.connect("pressed", Callable(self, "_on_item_selected").bind(key)) #pass key (process name) when button is pressed
 		
 		#apply custom focus theme for keyboard naviagation

File diff suppressed because it is too large
+ 2 - 2
theme/main_theme.tres


Some files were not shown because too many files changed in this diff