feat(update): huge changes
This commit is contained in:
98 files changed
+9636
-5575
No files matched your search
+261
-169
@@ -1,186 +1,289 @@
|
||||
from typing import Literal
|
||||
from fabric.hyprland.widgets import Language
|
||||
from fabric.hyprland.widgets import Language, get_hyprland_connection
|
||||
from fabric.hyprland.service import HyprlandEvent
|
||||
from fabric.system_tray.widgets import SystemTray
|
||||
from fabric.utils import (
|
||||
FormattedString,
|
||||
bulk_replace,
|
||||
exec_shell_command_async,
|
||||
get_relative_path,
|
||||
bulk_connect,
|
||||
)
|
||||
from fabric.widgets.shapes import Corner
|
||||
from fabric.widgets.box import Box
|
||||
from fabric.widgets.button import Button
|
||||
from fabric.widgets.centerbox import CenterBox
|
||||
from fabric.widgets.datetime import DateTime
|
||||
from fabric.widgets.label import Label
|
||||
from fabric.widgets.revealer import Revealer
|
||||
from fabric.widgets.wayland import WaylandWindow as Window
|
||||
from gi.repository import GLib
|
||||
from modules.bar.components import (
|
||||
Battery,
|
||||
Metrics,
|
||||
workspace,
|
||||
SystemIndicators,
|
||||
UpdatesWidget,
|
||||
)
|
||||
from services import sc
|
||||
from modules.bar.components import Metrics, workspace, SystemIndicators, UpdatesWidget
|
||||
import config.data as data
|
||||
from gi.repository import Gdk, GLib
|
||||
import utils.icons as icons
|
||||
|
||||
|
||||
class StatusBarCorner(Box):
|
||||
def __init__(self, corner: Literal["top-right", "top-left"]):
|
||||
super().__init__(
|
||||
style="margin-bottom: 15px;",
|
||||
name="bar-corner",
|
||||
children=Corner(
|
||||
orientation=corner,
|
||||
size=15,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class Tray(Box):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.tray = Box(
|
||||
name="left-tray",
|
||||
children=[SystemTray(name="tray", icon_size=16, spacing=4)],
|
||||
)
|
||||
self.profile = Button(
|
||||
child=Label(name="tray-revealer", markup=icons.chevron_left)
|
||||
)
|
||||
self.revealer = Revealer(transition_type="slide-left", transition_duration=1000)
|
||||
self.revealer.add(self.tray)
|
||||
|
||||
bulk_connect(
|
||||
self.profile,
|
||||
{
|
||||
"enter-notify-event": self._on_enter,
|
||||
"leave-notify-event": self._on_leave,
|
||||
"button-press-event": self.toggle_revealer,
|
||||
},
|
||||
)
|
||||
|
||||
self.add(self.profile)
|
||||
self.add(self.revealer)
|
||||
|
||||
def _on_enter(self, *args):
|
||||
self.profile.set_cursor("pointer")
|
||||
|
||||
def _on_leave(self, *args):
|
||||
self.profile.set_cursor("default")
|
||||
|
||||
def toggle_revealer(self, *args):
|
||||
new_state = not self.revealer.get_reveal_child()
|
||||
self.revealer.set_reveal_child(new_state)
|
||||
new_icon = icons.chevron_right if new_state else icons.chevron_left
|
||||
self.profile.get_child().set_markup(new_icon)
|
||||
import os
|
||||
import json
|
||||
|
||||
|
||||
class Bar(Window):
|
||||
def __init__(self):
|
||||
self.workspaces = Button(child=workspace, name="workspaces")
|
||||
self.language = Language(
|
||||
formatter=FormattedString(
|
||||
"{replace_lang(language)}",
|
||||
replace_lang=lambda lang: bulk_replace(
|
||||
lang,
|
||||
(r".*Eng.*", r".*Nep.*"),
|
||||
("en", "np"),
|
||||
regex=True,
|
||||
),
|
||||
),
|
||||
)
|
||||
self.bar_content = CenterBox(name="center-bar")
|
||||
self.recording_indicator = Button(
|
||||
name="recording-indicator",
|
||||
child=Label(name="recorder", markup=icons.record),
|
||||
visible=False,
|
||||
on_clicked=lambda *_: sc.screencast_stop(),
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(
|
||||
name="bar",
|
||||
layer="top",
|
||||
anchor="left top right"
|
||||
if not data.VERTICAL and not data.BOTTOM_BAR
|
||||
else "top right bottom"
|
||||
if data.VERTICAL and data.VERTICAL_RIGHT_ALIGN
|
||||
else "top left bottom"
|
||||
if data.VERTICAL
|
||||
else "bottom left right",
|
||||
exclusivity="auto",
|
||||
visible=True,
|
||||
all_visible=True,
|
||||
)
|
||||
|
||||
sc.connect("recording", self.on_recording_status_change)
|
||||
self.launcher = kwargs.get("launcher", None)
|
||||
self.component_visibility = data.BAR_COMPONENTS_VISIBILITY
|
||||
|
||||
self.date_time = DateTime(formatters=["%-I:%M %a %d %b"], name="datetime")
|
||||
self.battery = Battery()
|
||||
self.launcher = Button(
|
||||
name="logo",
|
||||
child=Label(name="logo-name", label=" "),
|
||||
on_clicked=lambda *_: GLib.spawn_command_line_async(
|
||||
"fabric-cli exec modus 'launcher.open(\"launcher\")'"
|
||||
),
|
||||
# Determine if we should use vertical layout for components
|
||||
is_vertical_layout = data.VERTICAL
|
||||
|
||||
self.workspaces = Button(
|
||||
child=workspace,
|
||||
name="workspaces",
|
||||
)
|
||||
self.button_config = Button(
|
||||
name="button-bar",
|
||||
on_clicked=lambda *_: exec_shell_command_async(
|
||||
f"python {get_relative_path('../../config/config.py')}"
|
||||
),
|
||||
child=Label(name="button-bar-label", markup=icons.config),
|
||||
)
|
||||
self.stats = Metrics()
|
||||
self.updates = UpdatesWidget()
|
||||
self.tray = Tray()
|
||||
self.indicators = SystemIndicators()
|
||||
self.applets = Box(
|
||||
name="system-indicators",
|
||||
|
||||
self.connection = get_hyprland_connection()
|
||||
self.tray = SystemTray(
|
||||
name="tray",
|
||||
spacing=4,
|
||||
orientation="h",
|
||||
icon_size=16,
|
||||
orientation="h" if not is_vertical_layout else "v",
|
||||
)
|
||||
|
||||
self.date_time = Button(
|
||||
name="datetime",
|
||||
child=DateTime(
|
||||
formatters=["%-I:%M:%p %a %d %b"]
|
||||
if not is_vertical_layout
|
||||
else ["%I\n%M\n%p"],
|
||||
h_align="center" if not is_vertical_layout else "fill",
|
||||
v_align="center",
|
||||
),
|
||||
on_clicked=lambda *_: self.calendar(),
|
||||
)
|
||||
self.date_time.connect("enter_notify_event", self.on_button_enter)
|
||||
self.date_time.connect("leave_notify_event", self.on_button_leave)
|
||||
|
||||
self.button_app = Button(
|
||||
name="button-bar",
|
||||
child=Label(name="button-bar-label", markup=icons.apps),
|
||||
on_clicked=lambda *_: self.search_apps(),
|
||||
)
|
||||
self.button_app.connect("enter_notify_event", self.on_button_enter)
|
||||
self.button_app.connect("leave_notify_event", self.on_button_leave)
|
||||
|
||||
self.updates = UpdatesWidget()
|
||||
self.updates.connect("enter_notify_event", self.on_button_enter)
|
||||
self.updates.connect("leave_notify_event", self.on_button_leave)
|
||||
|
||||
self.lang_label = Label(name="lang-label")
|
||||
self.language = Button(
|
||||
name="language", h_align="center", v_align="center", child=self.lang_label
|
||||
)
|
||||
self.on_language_switch()
|
||||
self.connection.connect("event::activelayout", self.on_language_switch)
|
||||
|
||||
self.metrics = Metrics()
|
||||
self.indicators = SystemIndicators(launcher=self.launcher)
|
||||
|
||||
self.applets = Box(
|
||||
name="system-indicator",
|
||||
spacing=4,
|
||||
orientation="h" if not is_vertical_layout else "v",
|
||||
children=[self.language, self.indicators],
|
||||
)
|
||||
|
||||
self.bar_content.end_children = [
|
||||
StatusBarCorner("top-right"),
|
||||
Box(
|
||||
name="bar",
|
||||
spacing=4,
|
||||
children=[
|
||||
self.recording_indicator,
|
||||
self.tray,
|
||||
self.battery,
|
||||
self.applets,
|
||||
self.date_time,
|
||||
self.button_config,
|
||||
],
|
||||
style_classes="end-container",
|
||||
),
|
||||
# Apply visibility settings to components
|
||||
self.apply_component_visibility()
|
||||
|
||||
self.h_start_children = [self.button_app, self.updates]
|
||||
|
||||
self.h_center_children = [
|
||||
self.date_time,
|
||||
self.workspaces,
|
||||
self.metrics,
|
||||
self.applets,
|
||||
]
|
||||
|
||||
self.bar_content.start_children = [
|
||||
Box(
|
||||
name="bar",
|
||||
spacing=4,
|
||||
children=[self.launcher, self.workspaces, self.stats, self.updates],
|
||||
style_classes="start-container",
|
||||
),
|
||||
StatusBarCorner("top-left"),
|
||||
]
|
||||
self.h_end_children = [self.tray]
|
||||
|
||||
super().__init__(
|
||||
layer="top",
|
||||
anchor="left top right",
|
||||
exclusivity="auto",
|
||||
visible=True,
|
||||
child=self.bar_content,
|
||||
self.v_start_children = [
|
||||
self.button_app,
|
||||
self.updates,
|
||||
self.workspaces,
|
||||
self.metrics,
|
||||
]
|
||||
self.v_end_children = [self.tray, self.applets, self.date_time]
|
||||
|
||||
self.v_all_children = []
|
||||
self.v_all_children.extend(self.v_start_children)
|
||||
self.v_all_children.extend(self.v_end_children)
|
||||
|
||||
# Use centered layout when both vertical and centered_bar are enabled
|
||||
is_centered_bar = is_vertical_layout and getattr(data, "CENTERED_BAR", False)
|
||||
|
||||
self.bar = CenterBox(
|
||||
name="bar",
|
||||
orientation="h" if not is_vertical_layout else "v",
|
||||
h_align="fill",
|
||||
v_align="fill",
|
||||
start_children=None
|
||||
if is_centered_bar
|
||||
else Box(
|
||||
name="start-container",
|
||||
spacing=4,
|
||||
orientation="h" if not is_vertical_layout else "v",
|
||||
children=self.h_start_children
|
||||
if not is_vertical_layout
|
||||
else self.v_start_children,
|
||||
),
|
||||
center_children=Box(
|
||||
orientation="v",
|
||||
spacing=4,
|
||||
children=self.v_all_children
|
||||
if is_centered_bar
|
||||
else Box(
|
||||
name="center-container",
|
||||
spacing=4,
|
||||
orientation="h" if not is_vertical_layout else "v",
|
||||
children=self.h_center_children if not is_vertical_layout else None,
|
||||
),
|
||||
)
|
||||
if is_vertical_layout
|
||||
else Box(
|
||||
name="center-container",
|
||||
spacing=4,
|
||||
orientation="h" if not is_vertical_layout else "v",
|
||||
children=self.h_center_children if not is_vertical_layout else None,
|
||||
),
|
||||
end_children=None
|
||||
if is_centered_bar
|
||||
else Box(
|
||||
name="end-container",
|
||||
spacing=4,
|
||||
orientation="h" if not is_vertical_layout else "v",
|
||||
children=self.h_end_children
|
||||
if not is_vertical_layout
|
||||
else self.v_end_children,
|
||||
),
|
||||
)
|
||||
self.hidden = False
|
||||
|
||||
def on_recording_status_change(self, _, status):
|
||||
self.recording_indicator.set_visible(status)
|
||||
self.children = self.bar
|
||||
|
||||
def toggle_hidden(self):
|
||||
self.hidden = not self.hidden
|
||||
if self.hidden:
|
||||
self.bar_content.add_style_class("hidden")
|
||||
self.bar_content.remove_style_class("visible")
|
||||
self.set_property("visible", False)
|
||||
def apply_component_visibility(self):
|
||||
"""Apply saved visibility settings to all components"""
|
||||
components = {
|
||||
"metrics": self.metrics,
|
||||
"indicators": self.applets,
|
||||
"updates": self.updates,
|
||||
"workspaces": self.workspaces,
|
||||
"button_app": self.button_app,
|
||||
# "button_tools": self.button_tools,
|
||||
"language": self.language,
|
||||
"date_time": self.date_time,
|
||||
"tray": self.tray,
|
||||
}
|
||||
|
||||
for component_name, widget in components.items():
|
||||
if component_name in self.component_visibility:
|
||||
widget.set_visible(self.component_visibility[component_name])
|
||||
|
||||
def toggle_component_visibility(self, component_name):
|
||||
"""Toggle visibility for a specific component"""
|
||||
components = {
|
||||
"metrics": self.metrics,
|
||||
"indicators": self.applets,
|
||||
"updates": self.updates,
|
||||
"workspaces": self.workspaces,
|
||||
"button_app": self.button_app,
|
||||
# "button_tools": self.button_tools,
|
||||
"language": self.language,
|
||||
"date_time": self.date_time,
|
||||
"tray": self.tray,
|
||||
}
|
||||
|
||||
if component_name in components and component_name in self.component_visibility:
|
||||
# Toggle the visibility state
|
||||
self.component_visibility[component_name] = not self.component_visibility[
|
||||
component_name
|
||||
]
|
||||
# Apply the new state
|
||||
components[component_name].set_visible(
|
||||
self.component_visibility[component_name]
|
||||
)
|
||||
|
||||
# Update the configuration
|
||||
config_file = os.path.expanduser(
|
||||
f"~/{data.APP_NAME}/config/assets/config.json"
|
||||
)
|
||||
try:
|
||||
if os.path.exists(config_file):
|
||||
with open(config_file, "r") as f:
|
||||
config = json.load(f)
|
||||
|
||||
# Update the config with the new visibility state
|
||||
config[f"bar_{component_name}_visible"] = self.component_visibility[
|
||||
component_name
|
||||
]
|
||||
|
||||
# Write the updated config back to file
|
||||
with open(config_file, "w") as f:
|
||||
json.dump(config, f, indent=4)
|
||||
except (json.JSONDecodeError, IOError) as e:
|
||||
print(f"Error updating config file: {e}")
|
||||
# Revert the visibility change if config update fails
|
||||
self.component_visibility[
|
||||
component_name
|
||||
] = not self.component_visibility[component_name]
|
||||
components[component_name].set_visible(
|
||||
self.component_visibility[component_name]
|
||||
)
|
||||
|
||||
return self.component_visibility[component_name]
|
||||
|
||||
return None
|
||||
|
||||
def on_button_enter(self, widget, event):
|
||||
window = widget.get_window()
|
||||
if window:
|
||||
window.set_cursor(Gdk.Cursor(Gdk.CursorType.HAND2))
|
||||
|
||||
def on_button_leave(self, widget, event):
|
||||
window = widget.get_window()
|
||||
if window:
|
||||
window.set_cursor(None)
|
||||
|
||||
def search_apps(self):
|
||||
self.launcher.open("launcher")
|
||||
|
||||
def calendar(self):
|
||||
self.launcher.open("calendar")
|
||||
|
||||
def on_language_switch(self, _=None, event: HyprlandEvent = None):
|
||||
lang = event.data[1] if event else Language().get_label()
|
||||
self.language.set_tooltip_text(lang)
|
||||
if not data.VERTICAL:
|
||||
self.lang_label.set_label(lang[:2].lower())
|
||||
else:
|
||||
self.bar_content.add_style_class("visible")
|
||||
self.bar_content.remove_style_class("hidden")
|
||||
self.set_property("visible", True)
|
||||
self.lang_label.add_style_class("icon")
|
||||
self.lang_label.set_markup(icons.keyboard)
|
||||
|
||||
|
||||
class ScreenCorners(Window):
|
||||
class MyCorner(Box):
|
||||
def __init__(self, position):
|
||||
super().__init__(
|
||||
name="corner-container",
|
||||
children=Corner(
|
||||
name="corner",
|
||||
orientation=position,
|
||||
size=20,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class Corners(Window):
|
||||
def __init__(self):
|
||||
super().__init__(
|
||||
layer="top",
|
||||
@@ -191,30 +294,19 @@ class ScreenCorners(Window):
|
||||
children=[
|
||||
Box(
|
||||
children=[
|
||||
self.make_corner("top-left"),
|
||||
MyCorner("top-left"),
|
||||
Box(h_expand=True),
|
||||
self.make_corner("top-right"),
|
||||
MyCorner("top-right"),
|
||||
]
|
||||
),
|
||||
Box(v_expand=True),
|
||||
Box(
|
||||
children=[
|
||||
self.make_corner("bottom-left"),
|
||||
MyCorner("bottom-left"),
|
||||
Box(h_expand=True),
|
||||
self.make_corner("bottom-right"),
|
||||
MyCorner("bottom-right"),
|
||||
]
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
def make_corner(self, orientation) -> Box:
|
||||
return Box(
|
||||
h_expand=False,
|
||||
v_expand=False,
|
||||
name="bar-corner",
|
||||
children=Corner(
|
||||
orientation=orientation,
|
||||
size=15,
|
||||
),
|
||||
)
|
||||
Reference in new issue
Block a user