aboutsummaryrefslogtreecommitdiff
path: root/.config/awesome/ui/fresnel/init.lua
diff options
context:
space:
mode:
Diffstat (limited to '.config/awesome/ui/fresnel/init.lua')
-rw-r--r--.config/awesome/ui/fresnel/init.lua276
1 files changed, 276 insertions, 0 deletions
diff --git a/.config/awesome/ui/fresnel/init.lua b/.config/awesome/ui/fresnel/init.lua
new file mode 100644
index 0000000..cf1357a
--- /dev/null
+++ b/.config/awesome/ui/fresnel/init.lua
@@ -0,0 +1,276 @@
+local awful = require "awful"
+local gtable = require "gears.table"
+local gdebug = require "gears.debug"
+local gfs = require "gears.filesystem"
+local h = require "misc.helpers"
+local cfg = require "misc.cfg"
+local vars = require "misc.vars"
+local wibox = require "wibox"
+local beautiful = require "beautiful"
+local rubato = require "lib.rubato"
+local al_prompt = require "lib.bling.widget.app_launcher.prompt"
+local btn = awful.button.names
+
+package.cpath = package.cpath .. ";" .. gfs.get_configuration_dir() .. "ui/fresnel/lenses/target/debug/lib?.so"
+
+local lenses = require "lenses"
+local max_entries = 10
+
+local fresnel = {}
+
+fresnel._toggled = false
+fresnel._entries_exec = {}
+fresnel._entries_offset = 0
+fresnel._entries_count = 0
+fresnel._visible_entries = 0
+fresnel._selected_index = 1
+
+function fresnel:_exec_entry(entry_index)
+ local exec = self._entries_exec[entry_index]
+ if type(exec) ~= "userdata" then
+ awful.spawn((exec[2] and cfg.terminal .. " -e " or "") .. exec[1])
+ end
+end
+
+function fresnel:_update(query, scrolled)
+ query = query or ""
+ scrolled = scrolled or false
+
+ if not scrolled then
+ self._selected_index = 1
+ self._entries_offset = 0
+ end
+
+ local layout = self._widget.widget:get_children_by_id("entry_layout")[1]
+ local status = self._widget.widget:get_children_by_id("status")[1]
+ local all_providers = {}
+ local entries_count = 0
+
+ self._entries_exec = {}
+ layout:reset()
+
+ for _, provider in h.opairs(lenses) do
+ local entries = provider(query)
+
+ table.sort(entries, function(a, b)
+ return a.message < b.message
+ end)
+
+ all_providers = gtable.join(all_providers, entries)
+ end
+
+ self._entries_count = #all_providers
+
+ for i, entry in ipairs(all_providers) do
+ if i <= self._entries_offset then
+ goto continue
+ end
+ if entries_count == max_entries then break end
+ table.insert(self._entries_exec, entry.exec)
+
+ local entry_widget = wibox.widget {
+ widget = wibox.container.background,
+ shape = vars.shape,
+ {
+ widget = wibox.container.margin,
+ margins = vars.padding,
+ {
+ widget = wibox.container.constraint,
+ strategy = "max",
+ height = vars.char_height,
+ {
+ {
+ widget = wibox.container.background,
+ fg = vars.colors.dim.fg,
+ {
+ widget = wibox.widget.textbox,
+ text = entry.provider .. " | "
+ }
+ },
+ {
+ widget = wibox.widget.textbox,
+ text = entry.message
+ },
+ spacing = vars.padding,
+ layout = wibox.layout.fixed.horizontal
+ }
+ }
+ },
+ buttons = {
+ awful.button {
+ modifiers = {},
+ button = btn.LEFT,
+ on_press = function()
+ self:_exec_entry(i)
+ end
+ }
+ },
+ _selected = false
+ }
+
+ if self._selected_index + self._entries_offset == i then
+ entry_widget._selected = true
+ entry_widget.bg = vars.colors.black
+ end
+
+ entry_widget:connect_signal("mouse::enter", function()
+ if entry_widget._selected == true then return end
+ entry_widget.bg = vars.colors.black
+ end)
+
+ entry_widget:connect_signal("mouse::leave", function()
+ if entry_widget._selected == true then return end
+ entry_widget.bg = vars.colors.bg
+ end)
+
+ layout:add(entry_widget)
+
+ entries_count = entries_count + 1
+ self._visible_entries = entries_count
+ ::continue::
+ end
+
+ status.text = self._entries_offset + self._selected_index .. "/" .. self._entries_count
+end
+
+fresnel._text = ""
+fresnel._prompt = al_prompt {
+ prompt = "",
+ reset_on_stop = true,
+ ul_cursor = "low",
+ bg_cursor = vars.colors.black,
+ changed_callback = function(text)
+ if fresnel._text == text then return end
+ if fresnel._toggled == false then return end
+ fresnel:_update(text)
+ fresnel._text = text
+ end,
+ keypressed_callback = function(mod, key)
+ if key == "Escape" or key == " " and mod.Mod4 then
+ fresnel:hide()
+ elseif key == "Return" then
+ fresnel:_exec_entry(fresnel._selected_index)
+ fresnel:hide()
+ elseif key == "Up" then
+ local next_index = fresnel._selected_index - 1
+ if next_index < 1 and fresnel._entries_offset == 0 then
+ return
+ elseif next_index < 1 and fresnel._entries_offset > 0 then
+ fresnel._entries_offset = fresnel._entries_offset - 1
+ else
+ fresnel._selected_index = next_index
+ end
+
+ fresnel:_update(fresnel._text, true)
+ elseif key == "Down" then
+ local next_index = fresnel._selected_index + 1
+ if next_index > fresnel._visible_entries and fresnel._entries_offset + fresnel._visible_entries == fresnel._entries_count then
+ return
+ elseif next_index > fresnel._visible_entries and fresnel._entries_offset + fresnel._visible_entries < fresnel._entries_count then
+ fresnel._entries_offset = fresnel._entries_offset + 1
+ else
+ fresnel._selected_index = next_index
+ end
+
+ fresnel:_update(fresnel._text, true)
+ end
+ end
+}
+
+fresnel._widget = h.popup {
+ visible = false,
+ ontop = true,
+ placement = function(d)
+ awful.placement.top(d, {
+ margins = {
+ top = beautiful.useless_gap * 2
+ }
+ })
+ end,
+ minimum_width = screen[1].geometry.width / 2,
+ maximum_width = screen[1].geometry.width / 2,
+ widget = {
+ {
+ widget = wibox.container.background,
+ bg = vars.colors.black,
+ fg = vars.colors.dim.fg,
+ shape = vars.shape,
+ {
+ widget = wibox.container.margin,
+ margins = vars.padding,
+ {
+ {
+ widget = wibox.widget.textbox,
+ text = ">"
+ },
+ {
+ widget = wibox.container.margin,
+ margins = {
+ left = vars.padding,
+ right = vars.padding
+ },
+ {
+ widget = wibox.container.constraint,
+ strategy = "max",
+ height = vars.char_height,
+ {
+ widget = wibox.container.background,
+ fg = vars.colors.fg,
+ fresnel._prompt.textbox
+ }
+ }
+ },
+ {
+ widget = wibox.widget.textbox,
+ text = "0/0",
+ id = "status"
+ },
+ layout = wibox.layout.align.horizontal
+ }
+ }
+ },
+ {
+ widget = wibox.container.margin,
+ margins = {
+ top = vars.padding
+ },
+ {
+ spacing = vars.padding,
+ layout = wibox.layout.fixed.vertical,
+ id = "entry_layout"
+ }
+ },
+ layout = wibox.layout.align.vertical
+ }
+}
+fresnel._widget.maximum_height = vars.big_padding * 2 + (vars.padding * 2 + vars.char_height) * (1 + 10) + vars.padding + vars.padding * 9
+
+function fresnel:show()
+ self._toggled = true
+ self._timed.target = 1
+ self:_update()
+ self._prompt:start()
+end
+
+function fresnel:hide()
+ self._toggled = false
+ self._timed.target = 0
+ self._prompt:stop()
+end
+
+fresnel._timed = rubato.timed {
+ duration = vars.anim_duration,
+ intro = vars.anim_intro,
+ pos = 0,
+ subscribed = function(pos)
+ fresnel._widget.opacity = pos
+
+ if pos == 0 then
+ fresnel._widget.visible = false
+ else
+ fresnel._widget.visible = true
+ end
+ end
+}
+
+return fresnel