Add 'add_widget' function to menus, allow to add arbitrary widgets as menu items

This commit is contained in:
Emmanuel Lepage Vallee 2013-07-04 01:20:46 -04:00
parent 82421bf8bb
commit 42e12e297c
3 changed files with 74 additions and 11 deletions

View File

@ -99,7 +99,7 @@ end
---------------------------------ITEM HANDLING----------------------------------
function add_item(data,args)
local function add_item(data,args)
local args = args or {}
local item,set_map,get_map,private_data = object({
private_data = {
@ -175,11 +175,54 @@ function add_item(data,args)
end
local function add_widget(data,widget,args)
args = args or {}
data._internal.has_widget = true
widget._fit = widget.fit
widget.fit = function(...)
local w,h = widget._fit(...)
return args.width or w,args.height or h
end
local item,set_map,get_map,private_data = object({
private_data = {
widget = widget,
selected = false,
},
force_private = {
visible = true,
selected = true,
},
get_map = {
y = function() return (args.y and args.y >= 0) and args.y or data.height - (data.margins.top or data.border_width) - data.item_height end, --Hack around missing :fit call for last item
},
autogen_getmap = true,
autogen_setmap = true,
autogen_signals = true,
})
item._private_data = private_data
item._internal = {get_map=get_map,set_map=set_map}
data._internal.widgets[#data._internal.widgets+1] = item
data._internal.items[#data._internal.items+1] = {item}
data._internal.layout:add(item)
if data.visible then
local fit_w,fit_h = data._internal.layout:fit()
data.width = fit_w
data.height = fit_h
end
end
local function add_embeded_menu(data,menu)
end
---------------------------------MENU HANDLING----------------------------------
local function new(args)
local internal,args = args.internal or {},args or {}
if not internal.items then internal.items = {} end
if not internal.widgets then internal.widgets = {} end
-- All the magic in the universe
local data,set_map,get_map,private_data = object({
@ -238,7 +281,7 @@ local function new(args)
autogen_signals = true,
})
internal.get_map,internal.set_map,internal.private_data = get_map,set_map,private_data
data.add_item,data._internal = add_item,internal
data.add_item,data.add_widget,data.add_embeded_menu,data._internal = add_item,add_widget,add_embeded_menu,internal
set_map.parent_geometry = function(value)
private_data.parent_geometry = value
@ -251,6 +294,11 @@ local function new(args)
end
set_map.visible = function(value)
if value then
local fit_w,fit_h = data._internal.layout:fit()
data.width = fit_w
data.height = fit_h
end
if internal.has_changed and data.style then
data.style(data,{arrow_x=20,margin=internal.margin})
end

View File

@ -136,9 +136,12 @@ local function setup_drawable(data)
function internal:set_visible(value)
internal.w.visible = value
end
local fit_w,fit_h = data._internal.layout:fit()
data.width = fit_w
data.height = fit_h
if data.visible then
local fit_w,fit_h = data._internal.layout:fit()
data.width = fit_w
data.height = fit_h
end
end
local function setup_item(data,item,args)

View File

@ -191,6 +191,23 @@ function module:setup_item(data,item,args)
item._internal.set_map.text(item._private_data.text)
end
local function compute_geo(data)
local w = data.default_width
if data.auto_resize and data._internal.largest_item_w then
w = data._internal.largest_item_w_v+100 > data.default_width and data._internal.largest_item_w_v+100 or data.default_width
end
if not data._internal.has_widget then
return w,(total and total > 0 and total or data.rowcount*data.item_height) + (filter_tb and data.item_height or 0)
else
local h = (data.rowcount-#data._internal.widgets)*data.item_height
for k,v in ipairs(data._internal.widgets) do
local fw,fh = v.widget:fit(9999,9999)
h = h + fh
end
return w,h
end
end
local function new(data)
local l,real_l = wibox.layout.fixed.vertical(),nil
local filter_tb = nil
@ -215,12 +232,7 @@ local function new(data)
real_l.fit = function(a1,a2,a3)
local result,r2 = wibox.layout.fixed.fit(a1,99999,99999)
local total = data._total_item_height
if data.auto_resize and data._internal.largest_item_w then
return data._internal.largest_item_w_v+100 > data.default_width and data._internal.largest_item_w_v+100 or data.default_width
,(total and total > 0 and total or data.rowcount*data.item_height) + (filter_tb and data.item_height or 0)
else
return data.default_width, (total and total > 0 and total or data.rowcount*data.item_height) + (filter_tb and data.item_height or 0)
end
return compute_geo(data)
end
real_l.add = function(real_l,item)
return wibox.layout.fixed.add(l,item.widget)