tests: "Complete" the screen template.

This isn't very nice code, far from it. But it renders fine. So,
as mentionned like what, 1.5 years ago, the original code dump was
half of the scope. This is the second half. It it has various sizes
for various core objects. All of them are hardcoded and some off by
a few pixels, but overall it works.
This commit is contained in:
Emmanuel Lepage Vallee 2020-08-09 23:33:29 -07:00
parent d9514820ef
commit 1cbd839084
1 changed files with 468 additions and 67 deletions

View File

@ -76,12 +76,13 @@ local function stripe_pat(col, angle, line_width, spacing)
end
local colors = {
geometry = "#000000",
workarea = "#0000ff",
tiling_area = "#ff0000",
padding_area= "#ff0000",
wibar = "#000000",
geometry = "#000000",
workarea = "#0000ff",
tiling_area = "#ff0000",
padding_area = "#ff0000",
wibar = "#000000",
tiling_client = "#ff0000",
gaps = "#9900ff",
}
local function draw_area(_, rect, name, offset, highlight)
@ -142,6 +143,7 @@ local function write_on_area_middle(rect, text, offset)
cr:show_layout(playout)
end
-- For clients/wibars with struts only.
local function draw_struct(_, struct, name, offset, label)
draw_solid_area(_, struct, name, offset)
if type(label) == 'string' then
@ -149,6 +151,15 @@ local function draw_struct(_, struct, name, offset, label)
end
end
-- For floating or tiled clients.
local function draw_client(_, c, name, offset, label, alpha)
draw_solid_area(_, c, name, offset, alpha)
if type(label) == 'string' then
write_on_area_middle(c, label, offset)
end
end
local function compute_ruler(_, rect, name)
table.insert(hrulers, {
label = name, x = rect.x, width = rect.width
@ -176,7 +187,37 @@ end
local dx = 5
local function show_ruler_label(offset, padding, ruler, playout)
local playout, playout_height = nil, nil
local function get_playout()
if playout then return playout end
local pctx = PangoCairo.font_map_get_default():create_context()
playout = Pango.Layout.new(pctx)
local pdesc = Pango.FontDescription()
pdesc:set_absolute_size(11 * Pango.SCALE)
playout:set_font_description(pdesc)
return playout
end
local function get_text_height()
if playout_height then return playout_height end
local l = get_playout()
local attr, parsed = Pango.parse_markup("<b>GeometryWorkareaPaddingMargins</b>", -1, 0)
l.attributes, l.text = attr, parsed
local _, logical = playout:get_pixel_extents()
playout_height = logical.height
return playout_height
end
local function show_ruler_label(offset, padding, ruler, playout2)
if not ruler.label then return end
local lbl
if ruler.x then
@ -187,13 +228,85 @@ local function show_ruler_label(offset, padding, ruler, playout)
ruler.y.." height = "..ruler.height.."</i>"
end
local attr, parsed = Pango.parse_markup(lbl, -1, 0)
playout2.attributes, playout2.text = attr, parsed
local _, logical = playout2:get_pixel_extents()
cr:move_to((offset.x - logical.width) /2, offset.y+padding)
cr:show_layout(playout2)
end
local function show_aligned_label(dx2, offset, padding, ruler)
local lbl
if ruler.x then
lbl = ruler.width
else
lbl = ruler.height
end
local attr, parsed = Pango.parse_markup(lbl, -1, 0)
playout.attributes, playout.text = attr, parsed
local _, logical = playout:get_pixel_extents()
cr:move_to((offset.x - logical.width) /2, offset.y+padding)
if ruler.x then
local off = (ruler.width*factor - logical.width)/2
cr:move_to(ruler.x*factor+off, offset.y+padding)
else
local off = (ruler.height*factor - logical.width)/2
cr:move_to(-ruler.y*factor-dx2*factor-off, padding)
end
cr:show_layout(playout)
end
local function draw_vruler(s, dx2, sx, ruler, layer)
local pad = 5+(layer-1)*dx2
cr:set_source(color(ruler.color or (colors[ruler.label].."66")))
cr:move_to(sx+layer*dx2, ruler.y*factor)
cr:line_to(sx+layer*dx2, ruler.y*factor+ruler.height*factor)
cr:stroke()
cr:move_to(sx+layer*dx2-2.5,ruler.y*factor)
cr:line_to(sx+layer*dx2+2.5, ruler.y*factor)
cr:stroke()
cr:move_to(sx+layer*dx2-2.5,ruler.y*factor+ruler.height*factor)
cr:line_to(sx+layer*dx2+2.5, ruler.y*factor+ruler.height*factor)
cr:stroke()
cr:save()
cr:move_to(sx+layer*dx2-2.5,ruler.y*factor)
cr:rotate(-math.pi/2)
if ruler and ruler.label then
show_ruler_label({x=-s.geometry.height*factor, y=sx}, pad, ruler, get_playout())
elseif ruler and ruler.align then
show_aligned_label(dx2, {x=s.geometry.width*factor, y=0}, pad, ruler)
end
cr:restore()
end
local function draw_hruler(s, dx2, sy, ruler, layer)
local pad = 10+(layer-1)*(dx2 or 0)
cr:set_source(color(ruler.color or (colors[ruler.label].."66")))
cr:move_to(ruler.x*factor, sy+pad)
cr:line_to(ruler.x*factor+ruler.width*factor, sy+pad)
cr:stroke()
cr:move_to(ruler.x*factor, sy+pad-2.5)
cr:line_to(ruler.x*factor, sy+pad+2.5)
cr:stroke()
cr:move_to(ruler.x*factor+ruler.width*factor, sy+pad-2.5)
cr:line_to(ruler.x*factor+ruler.width*factor, sy+pad+2.5)
cr:stroke()
if ruler and ruler.label then
show_ruler_label({x=s.geometry.width*factor, y=sy}, pad, ruler, get_playout())
elseif ruler and ruler.align then
show_aligned_label(dx2, {x=s.geometry.width*factor, y=sy}, pad, ruler)
end
end
local function draw_rulers(s)
-- The table has a maximum of 4 entries, the sort algorithm is irrelevant.
while not bubble_sort(hrulers, "x", "width" ) do end
@ -205,67 +318,290 @@ local function draw_rulers(s)
local sx = (s.geometry.x+s.geometry.width )*factor
local sy = (s.geometry.y+s.geometry.height)*factor
local pctx = PangoCairo.font_map_get_default():create_context()
local playout = Pango.Layout.new(pctx)
local pdesc = Pango.FontDescription()
pdesc:set_absolute_size(11 * Pango.SCALE)
playout:set_font_description(pdesc)
local attr, parsed = Pango.parse_markup("<b>GeometryWorkareaPaddingMargins</b>", -1, 0)
playout.attributes, playout.text = attr, parsed
local _, logical = playout:get_pixel_extents()
dx = logical.height + 10
dx = get_text_height() + 10
for k, ruler in ipairs(vrulers) do
local pad = 5+(k-1)*dx
cr:set_source(color(colors[ruler.label].."66"))
cr:move_to(sx+k*dx, ruler.y*factor)
cr:line_to(sx+k*dx, ruler.y*factor+ruler.height*factor)
cr:stroke()
cr:move_to(sx+k*dx-2.5,ruler.y*factor)
cr:line_to(sx+k*dx+2.5, ruler.y*factor)
cr:stroke()
cr:move_to(sx+k*dx-2.5,ruler.y*factor+ruler.height*factor)
cr:line_to(sx+k*dx+2.5, ruler.y*factor+ruler.height*factor)
cr:stroke()
cr:save()
cr:move_to(sx+k*dx-2.5,ruler.y*factor)
cr:rotate(-math.pi/2)
show_ruler_label({x=-s.geometry.height*factor, y=sx}, pad, ruler, playout)
cr:restore()
draw_vruler(s, dx, sx, ruler, k)
end
for k, ruler in ipairs(hrulers) do
local pad = 10+(k-1)*dx
cr:set_source(color(colors[ruler.label].."66"))
cr:move_to(ruler.x*factor, sy+pad)
cr:line_to(ruler.x*factor+ruler.width*factor, sy+pad)
cr:stroke()
cr:move_to(ruler.x*factor, sy+pad-2.5)
cr:line_to(ruler.x*factor, sy+pad+2.5)
cr:stroke()
cr:move_to(ruler.x*factor+ruler.width*factor, sy+pad-2.5)
cr:line_to(ruler.x*factor+ruler.width*factor, sy+pad+2.5)
cr:stroke()
show_ruler_label({x=s.geometry.width*factor, y=sy}, pad, ruler, playout)
draw_hruler(s, dx, sy, ruler, k)
end
end
local tr_x, tr_y = 0, 0
-- Not a very efficient way to do this, but at least it is simple.
local function deduplicate_gaps(gaps)
for _, gap1 in ipairs(gaps) do
for k, gap2 in ipairs(gaps) do
if gap1[2] == gap2[1] then
gap1[2] = gap2[2]
table.remove(gaps, k)
return true
elseif gap2[1] >= gap1[1] and gap2[2] <= gap1[2] and gap1 ~= gap2 then
table.remove(gaps, k)
return true
elseif gap1[1] == gap2[1] and gap2[2] == gap2[2] and gap1 ~= gap2 then
table.remove(gaps, k)
return true
end
end
end
return false
end
local function get_gaps(s)
local ret = {vertical={gaps={}, content={}}, horizontal={gaps={}, content={}}}
local gap = s.selected_tag.gap
if gap == 0 then return ret end
if s.selected_tag.gap_single_client == false and #s.tiled_clients == 1 then
return ret
end
-- First, get all gaps.
for _, c in ipairs(s.tiled_clients) do
local bw = c.border_width
table.insert(ret.horizontal.gaps, {c.x-gap , c.x })
table.insert(ret.vertical.gaps , {c.y-gap , c.y })
table.insert(ret.horizontal.gaps, {c.x+c.width +2*bw, c.x+c.width+gap +2*bw})
table.insert(ret.vertical.gaps , {c.y+c.height+2*bw, c.y+c.height+gap+2*bw})
end
-- Merge continuous gaps.
while deduplicate_gaps(ret.vertical.gaps ) do end
while deduplicate_gaps(ret.horizontal.gaps) do end
return ret
end
local function evaluate_translation(draw_gaps, draw_struts, draw_mwfact, draw_client_snap)
for s in screen do
if (draw_gaps and s.selected_tag and s.selected_tag.gap > 0) then
local gaps = get_gaps(s)
-- Only add the space if there is something to display.
if #gaps.horizontal.gaps > 0 then
tr_y = math.max(tr_y, 3 * get_text_height())
end
if #gaps.vertical.gaps > 0 then
tr_x = math.max(tr_x, 2 * get_text_height())
end
end
if draw_client_snap or draw_struts then
tr_y = math.max(tr_y, 3 * get_text_height())
tr_x = math.max(tr_x, 2 * get_text_height())
end
if draw_mwfact then
tr_y = math.max(tr_y, 3 * get_text_height())
end
end
end
local function translate()
cr:translate(tr_x, tr_y * 0.66)
end
local function draw_gaps(s)
cr:translate(-tr_x, -tr_y)
local gaps = get_gaps(s)
local offset = s.tiling_area
for _, hgap in ipairs(gaps.horizontal.gaps) do
draw_hruler(
s,
offset.x,
get_text_height(),
{
x = offset.x+hgap[1]+tr_x,
width = math.ceil(hgap[2]-hgap[1]),
label = nil,
color = colors.gaps.."66",
align = true
},
1
)
end
for _, vgap in ipairs(gaps.vertical.gaps) do
draw_vruler(
s,
get_text_height()*1.5,
0,
{
y = offset.y+vgap[1]+tr_y,
height = math.ceil(vgap[2]-vgap[1]),
label = nil,
color = colors.gaps.."66",
align = true
},
1
)
end
cr:translate(tr_x, tr_y)
end
local function has_struts(s)
for k, v in pairs(s.workarea) do
if s.geometry[k] ~= v then
return true
end
end
return false
end
local function draw_struts(s)
local left = s.workarea.x - s.geometry.x
local right = (s.geometry.x + s.geometry.width) - (s.workarea.x + s.workarea.width)
local top = s.workarea.y - s.geometry.y
local bottom = (s.geometry.y + s.geometry.height) - (s.workarea.y + s.workarea.height)
cr:translate(-tr_x, -tr_y)
if left > 0 then
draw_hruler(
s,
0,
get_text_height(),
{x = s.geometry.x+tr_x*2, width = left, color = colors.gaps.."66", align = true},
1
)
end
if top > 0 then
draw_vruler(
s,
get_text_height()*1.5,
0,
{y=s.geometry.y+tr_y*(1/factor), height = top, color = colors.gaps.."66", align = true},
1
)
end
if right > 0 then
draw_hruler(
s,
0,
get_text_height(),
{x = s.geometry.x, width = left, color = colors.gaps.."66", align = true},
1
)
end
if bottom > 0 then
draw_vruler(
s,
get_text_height()*1.5,
0,
{
y = s.geometry.y+tr_y*(1/factor)+s.geometry.height - bottom,
height = bottom,
color = colors.gaps.."66",
align = true
},
1
)
end
cr:translate(tr_x, tr_y)
end
local function draw_mwfact(s)
cr:translate(-tr_x, -tr_y)
local mwfact = s.selected_tag.master_width_factor
local offset = s.tiling_area.x
local width = s.tiling_area.width
local w1, w2 = math.ceil(width*mwfact), math.ceil(width*(1-mwfact))
draw_hruler(s, offset, get_text_height(), {x=offset,width=w1,color = colors.gaps.."66", align=true}, 1)
draw_hruler(s, offset, get_text_height(), {x=offset+w1,width=w2,color = colors.gaps.."66", align=true}, 1)
cr:translate(tr_x, tr_y)
end
local function draw_client_snap(s)
cr:translate(-tr_x, -tr_y)
local snap_areas = {
vertical ={},
horizontal={}
}
local d = require("awful.mouse.snap").default_distance
for _, c in ipairs(s.clients) do
if c.floating then
table.insert(snap_areas.horizontal, {c.x-d, c.x})
table.insert(snap_areas.horizontal, {c.x+c.width, c.x+c.width+d})
table.insert(snap_areas.vertical , {c.y-d, c.y})
table.insert(snap_areas.vertical , {c.y+c.height, c.y+c.height+d})
end
end
while deduplicate_gaps(snap_areas.horizontal) do end
while deduplicate_gaps(snap_areas.vertical ) do end
--FIXME
--[[for _, hgap in ipairs(snap_areas.horizontal) do
draw_hruler(
s,
0,
get_text_height(),
{x=tr_x+s.workarea.x+hgap[1],width=hgap[2]-hgap[1],label="gaps"},
1
)
end
for _, vgap in ipairs(snap_areas.vertical) do
draw_vruler(
s,
get_text_height()*1.5,
0,
{y=tr_y+vgap[1],height=vgap[2]-vgap[1],label="gaps"},
1
)
end]]--
cr:translate(tr_x, tr_y)
end
-- local function draw_screen_snap(s)
-- local d = require("awful.mouse.snap").aerosnap_distance
--
--
-- local proxy = {
-- x = c.x - sd,
-- y = c.y - sd,
-- width = c.width + 2*sd,
-- height = c.height + 2*sd,
-- }
--
-- draw_client(s, proxy, 'gaps', (k-1)*10, nil, "11")
-- end
local function draw_info(s)
cr:set_source_rgb(0, 0, 0)
local pctx = PangoCairo.font_map_get_default():create_context()
local playout = Pango.Layout.new(pctx)
local pdesc = Pango.FontDescription()
local pctx = PangoCairo.font_map_get_default():create_context()
local playout2 = Pango.Layout.new(pctx)
local pdesc = Pango.FontDescription()
pdesc:set_absolute_size(11 * Pango.SCALE)
playout:set_font_description(pdesc)
playout2:set_font_description(pdesc)
local rows = {
"primary", "index", "geometry", "dpi", "dpi range", "outputs"
@ -298,13 +634,13 @@ local function draw_info(s)
-- Get the extents of the longest label.
for k, label in ipairs(rows) do
local attr, parsed = Pango.parse_markup(label..":", -1, 0)
playout.attributes, playout.text = attr, parsed
local _, logical = playout:get_pixel_extents()
playout2.attributes, playout2.text = attr, parsed
local _, logical = playout2:get_pixel_extents()
col1_width = math.max(col1_width, logical.width+10)
attr, parsed = Pango.parse_markup(values[k], -1, 0)
playout.attributes, playout.text = attr, parsed
_, logical = playout:get_pixel_extents()
playout2.attributes, playout2.text = attr, parsed
_, logical = playout2:get_pixel_extents()
col2_width = math.max(col2_width, logical.width+10)
height = math.max(height, logical.height)
@ -316,15 +652,15 @@ local function draw_info(s)
-- Draw everything.
for k, label in ipairs(rows) do
local attr, parsed = Pango.parse_markup(label..":", -1, 0)
playout.attributes, playout.text = attr, parsed
playout2.attributes, playout2.text = attr, parsed
cr:move_to(dx2, dy)
cr:show_layout(playout)
cr:show_layout(playout2)
attr, parsed = Pango.parse_markup(values[k], -1, 0)
playout.attributes, playout.text = attr, parsed
local _, logical = playout:get_pixel_extents()
playout2.attributes, playout2.text = attr, parsed
local _, logical = playout2:get_pixel_extents()
cr:move_to( dx2+col1_width+5, dy)
cr:show_layout(playout)
cr:show_layout(playout2)
dy = dy + 5 + logical.height
end
@ -344,11 +680,21 @@ for _=1, screen.count() do
compute_ruler(s, s.geometry, "geometry")
end
-- If there is some rulers on the left/top, add a global translation.
evaluate_translation(
args.draw_gaps,
args.draw_struts,
args.draw_mwfact,
args.draw_client_snap
)
-- Get the final size of the image.
local sew, seh = screen._get_extents()
sew, seh = sew/args.factor + (screen.count()-1)*10+2, seh/args.factor+2
sew,seh=sew+100,seh+100
sew, seh = sew + tr_x, seh + 0.66*tr_y
sew, seh = sew + 5*get_text_height(), seh + 5*get_text_height()
img = cairo.SvgSurface.create(image_path..".svg", sew, seh)
cr = cairo.Context(img)
@ -356,10 +702,14 @@ cr = cairo.Context(img)
cr:set_line_width(1.5)
cr:set_dash({10,4},1)
-- Instead of adding origin offset everywhere, translate the viewport.
translate()
-- Draw the various areas.
for k=1, screen.count() do
local s = screen[1]
-- The outer geometry.
draw_area(s, s.geometry, "geometry", (k-1)*10, args.highlight_geometry)
@ -381,17 +731,68 @@ for k=1, screen.count() do
draw_struct(s, args.draw_wibar, 'wibar', (k-1)*10, 'Wibar')
end
local skip_gaps = s.selected_tag
and s.selected_tag.gap_single_client == false
and #s.tiled_clients == 1
local sd = require("awful.mouse.snap").default_distance
-- Draw clients.
if args.draw_clients then
for label,c in pairs(args.draw_clients) do
draw_struct(s, c, 'tiling_client', (k-1)*10, label)
local gap = c:tags()[1].gap
if args.draw_gaps and gap > 0 and (not c.floating) and not skip_gaps then
local proxy = {
x = c.x - gap,
y = c.y - gap,
width = c.width + 2*gap,
height = c.height + 2*gap,
}
draw_client(s, proxy, 'gaps', (k-1)*10, nil, "11")
elseif args.draw_client_snap and c.floating then
local proxy = {
x = c.x - sd,
y = c.y - sd,
width = c.width + 2*sd,
height = c.height + 2*sd,
}
draw_client(s, proxy, 'gaps', (k-1)*10, nil, "11")
end
draw_client(s, c, 'tiling_client', (k-1)*10, label)
end
end
if args.draw_struts and has_struts(s) then
draw_struts(s)
end
-- Draw the informations.
if args.display_screen_info ~= false then
draw_info(s)
end
-- Draw the useless gaps.
if args.draw_gaps and not skip_gaps then
draw_gaps(s)
end
-- Draw the useless gaps.
if args.draw_mwfact then
draw_mwfact(s)
end
-- Draw the snapping areas of floating clients.
if args.draw_client_snap then
draw_client_snap(s)
end
-- Draw the screen edge areas.
--if args.draw_screen_snap then
-- draw_screen_snap(s)
--end
end
img:finish()