forked from Elv13/collision
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmax.lua
291 lines (239 loc) · 8.21 KB
/
max.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
local capi = {screen=screen,client=client,mouse=mouse}
local wibox = require("wibox")
local awful = require("awful")
local cairo = require( "lgi" ).cairo
local color = require( "gears.color" )
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 pango = require("lgi").Pango
local pangocairo = require("lgi").PangoCairo
local module = {}
local w = nil
local rad = 10
local border = 3
local function init()
w = wibox{}
w.ontop = true
w.visible = true
end
local margin = 15
local function create_arrow(cr,x,y,width, height,direction)
local r,g,b = util.get_rgb()
cr:set_source_rgba(r,g,b,0.15)
cr:set_antialias(1)
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()
end
local pango_l = nil
local function draw_shape(s,collection,current_idx,icon_f,y,text_height)
local geo = capi.screen[s].geometry
local wa =capi.screen[s].workarea
--Compute thumb dimensions
local margins = 2*20 + (#collection-1)*20
local width = (geo.width - margins) / #collection
local ratio = geo.height/geo.width
local height = width*ratio
local dx = 20
-- Do not let the thumb get too big
if height > 150 then
height = 150
width = 150 * (1.0/ratio)
dx = (wa.width-margins-(#collection*width))/2 + 20
end
-- Resize the wibox
w.x,w.y,w.width,w.height = math.floor(geo.x),math.floor(y or (wa.y+wa.height) - margin - height),math.floor(geo.width),math.floor(height)
local rshape = beautiful.collision_max_shape or shape.rounded_rect
local img = cairo.ImageSurface(cairo.Format.ARGB32, geo.width,geo.height)
local img3 = cairo.ImageSurface(cairo.Format.ARGB32, geo.width,geo.height)
local cr = cairo.Context(img)
local cr3 = cairo.Context(img3)
cr:set_source_rgba(0,0,0,0)
cr:paint()
-- Get the colors
local white,bg = color("#FFFFFF"),color(
beautiful.collision_max_bg or beautiful.menu_bg_normal or beautiful.bg_normal
)
local normal, focus = color(beautiful.collision_max_fg or beautiful.fg_normal), color(beautiful.bg_urgent)
-- Init the text properties
if not pango_l then
local pango_crx = pangocairo.font_map_get_default():create_context()
pango_l = pango.Layout.new(pango_crx)
pango_l:set_font_description(beautiful.get_font(font))
pango_l:set_alignment("CENTER")
pango_l:set_wrap("CHAR")
end
for k,v in ipairs(collection) do
-- Shape bounding
cr:set_source(white)
local s = shape.transform(rshape) : translate(dx, 0)
s(cr, width, height, 10)
cr:fill()
-- Borders and background
cr3:set_source(k==current_idx and focus or normal)
cr3:move_to(0,0)
s = shape.transform(rshape) : 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)
cr3:fill()
-- Print the icon
local icon = icon_f(v,width-20,height-20-text_height)
if icon then
cr3:save()
cr3:translate(dx+10,10)
cr3:set_source_surface(icon)
cr3:paint_with_alpha(0.7)
cr3:restore()
end
-- Print a pretty line
local r,g,b = util.get_rgb(normal)
cr3:set_source_rgba(r,g,b,0.7)
cr3:set_line_width(1)
cr3:move_to(dx+margin,height - text_height-border)
cr3:line_to(dx+margin+width-2*margin,height - text_height-border)
cr3:stroke()
-- Pring the text
pango_l.text = v.name
pango_l.width = pango.units_from_double(width-16)
pango_l.height = pango.units_from_double(height-text_height-10)
cr3:move_to(dx+8,height-text_height-0)
cr3:show_layout(pango_l)
-- Draw an arrow
if k == current_idx-1 then
create_arrow(cr3,dx,0,width,height,1)
elseif k == current_idx+1 then
create_arrow(cr3,dx,0,width,height,nil)
end
dx = dx + width + 20
end
w:set_bg(cairo.Pattern.create_for_surface(img3))
w.shape_bounding = img._native
w.visible = true
end
function module.hide()
w.visible = false
end
--Client related
local function client_icon(c,width,height)
-- Get the content
--TODO detect pure black frames
local img = cairo.ImageSurface(cairo.Format.ARGB32, width, height)
local rshape = beautiful.collision_max_shape or shape.rounded_rect
local cr = cairo.Context(img)
local geom = c:geometry()
local scale = width/geom.width
if geom.height*scale > height then
scale = height/geom.height
end
local w,h = geom.width*scale,geom.height*scale
-- Create a mask
local s = shape.transform(rshape) : translate((width-w)/2, (height-h)/2)
s(cr, w, h, 10)
cr:clip()
cr:translate((width-w)/2,(height-h)/2)
-- Create a matrix to scale down the screenshot
cr:save()
cr:scale(scale,scale)
-- Paint the screenshot in the rounded rectangle
cr:set_source_surface(surface(c.content))
cr:paint()
cr:restore()
-- Add icon on top, "solve" the black window issue
local icon = surface(c.icon)
if not icon then
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)
return img
end
function module.display_clients(s,direction)
if not w then
init()
end
if direction then
awful.client.focus.byidx(direction == "right" and 1 or -1)
capi.client.focus:raise()
end
local clients = awful.client.tiled(s)
local fk = awful.util.table.hasitem(clients,capi.client.focus)
draw_shape(s,clients,fk,client_icon,nil,50)
end
function module.change_focus(mod,key,event,direction,is_swap,is_max)
awful.client.focus.byidx(direction == "right" and 1 or -1)
local c = capi.client.focus
local s = c.screen
c:raise()
local clients = awful.client.tiled(s)
local fk = awful.util.table.hasitem(clients,c)
draw_shape(s,clients,fk,client_icon,nil,50)
return true
end
--Tag related
local function tag_icon(t,width,height)
local img = cairo.ImageSurface(cairo.Format.ARGB32, width, height)
local cr = cairo.Context(img)
local has_layout = layout.draw(t,cr,width,height)
-- Create a monochrome representation of the icon
local icon_orig = surface(t.icon)
if icon_orig then
local icon = cairo.ImageSurface(cairo.Format.ARGB32, icon_orig:get_width(), icon_orig:get_height())
local cr2 = cairo.Context(icon)
cr2:set_source_surface(icon_orig)
cr2:paint()
cr2:set_source(color(beautiful.fg_normal))
cr2:set_operator(cairo.Operator.IN)
cr2:paint()
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(has_layout and 0.35 or 1)
end
return img
end
local function change_tag(s,direction,is_swap)
local s = capi.client.focus and capi.client.focus.screen or capi.mouse.screen
if not is_swap then
awful.tag[direction == "left" and "viewprev" or "viewnext"](s)
else
-- Move the tag
local t = capi.screen[s].selected_tag
local cur_idx,count = awful.tag.getidx(t),#capi.screen[s].tags
cur_idx = cur_idx + (direction == "left" and -1 or 1)
cur_idx = cur_idx == 0 and count or cur_idx > count and 1 or cur_idx
t.index = cur_idx
end
local tags = capi.screen[s].tags
local fk = awful.util.table.hasitem(tags,capi.screen[s].selected_tag)
draw_shape(s,tags,fk,tag_icon,capi.screen[s].workarea.y + 15,20)
end
function module.display_tags(s,direction,c,is_swap,is_max)
if not w then
init()
end
change_tag(s,direction,is_swap)
end
function module.change_tag(mod,key,event,direction,is_swap,is_max)
change_tag(s,direction,is_swap)
return true
end
return module
-- kate: space-indent on; indent-width 2; replace-tabs on;