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.
pull/145/head
Peter Hutterer 2019-07-16 12:56:02 +10:00
parent 84273a1c83
commit 2f3094d3db
4 changed files with 118 additions and 8 deletions

73
tuhigui/config.py Normal file
View File

@ -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

View File

@ -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)):

View File

@ -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

View File

@ -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 = """
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="primary-menu">
<section>
<item>
<attribute name="label">Portrait</attribute>
<attribute name="action">win.orientation</attribute>
<attribute name="target">portrait</attribute>
</item>
<item>
<attribute name="label">Landscape</attribute>
<attribute name="action">win.orientation</attribute>
<attribute name="target">landscape</attribute>
</item>
</section>
<section>
<item>
<attribute name="label">Help</attribute>
<attribute name="action">app.help</attribute>
</item>
</section>
<section>
<item>
<attribute name="label">About</attribute>
<attribute name="action">app.about</attribute>
@ -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