some deletions
[dotfiles/.git] / .config / awesome / themes / vertex / theme.lua
1 --[[
2
3      Vertex Awesome WM theme
4      github.com/lcpz
5
6 --]]
7
8 local gears = require("gears")
9 local lain  = require("lain")
10 local awful = require("awful")
11 local wibox = require("wibox")
12 local dpi   = require("beautiful.xresources").apply_dpi
13
14 local math, string, tag, tonumber, type, os = math, string, tag, tonumber, type, os
15 local my_table = awful.util.table or gears.table -- 4.{0,1} compatibility
16
17 local theme                                     = {}
18 theme.default_dir                               = require("awful.util").get_themes_dir() .. "default"
19 theme.icon_dir                                  = os.getenv("HOME") .. "/.config/awesome/themes/vertex/icons"
20 theme.wallpaper                                 = os.getenv("HOME") .. "/.config/awesome/themes/vertex/wall.png"
21 theme.font                                      = "Roboto Bold 10"
22 theme.taglist_font                              = "FontAwesome 17"
23 theme.fg_normal                                 = "#FFFFFF"
24 theme.fg_focus                                  = "#6A95EB"
25 theme.bg_focus                                  = "#303030"
26 theme.bg_focus2                                 = "#3762B8"
27 theme.bg_normal                                 = "#242424"
28 theme.fg_urgent                                 = "#CC9393"
29 theme.bg_urgent                                 = "#006B8E"
30 theme.border_width                              = dpi(4)
31 theme.border_normal                             = "#252525"
32 theme.border_focus                              = "#7CA2EE"
33 theme.tooltip_border_color                      = theme.fg_focus
34 theme.tooltip_border_width                      = theme.border_width
35 theme.menu_height                               = dpi(24)
36 theme.menu_width                                = dpi(140)
37 theme.awesome_icon                              = theme.icon_dir .. "/awesome.png"
38 theme.taglist_squares_sel                       = gears.surface.load_from_shape(dpi(3), dpi(30), gears.shape.rectangle, theme.fg_focus)
39 theme.taglist_squares_unsel                     = gears.surface.load_from_shape(dpi(3), dpi(30), gears.shape.rectangle, theme.bg_focus2)
40 theme.panelbg                                   = theme.icon_dir .. "/panel.png"
41 theme.bat000charging                            = theme.icon_dir .. "/bat-000-charging.png"
42 theme.bat000                                    = theme.icon_dir .. "/bat-000.png"
43 theme.bat020charging                            = theme.icon_dir .. "/bat-020-charging.png"
44 theme.bat020                                    = theme.icon_dir .. "/bat-020.png"
45 theme.bat040charging                            = theme.icon_dir .. "/bat-040-charging.png"
46 theme.bat040                                    = theme.icon_dir .. "/bat-040.png"
47 theme.bat060charging                            = theme.icon_dir .. "/bat-060-charging.png"
48 theme.bat060                                    = theme.icon_dir .. "/bat-060.png"
49 theme.bat080charging                            = theme.icon_dir .. "/bat-080-charging.png"
50 theme.bat080                                    = theme.icon_dir .. "/bat-080.png"
51 theme.bat100charging                            = theme.icon_dir .. "/bat-100-charging.png"
52 theme.bat100                                    = theme.icon_dir .. "/bat-100.png"
53 theme.batcharged                                = theme.icon_dir .. "/bat-charged.png"
54 theme.ethon                                     = theme.icon_dir .. "/ethernet-connected.png"
55 theme.ethoff                                    = theme.icon_dir .. "/ethernet-disconnected.png"
56 theme.volhigh                                   = theme.icon_dir .. "/volume-high.png"
57 theme.vollow                                    = theme.icon_dir .. "/volume-low.png"
58 theme.volmed                                    = theme.icon_dir .. "/volume-medium.png"
59 theme.volmutedblocked                           = theme.icon_dir .. "/volume-muted-blocked.png"
60 theme.volmuted                                  = theme.icon_dir .. "/volume-muted.png"
61 theme.voloff                                    = theme.icon_dir .. "/volume-off.png"
62 theme.wifidisc                                  = theme.icon_dir .. "/wireless-disconnected.png"
63 theme.wififull                                  = theme.icon_dir .. "/wireless-full.png"
64 theme.wifihigh                                  = theme.icon_dir .. "/wireless-high.png"
65 theme.wifilow                                   = theme.icon_dir .. "/wireless-low.png"
66 theme.wifimed                                   = theme.icon_dir .. "/wireless-medium.png"
67 theme.wifinone                                  = theme.icon_dir .. "/wireless-none.png"
68 theme.layout_fairh                              = theme.default_dir.."/layouts/fairhw.png"
69 theme.layout_fairv                              = theme.default_dir.."/layouts/fairvw.png"
70 theme.layout_floating                           = theme.default_dir.."/layouts/floatingw.png"
71 theme.layout_magnifier                          = theme.default_dir.."/layouts/magnifierw.png"
72 theme.layout_max                                = theme.default_dir.."/layouts/maxw.png"
73 theme.layout_fullscreen                         = theme.default_dir.."/layouts/fullscreenw.png"
74 theme.layout_tilebottom                         = theme.default_dir.."/layouts/tilebottomw.png"
75 theme.layout_tileleft                           = theme.default_dir.."/layouts/tileleftw.png"
76 theme.layout_tile                               = theme.default_dir.."/layouts/tilew.png"
77 theme.layout_tiletop                            = theme.default_dir.."/layouts/tiletopw.png"
78 theme.layout_spiral                             = theme.default_dir.."/layouts/spiralw.png"
79 theme.layout_dwindle                            = theme.default_dir.."/layouts/dwindlew.png"
80 theme.layout_cornernw                           = theme.default_dir.."/layouts/cornernww.png"
81 theme.layout_cornerne                           = theme.default_dir.."/layouts/cornernew.png"
82 theme.layout_cornersw                           = theme.default_dir.."/layouts/cornersww.png"
83 theme.layout_cornerse                           = theme.default_dir.."/layouts/cornersew.png"
84 theme.tasklist_plain_task_name                  = true
85 theme.tasklist_disable_icon                     = true
86 theme.useless_gap                               = dpi(10)
87 theme.titlebar_close_button_normal              = theme.default_dir.."/titlebar/close_normal.png"
88 theme.titlebar_close_button_focus               = theme.default_dir.."/titlebar/close_focus.png"
89 theme.titlebar_minimize_button_normal           = theme.default_dir.."/titlebar/minimize_normal.png"
90 theme.titlebar_minimize_button_focus            = theme.default_dir.."/titlebar/minimize_focus.png"
91 theme.titlebar_ontop_button_normal_inactive     = theme.default_dir.."/titlebar/ontop_normal_inactive.png"
92 theme.titlebar_ontop_button_focus_inactive      = theme.default_dir.."/titlebar/ontop_focus_inactive.png"
93 theme.titlebar_ontop_button_normal_active       = theme.default_dir.."/titlebar/ontop_normal_active.png"
94 theme.titlebar_ontop_button_focus_active        = theme.default_dir.."/titlebar/ontop_focus_active.png"
95 theme.titlebar_sticky_button_normal_inactive    = theme.default_dir.."/titlebar/sticky_normal_inactive.png"
96 theme.titlebar_sticky_button_focus_inactive     = theme.default_dir.."/titlebar/sticky_focus_inactive.png"
97 theme.titlebar_sticky_button_normal_active      = theme.default_dir.."/titlebar/sticky_normal_active.png"
98 theme.titlebar_sticky_button_focus_active       = theme.default_dir.."/titlebar/sticky_focus_active.png"
99 theme.titlebar_floating_button_normal_inactive  = theme.default_dir.."/titlebar/floating_normal_inactive.png"
100 theme.titlebar_floating_button_focus_inactive   = theme.default_dir.."/titlebar/floating_focus_inactive.png"
101 theme.titlebar_floating_button_normal_active    = theme.default_dir.."/titlebar/floating_normal_active.png"
102 theme.titlebar_floating_button_focus_active     = theme.default_dir.."/titlebar/floating_focus_active.png"
103 theme.titlebar_maximized_button_normal_inactive = theme.default_dir.."/titlebar/maximized_normal_inactive.png"
104 theme.titlebar_maximized_button_focus_inactive  = theme.default_dir.."/titlebar/maximized_focus_inactive.png"
105 theme.titlebar_maximized_button_normal_active   = theme.default_dir.."/titlebar/maximized_normal_active.png"
106 theme.titlebar_maximized_button_focus_active    = theme.default_dir.."/titlebar/maximized_focus_active.png"
107
108 -- http://fontawesome.io/cheatsheet
109 awful.util.tagnames = { "", "", "", "", "", "", "", "" }
110
111 local markup = lain.util.markup
112
113 -- Clock
114 --os.setlocale(os.getenv("LANG")) -- to localize the clock
115 local mytextclock = wibox.widget.textclock(markup("#FFFFFF", "%a %d %b, %H:%M"))
116 mytextclock.font = theme.font
117 theme.cal = lain.widget.cal({
118     attach_to = { mytextclock },
119     notification_preset = {
120         fg = "#FFFFFF",
121         bg = theme.bg_normal,
122         position = "top_middle",
123         font = "Monospace 10"
124     }
125 })
126
127 -- Battery
128 local baticon = wibox.widget.imagebox(theme.bat000)
129 local battooltip = awful.tooltip({
130     objects = { baticon },
131     margin_leftright = dpi(15),
132     margin_topbottom = dpi(12)
133 })
134 battooltip.wibox.fg = theme.fg_normal
135 battooltip.textbox.font = theme.font
136 battooltip.timeout = 0
137 battooltip:set_shape(function(cr, width, height)
138     gears.shape.infobubble(cr, width, height, corner_radius, arrow_size, width - dpi(35))
139 end)
140 local bat = lain.widget.bat({
141     settings = function()
142         local index, perc = "bat", tonumber(bat_now.perc) or 0
143
144         if perc <= 7 then
145             index = index .. "000"
146         elseif perc <= 20 then
147             index = index .. "020"
148         elseif perc <= 40 then
149             index = index .. "040"
150         elseif perc <= 60 then
151             index = index .. "060"
152         elseif perc <= 80 then
153             index = index .. "080"
154         elseif perc <= 100 then
155             index = index .. "100"
156         end
157
158         if bat_now.ac_status == 1 then
159             index = index .. "charging"
160         end
161
162         baticon:set_image(theme[index])
163         battooltip:set_markup(string.format("\n%s%%, %s", perc, bat_now.time))
164     end
165 })
166
167 -- MPD
168 theme.mpd = lain.widget.mpd({
169     music_dir = "/mnt/storage/Downloads/Music",
170     settings = function()
171         if mpd_now.state == "play" then
172             title = mpd_now.title
173             artist  = "  " .. mpd_now.artist  .. " "
174         elseif mpd_now.state == "pause" then
175             title = "mpd "
176             artist  = "paused "
177         else
178             title  = ""
179             artist = ""
180         end
181
182         widget:set_markup(markup.font(theme.font, title .. markup(theme.fg_focus, artist)))
183     end
184 })
185
186 -- ALSA volume
187 local volicon = wibox.widget.imagebox()
188 theme.volume = lain.widget.alsabar({
189     --togglechannel = "IEC958,3",
190     notification_preset = { font = "Monospace 12", fg = theme.fg_normal },
191     settings = function()
192         local index, perc = "", tonumber(volume_now.level) or 0
193
194         if volume_now.status == "off" then
195             index = "volmutedblocked"
196         else
197             if perc <= 5 then
198                 index = "volmuted"
199             elseif perc <= 25 then
200                 index = "vollow"
201             elseif perc <= 75 then
202                 index = "volmed"
203             else
204                 index = "volhigh"
205             end
206         end
207
208         volicon:set_image(theme[index])
209     end
210 })
211 volicon:buttons(my_table.join (
212           awful.button({}, 1, function()
213             awful.spawn(string.format("%s -e alsamixer", awful.util.terminal))
214           end),
215           awful.button({}, 2, function()
216             os.execute(string.format("%s set %s 100%%", theme.volume.cmd, theme.volume.channel))
217             theme.volume.notify()
218           end),
219           awful.button({}, 3, function()
220             os.execute(string.format("%s set %s toggle", theme.volume.cmd, theme.volume.togglechannel or theme.volume.channel))
221             theme.volume.notify()
222           end),
223           awful.button({}, 4, function()
224             os.execute(string.format("%s set %s 1%%+", theme.volume.cmd, theme.volume.channel))
225             theme.volume.notify()
226           end),
227           awful.button({}, 5, function()
228             os.execute(string.format("%s set %s 1%%-", theme.volume.cmd, theme.volume.channel))
229             theme.volume.notify()
230           end)
231 ))
232
233 -- Wifi carrier and signal strength
234 local wificon = wibox.widget.imagebox(theme.wifidisc)
235 local wifitooltip = awful.tooltip({
236     objects = { wificon },
237     margin_leftright = dpi(15),
238     margin_topbottom = dpi(15)
239 })
240 wifitooltip.wibox.fg = theme.fg_normal
241 wifitooltip.textbox.font = theme.font
242 wifitooltip.timeout = 0
243 wifitooltip:set_shape(function(cr, width, height)
244     gears.shape.infobubble(cr, width, height, corner_radius, arrow_size, width - dpi(120))
245 end)
246 local mywifisig = awful.widget.watch(
247     { awful.util.shell, "-c", "awk 'NR==3 {printf(\"%d-%.0f\\n\",$2, $3*10/7)}' /proc/net/wireless; iw dev wlan0 link" },
248     2,
249     function(widget, stdout)
250         local carrier, perc = stdout:match("(%d)-(%d+)")
251         local tiptext = stdout:gsub("(%d)-(%d+)", ""):gsub("%s+$", "")
252         perc = tonumber(perc)
253
254         if carrier == "1" or not perc then
255             wificon:set_image(theme.wifidisc)
256             wifitooltip:set_markup("No carrier")
257         else
258             if perc <= 5 then
259                 wificon:set_image(theme.wifinone)
260             elseif perc <= 25 then
261                 wificon:set_image(theme.wifilow)
262             elseif perc <= 50 then
263                 wificon:set_image(theme.wifimed)
264             elseif perc <= 75 then
265                 wificon:set_image(theme.wifihigh)
266             else
267                 wificon:set_image(theme.wififull)
268             end
269             wifitooltip:set_markup(tiptext)
270         end
271     end
272 )
273 wificon:connect_signal("button::press", function() awful.spawn(string.format("%s -e wavemon", awful.util.terminal)) end)
274
275 -- Weather
276 theme.weather = lain.widget.weather({
277     city_id = 2643743, -- placeholder (London)
278     notification_preset = { font = "Monospace 10" },
279     settings = function()
280         units = math.floor(weather_now["main"]["temp"])
281         widget:set_markup(" " .. markup.font(theme.font, units .. "°C") .. " ")
282     end
283 })
284
285 -- Launcher
286 local mylauncher = awful.widget.button({image = theme.awesome_icon})
287 mylauncher:connect_signal("button::press", function() awful.util.mymainmenu:toggle() end)
288
289 -- Separators
290 local space = wibox.widget.textbox(" ")
291 local rspace1 = wibox.widget.textbox()
292 local rspace0 = wibox.widget.textbox()
293 local rspace2 = wibox.widget.textbox()
294 local rspace3 = wibox.widget.textbox()
295 local tspace1 = wibox.widget.textbox()
296 tspace1.forced_width = dpi(18)
297 rspace1.forced_width = dpi(16)
298 rspace0.forced_width = dpi(18)
299 rspace2.forced_width = dpi(19)
300 rspace3.forced_width = dpi(21)
301
302 local lspace1 = wibox.widget.textbox()
303 local lspace2 = wibox.widget.textbox()
304 local lspace3 = wibox.widget.textbox()
305 lspace1.forced_height = dpi(18)
306 lspace2.forced_height = dpi(10)
307 lspace3.forced_height = dpi(16)
308
309 local barcolor = gears.color({
310     type  = "linear",
311     from  = { 0, dpi(46) },
312     to    = { dpi(46), dpi(46) },
313     stops = { {0, theme.bg_focus}, {0.9, theme.bg_focus2} }
314 })
315
316 local barcolor2 = gears.color({
317     type  = "linear",
318     from  = { 0, dpi(46) },
319     to    = { dpi(46), dpi(46) },
320     stops = { {0, "#323232"}, {1, theme.bg_normal} }
321 })
322
323 local dockshape = function(cr, width, height)
324     gears.shape.partially_rounded_rect(cr, width, height, false, true, true, false, 6)
325 end
326
327 function theme.vertical_wibox(s)
328     -- Create the vertical wibox
329     s.dockheight = (35 *  s.workarea.height)/100
330
331     s.myleftwibox = wibox({ screen = s, x=0, y=s.workarea.height/2 - s.dockheight/2, width = dpi(6), height = s.dockheight, fg = theme.fg_normal, bg = barcolor2, ontop = true, visible = true, type = "dock" })
332
333     if s.index > 1 and s.myleftwibox.y == 0 then
334         s.myleftwibox.y = screen[1].myleftwibox.y
335     end
336
337     -- Add widgets to the vertical wibox
338     s.myleftwibox:setup {
339         layout = wibox.layout.align.vertical,
340         {
341             layout = wibox.layout.fixed.vertical,
342             lspace1,
343             s.mytaglist,
344             lspace2,
345             s.layoutb,
346             wibox.container.margin(mylauncher, dpi(5), dpi(8), dpi(13), dpi(0)),
347         },
348     }
349
350     -- Add toggling functionalities
351     s.docktimer = gears.timer{ timeout = 2 }
352     s.docktimer:connect_signal("timeout", function()
353         local s = awful.screen.focused()
354         s.myleftwibox.width = dpi(9)
355         s.layoutb.visible = false
356         mylauncher.visible = false
357         if s.docktimer.started then
358             s.docktimer:stop()
359         end
360     end)
361     tag.connect_signal("property::selected", function(t)
362         local s = t.screen or awful.screen.focused()
363         s.myleftwibox.width = dpi(38)
364         s.layoutb.visible = true
365         mylauncher.visible = true
366         gears.surface.apply_shape_bounding(s.myleftwibox, dockshape)
367         if not s.docktimer.started then
368             s.docktimer:start()
369         end
370     end)
371
372     s.myleftwibox:connect_signal("mouse::leave", function()
373         local s = awful.screen.focused()
374         s.myleftwibox.width = dpi(9)
375         s.layoutb.visible = false
376         mylauncher.visible = false
377     end)
378
379     s.myleftwibox:connect_signal("mouse::enter", function()
380         local s = awful.screen.focused()
381         s.myleftwibox.width = dpi(38)
382         s.layoutb.visible = true
383         mylauncher.visible = true
384         gears.surface.apply_shape_bounding(s.myleftwibox, dockshape)
385     end)
386 end
387
388
389 function theme.at_screen_connect(s)
390     -- Quake application
391     s.quake = lain.util.quake({ app = awful.util.terminal, border = theme.border_width })
392
393     -- If wallpaper is a function, call it with the screen
394     local wallpaper = theme.wallpaper
395     if type(wallpaper) == "function" then
396         wallpaper = wallpaper(s)
397     end
398     gears.wallpaper.maximized(wallpaper, s, true)
399
400     -- Tags
401     awful.tag(awful.util.tagnames, s, awful.layout.layouts)
402
403     -- Create a promptbox for each screen
404     s.mypromptbox = awful.widget.prompt()
405     s.mypromptbox.bg = "#00000000"
406
407     -- Create an imagebox widget which will contains an icon indicating which layout we're using.
408     -- We need one layoutbox per screen.
409     s.mylayoutbox = awful.widget.layoutbox(s)
410     s.mylayoutbox:buttons(my_table.join(
411                            awful.button({}, 1, function () awful.layout.inc( 1) end),
412                            awful.button({}, 2, function () awful.layout.set( awful.layout.layouts[1] ) end),
413                            awful.button({}, 3, function () awful.layout.inc(-1) end),
414                            awful.button({}, 4, function () awful.layout.inc( 1) end),
415                            awful.button({}, 5, function () awful.layout.inc(-1) end)))
416     s.layoutb = wibox.container.margin(s.mylayoutbox, dpi(8), dpi(11), dpi(3), dpi(3))
417
418     -- Create a taglist widget
419     s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, awful.util.taglist_buttons, {
420         font = theme.taglist_font,
421         shape = gears.shape.rectangle,
422         spacing = dpi(10),
423         square_unsel = theme.square_unsel,
424         bg_focus = barcolor
425     }, nil, wibox.layout.fixed.vertical())
426
427     -- Create a tasklist widget
428     s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.focused, awful.util.tasklist_buttons, { bg_focus = "#00000000" })
429
430     -- Create the wibox
431     s.mywibox = awful.wibar({ position = "top", screen = s, height = dpi(25), bg = gears.color.create_png_pattern(theme.panelbg) })
432
433     -- Add widgets to the wibox
434     s.mywibox:setup {
435         layout = wibox.layout.align.horizontal,
436         expand = "none",
437         { -- Left widgets
438             layout = wibox.layout.fixed.horizontal,
439             s.mypromptbox,
440             tspace1,
441             s.mytasklist,
442         },
443         { -- Middle widgets
444             layout = wibox.layout.flex.horizontal,
445             max_widget_size = 1500,
446             mytextclock
447         },
448         { -- Right widgets
449             layout = wibox.layout.fixed.horizontal,
450             wibox.widget { nil, nil, theme.mpd.widget, layout = wibox.layout.align.horizontal },
451             rspace0,
452             theme.weather.icon,
453             theme.weather.widget,
454             rspace1,
455             wificon,
456             rspace0,
457             volicon,
458             rspace2,
459             baticon,
460             rspace3,
461             wibox.widget.systray(),
462         },
463     }
464
465     gears.timer.delayed_call(theme.vertical_wibox, s)
466 end
467
468 return theme