diff options
Diffstat (limited to 'python')
-rw-r--r-- | python/.gitignore | 1 | ||||
-rw-r--r-- | python/astal/__init__.py | 17 | ||||
-rw-r--r-- | python/astal/application.py | 62 | ||||
-rw-r--r-- | python/astal/binding.py | 33 | ||||
-rw-r--r-- | python/astal/variable.py | 100 | ||||
-rw-r--r-- | python/astal/widget.py | 78 | ||||
-rw-r--r-- | python/pyproject.toml | 14 | ||||
-rw-r--r-- | python/ruff.toml | 62 | ||||
-rwxr-xr-x | python/sample.py | 31 |
9 files changed, 0 insertions, 398 deletions
diff --git a/python/.gitignore b/python/.gitignore deleted file mode 100644 index c18dd8d..0000000 --- a/python/.gitignore +++ /dev/null @@ -1 +0,0 @@ -__pycache__/ diff --git a/python/astal/__init__.py b/python/astal/__init__.py deleted file mode 100644 index 58d0a0d..0000000 --- a/python/astal/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -import gi - -gi.require_version("Astal", "0.1") -gi.require_version("Gtk", "3.0") -gi.require_version("Gdk", "3.0") -gi.require_version("GLib", "2.0") -gi.require_version("Gio", "2.0") -gi.require_version("GObject", "2.0") -from gi.repository import Astal, Gtk, GLib, Gio, GObject, Gdk -from .application import App -from .variable import Variable -from .binding import Binding -from . import widget as Widget - -bind = Binding - -__all__ = ["App", "Variable", "Widget" "bind", "Astal", "Gtk", "Gdk", "GLib", "Gio", "GObject"] diff --git a/python/astal/application.py b/python/astal/application.py deleted file mode 100644 index b5d5c41..0000000 --- a/python/astal/application.py +++ /dev/null @@ -1,62 +0,0 @@ -from collections.abc import Callable -from gi.repository import Astal, Gio - -RequestHandler = Callable[[str, Callable[[str], None]], None] - - -class _Application(Astal.Application): - def __init__(self) -> None: - super().__init__() - self.request_handler: RequestHandler | None = None - - def do_request(self, msg: str, conn: Gio.SocketConnection) -> None: - if self.request_handler: - self.request_handler( - msg, - lambda response: Astal.write_sock( - conn, - str(response), - lambda _, res: Astal.write_sock_finish(res), - ), - ) - else: - super().do_request(msg, conn) - - def start( - self, - instance_name: str | None = None, - gtk_theme: str | None = None, - icon_theme: str | None = None, - cursor_theme: str | None = None, - css: str | None = None, - hold: bool | None = True, - request_handler: RequestHandler | None = None, - callback: Callable | None = None, - ) -> None: - if request_handler: - self.request_handler = request_handler - if hold: - self.hold() - if instance_name: - self.instance_name = instance_name - if gtk_theme: - self.gtk_theme = gtk_theme - if icon_theme: - self.icon_theme = icon_theme - if cursor_theme: - self.cursor_theme = icon_theme - if css: - self.apply_css(css, False) - if not self.acquire_socket(): - print(f"Astal instance {self.instance_name} already running") - return - - def on_activate(app): - if callback: - callback() - - self.connect("activate", on_activate) - self.run() - - -App = _Application() diff --git a/python/astal/binding.py b/python/astal/binding.py deleted file mode 100644 index 0fe1b6c..0000000 --- a/python/astal/binding.py +++ /dev/null @@ -1,33 +0,0 @@ -import re - - -def kebabify(string): - return re.sub(r"([a-z])([A-Z])", r"\1-\2", string).replace("_", "-").lower() - - -class Binding: - def __init__(self, emitter, prop=None): - self.emitter = emitter - self.prop = kebabify(prop) if prop else None - self.transform_fn = lambda v: v - - def __str__(self): - return f"Binding<{self.emitter}{', ' + self.prop if self.prop else ''}>" - - def as_(self, fn): - bind = Binding(self.emitter, self.prop) - bind.transform_fn = lambda v: fn(self.transform_fn(v)) - return bind - - def get(self): - if hasattr(self.emitter, "get") and callable(self.emitter.get): - return self.transform_fn(self.emitter.get()) - - return self.transform_fn(self.emitter[f"get_{self.prop}"]()) - - def subscribe(self, callback): - if hasattr(self.emitter, "subscribe") and callable(self.emitter.subscribe): - return self.emitter.subscribe(lambda _: callback(self.get())) - - i = self.emitter.connect(f"notify::{self.prop}", lambda: callback(self.get())) - return lambda: self.emitter.disconnect(i) diff --git a/python/astal/variable.py b/python/astal/variable.py deleted file mode 100644 index 9b165cd..0000000 --- a/python/astal/variable.py +++ /dev/null @@ -1,100 +0,0 @@ -from gi.repository import Astal - -from .binding import Binding - - -class Variable: - def __init__(self, init): - v = Astal.Variable.new(init) - self._variable = v - self._err_handler = print - v.connect("error", lambda _, err: self._err_handler(err) if self._err_handler else None) - - def __call__(self, transform=None): - if transform: - return Binding(self).as_(transform) - - return Binding(self) - - def __str__(self): - return f"Variable<{self.get()}>" - - def get(self): - return self._variable.get_value() - - def set(self, value): - return self._variable.set_value(value) - - def watch(self, cmd): - if isinstance(cmd, str): - self._variable.watch(cmd) - elif isinstance(cmd, list): - self._variable.watchv(cmd) - return self - - def poll(self, interval, cmd): - if isinstance(cmd, str): - self._variable.poll(interval, cmd) - elif isinstance(cmd, list): - self._variable.pollv(interval, cmd) - else: - self._variable.pollfn(interval, cmd) - return self - - def start_watch(self): - self._variable.start_watch() - - def start_poll(self): - self._variable.start_poll() - - def stop_watch(self): - self._variable.stop_watch() - - def stop_poll(self): - self._variable.stop_poll() - - def drop(self): - self._variable.emit_dropped() - self._variable.run_dispose() - - def on_dropped(self, callback): - self._variable.connect("dropped", lambda _: callback()) - return self - - def on_error(self, callback): - self._err_handler = None - self._variable.connect("error", lambda _, e: callback(e)) - return self - - def subscribe(self, callback): - s = self._variable.connect("changed", lambda _: callback(self.get())) - return lambda: self._variable.disconnect(s) - - def observe(self, objs, sigOrFn, callback=None): - if callable(sigOrFn): - f = sigOrFn - elif callable(callback): - f = callback - else: - f = lambda *_: self.get() - - def setter(*args): - self.set(f(*args)) - - if isinstance(objs, list): - for obj in objs: - obj[0].connect(obj[1], setter) - elif isinstance(sigOrFn, str): - objs.connect(sigOrFn, setter) - - return self - - @staticmethod - def derive(deps, fn): - def update(): - return fn(*[d.get() for d in deps]) - - derived = Variable(update()) - unsubs = [dep.subscribe(lambda _: derived.set(update())) for dep in deps] - derived.on_dropped(lambda: ([unsub() for unsub in unsubs])) - return derived diff --git a/python/astal/widget.py b/python/astal/widget.py deleted file mode 100644 index 8f2285f..0000000 --- a/python/astal/widget.py +++ /dev/null @@ -1,78 +0,0 @@ -from gi.repository import Astal, Gtk -from .binding import Binding, kebabify - - -def set_child(self, child): - if isinstance(self, Gtk.Bin): - self.remove(self.get_child()) - if isinstance(self, Gtk.Container): - self.add(child) - - -def astalify(ctor): - ctor.set_css = Astal.widget_set_css - ctor.get_css = Astal.widget_get_css - - ctor.set_class_name = lambda self, names: Astal.widget_set_class_names(self, names.split()) - ctor.get_class_name = lambda self: " ".join(Astal.widget_set_class_names(self)) - - ctor.set_cursor = Astal.widget_set_cursor - ctor.get_cursor = Astal.widget_get_cursor - - def widget(**kwargs): - args = {} - bindings = {} - handlers = {} - setup = None - if not hasattr(kwargs, "visible"): - kwargs["visible"] = True - - for key, value in kwargs.items(): - if key == "setup": - setup = value - if isinstance(value, Binding): - bindings[key] = value - if key.startswith("on_"): - handlers[key] = value - else: - args[key] = value - - self = ctor(**args) - - for key, value in bindings.items(): - setter = getattr(self, f"set_{key}") - setter(value.get()) - unsub = value.subscribe(setter) - self.connect("destroy", lambda _: unsub()) - - for key, value in handlers.items(): - self.connect(kebabify(key.replace("on_", "")), value) - - if setup: - setup(self) - - return self - - return widget - - -Box = astalify(Astal.Box), -Button = astalify(Astal.Button), -CenterBox = astalify(Astal.CenterBox), -# TODO: CircularProgress -DrawingArea = astalify(Gtk.DrawingArea), -Entry = astalify(Gtk.Entry), -EventBox = astalify(Astal.EventBox), -# TODO: Fixed -# TODO: FlowBox -Icon = astalify(Astal.Icon), -Label = astalify(Gtk.Label), -LevelBar = astalify(Astal.LevelBar), -# TODO: ListBox -Overlay = astalify(Astal.Overlay), -Revealer = astalify(Gtk.Revealer), -Scrollable = astalify(Astal.Scrollable), -Slider = astalify(Astal.Slider), -# TODO: Stack -Switch = astalify(Gtk.Switch), -Window = astalify(Astal.Window), diff --git a/python/pyproject.toml b/python/pyproject.toml deleted file mode 100644 index 6dc48e2..0000000 --- a/python/pyproject.toml +++ /dev/null @@ -1,14 +0,0 @@ -[tool.poetry] -name = "astal" -version = "0.1.0" -description = "" -authors = [] - -[tool.poetry.dependencies] -python = "^3.11" -gengir = "^1.0.2" - - -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" diff --git a/python/ruff.toml b/python/ruff.toml deleted file mode 100644 index a6bedc2..0000000 --- a/python/ruff.toml +++ /dev/null @@ -1,62 +0,0 @@ -target-version = "py311" - -exclude = [ - ".bzr", - ".direnv", - ".eggs", - ".git", - ".git-rewrite", - ".hg", - ".ipynb_checkpoints", - ".mypy_cache", - ".nox", - ".pants.d", - ".pyenv", - ".pytest_cache", - ".pytype", - ".ruff_cache", - ".svn", - ".tox", - ".venv", - ".vscode", - "__pypackages__", - "_build", - "buck-out", - "build", - "dist", - "node_modules", - "site-packages", - "venv", -] - -line-length = 100 -indent-width = 4 - -[lint] -select = ["ALL"] -ignore = ["D", "ANN101", "ERA", "ANN"] - -# Allow fix for all enabled rules (when `--fix`) is provided. -fixable = ["ALL"] -unfixable = [] - -# Allow unused variables when underscore-prefixed. -dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" - -[format] -quote-style = "double" -indent-style = "space" - -# Like Black, respect magic trailing commas. -skip-magic-trailing-comma = false - -# Like Black, automatically detect the appropriate line ending. -line-ending = "auto" - -# Enable auto-formatting of code examples in docstrings. Markdown, -# reStructuredText code/literal blocks and doctests are all supported. -docstring-code-format = false - -# Set the line length limit used when formatting code snippets in -# docstrings. -docstring-code-line-length = "dynamic" diff --git a/python/sample.py b/python/sample.py deleted file mode 100755 index af09ce2..0000000 --- a/python/sample.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -import gi - -gi.require_version("Playerctl", "2.0") - -from gi.repository import Playerctl -from astal import App, Astal, Variable, Widget, bind - -player = Playerctl.Player.new("spotify") -v = Variable(player.get_title()).observe(player, "metadata", lambda *_: player.get_title()) - - -def Bar(monitor): - return Widget.Window( - anchor=Astal.WindowAnchor.BOTTOM | Astal.WindowAnchor.LEFT | Astal.WindowAnchor.RIGHT, - monitor=monitor, - exclusivity=Astal.Exclusivity.EXCLUSIVE, - child=Widget.CenterBox( - start_widget=Widget.Label( - label="Welcome to Astal.py!", - ), - end_widget=Widget.Label(label=v()), - ), - ) - - -def start(): - Bar(0) - - -App.start(callback=start) |