roundabout,
created on Monday, 21 July 2025, 10:15:10 (1753092910),
received on Saturday, 26 July 2025, 07:40:05 (1753515605)
Author identity: vlad <vlad.muntoiu@gmail.com>
9c593e83b129d2a40a33f66ec61ffdd4c3395892
applets/clock/panorama-clock-options.cmb
@@ -2,5 +2,5 @@
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
<!-- Created with Cambalache 0.96.1 -->
<cambalache-project version="0.96.0" target_tk="gtk-4.0">
<ui template-class="ClockOptions" filename="panorama-clock-options.ui" sha256="d183407b347a36fc200e673b53bfbfff8682eca6dfe7d89bcaacca565f7248a8"/>
<ui template-class="ClockOptions" filename="panorama-clock-options.ui" sha256="626c777f1e749e763b08598621ce69e7e40f41bf400d2370ed25743bd94a64ba"/>
</cambalache-project>
applets/clock/panorama-clock-options.ui
@@ -31,10 +31,10 @@
</property>
<child>
<object class="GtkListBox">
<property name="activate-on-single-click">False</property>
<property name="selection-mode">none</property>
<child>
<object class="GtkListBoxRow">
<property name="activatable">False</property>
<child>
<object class="GtkBox">
<child>
main.py
@@ -1,3 +1,5 @@
from __future__ import annotations
import os
import sys
import importlib
@@ -21,54 +23,47 @@ sys.path.insert(0, str((Path(__file__).parent / "shared").resolve()))
import panorama_panel
def get_applet_directories():
data_home = Path(os.getenv("XDG_DATA_HOME", Path.home() / ".local" / "share"))
data_dirs = [Path(d) for d in os.getenv("XDG_DATA_DIRS", "/usr/local/share:/usr/share").split(":")]
@Gtk.Template(filename="panel-manager.ui")
class PanelManager(Gtk.Window):
__gtype_name__ = "PanelManager"
all_paths = [data_home / "panorama-panel" / "applets"] + [d / "panorama-panel" / "applets" for d in data_dirs]
return [d for d in all_paths if d.is_dir()]
panel_editing_switch = Gtk.Template.Child()
def __init__(self, application: Gtk.Application, **kwargs):
super().__init__(application=application, **kwargs)
def get_config_file():
config_home = Path(os.getenv("XDG_CONFIG_HOME", Path.home() / ".config"))
self.connect("close-request", lambda *args: self.destroy())
return config_home / "panorama-panel" / "config.yaml"
action_group = Gio.SimpleActionGroup()
toggle_edit_mode_action = Gio.SimpleAction(name="toggle-edit-mode-switch")
action_group.add_action(toggle_edit_mode_action)
toggle_edit_mode_action.connect("activate", lambda *args: self.panel_editing_switch.set_active(not self.panel_editing_switch.get_active()))
class ManagerWindow(Gtk.Window):
def __init__(self):
super().__init__()
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.set_child(box)
switch_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.edit_mode_switch = Gtk.Switch()
switch_box.append(self.edit_mode_switch)
edit_mode_label = Gtk.Label()
edit_mode_label.set_text("Panel editing")
edit_mode_label.set_mnemonic_widget(self.edit_mode_switch)
switch_box.append(edit_mode_label)
box.append(switch_box)
self.insert_action_group("win", action_group)
if isinstance(self.get_application(), PanoramaPanel):
self.panel_editing_switch.set_active(application.edit_mode)
self.panel_editing_switch.connect("state-set", self.set_edit_mode)
self.edit_mode_switch.connect("state-set", self.set_edit_mode)
self.connect("close-request", lambda *args: self.destroy())
self.set_title("Panel configuration")
def set_edit_mode(self, switch, value):
if isinstance(self.get_application(), PanoramaPanel):
self.get_application().set_edit_mode(value)
self.connect("close-request", self.on_destroy)
def on_destroy(self, widget):
self.destroy()
if self.get_application():
self.get_application().manager_window = None
def get_applet_directories():
data_home = Path(os.getenv("XDG_DATA_HOME", Path.home() / ".local" / "share"))
data_dirs = [Path(d) for d in os.getenv("XDG_DATA_DIRS", "/usr/local/share:/usr/share").split(":")]
def set_edit_mode(self, switch, value):
print(f"Editing is {value}")
all_paths = [data_home / "panorama-panel" / "applets"] + [d / "panorama-panel" / "applets" for d in data_dirs]
return [d for d in all_paths if d.is_dir()]
if value:
for panel in panels:
panel.set_edit_mode(True)
else:
for panel in panels:
panel.set_edit_mode(False)
def get_config_file():
config_home = Path(os.getenv("XDG_CONFIG_HOME", Path.home() / ".config"))
return config_home / "panorama-panel" / "config.yaml"
class AppletArea(Gtk.Box):
@@ -160,8 +155,8 @@ class Panel(Gtk.Window):
print("Showing manager")
if self.get_application():
if not self.get_application().manager_window:
self.get_application().manager_window = ManagerWindow()
self.get_application().manager_window.set_application(self.get_application())
self.get_application().manager_window = PanelManager(self.get_application())
self.get_application().manager_window.connect("close-request", self.get_application().reset_manager_window)
self.get_application().manager_window.present()
def get_orientation(self):
@@ -220,6 +215,7 @@ class PanoramaPanel(Gtk.Application):
self.applets_by_name = {}
self.panels = []
self.manager_window = None
self.edit_mode = False
def do_startup(self):
Gtk.Application.do_startup(self)
@@ -297,6 +293,14 @@ class PanoramaPanel(Gtk.Application):
Gtk.Application.do_shutdown(self)
self.save_config()
def set_edit_mode(self, value):
self.edit_mode = value
for panel in self.panels:
panel.set_edit_mode(value)
def reset_manager_window(self, *args):
self.manager_window = None
if __name__ == "__main__":
app = PanoramaPanel()
panel-manager.cmb
@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
<!-- Created with Cambalache 0.96.1 -->
<cambalache-project version="0.96.0" target_tk="gtk-4.0">
<ui template-class="PanelManager" filename="panel-manager.ui" sha256="aa48b67ba698d273b209d7ead4e7ef3f40511b9ab555cc29c88837999013b9ba"/>
<ui template-class="PanelConfigurator" filename="panel-configurator.ui" sha256="d247205b06581ddcde855e0e0e3b9cacda44d393117393bab8505455f04bc876"/>
</cambalache-project>
panel-manager.ui
@@ -0,0 +1,136 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.96.1 -->
<interface>
<!-- interface-name panel-manager.ui -->
<requires lib="gtk" version="4.6"/>
<template class="PanelManager" parent="GtkWindow">
<property name="default-height">320</property>
<property name="default-width">576</property>
<property name="title" translatable="yes">Panel management</property>
<child>
<object class="GtkScrolledWindow">
<child>
<object class="GtkViewport">
<child>
<object class="GtkBox">
<property name="margin-bottom">32</property>
<property name="margin-end">32</property>
<property name="margin-start">32</property>
<property name="margin-top">32</property>
<property name="orientation">vertical</property>
<property name="spacing">4</property>
<child>
<object class="GtkFrame">
<property name="label-widget">
<object class="GtkLabel">
<property name="label" translatable="yes">General options</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</property>
<child>
<object class="GtkListBox">
<property name="selection-mode">none</property>
<child>
<object class="GtkListBoxRow">
<property name="action-name">win.toggle-edit-mode-switch</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel">
<property name="hexpand">True</property>
<property name="label" translatable="yes">Panel _editing mode</property>
<property name="mnemonic-widget">panel_editing_switch</property>
<property name="use-underline">True</property>
<property name="wrap">True</property>
<property name="xalign">0.0</property>
</object>
</child>
<child>
<object class="GtkSwitch" id="panel_editing_switch">
<property name="halign">end</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">False</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">4</property>
<child>
<object class="GtkButton" id="save_now_button">
<property name="label" translatable="yes">_Save settings now</property>
<property name="use-underline">True</property>
<signal name="clicked" handler="save_settings"/>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="hexpand">True</property>
<property name="label" translatable="yes">The configuration is also saved when exiting the app.</property>
<property name="wrap">True</property>
<property name="xalign">0.0</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">4</property>
<child>
<object class="GtkCenterBox">
<child type="center">
<object class="GtkLabel" id="current_panel_label">
<property name="justify">center</property>
<property name="label" translatable="yes">No panel selected</property>
</object>
</child>
<child type="end">
<object class="GtkButton" id="next_panel_button">
<property name="action-name">win.next-panel</property>
<property name="icon-name">go-next-symbolic</property>
<property name="tooltip-text" translatable="yes">Next panel</property>
</object>
</child>
<child type="start">
<object class="GtkButton" id="previous_panel_button">
<property name="action-name">win.previous-panel</property>
<property name="has-tooltip">True</property>
<property name="icon-name">go-previous-symbolic</property>
<property name="tooltip-text" translatable="yes">Previous panel</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkStack">
<property name="transition-type">slide-left-right</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>