Skip to content

Commit

Permalink
Take into account handle height when calculating scroll
Browse files Browse the repository at this point in the history
Also fix for scroll.y in list and scrollbar having inverted values.
  • Loading branch information
britzl committed Mar 26, 2019
1 parent 7436b51 commit 27b7111
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 24 deletions.
4 changes: 3 additions & 1 deletion example/kenneyblue.gui_script
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ function init(self)
kenneyblue.input("input", gui.KEYBOARD_TYPE_DEFAULT, nil, nil, { empty_text = "EMPTY, MAX 8 CHARS" })
kenneyblue.static_list("staticlist", "staticscrollbar", self.list_ids)
kenneyblue.dynamic_list("dynamiclist", "dynamicscrollbar", self.list_data)
kenneyblue.scrollbar("staticscrollbar")
kenneyblue.scrollbar("dynamicscrollbar")
end

function on_input(self, action_id, action)
Expand Down Expand Up @@ -146,7 +148,7 @@ function on_input(self, action_id, action)
kenneyblue.button("remove", action_id, action, function(button)
table.remove(self.list_data)
end)

kenneyblue.static_list("staticlist", "staticscrollbar", self.list_ids, action_id, action, function(list)
print("selected list item", list.selected_item)
end)
Expand Down
28 changes: 14 additions & 14 deletions gooey/internal/list.lua
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function LIST.scroll_to(list, x, y)
list.consumed = true
list.scrolling = true
list.scroll_pos.y = list.min_y + (list.max_y - list.min_y) * y
list.scroll.y = 1 - y
list.scroll.y = y
if list.static then
update_static_listitems(list.items, vmath.vector3(list.scroll_pos))
elseif list.dynamic then
Expand All @@ -69,7 +69,7 @@ local function get_instance(list_id, stencil_id, refresh_fn, lists)
local list = core.instance(stencil_id, lists, LIST)
list.id = list_id
list.scroll = list.scroll or vmath.vector3(1)
list.stencil = list.stencil or gui.get_node(stencil_id)
list.stencil = list.stencil or gui.get_node(stencil_id)
list.stencil_size = list.stencil_size or gui.get_size(list.stencil)
list.refresh_fn = refresh_fn
list.enabled = core.is_enabled(list.stencil)
Expand All @@ -94,7 +94,7 @@ local function handle_input(list, action_id, action, click_fn)
list.pressed = false
end
list.consumed = false

-- handle mouse-wheel scrolling
if over_stencil and (scroll_up or scroll_down) then
list.consumed = true
Expand Down Expand Up @@ -125,7 +125,7 @@ local function handle_input(list, action_id, action, click_fn)
if list.scrolling then
list.scroll_pos.y = math.min(list.scroll_pos.y, list.max_y)
list.scroll_pos.y = math.max(list.scroll_pos.y, list.min_y)
list.scroll.y = 1 - (list.scroll_pos.y / list.max_y)
list.scroll.y = (list.scroll_pos.y / list.max_y)
end

-- find which item (if any) that the touch event is over
Expand All @@ -136,7 +136,7 @@ local function handle_input(list, action_id, action, click_fn)
list.consumed = true
over_item = item.index
break
end
end
end

-- handle list item over state
Expand Down Expand Up @@ -185,11 +185,11 @@ function M.static(list_id, stencil_id, item_ids, action_id, action, fn, refresh_
gui.set_parent(node, list.stencil)
end
update_static_listitems(list.items, vmath.vector3(0))

local last_item = list.items[#list.items].root
local total_height = last_item and (math.abs(gui.get_position(last_item).y) + gui.get_size(last_item).y / 2) or 0
local list_height = gui.get_size(list.stencil).y

list.scroll_pos = vmath.vector3(0)
list.min_y = 0
list.max_y = total_height - list_height
Expand All @@ -204,10 +204,10 @@ function M.static(list_id, stencil_id, item_ids, action_id, action, fn, refresh_
if refresh_fn then refresh_fn(list) end
return list
end

if list.enabled then
handle_input(list, action_id, action, fn)

-- re-position the list items if we're scrolling
if list.scrolling then
update_static_listitems(list.items, vmath.vector3(list.scroll_pos))
Expand Down Expand Up @@ -235,7 +235,7 @@ function M.dynamic(list_id, stencil_id, item_id, data, action_id, action, fn, re
list.scroll_pos = vmath.vector3(0)
list.first_item_pos = vmath.vector3(item_pos)
list.data_size = nil

local item_count = math.ceil(list.stencil_size.y / item_size.y) + 1
for i=1,item_count do
local nodes = gui.clone_tree(item_node)
Expand All @@ -256,7 +256,7 @@ function M.dynamic(list_id, stencil_id, item_id, data, action_id, action, fn, re
-- deselect and realign items
local data_size_changed = list.data_size ~= #data
if not list.data_size or data_size_changed then
list.data_size = #data
list.data_size = #data
list.min_y = 0
list.max_y = (#data * list.item_size.y) - list.stencil_size.y
list.selected_item = nil
Expand Down Expand Up @@ -284,7 +284,7 @@ function M.dynamic(list_id, stencil_id, item_id, data, action_id, action, fn, re
end
end
end

-- bail early if the list is empty
if list.data_size == 0 then
if refresh_fn then refresh_fn(list) end
Expand All @@ -299,7 +299,7 @@ function M.dynamic(list_id, stencil_id, item_id, data, action_id, action, fn, re
update_dynamic_listitem_positions(list)
end
end

update_dynamic_listitem_data(list, data)

if refresh_fn then refresh_fn(list) end
Expand All @@ -313,4 +313,4 @@ setmetatable(M, {
end
})

return M
return M
30 changes: 21 additions & 9 deletions gooey/internal/scrollbar.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,17 @@ function SCROLLBAR.scroll_to(scrollbar, x, y)

x = core.clamp(x, 0, 1)
y = core.clamp(y, 0, 1)
handle_pos.x = x * scrollbar.bounds_size.x
handle_pos.y = y * scrollbar.bounds_size.y
if scrollbar.vertical then
local adjusted_height = (scrollbar.bounds_size.y - scrollbar.handle_size.y)
local offset_y = scrollbar.vertical and (scrollbar.handle_size.y / 2) or 0
handle_pos.y = offset_y + adjusted_height - y * adjusted_height
else
local adjusted_width = (scrollbar.bounds_size.x - scrollbar.handle_size.x)
local offset_x = scrollbar.vertical and 0 or (scrollbar.handle_size.x / 2)
handle_pos.x = offset_x + adjusted_width - x * adjusted_width
end
gui.set_position(scrollbar.node, handle_pos)
scrollbar.scroll.y = 1 - y
scrollbar.scroll.y = y
end
function SCROLLBAR.set_visible(button, visible)
gui.set_enabled(scrollbar.node, visible)
Expand All @@ -36,15 +43,18 @@ function M.vertical(handle_id, bounds_id, action_id, action, fn, refresh_fn)
assert(handle)
assert(bounds)
local scrollbar = core.instance(handle_id, scrollbars, SCROLLBAR)
scrollbar.scroll = scrollbar.scroll or vmath.vector3()
scrollbar.scroll = scrollbar.scroll or vmath.vector3(0, 0, 0)
scrollbar.vertical = true

local handle_size = gui.get_size(handle)
local bounds_size = gui.get_size(bounds)

scrollbar.enabled = core.is_enabled(handle)
scrollbar.node = handle
scrollbar.bounds = bounds
scrollbar.bounds_size = bounds_size

scrollbar.handle_size = handle_size

if action then
scrollbar.refresh_fn = refresh_fn

Expand All @@ -53,11 +63,13 @@ function M.vertical(handle_id, bounds_id, action_id, action, fn, refresh_fn)
core.clickable(scrollbar, action_id, action)
if scrollbar.pressed_now or scrollbar.pressed then
local bounds_pos = core.get_root_position(bounds)
local ratio = (action_pos.y - bounds_pos.y) / bounds_size.y
local size = bounds_size.y - handle_size.y
local ratio = (size - (action_pos.y - bounds_pos.y - (scrollbar.handle_size.y / 2))) / size
SCROLLBAR.scroll_to(scrollbar, 0, ratio)
action.scroll_y = scrollbar.scroll.y
fn(scrollbar)
end
else
SCROLLBAR.scroll_to(scrollbar, 0, scrollbar.scroll.y)
end

scrollbar.refresh()
Expand All @@ -70,4 +82,4 @@ setmetatable(M, {
end
})

return M
return M
3 changes: 3 additions & 0 deletions gooey/themes/kenneyblue/kenneyblue.lua
Original file line number Diff line number Diff line change
Expand Up @@ -176,5 +176,8 @@ function M.dynamic_list(list_id, scrollbar_id, data, action_id, action, fn)
return list
end

function M.scrollbar(scrollbar_id, action_id, action, fn)
return gooey.vertical_scrollbar(scrollbar_id .. "/handle", scrollbar_id .. "/bounds")
end

return M

0 comments on commit 27b7111

Please sign in to comment.