miggor-StreamGraph/graph_node_renderer/tab_container_custom.gd
2024-01-17 11:15:42 +03:00

148 lines
4.7 KiB
GDScript

# (c) 2023-present Eroax
# (c) 2023-present Yagich
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
extends VBoxContainer
class_name TabContainerCustom
## Custom Recreation of [TabContainer] for Flexibility
##
## Alternative to [TabContainer]. Instead of using the tree hierarchy to add tabs directly,
## tabs must be created by script.
## Reference to the [TabBar] at the top of the container.
@onready var tab_bar: TabBar = %TabBar
## Reference to the [Button] at the end of the [TabBar] that's
## used for adding new tabs.
@onready var add_tab_button: Button = %Button
## Reference to the [MarginContainer] around the tab's contents.
@onready var content_container: MarginContainer = %ContentContainer
## Emitted when the add [Button] within [member tab_bar] is pressed.
signal add_button_pressed
## Emitted when the current tab in [member tab_bar] is changed.
signal tab_changed(tab: int)
## Emitted just before the current tab in [member tab_bar] is changed.s
signal tab_about_to_change(previous_tab: int)
## Emitted when a tab in [member tab_bar] has been closed.
## See [signal TabBar.tab_close_requested]
signal tab_closed(tab: int)
## Emitted when a request to close a tab in the [member tab_bar] has been requested.
signal tab_close_requested(tab: int)
## Emitted when the order of the tabs in [member tab_bar] has been changed.
signal tab_rearranged(old: int, new: int)
# Holds the previously active tab in the internal tab_bar
var _previous_active_tab: int = -1
var _tab_metadata: Array[Dictionary] #Array[Dictionary[String -> key, Variant]]
func _ready() -> void:
tab_bar.tab_selected.connect(
func(tab: int):
if _previous_active_tab == tab:
return
tab_about_to_change.emit(_previous_active_tab)
if _previous_active_tab > -1:
content_container.get_child(_previous_active_tab).visible = false
content_container.get_child(tab).visible = true
tab_changed.emit(tab)
_previous_active_tab = tab
)
tab_bar.tab_close_pressed.connect(func(tab: int): tab_close_requested.emit(tab))
add_tab_button.pressed.connect(
func():
add_button_pressed.emit()
)
tab_bar.active_tab_rearranged.connect(
func(idx_to: int):
var old := _tab_metadata[_previous_active_tab]
var new := _tab_metadata[idx_to]
_tab_metadata[idx_to] = old
_tab_metadata[_previous_active_tab] = new
tab_rearranged.emit(_previous_active_tab, idx_to)
content_container.move_child(content_container.get_child(_previous_active_tab), idx_to)
_previous_active_tab = idx_to
)
## Adds the given [Node] as the displayed content for a tab.
func add_content(c: Node, tab_title: String) -> int:
tab_bar.add_tab(tab_title)
content_container.add_child(c)
#tab_bar.set_current_tab(tab_bar.tab_count - 1)
_tab_metadata.append({})
return tab_bar.tab_count - 1
## Updates the tab at index [param tab_idx]'s title to [param title].
func set_tab_title(tab_idx: int, title: String) -> void:
tab_bar.set_tab_title(tab_idx, title)
func get_tab_title(tab_idx: int) -> String:
return tab_bar.get_tab_title(tab_idx)
## Returns the number of tabs.
func get_tab_count() -> int:
return tab_bar.tab_count
## Returns [code]true[/code] if the tab bar has no tabs.
func is_empty() -> bool:
return get_tab_count() == 0
## Closes a tab at the index [param tab].
func close_tab(tab: int) -> void:
content_container.get_child(tab).queue_free()
_tab_metadata.remove_at(tab)
tab_bar.remove_tab(tab)
if !tab_bar.select_previous_available():
tab_bar.select_next_available()
tab_closed.emit(tab)
if tab_bar.tab_count == 0:
_previous_active_tab = -1
## Returns the currently selected tab.
func get_current_tab() -> int:
return tab_bar.current_tab
## Sets the current tab to the tab at [param idx].
func set_current_tab(idx: int) -> void:
tab_bar.current_tab = idx
## Returns the child of [member content_container] at the [param idx].
func get_content(idx: int) -> Control:
return content_container.get_child(idx)
## Sets the metadata value for the tab at index [param tab_idx] at [param key], which can be
## retrieved later using [method get_tab_metadata].
func set_tab_metadata(tab: int, key: String, value: Variant) -> void:
#var m = _tab_metadata.get(tab, {})
#m[key] = value
#_tab_metadata[tab] = m
var m := _tab_metadata[tab]
m[key] = value
## Returns the metadata value set to the tab at index [param tab_idx] using [method set_tab_metadata].
## If no metadata was previously set, returns [code]null[/code] by default.
func get_tab_metadata(tab: int, key: String, default: Variant = null) -> Variant:
#if _tab_metadata.size() - 1 < tab:
#return default
#if tab < _tab_metadata.size():
#return default
assert(tab < _tab_metadata.size())
var m = _tab_metadata[tab]
return m.get(key, default)