summaryrefslogtreecommitdiff
path: root/examples/gtk3/lua/applauncher/widget/Applauncher.lua
blob: 78f7fa5499922cdb4ab820f783b25bbda39b49cf (plain)
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
local astal = require("astal")

local Apps = astal.require("AstalApps")
local App = require("astal.gtk3.app")
local Astal = require("astal.gtk3").Astal
local Gdk = require("astal.gtk3").Gdk
local Variable = astal.Variable
local Widget = require("astal.gtk3.widget")

local slice = require("lib").slice
local map = require("lib").map

local MAX_ITEMS = 8

local function hide()
	local launcher = App:get_window("launcher")
	if launcher then launcher:hide() end
end

local function AppButton(app)
	return Widget.Button({
		class_name = "AppButton",
		on_clicked = function()
			hide()
			app:launch()
		end,
		Widget.Box({
			Widget.Icon({ icon = app.icon_name }),
			Widget.Box({
				valign = "CENTER",
				vertical = true,
				Widget.Label({
					class_name = "name",
					wrap = true,
					xalign = 0,
					label = app.name,
				}),
				app.description and Widget.Label({
					class_name = "description",
					wrap = true,
					xalign = 0,
					label = app.description,
				}),
			}),
		}),
	})
end

return function()
	local apps = Apps.Apps()

	local text = Variable("")
	local list = text(
		function(t) return slice(apps:fuzzy_query(t), 1, MAX_ITEMS) end
	)

	local on_enter = function()
		local found = apps:fuzzy_query(text:get())[1]
		if found then
			found:launch()
			hide()
		end
	end

	return Widget.Window({
		name = "launcher",
		anchor = Astal.WindowAnchor.TOP + Astal.WindowAnchor.BOTTOM,
		exclusivity = "IGNORE",
		keymode = "ON_DEMAND",
		application = App,
		on_show = function() text:set("") end,
		on_key_press_event = function(self, event)
			if event.keyval == Gdk.KEY_Escape then self:hide() end
		end,
		Widget.Box({
			Widget.EventBox({
				expand = true,
				on_click = hide,
				width_request = 4000,
			}),
			Widget.Box({
				hexpand = false,
				vertical = true,
				Widget.EventBox({ on_click = hide, height_request = 100 }),
				Widget.Box({
					vertical = true,
					width_request = 500,
					class_name = "Applauncher",
					Widget.Entry({
						placeholder_text = "Search",
						text = text(),
						on_changed = function(self) text:set(self.text) end,
						on_activate = on_enter,
					}),
					Widget.Box({
						spacing = 6,
						vertical = true,
						list:as(function(l) return map(l, AppButton) end),
					}),
					Widget.Box({
						halign = "CENTER",
						class_name = "not-found",
						vertical = true,
						visible = list:as(function(l) return #l == 0 end),
						Widget.Icon({ icon = "system-search-symbolic" }),
						Widget.Label({ label = "No match found" }),
					}),
				}),
				Widget.EventBox({ expand = true, on_click = hide }),
			}),
			Widget.EventBox({
				width_request = 4000,
				expand = true,
				on_click = hide,
			}),
		}),
	})
end