Skip to content

Commit 907230e

Browse files
authored
add: lua gtk3 examples (#156)
1 parent 4d6d855 commit 907230e

File tree

26 files changed

+1000
-69
lines changed

26 files changed

+1000
-69
lines changed

docs/guide/getting-started/supported-languages.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ Examples:
3939
- [Simple Bar](https://github.com/Aylur/astal/tree/main/examples/gtk3/lua/simple-bar)
4040
![simple-bar](https://github.com/user-attachments/assets/a306c864-56b7-44c4-8820-81f424f32b9b)
4141

42+
- [Notification Popups](https://github.com/Aylur/astal/tree/main/examples/lua/notifications)
43+
![notification-popups](https://github.com/user-attachments/assets/0df0eddc-5c74-4af0-a694-48dc8ec6bb44)
44+
45+
- [Applauncher](https://github.com/Aylur/astal/tree/main/examples/lua/applauncher)
46+
![launcher](https://github.com/user-attachments/assets/2695e3bb-dff4-478a-b392-279fe638bfd3)
47+
48+
- [Media Player](https://github.com/Aylur/astal/tree/main/examples/lua/media-player)
49+
![media-player](https://github.com/user-attachments/assets/891e9706-74db-4505-bd83-c3628d7b4fd0)
50+
4251
## Python
4352

4453
There is a WIP [package for python](https://github.com/aylur/astal/tree/feat/python),

docs/guide/lua/binding.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,13 @@ local Gtk = require("astal.gtk3").Gtk
6868
local Variable = require("astal.variable")
6969

7070
---@param initial table
71+
---@return varmap
7172
return function(initial)
7273
local map = initial
73-
local var = Variable()
74+
local var = Variable.new({})
7475

7576
local function notify()
76-
local arr
77+
local arr = {}
7778
for _, value in pairs(map) do
7879
table.insert(arr, value)
7980
end
@@ -90,7 +91,13 @@ return function(initial)
9091

9192
notify() -- init
9293

93-
return {
94+
---@class varmap
95+
---@field set fun(key: any, value: any): nil
96+
---@field delete fun(key: any): nil
97+
---@field get fun(): any
98+
---@field subscribe fun(callback: function): function
99+
---@overload fun(): Binding
100+
return setmetatable({
94101
set = function(key, value)
95102
delete(key)
96103
map[key] = value
@@ -106,7 +113,11 @@ return function(initial)
106113
subscribe = function(callback)
107114
return var:subscribe(callback)
108115
end,
109-
}
116+
}, {
117+
__call = function()
118+
return var()
119+
end,
120+
})
110121
end
111122
```
112123

@@ -130,7 +141,7 @@ function MappedBox()
130141
map.delete(id)
131142
end)
132143
end,
133-
bind(map):as(function (arr)
144+
map():as(function(arr)
134145
-- can be sorted here
135146
return arr
136147
end),

docs/guide/lua/examples.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,12 @@
22

33
## [Simple Bar](https://github.com/Aylur/astal/tree/main/examples/gtk3/lua/simple-bar)
44
![simple-bar](https://github.com/user-attachments/assets/a306c864-56b7-44c4-8820-81f424f32b9b)
5+
6+
### [Notification Popups](https://github.com/Aylur/astal/tree/main/examples/gtk3/lua/notifications)
7+
![notification-popups](https://github.com/user-attachments/assets/0df0eddc-5c74-4af0-a694-48dc8ec6bb44)
8+
9+
### [Applauncher](https://github.com/Aylur/astal/tree/main/examples/gtk3/lua/applauncher)
10+
![launcher](https://github.com/user-attachments/assets/2695e3bb-dff4-478a-b392-279fe638bfd3)
11+
12+
### [Media Player](https://github.com/Aylur/astal/tree/main/examples/gtk3/lua/media-player)
13+
![media-player](https://github.com/user-attachments/assets/891e9706-74db-4505-bd83-c3628d7b4fd0)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Applauncher
2+
3+
![launcher](https://github.com/user-attachments/assets/2695e3bb-dff4-478a-b392-279fe638bfd3)
4+
5+
Using [Apps](https://aylur.github.io/astal/guide/libraries/apps).
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
local astal = require("astal")
2+
local App = require("astal.gtk3.app")
3+
4+
local AppLauncher = require("widget.Applauncher")
5+
local src = require("lib").src
6+
7+
local scss = src("style.scss")
8+
local css = "/tmp/style.css"
9+
10+
astal.exec("sass " .. scss .. " " .. css)
11+
12+
App:start({
13+
instance_name = "launcher",
14+
css = css,
15+
main = AppLauncher,
16+
})

examples/gtk3/lua/applauncher/lib.lua

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
local M = {}
2+
3+
function M.src(path)
4+
local str = debug.getinfo(2, "S").source:sub(2)
5+
local src = str:match("(.*/)") or str:match("(.*\\)") or "./"
6+
return src .. path
7+
end
8+
9+
---@generic T, R
10+
---@param array T[]
11+
---@param func fun(T, i: integer): R
12+
---@return R[]
13+
function M.map(array, func)
14+
local new_arr = {}
15+
for i, v in ipairs(array) do
16+
new_arr[i] = func(v, i)
17+
end
18+
return new_arr
19+
end
20+
21+
---@generic T
22+
---@param array T[]
23+
---@param start integer
24+
---@param stop? integer
25+
---@return T[]
26+
function M.slice(array, start, stop)
27+
local new_arr = {}
28+
29+
stop = stop or #array
30+
31+
for i = start, stop do
32+
table.insert(new_arr, array[i])
33+
end
34+
35+
return new_arr
36+
end
37+
38+
return M
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@use "./widget/Applauncher.scss"
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
local astal = require("astal")
2+
3+
local Apps = astal.require("AstalApps")
4+
local App = require("astal.gtk3.app")
5+
local Astal = require("astal.gtk3").Astal
6+
local Gdk = require("astal.gtk3").Gdk
7+
local Variable = astal.Variable
8+
local Widget = require("astal.gtk3.widget")
9+
10+
local slice = require("lib").slice
11+
local map = require("lib").map
12+
13+
local MAX_ITEMS = 8
14+
15+
local function hide()
16+
local launcher = App:get_window("launcher")
17+
if launcher then launcher:hide() end
18+
end
19+
20+
local function AppButton(app)
21+
return Widget.Button({
22+
class_name = "AppButton",
23+
on_clicked = function()
24+
hide()
25+
app:launch()
26+
end,
27+
Widget.Box({
28+
Widget.Icon({ icon = app.icon_name }),
29+
Widget.Box({
30+
valign = "CENTER",
31+
vertical = true,
32+
Widget.Label({
33+
class_name = "name",
34+
wrap = true,
35+
xalign = 0,
36+
label = app.name,
37+
}),
38+
app.description and Widget.Label({
39+
class_name = "description",
40+
wrap = true,
41+
xalign = 0,
42+
label = app.description,
43+
}),
44+
}),
45+
}),
46+
})
47+
end
48+
49+
return function()
50+
local apps = Apps.Apps()
51+
52+
local text = Variable("")
53+
local list = text(
54+
function(t) return slice(apps:fuzzy_query(t), 1, MAX_ITEMS) end
55+
)
56+
57+
local on_enter = function()
58+
local found = apps:fuzzy_query(text:get())[1]
59+
if found then
60+
found:launch()
61+
hide()
62+
end
63+
end
64+
65+
return Widget.Window({
66+
name = "launcher",
67+
anchor = Astal.WindowAnchor.TOP + Astal.WindowAnchor.BOTTOM,
68+
exclusivity = "IGNORE",
69+
keymode = "ON_DEMAND",
70+
application = App,
71+
on_show = function() text:set("") end,
72+
on_key_press_event = function(self, event)
73+
if event.keyval == Gdk.KEY_Escape then self:hide() end
74+
end,
75+
Widget.Box({
76+
Widget.EventBox({
77+
expand = true,
78+
on_click = hide,
79+
width_request = 4000,
80+
}),
81+
Widget.Box({
82+
hexpand = false,
83+
vertical = true,
84+
Widget.EventBox({ on_click = hide, height_request = 100 }),
85+
Widget.Box({
86+
vertical = true,
87+
width_request = 500,
88+
class_name = "Applauncher",
89+
Widget.Entry({
90+
placeholder_text = "Search",
91+
text = text(),
92+
on_changed = function(self) text:set(self.text) end,
93+
on_activate = on_enter,
94+
}),
95+
Widget.Box({
96+
spacing = 6,
97+
vertical = true,
98+
list:as(function(l) return map(l, AppButton) end),
99+
}),
100+
Widget.Box({
101+
halign = "CENTER",
102+
class_name = "not-found",
103+
vertical = true,
104+
visible = list:as(function(l) return #l == 0 end),
105+
Widget.Icon({ icon = "system-search-symbolic" }),
106+
Widget.Label({ label = "No match found" }),
107+
}),
108+
}),
109+
Widget.EventBox({ expand = true, on_click = hide }),
110+
}),
111+
Widget.EventBox({
112+
width_request = 4000,
113+
expand = true,
114+
on_click = hide,
115+
}),
116+
}),
117+
})
118+
end
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
@use 'sass:string';
2+
3+
@function gtkalpha($c, $a) {
4+
@return string.unquote('alpha(#{$c},#{$a})');
5+
}
6+
7+
// https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gtk/theme/Adwaita/_colors-public.scss
8+
$fg-color: #{'@theme_fg_color'};
9+
$bg-color: #{'@theme_bg_color'};
10+
11+
window#launcher {
12+
all: unset;
13+
14+
box.Applauncher {
15+
background-color: $bg-color;
16+
border-radius: 11px;
17+
margin: 1rem;
18+
padding: 0.8rem;
19+
box-shadow: 2px 3px 8px 0 gtkalpha(black, 0.4);
20+
21+
entry {
22+
margin-bottom: 0.8rem;
23+
}
24+
25+
button {
26+
min-width: 0;
27+
min-height: 0;
28+
padding: 0.5rem;
29+
30+
icon {
31+
font-size: 3em;
32+
margin-right: 0.3rem;
33+
}
34+
35+
label.name {
36+
font-weight: bold;
37+
font-size: 1.1em;
38+
}
39+
40+
label.description {
41+
color: gtkalpha($fg-color, 0.8);
42+
}
43+
}
44+
45+
box.not-found {
46+
padding: 1rem;
47+
48+
icon {
49+
font-size: 6em;
50+
color: gtkalpha($fg-color, 0.7);
51+
}
52+
53+
label {
54+
color: gtkalpha($fg-color, 0.9);
55+
font-size: 1.2em;
56+
}
57+
}
58+
}
59+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Media Player
2+
3+
![mpris](https://github.com/user-attachments/assets/891e9706-74db-4505-bd83-c3628d7b4fd0)
4+
5+
Using [Mpris](https://aylur.github.io/astal/guide/libraries/mpris).

0 commit comments

Comments
 (0)