Skip to content

Commit

Permalink
make expandability system work for all elements
Browse files Browse the repository at this point in the history
  • Loading branch information
Bauumm committed Nov 14, 2023
1 parent c78aab4 commit 751def8
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 15 deletions.
76 changes: 68 additions & 8 deletions ui/elements/element.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,35 @@ local function set_hold_element(elem)
end
end

---get outermost parent of element
---@param elem any
---@return unknown
local function get_parent(elem)
if elem.parent then
return get_parent(elem.parent)
end
return elem
end

---find a sufficiently expandable parent
---@param elem any
---@param amount_x number
---@param amount_y number
---@return any
local function find_expandable_parent(elem, amount_x, amount_y)
elem.changed = true
if elem.expandable_x >= amount_x and elem.expandable_y >= amount_y then
return elem
else
if elem.parent then
return find_expandable_parent(elem.parent, amount_x, amount_y)
else
log("no have sufficiently expandable parent!")
return elem
end
end
end

---create a new element, implements base functionality for all other elements (does nothing on its own)
---@param options any
---@return table
Expand Down Expand Up @@ -66,6 +95,42 @@ function element:new(options)
return self
end

---call after modifying element
function element:update_size()
self.changed = true
local old_width, old_height = self.width, self.height
self:calculate_layout(self.last_available_width, self.last_available_height)
local x = self.width - old_width
local y = self.height - old_height
if x == 0 and y == 0 then
return
end
if x > 0 or y > 0 then
self.last_space_maker = find_expandable_parent(self, x, y)
if not self.last_space_maker.mutated then
self.last_space_maker = nil
return
end
self.last_space_maker:mutated()
elseif self.last_space_maker then
local parent = self.parent
while parent ~= self.last_space_maker do
parent.changed = true
parent = parent.parent
end
self.last_space_maker:mutated()
end
end

function element:_update_child_expand()
if self.parent and self.parent.prevent_child_expand then
if self.parent.prevent_child_expand then
self.expandable_x = 0
self.expandable_y = 0
end
end
end

---set the style of the element
---@param style table
function element:set_style(style)
Expand Down Expand Up @@ -112,20 +177,15 @@ function element:calculate_layout(width, height)
else
log("Element has no calculate_element_layout function?")
end
self.expandable_x = width - self.width
self.expandable_y = height - self.height
self.expandable_x = math.max(width - self.width, 0)
self.expandable_y = math.max(height - self.height, 0)
self:_update_child_expand()
return self.width, self.height
end

---follows the references to element's parent until an element has no parent, this element is returned
---@return table
function element:get_root()
local function get_parent(elem)
if elem.parent then
return get_parent(elem.parent)
end
return elem
end
return get_parent(self)
end

Expand Down
1 change: 1 addition & 0 deletions ui/elements/quad.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function quad:new(options)
border_color = { 1, 1, 1, 1 },
background_color = { 0, 0, 0, 1 },
vertices = {},
prevent_child_expand = "all",
}, quad),
options
)
Expand Down
7 changes: 5 additions & 2 deletions ui/layout/collapse.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local log = require("log")(...)
local animated_transform = require("ui.anim.transform")
local signal = require("ui.anim.signal")
local update_expand = require("ui.elements.element")._update_child_expand

local collapse = {}
collapse.__index = collapse
Expand Down Expand Up @@ -60,6 +61,7 @@ function collapse:new(element, options)
scale = true,
pos = true,
},
prevent_child_expand = "all",
}, collapse)
obj.element.parent = obj
if options.style then
Expand Down Expand Up @@ -178,8 +180,9 @@ function collapse:calculate_layout(width, height)
end
self.content_length, self.content_thickness = self.wh2lt(content_width, content_height)
self.width, self.height = self.lt2wh(self.pos(), self.content_thickness)
self.expandable_x = width - self.width
self.expandable_y = height - self.height
self.expandable_x = math.max(width - self.width, 0)
self.expandable_y = math.max(height - self.height, 0)
update_expand(self)
self.changed = false
return self.width, self.height
end
Expand Down
11 changes: 9 additions & 2 deletions ui/layout/flex.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local animated_transform = require("ui.anim.transform")
local element = require("ui.elements.element")

---@class flex
---@field direction string direction the flex container will position elements in
Expand All @@ -19,6 +20,7 @@ local animated_transform = require("ui.anim.transform")
-- amount that children can expand (in pixels)
---@field expandable_x number
---@field expandable_y number
---@field prevent_child_expand string
---@field changed boolean something changed, requires layout recalculation
local flex = {}
flex.__index = flex
Expand Down Expand Up @@ -71,6 +73,10 @@ function flex:new(elements, options)
scale = true,
},
}, flex)
obj.prevent_child_expand = "horizontal"
if options.direction == "column" then
obj.prevent_child_expand = "vertical"
end
for i = 1, #elements do
elements[i].parent = obj
elements[i].parent_index = i
Expand Down Expand Up @@ -408,8 +414,9 @@ function flex:calculate_layout(width, height)
end

self.width, self.height = lt2wh(final_length, final_thickness)
self.expandable_x = width - self.width
self.expandable_y = height - self.height
self.expandable_x = math.max(width - self.width, 0)
self.expandable_y = math.max(height - self.height, 0)
element._update_child_expand(self)
self.changed = false
return self.width, self.height
end
Expand Down
7 changes: 7 additions & 0 deletions ui/layout/scroll.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local animated_transform = require("ui.anim.transform")
local signal = require("ui.anim.signal")
local ease = require("ui.anim.ease")
local extmath = require("ui.extmath")
local update_expand = require("ui.elements.element")._update_child_expand

-- how much has to be moved on touchscreen until scrolling starts (if 0 clicking in a scrollable container becomes impossible as it's always registered as scroll since touch is analog input which will always have small fluctuations)
local SCROLL_THRESHOLD = 10
Expand Down Expand Up @@ -83,6 +84,7 @@ function scroll:new(element, options)
-- position on screen
x = 0,
y = 0,
prevent_child_expand = "all",
}, scroll)
obj.element.parent = obj
if options.style then
Expand Down Expand Up @@ -394,6 +396,11 @@ function scroll:calculate_layout(width, height)
self.scroll_pos:set_immediate_value(self.scroll_target)
end
self.expandable_x, self.expandable_y = self.lt2wh(math.huge, avail_thick - thick)
self.expandable_x = math.max(self.expandable_x, 0)
self.expandable_y = math.max(self.expandable_y, 0)
update_expand(self)
local _, expand_thick = self.wh2lt(self.expandable_x, self.expandable_y)
self.expandable_x, self.expandable_y = self.lt2wh(math.huge, expand_thick)
self.width, self.height = self.lt2wh(math.min(self.content_length, avail_len), thick)
self.changed = false
return self.width, self.height
Expand Down
5 changes: 2 additions & 3 deletions ui/overlay/settings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ local function create_setting(name, property, value)
else
text.raw_text = property.display_name .. ": " .. state
end
text.changed = true
layout:mutated()
text:update_size()
if property.onchange then
if property.onchange(state) then
return true
Expand Down Expand Up @@ -131,7 +130,7 @@ local function create_setting(name, property, value)
end,
click_handler = function(self)
self.element:wait_for_input():done(function()
self:mutated()
self:update_size()
end)
return true
end,
Expand Down

0 comments on commit 751def8

Please sign in to comment.