🔧 - This commit adds example configurations for several features and widgets, including app launcher, status bar, bluetooth widget, desktop widget, icon browser, notifications, and side panel.
This commit is contained in:
14 files changed
+1596
-12
No files matched your search
@@ -0,0 +1,162 @@
|
||||
from typing import cast
|
||||
|
||||
from fabric import Application
|
||||
from fabric.widgets.box import Box
|
||||
from fabric.widgets.label import Label
|
||||
from fabric.widgets.image import Image
|
||||
from fabric.widgets.button import Button
|
||||
from fabric.widgets.wayland import WaylandWindow
|
||||
from fabric.notifications import Notifications, Notification
|
||||
from fabric.utils import invoke_repeater, get_relative_path
|
||||
|
||||
from gi.repository import GdkPixbuf
|
||||
|
||||
|
||||
NOTIFICATION_WIDTH = 360
|
||||
NOTIFICATION_IMAGE_SIZE = 64
|
||||
NOTIFICATION_TIMEOUT = 10 * 1000 # 10 seconds
|
||||
|
||||
|
||||
class NotificationWidget(Box):
|
||||
def __init__(self, notification: Notification, **kwargs):
|
||||
super().__init__(
|
||||
size=(NOTIFICATION_WIDTH, -1),
|
||||
name="notification",
|
||||
spacing=8,
|
||||
orientation="v",
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
self._notification = notification
|
||||
|
||||
body_container = Box(spacing=4, orientation="h")
|
||||
|
||||
if image_pixbuf := self._notification.image_pixbuf:
|
||||
body_container.add(
|
||||
Image(
|
||||
pixbuf=image_pixbuf.scale_simple(
|
||||
NOTIFICATION_IMAGE_SIZE,
|
||||
NOTIFICATION_IMAGE_SIZE,
|
||||
GdkPixbuf.InterpType.BILINEAR,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
body_container.add(
|
||||
Box(
|
||||
spacing=4,
|
||||
orientation="v",
|
||||
children=[
|
||||
# a box for holding both the "summary" label and the "close" button
|
||||
Box(
|
||||
orientation="h",
|
||||
children=[
|
||||
Label(
|
||||
label=self._notification.summary,
|
||||
ellipsization="middle",
|
||||
)
|
||||
.build()
|
||||
.add_style_class("summary")
|
||||
.unwrap(),
|
||||
],
|
||||
h_expand=True,
|
||||
v_expand=True,
|
||||
)
|
||||
# add the "close" button
|
||||
.build(
|
||||
lambda box, _: box.pack_end(
|
||||
Button(
|
||||
image=Image(
|
||||
icon_name="close-symbolic",
|
||||
icon_size=18,
|
||||
),
|
||||
v_align="center",
|
||||
h_align="end",
|
||||
on_clicked=lambda *_: self._notification.close(),
|
||||
),
|
||||
False,
|
||||
False,
|
||||
0,
|
||||
)
|
||||
),
|
||||
Label(
|
||||
label=self._notification.body,
|
||||
line_wrap="word-char",
|
||||
v_align="start",
|
||||
h_align="start",
|
||||
)
|
||||
.build()
|
||||
.add_style_class("body")
|
||||
.unwrap(),
|
||||
],
|
||||
h_expand=True,
|
||||
v_expand=True,
|
||||
)
|
||||
)
|
||||
|
||||
self.add(body_container)
|
||||
|
||||
if actions := self._notification.actions:
|
||||
self.add(
|
||||
Box(
|
||||
spacing=4,
|
||||
orientation="h",
|
||||
children=[
|
||||
Button(
|
||||
h_expand=True,
|
||||
v_expand=True,
|
||||
label=action.label,
|
||||
on_clicked=lambda *_, action=action: action.invoke(),
|
||||
)
|
||||
for action in actions
|
||||
],
|
||||
)
|
||||
)
|
||||
|
||||
# destroy this widget once the notification is closed
|
||||
self._notification.connect(
|
||||
"closed",
|
||||
lambda *_: (
|
||||
parent.remove(self) if (parent := self.get_parent()) else None, # type: ignore
|
||||
self.destroy(),
|
||||
),
|
||||
)
|
||||
|
||||
# automatically close the notification after the timeout period
|
||||
invoke_repeater(
|
||||
NOTIFICATION_TIMEOUT,
|
||||
lambda: self._notification.close("expired"),
|
||||
initial_call=False,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application(
|
||||
"notifications",
|
||||
WaylandWindow(
|
||||
margin="8px 8px 8px 8px",
|
||||
anchor="top right",
|
||||
child=Box(
|
||||
size=2, # so it's not ignored by the compositor
|
||||
spacing=4,
|
||||
orientation="v",
|
||||
).build(
|
||||
lambda viewport, _: Notifications(
|
||||
on_notification_added=lambda notifs_service, nid: viewport.add(
|
||||
NotificationWidget(
|
||||
cast(
|
||||
Notification,
|
||||
notifs_service.get_notification_from_id(nid),
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
visible=True,
|
||||
all_visible=True,
|
||||
),
|
||||
)
|
||||
|
||||
app.set_stylesheet_from_file(get_relative_path("./style.css"))
|
||||
|
||||
app.run()
|
||||
@@ -0,0 +1,40 @@
|
||||
:vars {
|
||||
--foreground: rgb(255, 255, 255);
|
||||
--background: rgb(26, 28, 30);
|
||||
--border-color: rgb(42, 43, 45);
|
||||
--button-color: var(--border-color);
|
||||
}
|
||||
|
||||
* {
|
||||
all: unset;
|
||||
color: var(--foreground);
|
||||
font-family: "Jost*", "Cantarell", "Helvetica", "Arial", sans-serif;
|
||||
}
|
||||
|
||||
#notification {
|
||||
padding: 0.8rem;
|
||||
border: solid 1px var(--border-color);
|
||||
border-radius: 1rem;
|
||||
background-color: var(--background);
|
||||
}
|
||||
|
||||
#notification .summary {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#notification .body {
|
||||
color: darker(var(--foreground));
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 0.6rem;
|
||||
font-weight: 600;
|
||||
border-radius: 3rem;
|
||||
background-color: var(--button-color);
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: lighter(var(--button-color));
|
||||
}
|
||||
Reference in new issue
Block a user