Begin the big changes for 3.6

Lots of things will break, hopefully for the better (eventually)

This commit use new upstream APIs:

 * Many cairo paths have been replaced with gears.shape and gears.matrix

This commit add some features:

 * Improved border_color support, now available per state
 * bg_image support, now available per state
 * Mutualize the state setting, remove duplicated code

Regressions:

 * The arrow menu background border is off by a pixel
 * The layout position problem reported by @mindeunix is now worst.

The positioning algo is full of race conditions and cannot be fixed
without a full rewrite. This commit break more things than it solve
and the code is in the middle of a transition. This will be solved
by future commits addressing the code quality (after the refactoring).
This commit is contained in:
Emmanuel Lepage Vallee 2016-02-11 01:36:50 -05:00
parent 7f6bd3c673
commit 5271ffd35c
26 changed files with 411 additions and 613 deletions

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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 = "<b>"..c.name.."</b>",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 = "<b>"..c.name:gsub('&','&amp;').."</b>"
end

View File

@ -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 " <b>#")..(index)..(menu.index_suffix or "</b>: "))
tw:set_markup((menu.index_prefix or " <b>2#")..(index)..(menu.index_suffix or "</b>: "))
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

View File

@ -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)

View File

@ -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 ,

View File

@ -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

View File

@ -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 })

View File

@ -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 = {

View File

@ -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 })

View File

@ -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 })

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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 })

View File

@ -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 })

View File

@ -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 })

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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("<b>".. data._text .."</b>")
if not args.is_markup then
textw:set_markup("<b>".. data._text .."</b>")
else
textw:set_markup(data._text)
end
data._w = textw
init(data,textw,args)

View File

@ -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

View File

@ -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))