🔧 - 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,174 @@
|
||||
"""side panel example, contains info about the system"""
|
||||
|
||||
import os
|
||||
import time
|
||||
import psutil
|
||||
from loguru import logger
|
||||
from fabric import Application
|
||||
from fabric.widgets.box import Box
|
||||
from fabric.widgets.label import Label
|
||||
from fabric.widgets.overlay import Overlay
|
||||
from fabric.widgets.datetime import DateTime
|
||||
from fabric.widgets.circularprogressbar import CircularProgressBar
|
||||
from fabric.widgets.wayland import WaylandWindow as Window
|
||||
from fabric.utils import invoke_repeater, get_relative_path
|
||||
|
||||
|
||||
def get_profile_picture_path() -> str | None:
|
||||
path = os.path.expanduser("~/Pictures/Other/face.jpg")
|
||||
if not os.path.exists(path):
|
||||
path = os.path.expanduser("~/.face")
|
||||
if not os.path.exists(path):
|
||||
logger.warning(
|
||||
"can't fetch a user profile picture, add a profile picture image at ~/.face or at ~/Pictures/Other/profile.jpg"
|
||||
)
|
||||
path = None
|
||||
return path
|
||||
|
||||
|
||||
class SidePanel(Window):
|
||||
@staticmethod
|
||||
def bake_progress_bar(name: str = "progress-bar", size: int = 64, **kwargs):
|
||||
return CircularProgressBar(
|
||||
name=name, min_value=0, max_value=100, size=size, **kwargs
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def bake_progress_icon(**kwargs):
|
||||
return Label(**kwargs).build().add_style_class("progress-icon").unwrap()
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(
|
||||
layer="overlay",
|
||||
title="fabric-overlay",
|
||||
anchor="top right",
|
||||
margin="10px 10px 10px 0px",
|
||||
exclusivity="none",
|
||||
visible=False,
|
||||
all_visible=False,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
self.profile_pic = Box(
|
||||
name="profile-pic",
|
||||
style=f"background-image: url(\"file://{get_profile_picture_path() or ''}\")",
|
||||
)
|
||||
self.uptime_label = Label(label=f"{self.get_current_uptime()}")
|
||||
|
||||
self.header = Box(
|
||||
spacing=14,
|
||||
name="header",
|
||||
orientation="h",
|
||||
children=[
|
||||
self.profile_pic,
|
||||
Box(
|
||||
orientation="v",
|
||||
children=[
|
||||
DateTime(
|
||||
name="date-time",
|
||||
style="margin-top: 4px; min-width: 180px;",
|
||||
),
|
||||
self.uptime_label,
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
self.greeter_label = Label(
|
||||
label=f"Good {'Morning' if time.localtime().tm_hour < 12 else 'Afternoon'}, {os.getlogin().title()}!",
|
||||
style="font-size: 20px;",
|
||||
)
|
||||
|
||||
self.cpu_progress = self.bake_progress_bar()
|
||||
self.ram_progress = self.bake_progress_bar()
|
||||
self.bat_circular = self.bake_progress_bar().build().set_value(42).unwrap()
|
||||
|
||||
self.progress_container = Box(
|
||||
name="progress-bar-container",
|
||||
spacing=12,
|
||||
children=[
|
||||
Box(
|
||||
children=[
|
||||
Overlay(
|
||||
child=self.cpu_progress,
|
||||
overlays=[
|
||||
self.bake_progress_icon(
|
||||
label="",
|
||||
style="margin-right: 8px; text-shadow: 0 0 10px #fff, 0 0 10px #fff, 0 0 10px #fff;",
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Box(name="progress-bar-sep"),
|
||||
Box(
|
||||
children=[
|
||||
Overlay(
|
||||
child=self.ram_progress,
|
||||
overlays=[
|
||||
self.bake_progress_icon(
|
||||
label="",
|
||||
style="margin-right: 4px; text-shadow: 0 0 10px #fff;",
|
||||
)
|
||||
],
|
||||
)
|
||||
]
|
||||
),
|
||||
Box(name="progress-bar-sep"),
|
||||
Box(
|
||||
children=[
|
||||
Overlay(
|
||||
child=self.bat_circular,
|
||||
overlays=[
|
||||
self.bake_progress_icon(
|
||||
label="",
|
||||
style="margin-right: 0px; text-shadow: 0 0 10px #fff, 0 0 18px #fff;",
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
self.update_status()
|
||||
invoke_repeater(
|
||||
15 * 60 * 1000, # every 15min
|
||||
lambda: (self.uptime_label.set_label(self.get_current_uptime()), True)[1],
|
||||
)
|
||||
invoke_repeater(1000, self.update_status)
|
||||
|
||||
self.add(
|
||||
Box(
|
||||
name="window-inner",
|
||||
orientation="v",
|
||||
spacing=24,
|
||||
children=[self.header, self.greeter_label, self.progress_container],
|
||||
),
|
||||
)
|
||||
self.show_all()
|
||||
|
||||
def update_status(self):
|
||||
self.cpu_progress.value = psutil.cpu_percent()
|
||||
self.ram_progress.value = psutil.virtual_memory().percent
|
||||
if not (bat_sen := psutil.sensors_battery()):
|
||||
self.bat_circular.value = 42
|
||||
else:
|
||||
self.bat_circular.value = bat_sen.percent
|
||||
|
||||
return True
|
||||
|
||||
def get_current_uptime(self):
|
||||
uptime = time.time() - psutil.boot_time()
|
||||
uptime_days, remainder = divmod(uptime, 86400)
|
||||
uptime_hours, remainder = divmod(remainder, 3600)
|
||||
# uptime_minutes, _ = divmod(remainder, 60)
|
||||
return f"{int(uptime_days)} {'days' if uptime_days > 1 else 'day'}, {int(uptime_hours)} {'hours' if uptime_hours > 1 else 'hour'}"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
side_panel = SidePanel()
|
||||
app = Application("side-panel", side_panel)
|
||||
app.set_stylesheet_from_file(get_relative_path("./style.css"))
|
||||
|
||||
app.run()
|
||||
@@ -0,0 +1,83 @@
|
||||
:vars {
|
||||
--background: #150d16;
|
||||
--foreground: #f5dbc4;
|
||||
--color0: #150d16;
|
||||
--color1: #72448D;
|
||||
--color2: #9C5995;
|
||||
--color3: #D5719F;
|
||||
--color4: #9A62F3;
|
||||
--color5: #E075DF;
|
||||
--color6: #F98F9F;
|
||||
--color7: #f5dbc4;
|
||||
--color8: #ab9989;
|
||||
--color9: #72448D;
|
||||
--color10: #9C5995;
|
||||
--color11: #D5719F;
|
||||
--color12: #9A62F3;
|
||||
--color13: #E075DF;
|
||||
--color14: #F98F9F;
|
||||
--color15: #f5dbc4;
|
||||
--window-bg: alpha(var(--background), 0.6);
|
||||
--module-bg: alpha(var(--background), 0.4);
|
||||
--border-color: var(--color11);
|
||||
}
|
||||
|
||||
* {
|
||||
all: unset;
|
||||
font-family: "Jost*";
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
#window-inner {
|
||||
border: solid 2px;
|
||||
border-color: var(--color11);
|
||||
background-color: var(--window-bg);
|
||||
border-radius: 100px;
|
||||
border-radius: 12px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#date-time>label {
|
||||
font-weight: 900;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
#header {
|
||||
border: solid 1px var(--border-color);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0px 18px 23px -6px rgba(0, 0, 0, 0.75);
|
||||
background: linear-gradient(90deg,
|
||||
alpha(var(--color11), 0.2),
|
||||
alpha(var(--background), 0.2),
|
||||
var(--module-bg));
|
||||
}
|
||||
|
||||
#profile-pic {
|
||||
background-color: alpha(var(--color11), 0.2);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
border-radius: 6px;
|
||||
padding: 32px;
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
#progress-bar {
|
||||
color: var(--module-bg);
|
||||
border: solid 10px var(--border-color);
|
||||
}
|
||||
|
||||
#progress-bar-sep {
|
||||
padding: 4px;
|
||||
margin: 16px 0px;
|
||||
border-radius: 100px;
|
||||
background-color: var(--module-bg);
|
||||
}
|
||||
|
||||
#progress-bar-container {
|
||||
background-color: var(--module-bg);
|
||||
border-radius: 100px;
|
||||
padding: 8px;
|
||||
}
|
||||
Reference in new issue
Block a user