cleanup: Mutualize some code and fix embed menus

This commit is contained in:
Emmanuel Lepage Vallee 2016-03-05 02:14:24 -05:00
parent 2af6ad83e2
commit 9ea34d4003
9 changed files with 185 additions and 237 deletions

View File

@ -68,17 +68,6 @@ theme.register_color(module.item_flags.USED , "used" , "used" , t
theme.register_color(module.item_flags.CHECKED , "checked" , "checked" , true )
theme.register_color(module.item_flags.ALTERNATE , "alternate" , "alternate" , true )
theme.register_color(module.item_flags.HIGHLIGHT , "highlight" , "highlight" , true )
-- register_color(item_flags.HEADER , ""
-- register_color(item_flags.USR1 , ""
-- register_color(item_flags.USR2 , ""
-- register_color(item_flags.USR3 , ""
-- register_color(item_flags.USR4 , ""
-- register_color(item_flags.USR5 , ""
-- register_color(item_flags.USR6 , ""
-- register_color(item_flags.USR7 , ""
-- register_color(item_flags.USR8 , ""
-- register_color(item_flags.USR9 , ""
-- register_color(item_flags.USR10 , ""
local function filter(data)

View File

@ -1,48 +1,35 @@
local base = require( "radical.base" )
local print = print
local unpack = unpack
local debug = debug
local type = type
local setmetatable = setmetatable
local color = require( "gears.color" )
local wibox = require( "wibox" )
local beautiful = require( "beautiful" )
local cairo = require( "lgi" ).cairo
local awful = require( "awful" )
local util = require( "awful.util" )
local button = require( "awful.button" )
local layout = require( "radical.layout" )
local checkbox = require( "radical.widgets.checkbox" )
local setmetatable = setmetatable
local base = require( "radical.base" )
local layout = require( "radical.layout" )
local classic_style = require( "radical.style.classic" )
local common = require( "radical.common" )
local capi,module = { mouse = mouse , screen = screen , keygrabber = keygrabber },{}
local common = require( "radical.common" )
local function setup_drawable(data)
local internal = data._internal
local private_data = internal.private_data
local internal = data._internal
-- An embeded menu can only be visible if the parent is
data.get_visible = function() return data._embeded_parent and data._embeded_parent.visible or false end --Let the parent handle that
data.set_visible = function(_,v) if data._embeded_parent then data._embeded_parent.visible = v end end
-- An embeded menu can only be visible if the parent is
data.get_visible = function() return data._embeded_parent and data._embeded_parent.visible or false end
data.set_visible = function(_,v) if data._embeded_parent then data._embeded_parent.visible = v end end
-- Enumate geometry --BUG this is fake, but better than nothing
local l = data.layout or layout.vertical
internal.layout = l(data)
if not data.layout then
data.layout = layout.vertical
end
internal.layout = data.layout(data)
data.margins={left=0,right=0,bottom=0,top=0}
internal.layout:connect_signal("mouse::enter",function(_,geo)
if data._embeded_parent._current_item then
data._embeded_parent._current_item.selected = false
end
end)
internal.layout:connect_signal("mouse::leave",function(_,geo)
if data._current_item then
data._current_item.selected = false
end
end)
data.margins = {left=0,right=0,bottom=0,top=0}
internal.layout:connect_signal("mouse::enter",function(_,geo)
if data._embeded_parent._current_item then
data._embeded_parent._current_item.selected = false
end
end)
internal.layout:connect_signal("mouse::leave",function(_,geo)
if data._current_item then
data._current_item.selected = false
end
end)
-- Support remove, swap, insert, append...
common.setup_item_move_events(data)
end
local function new(args)
@ -53,11 +40,12 @@ local function new(args)
args.style = args.style or classic_style
local ret = base(args)
ret:connect_signal("clear::menu",function(_,vis)
local l = ret._internal.content_layout or ret._internal.layout
l:reset()
local l = ret._internal.content_layout or ret._internal.layout
l:reset()
end)
return ret
end
return setmetatable(module, { __call = function(_, ...) return new(...) end })
-- kate: space-indent on; indent-width 2; replace-tabs on;
return setmetatable({}, { __call = function(_, ...) return new(...) end })
-- kate: space-indent on; indent-width 4; replace-tabs on;

79
item/common.lua Normal file
View File

@ -0,0 +1,79 @@
local wibox = require( "wibox" )
local module = {}
-- Apply icon transformation
local function set_icon(self,image)
if self._data.icon_transformation then
self._item._original_icon = image
image = self._data.icon_transformation(image,self._data,self._item)
end
wibox.widget.imagebox.set_image(self,image)
end
-- Setup the item icon
function module.setup_icon(item,data) --TODO maybe create a proper widget
local icon = wibox.widget.imagebox()
icon._data = data
icon._item = item
icon.set_image = set_icon
if item.icon then
icon:set_image(item.icon)
end
item.set_icon = function (_,value) icon:set_image(value) end
return icon
end
-- Add [F1], [F2] ... to items
function module.setup_fkey(item,data)
item.set_f_key = function(_,value)
item._internal.has_changed = true
item._internal.f_key = value
data:remove_key_hook("F"..value)
data:add_key_hook({}, "F"..value , "press", function()
item.button1(data,menu)
data.visible = false
end)
end
item.get_f_key = function() return item._internal.f_key end
end
-- Proxy all events to the parent
function module.setup_event(data,item,widget)
local widget = widget or item.widget
-- Setup data signals
widget:connect_signal("button::press",function(_,__,___,id,mod,geo)
local mods_invert = {}
for k,v in ipairs(mod) do
mods_invert[v] = i
end
item.state[4] = true
data:emit_signal("button::press",item,id,mods_invert,geo)
item:emit_signal("button::press",data,id,mods_invert,geo)
end)
widget:connect_signal("button::release",function(wdg,__,___,id,mod,geo)
local mods_invert = {}
for k,v in ipairs(mod) do
mods_invert[v] = i
end
item.state[4] = nil
data:emit_signal("button::release",item,id,mods_invert,geo)
item:emit_signal("button::release",data,id,mods_invert,geo)
end)
widget:connect_signal("mouse::enter",function(b,mod,geo)
data:emit_signal("mouse::enter",item,mod,geo)
item:emit_signal("mouse::enter",data,mod,geo)
end)
widget:connect_signal("mouse::leave",function(b,mod,geo)
data:emit_signal("mouse::leave",item,mod,geo)
item:emit_signal("mouse::leave",data,mod,geo)
end)
end
return module
-- kate: space-indent on; indent-width 4; replace-tabs on;

View File

@ -135,9 +135,7 @@ local function new_item(data,args)
item._private_data = private_data
item._internal = args._internal or {}
theme.setup_item_colors(data,item,args)
-- item.get_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 --Hack around missing :fit call for last item
-- end
item.get_height = function()
return args.height or data.item_height or beautiful.menu_height or 30
end
@ -188,6 +186,12 @@ local function new_item(data,args)
data._current_item = item
end
function item:set_hover(value)
local item_style = item.item_style or data.item_style
item.state[module.item_flags.HOVERED] = value and true or nil
item_style(item)
end
-- Overlay and underlay
item.set_infoshapes = set_infoshapes

View File

@ -3,6 +3,7 @@ local wibox = require( "wibox" )
local util = require( "awful.util" )
local horizontal = require( "radical.item.layout.horizontal" )
local margins2 = require( "radical.margins" )
local common = require( "radical.item.common" )
local function create_item(item,data,args)
@ -39,7 +40,7 @@ local function create_item(item,data,args)
end
-- Setup events
horizontal.setup_event(data, item, w)
common.setup_event(data, item, w)
return w
end

View File

@ -1,65 +1,17 @@
local setmetatable = setmetatable
local beautiful = require( "beautiful" )
local color = require( "gears.color" )
local cairo = require( "lgi" ).cairo
local wibox = require( "wibox" )
local checkbox = require( "radical.widgets.checkbox" )
local fkey = require( "radical.widgets.fkey" )
local infoshapes = require( "radical.widgets.infoshapes" )
local theme = require( "radical.theme" )
local util = require( "awful.util" )
local margins2 = require( "radical.margins" )
local shape = require( "gears.shape" )
local surface = require( "gears.surface" )
local common = require( "radical.item.common" )
local module = {}
-- Add [F1], [F2] ... to items
function module:setup_fkey(item,data)
item.set_f_key = function(_,value)
item._internal.has_changed = true
item._internal.f_key = value
data:remove_key_hook("F"..value)
data:add_key_hook({}, "F"..value , "press", function()
item.button1(data,menu)
data.visible = false
end)
end
item.get_f_key = function() return item._internal.f_key end
end
function module.after_draw_children(self, context, cr, width, height)
--TODO get rid of this, use the stack container
if self._item.overlay_draw then
self._item.overlay_draw(context,self._item,cr,width,height)
end
end
-- Apply icon transformation
function module.set_icon(self,image)
if self._data.icon_transformation then
self._item._original_icon = image
image = self._data.icon_transformation(image,self._data,self._item)
end
wibox.widget.imagebox.set_image(self,image)
end
-- Setup the item icon
function module:setup_icon(item,data)
local icon = wibox.widget.imagebox()
icon._data = data
icon._item = item
icon.set_image = module.set_icon
if item.icon then
icon:set_image(item.icon)
end
item.set_icon = function (_,value)
icon:set_image(value)
end
return icon
end
-- Show the checkbox
function module:setup_checked(item,data)
if item.checkable then
@ -81,15 +33,6 @@ function module:setup_checked(item,data)
end
end
-- Setup hover
function module:setup_hover(item,data)
item.set_hover = function(_,value)
local item_style = item.item_style or data.item_style
item.state[-1] = value and true or nil
item_style(item,{})
end
end
-- Create sub_menu arrows
local sub_arrow = nil
function module:setup_sub_menu_arrow(item,data)
@ -112,97 +55,30 @@ function module:setup_sub_menu_arrow(item,data)
end
end
-- Proxy all events to the parent
function module.setup_event(data,item,widget)
local widget = widget or item.widget
-- Setup data signals
widget:connect_signal("button::press",function(_,__,___,id,mod,geo)
local mods_invert = {}
for k,v in ipairs(mod) do
mods_invert[v] = i
local function set_text(self, value)
if data.disable_markup then
self:set_text(value)
else
self:set_markup(value)
end
item.state[4] = true
data:emit_signal("button::press",item,id,mods_invert,geo)
item:emit_signal("button::press",data,id,mods_invert,geo)
end)
widget:connect_signal("button::release",function(wdg,__,___,id,mod,geo)
local mods_invert = {}
for k,v in ipairs(mod) do
mods_invert[v] = i
end
item.state[4] = nil
data:emit_signal("button::release",item,id,mods_invert,geo)
item:emit_signal("button::release",data,id,mods_invert,geo)
end)
widget:connect_signal("mouse::enter",function(b,mod,geo)
data:emit_signal("mouse::enter",item,mod,geo)
item:emit_signal("mouse::enter",data,mod,geo)
end)
widget:connect_signal("mouse::leave",function(b,mod,geo)
data:emit_signal("mouse::leave",item,mod,geo)
item:emit_signal("mouse::leave",data,mod,geo)
end)
-- Always tracking mouse::move is expensive, only do it when necessary
-- local function conn(b,t)
-- item:emit_signal("mouse::move",item)
-- end
-- item:connect_signal("connection",function(_,name,count)
-- if name == "mouse::move" then
-- widget:connect_signal("mouse::move",conn)
-- end
-- end)
-- item:connect_signal("disconnection",function(_,name,count)
-- if count == 0 then
-- widget:connect_signal("mouse::move",conn)
-- end
-- end)
self._private_data.text = value
end
-- Create the actual widget
local function create_item(item,data,args)
-- F keys
common.setup_fkey(item,data)
-- F keys
module:setup_fkey(item,data)
-- Icon
local icon = common.setup_icon(item,data)
-- Icon
local icon = module:setup_icon(item,data)
icon.fit = function(...)
local w,h = wibox.widget.imagebox.fit(...)
return w+3,h
end
if data.icon_per_state == true then
item:connect_signal("state::changed",function(i,d,st)
if item._original_icon and data.icon_transformation then
wibox.widget.imagebox.set_image(icon,data.icon_transformation(item._original_icon,data,item))
end
end)
end
-- Text
local tb = wibox.widget.textbox()
tb:set_text(item.text)
item.set_text = function (_,value)
if data.disable_markup then
tb:set_text(value)
else
tb:set_markup(value)
if data.icon_per_state == true then --TODO create an icon widget, see item/common.lua
item:connect_signal("state::changed",function(i,d,st)
if item._original_icon and data.icon_transformation then
wibox.widget.imagebox.set_image(icon,data.icon_transformation(item._original_icon,data,item))
end
end)
end
item._private_data.text = value
end
-- Hover
module:setup_hover(item,data)
-- Overlay
item.set_overlay = function(_,value)
item._private_data.overlay = value
item.widget:emit_signal("widget::updated")
end
-- Define the item layout
item.widget = wibox.widget.base.make_widget_declarative {
@ -219,7 +95,11 @@ local function create_item(item,data,args)
-- Widget
data.fkeys_prefix and fkey(data,item) or nil,
icon ,
{
icon ,
right = 3 ,
widget = wibox.layout.margin ,
},
args.prefix_widget ,
-- Attributes
@ -227,7 +107,13 @@ local function create_item(item,data,args)
},
{
-- Underlay and overlay
tb,
{
-- The main textbox
id = "main_text" ,
_private_data = item._private_data ,
text = item.text ,
widget = wibox.widget.textbox,
},
-- Attributes
widget = infoshapes,
@ -270,10 +156,11 @@ local function create_item(item,data,args)
-- Make some widgets easier to access
item._internal.margin_w = item.widget:get_children_by_id("main_margin")[1]
item._internal.align = item.widget:get_children_by_id("main_align" )[1]
item._internal.text_w = item.widget:get_children_by_id("main_text" )[1]
item._internal.icon_w = icon
-- Override some methods
item._internal.text_w = tb
item._internal.icon_w = icon
item._internal.text_w.set_text = set_text
-- Export the margin
local mrgns = margins2(
@ -292,7 +179,7 @@ local function create_item(item,data,args)
item_style(item,{})
-- Setup events
module.setup_event(data,item)
common.setup_event(data,item)
return item.widget
end

View File

@ -6,30 +6,36 @@ local checkbox = require( "radical.widgets.checkbox" )
local horizontal = require( "radical.item.layout.horizontal" )
local util = require( "awful.util" )
local margins2 = require( "radical.margins" )
local common = require( "radical.item.common" )
local module = {}
local function icon_fit(data,...)
local w,h = wibox.widget.imagebox.fit(...)
--Try to retermine the limiting factor
if data._internal.layout.dir == "y" then
return data.icon_size or w,data.icon_size or h
else
return w,data.icon_size or h
end
local function after_draw_children(self, context, cr, width, height)
--TODO get rid of this, use the stack container
if self._item.overlay_draw then
self._item.overlay_draw(context,self._item,cr,width,height)
end
end
local function icon_fit(data,...)
local w,h = wibox.widget.imagebox.fit(...)
--Try to retermine the limiting factor
if data._internal.layout.dir == "y" then
return data.icon_size or w,data.icon_size or h
else
return w,data.icon_size or h
end
end
local function icon_draw(self, context, cr, width, height)
local w,h = wibox.widget.imagebox.fit(self,context,width,height)
cr:save()
cr:translate((width-w)/2,0)
wibox.widget.imagebox.draw(self, context, cr, width, height)
cr:restore()
local w,h = wibox.widget.imagebox.fit(self,context,width,height)
cr:save()
cr:translate((width-w)/2,0)
wibox.widget.imagebox.draw(self, context, cr, width, height)
cr:restore()
end
local function create_item(item,data,args)
if data.fkeys_prefix == true then
local pref = wibox.widget.textbox()
@ -40,7 +46,7 @@ local function create_item(item,data,args)
end
end
local icon = horizontal.setup_icon(horizontal,item,data)
local icon = common.setup_icon(item,data)
icon.fit = function(...) return icon_fit(data,...) end
icon.draw = icon_draw
@ -128,7 +134,7 @@ local function create_item(item,data,args)
item._internal.margin_w = item.widget:get_children_by_id("main_margin")[1]
item._internal.text_w = item.widget:get_children_by_id("main_text")[1]
item._private_data._fit = wibox.widget.background.fit
w.after_draw_children = horizontal.after_draw_children
w.after_draw_children = after_draw_children
w.fit = bg_fit
-- Setup margins
@ -142,7 +148,7 @@ local function create_item(item,data,args)
end
-- Setup events
horizontal.setup_event(data,item,w)
common.setup_event(data,item,w)
return w
end

View File

@ -1,7 +1,8 @@
local setmetatable = setmetatable
local wibox = require( "wibox" )
local wibox = require( "wibox" )
local horizontal= require( "radical.item.layout.horizontal")
local margins2 = require( "radical.margins" )
local common = require( "radical.item.common" )
local module = {}
@ -31,7 +32,7 @@ local function create_item(item,data,args)
local right = wibox.layout.fixed.horizontal()
-- Icon
local icon = horizontal.setup_icon(horizontal,item,data)
local icon = common.setup_icon(item,data)
icon.fit = function(...)
local w,h = wibox.widget.imagebox.fit(...)
return w+3,h
@ -49,9 +50,6 @@ local function create_item(item,data,args)
right:add(ck)
end
-- Hover
horizontal:setup_hover(item,data)
-- Sub_arrow
local ar = horizontal:setup_sub_menu_arrow(item,data)
if ar then
@ -122,7 +120,7 @@ local function create_item(item,data,args)
item.widget:set_fg(item._private_data.fg)
-- Setup events
horizontal.setup_event(data,item)
common.setup_event(data,item)
return bg
end

View File

@ -13,7 +13,7 @@ local module = {}
local function item_fit(data,item,self,context, width,height)
local w, h = 0,0--item._internal.cache_w or 1,item._internal.cache_h or 1
if data.visible then
w, h = item._private_data._fit({},self,context,width,height)
w, h = item._private_data._fit(self,context,width,height)
end
return w, item.height or h
@ -21,17 +21,13 @@ end
function module:setup_item(data,item,args)
item._private_data._fit = wibox.widget.background.fit
if item._internal.margin_w then
item._internal.margin_w.fit = function(...)
if (item.visible == false or item._filter_out == true or item.widget.visible == false) then
return 0,0
end
return item_fit(data,item,...)
end
end
if not item._internal.margin_w then return end
item._internal.margin_w.fit = function(...) return item_fit(data,item,...) end
-- Compute the minimum width
if data.auto_resize and item._internal.margin_w then
if data.auto_resize then
local fit_w = wibox.layout.margin.fit(item._internal.margin_w,{dpi=96},9999,9999)
local is_largest = item == data._internal.largest_item_w
if fit_w < 1000 and (not data._internal.largest_item_w_v or data._internal.largest_item_w_v < fit_w) then