collision/focus.lua

195 lines
6.0 KiB
Lua
Raw Normal View History

2013-06-03 23:22:41 +02:00
local capi =
{
client = client,
mouse = mouse,
screen = screen,
}
local setmetatable = setmetatable
local print = print
local ipairs = ipairs
local util = require("awful.util")
local client = require("awful.client")
local screen = require("awful.screen")
local wibox = require("wibox")
local cairo = require("lgi").cairo
local beautiful = require( "beautiful" )
local color = require("gears.color")
local module = {}
local wiboxes = nil
local function gen(item_height)
local img = cairo.ImageSurface(cairo.Format.ARGB32, item_height,item_height)
local cr = cairo.Context(img)
local rad = 10
cr:set_source_rgba(0,0,0,0)
cr:paint()
cr:set_source_rgba(1,1,1,1)
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:fill()
cr:rectangle(0,rad, item_height, item_height-2*rad)
cr:rectangle(rad,0, item_height-2*rad, item_height)
cr:fill()
return img._native
end
local constructor = {
up = function (width, height)
local img = cairo.ImageSurface(cairo.Format.ARGB32, width, height)
local cr = cairo.Context(img)
cr:move_to(0,0)
cr:set_source(color(beautiful.fg_normal))
cr:paint()
cr:set_source(color(beautiful.bg_normal))
cr:set_antialias(1)
cr:rectangle(0, (width/2), 10, (width/2))
cr:rectangle(width-10, (width/2), 10, (width/2))
for i=0,(width/2) do
cr:rectangle(i, 0, 1, (width/2)-i)
cr:rectangle(width-i, 0, 1, (width/2)-i)
end
cr:fill()
return img
end,
down = function (width, height)
local img = cairo.ImageSurface(cairo.Format.ARGB32, width, height)
local cr = cairo.Context(img)
cr:set_source(color(beautiful.fg_normal))
cr:paint()
cr:set_source(color(beautiful.bg_normal))
cr:set_antialias(1)
cr:rectangle(0, 0, 10, (width/2))
cr:rectangle(width-10, 0, 10, (width/2))
for i=0,(width/2) do
cr:rectangle((width/2)+i, height-i, 1, i)
cr:rectangle((width/2)-i, height-i, 1, i)
end
cr:fill()
return img
end,
right = function (width, height)
local img = cairo.ImageSurface(cairo.Format.ARGB32, width, height)
local cr = cairo.Context(img)
cr:set_source(color(beautiful.fg_normal))
cr:paint()
cr:set_source(color(beautiful.bg_normal))
cr:set_antialias(1)
cr:rectangle(0, 0, (width/2), 10)
cr:rectangle(0, height-10, (width/2), 10)
for i=0,(width/2) do
cr:rectangle(width-i, (width/2)+i, i, 1)
cr:rectangle(width-i, (width/2)-i, i, 1)
end
cr:fill()
return img
end,
left = function (width, height)
local img = cairo.ImageSurface(cairo.Format.ARGB32, width, height)
local cr = cairo.Context(img)
cr:set_source(color(beautiful.fg_normal))
cr:paint()
cr:set_source(color(beautiful.bg_normal))
cr:set_antialias(1)
cr:rectangle((width/2), 0, (width/2), 10)
cr:rectangle((width/2), height-10, (width/2), 10)
for i=0,(width/2) do
cr:rectangle(0, i, (width/2)-i, 1)
cr:rectangle(0, (width/2)+i, i, 1)
end
cr:fill()
return img
end
}
function module.bydirection(dir, c)
local sel = c or capi.client.focus
if sel then
local cltbl = client.visible(sel.screen)
local geomtbl = {}
for i,cl in ipairs(cltbl) do
geomtbl[i] = cl:geometry()
end
local target = util.get_rectangle_in_direction(dir, geomtbl, sel:geometry())
-- If we found a client to focus, then do it.
if target then
capi.client.focus = cltbl[target]
capi.client.focus:raise()
end
local next_clients = {
left = cltbl[util.get_rectangle_in_direction("left" , geomtbl, capi.client.focus:geometry())],
right = cltbl[util.get_rectangle_in_direction("right", geomtbl, capi.client.focus:geometry())],
up = cltbl[util.get_rectangle_in_direction("up" , geomtbl, capi.client.focus:geometry())],
down = cltbl[util.get_rectangle_in_direction("down" , geomtbl, capi.client.focus:geometry())],
}
if not wiboxes then
local bounding = gen(75)
wiboxes = {}
for k,v in ipairs({"left","right","up","down"}) do
wiboxes[v] = wibox({})
wiboxes[v].height = 75
wiboxes[v].width = 75
wiboxes[v].ontop = true
local ib = wibox.widget.imagebox()
ib:set_image(constructor[v](55,55))
local m = wibox.layout.margin(arrow)
m:set_margins(10)
m:set_widget(ib)
wiboxes[v]:set_widget(m)
wiboxes[v].shape_bounding = bounding
end
end
for k,v in ipairs({"left","right","up","down"}) do
if next_clients[v] then
local geo = next_clients[v]:geometry()
wiboxes[v].visible = true
wiboxes[v].x = geo.x + geo.width/2 - 75/2
wiboxes[v].y = geo.y + geo.height/2 - 75/2
else
wiboxes[v].visible = false
end
end
end
end
function module.global_bydirection(dir, c)
local sel = c or capi.client.focus
local scr = capi.mouse.screen
if sel then
scr = sel.screen
end
-- change focus inside the screen
module.bydirection(dir, sel)
-- if focus not changed, we must change screen
if sel == capi.client.focus then
screen.focus_bydirection(dir, scr)
if scr ~= capi.mouse.screen then
local cltbl = client.visible(capi.mouse.screen)
local geomtbl = {}
for i,cl in ipairs(cltbl) do
geomtbl[i] = cl:geometry()
end
local target = util.get_rectangle_in_direction(dir, geomtbl, capi.screen[scr].geometry)
if target then
capi.client.focus = cltbl[target]
capi.client.focus:raise()
end
end
end
end
return setmetatable(module, { __call = function(_, ...) return new(...) end })