From 2f3094d3db69285b7fbcbc46acee987456ae9f72 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 16 Jul 2019 12:56:02 +1000 Subject: [PATCH] Allow for orientation changes for the device This is saved for posterity in the new settings file, so we need a new Config object (singleton is enough here). For now, whenever the orientation changes, we just wipe our UI and re-generate all SVG files. Much easier than messing with proper SVG rotation given that a device should only ever change between rotations once. --- tuhigui/config.py | 73 +++++++++++++++++++++++++++++++++++ tuhigui/drawingperspective.py | 13 +++++++ tuhigui/svg.py | 13 ++++--- tuhigui/window.py | 27 +++++++++++-- 4 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 tuhigui/config.py diff --git a/tuhigui/config.py b/tuhigui/config.py new file mode 100644 index 0000000..ba4f608 --- /dev/null +++ b/tuhigui/config.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# + + +from gi.repository import GObject + +import xdg.BaseDirectory +import configparser +import os +import logging + +logger = logging.getLogger('config') + +ROOT_PATH = os.path.join(xdg.BaseDirectory.xdg_data_home, 'tuhigui') + + +class Config(GObject.Object): + _config_obj = None + + def __init__(self): + super().__init__() + self.path = os.path.join(ROOT_PATH, 'tuhigui.ini') + self.config = configparser.ConfigParser() + # Don't lowercase options + self.config.optionxform = str + self._load() + + def _load(self): + if not os.path.exists(self.path): + return + + logger.debug(f'configuration found') + self.config.read(self.path) + + def _write(self): + if not os.path.exists(ROOT_PATH): + os.mkdir(ROOT_PATH) + with open(self.path, 'w') as fd: + self.config.write(fd) + + @GObject.property + def orientation(self): + try: + return self.config['Device']['Orientation'] + except KeyError: + return 'landscape' + + @orientation.setter + def orientation(self, orientation): + assert(orientation in ['landscape', 'portrait']) + self._add_key('Device', 'Orientation', orientation) + + def _add_key(self, section, key, value): + if section not in self.config: + self.config[section] = {} + self.config[section][key] = value + self._write() + + @classmethod + def load(cls): + if cls._config_obj is None: + cls._config_obj = Config() + return cls._config_obj diff --git a/tuhigui/drawingperspective.py b/tuhigui/drawingperspective.py index 71e8b9b..30ad97b 100644 --- a/tuhigui/drawingperspective.py +++ b/tuhigui/drawingperspective.py @@ -14,6 +14,7 @@ from gi.repository import GObject, Gtk from .drawing import Drawing from .svg import JsonSvg +from .config import Config import json import time @@ -61,6 +62,18 @@ class DrawingPerspective(Gtk.Stack): self.last_sync_time = 0 self._sync_label_timer = GObject.timeout_add_seconds(60, self._update_sync_label) self._update_sync_label() + Config.load().connect('notify::orientation', self._on_orientation_changed) + + def _on_orientation_changed(self, config, pspec): + # When the orientation changes, we just re-generate all SVGs. This + # isn't something that should happen very often anyway so meh. + self.known_drawings = [] + child = self.flowbox_drawings.get_child_at_index(0) + while child is not None: + self.flowbox_drawings.remove(child) + child = self.flowbox_drawings.get_child_at_index(0) + + self._update_drawings(self.device, None) def _update_drawings(self, device, pspec): for ts in reversed(sorted(self.device.drawings_available)): diff --git a/tuhigui/svg.py b/tuhigui/svg.py index 753e1f7..7b785fc 100644 --- a/tuhigui/svg.py +++ b/tuhigui/svg.py @@ -12,6 +12,9 @@ # from gi.repository import GObject + +from .config import Config + import xdg.BaseDirectory import svgwrite import os @@ -29,7 +32,7 @@ class JsonSvg(GObject.Object): self.timestamp = json['timestamp'] self.filename = os.path.join(DATA_PATH, f'{self.timestamp}.svg') - self.orientation = 'Landscape' + self.orientation = Config.load().orientation self._convert() def _convert(self): @@ -42,7 +45,7 @@ class JsonSvg(GObject.Object): # so we normalize them width, height = dimensions[0] / 100, dimensions[1] / 100 - if self.orientation in ['Portrait', 'Reverse-Portrait']: + if self.orientation in ['portrait', 'reverse-Portrait']: size = (height, width) else: size = (width, height) @@ -58,11 +61,11 @@ class JsonSvg(GObject.Object): # Normalize coordinates too x, y = x / 100, y / 100 - if self.orientation == 'Reverse-Portrait': + if self.orientation == 'reverse-Portrait': x, y = y, width - x - elif self.orientation == 'Portrait': + elif self.orientation == 'portrait': x, y = height - y, x - elif self.orientation == 'Reverse-Landscape': + elif self.orientation == 'reverse-Landscape': x, y = width - x, height - y delta = (p['pressure'] - 1000.0) / 1000.0 diff --git a/tuhigui/window.py b/tuhigui/window.py index b4d7de3..8cb0d1c 100644 --- a/tuhigui/window.py +++ b/tuhigui/window.py @@ -11,12 +11,13 @@ # GNU General Public License for more details. # -from gi.repository import Gtk +from gi.repository import Gtk, Gio, GLib from .setupdialog import SetupDialog from .drawingperspective import DrawingPerspective from .errorperspective import ErrorPerspective from .tuhi import TuhiKeteManager +from .config import Config import logging import gi @@ -29,13 +30,23 @@ MENU_XML = """ +
+ + Portrait + win.orientation + portrait + + + Landscape + win.orientation + landscape + +
Help app.help -
-
About app.about @@ -59,6 +70,12 @@ class MainWindow(Gtk.ApplicationWindow): self._tuhi = TuhiKeteManager() + action = Gio.SimpleAction.new_stateful('orientation', GLib.VariantType('s'), + GLib.Variant('s', 'landscape')) + action.connect('activate', self._on_orientation_changed) + action.set_state(GLib.Variant.new_string(Config.load().orientation)) + self.add_action(action) + builder = Gtk.Builder.new_from_string(MENU_XML, -1) menu = builder.get_object("primary-menu") self.menubutton1.set_menu_model(menu) @@ -114,3 +131,7 @@ class MainWindow(Gtk.ApplicationWindow): def _on_reconnect_tuhi(self, tuhi): self._tuhi = tuhi + + def _on_orientation_changed(self, action, label): + action.set_state(label) + Config.load().orientation = label.get_string() # this is a GVariant