Skip to content

Commit

Permalink
Added layout load/save and updated a few panels
Browse files Browse the repository at this point in the history
  • Loading branch information
RodZill4 committed Nov 26, 2023
1 parent b6c792f commit 3133fbc
Show file tree
Hide file tree
Showing 13 changed files with 202 additions and 149 deletions.
8 changes: 4 additions & 4 deletions addons/flexible_layout/flexible_dragger.gd
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ extends Control


var dragging : bool = false
var flex_split
var flex_split : WeakRef
var dragger_index : int
var vertical : bool

func _init():
set_meta("flexlayout", true)

func set_split(s, i : int, v : bool):
flex_split = s
flex_split = weakref(s)
dragger_index = i
vertical = v
if vertical:
Expand All @@ -28,7 +28,7 @@ func _on_gui_input(event):
if dragging:
if vertical:
position.y += event.position.y-5
flex_split.drag(dragger_index, position.y)
flex_split.get_ref().drag(dragger_index, position.y)
else:
position.x += event.position.x-5
flex_split.drag(dragger_index, position.x)
flex_split.get_ref().drag(dragger_index, position.x)
183 changes: 117 additions & 66 deletions addons/flexible_layout/flexible_layout.gd
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
extends Control


class FlexPanel:
var name : String
var widget : Control


class FlexNode:
extends RefCounted
var type : String
var parent : FlexNode = null
var parent : WeakRef
var flexible_layout : Control
var rect : Rect2 = Rect2(0, 0, 1000, 1000)

func _init(p : FlexNode = null,fl : Control = null):
func _init(p : FlexNode = null, fl : Control = null):
type = "FlexNode"
parent = p
parent = weakref(p)
flexible_layout = fl

func _notification(what):
if what == NOTIFICATION_PREDELETE:
print("removing %s!" % type)
print("removing %s (%s)!" % [ self, type ])
print("Done")

func serialize() -> Dictionary:
var rv : Dictionary = { type=type, w=rect.size.x, h=rect.size.y, children=[] }
for c in get_children():
rv.children.append(c.serialize())
return rv

func deserialize(data : Dictionary):
rect = Rect2(0, 0, data.w, data.h)

func get_children() -> Array[FlexNode]:
return []

Expand All @@ -46,9 +46,9 @@ class FlexNode:

class PanelInfo:
var flex_node : FlexNode
var flex_panel : FlexPanel
var flex_panel : Control

func _init(fn : FlexNode, fp : FlexPanel):
func _init(fn : FlexNode, fp : Control):
flex_node = fn
flex_panel = fp
flex_node.flexible_layout.start_drag()
Expand All @@ -67,9 +67,12 @@ class FlexTop:
func _init(fl : Control, c : Control = null):
type = "FlexTop"
control = c if c else fl
parent = null
flexible_layout = fl

func deserialize(data : Dictionary):
super.deserialize(data)
child = flexible_layout.deserialize(self, data.children[0])

func get_children() -> Array[FlexNode]:
if child:
return [ child ]
Expand All @@ -83,7 +86,7 @@ class FlexTop:
return false
if new_fn:
child = new_fn
new_fn.parent = self
new_fn.parent = weakref(self)
else:
child = null
return true
Expand All @@ -106,11 +109,24 @@ class FlexSplit:
super._init(p, fl)
type = "FlexSplit"

func _notification(what):
if what == NOTIFICATION_PREDELETE:
for d in draggers:
if is_instance_valid(d):
d.queue_free()

func serialize() -> Dictionary:
var rv : Dictionary = super.serialize()
rv.dir = "v" if vertical else "h"
return rv

func deserialize(data : Dictionary):
super.deserialize(data)
vertical = data.dir == "v"
children.clear()
for c in data.children:
children.append(flexible_layout.deserialize(self, c))

func get_children() -> Array[FlexNode]:
return children

Expand All @@ -128,7 +144,7 @@ class FlexSplit:
ref.rect.size.x /= 2
fn.rect = ref.rect
children.insert(index, fn)
fn.parent = self
fn.parent = weakref(self)

func replace(fn : FlexNode, new_fn : FlexNode) -> bool:
var index : int = children.find(fn)
Expand All @@ -139,23 +155,22 @@ class FlexSplit:
if new_fn:
new_fn.rect = fn.rect
children.insert(index, new_fn)
new_fn.parent = self
new_fn.parent = weakref(self)
if children.size() == 1:
parent.replace(self, children[0])
parent.get_ref().replace(self, children[0])
children.remove_at(0)
for d in draggers:
d.queue_free()
return true

func layout(r : Rect2):
print("Layout FlexSplit (%d children) - %s" % [ children.size(), str(r) ])
#print("Layout FlexSplit (%d children) - %s" % [ children.size(), str(r) ])
var grip_size : int = 10
rect = r
var children_count : int = children.size()
var draggers_count : int = draggers.size()
if draggers_count < children_count-1:
for i in children_count-1-draggers_count:
print("Creating dragger")
var dragger = DRAGGER_SCENE.instantiate()
draggers.append(dragger)
flexible_layout.add_child(dragger)
Expand Down Expand Up @@ -212,7 +227,6 @@ class FlexSplit:

class FlexTab:
extends FlexNode
var children : Array[FlexPanel] = []
var tabs : Control

const TAB_SCENE = preload("res://addons/flexible_layout/flexible_tabs.tscn")
Expand All @@ -225,86 +239,120 @@ class FlexTab:
flexible_layout.add_child(tabs)
tabs.set_flex_tab(self)

func _notification(what):
if what == NOTIFICATION_PREDELETE:
if is_instance_valid(tabs):
tabs.queue_free()

func serialize() -> Dictionary:
var rv : Dictionary = super.serialize()
rv.tabs = []
for t in children:
for t in tabs.get_controls():
rv.tabs.append(t.name)
rv.current = tabs.current
return rv

func add(fp : FlexPanel):
children.push_back(fp)
func deserialize(data : Dictionary):
super.deserialize(data)
for c in data.tabs:
add(flexible_layout.panels[c])

func add(fp : Control):
tabs.add(fp)
if fp.widget.get_parent() != flexible_layout:
flexible_layout.add_child(fp.widget)
if fp.get_parent() != flexible_layout:
flexible_layout.add_child(fp)

func remove(fp : FlexPanel):
children.erase(fp)
func remove(fp : Control):
tabs.erase(fp)
if children.is_empty():
if tabs.get_controls().is_empty():
tabs.queue_free()
parent.replace(self, null)
parent.get_ref().replace(self, null)

func set_current(fp : FlexPanel):
tabs.set_current(tabs.controls.find(fp))
func set_current(fp : Control):
tabs.set_current(tabs.get_control_index(fp))

func layout(r : Rect2):
print("Layout FlexTab - "+str(r))
#print("Layout FlexTab - "+str(r))
rect = r
tabs.position = rect.position
tabs.size = Vector2i(rect.size.x, 0)
var tabs_height : int = tabs.get_combined_minimum_size().y
for c in children:
c.widget.position = rect.position+Vector2(0, tabs.get_combined_minimum_size().y)
c.widget.size = rect.size-Vector2(0, tabs.get_combined_minimum_size().y)
for c in tabs.get_controls():
c.position = rect.position+Vector2(0, tabs_height)
c.size = rect.size-Vector2(0, tabs_height)


class FlexMain:
extends FlexNode
var child : FlexPanel = null
var child : Control = null

func _init(p : FlexNode = null, fl : Control = null):
super._init(p, fl)
type = "FlexMain"

func add(fp : FlexPanel):
assert(child == null)
func deserialize(data : Dictionary):
super.deserialize(data)
add(flexible_layout.panels["Main"])

func add(fp : Control):
#assert(child == null)
child = fp
if fp.widget.get_parent() != flexible_layout:
flexible_layout.add_child(fp.widget)
if fp.get_parent() != flexible_layout:
flexible_layout.add_child(fp)

func layout(r : Rect2):
print("Layout FlexNode - "+str(r))
#print("Layout FlexNode - "+str(r))
rect = r
child.widget.position = rect.position
child.widget.size = rect.size
child.position = rect.position
child.size = rect.size


class FlexWindow:
extends Window


var top : FlexTop = null
var unassigned : Array = []
var unassigned : Array[Control] = []
var panels : Dictionary = {}

var overlay : Control


const OVERLAY_SCENE = preload("res://addons/flexible_layout/flexible_overlay.tscn")


signal layout_changed


func _ready():
var children = get_children()
for c in children:
if c.visible and ! c.has_meta("flexlayout"):
add(c.name, c)
await get_tree().process_frame
layout()

func serialize() -> Dictionary:
return top.serialize()

func deserialize(parent : FlexNode, data : Dictionary) -> FlexNode:
var fn : FlexNode
match data.type:
"FlexTop":
fn = FlexTop.new(self)
"FlexMain":
fn = FlexMain.new(parent, self)
"FlexSplit":
fn = FlexSplit.new(parent, self)
"FlexTab":
fn = FlexTab.new(parent, self)
_:
print(data.type)
assert(false)
fn.deserialize(data)
return fn

func get_flexmain(p : FlexNode = top) -> FlexMain:
for c in p.get_children():
if c is FlexTab:
if c is FlexMain:
return c
for c in p.get_children():
var rv : FlexMain = get_flexmain(c)
Expand Down Expand Up @@ -342,35 +390,37 @@ func get_default_flextab(p : FlexNode = top) -> FlexTab:
top.child.insert(tab)
return tab

func layout():
func layout(layout = null):
var default_flextab : FlexTab = null
print("layout")
if top == null:
print("creating top")
if layout != null:
top = FlexTop.new(self)
for fp in unassigned:
if fp.name == "Main":
get_flexmain().add(fp)
else:
if default_flextab == null:
default_flextab = get_default_flextab()
default_flextab.add(fp)
unassigned = []
print("Deleted?")
top = deserialize(null, layout)
unassigned = []
else:
if top == null:
top = FlexTop.new(self)
for c in unassigned:
if c.name == "Main":
get_flexmain().add(c)
else:
if default_flextab == null:
default_flextab = get_default_flextab()
default_flextab.add(c)
unassigned = []
top.layout(get_rect())
print("done")

func add(n : String, c : Control):
var fp = FlexPanel.new()
fp.name = n
fp.widget = c
unassigned.push_back(fp)
c.name = n
unassigned.push_back(c)
panels[n] = c

func _on_resized():
print("resized")
layout()
layout_changed.emit()

func start_drag():
print("Starting drag")
overlay = OVERLAY_SCENE.instantiate()
overlay.position = Vector2(0, 0)
overlay.size = size
Expand All @@ -384,7 +434,7 @@ func get_flexnode_at(p : Vector2) -> FlexNode:
return top.get_flexnode_at(p)

func move_panel(panel, reference_panel : FlexNode, destination):
var parent_panel : FlexNode = reference_panel.parent
var parent_panel : FlexNode = reference_panel.parent.get_ref() as FlexNode
var vertical : bool
var offset : int
var tab : FlexTab = null
Expand Down Expand Up @@ -422,4 +472,5 @@ func move_panel(panel, reference_panel : FlexNode, destination):
panel.flex_node.remove(panel.flex_panel)
tab.add(panel.flex_panel)
layout()
print(top.serialize())
layout_changed.emit()

Loading

0 comments on commit 3133fbc

Please sign in to comment.