Add full support for max_items in the vertical menu

This commit is contained in:
Emmanuel Lepage Vallee 2013-07-07 18:18:55 -04:00
parent 34f7e74a92
commit 4484e671a7
5 changed files with 113 additions and 70 deletions

View File

@ -139,6 +139,10 @@ local function add_item(data,args)
for i=1,10 do for i=1,10 do
item["button"..i] = args["button"..i] item["button"..i] = args["button"..i]
end end
if data.max_items ~= nil and data.rowcount >= data.max_items then-- and (data._start_at or 0)
item._hidden = true
end
set_map.selected = function(value) set_map.selected = function(value)
private_data.selected = value private_data.selected = value
@ -385,6 +389,26 @@ local function new(args)
data:emit_signal("clear::menu") data:emit_signal("clear::menu")
end end
function data:scroll_up()
if data.max_items ~= nil and data.rowcount >= data.max_items and (data._start_at or 1) > 1 then
data._start_at = (data._start_at or 1) - 1
internal.items[data._start_at][1]._hidden = false
data:emit_signal("_hidden::changed",internal.items[data._start_at][1])
internal.items[data._start_at+data.max_items][1]._hidden = true
data:emit_signal("_hidden::changed",internal.items[data._start_at+data.max_items][1])
end
end
function data:scroll_down()
if data.max_items ~= nil and data.rowcount >= data.max_items and (data._start_at or 1)+data.max_items <= data.rowcount then
data._start_at = (data._start_at or 1) + 1
internal.items[data._start_at-1][1]._hidden = true
data:emit_signal("_hidden::changed",internal.items[data._start_at-1][1])
internal.items[data._start_at-1+data.max_items][1]._hidden = false
data:emit_signal("_hidden::changed",internal.items[data._start_at-1+data.max_items][1])
end
end
if private_data.layout then if private_data.layout then
private_data.layout:setup_key_hooks(data) private_data.layout:setup_key_hooks(data)
end end

View File

@ -42,7 +42,7 @@ local function set_position(self)
if parent.direction == "right" then if parent.direction == "right" then
ret={x=parent.x-self.width,y=parent.y+(self.parent_item.y)} ret={x=parent.x-self.width,y=parent.y+(self.parent_item.y)}
else else
ret={x=parent.x+parent.width,y=parent.y+(self.parent_item.y)} ret={x=parent.x+parent.width,y=parent.y+(self.parent_item.y)- (parent.show_filter and parent.item_height or 0)}
if ret.y+self.height > capi.screen[capi.mouse.screen].geometry.height then if ret.y+self.height > capi.screen[capi.mouse.screen].geometry.height then
ret.y = ret.y - self.height + self.item_height ret.y = ret.y - self.height + self.item_height
end end
@ -147,6 +147,31 @@ end
local function setup_item(data,item,args) local function setup_item(data,item,args)
local f = (data._internal.layout.setup_item) or (layout.vertical.setup_item) local f = (data._internal.layout.setup_item) or (layout.vertical.setup_item)
f(data._internal.layout,data,item,args) f(data._internal.layout,data,item,args)
local buttons = {}
for i=1,10 do
if args["button"..i] then
buttons[#buttons+1] = button({},i,args["button"..i])
end
end
if not buttons[3] then --Hide on right click
buttons[#buttons+1] = button({},3,function()
data.visible = false
if data.parent_geometry and data.parent_geometry.is_menu then
data.parent_geometry.visible = false
end
end)
end
if not buttons[4] then
buttons[#buttons+1] = button({},4,function()
data:scroll_up()
end)
end
if not buttons[5] then
buttons[#buttons+1] = button({},5,function()
data:scroll_down()
end)
end
item.widget:buttons( util.table.join(unpack(buttons)))
end end
local function new(args) local function new(args)
@ -161,6 +186,9 @@ local function new(args)
ret:connect_signal("clear::menu",function(_,vis) ret:connect_signal("clear::menu",function(_,vis)
ret._internal.layout:reset() ret._internal.layout:reset()
end) end)
ret:connect_signal("_hidden::changed",function(_,item)
item.widget:emit_signal("widget::updated")
end)
return ret return ret
end end

View File

@ -13,7 +13,7 @@ local module = {
} }
} }
local focussed,default,alt = nil, nil,nil local focussed,default,alt = nil, nil,{}
local function gen(item_height,bg_color,border_color) local function gen(item_height,bg_color,border_color)
local img = cairo.ImageSurface(cairo.Format.ARGB32, 800,item_height) local img = cairo.ImageSurface(cairo.Format.ARGB32, 800,item_height)
@ -26,7 +26,7 @@ local function gen(item_height,bg_color,border_color)
return cairo.Pattern.create_for_surface(img) return cairo.Pattern.create_for_surface(img)
end end
local function draw(data,item,is_focussed,is_pressed,is_alt) local function draw(data,item,is_focussed,is_pressed,col)
local ih = data.item_height local ih = data.item_height
if not focussed or not focussed[ih] then if not focussed or not focussed[ih] then
if not focussed then if not focussed then
@ -35,13 +35,16 @@ local function draw(data,item,is_focussed,is_pressed,is_alt)
local bc = data.border_color local bc = data.border_color
focussed[ih] = gen(ih,data.bg_focus,bc) focussed[ih] = gen(ih,data.bg_focus,bc)
default [ih] = gen(ih,data.bg,bc) default [ih] = gen(ih,data.bg,bc)
alt [ih] = gen(ih,beautiful.bg_highlight,bc) end
if col and (not alt[col] or not alt[col][ih]) then
alt[col] = alt[col] or {}
alt[col][ih] = gen(ih,color(col),bc)
end end
if is_focussed then if is_focussed then
item.widget:set_bg(focussed[ih]) item.widget:set_bg(focussed[ih])
elseif is_alt then elseif col then
item.widget:set_bg(alt[ih]) item.widget:set_bg(alt[col][ih])
else else
item.widget:set_bg(default[ih]) item.widget:set_bg(default[ih])
end end

View File

@ -1,17 +1,16 @@
local setmetatable = setmetatable local setmetatable = setmetatable
local print,pairs = print,pairs local print,pairs = print,pairs
local unpack=unpack local unpack = unpack
local math = math local util = require( "awful.util" )
local util = require( "awful.util" ) local button = require( "awful.button" )
local button = require( "awful.button" )
local checkbox = require( "radical.widgets.checkbox" ) local checkbox = require( "radical.widgets.checkbox" )
local scroll = require( "radical.widgets.scroll" ) local scroll = require( "radical.widgets.scroll" )
local filter = require( "radical.widgets.filter" ) local filter = require( "radical.widgets.filter" )
local fkey = require( "radical.widgets.fkey" ) local fkey = require( "radical.widgets.fkey" )
local beautiful = require("beautiful") local beautiful = require("beautiful" )
local wibox = require( "wibox" ) local wibox = require( "wibox" )
local color = require( "gears.color" ) local color = require( "gears.color" )
local cairo = require( "lgi" ).cairo local cairo = require( "lgi" ).cairo
local module = {} local module = {}
@ -80,7 +79,7 @@ local function cache_pixmap(item)
item._internal.pix_cache = {} item._internal.pix_cache = {}
item.widget._draw = item.widget.draw item.widget._draw = item.widget.draw
item.widget.draw = function(self,wibox, cr, width, height) item.widget.draw = function(self,wibox, cr, width, height)
if not wibox.visible then return end if not wibox.visible or item._hidden then return end
if item._internal.pix_cache[10*width+7*height+(item.selected and 8888 or 999)] then if item._internal.pix_cache[10*width+7*height+(item.selected and 8888 or 999)] then
cr:set_source_surface(item._internal.pix_cache[10*width+7*height+(item.selected and 8888 or 999)]) cr:set_source_surface(item._internal.pix_cache[10*width+7*height+(item.selected and 8888 or 999)])
cr:paint() cr:paint()
@ -110,20 +109,6 @@ function module:setup_item(data,item,args)
item.widget:connect_signal("mouse::enter", function() item.selected = true end) item.widget:connect_signal("mouse::enter", function() item.selected = true end)
item.widget:connect_signal("mouse::leave", function() item.selected = false end) item.widget:connect_signal("mouse::leave", function() item.selected = false end)
data._internal.layout:add(item) data._internal.layout:add(item)
local buttons = {}
for i=1,10 do
if args["button"..i] then
buttons[#buttons+1] = button({},i,args["button"..i])
end
end
if not buttons[3] then --Hide on right click
buttons[#buttons+1] = button({},3,function()
data.visible = false
if data.parent_geometry and data.parent_geometry.is_menu then
data.parent_geometry.visible = false
end
end)
end
--Be sure to always hide sub menus, even when data.visible is set manually --Be sure to always hide sub menus, even when data.visible is set manually
data:connect_signal("visible::changed",function(_,vis) data:connect_signal("visible::changed",function(_,vis)
@ -136,7 +121,6 @@ function module:setup_item(data,item,args)
data.height = fit_h data.height = fit_h
data.style(data) data.style(data)
end) end)
item.widget:buttons( util.table.join(unpack(buttons)))
--Create the main item layout --Create the main item layout
local l,la,lr = wibox.layout.fixed.horizontal(),wibox.layout.align.horizontal(),wibox.layout.fixed.horizontal() local l,la,lr = wibox.layout.fixed.horizontal(),wibox.layout.align.horizontal(),wibox.layout.fixed.horizontal()
@ -158,8 +142,8 @@ function module:setup_item(data,item,args)
item._private_data._fit = wibox.widget.background.fit item._private_data._fit = wibox.widget.background.fit
m.fit = function(...) m.fit = function(...)
if not data.visible or (item.visible == false or item._filter_out == true) then if not data.visible or (item.visible == false or item._filter_out == true or item._hidden == true) then
return 1,1 return 0,0
end end
return data._internal.layout.item_fit(data,item,...) return data._internal.layout.item_fit(data,item,...)
end end
@ -260,10 +244,22 @@ local function compute_geo(data)
if data.auto_resize and data._internal.largest_item_w then 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 w = data._internal.largest_item_w_v+100 > data.default_width and data._internal.largest_item_w_v+100 or data.default_width
end end
local visblerow = data.filter_string == "" and data.rowcount or data._internal.visible_item_count
if data.max_items and data.max_items < data.rowcount then
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][1]) and cur < data.max_items + (data._start_at or 1) do
vis = vis + (data._internal.items[cur][1]._filter_out and 0 or 1)
cur = cur +1
end
visblerow = vis
end
end
if not data._internal.has_widget then if not data._internal.has_widget then
return w,(total and total > 0 and total or data.rowcount*data.item_height) + (data._internal.filter_tb and data.item_height or 0) + (data.max_items and data._internal.scroll_w["up"].visible and (2*data.item_height) or 0) return w,(total and total > 0 and total or visblerow*data.item_height) + (data._internal.filter_tb and data.item_height or 0) + (data.max_items and data._internal.scroll_w["up"].visible and (2*data.item_height) or 0)
else else
local h = (data.rowcount-#data._internal.widgets)*data.item_height local h = (visblerow-#data._internal.widgets)*data.item_height
for k,v in ipairs(data._internal.widgets) do for k,v in ipairs(data._internal.widgets) do
local fw,fh = v.widget:fit(9999,9999) local fw,fh = v.widget:fit(9999,9999)
h = h + fh h = h + fh

View File

@ -1,16 +1,16 @@
local setmetatable = setmetatable local setmetatable = setmetatable
local print = print local print = print
local color = require("gears.color") local color = require( "gears.color" )
local cairo = require( "lgi" ).cairo local cairo = require( "lgi" ).cairo
local wibox = require("wibox") local wibox = require( "wibox" )
local util = require( "awful.util" )
local beautiful = require( "beautiful" ) local button = require( "awful.button" )
local beautiful = require( "beautiful" )
local module = {} local module = {}
local arr_up local arr_up,arr_down
local arr_down local isinit = false
local isinit = false
local function init() local function init()
local size = beautiful.menu_height or 16 local size = beautiful.menu_height or 16
@ -18,31 +18,14 @@ local function init()
arr_up = cairo.ImageSurface(cairo.Format.ARGB32, size,size) arr_up = cairo.ImageSurface(cairo.Format.ARGB32, size,size)
local cr2 = cairo.Context(arr_down) local cr2 = cairo.Context(arr_down)
local cr = cairo.Context(arr_up) local cr = cairo.Context(arr_up)
cr:set_operator(cairo.Operator.CLEAR)
cr2:set_operator(cairo.Operator.CLEAR)
cr:paint()
cr2:paint()
cr:set_operator(cairo.Operator.SOURCE)
cr2:set_operator(cairo.Operator.SOURCE)
local sp = 2.5
local rs = size - (2*sp)
cr:set_source(color(beautiful.fg_normal)) cr:set_source(color(beautiful.fg_normal))
cr2:set_source(color(beautiful.fg_normal)) cr2:set_source(color(beautiful.fg_normal))
cr:set_line_width(2) for i=1,5 do
cr2:set_line_width(2) cr:rectangle(i, (size-11)/2+(11/2)-i, 11-i*2, 1)
cr:move_to( sp , sp );cr:line_to( rs , sp ) cr2:rectangle(i, (11)-(11/2)+i, 11-i*2, 1)
cr:move_to( sp , sp );cr:line_to( sp , rs ) end
cr:move_to( sp , rs );cr:line_to( rs , rs ) cr:fill()
cr:move_to( rs , sp );cr:line_to( rs , rs ) cr2:fill()
cr:move_to( sp , sp );cr:line_to( rs , rs )
cr:move_to( sp , rs );cr:line_to( rs , sp )
cr:stroke()
cr2:move_to( sp , sp );cr2:line_to (rs , sp , beautiful.fg_normal )
cr2:move_to( sp , sp );cr2:line_to (sp , rs , beautiful.fg_normal )
cr2:move_to( sp , rs );cr2:line_to (rs , rs , beautiful.fg_normal )
cr2:move_to( rs , sp );cr2:line_to (rs , rs , beautiful.fg_normal )
cr2:stroke()
isinit = true isinit = true
end end
@ -76,7 +59,16 @@ local function new(data)
scroll_w[v] = wibox.widget.background() scroll_w[v] = wibox.widget.background()
scroll_w[v]:set_widget(ib) scroll_w[v]:set_widget(ib)
scroll_w[v].visible = true scroll_w[v].visible = true
data.item_style(data,{widget=scroll_w[v]},false,false,true) data.item_style(data,{widget=scroll_w[v]},false,false,beautiful.bg_highlight)
scroll_w[v]:connect_signal("mouse::enter",function()
data.item_style(data,{widget=scroll_w[v]},false,false,beautiful.bg_alternate or beautiful.bg_focus)
end)
scroll_w[v]:connect_signal("mouse::leave",function()
data.item_style(data,{widget=scroll_w[v]},false,false,beautiful.bg_highlight)
end)
scroll_w[v]:buttons( util.table.join( button({ }, 1, function()
data["scroll_"..v](data)
end) ))
end end
return scroll_w return scroll_w
end end