diff --git a/base.lua b/base.lua index 424ed67..4491de1 100644 --- a/base.lua +++ b/base.lua @@ -139,6 +139,10 @@ local function add_item(data,args) for i=1,10 do item["button"..i] = args["button"..i] 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) private_data.selected = value @@ -385,6 +389,26 @@ local function new(args) data:emit_signal("clear::menu") 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 private_data.layout:setup_key_hooks(data) end diff --git a/context.lua b/context.lua index e7bd585..7f98e7d 100644 --- a/context.lua +++ b/context.lua @@ -42,7 +42,7 @@ local function set_position(self) if parent.direction == "right" then ret={x=parent.x-self.width,y=parent.y+(self.parent_item.y)} 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 ret.y = ret.y - self.height + self.item_height end @@ -147,6 +147,31 @@ end local function setup_item(data,item,args) local f = (data._internal.layout.setup_item) or (layout.vertical.setup_item) 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 local function new(args) @@ -161,6 +186,9 @@ local function new(args) ret:connect_signal("clear::menu",function(_,vis) ret._internal.layout:reset() end) + ret:connect_signal("_hidden::changed",function(_,item) + item.widget:emit_signal("widget::updated") + end) return ret end diff --git a/item_style/classic.lua b/item_style/classic.lua index a04410e..68524e2 100644 --- a/item_style/classic.lua +++ b/item_style/classic.lua @@ -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 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) 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 if not focussed or not focussed[ih] 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 focussed[ih] = gen(ih,data.bg_focus,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 if is_focussed then item.widget:set_bg(focussed[ih]) - elseif is_alt then - item.widget:set_bg(alt[ih]) + elseif col then + item.widget:set_bg(alt[col][ih]) else item.widget:set_bg(default[ih]) end diff --git a/layout/vertical.lua b/layout/vertical.lua index 50be7d2..995eacc 100644 --- a/layout/vertical.lua +++ b/layout/vertical.lua @@ -1,17 +1,16 @@ local setmetatable = setmetatable -local print,pairs = print,pairs -local unpack=unpack -local math = math -local util = require( "awful.util" ) -local button = require( "awful.button" ) +local print,pairs = print,pairs +local unpack = unpack +local util = require( "awful.util" ) +local button = require( "awful.button" ) local checkbox = require( "radical.widgets.checkbox" ) -local scroll = require( "radical.widgets.scroll" ) -local filter = require( "radical.widgets.filter" ) -local fkey = require( "radical.widgets.fkey" ) -local beautiful = require("beautiful") -local wibox = require( "wibox" ) -local color = require( "gears.color" ) -local cairo = require( "lgi" ).cairo +local scroll = require( "radical.widgets.scroll" ) +local filter = require( "radical.widgets.filter" ) +local fkey = require( "radical.widgets.fkey" ) +local beautiful = require("beautiful" ) +local wibox = require( "wibox" ) +local color = require( "gears.color" ) +local cairo = require( "lgi" ).cairo local module = {} @@ -80,7 +79,7 @@ local function cache_pixmap(item) item._internal.pix_cache = {} item.widget._draw = item.widget.draw 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 cr:set_source_surface(item._internal.pix_cache[10*width+7*height+(item.selected and 8888 or 999)]) 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::leave", function() item.selected = false end) 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 data:connect_signal("visible::changed",function(_,vis) @@ -136,7 +121,6 @@ function module:setup_item(data,item,args) data.height = fit_h data.style(data) end) - item.widget:buttons( util.table.join(unpack(buttons))) --Create the main item layout 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 m.fit = function(...) - if not data.visible or (item.visible == false or item._filter_out == true) then - return 1,1 + if not data.visible or (item.visible == false or item._filter_out == true or item._hidden == true) then + return 0,0 end return data._internal.layout.item_fit(data,item,...) end @@ -260,10 +244,22 @@ local function compute_geo(data) 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 + 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 - 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 - 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 local fw,fh = v.widget:fit(9999,9999) h = h + fh diff --git a/widgets/scroll.lua b/widgets/scroll.lua index b2c3646..0c3a632 100644 --- a/widgets/scroll.lua +++ b/widgets/scroll.lua @@ -1,16 +1,16 @@ local setmetatable = setmetatable local print = print -local color = require("gears.color") -local cairo = require( "lgi" ).cairo -local wibox = require("wibox") - -local beautiful = require( "beautiful" ) +local color = require( "gears.color" ) +local cairo = require( "lgi" ).cairo +local wibox = require( "wibox" ) +local util = require( "awful.util" ) +local button = require( "awful.button" ) +local beautiful = require( "beautiful" ) local module = {} -local arr_up -local arr_down -local isinit = false +local arr_up,arr_down +local isinit = false local function init() local size = beautiful.menu_height or 16 @@ -18,31 +18,14 @@ local function init() arr_up = cairo.ImageSurface(cairo.Format.ARGB32, size,size) local cr2 = cairo.Context(arr_down) 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)) cr2:set_source(color(beautiful.fg_normal)) - cr:set_line_width(2) - cr2:set_line_width(2) - cr:move_to( sp , sp );cr:line_to( rs , sp ) - cr:move_to( sp , sp );cr:line_to( sp , rs ) - cr:move_to( sp , rs );cr:line_to( rs , rs ) - cr:move_to( rs , sp );cr:line_to( rs , rs ) - 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() + for i=1,5 do + cr:rectangle(i, (size-11)/2+(11/2)-i, 11-i*2, 1) + cr2:rectangle(i, (11)-(11/2)+i, 11-i*2, 1) + end + cr:fill() + cr2:fill() isinit = true end @@ -76,7 +59,16 @@ local function new(data) scroll_w[v] = wibox.widget.background() scroll_w[v]:set_widget(ib) 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 return scroll_w end