Skip to content

Commit

Permalink
Merge branch 'master' into variadic-sdf-boolean
Browse files Browse the repository at this point in the history
  • Loading branch information
williamchange committed Apr 30, 2024
2 parents f1764b9 + 246d808 commit 72d6921
Show file tree
Hide file tree
Showing 147 changed files with 5,533 additions and 1,541 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dev-desktop-builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ on:
description: 'Generate documentation'
type: boolean
required: true
default: 'false'
default: 'true'

env:
GODOT_VERSION: 4.2
Expand Down
22 changes: 18 additions & 4 deletions addons/flexible_layout/flexible_dragger.gd
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,29 @@ func set_split(s, i : int, v : bool):
mouse_default_cursor_shape = Control.CURSOR_HSPLIT
$TextureRect.texture = get_theme_icon("grabber", "HSplitContainer")

var drag_limits : Vector2i
var drag_position : int

func _on_gui_input(event):
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT:
dragging = event.pressed
if vertical:
drag_position = position.y
else:
drag_position = position.x
drag_limits = flex_split.get_ref().start_drag(dragger_index, drag_position)
elif event is InputEventMouseMotion:
if dragging:
if vertical:
position.y += event.position.y-5
flex_split.get_ref().drag(dragger_index, position.y)
drag_position = position.y+event.position.y-5
var new_position_y = clampi(drag_position, drag_limits.x, drag_limits.y)
if position.y != new_position_y:
position.y = new_position_y
flex_split.get_ref().drag(dragger_index, position.y)
else:
position.x += event.position.x-5
flex_split.get_ref().drag(dragger_index, position.x)
drag_position = position.x+event.position.x-5
var new_position_x = clampi(drag_position, drag_limits.x, drag_limits.y)
if position.x != new_position_x:
position.x = new_position_x
flex_split.get_ref().drag(dragger_index, position.x)
124 changes: 104 additions & 20 deletions addons/flexible_layout/flexible_layout.gd
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ class FlexNode:
if parent.get_ref() != null:
parent.get_ref().replace(self, null)

func get_minimum_size() -> Vector2i:
assert(false)
return Vector2i(0, 0)

func serialize() -> Dictionary:
var rv : Dictionary = { type=type, w=rect.size.x, h=rect.size.y, children=[] }
for c in get_children():
Expand Down Expand Up @@ -66,6 +70,9 @@ class FlexTop:
func _init(fl : FlexLayout):
super._init(null, fl, "FlexTop")

func get_minimum_size() -> Vector2i:
return child.get_minimum_size() if child else Vector2i(0, 0)

func deserialize(data : Dictionary):
super.deserialize(data)
child = flexible_layout.deserialize(self, data.children[0])
Expand Down Expand Up @@ -112,6 +119,22 @@ class FlexSplit:
if is_instance_valid(d):
d.queue_free()

func get_minimum_size() -> Vector2i:
var s : Vector2i
if vertical:
s = Vector2i(0, (10*children.size()-1))
for c in children:
var ms : Vector2i = c.get_minimum_size()
s.x = max(s.x, ms.x)
s.y += ms.y
else:
s = Vector2i(10*(children.size()-1), 0)
for c in children:
var ms : Vector2i = c.get_minimum_size()
s.x += ms.x
s.y = max(s.y, ms.y)
return s

func serialize() -> Dictionary:
var rv : Dictionary = super.serialize()
rv.dir = "v" if vertical else "h"
Expand Down Expand Up @@ -210,7 +233,17 @@ class FlexSplit:
var width : int = (c.rect.size.x*new_width+(old_width>>1))/old_width
c.layout(Rect2(x, r.position.y, width, r.size.y))
x += width


func start_drag(dragger_index : int, p : int) -> Vector2i:
var c1 = children[dragger_index]
var c2 = children[dragger_index+1]
var min_c1_size : Vector2i = c1.get_minimum_size()
var min_c2_size : Vector2i = c2.get_minimum_size()
if vertical:
return Vector2i(c1.rect.position.y+min_c1_size.y, c2.rect.position.y+c2.rect.size.y-min_c2_size.y-10)
else:
return Vector2i(c1.rect.position.x+min_c1_size.x, c2.rect.position.x+c2.rect.size.x-min_c2_size.x-10)

func drag(dragger_index : int, p : int):
var c1 = children[dragger_index]
var c2 = children[dragger_index+1]
Expand Down Expand Up @@ -241,6 +274,15 @@ class FlexTab:
if is_instance_valid(tabs):
tabs.queue_free()

func get_minimum_size() -> Vector2i:
var s : Vector2i = Vector2i(0, 0)
for t : Control in tabs.get_controls():
var ms : Vector2i = t.get_combined_minimum_size()
s.x = max(s.x, ms.x)
s.y = max(s.y, ms.y)
s.y += tabs.get_combined_minimum_size().y
return s

func serialize() -> Dictionary:
var rv : Dictionary = super.serialize()
rv.tabs = []
Expand All @@ -253,6 +295,8 @@ class FlexTab:
super.deserialize(data)
for c in data.tabs:
add(flexible_layout.main_control.panels[c])
if data.has("current"):
tabs.set_current(data.current)

func add(fp : Control):
adding = true
Expand Down Expand Up @@ -303,6 +347,9 @@ class FlexMain:
super._init(p, fl)
type = "FlexMain"

func get_minimum_size() -> Vector2i:
return child.get_combined_minimum_size()

func deserialize(data : Dictionary):
super.deserialize(data)
add(flexible_layout.main_control.panels["Main"])
Expand Down Expand Up @@ -421,19 +468,28 @@ class FlexLayout:
layout()

func layout():
var rect : Rect2i = control.get_rect()
if rect.size.x == 0 or rect.size.y == 0:
return
if top:
top.layout(control.get_rect())
main_control.layout_changed.emit()

func move_panel(panel, reference_panel : FlexNode, destination):
func move_panel(panel, reference_panel : FlexNode, destination : int, test_only : bool = false) -> bool:
var parent_panel : FlexNode = reference_panel.parent.get_ref() as FlexNode
# if current container has only 1 tab, it cannot be dropped into or near itself
var into_same_tab : bool = false
if reference_panel is FlexTab and reference_panel == panel.flex_panel.get_meta("flex_node"):
into_same_tab = true
if reference_panel.tabs.get_controls().size() == 1:
return false
var vertical : bool
var offset : int
var tab : FlexTab = null
match destination:
0:
if not reference_panel is FlexTab:
return
if not reference_panel is FlexTab or into_same_tab:
return false
tab = reference_panel
1:
vertical = true
Expand All @@ -448,21 +504,23 @@ class FlexLayout:
vertical = true
offset = 1
_:
return
if tab == null:
var split : FlexSplit
if parent_panel is FlexSplit and parent_panel.vertical == vertical:
split = parent_panel as FlexSplit
else:
split = FlexSplit.new(parent_panel, reference_panel.flexible_layout)
split.vertical = vertical
parent_panel.replace(reference_panel, split)
split.insert(reference_panel, 0)
tab = FlexTab.new(parent_panel, reference_panel.flexible_layout)
var ref_index : int = split.find(reference_panel)
split.insert(tab, ref_index+offset, ref_index)
tab.add(panel.flex_panel)
layout()
return false
if not test_only:
if tab == null:
var split : FlexSplit
if parent_panel is FlexSplit and parent_panel.vertical == vertical:
split = parent_panel as FlexSplit
else:
split = FlexSplit.new(parent_panel, reference_panel.flexible_layout)
split.vertical = vertical
parent_panel.replace(reference_panel, split)
split.insert(reference_panel, 0)
tab = FlexTab.new(parent_panel, reference_panel.flexible_layout)
var ref_index : int = split.find(reference_panel)
split.insert(tab, ref_index+offset, ref_index)
tab.add(panel.flex_panel)
layout()
return true

func undock(panel : Control):
main_control.subwindows.append(FlexWindow.new(main_control, panel))
Expand Down Expand Up @@ -506,6 +564,7 @@ class FlexWindow:

func serialize() -> Dictionary:
var data : Dictionary = {}
data.screen = current_screen
data.x = position.x
data.y = position.y
data.w = size.x
Expand All @@ -514,6 +573,10 @@ class FlexWindow:
return data

func init(data : Dictionary):
if data.has("screen"):
current_screen = data.screen
else:
current_screen = 0
position = Vector2i(data.x, data.y)
size = Vector2i(data.w, data.h)
flex_layout.init(data.layout)
Expand All @@ -530,6 +593,9 @@ class FlexWindow:
overlay.queue_free()
overlay = null


@export var allow_undock : bool = false

var panels : Dictionary = {}
var flex_layout : FlexLayout
var subwindows : Array[Window]
Expand All @@ -552,17 +618,35 @@ func _ready():
if c.visible and ! c.has_meta("flexlayout"):
add(c.name, c)

func _notification(what):
match what:
NOTIFICATION_THEME_CHANGED:
var new_theme = null
var control = self
while control:
if control is Control and control.theme != null:
new_theme = control.theme
break
control = control.get_parent()
if new_theme != null:
for w in subwindows:
for c in w.get_children():
if c is Control:
c.theme = new_theme

func add(n : String, c : Control):
c.name = n
c.set_meta("flex_layout", self)
panels[n] = c

func init(layout = null):
for p in panels.keys():
show_panel(p, false)
if layout and layout.has("main"):
for w in layout.windows:
var subwindow = FlexWindow.new(self)
subwindow.init(w)
subwindows.append(subwindow)
subwindow.layout(w)
flex_layout.init(layout.main)
else:
flex_layout.init(layout)
Expand Down
40 changes: 29 additions & 11 deletions addons/flexible_layout/flexible_overlay.gd
Original file line number Diff line number Diff line change
Expand Up @@ -7,56 +7,74 @@ var arrow_icon = preload("res://addons/flexible_layout/arrow.svg")
var tab_icon = preload("res://addons/flexible_layout/tab.svg")


func find_position_from_target(at_position, target):
const MARKER_WIDTH : int = 10
const ARROW_OFFSET : int = 5


func find_position_from_target(at_position, target) -> int:
const POSITIONS = [ -1, 1, -1, 2, 0, 3, -1, 4, -1]
var pos_x = int(3*(at_position.x-target.rect.position.x) / target.rect.size.x)
var pos_y = int(3*(at_position.y-target.rect.position.y) / target.rect.size.y)
return POSITIONS[pos_x+3*pos_y]

func _drop_data(at_position, data):
at_position /= get_window().content_scale_factor
var target = flex_layout.get_flexnode_at(at_position)
if target:
var destination = find_position_from_target(at_position, target)
if destination != -1:
flex_layout.move_panel(data, target, destination)

func _can_drop_data(at_position, data):
at_position /= get_window().content_scale_factor
var target = flex_layout.get_flexnode_at(at_position)
if target:
var rect : Rect2 = target.rect
match find_position_from_target(at_position, target):
var destination : int = find_position_from_target(at_position, target)
if not flex_layout.move_panel(data, target, destination, true):
destination = -1
match destination:
0:
if data.flex_panel.get_meta("flex_node") == target:
$Arrow.visible = false
return false
$Arrow.visible = true
$Arrow.texture = tab_icon
$Arrow.position = rect.get_center()-Vector2(32, 32)
$Arrow.rotation_degrees = 0
$Rect.visible = true
$Rect.position = rect.position
$Rect.size = rect.size
1:
$Arrow.visible = true
$Arrow.texture = arrow_icon
$Arrow.position = Vector2(rect.get_center().x-32, rect.position.y)
$Arrow.position = Vector2(rect.get_center().x-32, rect.position.y+ARROW_OFFSET)
$Arrow.rotation_degrees = 0
$Rect.visible = true
$Rect.position = rect.position
$Rect.size = Vector2i(rect.size.x, MARKER_WIDTH)
2:
$Arrow.visible = true
$Arrow.texture = arrow_icon
$Arrow.position = Vector2(rect.position.x, rect.get_center().y-32)
$Arrow.position = Vector2(rect.position.x+ARROW_OFFSET, rect.get_center().y-32)
$Arrow.rotation_degrees = -90
$Rect.visible = true
$Rect.position = rect.position
$Rect.size = Vector2i(MARKER_WIDTH, rect.size.y)
3:
$Arrow.visible = true
$Arrow.texture = arrow_icon
$Arrow.position = Vector2(rect.end.x-64, rect.get_center().y-32)
$Arrow.position = Vector2(rect.end.x-64-ARROW_OFFSET, rect.get_center().y-32)
$Arrow.rotation_degrees = 90
$Rect.visible = true
$Rect.position = Vector2i(rect.end.x-MARKER_WIDTH, rect.position.y)
$Rect.size = Vector2i(MARKER_WIDTH, rect.size.y)
4:
$Arrow.visible = true
$Arrow.texture = arrow_icon
$Arrow.position = Vector2(rect.get_center().x-32, rect.end.y-64)
$Arrow.position = Vector2(rect.get_center().x-32, rect.end.y-64-ARROW_OFFSET)
$Arrow.rotation_degrees = 180
$Rect.visible = true
$Rect.position = Vector2i(rect.position.x, rect.end.y-MARKER_WIDTH)
$Rect.size = Vector2i(rect.size.x, MARKER_WIDTH)
_:
$Arrow.visible = false
$Rect.visible = false
return false
return true

10 changes: 9 additions & 1 deletion addons/flexible_layout/flexible_overlay.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0.513726, 0.513726, 0.513726, 0.501961)
color = Color(0.501961, 0.501961, 0.501961, 0.501961)
script = ExtResource("1_5tomg")

[node name="Arrow" type="TextureRect" parent="."]
Expand All @@ -19,3 +19,11 @@ offset_right = 40.0
offset_bottom = 40.0
pivot_offset = Vector2(32, 32)
texture = ExtResource("2_0tnc1")

[node name="Rect" type="ColorRect" parent="."]
visible = false
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
mouse_filter = 2
color = Color(1, 1, 1, 0.501961)
Loading

0 comments on commit 72d6921

Please sign in to comment.