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.
This commit is contained in:
parent
84273a1c83
commit
2f3094d3db
|
@ -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
|
|
@ -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)):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue