diff --git a/base.lua b/base.lua index 313b85a..aee3acb 100644 --- a/base.lua +++ b/base.lua @@ -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) diff --git a/embed.lua b/embed.lua index 8d2bd33..20e8c05 100644 --- a/embed.lua +++ b/embed.lua @@ -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; diff --git a/item/common.lua b/item/common.lua new file mode 100644 index 0000000..6f094b1 --- /dev/null +++ b/item/common.lua @@ -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; diff --git a/item/init.lua b/item/init.lua index 53664e9..866532c 100644 --- a/item/init.lua +++ b/item/init.lua @@ -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 diff --git a/item/layout/centerred.lua b/item/layout/centerred.lua index 3864d18..5cdd4e6 100644 --- a/item/layout/centerred.lua +++ b/item/layout/centerred.lua @@ -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 diff --git a/item/layout/horizontal.lua b/item/layout/horizontal.lua index d71b350..027996f 100644 --- a/item/layout/horizontal.lua +++ b/item/layout/horizontal.lua @@ -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 diff --git a/item/layout/icon.lua b/item/layout/icon.lua index 34e6ae1..4ff40fd 100644 --- a/item/layout/icon.lua +++ b/item/layout/icon.lua @@ -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 diff --git a/item/layout/notification.lua b/item/layout/notification.lua index 74efa55..6529e5c 100644 --- a/item/layout/notification.lua +++ b/item/layout/notification.lua @@ -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 diff --git a/layout/vertical.lua b/layout/vertical.lua index 3523083..8c5bd3c 100644 --- a/layout/vertical.lua +++ b/layout/vertical.lua @@ -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