142 lines
3.7 KiB
GDScript
142 lines
3.7 KiB
GDScript
extends WindowDialog
|
|
|
|
const FlexView = preload("res://addons/de.mewin.gduibasics/scenes/scripts/flexview.gd")
|
|
|
|
var flex_view : FlexView setget _set_flex_view, _get_flex_view
|
|
|
|
var __drop_target : FlexView = null
|
|
var __is_dragging := false
|
|
|
|
#############
|
|
# overrides #
|
|
#############
|
|
func _ready() -> void:
|
|
set_process(false) # only used to stop dropping when mouse button is lifted
|
|
__update_title()
|
|
|
|
func _process(delta : float) -> void:
|
|
if !Input.is_mouse_button_pressed(BUTTON_LEFT):
|
|
__drop()
|
|
|
|
func _input(event : InputEvent) -> void:
|
|
if event is InputEventKey && event.scancode == KEY_SHIFT && __is_dragging:
|
|
__update_dragging()
|
|
|
|
#################
|
|
# private stuff #
|
|
#################
|
|
func __update_view_count() -> void:
|
|
var child := __get_flex_child()
|
|
if !(child is FlexView):
|
|
return
|
|
|
|
var count : int = child.get_view_count()
|
|
if count == 0:
|
|
self.queue_free()
|
|
return
|
|
else:
|
|
# child.show_tabs = (count > 1)
|
|
pass
|
|
|
|
func __update_dragging() -> void:
|
|
var child := __get_flex_child()
|
|
if !(child is FlexView) || child.get_view_count() > 1:
|
|
set_process(false)
|
|
__is_dragging = false
|
|
return
|
|
|
|
__is_dragging = true
|
|
set_process(true)
|
|
|
|
# dragging with shift disables dropping
|
|
if Input.is_key_pressed(KEY_SHIFT):
|
|
__set_drop_target(null)
|
|
return
|
|
|
|
var mouse_pos := get_viewport().get_mouse_position()
|
|
var flex_views := get_tree().get_nodes_in_group(FlexView.GROUP_NAME)
|
|
var views_under_cursor := []
|
|
|
|
for view in flex_views:
|
|
if !self.is_a_parent_of(view) && view.visible && view.get_global_rect().has_point(mouse_pos):
|
|
views_under_cursor.append(view)
|
|
|
|
if views_under_cursor.empty():
|
|
__set_drop_target(null)
|
|
return
|
|
|
|
# find first in tree
|
|
var target : FlexView = views_under_cursor[0]
|
|
for i in range(1, views_under_cursor.size()):
|
|
var node : FlexView = views_under_cursor[i]
|
|
if GDBUtility.control_is_in_front_of(node, target):
|
|
target = node
|
|
__set_drop_target(target)
|
|
|
|
func __set_drop_target(target : FlexView) -> void:
|
|
if target == __drop_target:
|
|
return
|
|
set_process(is_instance_valid(__drop_target)) # process to check if mouse button is lifted
|
|
|
|
if is_instance_valid(__drop_target):
|
|
__drop_target._stop_dropping()
|
|
__drop_target = target
|
|
if is_instance_valid(__drop_target):
|
|
__drop_target._start_dropping()
|
|
|
|
func __drop() -> void:
|
|
var child := __get_flex_child()
|
|
set_process(false)
|
|
__is_dragging = false
|
|
|
|
if !is_instance_valid(__drop_target) || !(child is FlexView) || child.get_view_count() != 1:
|
|
return
|
|
|
|
var control : Control = child.get_view_control(0)
|
|
child.remove_view(0)
|
|
__drop_target._drop(control)
|
|
self.queue_free()
|
|
|
|
func __update_title() -> void:
|
|
var child := __get_flex_child()
|
|
if !(child is FlexView):
|
|
window_title = ""
|
|
elif child.get_view_count() > 0:
|
|
window_title = child.get_view_title(child.current_view)
|
|
|
|
func __get_flex_child() -> Control:
|
|
return get_child(1) as Control # TODO: something better (and safer) than a fixed index
|
|
|
|
func __close_requested() -> void:
|
|
for flex_view in GDBUtility.find_nodes_by_type(self, FlexView):
|
|
flex_view.close_all_views()
|
|
|
|
#####################
|
|
# setters & getters #
|
|
#####################
|
|
func _set_flex_view(val) -> void:
|
|
assert(0, "Cannot set this.")
|
|
|
|
func _get_flex_view() -> FlexView:
|
|
return $flex_view as FlexView
|
|
|
|
###################
|
|
# signal handlers #
|
|
###################
|
|
func _on_flex_view_view_added(view : int, flex_view : FlexView) -> void:
|
|
__update_view_count()
|
|
|
|
func _on_flex_view_view_removed(view : int, flex_view : FlexView) -> void:
|
|
__update_view_count()
|
|
|
|
func _on_flexview_window_item_rect_changed() -> void:
|
|
__update_dragging()
|
|
|
|
func _on_flex_view_current_view_changed(flex_view : FlexView):
|
|
__update_title()
|
|
|
|
func _on_flexview_window_visibility_changed():
|
|
if !visible:
|
|
__close_requested()
|
|
visible = true
|