]> git.mar77i.info Git - zenbook_gui/commitdiff
store settings in a keyboard config file
authormar77i <mar77i@protonmail.ch>
Fri, 19 Sep 2025 08:40:17 +0000 (10:40 +0200)
committermar77i <mar77i@protonmail.ch>
Fri, 19 Sep 2025 08:40:17 +0000 (10:40 +0200)
keyboard/config.py [new file with mode: 0644]
keyboard/keyboard.py
keyboard/layout.py
keyboard/menu.py

diff --git a/keyboard/config.py b/keyboard/config.py
new file mode 100644 (file)
index 0000000..60cd65d
--- /dev/null
@@ -0,0 +1,31 @@
+import json
+import os
+import sys
+from traceback import print_exc
+from pathlib import Path
+
+
+class Config:
+    def __init__(self, base):
+        self.path = Path(
+            os.environ.get(
+                "XDG_CONFIG_HOME", f"{os.path.expanduser('~')}{os.pathsep}.config"
+            )
+        ) / "zenbook_gui" / f"{base}.json"
+        self.loaded = None
+
+    def load(self):
+        try:
+            with self.path.open("rt") as fh:
+                self.loaded = json.load(fh)
+                return self.loaded
+        except Exception:
+            print_exc(file=sys.stderr)
+            return None
+
+    def save(self, data):
+        if data == self.loaded:
+            return
+        self.path.parent.mkdir(0o755, parents=True, exist_ok=True)
+        with self.path.open("wt") as fh:
+            json.dump(data, fh)
index ef4acdd180d163cefa7e192afe261aab2580381a..fe1c8ceafe60087655393781d3d1b79f302835a8 100644 (file)
@@ -34,7 +34,7 @@ class Root(BaseRoot):
         self.led_mask = self.display.get_keyboard_control().led_mask
         FPSWidget(self)
         size = self.surf.get_size()
-        self.settings_modal = MenuModal(
+        self.menu_modal = MenuModal(
             self,
             pygame.Rect((size[0] // 4, size[1] // 4), (size[0] // 2, size[1] // 2)),
         )
@@ -48,15 +48,15 @@ class Root(BaseRoot):
         half_height = size[1] // 2
         for row in range(2):
             widget_top = half_height * row
-            if row == self.settings_modal.layout_modal.keyboard_row:
+            if row == self.menu_modal.layout_modal.keyboard_row:
                 get_keyboard_keys(
                     self,
-                    pygame.Rect((widget_top, 0), (size[0], half_height)),
+                    pygame.Rect((0, widget_top), (size[0], half_height)),
                     self.key_cb,
                     KEYBOARD,
                 )
                 continue
-            widget_row = self.settings_modal.layout_modal.widget_row
+            widget_row = self.menu_modal.layout_modal.widget_row
             widget_width = size[0] // (3 if len(widget_row) == 3 else 2)
             x = 0 if len(widget_row) > 0 else size[0] // 4
             for keyset in widget_row:
@@ -71,7 +71,8 @@ class Root(BaseRoot):
 
     def key_cb(self, key, release=False):
         if key == "Settings":
-            self.settings_modal.activate()
+            if not release:
+                self.menu_modal.activate()
         if isinstance(key, (Key, KeyCode)):
             if release:
                 self.keyboard.release(key)
@@ -90,7 +91,7 @@ class Root(BaseRoot):
             if button in self.pushed:
                 self.mouse.release(button)
                 self.pushed.remove(button)
-        elif n is not None:
+        elif n > 1:
             self.mouse.click(button, n)
         else:
             self.mouse.press(button)
@@ -117,7 +118,8 @@ class Root(BaseRoot):
         finally:
             for key in self.pushed:
                 (self.mouse if isinstance(key, Button) else self.keyboard).release(key)
+            self.menu_modal.save_config()
 
     @property
     def muted(self):
-        return self.settings_modal.muted
+        return self.menu_modal.muted
index 0035a6ff0239dc7c43b2947b61d6c429c5eca26e..92936a1d6fefc7f0a0d20b9c4da9f0eca4a89f73 100644 (file)
@@ -152,6 +152,11 @@ class LayoutWidget(Child):
             self.keyboard_callback,
         )
 
+    def activate(self):
+        self.keyboard.rect = self.keyboard_rects[self.parent.keyboard_row]
+        self.keyboard.dests.clear()
+        self.keyboard.dests.append(self.keyboard_rects[not self.parent.keyboard_row])
+
     def keyboard_callback(self):
         self.parent.keyboard_row = int(
             (self.keyboard.rect.top - self.rect.top) * 2 / self.rect.height
@@ -173,7 +178,14 @@ class LayoutWidget(Child):
 
 
 class LayoutModal(QuittableModal):
-    def __init__(self, parent):
+    WIDGETS = {
+        "KEYPAD_KEYS": KEYPAD_KEYS,
+        "CURSOR_KEYS": CURSOR_KEYS,
+        "MousePadWidget": MousePadWidget,
+        "ClockWidget": ClockWidget,
+    }
+
+    def __init__(self, parent, config=None):
         super().__init__(parent)
         size = self.surf.get_size()
         self.rect = pygame.Rect(150, 150, size[0] - 300, size[1] - 300)
@@ -185,6 +197,43 @@ class LayoutModal(QuittableModal):
             self.deactivate,
         )
         self.keyboard_row = 0
-        self.widget_row = [CURSOR_KEYS, MousePadWidget, ClockWidget]
+        self.widget_row = []
         half_size = (size[0] / 2, size[1] / 2)
-        LayoutWidget(self, pygame.Rect((half_size[0] / 2, half_size[1] / 2), half_size))
+        self.layout_widget = LayoutWidget(
+            self, pygame.Rect((half_size[0] / 2, half_size[1] / 2), half_size)
+        )
+
+    def activate(self):
+        super().activate()
+        self.layout_widget.activate()
+
+    def deactivate(self):
+        self.root.setup_widgets()
+        super().deactivate()
+
+    def apply_config(self, data):
+        if "keyboard_row" in data:
+            self.keyboard_row = data["keyboard_row"]
+        if "widget_row" in data:
+            self.widget_row.clear()
+            self.widget_row.extend(
+                w for w in (self.WIDGETS.get(key) for key in data["widget_row"]) if w
+            )
+
+    @classmethod
+    def stringify_widgets(cls, widget_row):
+        result = [None] * len(widget_row)
+        for key, value in cls.WIDGETS.items():
+            try:
+                index = widget_row.index(value)
+            except ValueError:
+                continue
+            else:
+                result[index] = key
+        return result
+
+    def get_config(self):
+        return {
+            "keyboard_row": self.keyboard_row,
+            "widget_row": self.stringify_widgets(self.widget_row),
+        }
index 6c3b3e36a40df18d3d491d58ba14807cb1b78cf1..3956486a7e9028a737f08eb080d4f587a95d5091 100644 (file)
@@ -1,3 +1,4 @@
+import atexit
 import os
 import sys
 from functools import partial
@@ -8,17 +9,10 @@ import pygame
 
 from ui import QuittableModal, Rect
 
+from .config import Config
 from .touchbutton import TouchButton
 from .layout import LayoutModal
 
-# what settings do we need?
-# - configure widgets
-#   - keyboard above, two widgets below
-#   - keyboard above, three widgets below
-#   - keyboard below, two widgets above
-#   - keyboard below, three widgets above
-#   - three available widgets: touchpad mouse, number keypad, cursor and navkeys
-
 
 class MenuModal(QuittableModal):
     def __init__(self, parent, rect):
@@ -26,14 +20,16 @@ class MenuModal(QuittableModal):
         self.rect = rect
         self.layout_modal = LayoutModal(parent)
         self.muted = False
+        self.config = Config("keyboard")
+        self.load_config()
         Rect(self, rect, "black", "gray")
         buttons_args = (
+            ("Back", self.deactivate),
             ("Mute", None, self.muted),
             ("Layout...", self.layout_modal.activate),
             ("Fix Xkb layout", self.fix_xkb_layout),
-            ("Restart", self.restart),
+            ("Restart", self.prepare_restart),
             ("Exit", self.root.handle_quit),
-            ("Back", self.deactivate),
         )
         width = rect.width * 2 / 3
         height = rect.height / len(buttons_args)
@@ -47,6 +43,20 @@ class MenuModal(QuittableModal):
                 button.callback = partial(self.mute, button)
             y += height
 
+    def load_config(self):
+        data = self.config.load()
+        if not data:
+            return
+        if "layout" in data:
+            self.layout_modal.apply_config(data["layout"])
+        if "muted" in data:
+            self.muted = data["muted"]
+
+    def save_config(self):
+        self.config.save(
+            {"muted": self.muted, "layout": self.layout_modal.get_config()}
+        )
+
     def mute(self, button):
         self.muted ^= True
         button.highlight = self.muted
@@ -55,7 +65,13 @@ class MenuModal(QuittableModal):
         run(["setxkbmap", "-synch"])
         self.deactivate()
 
-    def restart(self):
+    def prepare_restart(self):
+        atexit.register(self.restart)
+        self.root.running = False
+        self.deactivate()
+
+    @staticmethod
+    def restart():
         executable = Path(sys.executable).name
         os.execl(
             sys.executable,