From 42e12e297c5a3aa24c05440fca8c93d81a4c6d6c Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Thu, 4 Jul 2013 01:20:46 -0400 Subject: [PATCH] Add 'add_widget' function to menus, allow to add arbitrary widgets as menu items --- base.lua | 52 +++++++++++++++++++++++++++++++++++++++++++-- context.lua | 9 +++++--- layout/vertical.lua | 24 +++++++++++++++------ 3 files changed, 74 insertions(+), 11 deletions(-) diff --git a/base.lua b/base.lua index af8a4ba..e301450 100644 --- a/base.lua +++ b/base.lua @@ -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 diff --git a/context.lua b/context.lua index fc338d3..c73b4d5 100644 --- a/context.lua +++ b/context.lua @@ -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) diff --git a/layout/vertical.lua b/layout/vertical.lua index eccb4bb..47d3a58 100644 --- a/layout/vertical.lua +++ b/layout/vertical.lua @@ -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)