diff --git a/bar.lua b/bar.lua index 0b488ac..437cf2e 100644 --- a/bar.lua +++ b/bar.lua @@ -156,6 +156,9 @@ local function setup_item(data,item,args) -- Setup buttons setup_buttons(data,item,args) + + -- Tooltip + item.widget:set_tooltip(item.tooltip) end local function new(args) diff --git a/base.lua b/base.lua index f4d5fde..62532ab 100644 --- a/base.lua +++ b/base.lua @@ -331,7 +331,7 @@ local function new(args) layout = args.layout or nil, screen = args.screen or nil, style = args.style or nil, - item_style = args.item_style or beautiful.menu_item_style or require("radical.item.style.basic"), + item_style = args.item_style or beautiful.menu_default_item_style or require("radical.item.style.basic"), item_layout = args.item_layout or nil, filter = args.filter ~= false, show_filter = args.show_filter or false, @@ -369,7 +369,9 @@ local function new(args) filter_underlay_color = args.filter_underlay_color, filter_placeholder = args.filter_placeholder or "", disable_submenu_icon = args.disable_submenu_icon or false, - item_border_color = args.item_border_color or beautiful.menu_item_border_color or nil, + item_border_color = args.item_border_color or beautiful.menu_item_border_color + or args.border_color or beautiful.menu_border_color or beautiful.border_color or nil, + item_border_width = args.item_border_width or beautiful.menu_item_border_width or nil, }, force_private = { parent = true, @@ -603,6 +605,12 @@ local function new(args) internal.items[data._start_at+data.max_items]._hidden = true data:emit_signal("_hidden::changed",internal.items[data._start_at+data.max_items]) filter(data) + + --HACK upstream bug + internal.items[data._start_at].widget:emit_signal("widget::layout_changed") + internal.items[data._start_at+data.max_items].widget:emit_signal("widget::layout_changed") + data._internal.layout:emit_signal("widget::redraw_needed") + data._internal.layout:emit_signal("widget::layout_changed") end end @@ -618,6 +626,12 @@ local function new(args) internal.items[data._start_at-1+data.max_items]._hidden = false data:emit_signal("_hidden::changed",internal.items[data._start_at-1+data.max_items]) filter(data) + + --HACK upstream bug + internal.items[data._start_at-1].widget:emit_signal("widget::layout_changed") + internal.items[data._start_at-1+data.max_items].widget:emit_signal("widget::layout_changed") + data._internal.layout:emit_signal("widget::redraw_needed") + data._internal.layout:emit_signal("widget::layout_changed") end end diff --git a/context.lua b/context.lua index 07e81d0..1f48a14 100644 --- a/context.lua +++ b/context.lua @@ -1,6 +1,6 @@ local base = require( "radical.base" ) local print = print -local unpack = unpack +local unpack = unpack or table.unpack local debug = debug local rawset = rawset local type = type @@ -23,15 +23,22 @@ local capi,module = { mouse = mouse , screen = screen, keygrabber = keygrabber } local function get_direction(data) local parent_geometry = data.parent_geometry --Local cache to avoid always calling the object hooks if not parent_geometry or not parent_geometry.drawable then return "bottom" end + + -- The border width is not included in the geometry + local bw = data.wibox.border_width or 0 + local drawable_geom = parent_geometry.drawable.drawable.geometry(parent_geometry.drawable.drawable) + + drawable_geom.x, drawable_geom.height = drawable_geom.x - bw, drawable_geom.height + 2*bw + if parent_geometry.y+parent_geometry.height < drawable_geom.height then --Vertical wibox - if drawable_geom.x > capi.screen[capi.mouse.screen].geometry.width - (drawable_geom.x+drawable_geom.width) then + if drawable_geom.x >= capi.screen[capi.mouse.screen].geometry.width - (drawable_geom.x+drawable_geom.width) then return "right" else return "left" end else --Horizontal wibox - if drawable_geom.y > capi.screen[capi.mouse.screen].geometry.height - (drawable_geom.y+drawable_geom.height) then + if drawable_geom.y >= capi.screen[capi.mouse.screen].geometry.height - (drawable_geom.y+drawable_geom.height) then return "bottom" else return "top" @@ -55,12 +62,14 @@ end local function change_geometry_idle(data, x, y, w, h) data._internal._next_geometry = data._internal._next_geometry or {} local geo = data._internal._next_geometry - geo.x = x or geo.x - geo.y = y or geo.y - geo.width = w or geo.width - geo.height = h or geo.height + + -- The border_width is not included in the geometry + geo.x = x and (x - data.wibox.border_width) or geo.x + geo.y = y and (y - data.wibox.border_width) or geo.y + geo.width = w and (w - data.wibox.border_width) or geo.width + geo.height = h and (h - data.wibox.border_width) or geo.height if not data._internal._need_geometry_reload then - glib.idle_add(glib.PRIORITY_HIGH_IDLE, function() set_geometry_real(data) end) + glib.idle_add(0, function() set_geometry_real(data) end) data._internal._need_geometry_reload = true end end @@ -90,9 +99,14 @@ local function set_position(self) elseif parent then local drawable_geom = parent.drawable.drawable.geometry(parent.drawable.drawable) if (self.direction == "left") or (self.direction == "right") then - ret = {x=drawable_geom.x+((self.direction == "right") and - self.width or drawable_geom.width),y=drawable_geom.y+parent.y--[[+((self.arrow_type ~= base.arrow_type.NONE) and parent.height/2-(self.arrow_x or 20)-6 or 0)]]} + ret = { + x=drawable_geom.x+((self.direction == "right") and - self.width or drawable_geom.width), + y=drawable_geom.y+parent.y--[[+((self.arrow_type ~= base.arrow_type.NONE) and parent.height/2-(self.arrow_x or 20)-6 or 0)]] + } else - ret = {x=drawable_geom.x+parent.x-((self.arrow_type ~= base.arrow_type.NONE) and (self.arrow_x or 20)+11-parent.width/2 or 0),y=(self.direction == "bottom") and drawable_geom.y-self.height or drawable_geom.y+drawable_geom.height} + ret = { + x=drawable_geom.x+parent.x-((self.arrow_type ~= base.arrow_type.NONE) and (self.arrow_x or 20)+11-parent.width/2 or 0), + y=(self.direction == "bottom") and drawable_geom.y-self.height or drawable_geom.y+drawable_geom.height} end elseif prefx ~= 0 or prefy ~= 0 then ret = capi.mouse.coords() @@ -145,6 +159,8 @@ local function setup_drawable(data) internal.w:set_widget(internal.margin) internal.w:set_fg(data.fg) internal.w.opacity = data.opacity + internal.w.border_color = data.border_color or beautiful.menu_outline_color or beautiful.menu_border_color or beautiful.fg_normal + internal.w:set_bg(data.bg) --Getters data.get_wibox = function() return internal.w end @@ -276,7 +292,7 @@ local function new(args) args.internal.set_position = args.internal.set_position or set_position args.internal.setup_drawable = args.internal.setup_drawable or setup_drawable args.internal.setup_item = args.internal.setup_item or setup_item - args.style = args.style or arrow_style + args.style = args.style or beautiful.menu_default_style or arrow_style local ret = base(args) ret:connect_signal("clear::menu",function(_,vis) ret._internal.layout:reset() diff --git a/dock.lua b/dock.lua index 78fb05c..9c82a48 100644 --- a/dock.lua +++ b/dock.lua @@ -199,7 +199,8 @@ local function adapt_size(data,w,h,screen) data.icon_size = w end data._internal._geom_vals = nil - return w,h + + return w == 0 and 1 or w, h == 0 and 1 or h end -- Create the auto hiding wibox diff --git a/impl/common/client.lua b/impl/common/client.lua index a7e03ce..e485119 100644 --- a/impl/common/client.lua +++ b/impl/common/client.lua @@ -4,6 +4,8 @@ local type,math = type,math local awful = require( "awful" ) local cairo = require( "lgi" ).cairo local surface = require("gears.surface") +local shape = require("gears.shape") +local util = require("awful.util") local module = {} local function createTagList(aScreen) @@ -81,31 +83,17 @@ function module.screenshot(clients,geo) local img = cairo.ImageSurface(cairo.Format.ARGB32, w, h) local cr = cairo.Context(img) - -- Create a mask - cr:arc(10,10,10,0,math.pi*2) - cr:fill() - cr:arc(w-10,10,10,0,math.pi*2) - cr:fill() - cr:arc(w-10,h-10,10,0,math.pi*2) - cr:fill() - cr:arc(10,h-10,10,0,math.pi*2) - cr:fill() - cr:rectangle(10,0,w-20,h) - cr:rectangle(0,10,w,h-20) - cr:fill() - -- Create a matrix to scale down the screenshot cr:scale(scale+0.05,scale+0.05) -- Paint the screenshot in the rounded rectangle cr:set_source_surface(surface(c.content)) - cr:set_operator(cairo.Operator.IN) cr:paint() -- Create the item local prev_item = prev_menu:add_item({text = ""..c.name.."",icon=img}) prev_menu.wibox.opacity=0.8 - prev_item.icon = img + prev_item.icon = surface.duplicate_surface(img, shape.rounded_rect, 10) prev_item.text = ""..c.name:gsub('&','&').."" end diff --git a/impl/taglist/init.lua b/impl/taglist/init.lua index 35b486d..1228a80 100644 --- a/impl/taglist/init.lua +++ b/impl/taglist/init.lua @@ -80,7 +80,7 @@ local function create_item(t,s) tw = wibox.widget.textbox() tw.draw = index_draw local index = tag.getproperty(t,"index") or tag.getidx(t) - tw:set_markup((menu.index_prefix or " #")..(index)..(menu.index_suffix or ": ")) + tw:set_markup((menu.index_prefix or " 2#")..(index)..(menu.index_suffix or ": ")) w:add(tw) end local suf_w = wibox.layout.fixed.horizontal() @@ -270,10 +270,13 @@ local function new(s) default_item_margins = beautiful.taglist_default_item_margins, default_margins = beautiful.taglist_default_margins , icon_per_state = beautiful.taglist_icon_per_state, + item_border_color = beautiful.taglist_item_border_color , + item_border_width = beautiful.taglist_item_border_width , -- fkeys_prefix = true, } for k,v in ipairs {"hover","used","urgent","cloned","changed","highlight"} do args["bg_"..v] = beautiful["taglist_bg_"..v] + args["bgimage_"..v] = beautiful["taglist_bgimage_"..v] args["fg_"..v] = beautiful["taglist_fg_"..v] end diff --git a/impl/tasklist/init.lua b/impl/tasklist/init.lua index 5f64e27..e2ddded 100644 --- a/impl/tasklist/init.lua +++ b/impl/tasklist/init.lua @@ -20,7 +20,7 @@ local rad_client = require( "radical.impl.common.client") local sticky,urgent,instances,module = {extensions=require("radical.impl.tasklist.extensions")},{},{},{} local _cache = setmetatable({}, { __mode = 'k' }) -local MINIMIZED = 101 +local MINIMIZED = 6.5 theme.register_color(MINIMIZED , "minimized" , "tasklist_minimized" , true ) -- Default button implementation @@ -63,7 +63,18 @@ local function display_screenshot(c,geo,visible) end if not c then return end - return rad_client.screenshot(c,geo) + local dgeo = geo.drawable.drawable:geometry() + + -- The geometry is a mix of the drawable and widget one + local geo2 = { + x = dgeo.x + geo.x, + y = dgeo.y + geo.y, + width = geo.width , + height = geo.height , + drawable = geo.drawable , + } + + return rad_client.screenshot(c,geo2) end local function sticky_callback(c) @@ -162,6 +173,11 @@ local function create_client_item(c,screen) icon=(not beautiful.tasklist_disable_icon) and surface(c.icon), suffix_widget=suf_w } + item.state[radical.base.item_flags.USED] = true + + if c.minimized then + item.state[MINIMIZED] = true + end item:connect_signal("mouse::enter", function() item.overlay = {"1:23:45", c.pid} @@ -271,10 +287,14 @@ local function new(screen) style = beautiful.tasklist_style , spacing = beautiful.tasklist_spacing , icon_per_state = true , + item_border_color = beautiful.tasklist_item_border_color , + item_border_width = beautiful.tasklist_item_border_width , } - for k,v in ipairs {"hover","urgent","minimized","focus"} do + for k,v in ipairs {"hover","urgent","minimized","focus","used"} do args["bg_"..v] = beautiful["tasklist_bg_"..v] + args["bgimage_"..v] = beautiful["tasklist_bgimage_"..v] args["fg_"..v] = beautiful["tasklist_fg_"..v] + args["border_color_"..v] = beautiful["tasklist_border_color_"..v] args["underlay_bg_"..v] = beautiful["tasklist_underlay_bg_"..v] end local menu = radical.flexbar(args) diff --git a/item/init.lua b/item/init.lua index 597f841..a660ca1 100644 --- a/item/init.lua +++ b/item/init.lua @@ -55,6 +55,13 @@ local function load_async(tab,key) elseif key == "layout" then module.layout = require("radical.item.layout") return module.layout + --TODO handle colors this way +-- elseif key:sub(1,7 ) == "get_fg_" then +-- +-- elseif key:sub(1,7 ) == "get_bg_" then +-- +-- elseif key:sub(1,17) == "get_border_color_" then +-- end return rawget(module,key) end @@ -107,8 +114,8 @@ local function new_item(data,args) suffix = args.suffix or "" , bg = args.bg or nil , fg = args.fg or data.fg , --TODO don't do this - border_color= args.border_color or data.border_color , - border_width= args.border_width or data.border_width , + border_color= args.border_color or data.item_border_color , + border_width= args.border_width or data.item_border_width , bg_prefix = args.bg_prefix or data.bg_prefix , sub_menu_m = (args.sub_menu and type(args.sub_menu) == "table" and args.sub_menu.is_menu) and args.sub_menu or nil, sub_menu_f = (args.sub_menu and type(args.sub_menu) == "function") and args.sub_menu or nil , diff --git a/item/layout/horizontal.lua b/item/layout/horizontal.lua index 2f3704d..570dcc4 100644 --- a/item/layout/horizontal.lua +++ b/item/layout/horizontal.lua @@ -8,7 +8,9 @@ local fkey = require( "radical.widgets.fkey" ) local underlay = require( "radical.widgets.underlay" ) local theme = require( "radical.theme" ) local util = require( "awful.util" ) -local margins2 = require("radical.margins") +local margins2 = require( "radical.margins") +local shape = require( "gears.shape" ) +local surface = require( "gears.surface" ) local module = {} @@ -60,6 +62,11 @@ function module.after_draw_children(self, context, cr, width, height) if self._item.overlay_draw then self._item.overlay_draw(context,self._item,cr,width,height) end + + -- Draw the border, if any + if self._after_draw_children then + self._after_draw_children(self, context, cr, width, height) + end end -- Apply icon transformation @@ -124,7 +131,16 @@ function module:setup_sub_menu_arrow(item,data) if not sub_arrow then sub_arrow = wibox.widget.imagebox() --TODO, make global sub_arrow.fit = function(box, context,w, h) return (sub_arrow._image and sub_arrow._image:get_width() or 0),item.height end - sub_arrow:set_image( beautiful.menu_submenu_icon ) + + if beautiful.menu_submenu_icon then + sub_arrow:set_image( beautiful.menu_submenu_icon ) + else + local h = data.item_height + sub_arrow:set_image(surface.load_from_shape(7, h, + shape.transform(shape.isosceles_triangle) : rotate_at(3.5,h/2,math.pi/2), + beautiful.menu_fg_normal or beautiful.menu_fg or beautiful.fg_normal + )) + end end return sub_arrow end @@ -323,7 +339,8 @@ local function create_item(item,data,args) -- bg:buttons(item.buttons) -- end - bg.after_draw_children = module.after_draw_children + bg._after_draw_children = bg.after_draw_children + bg.after_draw_children = module.after_draw_children return bg end diff --git a/item/style/arrow_3d.lua b/item/style/arrow_3d.lua index 0f1ca26..89d453a 100644 --- a/item/style/arrow_3d.lua +++ b/item/style/arrow_3d.lua @@ -3,6 +3,7 @@ local print = print local pairs = pairs local color = require( "gears.color" ) local base = require( "radical.base" ) +local theme = require( "radical.theme" ) local module = { margins = { @@ -80,20 +81,7 @@ local function draw(item,args) item.widget.background = nil end - local state = item.state or {} - local current_state = state._current_key or nil - local state_name = base.colors_by_id[current_state] - - if current_state == base.item_flags.SELECTED or (item._tmp_menu) then - item.widget:set_bg(item.bg_focus) - item.widget:set_fg(item.fg_focus) - elseif state_name then - item.widget:set_bg(args.color or item["bg_"..state_name]) - item.widget:set_fg( item["fg_"..state_name]) - else - item.widget:set_bg(args.color or nil) - item.widget:set_fg(item["fg"]) - end + theme.update_colors(item) end return setmetatable(module, { __call = function(_, ...) return draw(...) end }) diff --git a/item/style/arrow_alt.lua b/item/style/arrow_alt.lua index d197e9e..9959459 100644 --- a/item/style/arrow_alt.lua +++ b/item/style/arrow_alt.lua @@ -8,6 +8,7 @@ local beautiful = require("beautiful") local color = require("gears.color") local cairo = require("lgi").cairo local wibox = require("wibox") +local theme = require( "radical.theme" ) local module = { margins = { diff --git a/item/style/arrow_prefix.lua b/item/style/arrow_prefix.lua index cca6ad1..421f4e9 100644 --- a/item/style/arrow_prefix.lua +++ b/item/style/arrow_prefix.lua @@ -1,10 +1,9 @@ local setmetatable = setmetatable -local base = require( "radical.base" ) -local beautiful = require("beautiful" ) -local color = require("gears.color" ) -local cairo = require("lgi" ).cairo -local wibox = require("wibox" ) -local arrow_alt = require("radical.item.style.arrow_alt") +local beautiful = require( "beautiful" ) +local color = require( "gears.color" ) +local wibox = require( "wibox" ) +local theme = require( "radical.theme" ) +local shape = require( "gears.shape" ) local module = { margins = { @@ -16,26 +15,27 @@ local module = { need_full_repaint = true } -local function prefix_draw(self, context, cr, width, height) +local function before_draw_children(self, context, cr, width, height) cr:save() -- This item style require negative padding, this is a little dangerous to -- do as it can corrupt area outside of the widget - local col = self._item.bg_prefix or beautiful.icon_grad or beautiful.fg_normal - cr:set_source(color(col)) - cr:move_to(-height/2-2,0) - cr:line_to(width-height+2,0) - cr:rel_line_to(height*.6,height/2) - cr:line_to(width-height+2,height) - cr:line_to(-height*.6,height) - cr:line_to(0,height/2) - cr:close_path() + local col = self._item.bg_prefix or beautiful.icon_grad or beautiful.bg_prefix or beautiful.fg_normal + + cr:translate(-height/2, 0) + shape.powerline(cr, width, height) + cr:reset_clip() + + if self._item.border_width and self._item.border_color then + cr:set_line_width(self._item.border_width) + cr:set_source(color(self._item.border_color)) + cr:stroke_preserve() + end + + cr:set_source(color(col)) cr:fill() cr:restore() - if self._draw then - self._draw(self, context, cr, width, height) - end end local function prefix_fit(box,context,w,h) @@ -48,16 +48,10 @@ local function suffix_fit(box,context,w,h) return width + h/2 + h/6,height end -local function widget_draw(self, context, cr, width, height) - self:_drawprefix(context, cr, width, height) -end - local function draw(item,args) local args = args or {} if not item.widget._overlay_init then - item.widget._drawprefix = item.widget.draw - item.widget.draw = widget_draw item.widget._overlay_init = true end @@ -67,9 +61,8 @@ local function draw(item,args) -- Replace prefix function item._internal.align.first._item = item item._internal.align.first._fit = item._internal.align.first.fit - item._internal.align.first._draw = item._internal.align.first.draw item._internal.align.first.fit = prefix_fit - item._internal.align.first.draw = prefix_draw + item._internal.align.first.before_draw_children = before_draw_children -- Replace suffix function item._internal.align.third._item = item @@ -77,20 +70,7 @@ local function draw(item,args) item._internal.align.third.fit = suffix_fit end - local state = item.state or {} - local current_state = state._current_key or nil - local state_name = base.colors_by_id[current_state] - - if current_state == base.item_flags.SELECTED or (item._tmp_menu) then - item.widget:set_bg(args.color or item.bg_focus) - item.widget:set_fg(item["fg_focus"]) - elseif state_name then - item.widget:set_bg(args.color or item["bg_"..state_name]) - item.widget:set_fg( item["fg_"..state_name]) - else - item.widget:set_bg(args.color or nil) - item.widget:set_fg(item["fg"]) - end + theme.update_colors(item) end return setmetatable(module, { __call = function(_, ...) return draw(...) end }) diff --git a/item/style/arrow_single.lua b/item/style/arrow_single.lua index 615df1b..a301491 100644 --- a/item/style/arrow_single.lua +++ b/item/style/arrow_single.lua @@ -1,10 +1,7 @@ local setmetatable = setmetatable -local base = require( "radical.base" ) -local beautiful = require("beautiful" ) -local color = require("gears.color" ) -local cairo = require("lgi" ).cairo -local wibox = require("wibox" ) -local arrow_alt = require("radical.item.style.arrow_alt") +local wibox = require("wibox" ) +local theme = require( "radical.theme" ) +local shape = require( "gears.shape" ) local module = { margins = { @@ -15,45 +12,10 @@ local module = { } } - -local function suffix_draw(self, context, cr, width, height) - cr:save() - cr:move_to(height/2,0) - cr:line_to(width-height/2,0) - cr:line_to(width,height/2) - cr:line_to(width-height/2,height) - cr:line_to(height/2,height) - cr:line_to(0,height/2) - cr:line_to(height/2,0) - cr:close_path() - cr:clip() - - if wibox.widget.background.draw then - wibox.widget.background.draw(self, context, cr, width, height) - end - - cr:restore() -end - - -local function draw(item,args) - local args = args or {} - - item.widget.draw = suffix_draw - - local state = item.state or {} - local current_state = state._current_key or nil - local state_name = base.colors_by_id[current_state] - if current_state == base.item_flags.SELECTED or (item._tmp_menu) then - item.widget:set_bg(args.color or item.bg_focus) - item.widget:set_fg(item.fg_focus) - elseif state_name then - item.widget:set_bg(args.color or item["bg_"..state_name]) - item.widget:set_fg( item["fg_"..state_name]) - else - item.widget:set_bg(args.color or nil) - item.widget:set_fg(item["fg"]) - end +local function draw(item) + item.widget:set_shape(shape.hexagon) + item.widget:set_shape_border_width(item.border_width) + theme.update_colors(item) end return setmetatable(module, { __call = function(_, ...) return draw(...) end }) diff --git a/item/style/basic.lua b/item/style/basic.lua index 5a825e9..333dc2b 100644 --- a/item/style/basic.lua +++ b/item/style/basic.lua @@ -3,6 +3,7 @@ local print = print local pairs=pairs local base = require( "radical.base" ) local wibox = require("wibox" ) +local theme = require( "radical.theme" ) local module = { margins = { @@ -13,32 +14,5 @@ local module = { } } -local function widget_draw23(self, context, cr, width, height) - if wibox.widget.background.draw then - wibox.widget.background.draw(self, context, cr, width, height) - end -end - -local function draw(item,args) - local args = args or {} - - item.widget.draw = widget_draw23 - - local state = item.state or {} - local current_state = state._current_key or nil - local state_name = base.colors_by_id[current_state] - - if current_state == base.item_flags.SELECTED or (item._tmp_menu) then - item.widget:set_bg(item.bg_focus) - item.widget:set_fg(item.fg_focus) - elseif state_name then - item.widget:set_bg(args.color or item["bg_"..state_name]) - item.widget:set_fg( item["fg_"..state_name]) - else - item.widget:set_bg(args.color or nil) - item.widget:set_fg(item["fg"]) - end -end - -return setmetatable(module, { __call = function(_, ...) return draw(...) end }) +return setmetatable(module, { __call = function(_, ...) theme.update_colors(...) end }) -- kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/item/style/classic.lua b/item/style/classic.lua index 753d280..fb38db2 100644 --- a/item/style/classic.lua +++ b/item/style/classic.lua @@ -1,10 +1,7 @@ local setmetatable = setmetatable -local base = require( "radical.base" ) -local color = require( "gears.color" ) -local cairo = require( "lgi" ).cairo -local beautiful = require( "beautiful" ) -local wibox = require("wibox" ) -local print = print +local color = require( "gears.color" ) +local wibox = require( "wibox" ) +local theme = require( "radical.theme" ) local module = { margins = { @@ -15,61 +12,37 @@ local module = { } } -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) - local cr = cairo.Context(img) - cr:set_source( color(bg_color) ) - cr:paint() - cr:set_source( color(border_color) ) - cr:rectangle(0,item_height-1,800,1) - cr:fill() - return cairo.Pattern.create_for_surface(img) -end - -local function widget_draw(self, context, cr, width, height) - - if wibox.widget.background.draw then - wibox.widget.background.draw(self, context, cr, width, height) +local function horizontal(self, context, cr, width, height) + if self._item and self._shape_border_color then + cr:set_source(color(self._shape_border_color)) + cr:rectangle(0, height -1, width, 1) + cr:fill() end end -local function draw(item,args) - local args = args or {} - local col = args.color - - item.widget.draw = widget_draw - - local ih = item.height or 1 - if not focussed or not focussed[ih] then - if not focussed then - focussed,default,alt={},{},{} - end - local bc = item.item_border_color or item.border_color - focussed[ih] = gen(ih,item.bg_focus,bc) - default [ih] = gen(ih,item.bg,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 - - local state = item.state or {} - local current_state = state._current_key or nil - local state_name = current_state and base.colors_by_id[current_state] or "normal" - - if current_state == base.item_flags.SELECTED or (item._tmp_menu) then - item.widget:set_bg(focussed[ih]) - item.widget:set_fg(item["fg_focus"]) - elseif col then - item.widget:set_bg(alt[col][ih]) - item.widget:set_fg(item["fg_"..state_name]) - else - item.widget:set_bg(default[ih]) - item.widget:set_fg(item["fg"]) +local function vertical(self, context, cr, width, height) + if self._item and self._shape_border_color then + cr:set_source(color(self._shape_border_color)) + cr:rectangle(width-1, 0, 1, height) + cr:fill() end end -return setmetatable(module, { __call = function(_, ...) return draw(...) end }) + +local function draw(item, v) + item.widget.border_color = color(item.item_border_color or item.border_color) + item.widget.after_draw_children = v and vertical or horizontal + + theme.update_colors(item) +end + +module.vertical = setmetatable({margins={ + TOP = 2, + BOTTOM = 2, + RIGHT = 4, + LEFT = 4 + }},{ __call = function(_, item) draw(item,true) end } +) + +return setmetatable(module, { __call = function(_, item) draw(item) end }) -- kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/item/style/holo.lua b/item/style/holo.lua index cd854cd..80f5847 100644 --- a/item/style/holo.lua +++ b/item/style/holo.lua @@ -1,9 +1,6 @@ local setmetatable = setmetatable -local math = math -local base = require( "radical.base" ) -local color = require( "gears.color" ) -local cairo = require( "lgi" ).cairo -local print = print +local color = require( "gears.color" ) +local theme = require( "radical.theme" ) local module = { margins = { @@ -14,78 +11,39 @@ local module = { } } -local state_cache = {} - local default_height = 3 -local rect = { - bottom = function(x,y,width,height) return 0, height-default_height, width , default_height end, - top = function(x,y,width,height) return 0, 0, width , 3 end, -} - -local function gen(width,height,bg_color,border_color, pos) - local img = cairo.ImageSurface(cairo.Format.ARGB32, width,height) - local cr = cairo.Context(img) - cr:set_source(color(bg_color)) - cr:rectangle(rect[pos](0,0,width,height)) - cr:fill() - return cairo.Pattern.create_for_surface(img) +local function widget_draw(self, context, cr, width, height) + -- Nothing to do end -local function widget_draw(self, context, cr, width, height) +local function after_draw_children_top(self, context, cr, width, height) + cr:save() + cr:set_source(color(self.background)) + cr:rectangle(0, 0, width, default_height) + cr:fill() + cr:restore() +end - local state = self._item.state or {} - local current_state = state._current_key or "" - if not state_cache[current_state] then - state_cache[current_state] = {} - end - local cache = state_cache[current_state] - local hash = width+1234*height - - local cached = cache[hash] - - --Generate the pixmap - if not cached then - local state_name = current_state == "" and "bg" or "bg_"..(base.colors_by_id[current_state] or "") - cached = gen(width,height,self._item[state_name],bc,self.holo_pos) - cache[hash] = cached - end - - if current_state ~= self._last_state then - self:set_bg(cached) - self._last_state = current_state - end - - if self._drawrounded then - self:_drawrounded(context, cr, width, height) - end +local function after_draw_children_bottom(self, context, cr, width, height) + cr:save() + cr:set_source(color(self.background)) + cr:rectangle(0, height -default_height, width, default_height) + cr:fill() + cr:restore() end local function draw(item,args) local args = args or {} - if not item.widget._overlay_init then - item.widget._drawrounded = item.widget.draw - item.widget.draw = widget_draw - item.widget._overlay_init = true - item.widget._item = item - item.widget.holo_pos = args.pos or "bottom" - end + item.widget.draw = widget_draw + item.widget.before_draw_children = args.pos == "top" + and after_draw_children_top or after_draw_children_bottom - local state = item.state or {} - local current_state = state._current_key or nil - local state_name = base.colors_by_id[current_state] - - if current_state == base.item_flags.SELECTED or (item._tmp_menu) then - item.widget:set_fg(item["fg_focus"]) - elseif state_name then - item.widget:set_fg( item["fg_"..state_name]) - else - item.widget:set_fg(item["fg_normal"]) - end + theme.update_colors(item) end -local function draw_top(item,args) +local function draw_top(item) return draw(item,{pos="top"}) end diff --git a/item/style/line_3d.lua b/item/style/line_3d.lua index bc06e4a..f559d46 100644 --- a/item/style/line_3d.lua +++ b/item/style/line_3d.lua @@ -1,10 +1,8 @@ local setmetatable = setmetatable -local print = print -local pairs=pairs -local base = require( "radical.base" ) -local beautiful = require("beautiful" ) -local color = require("gears.color") -local cairo = require("lgi").cairo +local beautiful = require( "beautiful" ) +local color = require( "gears.color" ) +local cairo = require( "lgi" ).cairo +local theme = require( "radical.theme" ) local module = { margins = { @@ -15,8 +13,7 @@ local module = { } } -local function widget_draw(self, context, cr, width, height) - self.__drawbasic(self,context, cr, width, height) +local function after_draw_children(self, context, cr, width, height) cr:set_source(self.col1) cr:rectangle(0,3,1,height-6) cr:fill() @@ -29,10 +26,8 @@ local function draw(item,args) local args = args or {} if not item.widget._overlay_init then - item.widget.__drawbasic = item.widget.draw - item.widget.draw = widget_draw + item.widget.after_draw_children = after_draw_children item.widget._overlay_init = true - item.widget._item = item -- Build the 2 item border colors, this item_style doesn't support gradient -- or patterns @@ -42,20 +37,7 @@ local function draw(item,args) item.widget.col2 = cairo.Pattern.create_rgba(r,g,b,a) end - local state = item.state or {} - local current_state = state._current_key or nil - local state_name = base.colors_by_id[current_state] - - if current_state == base.item_flags.SELECTED or (item._tmp_menu) then - item.widget:set_bg(item.bg_focus) - item.widget:set_fg(item.fg_focus) - elseif state_name then - item.widget:set_bg(args.color or item["bg_"..state_name]) - item.widget:set_fg( item["fg_"..state_name]) - else - item.widget:set_bg(args.color or nil) - item.widget:set_fg(item["fg"]) - end + theme.update_colors(item) end return setmetatable(module, { __call = function(_, ...) return draw(...) end }) diff --git a/item/style/rounded.lua b/item/style/rounded.lua index 555bc0a..5ff3e21 100644 --- a/item/style/rounded.lua +++ b/item/style/rounded.lua @@ -1,10 +1,7 @@ local setmetatable = setmetatable -local math = math -local base = require( "radical.base" ) -local color = require( "gears.color" ) -local cairo = require( "lgi" ).cairo -local wibox = require("wibox" ) -local print = print +local theme = require( "radical.theme" ) +local shape = require( "gears.shape" ) +local color = require( "gears.color" ) local module = { margins = { @@ -15,67 +12,29 @@ local module = { } } -local state_cache = {} +local function widget_draw(self, context, cr, width, height) -local function rect(cr,width,height,x,y) - local radius = 3 - cr:move_to(0,radius) - cr:arc(radius,radius,radius,math.pi,3*(math.pi/2)) - cr:arc(width-radius,radius,radius,3*(math.pi/2),math.pi*2) - cr:arc(width-radius,height-radius,radius,math.pi*2,math.pi/2) - cr:arc(radius,height-radius,radius,math.pi/2,math.pi) - cr:close_path() -end + if not self.background then + cr:set_source_rgba(0,0,0,0) + else + cr:set_source(color(self.background)) + end -local function gen(width,height,bg_color,border_color,item,shadow) - local extra = shadow and 5 or 0 - local img = cairo.ImageSurface(cairo.Format.ARGB32, width+extra,height+extra) - local cr = cairo.Context(img) + shape.rounded_rect(cr ,width, height, 3) - rect(cr,width,height,0,0) - - cr:set_source(color(bg_color)) - if item.item_border_color then + if self._item.item_border_color then cr:fill_preserve() - cr:set_line_width(item.border_width or 1) - cr:set_source(color(item.item_border_color)) + cr:set_line_width(self._item.border_width or 1) + cr:set_source(color(self._item.item_border_color)) cr:stroke() else cr:fill() end - return cairo.Pattern.create_for_surface(img) -end -local function widget_draw(self, context, cr, width, height,shadow) - local item = self._item - local state = item.state or {} - local current_state = state._current_key or "" - if not state_cache[current_state] then - state_cache[current_state] = {} - end - local cache = state_cache[current_state] - local hash = width+1234*height - - local cached = cache[hash] - - --Generate the pixmap - if not cached then - local state_name = current_state == "" and "bg" or "bg_"..(base.colors_by_id[current_state] or "") - cached = gen(width,height,item[state_name],bc,item,shadow) - cache[hash] = cached - end - - if current_state ~= self._last_state then - self:set_bg(cached) - self._last_state = current_state - end - - if wibox.widget.background.draw then - wibox.widget.background.draw(self, context, cr, width, height) - end end local function draw_width_shadow(self, context, cr, width, height) + if not self.background then return end cr:save() cr:reset_clip() @@ -84,54 +43,25 @@ local function draw_width_shadow(self, context, cr, width, height) cr:translate(3,3) for i=1,3 do cr:translate(-1,-1) - rect(cr,width,height) + shape.rounded_rect(cr, width, height, 3) cr:fill() end cr:restore() - - widget_draw(self, context, cr, width, height,true) end -local function common(item,args) - local state = item.state or {} - local current_state = state._current_key or nil - local state_name = base.colors_by_id[current_state] - - if current_state == base.item_flags.SELECTED or (item._tmp_menu) then - item.widget:set_fg(item["fg_focus"]) - elseif state_name then - item.widget:set_fg( item["fg_"..state_name]) - else - item.widget:set_fg(item["fg_normal"]) - end -end - -local function draw(item,args) - local args = args or {} - +local function draw(item) + item.widget._item = item item.widget.draw = widget_draw - - if not item.widget._overlay_init then - item.widget._overlay_init = true - item.widget._item = item - end - - common(item,args) + theme.update_colors(item) end -- Same as the default, but also draw a shadow -local function shadow(item,args) - local args = args or {} - - item.widget.draw = draw_width_shadow - - if not item.widget._overlay_init then - item.widget._overlay_init = true - item.widget._item = item - end - - common(item,args) +local function shadow(item) + item.widget.draw = widget_draw + item.widget.before_draw_children = draw_width_shadow + theme.update_colors(item) end + module.shadow = {} setmetatable(module.shadow, { __call = function(_, ...) return shadow(...) end }) diff --git a/item/style/slice_prefix.lua b/item/style/slice_prefix.lua index c5856c9..92bde38 100644 --- a/item/style/slice_prefix.lua +++ b/item/style/slice_prefix.lua @@ -1,10 +1,7 @@ local setmetatable = setmetatable -local base = require( "radical.base" ) local beautiful = require("beautiful" ) local color = require("gears.color" ) -local cairo = require("lgi" ).cairo -local wibox = require("wibox" ) -local arrow_alt = require("radical.item.style.arrow_alt") +local theme = require( "radical.theme" ) local module = { margins = { @@ -16,7 +13,7 @@ local module = { need_full_repaint = true } -local function prefix_draw(self, context, cr, width, height) +local function prefix_before_draw_children(self, context, cr, width, height) cr:save() -- This item style require negative padding, this is a little dangerous to @@ -32,9 +29,6 @@ local function prefix_draw(self, context, cr, width, height) cr:fill() cr:restore() - if self._draw then - self._draw(self, context, cr, width, height) - end end local function prefix_fit(box,context,w,h) @@ -47,18 +41,11 @@ local function suffix_fit(box,context,w,h) return width + h/2 + h/6,height end -local function widget_draw(self, context, cr, width, height) - if self._drawprefix then - self:_drawprefix(context, cr, width, height) - end -end - local function draw(item,args) local args = args or {} if not item.widget._overlay_init then item.widget._drawprefix = item.widget.draw - item.widget.draw = widget_draw item.widget._overlay_init = true end @@ -68,9 +55,8 @@ local function draw(item,args) -- Replace prefix function item._internal.align.first._item = item item._internal.align.first._fit = item._internal.align.first.fit - item._internal.align.first._draw = item._internal.align.first.draw item._internal.align.first.fit = prefix_fit - item._internal.align.first.draw = prefix_draw + item._internal.align.first.before_draw_children = prefix_before_draw_children -- Replace suffix function item._internal.align.third._item = item @@ -78,20 +64,7 @@ local function draw(item,args) item._internal.align.third.fit = suffix_fit end - local state = item.state or {} - local current_state = state._current_key or nil - local state_name = base.colors_by_id[current_state] - - if current_state == base.item_flags.SELECTED or (item._tmp_menu) then - item.widget:set_bg(args.color or item.bg_focus) - item.widget:set_fg(item["fg_focus"]) - elseif state_name then - item.widget:set_bg(args.color or item["bg_"..state_name]) - item.widget:set_fg( item["fg_"..state_name]) - else - item.widget:set_bg(args.color or nil) - item.widget:set_fg(item["fg"]) - end + theme.update_colors(item) end return setmetatable(module, { __call = function(_, ...) return draw(...) end }) diff --git a/item/style/subtle.lua b/item/style/subtle.lua index 8600e6b..82cadc6 100644 --- a/item/style/subtle.lua +++ b/item/style/subtle.lua @@ -3,6 +3,7 @@ local math = math local base = require( "radical.base" ) local color = require( "gears.color" ) local cairo = require( "lgi" ).cairo +local theme = require( "radical.theme" ) local print = print local module = { @@ -39,7 +40,7 @@ local function gen(w,h,bg_color,border_color) return cairo.Pattern.create_for_surface(img) end -local function widget_draw(self, context, cr, width, height) +local function before_draw_children(self, context, cr, width, height) local state = self._item.state or {} local current_state = state._current_key or "" @@ -62,18 +63,13 @@ local function widget_draw(self, context, cr, width, height) self:set_bg(cached) self._last_state = current_state end - - if self._drawrounded then - self:_drawrounded(context, cr, width, height) - end end local function draw(item,args) local args = args or {} if not item.widget._overlay_init then - item.widget._drawrounded = item.widget.draw - item.widget.draw = widget_draw + item.widget.before_draw_children = before_draw_children item.widget._overlay_init = true item.widget._item = item end diff --git a/layout/horizontal.lua b/layout/horizontal.lua index 9a30938..93ff5bb 100644 --- a/layout/horizontal.lua +++ b/layout/horizontal.lua @@ -170,9 +170,9 @@ local function new(data) l.setup_key_hooks = module.setup_key_hooks l.setup_item = module.setup_item --- if data.spacing and l.set_spacing then --- l:set_spacing(data.spacing) --- end + if data.spacing and l.set_spacing then + l:set_spacing(data.spacing) + end data:connect_signal("widget::added",function(_,item,widget) wibox.layout.fixed.add(l,item.widget) diff --git a/style/arrow.lua b/style/arrow.lua index 4e9347e..497337f 100644 --- a/style/arrow.lua +++ b/style/arrow.lua @@ -1,10 +1,11 @@ local setmetatable = setmetatable local beautiful = require( "beautiful" ) local color = require( "gears.color" ) +local surface = require( "gears.surface" ) local cairo = require( "lgi" ).cairo local base = require( "radical.base" ) local glib = require("lgi").GLib -local margins = require("radical.margins") +local shape = require( "gears.shape" ) local module = { margins = { @@ -23,8 +24,8 @@ local arrow_height = 13 local angles = { top = 0 , -- 0 bottom = math.pi , -- 180 - right = 3*math.pi/2 , -- 270 - left = math.pi/2 , -- 90 + left = 3*math.pi/2 , -- 270 + right = math.pi/2 , -- 90 } -- If width and height need to be swapped @@ -35,73 +36,11 @@ local swaps = { left = true , } -local function rotate(img, geometry, angle,swap_size) - -- Swap height ans width - geometry = swap_size and {width = geometry.height, height=geometry.width} or geometry - - -- Create a rotation matrix - local matrix,pattern,img2 = cairo.Matrix(),cairo.Pattern.create_for_surface(img),cairo.ImageSurface(cairo.Format.ARGB32, geometry.width, geometry.height) - cairo.Matrix.init_rotate(matrix,angle) - - -- Apply necessary transformations - matrix:translate((angle == math.pi/2) and 0 or -geometry.width, (angle == 3*(math.pi/2)) and 0 or -geometry.height) - pattern:set_matrix(matrix) - - -- Paint the new image - local cr2 = cairo.Context(img2) - cr2:set_source(pattern) - cr2:paint() - return img2 -end - --- Generate a rounded cairo path with the arrow -local function draw_roundedrect_path(cr, data, width, height, radius,padding) - local no_arrow = data.arrow_type == base.arrow_type.NONE - local top_padding = (no_arrow) and 0 or arrow_height - local arrow_x = data._arrow_x or 20 - - --Begin the rounded rect - cr:move_to(padding,radius) - cr:arc(radius , radius+top_padding , (radius-padding) , math.pi , 3*(math.pi/2)) - - -- Draw the arrow - if not no_arrow then - cr:line_to(arrow_x , top_padding+padding) - cr:line_to(arrow_x+arrow_height , padding ) - cr:line_to(arrow_x+2*arrow_height , top_padding+padding) - end - - -- Complete the rounded rect - cr:arc(width-radius, radius+top_padding , (radius-padding) , 3*(math.pi/2) , math.pi*2 ) - cr:arc(width-radius, height-(radius-padding)-padding , (radius-padding) , math.pi*2 , math.pi/2 ) - cr:arc(radius , height-(radius-padding)-padding , (radius-padding) , math.pi/2 , math.pi ) - cr:close_path() -end - -local function do_gen_menu_top(data, width, height, radius,padding,args) - local img = cairo.ImageSurface(cairo.Format.ARGB32, width,height) - local cr = cairo.Context(img) - - -- Clear the surface - cr:set_operator(cairo.Operator.SOURCE) - cr:set_source( color(args.bg) ) - cr:paint() - cr:set_source( color(args.fg) ) - - -- Generate the path - draw_roundedrect_path(cr, data, width, height, beautiful.menu_corner_radius or radius,padding,args) - - -- Apply - cr:fill() - return img -end - +-- Generate the arrow position local function gen_arrow_x(data,direction) local at = data.arrow_type local par_center_x = data.parent_geometry and (data.parent_geometry.x + data.parent_geometry.width/2) or -1 - local par_center_y = data.parent_geometry and (data.parent_geometry.y + data.parent_geometry.height/2) or -1 local menu_beg_x = data.x - local menu_end_x = data.x + data.width if at == base.arrow_type.PRETTY or not at then if direction == "left" then @@ -125,9 +64,38 @@ local function gen_arrow_x(data,direction) end end +-- Generate a rounded cairo path with the arrow +local function draw_roundedrect_path(cr, width, height, radius, data, padding, angle, swap_size) + local no_arrow = data.arrow_type == base.arrow_type.NONE + local padding = padding or 0 + local arrow_offset = no_arrow and 0 or padding/2 + local width, height = width - 2*padding - (swap_size and arrow_offset or 0), height - 2*padding - (swap_size and 0 or arrow_offset) + + if swap_size then + width, height = height - arrow_offset, width + end + + -- Use rounded rext for sub-menu and + local s = shape.transform(no_arrow and shape.rounded_rect or shape.infobubble) + + -- Apply transformations + s = s : rotate_at(width / 2, height / 2, angle) + if padding > 0 then + s = s : translate(padding + (swap_size and arrow_offset or 0), padding + (angle == 0 and arrow_offset or 0)) + end + + -- Avoid a race condition + if (not data._arrow_x) and (not no_arrow) then + gen_arrow_x(data, data.direction) + end + + -- the (swap_size and 2 or 1) indicate a bug elsewhere + s(cr, width, height, radius, arrow_height - arrow_offset, (data._arrow_x or 20) - arrow_offset*(swap_size and 2 or 1)) + +end + local function _set_direction(data,direction) - local height,width = data.height,data.width - local hash = height*1000+width + local hash = data.height*1000 + data.width -- Try not to waste time for nothing if data._internal._last_direction == direction..(hash) then return end @@ -138,27 +106,13 @@ local function _set_direction(data,direction) data._internal.last_size = hash end - local border_color = color(beautiful.menu_outline_color or beautiful.menu_border_color or beautiful.fg_normal) - local geometry = (direction == "left" or direction == "right") and {width = height, height = width} or {height = height, width = width} - local top_clip_surface = do_gen_menu_top(data,geometry.width,geometry.height,radius,data.border_width,{bg=border_color or "#0000ff",fg=data.bg or "#00ffff"}) - local top_bounding_surface = do_gen_menu_top(data,geometry.width,geometry.height,radius,0,{bg="#00000000",fg="#ffffffff"}) - - local arr_margin = (data.arrow_type == base.arrow_type.NONE) and 0 or arrow_height local angle, swap = angles[direction],swaps[direction] - --TODO this could be simplified by appling the transform before drawing the bounding mask - if angle ~= 0 then - top_bounding_surface = rotate(top_bounding_surface,geometry,angle,swap) - top_clip_surface = rotate(top_clip_surface,geometry,angle,swap) - end - - -- Set the bounding mask - data.wibox.shape_bounding = top_bounding_surface._native - data.wibox:set_bg(cairo.Pattern.create_for_surface(top_clip_surface)) data._internal._need_direction_reload = false data._internal._last_direction = direction..(hash) - + surface.apply_shape_bounding(data.wibox, draw_roundedrect_path, radius, data, 0, angle, swap) +-- surface.apply_shape_clip (data.wibox, draw_roundedrect_path, radius, data, data.border_width, angle, swap) end -- Try to avoid useless repaint, this function is heavy @@ -184,7 +138,7 @@ local function get_arrow_x(data) local hash = height*1000+width if not data._arrow_x or data._internal.last_size ~= hash then gen_arrow_x(data,direction) --- data._internal.last_size = hash + data._internal.last_size = hash end return data._arrow_x end @@ -195,18 +149,19 @@ end local function after_draw_children(self, context, cr, width, height) local data = self._data - -- Create a matrix to rotate the border - local matrix = cairo.Matrix() - cairo.Matrix.init_rotate(matrix,angles[data.direction]) - cr:set_matrix(matrix) + local dir = data.direction + local angle, swap = angles[dir], swaps[dir] + + cr:translate(data.border_width/2,data.border_width/2) -- Generate the path - draw_roundedrect_path(cr, data, width, height, beautiful.menu_corner_radius or radius,data.border_width/2) + draw_roundedrect_path(cr, width, height, beautiful.menu_corner_radius or radius, data, data.border_width/2, angle, swap) cr:set_source(color(beautiful.menu_outline_color or beautiful.menu_border_color or beautiful.fg_normal)) cr:set_line_width(data.border_width) cr:stroke() end + local function draw(data,args) local args = args or {} local direction = data.direction or "top" @@ -217,7 +172,12 @@ local function draw(data,args) -- Prevent sharp corners from being over the border if data._internal.margin then data._internal.margin.__draw = data._internal.margin.draw + + --TODO eventually restart work on upstreaming this, for now it pull too + -- much trouble along with it + data._internal.margin._data = data data._internal.margin.after_draw_children = after_draw_children + if not data._internal.margin._data then data._internal.margin._data = data end diff --git a/theme/init.lua b/theme/init.lua index dd24a50..99e3229 100644 --- a/theme/init.lua +++ b/theme/init.lua @@ -1,6 +1,7 @@ local math = math local rawget,rawset=rawget,rawset local beautiful = require( "beautiful" ) +local base = nil local module = { colors_by_id = {} @@ -11,6 +12,34 @@ local function return_data(tab, key) return tab._real_table[key] end +-- Common method to set foreground and background color dependeing on state +function module.update_colors(item) + local state = item.state or {} + local current_state = state._current_key or nil + + local state_name = base.colors_by_id[current_state] + + -- Awesome use "focus" and radical "selected", convert the name + if current_state == base.item_flags.SELECTED or (item._tmp_menu) then + item.widget:set_bg ( item.bg_focus ) + item.widget:set_bgimage( item.bgimage_focus ) + item.widget:set_fg ( item.fg_focus ) + item.widget:set_shape_border_color(item.border_color_focus + or item["border_color"]) + elseif state_name then + item.widget:set_bg (item["bg_"..state_name] ) + item.widget:set_bgimage(item["bgimage_"..state_name] ) + item.widget:set_fg (item["fg_"..state_name] ) + item.widget:set_shape_border_color(item["border_color_"..state_name] + or item["border_color"]) + else + item.widget:set_bg ( nil ) + item.widget:set_bgimage( nil ) + item.widget:set_fg ( item["fg"] ) + item.widget:set_shape_border_color(item["border_color"]) + end +end + local function change_data(tab, key,value) if not value and key == rawget(tab,"_current_key") then -- Loop the array to find a new current_key @@ -36,6 +65,7 @@ local function change_data(tab, key,value) end function module.init_state(item) + base = base or require("radical.base") local mt = {__newindex = change_data,__index=return_data} return setmetatable({_real_table={},_item=item},mt) end @@ -55,11 +85,17 @@ function module.register_color(state_id,name,beautiful_name,allow_fallback) theme_colors[name] = {id=state_id,beautiful_name=beautiful_name,fallback=allow_fallback} module.colors_by_id[state_id] = name end + function module.setup_colors(data,args) local priv = data._internal.private_data for k,v in pairs(theme_colors) do priv["fg_"..k] = args["fg_"..k] or beautiful["menu_fg_"..v.beautiful_name] or beautiful["fg_"..v.beautiful_name] or (v.fallback and beautiful.fg_normal) priv["bg_"..k] = args["bg_"..k] or beautiful["menu_bg_"..v.beautiful_name] or beautiful["bg_"..v.beautiful_name] or (v.fallback and beautiful.bg_normal) + priv["bgimage_"..k] = args["bgimage_"..k] or beautiful["menu_bgimage_"..v.beautiful_name] or beautiful["bgimage_"..v.beautiful_name] + priv["border_color_"..k] = args["border_color_"..k] + or beautiful["menu_border_color_"..v.beautiful_name] + or beautiful["border_color_"..v.beautiful_name] + or (v.fallback and beautiful.border_color) --priv["underlay_bg_"..k] = args["underlay_bg_"..k] or beautiful["menu_underlay_bg_"..v.beautiful_name] or beautiful["underlay_bg_"..v.beautiful_name] end @@ -69,9 +105,12 @@ function module.setup_colors(data,args) end end +--TODO URGENT use metatable for this, it is damn slow function module.setup_item_colors(data,item,args) local priv = item._private_data for k,v in pairs(theme_colors) do + + -- Foreground if args["fg_"..k] then priv["fg_"..k] = args["fg_"..k] else @@ -79,6 +118,8 @@ function module.setup_item_colors(data,item,args) return priv["fg_"..k] or data["fg_"..k] end) end + + -- Background if args["bg_"..k] then priv["bg_"..k] = args["bg_"..k] else @@ -86,6 +127,24 @@ function module.setup_item_colors(data,item,args) return priv["bg_"..k] or data["bg_"..k] end) end + + -- Background image + if args["bgimage_"..k] then + priv["bgimage_"..k] = args["bgimage_"..k] + else + rawset(item,"get_bgimage_"..k, function() + return priv["bgimage_"..k] or data["bgimage_"..k] + end) + end + + -- Border color + if args["border_color_"..k] then + priv["border_color_"..k] = args["border_color_"..k] + else + rawset(item,"get_border_color_"..k, function() + return priv["border_color_"..k] or data["border_color_"..k] + end) + end end end @@ -97,9 +156,12 @@ function module.add_colors_from_namespace(data,namespace) for k,v in pairs(theme_colors) do priv["fg_"..k] = beautiful[namespace.."_fg_"..v.beautiful_name] or priv["fg_"..k] priv["bg_"..k] = beautiful[namespace.."_bg_"..v.beautiful_name] or priv["bg_"..k] + priv["bgimage_"..k] = beautiful[namespace.."_bgimage_"..v.beautiful_name] or priv["bgimage_"..k] + priv["border_color_"..k] = beautiful[namespace.."_border_color_"..v.beautiful_name] or priv["border_color_"..k] end priv["fg"] = beautiful[namespace.."_fg"] or priv["fg"] priv["bg"] = beautiful[namespace.."_bg"] or priv["bg"] + priv["bgimage"] = beautiful[namespace.."_bgimage"] or priv["bgimage"] priv["border_color"] = beautiful[namespace.."_border_color"] or priv["border_color"] priv["item_border_color"] = beautiful[namespace.."_item_border_color"] or priv["item_border_color"] priv.namespace = priv.namespace or {} @@ -114,10 +176,10 @@ function module.add_section(data,section,args) local priv = data._internal.private_data load_section(data,priv,section,args) - + priv.section = priv.section or {} priv.section[#priv.section+1] = section end -return setmetatable(module, { __call = function(_, ...) return new(...) end }) +return module -- kate: space-indent on; indent-width 2; replace-tabs on; \ No newline at end of file diff --git a/tooltip.lua b/tooltip.lua index e6676c9..c7e0ceb 100644 --- a/tooltip.lua +++ b/tooltip.lua @@ -1,8 +1,10 @@ local setmetatable,math = setmetatable,math -local beautiful = require( "beautiful" ) -local wibox = require( "wibox" ) -local cairo = require( "lgi" ).cairo +local beautiful = require( "beautiful" ) +local surface = require( "gears.surface" ) +local wibox = require( "wibox" ) +local cairo = require( "lgi" ).cairo local object = require( "radical.object" ) +local shape = require( "gears.shape" ) local capi = { screen = screen , mouse = mouse } local module={} @@ -41,8 +43,9 @@ local function init(data,widget,args) if widget and not data.init then data.init = true + -- Setup the wibox local vertical = (args.direction == "left") or (args.direction == "right") - local w,extents = data.wibox or wibox({position="free"}),widget._layout:get_pixel_extents() + local w,extents = data.wibox or wibox{},widget._layout:get_pixel_extents() extents.width = extents.width + 60 w.visible = false w.width = extents.width @@ -50,48 +53,19 @@ local function init(data,widget,args) w.ontop = true w:set_bg(beautiful.tooltip_bg or beautiful.bg_normal or "") - local img = cairo.ImageSurface(cairo.Format.A1, extents.width, vertical and 20 or 25) - local cr = cairo.Context(img) - --Clear the surface - cr:set_source_rgba( 0, 0, 0, 0 ) - cr:paint() - - --Draw the corner - cr:set_source_rgba( 1, 1, 1, 1 ) - if not (vertical) then - cr:arc(20-(vertical and 5 or 0), 20/2 + (5), 20/2 - 1,0,2*math.pi) - end - cr:arc(extents.width-20+(2*(vertical and 5 or 0)), 20/2 + (vertical and 0 or 5), 20/2 - 1,0,2*math.pi) - - --Draw arrow - if not (vertical) then - for i=0,(5) do - cr:rectangle(extents.width/2 - 5 + i ,5-i, 1, i) - cr:rectangle(extents.width/2 + 5 - i ,5-i, 1, i) - end + -- Pick the right shape + local s = nil + if args.direction == "bottom" then + s = shape.infobubble + elseif args.direction == "top" then + s = shape.transform(shape.infobubble) : rotate_at(w.width/2, w.height/2, math.pi) + elseif args.direction == "left" then + s = shape.transform(shape.rectangular_tag) : rotate_at(w.width/2, w.height/2, math.pi) else - for i=0,(12) do - cr:rectangle(i, (20/2) - i, i, i*2) - end + s = shape.rectangular_tag end - cr:rectangle(20-((vertical) and 5 or 0),vertical and 0 or 5, extents.width-40+((vertical) and 14 or 0 ), 20) - cr:fill() - - w:set_fg(beautiful.fg_normal) - - if args.direction == "left" or args.direction == "top" then --Mirror - local matrix,pattern = cairo.Matrix(),cairo.Pattern.create_for_surface(img) - cairo.Matrix.init_rotate(matrix,math.pi) - matrix:translate(-extents.width,-((vertical) and 20 or 25)) - pattern:set_matrix(matrix) - local img2 = cairo.ImageSurface(cairo.Format.A1, extents.width, vertical and 20 or 25) - local cr2 = cairo.Context(img2) - cr2:set_source(pattern) - cr2:paint() - img = img2 - end - w.shape_bounding = img._native + surface.apply_shape_bounding(w, s, w.height/2 - 2.5, 5) data.wibox = w end @@ -106,6 +80,16 @@ local function set_text(self,text) init(self,self._w,self._args) end +local function set_markup(self,text) + self.init = nil + self._text = text + if self._w then + self._w:set_markup(self._text) + end + init(self,self._w,self._args) +end + + local function new(widget,text, args) local args,data = args or {},object({ private_data = { @@ -135,7 +119,13 @@ local function new(widget,text, args) local vertical,textw = (args.direction == "left") or (args.direction == "right"),wibox.widget.textbox() textw.align = "center" - textw:set_markup("".. data._text .."") + + if not args.is_markup then + textw:set_markup("".. data._text .."") + else + textw:set_markup(data._text) + end + data._w = textw init(data,textw,args) diff --git a/widgets/scroll.lua b/widgets/scroll.lua index be38c9f..eeccce5 100644 --- a/widgets/scroll.lua +++ b/widgets/scroll.lua @@ -1,11 +1,13 @@ local setmetatable = setmetatable local print = print -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 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 shape = require( "gears.shape" ) +local surface = require( "gears.surface" ) local module = {} @@ -13,19 +15,16 @@ local arr_up,arr_down local isinit = false local function init() - local size = beautiful.menu_height or 16 - arr_down = cairo.ImageSurface(cairo.Format.ARGB32, 10,size) - arr_up = cairo.ImageSurface(cairo.Format.ARGB32, 10,size) - local cr2 = cairo.Context(arr_down) - local cr = cairo.Context(arr_up) - cr:set_source(color(beautiful.fg_normal)) - cr2:set_source(color(beautiful.fg_normal)) - 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() + if isinit then return end + + arr_down = surface.load_from_shape(10, 10, + shape.transform(shape.isosceles_triangle) : scale(1, 0.5) : rotate_at(5,5, math.pi) : translate(0,5), + beautiful.fg_normal + ) + arr_up = surface.load_from_shape(10, 10, + shape.transform(shape.isosceles_triangle) : scale(1, 0.5) : translate(0,5), + beautiful.fg_normal + ) isinit = true end diff --git a/widgets/underlay.lua b/widgets/underlay.lua index 2827351..b5b6e71 100644 --- a/widgets/underlay.lua +++ b/widgets/underlay.lua @@ -6,21 +6,26 @@ local cairo = require("lgi").cairo local pango = require("lgi").Pango local pangocairo = require("lgi").PangoCairo local beautiful = require("beautiful") +local shape = require("gears.shape") local module = {} local pango_l,pango_crx = {},{} +--TODO using the current cairo path extents, it would be possible to merge the 2 function +-- and have an abstract underlay that work with most shapes + local function draw_item(cr,x,y,width,height,padding,args) cr:save() cr:rectangle(x,y,width+padding,height+padding) cr:clip() + + local s = shape.transform(shape.rounded_bar) : translate(x + padding, y + padding/4) + s(cr, width - 2*padding, height - padding/2) + cr:set_source(color(args.bg or beautiful.bg_underlay or beautiful.bg_alternate)) - cr:arc(x + (height-padding)/2 + 2, y + (height-padding)/2 + padding/4 + (args.margins or 0), (height-padding)/2+(args.padding or 0)/2,0,2*math.pi) - cr:fill() - cr:arc(x + width - (height-padding)/2 - 2, y + (height-padding)/2 + padding/4 + (args.margins or 0), (height-padding)/2+(args.padding or 0)/2,0,2*math.pi) - cr:rectangle(x + (height-padding)/2+2, y + padding/4 + (args.margins or 0)-(args.padding or 0)/2,width - (height),(height-padding)+(args.padding or 0)) cr:fill() + cr:set_source(color(args.fg or beautiful.bg_normal)) cr:set_operator(cairo.Operator.CLEAR) cr:move_to(x+height/2 + 2,y+padding/4 + (args.margins or 0)-(args.padding or 0)/2) @@ -34,14 +39,10 @@ function module.draw_arrow(cr,x,y,width,height,padding,args) cr:clip() padding=padding/2 local mid = (height-2*padding)/2 - cr:move_to(x+mid ,padding) - cr:line_to(x+width-mid,padding) - cr:line_to(x+width ,mid+padding) - cr:line_to(x+width-mid,height-padding) - cr:line_to(x+mid ,height-padding) - cr:line_to(x+0 ,mid+padding) - cr:line_to(x+mid ,padding) - cr:close_path() + + local s = shape.transform(shape.hexagon) : translate(x, padding) + s(cr, width, height - 2*padding) + cr:set_source(color(args.bg or beautiful.bg_underlay or beautiful.bg_alternate)) cr:fill() cr:set_source(color(args.fg or beautiful.bg_normal))