panorama_panel.py
Python script, ASCII text executable
1import gi 2gi.require_version("Gtk", "4.0") 3 4from gi.repository import Gtk, Gdk, GObject, GLib 5 6 7class Applet(Gtk.Box): 8name = "Generic applet" 9description = "" 10 11__gsignals__ = { 12"config-changed": (GObject.SIGNAL_RUN_FIRST, None, ()) 13} 14 15def __init__(self, orientation=Gtk.Orientation.HORIZONTAL, config=None): 16super().__init__(orientation=orientation) 17if orientation == Gtk.Orientation.VERTICAL: 18self.set_hexpand(True) 19self.set_vexpand(False) 20elif orientation == Gtk.Orientation.HORIZONTAL: 21self.set_vexpand(True) 22self.set_hexpand(False) 23 24self.drag_source = Gtk.DragSource(actions=Gdk.DragAction.MOVE) 25self.drag_source.connect("prepare", self.provide_drag_data) 26self.drag_source.connect("drag-begin", self.drag_begin) 27self.drag_source.connect("drag-cancel", self.drag_cancel) 28 29def provide_drag_data(self, source: Gtk.DragSource, x: float, y: float): 30app = self.get_root().get_application() 31app.drags[id(self)] = self 32value = GObject.Value() 33value.init(GObject.TYPE_UINT64) 34value.set_uint64(id(self)) 35return Gdk.ContentProvider.new_for_value(value) 36 37def drag_begin(self, source: Gtk.DragSource, drag: Gdk.Drag): 38paintable = Gtk.WidgetPaintable.new(self).get_current_image() 39source.set_icon(paintable, 0, 0) 40self.hide() 41 42def drag_cancel(self, source: Gtk.DragSource, drag: Gdk.Drag, reason: Gdk.DragCancelReason): 43self.show() 44return False 45 46def get_config(self): 47return {} 48 49def shutdown(self): 50return 51 52def set_panel_position(self, position: Gtk.PositionType): 53return 54 55def make_draggable(self): 56self.add_controller(self.drag_source) 57 58def restore_drag(self): 59self.remove_controller(self.drag_source) 60 61def output_changed(self): 62return 63 64@classmethod 65def print_log(cls, *args, **kwargs): 66print(f"{cls.__name__}:", *args, **kwargs) 67 68 69def track_popover(popover: Gtk.Popover): 70popover.connect("show", lambda *args: _popover_shown(popover)) 71popover.connect("closed", lambda *args: _popover_hidden(popover)) 72 73 74def _popover_shown(popover: Gtk.Popover): 75popover.get_root().open_popovers.add(id(popover)) 76if popover.get_root().autohide: 77GLib.timeout_add(popover.get_root().hide_time // (popover.get_root().size - 1), 78popover.get_root().slide_in) 79 80 81def _popover_hidden(popover: Gtk.Popover): 82popover.get_root().open_popovers.remove(id(popover)) 83if popover.get_root().autohide and not popover.get_root().open_popovers: 84GLib.timeout_add(popover.get_root().hide_time // (popover.get_root().size - 1), 85popover.get_root().slide_out) 86 87 88def get_panel_position(applet: Applet) -> Gtk.PositionType: 89return applet.get_root().position 90 91 92OPPOSITE_POSITION = { 93Gtk.PositionType.TOP: Gtk.PositionType.BOTTOM, 94Gtk.PositionType.BOTTOM: Gtk.PositionType.TOP, 95Gtk.PositionType.LEFT: Gtk.PositionType.RIGHT, 96Gtk.PositionType.RIGHT: Gtk.PositionType.LEFT, 97} 98 99POSITION_TO_ARROW = { 100Gtk.PositionType.TOP: Gtk.ArrowType.UP, 101Gtk.PositionType.BOTTOM: Gtk.ArrowType.DOWN, 102Gtk.PositionType.LEFT: Gtk.ArrowType.LEFT, 103Gtk.PositionType.RIGHT: Gtk.ArrowType.RIGHT, 104} 105