diff --git a/default.svg b/default.svg new file mode 100644 index 0000000..347cc93 --- /dev/null +++ b/default.svg @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..cbcd8db --- /dev/null +++ b/init.lua @@ -0,0 +1,186 @@ +local awful = require("awful") +local wibox = require("wibox") +local gears = require("gears") +local beautiful = require("beautiful") +local menubar = require("menubar") +local naughty = require "naughty" +local cairo = require("lgi").cairo +local Rsvg = require("lgi").Rsvg +local longpress = require("awesome-longpress") +local launcherpopup = { + buttonsize = 128, + spacing = 5, + iconPath = gears.filesystem.get_configuration_dir() .. "/awesome-launcherpopup/", + updateOnSpawn = true, + font = "sans", + fontSize = 15, + applications = {}, + allInstances = {} +} + +function launcherpopup.update() + naughty.notify({text="started update"}) + menubar.menu_gen.generate(function(rv) + launcherpopup.applications = rv + for k,v in pairs(launcherpopup.allInstances) do + if k and v then + w,e = pcall(v.populateMenu) + if not w then naughty.notify{text=e} end + end + end + end) +end + +local function tryLoadIcon(icon) + local img = icon + if dentry.icon:match("%.([^%.]+)$") == "svg" then + naughty.notify{text="is svg"} + img = cairo.ImageSurface(cairo.Format.ARGB32,launcherpopup.buttonsize,launcherpopup.buttonsize) + local cr = cairo.Context(img) + Rsvg.Handle.new_from_file(dentry.icon):render_cairo(cr) + end + return img +end + +local function getFont(scale) + return string.format("%s %d",launcherpopup.font,launcherpopup.fontSize * (scale or 1)) +end + +function launcherpopup.new(s) + local menuStart = 1 + local launcherWidget = wibox.widget{ + layout = wibox.layout.fixed.vertical, + spacing = launcherpopup.spacing + } + local launcher = awful.popup{ + layout = wibox.layout.fixed.vertical, + widget = launcherWidget, + border_color = beautiful.border_focus, + border_width = 2, + ontop = true, + placement = awful.placement.centered, + visible = false, + screen = s, + } + local launcherButtons = wibox.widget{ + layout = wibox.layout.grid.vertical, + spacing = launcherpopup.spacing + } + local launcherNav = wibox.widget{ + layout = wibox.layout.ratio.horizontal, + forced_width = math.floor((s.geometry.width) / (launcherpopup.buttonsize + launcherpopup.spacing * 2)) * (launcherpopup.buttonsize + launcherpopup.spacing) + } + local launcherList = wibox.widget{ + layout = wibox.layout.grid, + spacing = launcherpopup.spacing + } + launcherWidget:add(launcherList) + launcherWidget:add(launcherNav) + local launcherNextPage = wibox.widget{ + widget = wibox.widget.imagebox, + image = launcherpopup.iconPath .. "/next.svg", + forced_width=launcherpopup.buttonsize * 0.75, + forced_height=launcherpopup.buttonsize * 0.75 + } + local launcherPreviousPage = wibox.widget{ + widget = wibox.widget.imagebox, + image = launcherpopup.iconPath .. "/previous.svg", + forced_width=launcherpopup.buttonsize * 0.75, + forced_height=launcherpopup.buttonsize * 0.75 + } + launcherNav:add( + wibox.container.place(launcherPreviousPage,"left","top"), + wibox.container.place(launcherNextPage,"right","top")) + local function fillMenu() + launcherList:reset() + local maxRows = math.floor(s.geometry.height / (launcherpopup.buttonsize * 1.5 + launcherpopup.spacing * 2)) - 2 + local maxColumns = math.floor((s.geometry.width) / (launcherpopup.buttonsize + launcherpopup.spacing * 2)) + local maxEntries = maxRows * maxColumns + local x,y = 1,1 + for y = 1, maxRows do + for x = 1, maxColumns do + local dentry = launcherpopup.applications[(menuStart - 1) + (y-1)*maxColumns + x] + if not dentry then dentry = {icon="",name=""} end + local mwidget = wibox.widget{ + layout = wibox.layout.fixed.vertical + } + local mwicon = wibox.widget{ + image = dentry.icon or launcherpopup.iconPath .. "/default.svg", + widget = wibox.widget.imagebox, + forced_width = launcherpopup.buttonsize, + forced_height = launcherpopup.buttonsize + } + mwidget:add(mwicon) + local mwtext = wibox.container.constraint(wibox.widget{ + widget = wibox.widget.textbox, + valign = center, + align = center, + font = getFont(), + text = dentry.name + },"exact",launcherpopup.buttonsize,launcherpopup.buttonsize * 0.5) + mwidget:add(mwtext) + longpress.add(mwidget,function() + if dentry.cmdline then + awful.spawn(dentry.cmdline) + launcher:hide() + end + end) + launcherList:add_widget_at(wibox.container.constraint(mwidget,"max",launcherpopup.buttonsize,launcherpopup.buttonsize*1.5),y,x) + end + end + end + local function goToEntry(n) + local maxRows = math.floor(s.geometry.height / (launcherpopup.buttonsize * 1.5 + launcherpopup.spacing * 2)) - 2 + local maxColumns = math.floor((s.geometry.width) / (launcherpopup.buttonsize + launcherpopup.spacing * 2)) + local maxEntries = maxRows * maxColumns + menuStart = n + if menuStart < 1 then menuStart = (math.floor(#launcherpopup.applications / maxEntries) * maxEntries) + 1 end + if menuStart > #launcherpopup.applications then menuStart = 1 end + fillMenu() + end + longpress.add(launcherNextPage,function() + goToEntry(menuStart + ((math.floor(s.geometry.height / (launcherpopup.buttonsize * 1.5 + launcherpopup.spacing * 2)) - 2) * math.floor((s.geometry.width) / (launcherpopup.buttonsize + launcherpopup.spacing * 2)))) + end, + function() + goToEntry(#launcherpopup.applications) + end) + longpress.add(launcherPreviousPage,function() + goToEntry(menuStart - ((math.floor(s.geometry.height / (launcherpopup.buttonsize * 1.5 + launcherpopup.spacing * 2)) - 2) * math.floor((s.geometry.width) / (launcherpopup.buttonsize + launcherpopup.spacing * 2)))) + end, + function() + goToEntry(1) + end) + function launcher.populateMenu() + fillMenu() + end + function launcher.addButton(icon, fn) + local newButton = awful.widget.button{ + image = launcherpopup.iconPath .. "/" .. icon + } + newButton:set_forced_width(launcherpopup.buttonsize) + newButton:set_forced_height(launcherpopup.buttonsize) + newButton:buttons(gears.table.join( + newButton:buttons(), + awful.button({}, 1, nil, function() + fn() + launcher:hide() + end) + )) + launcherButtons:add(newButton) + end + + function launcher.show(self) + self.visible = true + end + function launcher.hide(self) + self.visible = false + end + function launcher.toggle(self) + self.visible = not self.visible + end + launcherpopup.allInstances[#launcherpopup.allInstances+1] = launcher + launcherpopup.update() + return launcher +end + +return launcherpopup diff --git a/next.svg b/next.svg new file mode 100644 index 0000000..cfe6f2f --- /dev/null +++ b/next.svg @@ -0,0 +1,151 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previous.svg b/previous.svg new file mode 100644 index 0000000..e55cb62 --- /dev/null +++ b/previous.svg @@ -0,0 +1,151 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +