--- /dev/null
+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)
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)),
)
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:
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)
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)
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
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
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)
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),
+ }
+import atexit
import os
import sys
from functools import partial
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):
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)
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
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,