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