Add better tooling to track menu dimensions

This commit is contained in:
Emmanuel Lepage Vallee 2014-10-05 18:01:54 -04:00
parent f215d24f35
commit 46481f0a8a
5 changed files with 84 additions and 66 deletions

View File

@ -2,6 +2,7 @@ local base = require( "radical.base" )
local print = print
local unpack = unpack
local debug = debug
local rawset = rawset
local type = type
local setmetatable = setmetatable
local color = require( "gears.color" )
@ -15,6 +16,7 @@ local checkbox = require( "radical.widgets.checkbox" )
local arrow_style = require( "radical.style.arrow" )
local item_mod = require("radical.item")
local glib = require("lgi").GLib
local margins2 = require("radical.margins")
local capi,module = { mouse = mouse , screen = screen, keygrabber = keygrabber },{}
@ -72,7 +74,8 @@ local function set_position(self)
if parent.direction == "right" then
ret={x=parent.x-self.width,y=parent.y+(self.parent_item.y)}
else
ret={x=parent.x+parent.width,y=parent.y+(self.parent_item.y)-self.style.margins.TOP}
local margins = self.margins
ret={x=parent.x+parent.width,y=parent.y+(self.parent_item.y)-(margins and self.margins.top or self.style.margins.TOP)}
--Handle when the menu doesn't fit in the srceen horizontally
if ret.x+self.width > src_geo.x + src_geo.width then
@ -81,13 +84,13 @@ local function set_position(self)
-- Handle when the menu doesn't fit on the screen vertically
if ret.y+self.height > src_geo.y + src_geo.height then
ret.y = ret.y - self.height + self.item_height + 2*self.style.margins.TOP
ret.y = ret.y - self.height + self.item_height + 2*(margins and self.margins.top or self.style.margins.TOP)
end
end
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}
end
@ -99,7 +102,7 @@ local function set_position(self)
if prefy then
ret.y = prefy
end
elseif not parent then --Use mouse position to set position --TODO it is called too often
else --Use mouse position to set position --TODO it is called too often
ret = capi.mouse.coords()
local draw = awful.mouse.wibox_under_pointer and awful.mouse.wibox_under_pointer() or awful.mouse.drawin_under_pointer and awful.mouse.drawin_under_pointer()
if draw then
@ -152,11 +155,22 @@ local function setup_drawable(data)
data.get_visible = function() return private_data.visible end
data.get_direction = function() return private_data.direction end
data.get_margins = function()
local ret = {left=data.border_width,right=data.border_width,top=data.style.margins.TOP,bottom=data.style.margins.BOTTOM}
if data.arrow_type ~= base.arrow_type.NONE then
ret[data.direction] = ret[data.direction]+13
if not internal._margins then
local ret = {
left = data.border_width+data.style.margins.LEFT ,
right = data.border_width+data.style.margins.RIGHT ,
top = data.border_width+data.style.margins.TOP ,
bottom = data.border_width+data.style.margins.BOTTOM ,
}
m = margins2(internal.margin,ret)
rawset(m,"_reset",m.reset)
m.reset = function(margins)
m.defaults = ret
m:_reset()
end
internal._margins = m
end
return ret
return internal._margins
end
--Setters

View File

@ -14,25 +14,48 @@ local module = {
}
}
local focussed,default = nil, nil
local state_cache = {}
local function gen(item_height,bg_color,border_color)
local img = cairo.ImageSurface(cairo.Format.ARGB32, item_height,item_height)
local function gen(width,height,bg_color,border_color)
local img = cairo.ImageSurface(cairo.Format.ARGB32, width,height)
local cr = cairo.Context(img)
local rad = corner_radius or 3
cr:set_source(color(bg_color))
cr:arc(rad,rad,rad,0,2*math.pi)
cr:arc(item_height-rad,rad,rad,0,2*math.pi)
cr:arc(rad,item_height-rad,rad,0,2*math.pi)
cr:arc(item_height-rad,item_height-rad,rad,0,2*math.pi)
cr:arc(width-rad,rad,rad,0,2*math.pi)
cr:arc(rad,height-rad,rad,0,2*math.pi)
cr:arc(width-rad,height-rad,rad,0,2*math.pi)
cr:fill()
cr:rectangle(0,rad, item_height, item_height-2*rad)
cr:rectangle(rad,0, item_height-2*rad, item_height)
cr:rectangle(0,rad, width, height-2*rad)
cr:rectangle(rad,0, width-2*rad, height)
cr:fill()
return cairo.Pattern.create_for_surface(img)
end
local function widget_draw(self, w, cr, width, height)
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)
cache[hash] = cached
end
if current_state ~= self._last_state then
self:set_bg(cached)
self._last_state = current_state
end
self:_drawrounded(w, cr, width, height)
local overlay = self._item and self._item.overlay
if overlay then
@ -47,21 +70,7 @@ local function draw(item,args)
item.widget._drawrounded = item.widget.draw
item.widget.draw = widget_draw
item.widget._overlay_init = true
end
local ih = item.height
local iw = item.width
if iw and iw > ih then
ih = iw
end
if not focussed or not focussed[ih] then
if not focussed then
focussed,default={},{}
end
local bc = item.border_color
focussed[ih] = gen(ih,item.bg_focus,bc)
default [ih] = gen(ih,item.bg,bc)
item.widget._item = item
end
local state = item.state or {}
@ -69,13 +78,10 @@ local function draw(item,args)
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(focussed[ih])
item.widget:set_fg(item["fg_focus"])
elseif state_name then --TODO incomplete
item.widget:set_bg(args.color or item["bg_"..state_name])
elseif state_name then
item.widget:set_fg( item["fg_"..state_name])
else
item.widget:set_bg(default[ih])
item.widget:set_fg(item["fg_normal"])
end
end

View File

@ -144,9 +144,8 @@ local function new(data)
base = require( "radical.base" )
end
local l = wibox.layout.fixed.horizontal()
l.fit = function(a1,a2,a3)
local result,r2 = wibox.layout.fixed.fit(a1,99999,99999)
-- return data.rowcount*(data.item_width or data.default_width),data.item_height
l.fit = function(a1,a2,a3,force_values)
local result,r2 = wibox.layout.fixed.fit(a1,force_values and a2 or 99999,force_values and a3 or 99999)
local w,h
if data.auto_resize and data._internal.largest_item_h then
w,h = data.rowcount*(data.item_width or data.default_width),data._internal.largest_item_h_v > data.item_height and data._internal.largest_item_h_v or data.item_height

View File

@ -194,33 +194,21 @@ function module:setup_item(data,item,args)
item.widget:emit_signal("widget::updated")
end
local function compute_geo(data)
local function compute_geo(data,width,height,force_values)
local w = data.default_width
if data.auto_resize and data._internal.largest_item_w then
w = data._internal.largest_item_w_v > data.default_width and data._internal.largest_item_w_v or data.default_width
end
local visblerow = data.filter_string == "" and data.rowcount or data._internal.visible_item_count
if data.max_items and data.max_items < data.rowcount then
visblerow = data.max_items
if data.filter_string ~= "" then
local cur,vis = (data._start_at or 1),0
while (data._internal.items[cur] and data._internal.items[cur]) and cur < data.max_items + (data._start_at or 1) do
vis = vis + (data._internal.items[cur]._filter_out and 0 or 1)
cur = cur +1
end
visblerow = vis
end
end
local visblerow = data.visible_row_count
local sw,sh = data._internal.suf_l:fit(9999,9999)
local pw,ph = data._internal.pref_l:fit(9999,9999)
if not data._internal.has_widget then
return w,(total and total > 0 and total or visblerow*data.item_height) + ph + sh
else
local h = (visblerow-#data._internal.widgets)*data.item_height
for k,v in ipairs(data._internal.widgets) do
local fw,fh = v.widget:fit(9999,9999)
h = h + fh
end
local sumh = data.widget_fit_height_sum
local h = (visblerow-#data._internal.widgets)*data.item_height + sumh
return w,h
end
end
@ -251,10 +239,9 @@ local function new(data)
suf_l:add(data._internal.scroll_w["down"])
end
end
real_l.fit = function(a1,a2,a3)
real_l.fit = function(a1,a2,a3,force_values)
if not data.visible then return 1,1 end
local result,r2 = wibox.layout.fixed.fit(a1,99999,99999)
local w,h = compute_geo(data)
local w,h = compute_geo(data,a2,a3,force_values)
data:emit_signal("layout_size",w,h)
return w,h
end

View File

@ -4,6 +4,7 @@ local color = require( "gears.color" )
local cairo = require( "lgi" ).cairo
local base = require( "radical.base" )
local glib = require("lgi").GLib
local margins = require("radical.margins")
local module = {
margins = {
@ -75,14 +76,17 @@ local function gen_arrow_x(data,direction)
--TODO
end
elseif at == base.arrow_type.CENTERED then
data._arrow_x = data.width/2 - 13
if direction == "left" or direction == "right" then
data._arrow_x = data.height/2 - 13
else
data._arrow_x = data.width/2 - 13
end
end
end
local function _set_direction(data,direction)
local height,width = data.height,data.width
local hash = height*1000+width
print("DIR",direction,hash,data._arrow_x,data._internal.last_size)
-- Try not to waste time for nothing
if data._internal._last_direction == direction..(hash) then return end
@ -110,9 +114,12 @@ local function _set_direction(data,direction)
top_clip_surface = rotate(top_clip_surface,geometry,angle,swap)
end
data.wibox.shape_bounding = top_bounding_surface._native
-- data.wibox.shape_clip = top_clip_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)
end
-- Try to avoid useless repaint, this function is heavy
@ -122,6 +129,15 @@ local function set_direction(data,direction)
glib.idle_add(glib.PRIORITY_HIGH_IDLE, function() _set_direction(data,data._internal._need_direction) end)
data._internal._need_direction_reload = true
end
-- Margins need to set manually, a reset will override user changes
if data.arrow_type ~= base.arrow_type.NONE and (not (data.parent_geometry and data.parent_geometry.is_menu)) and data._internal.former_direction ~= direction then
if data._internal.former_direction then
data.margins[data._internal.former_direction] = data.border_width + module.margins[data._internal.former_direction:upper()]
end
data.margins[direction] = 13 + 2*data.border_width
end
data._internal.former_direction = direction
end
local function get_arrow_x(data)
@ -146,11 +162,7 @@ local function draw(data,args)
set_direction(data,direction)
-- data._internal.set_position(data) --TODO DEAD CODE?
local margins = data.margins
local margin = data._internal.margin
for k,v in pairs(margins) do
margin["set_"..k](margin,v)
end
--TODO call this less often
return w,w2
end