* Use the new Awesome `shape` API
* Fix the `split` module
* Support dynamic resize
This commit is contained in:
Emmanuel Lepage Vallee 2016-02-09 00:10:11 -05:00
parent 042272bee9
commit 7bcbb822c9
8 changed files with 164 additions and 75 deletions

View File

@ -117,6 +117,7 @@ assigned to shortcuts.
The `collision.highlight_cursor(timeout)` method will highlight the current mouse
cursor position.
Use `collision.mouse.highlight()` and `collision.mouse.hide()`
# Notes
Using the focus arrows to select empty screens only work in Awesome 3.5.7+

View File

@ -3,6 +3,8 @@ local capi = { client = client , mouse = mouse ,
local setmetatable = setmetatable
local ipairs = ipairs
local surface = require( "gears.surface" )
local shape = require( "gears.shape" )
local util = require( "awful.util" )
local client = require( "awful.client" )
local tag = require( "awful.tag" )
@ -19,16 +21,6 @@ local edge = nil
---------------- Visual -----------------------
local function init()
local img = cairo.ImageSurface(cairo.Format.ARGB32, 75, 75)
local cr = cairo.Context(img)
col_utils.draw_round_rect(cr,0,0,75,75,10)
cr:fill()
local bounding,arrow = img._native,col_utils.arrow(55,10,0,
beautiful.collision_bg_focus or beautiful.bg_normal or "#000000",
beautiful.collision_fg_focus or beautiful.fg_normal or "#0000ff"
)
wiboxes = {}
for k,v in ipairs({"up","right","down","left","center"}) do
wiboxes[v] = wibox({})
@ -37,26 +29,24 @@ local function init()
wiboxes[v].ontop = true
if v ~= "center" then
local ib,m = wibox.widget.imagebox(),wibox.layout.margin()
local img = cairo.ImageSurface(cairo.Format.ARGB32, 55, 55)
local cr = cairo.Context(img)
cr:translate(55/2,55/2)
cr:rotate((k-1)*(2*math.pi)/4)
cr:translate(-(55/2),-(55/2))
cr:set_source(arrow)
cr:paint()
ib:set_image(img)
ib:set_image(surface.load_from_shape(55, 55,
shape.transform(col_utils.arrow_path2)
: rotate_at(55/2, 55/2, (k-1)*(2*math.pi)/4),
beautiful.collision_fg_focus or beautiful.fg_normal or "#0000ff",
nil , 55, 55-20
))
m:set_margins(10)
m:set_widget(ib)
wiboxes[v]:set_widget(m)
wiboxes[v].shape_bounding = bounding
surface.apply_shape_bounding(wiboxes[v], shape.rounded_rect, 10)
end
end
wiboxes["center"]:set_bg(beautiful.collision_bg_center or beautiful.bg_urgent or "#ff0000")
local img = cairo.ImageSurface(cairo.Format.ARGB32, 75,75)
local cr = cairo.Context(img)
col_utils.draw_round_rect(cr,0,0,75,75,75/2)
cr:fill()
wiboxes["center"].shape_bounding = img._native
surface.apply_shape_bounding(wiboxes["center"], shape.rounded_rect, 37.5)
end
local function emulate_client(screen)

View File

@ -9,7 +9,7 @@ local module = {
_resize = require( "collision.resize"),
_max = require( "collision.max" ),
_screen = require( "collision.screen"),
_mouse = require( "collision.mouse" ),
mouse = require( "collision.mouse" ),
settings= col_utils.settings ,
util = col_utils ,
split = require( "collision.split" ),
@ -135,11 +135,11 @@ function module.select_screen(idx)
end
function module.highlight_cursor(timeout)
module._mouse.highlight()
module.mouse.highlight()
if timer then
local timer = capi.timer({ timeout = timeout }) -- 30 mins
timer:connect_signal("timeout", function()
module._mouse.hide()
module.mouse.hide()
timer:stop()
end)
timer:start()

View File

@ -8,6 +8,7 @@ local awful = require("awful")
local beautiful = require("beautiful")
local color = require( "gears.color")
local util = require( "collision.util" )
local shape = require( "gears.shape" )
local capi = { screen = screen, client=client }
local module = {}
@ -89,7 +90,13 @@ function module.draw(tag,cr,width,height)
cr:set_line_width(3)
for c,ll in ipairs({l,l2}) do
for c,geom in pairs(ll) do
util.draw_round_rect(cr,geom.x*ratio*w_stretch+margin,geom.y*ratio+margin,geom.width*ratio*w_stretch-margin*2,geom.height*ratio-margin*2,radius)
shape.transform(shape.rounded_rect)
: translate(geom.x*ratio*w_stretch+margin, geom.y*ratio+margin) (
cr,
geom.width*ratio*w_stretch-margin*2,
geom.height*ratio-margin*2,
radius
)
cr:close_path()
cr:set_source_rgba(r,g,b,0.7)
cr:stroke_preserve()

61
max.lua
View File

@ -7,6 +7,8 @@ local beautiful = require( "beautiful" )
local surface = require( "gears.surface" )
local layout = require( "collision.layout" )
local util = require( "collision.util" )
local shape = require( "gears.shape" )
local shape = require( "gears.shape" )
local pango = require("lgi").Pango
local pangocairo = require("lgi").PangoCairo
local module = {}
@ -22,26 +24,24 @@ local function init()
end
local margin = 15
local function create_arrow(cr,x,y,width, height,direction)
cr:save()
cr:translate(x,y)
if direction then
cr:translate(width,height)
cr:rotate(math.pi)
end
cr:move_to(x,y)
local r,g,b = util.get_rgb()
cr:set_source_rgba(r,g,b,0.15)
cr:set_antialias(1)
cr:rectangle(2*margin,2*(height/7),width/3,3*(height/7))
local s = shape.transform(shape.arrow)
: rotate_at(width/4, height/4, math.pi/2)
if direction == 1 then
s : rotate_at(width/4, height/4, math.pi)
end
s : translate(x, y)
s(cr, width/2, height/2, nil)
cr:fill()
cr:move_to(2*margin+width/3,(height/7))
cr:line_to(width-2*margin,height/2)
cr:line_to(2*margin+width/3,6*(height/7))
cr:line_to(2*margin+width/3,(height/7))
cr:close_path()
cr:fill()
cr:restore()
end
local pango_l = nil
@ -89,12 +89,19 @@ local function draw_shape(s,collection,current_idx,icon_f,y,text_height)
for k,v in ipairs(collection) do
-- Shape bounding
cr:set_source(white)
util.draw_round_rect(cr,dx,0,width,height,rad)
local s = shape.transform(shape.rounded_rect) : translate(dx, 0)
s(cr, width, height, 10)
cr:fill()
-- Borders and background
cr3:set_source(k==current_idx and focus or nornal)
util.draw_round_rect(cr3,dx+border,0+border,width-2*border,height-2*border,rad)
-- cr3:move_to(0,0)
-- s = shape.transform(shape.rounded_rect) : translate(dx+border, border)
-- s(cr3, width-2*border, height-2*border, rad)
cr3:set_line_width(2*border + 4) -- The 4 is required to cover the non-antialiased region
cr3:stroke_preserve()
cr3:set_source(bg)
@ -159,9 +166,10 @@ local function client_icon(c,width,height)
local w,h = geom.width*scale,geom.height*scale
-- Create a mask
util.draw_round_rect(cr,(width-w)/2,(height-h)/2,w,h,10)
local s = shape.transform(shape.rounded_rect) : translate((width-w)/2, (height-h)/2)
s(cr, w, h, 10)
cr:fill()
cr:clip()
cr:translate((width-w)/2,(height-h)/2)
@ -171,10 +179,9 @@ local function client_icon(c,width,height)
-- Paint the screenshot in the rounded rectangle
cr:set_source_surface(surface(c.content))
cr:set_operator(cairo.Operator.IN)
cr:paint()
cr:restore()
cr:restore()
-- Add icon on top, "solve" the black window issue
local icon = surface(c.icon)
@ -183,13 +190,13 @@ local function client_icon(c,width,height)
return img
end
local w,h = icon:get_width(),icon:get_height()
local aspect,aspect_h = width / w,(height) / h
if aspect > aspect_h then aspect = aspect_h end
cr:translate((width-w*aspect)/2,(height-h*aspect)/2)
cr:scale(aspect, aspect)
cr:set_source_surface(icon)
cr:paint_with_alpha(0.5)
-- local w,h = icon:get_width(),icon:get_height()
-- local aspect,aspect_h = width / w,(height) / h
-- if aspect > aspect_h then aspect = aspect_h end
-- cr:translate((width-w*aspect)/2,(height-h*aspect)/2)
-- cr:scale(aspect, aspect)
-- cr:set_source_surface(icon)
-- cr:paint_with_alpha(0.5)
return img
end

View File

@ -4,11 +4,19 @@ local wibox,color = require( "wibox" ) , require( "gears.color" )
local cairo,beautiful = require( "lgi").cairo , require( "beautiful" )
local awful = require("awful")
local col_utils = require( "collision.util" )
local d_resize = require( "awful.layout.dynamic.resize" )
local module,indicators,cur_c,auto_hide = {},nil,nil
local values = {"top" , "top_right" , "right" , "bottom_right" ,
"bottom" , "bottom_left", "left" , "top_left" }
local invert = {
left = "right" ,
right = "left" ,
top = "bottom",
bottom = "top"
}
local function gen_shape_bounding(radius)
local img = cairo.ImageSurface(cairo.Format.ARGB32, radius,radius)
local cr = cairo.Context(img)
@ -98,6 +106,12 @@ end
function module.display(c,toggle)
local c = c or capi.client.focus
if not c then return end
if type(c) ~= "client" then
print("FAILED", debug.traceback())
os.exit()
end
if not indicators then
create_indicators()
end
@ -127,6 +141,8 @@ function module.resize(mod,key,event,direction,is_swap,is_max)
new_geo[r_direction[direction]] = new_geo[r_direction[direction]] + r_sign[direction]*100
end
c:geometry(new_geo)
elseif lay.is_dynamic then
d_resize.ajust_geometry(c, 100 * (is_swap and -1 or 1), is_swap and invert[direction] or direction)
elseif layouts_all[lay] then
local ret = layouts_all[lay][direction]
if ret.mwfact then
@ -147,7 +163,20 @@ local corners = {
-- Resize from the top left corner
function module.mouse_resize(c,corner)
if not c then return end
module.display(c)
-- Check if the dynamic resize codepath is available
local lay = awful.layout.get(c.screen)
if lay.is_dynamic then
d_resize.generic_mouse_resize_handler(c, nil, nil, nil,{
leave_callback = module.hide
})
return
end
-- Use the internal resizing code
local geom,curX,curY = c:geometry(),capi.mouse.coords().x,capi.mouse.coords().y
capi.mousegrabber.run(function(mouse)
if mouse.buttons[1] == false then

View File

@ -11,6 +11,7 @@ local utils = require( "collision.util" )
local wibox = require( "wibox" )
local beautiful = require( "beautiful" )
local tag = require( "awful.tag" )
local util = require( "awful.util" )
local textbox = require( "wibox.widget.textbox" )
local color = require( "gears.color" )
local cairo = require( "lgi" ).cairo
@ -29,7 +30,12 @@ module.key_map = {
"a", "s", "d", "f", "g",
"h", "j", "k", "l", "z",
"x", "c", "v", "b", "n",
"m", "-", "=", ",", "."
"m", "-", "=", ",", ".",
";", "'", "[", "]", "/",
"!","@","#","$","%","^",
"&","*","(",")","+","{",
"}",":",'"',"<",">","?",
"`", "\\",
}
local dir_to_angle = {
@ -38,11 +44,12 @@ local dir_to_angle = {
top = math.pi ,
bottom = 0 ,
middle = 0 ,
stack = 0 ,
}
local dir_to_width_offset_ratio = {
internal = {
left = -0.5, right = -0.5, top = -0.5, bottom = -0.5, middle = -0.5,
left = -0.5, right = -0.5, top = -0.5, bottom = -0.5, middle = -0.5, stack = -0.5,
},
sides = {
right = -1 , left = 0 , top = -0.5, bottom = -0.5, middle = -0.5,
@ -51,7 +58,7 @@ local dir_to_width_offset_ratio = {
local dir_to_height_offset_ratio = {
internal = {
left = -0.5, right = -0.5, top = -0.5, bottom = -0.5, middle = -0.5,
left = -0.5, right = -0.5, top = -0.5, bottom = -0.5, middle = -0.5, stack = -0.5,
},
sides = {
left = -0.5, right = -0.5, top = 0 , bottom = -1 , middle = -0.5,
@ -59,7 +66,7 @@ local dir_to_height_offset_ratio = {
}
local dir_to_size = {
left = 60, right = 60, top = 60, bottom = 60, middle = 50,
left = 60, right = 60, top = 60, bottom = 60, middle = 50, stack = 50,
}
local type_to_size_ratio = {
@ -75,14 +82,26 @@ local function internal_rect_pattern(size, direction)
cr:set_source(color(beautiful.collision_bg_splitter or beautiful.bg_normal or "#0000ff"))
cr:paint()
local fg = color(beautiful.collision_fg_splitter or beautiful.fg_normal or "#ffffff")
local s,r,g,b,a = fg:get_rgba()
cr:set_source_rgba(r,g,b,0.4)
-- This one is different
if direction == "stack" then
cr:rectangle(3, 3, size - 12, size - 12)
cr:stroke()
cr:rectangle(9, 9, size - 12, size - 12)
cr:stroke_preserve()
cr:set_source_rgba(r,g,b,0.2)
cr:fill()
return cairo.Pattern.create_for_surface(img)
end
cr:translate(size/2,size/2)
cr:rotate(dir_to_angle[direction])
cr:translate(-size/2,-size/2)
local fg = color(beautiful.collision_fg_splitter or beautiful.fg_normal or "#ffffff")
local s,r,g,b,a = fg:get_rgba()
cr:set_source_rgba(r,g,b,0.4)
cr:rectangle(3, 3, size-6, size/2-6)
cr:stroke()
cr:rectangle(3, size/2+3, size-6, size/2-6)
@ -120,14 +139,7 @@ local function add_splitter(context, args)
local bg = beautiful.collision_bg_splitter or beautiful.bg_alternate or beautiful.bg_normal or "#0000ff"
local width = size * #points
local w = wibox {
x = math.ceil(args.x + dir_to_width_offset_ratio [s_type][direction]*width),
y = math.ceil(args.y + dir_to_height_offset_ratio[s_type][direction]*size),
width = width,
height = size,
ontop = true,
bg = bg ,
}
local top_level_l = wibox.layout.flex.vertical()
local l = wibox.layout.flex.horizontal()
@ -142,7 +154,7 @@ local function add_splitter(context, args)
local tb = textbox()
tb:set_markup("<b>".. shortcut .."</b>")
tb:set_markup("<b>".. util.quote_pattern(shortcut) .."</b>")
tb:set_valign "middle"
tb:set_align "center"
@ -153,7 +165,31 @@ local function add_splitter(context, args)
context.hooks[shortcut] = point
end
w:set_widget(l)
local height = size
if args.label then
local tb = wibox.widget.textbox()
tb:set_align("center")
tb:set_text(args.label)
tb:set_wrap("mode")
height = height + tb:get_height_for_width(width)
top_level_l:add(tb)
end
top_level_l:add(l)
-- Create a wibox
local w = wibox {
x = math.ceil(args.x + dir_to_width_offset_ratio [s_type][direction]*width),
y = math.ceil(args.y + dir_to_height_offset_ratio[s_type][direction]*size),
width = width,
height = height,
ontop = true,
bg = bg ,
}
w:set_widget(top_level_l)
utils.apply_shape_bounding(w, function(cr) type_to_shape[s_type](cr, w.width, w.height, direction) end)
@ -185,6 +221,7 @@ local function drill(context, root, source)
if points then
for k, point in ipairs(points) do
print(#points)
add_splitter(context, point)
end
end
@ -211,7 +248,9 @@ local function find_split_points(context)
if layout.hierarchy then
local wa = layout.param.workarea
context.add_x, context.add_y = wa.x, wa.y
if drill(context, layout.hierarchy, nil) then
local source = drill(context, layout.hierarchy, nil)
if source then
print("\n\nGET", layout.hierarchy, layout.hierarchy:get_widget())
context.source_root = layout.hierarchy:get_widget()
end
end
@ -232,12 +271,12 @@ end
local function start_keygrabber(context)
capi.keygrabber.run(function(mod, key, event)
local hook = context.hooks[key]
print("\n\nKEY", key, hook)
if hook and hook.callback and event == "press" then
context.hooks[key]:callback(context)
end
if event == "press" then
if event == "press" and not (key == "Shift_Lt" or key == "Shift_R") then
hide(context)
capi.keygrabber.stop()
end

View File

@ -38,6 +38,22 @@ function module.arrow_path(cr, width, sidesize)
cr:close_path()
end
function module.arrow_path2(cr, width, height, head_width, shaft_width, shaft_length)
local shaft_length = shaft_length or height / 2
local shaft_width = shaft_width or width / 2
local head_width = head_width or width
local head_length = height - shaft_length
cr:move_to( width/2 , 0 )
cr:rel_line_to( head_width/2 , head_length )
cr:rel_line_to( -(head_width-shaft_width)/2 , 0 )
cr:rel_line_to( 0 , shaft_length )
cr:rel_line_to( -shaft_width , 0 )
cr:rel_line_to( 0 , -shaft_length )
cr:rel_line_to( -(head_width-shaft_width)/2 , 0 )
cr:close_path()
end
function module.arrow(width, sidesize, margin, bg_color, fg_color)
local img = cairo.ImageSurface(cairo.Format.ARGB32, width+2*margin, width+2*margin)
local cr = cairo.Context(img)