base: Fix scroll, filter and embedded menus
This commit is contained in:
parent
ffd1e8003a
commit
7506a8f49d
114
base.lua
114
base.lua
|
@ -72,49 +72,50 @@ theme.register_color(module.item_flags.HIGHLIGHT , "highlight" , "highlight" , t
|
||||||
|
|
||||||
|
|
||||||
local function filter(data)
|
local function filter(data)
|
||||||
if not data.filter == false then
|
local max_items = data.max_items or 9999999
|
||||||
local fs,visible_counter = data.filter_string:lower(),0
|
|
||||||
data._internal.visible_item_count = 0
|
local fs = data.filter_string ~= "" and data.filter_string:lower() or nil
|
||||||
for k,v in pairs(data.items) do
|
|
||||||
local tmp = v._filter_out
|
local start_at, visible_counter = data._start_at or -1, 0
|
||||||
v._filter_out = (v.text:lower():find(fs) == nil)-- or (fs ~= "")
|
|
||||||
if tmp ~= v._filter_out then
|
-- There is 2 factors to consider to display the item:
|
||||||
v.widget.visible = not v._filter_out
|
--
|
||||||
|
-- * Is the item within range
|
||||||
|
-- * Is the item matching the filter
|
||||||
|
--
|
||||||
|
for k,v in ipairs(data.items) do
|
||||||
|
|
||||||
|
v.widget.visible = (not fs or v.text and v.text:lower():find(fs) ~= nil)
|
||||||
|
and k >= start_at and visible_counter < max_items
|
||||||
|
|
||||||
|
if v.widget.visible then
|
||||||
|
visible_counter = visible_counter + 1
|
||||||
|
v.f_key = visible_counter
|
||||||
end
|
end
|
||||||
if (not v._filter_out) and (not v.widget.visible == false) then
|
|
||||||
visible_counter = visible_counter + v.height
|
-- Don't waste CPU
|
||||||
data._internal.visible_item_count = data._internal.visible_item_count +1
|
if visible_counter >= max_items then break end
|
||||||
v.f_key = data._internal.visible_item_count
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
data._total_item_height = visible_counter
|
data._internal.visible_item_count = visible_counter
|
||||||
|
|
||||||
-- Make sure to select an item
|
-- Make sure to select an item
|
||||||
if data._current_item and data._current_item._filter_out then
|
if data._current_item and not data._current_item.widget.visible then
|
||||||
local n = data.next_item
|
local n = data.next_item
|
||||||
if n then
|
if n then
|
||||||
n.selected = true
|
n.selected = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Get the number of visible rows
|
-- Get the number of visible rows
|
||||||
local function get_visible_row_count(data)
|
local function get_visible_row_count(data)
|
||||||
local visblerow = data.filter_string == "" and data.rowcount or data._internal.visible_item_count
|
if not data._internal.visible_item_count then
|
||||||
if data.max_items and data.max_items < data.rowcount then
|
filter(data)
|
||||||
visblerow = data.max_items
|
|
||||||
if data.filter_string ~= "" then
|
|
||||||
local cur,vis = (data._start_at or 1),0
|
|
||||||
while (data._internal.items[cur] and data._internal.items[cur]) and cur < data.max_items + (data._start_at or 1) do
|
|
||||||
vis = vis + (data._internal.items[cur]._filter_out and 0 or 1)
|
|
||||||
cur = cur +1
|
|
||||||
end
|
end
|
||||||
visblerow = vis
|
|
||||||
end
|
return data._internal.visible_item_count
|
||||||
end
|
|
||||||
return visblerow
|
|
||||||
end
|
end
|
||||||
|
|
||||||
------------------------------------KEYBOARD HANDLING-----------------------------------
|
------------------------------------KEYBOARD HANDLING-----------------------------------
|
||||||
|
@ -163,10 +164,8 @@ local function activateKeyboard(data)
|
||||||
capi.keygrabber.stop()
|
capi.keygrabber.stop()
|
||||||
elseif (key == 'BackSpace') and data.filter_string ~= "" and data.filter == true then
|
elseif (key == 'BackSpace') and data.filter_string ~= "" and data.filter == true then
|
||||||
data.filter_string = data.filter_string:sub(1,-2)
|
data.filter_string = data.filter_string:sub(1,-2)
|
||||||
filter(data)
|
|
||||||
elseif data.filter == true and key:len() == 1 then
|
elseif data.filter == true and key:len() == 1 then
|
||||||
data.filter_string = data.filter_string .. key:lower()
|
data.filter_string = data.filter_string .. key:lower()
|
||||||
filter(data)
|
|
||||||
else
|
else
|
||||||
data.visible = false
|
data.visible = false
|
||||||
capi.keygrabber.stop()
|
capi.keygrabber.stop()
|
||||||
|
@ -211,6 +210,13 @@ local function add_item(data,args)
|
||||||
|
|
||||||
item.index = data.rowcount
|
item.index = data.rowcount
|
||||||
data:emit_signal("item::added",item)
|
data:emit_signal("item::added",item)
|
||||||
|
|
||||||
|
-- Keep the filter up-to-date
|
||||||
|
if data.max_items and data.rowcount - (data._start_at or 0) > data.max_items then
|
||||||
|
--FIXME and data._internal.visible_item_count < data.max_items then
|
||||||
|
filter(data)
|
||||||
|
end
|
||||||
|
|
||||||
return item
|
return item
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -278,11 +284,6 @@ local function get_widget_fit_sum(data)
|
||||||
return w,h
|
return w,h
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_widget_fit_width_sum(data)
|
|
||||||
-- TODO query this from the layout itself
|
|
||||||
return get_widget_fit_sum(data)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_widget_fit_height_sum(data)
|
local function get_widget_fit_height_sum(data)
|
||||||
-- TODO query this from the layout itself
|
-- TODO query this from the layout itself
|
||||||
local w,h = get_widget_fit_sum(data)
|
local w,h = get_widget_fit_sum(data)
|
||||||
|
@ -401,8 +402,7 @@ local function new(args)
|
||||||
data.get_items = function(_) return internal.items end
|
data.get_items = function(_) return internal.items end
|
||||||
data.get_rowcount = function(_) return #internal.items end
|
data.get_rowcount = function(_) return #internal.items end
|
||||||
data.get_visible_row_count = get_visible_row_count
|
data.get_visible_row_count = get_visible_row_count
|
||||||
data.get_widget_fit_height_sum = get_widget_fit_height_sum
|
data.get_widget_fit_height_sum = get_widget_fit_height_sum --TODO remove
|
||||||
data.get_widget_fit_width_sum = get_widget_fit_width_sum
|
|
||||||
|
|
||||||
-- Setters
|
-- Setters
|
||||||
data.set_auto_resize = function(_,val) private_data[""] = val end
|
data.set_auto_resize = function(_,val) private_data[""] = val end
|
||||||
|
@ -467,14 +467,14 @@ local function new(args)
|
||||||
|
|
||||||
data.get_previous_item = function(_)
|
data.get_previous_item = function(_)
|
||||||
local candidate,idx = internal.items[(data.current_index or 0)-1],(data.current_index or 0)-1
|
local candidate,idx = internal.items[(data.current_index or 0)-1],(data.current_index or 0)-1
|
||||||
while candidate and (candidate.widget.visible == false or candidate._filter_out) and idx > 0 do
|
while candidate and (candidate.widget.visible == false) and idx > 0 do
|
||||||
candidate,idx = internal.items[idx - 1],idx-1
|
candidate,idx = internal.items[idx - 1],idx-1
|
||||||
end
|
end
|
||||||
return (candidate or internal.items[data.rowcount])
|
return (candidate or internal.items[data.rowcount])
|
||||||
end
|
end
|
||||||
data.get_next_item = function(_)
|
data.get_next_item = function(_)
|
||||||
local candidate,idx = internal.items[(data.current_index or 0)+1],(data.current_index or 0)+1
|
local candidate,idx = internal.items[(data.current_index or 0)+1],(data.current_index or 0)+1
|
||||||
while candidate and (candidate.widget.visible == false or candidate._filter_out) and idx <= data.rowcount do
|
while candidate and (candidate.widget.visible == false) and idx <= data.rowcount do
|
||||||
candidate,idx = internal.items[idx + 1],idx+1
|
candidate,idx = internal.items[idx + 1],idx+1
|
||||||
end
|
end
|
||||||
return (candidate or internal.items[1])
|
return (candidate or internal.items[1])
|
||||||
|
@ -491,6 +491,10 @@ local function new(args)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Make sure the filter doesn't get outdated
|
||||||
|
data:connect_signal("max_items::changed" , filter)
|
||||||
|
data:connect_signal("filter_string::changed", filter)
|
||||||
|
|
||||||
function data:add_key_hook(mod, key, event, func)
|
function data:add_key_hook(mod, key, event, func)
|
||||||
if key and event and func then
|
if key and event and func then
|
||||||
internal.filter_hooks = internal.filter_hooks or {}
|
internal.filter_hooks = internal.filter_hooks or {}
|
||||||
|
@ -512,19 +516,19 @@ local function new(args)
|
||||||
data:emit_signal("clear::menu")
|
data:emit_signal("clear::menu")
|
||||||
end
|
end
|
||||||
|
|
||||||
function data:swap(item1,item2)
|
function data:swap(item1,item2) --TODO can item.index be used?
|
||||||
if not item1 or not item2 then return end
|
if not item1 or not item2 then return end
|
||||||
if not item1 or not item2 and item1 ~= item2 then return end
|
if not item1 or not item2 and item1 ~= item2 then return end
|
||||||
local idx1,idx2
|
local idx1,idx2
|
||||||
for k,v in ipairs(internal.items) do --rows
|
for k,v in ipairs(internal.items) do --rows
|
||||||
for k2,v2 in ipairs(v) do --columns
|
if item2 == v then
|
||||||
if item2 == v2 then
|
|
||||||
idx2 = k
|
idx2 = k
|
||||||
end
|
end
|
||||||
if item1 == v2 then
|
|
||||||
|
if item1 == v then
|
||||||
idx1 = k
|
idx1 = k
|
||||||
end
|
end
|
||||||
end
|
|
||||||
if idx1 and idx2 then
|
if idx1 and idx2 then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
@ -594,17 +598,9 @@ local function new(args)
|
||||||
current_item:set_selected(false,true)
|
current_item:set_selected(false,true)
|
||||||
end
|
end
|
||||||
data._start_at = (data._start_at or 1) - 1
|
data._start_at = (data._start_at or 1) - 1
|
||||||
internal.items[data._start_at].widget:set_visible(false)
|
|
||||||
data:emit_signal("_hidden::changed",internal.items[data._start_at])
|
|
||||||
internal.items[data._start_at+data.max_items].widget:set_visible(true)
|
|
||||||
data:emit_signal("_hidden::changed",internal.items[data._start_at+data.max_items])
|
|
||||||
filter(data)
|
filter(data)
|
||||||
|
|
||||||
--HACK upstream bug
|
|
||||||
internal.items[data._start_at].widget:emit_signal("widget::layout_changed")
|
|
||||||
internal.items[data._start_at+data.max_items].widget:emit_signal("widget::layout_changed")
|
|
||||||
data._internal.layout:emit_signal("widget::redraw_needed")
|
|
||||||
data._internal.layout:emit_signal("widget::layout_changed")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -615,17 +611,9 @@ local function new(args)
|
||||||
current_item:set_selected(false,true)
|
current_item:set_selected(false,true)
|
||||||
end
|
end
|
||||||
data._start_at = (data._start_at or 1) + 1
|
data._start_at = (data._start_at or 1) + 1
|
||||||
internal.items[data._start_at-1].widget:set_visible(true)
|
|
||||||
data:emit_signal("_hidden::changed",internal.items[data._start_at-1])
|
|
||||||
internal.items[data._start_at-1+data.max_items].widget:set_visible(false)
|
|
||||||
data:emit_signal("_hidden::changed",internal.items[data._start_at-1+data.max_items])
|
|
||||||
filter(data)
|
filter(data)
|
||||||
|
|
||||||
--HACK upstream bug
|
|
||||||
internal.items[data._start_at-1].widget:emit_signal("widget::layout_changed")
|
|
||||||
internal.items[data._start_at-1+data.max_items].widget:emit_signal("widget::layout_changed")
|
|
||||||
data._internal.layout:emit_signal("widget::redraw_needed")
|
|
||||||
data._internal.layout:emit_signal("widget::layout_changed")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue