From 82330b3c2a7db06a603e66239f56f68356fdf216 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Fri, 23 Jan 2015 19:00:09 +0800 Subject: [PATCH] gui: save layout --- artiq/frontend/artiq_gui.py | 18 ++++++++++++--- artiq/gui/parameters.py | 8 ++++--- artiq/gui/rt_results.py | 4 ++-- artiq/gui/scheduler.py | 8 ++++--- artiq/gui/tools.py | 44 +++++++++++++++++++++++++++++++++++-- 5 files changed, 69 insertions(+), 13 deletions(-) diff --git a/artiq/frontend/artiq_gui.py b/artiq/frontend/artiq_gui.py index 4a25b5464..808bff328 100755 --- a/artiq/frontend/artiq_gui.py +++ b/artiq/frontend/artiq_gui.py @@ -7,7 +7,9 @@ import atexit import gbulb from gi.repository import Gtk +from artiq.protocols.file_db import FlatFileDB from artiq.protocols.pc_rpc import AsyncioClient +from artiq.gui.tools import LayoutManager from artiq.gui.scheduler import SchedulerWindow from artiq.gui.parameters import ParametersWindow from artiq.gui.rt_results import RTResults @@ -24,12 +26,18 @@ def get_argparser(): parser.add_argument( "--port-control", default=3251, type=int, help="TCP port to connect to for control") + parser.add_argument( + "--db-file", default="artiq_gui.pyon", + help="database file for local GUI settings") return parser def main(): args = get_argparser().parse_args() + db = FlatFileDB(args.db_file, default_data=dict()) + lmgr = LayoutManager(db) + asyncio.set_event_loop_policy(gbulb.GtkEventLoopPolicy()) loop = asyncio.get_event_loop() atexit.register(lambda: loop.close()) @@ -40,7 +48,9 @@ def main(): args.server, args.port_control, "master_schedule")) atexit.register(lambda: schedule_ctl.close_rpc()) - scheduler_win = SchedulerWindow(schedule_ctl) + scheduler_win = lmgr.create_window(SchedulerWindow, + "scheduler", + schedule_ctl) scheduler_win.connect("delete-event", Gtk.main_quit) scheduler_win.show_all() loop.run_until_complete(scheduler_win.sub_connect( @@ -48,7 +58,8 @@ def main(): atexit.register( lambda: loop.run_until_complete(scheduler_win.sub_close())) - parameters_win = ParametersWindow() + parameters_win = lmgr.create_window(ParametersWindow, + "parameters") parameters_win.connect("delete-event", Gtk.main_quit) parameters_win.show_all() loop.run_until_complete(parameters_win.sub_connect( @@ -62,8 +73,9 @@ def main(): atexit.register( lambda: loop.run_until_complete(rtr.sub_close())) - loop.run_forever() + lmgr.save() + if __name__ == "__main__": main() diff --git a/artiq/gui/parameters.py b/artiq/gui/parameters.py index a48a992ad..62604ad92 100644 --- a/artiq/gui/parameters.py +++ b/artiq/gui/parameters.py @@ -28,9 +28,11 @@ class _LastChangesStoreSyncer(ListSyncer): class ParametersWindow(Window): - def __init__(self): - Window.__init__(self, title="Parameters") - self.set_default_size(500, 500) + def __init__(self, **kwargs): + Window.__init__(self, + title="Parameters", + default_size=(500, 500), + **kwargs) notebook = Gtk.Notebook() self.add(notebook) diff --git a/artiq/gui/rt_results.py b/artiq/gui/rt_results.py index 309107f8d..74c4bd014 100644 --- a/artiq/gui/rt_results.py +++ b/artiq/gui/rt_results.py @@ -13,8 +13,8 @@ class _PlotWindow(Window): self.set_names = set_names self.data = None - Window.__init__(self, title="/".join(set_names)) - self.set_default_size(700, 500) + Window.__init__(self, title="/".join(set_names), + default_size=(700, 500)) self.darea = Gtk.DrawingArea() self.darea.set_size_request(100, 100) diff --git a/artiq/gui/scheduler.py b/artiq/gui/scheduler.py index 2e08c1fcb..bce52110b 100644 --- a/artiq/gui/scheduler.py +++ b/artiq/gui/scheduler.py @@ -34,11 +34,13 @@ class _TimedStoreSyncer(DictSyncer): class SchedulerWindow(Window): - def __init__(self, schedule_ctl): + def __init__(self, schedule_ctl, **kwargs): self.schedule_ctl = schedule_ctl - Window.__init__(self, title="Scheduler") - self.set_default_size(720, 570) + Window.__init__(self, + title="Scheduler", + default_size=(720, 570), + **kwargs) topvbox = Gtk.VBox(spacing=6) self.add(topvbox) diff --git a/artiq/gui/tools.py b/artiq/gui/tools.py index 91f03bc1a..2499a229b 100644 --- a/artiq/gui/tools.py +++ b/artiq/gui/tools.py @@ -7,12 +7,52 @@ data_dir = os.path.abspath(os.path.dirname(__file__)) class Window(Gtk.Window): - def __init__(self, *args, **kwargs): - Gtk.Window.__init__(self, *args, **kwargs) + def __init__(self, title, default_size, layout_dict=dict()): + Gtk.Window.__init__(self, title=title) + self.set_wmclass("ARTIQ", "ARTIQ") self.set_icon_from_file(os.path.join(data_dir, "icon.png")) self.set_border_width(6) + try: + size = layout_dict["size"] + except KeyError: + size = default_size + self.set_default_size(size[0], size[1]) + try: + position = layout_dict["position"] + except KeyError: + pass + else: + self.move(position[0], position[1]) + + def get_layout_dict(self): + return { + "size": self.get_size(), + "position": self.get_position() + } + + +class LayoutManager: + def __init__(self, db): + self.db = db + self.windows = dict() + + def create_window(self, cls, name, *args, **kwargs): + try: + win_layouts = self.db.request("win_layouts") + layout_dict = win_layouts[name] + except KeyError: + layout_dict = dict() + win = cls(*args, layout_dict=layout_dict, **kwargs) + self.windows[name] = win + return win + + def save(self): + win_layouts = {name: window.get_layout_dict() + for name, window in self.windows.items()} + self.db.set("win_layouts", win_layouts) + class ListSyncer: def __init__(self, store, init):