rename snippets to utils
This commit is contained in:
1 parent
b89d4f514e
commit
54afacbcbf
6 files changed
+109
-200
No files matched your search
@@ -1,179 +0,0 @@
|
|||||||
from typing import cast
|
|
||||||
|
|
||||||
from fabric import Property, Service, Signal
|
|
||||||
from gi.repository import GLib, Gtk
|
|
||||||
|
|
||||||
|
|
||||||
class Animator(Service):
|
|
||||||
@Signal
|
|
||||||
def finished(self) -> None: ...
|
|
||||||
|
|
||||||
@Property(tuple[float, float, float, float], "read-write")
|
|
||||||
def bezier_curve(self) -> tuple[float, float, float, float]:
|
|
||||||
return self._bezier_curve
|
|
||||||
|
|
||||||
@bezier_curve.setter
|
|
||||||
def bezier_curve(self, value: tuple[float, float, float, float]):
|
|
||||||
self._bezier_curve = value
|
|
||||||
return
|
|
||||||
|
|
||||||
@Property(float, "read-write")
|
|
||||||
def value(self):
|
|
||||||
return self._value
|
|
||||||
|
|
||||||
@value.setter
|
|
||||||
def value(self, value: float):
|
|
||||||
self._value = value
|
|
||||||
return
|
|
||||||
|
|
||||||
@Property(float, "read-write")
|
|
||||||
def max_value(self):
|
|
||||||
return self._max_value
|
|
||||||
|
|
||||||
@max_value.setter
|
|
||||||
def max_value(self, value: float):
|
|
||||||
self._max_value = value
|
|
||||||
return
|
|
||||||
|
|
||||||
@Property(float, "read-write")
|
|
||||||
def min_value(self):
|
|
||||||
return self._min_value
|
|
||||||
|
|
||||||
@min_value.setter
|
|
||||||
def min_value(self, value: float):
|
|
||||||
self._min_value = value
|
|
||||||
return
|
|
||||||
|
|
||||||
@Property(bool, "read-write", default_value=False)
|
|
||||||
def playing(self):
|
|
||||||
return self._playing
|
|
||||||
|
|
||||||
@playing.setter
|
|
||||||
def playing(self, value: bool):
|
|
||||||
self._playing = value
|
|
||||||
return
|
|
||||||
|
|
||||||
@Property(bool, "read-write", default_value=False)
|
|
||||||
def repeat(self):
|
|
||||||
return self._repeat
|
|
||||||
|
|
||||||
@repeat.setter
|
|
||||||
def repeat(self, value: bool):
|
|
||||||
self._repeat = value
|
|
||||||
return
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
bezier_curve: tuple[float, float, float, float],
|
|
||||||
duration: float,
|
|
||||||
min_value: float = 0.0,
|
|
||||||
max_value: float = 1.0,
|
|
||||||
repeat: bool = False,
|
|
||||||
tick_widget: Gtk.Widget | None = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
super().__init__(**kwargs)
|
|
||||||
self._bezier_curve = (1, 0, 1, 1)
|
|
||||||
self._duration = 5
|
|
||||||
self._value = 0.0
|
|
||||||
self._min_value = 0.0
|
|
||||||
self._max_value = 1.0
|
|
||||||
self._repeat = False
|
|
||||||
|
|
||||||
self.bezier_curve = bezier_curve
|
|
||||||
self.duration = duration
|
|
||||||
self.value = min_value
|
|
||||||
self.min_value = min_value
|
|
||||||
self.max_value = max_value
|
|
||||||
self.repeat = repeat
|
|
||||||
|
|
||||||
self.playing = False
|
|
||||||
self._start_time = None
|
|
||||||
self._tick_handler = None
|
|
||||||
self._timeline_pos = 0
|
|
||||||
self._tick_widget = tick_widget
|
|
||||||
|
|
||||||
def do_get_time_now(self):
|
|
||||||
return GLib.get_monotonic_time() / 1_000_000
|
|
||||||
|
|
||||||
def do_lerp(self, start: float, end: float, time: float) -> float:
|
|
||||||
return start + (end - start) * time
|
|
||||||
|
|
||||||
def do_interpolate_cubic_bezier(self, time: float) -> float:
|
|
||||||
y_points = (0, self.bezier_curve[1], self.bezier_curve[3], 1)
|
|
||||||
return (
|
|
||||||
(1 - time) ** 3 * y_points[0]
|
|
||||||
+ 3 * (1 - time) ** 2 * time * y_points[1]
|
|
||||||
+ 3 * (1 - time) * time**2 * y_points[2]
|
|
||||||
+ time**3 * y_points[3]
|
|
||||||
)
|
|
||||||
|
|
||||||
def do_ease(self, time: float) -> float:
|
|
||||||
return self.do_lerp(
|
|
||||||
self.min_value, self.max_value, self.do_interpolate_cubic_bezier(time)
|
|
||||||
)
|
|
||||||
|
|
||||||
def do_update_value(self, delta_time: float):
|
|
||||||
if not self.playing:
|
|
||||||
return
|
|
||||||
|
|
||||||
elapsed_time = delta_time - cast(float, self._start_time)
|
|
||||||
|
|
||||||
self._timeline_pos = min(1, elapsed_time / self.duration)
|
|
||||||
|
|
||||||
self.value = self.do_ease(self._timeline_pos)
|
|
||||||
|
|
||||||
if not self._timeline_pos >= 1:
|
|
||||||
return
|
|
||||||
|
|
||||||
if not self.repeat:
|
|
||||||
self.value = self.max_value
|
|
||||||
self.finished()
|
|
||||||
self.pause()
|
|
||||||
return
|
|
||||||
|
|
||||||
self._start_time = delta_time
|
|
||||||
self._timeline_pos = 0
|
|
||||||
return
|
|
||||||
|
|
||||||
def do_handle_tick(self, *_):
|
|
||||||
current_time = self.do_get_time_now()
|
|
||||||
self.do_update_value(current_time)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def do_remove_tick_handlers(self):
|
|
||||||
if self._tick_handler:
|
|
||||||
if self._tick_widget:
|
|
||||||
self._tick_widget.remove_tick_callback(self._tick_handler)
|
|
||||||
else:
|
|
||||||
GLib.source_remove(self._tick_handler)
|
|
||||||
self._tick_handler = None
|
|
||||||
return
|
|
||||||
|
|
||||||
def play(self):
|
|
||||||
if self.playing:
|
|
||||||
return
|
|
||||||
|
|
||||||
self._start_time = self.do_get_time_now()
|
|
||||||
|
|
||||||
if not self._tick_handler:
|
|
||||||
if self._tick_widget:
|
|
||||||
self._tick_handler = self._tick_widget.add_tick_callback(
|
|
||||||
self.do_handle_tick
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self._tick_handler = GLib.timeout_add(16, self.do_handle_tick)
|
|
||||||
|
|
||||||
self.playing = True
|
|
||||||
return
|
|
||||||
|
|
||||||
def pause(self):
|
|
||||||
self.playing = False
|
|
||||||
return self.do_remove_tick_handlers()
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
if not self._tick_handler:
|
|
||||||
self._timeline_pos = 0
|
|
||||||
self.playing = False
|
|
||||||
return
|
|
||||||
return self.do_remove_tick_handlers()
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
from fabric.widgets.label import Label
|
|
||||||
|
|
||||||
|
|
||||||
def MaterialIcon(icon_name: str, size: int = 24, props=None):
|
|
||||||
label_props = {
|
|
||||||
"label": str(icon_name), # Directly use the provided icon name
|
|
||||||
"name": "material_icon",
|
|
||||||
"style": f"font-size: {size}px;", # Set font family for Material Icons
|
|
||||||
"h_align": "center", # Align horizontally
|
|
||||||
"v_align": "center", # Align vertically
|
|
||||||
}
|
|
||||||
|
|
||||||
if props:
|
|
||||||
label_props.update(props)
|
|
||||||
|
|
||||||
return Label(**label_props)
|
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
from .animator import *
|
|
||||||
from .custom_image import *
|
from .custom_image import *
|
||||||
from .icon import *
|
from .icon_resolver import *
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from fabric.utils import get_relative_path
|
from fabric.utils import get_relative_path
|
||||||
|
|
||||||
|
|
||||||
def read_config():
|
def read_config():
|
||||||
config_path = get_relative_path("../config/assets/launcher.json")
|
config_path = get_relative_path("../config/assets/modus.json")
|
||||||
|
|
||||||
with open(config_path, "r") as file:
|
with open(config_path, "r") as file:
|
||||||
# Load JSON data into a Python dictionary
|
# Load JSON data into a Python dictionary
|
||||||
File renamed without changes.
@@ -0,0 +1,103 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
import gi
|
||||||
|
|
||||||
|
gi.require_version("Gtk", "3.0")
|
||||||
|
from gi.repository import GLib, Gtk
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
|
||||||
|
# TODO WIP
|
||||||
|
# Idea: nearest string matching algorithm
|
||||||
|
# if already exists: retrieve from json
|
||||||
|
# if found: stor in json: app_id -> icon_name
|
||||||
|
# if not found: store in json -> misisng-icon
|
||||||
|
|
||||||
|
|
||||||
|
CACHE_DIR = str(GLib.get_user_cache_dir()) + "/modus"
|
||||||
|
ICON_CACHE_FILE = CACHE_DIR + "/icons.json"
|
||||||
|
if not os.path.exists(CACHE_DIR):
|
||||||
|
os.makedirs(CACHE_DIR)
|
||||||
|
|
||||||
|
|
||||||
|
class IconResolver:
|
||||||
|
def __init__(
|
||||||
|
self, default_applicaiton_icon: str = "application-x-executable-symbolic"
|
||||||
|
):
|
||||||
|
if os.path.exists(ICON_CACHE_FILE):
|
||||||
|
f = open(ICON_CACHE_FILE)
|
||||||
|
try:
|
||||||
|
self._icon_dict = json.load(f)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
logger.info("[ICONS] Cache file does not exist or is corrupted")
|
||||||
|
f.close()
|
||||||
|
else:
|
||||||
|
self._icon_dict = {}
|
||||||
|
|
||||||
|
self.default_applicaiton_icon = default_applicaiton_icon
|
||||||
|
|
||||||
|
def get_icon_name(self, app_id: str):
|
||||||
|
if app_id in self._icon_dict:
|
||||||
|
return self._icon_dict[app_id]
|
||||||
|
new_icon = self._compositor_find_icon(app_id)
|
||||||
|
logger.info(
|
||||||
|
f"[ICONS] found new icon: '{new_icon}' for app id: '{app_id}', storing..."
|
||||||
|
)
|
||||||
|
self._store_new_icon(app_id, new_icon)
|
||||||
|
return new_icon
|
||||||
|
|
||||||
|
def get_icon_pixbuf(self, app_id: str, size: int = 16):
|
||||||
|
return Gtk.IconTheme.get_default().load_icon(
|
||||||
|
self.get_icon_name(app_id),
|
||||||
|
size,
|
||||||
|
Gtk.IconLookupFlags.FORCE_SIZE,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _store_new_icon(self, app_id: str, icon: str):
|
||||||
|
self._icon_dict[app_id] = icon
|
||||||
|
with open(ICON_CACHE_FILE, "w") as f:
|
||||||
|
json.dump(self._icon_dict, f)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
def _get_icon_from_desktop_file(self, desktop_file_path: str):
|
||||||
|
# TODO: get icon in the [Desktop Entry] section only
|
||||||
|
with open(desktop_file_path) as f:
|
||||||
|
for line in f.readlines():
|
||||||
|
if "Icon=" in line:
|
||||||
|
return "".join(line[5:].split())
|
||||||
|
return self.default_applicaiton_icon
|
||||||
|
|
||||||
|
def _get_desktop_file(self, app_id: str) -> str | None:
|
||||||
|
data_dirs = GLib.get_system_data_dirs()
|
||||||
|
for data_dir in data_dirs:
|
||||||
|
data_dir = data_dir + "/applications/"
|
||||||
|
if os.path.exists(data_dir):
|
||||||
|
# Do name resolving here
|
||||||
|
|
||||||
|
files = os.listdir(data_dir)
|
||||||
|
matching = [
|
||||||
|
s for s in files if "".join(app_id.lower().split()) in s.lower()
|
||||||
|
]
|
||||||
|
if matching:
|
||||||
|
return data_dir + matching[0]
|
||||||
|
|
||||||
|
for word in list(filter(None, re.split(r"-|\.|_|\s", app_id))):
|
||||||
|
matching = [s for s in files if word.lower() in s.lower()]
|
||||||
|
if matching:
|
||||||
|
return data_dir + matching[0]
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _compositor_find_icon(self, app_id: str):
|
||||||
|
if Gtk.IconTheme.get_default().has_icon(app_id):
|
||||||
|
return app_id
|
||||||
|
if Gtk.IconTheme.get_default().has_icon(app_id + "-desktop"):
|
||||||
|
return app_id + "-desktop"
|
||||||
|
desktop_file = self._get_desktop_file(app_id)
|
||||||
|
return (
|
||||||
|
self._get_icon_from_desktop_file(desktop_file)
|
||||||
|
if desktop_file
|
||||||
|
else self.default_applicaiton_icon
|
||||||
|
)
|
||||||
@@ -53,8 +53,8 @@ shutdown: str = ""
|
|||||||
power_saving: str = ""
|
power_saving: str = ""
|
||||||
power_balanced: str = "勺"
|
power_balanced: str = "勺"
|
||||||
power_performance: str = ""
|
power_performance: str = ""
|
||||||
charging: str = "𐁣"
|
charging: str = ""
|
||||||
discharging: str = "𐁪"
|
discharging: str = ""
|
||||||
alert: str = ""
|
alert: str = ""
|
||||||
|
|
||||||
# Applets
|
# Applets
|
||||||
@@ -64,6 +64,7 @@ night: str = ""
|
|||||||
coffee: str = ""
|
coffee: str = ""
|
||||||
dnd: str = ""
|
dnd: str = ""
|
||||||
darkmode: str = "﹖"
|
darkmode: str = "﹖"
|
||||||
|
world: str = ""
|
||||||
|
|
||||||
wifi_off: str = ""
|
wifi_off: str = ""
|
||||||
bluetooth_off: str = ""
|
bluetooth_off: str = ""
|
||||||
@@ -128,6 +129,7 @@ disc_off: str = ""
|
|||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
dot: str = ""
|
dot: str = ""
|
||||||
|
palette: str = ""
|
||||||
|
|
||||||
exceptions: list[str] = ["font_family", "font_weight", "span"]
|
exceptions: list[str] = ["font_family", "font_weight", "span"]
|
||||||
|
|
||||||
Reference in new issue
Block a user