import sys import types class Fake: def __init__(self, *args, **kwargs): self._props = {} self._children = [] self._parent = None self._handlers = {} self._visible = kwargs.pop("visible", True) self._classes = list(kwargs.get("css_classes", [])) for key in ("child",): for item in _listify(kwargs.pop(key, [])): self.append(item) for key, value in kwargs.items(): self._props[key] = value self._props.setdefault("label", kwargs.get("label", "")) def append(self, widget): widget._parent = self self._children.append(widget) def remove(self, widget): assert widget._parent is self, "removing a non-child" widget._parent = None self._children.remove(widget) def get_parent(self): return self._parent def get_prev_sibling(self): if self._parent is None: return None siblings = self._parent._children index = siblings.index(self) return siblings[index - 1] if index else None def reorder_child_after(self, child, sibling): self._children.remove(child) self._children.insert(0 if sibling is None else self._children.index(sibling) + 1, child) def set_visible(self, value): self._visible = bool(value) def get_visible(self): return self._visible def set_css_classes(self, classes): self._classes = list(classes) def connect(self, signal, callback): self._handlers.setdefault(signal, []).append(callback) return len(self._handlers[signal]) def emit(self, signal, *args): for callback in self._handlers.get(signal, []): callback(self, *args) def set_sensitive(self, value): self._props["sensitive"] = value def set_spinning(self, value): self._props["spinning"] = value def set_visibility(self, value): self._props["visibility"] = value def get_visibility(self): return self._props.get("visibility", True) def grab_focus(self): pass def set_tooltip_text(self, text): self._props["tooltip"] = text def set_label(self, text): self._props["label"] = text def __getattr__(self, name): if name.startswith("_"): raise AttributeError(name) return self.__dict__.get("_props", {}).get(name) def __setattr__(self, name, value): if name.startswith("_") or name in ("on_error",): object.__setattr__(self, name, value) else: self._props[name] = value def walk(self): yield self for child in self._children: yield from child.walk() def _listify(value): if value is None: return [] return value if isinstance(value, (list, tuple)) else [value] def install(): widgets = types.ModuleType("ignis.widgets") for name in ("Box", "Label", "Button", "Entry", "Switch", "Revealer"): setattr(widgets, name, type(name, (Fake,), {})) ignis = types.ModuleType("ignis") ignis.widgets = widgets sys.modules["ignis"] = ignis sys.modules["ignis.widgets"] = widgets gi = types.ModuleType("gi") repo = types.ModuleType("gi.repository") repo.Gtk = types.SimpleNamespace( Spinner=type("Spinner", (Fake,), {}), Align=types.SimpleNamespace(CENTER=1) ) gi.repository = repo sys.modules["gi"] = gi sys.modules["gi.repository"] = repo m3 = types.ModuleType("modules.m3components") m3.NewButton = type("NewButton", (Fake,), {}) sys.modules["modules.m3components"] = m3 for name, path in (("modules.settings", None), ("modules.settings.tabs", None)): pass