Screen rotation dialog
This commit is contained in:
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "bbctrl",
|
||||
"version": "1.0.10b2",
|
||||
"version": "1.0.10b4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "bbctrl",
|
||||
"version": "1.0.10b2",
|
||||
"version": "1.0.10b4",
|
||||
"license": "GPL-3.0+",
|
||||
"dependencies": {
|
||||
"browserify": "^17.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bbctrl",
|
||||
"version": "1.0.10b2",
|
||||
"version": "1.0.10b4",
|
||||
"homepage": "https://onefinitycnc.com/",
|
||||
"repository": "https://github.com/OneFinityCNC/onefinity",
|
||||
"license": "GPL-3.0+",
|
||||
|
||||
@@ -21,5 +21,11 @@ module.exports = {
|
||||
this.$dispatch('config-changed');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
showScreenRotationDialog: function () {
|
||||
SvelteComponents.showDialog("ScreenRotation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,16 +4,14 @@ script#settings-view-template(type="text/x-template")
|
||||
|
||||
.pure-form.pure-form-aligned
|
||||
fieldset
|
||||
h2 Units
|
||||
h2 Screen
|
||||
.pure-control-group
|
||||
label(for="units") units
|
||||
select(name="units", v-model="display_units")
|
||||
option(value="METRIC") METRIC
|
||||
option(value="IMPERIAL") IMPERIAL
|
||||
label(for="screen-rotation")
|
||||
button.pure-button(name="screen-rotation", @click="showScreenRotationDialog") Change Screen Rotation
|
||||
|
||||
fieldset
|
||||
h2 Probe Dimensions
|
||||
templated-input(v-for="templ in template.probe", :name="$key",
|
||||
templated-input(v-for="templ in template.probe", v-if="$key !== 'probe-diameter'", :name="$key"
|
||||
:model.sync="config.probe[$key]", :template="templ")
|
||||
|
||||
fieldset
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
import tornado
|
||||
import sockjs.tornado
|
||||
@@ -349,6 +350,46 @@ class JogHandler(bbctrl.APIHandler):
|
||||
self.get_ctrl().mach.jog(self.json)
|
||||
|
||||
|
||||
displayRotatePattern = re.compile(r'display_rotate\s*=\s*(\d)')
|
||||
transformationMatrixPattern = re.compile(
|
||||
r'(\n)(\s+)(MatchIsTouchscreen.*?\n)(\s+Option\s+\"TransformationMatrix\".*?\n)(.*?EndSection)', re.DOTALL)
|
||||
matchIsTouchscreenPattern = re.compile(
|
||||
r'(\n)(\s+)(MatchIsTouchscreen.*?\n)(.*?EndSection)', re.DOTALL)
|
||||
|
||||
|
||||
class ScreenRotationHandler(bbctrl.APIHandler):
|
||||
@gen.coroutine
|
||||
def get(self):
|
||||
with open("/boot/config.txt", 'rt') as config:
|
||||
lines = config.readlines()
|
||||
for line in lines:
|
||||
if line.startswith('display_rotate'):
|
||||
self.write_json({
|
||||
'rotated': int(displayRotatePattern.search(line).group(1)) != 0
|
||||
})
|
||||
return
|
||||
|
||||
self.write_json({'rotated': False})
|
||||
return
|
||||
|
||||
@gen.coroutine
|
||||
def put_ok(self):
|
||||
rotated = self.json['rotated']
|
||||
|
||||
subprocess.Popen(
|
||||
['/usr/local/bin/edit-boot-config', 'display_rotate={}'.format(2 if rotated else 0)])
|
||||
|
||||
with open("/usr/share/X11/xorg.conf.d/40-libinput.conf", 'rt') as config:
|
||||
text = config.read()
|
||||
text = transformationMatrixPattern.sub(r'\1\2\3\5', text)
|
||||
if rotated:
|
||||
text = matchIsTouchscreenPattern.sub(r'\1\2\3\2Option "TransformationMatrix" "-1 0 1 0 -1 1 0 0 1"\1\4', text)
|
||||
with open("/usr/share/X11/xorg.conf.d/40-libinput.conf", 'wt') as config:
|
||||
config.write(text)
|
||||
|
||||
subprocess.run('reboot')
|
||||
|
||||
|
||||
# Base class for Web Socket connections
|
||||
class ClientConnection(object):
|
||||
def __init__(self, app):
|
||||
@@ -484,6 +525,7 @@ class Web(tornado.web.Application):
|
||||
(r'/api/modbus/write', ModbusWriteHandler),
|
||||
(r'/api/jog', JogHandler),
|
||||
(r'/api/video', bbctrl.VideoHandler),
|
||||
(r'/api/screen-rotation', ScreenRotationHandler),
|
||||
(r'/(.*)', StaticFileHandler,
|
||||
{'path': bbctrl.get_resource('http/'),
|
||||
'default_filename': 'index.html'}),
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
<Button defaultAction on:click={onConfirm} disabled={hostname.length === 0}>
|
||||
<Label>Confirm</Label>
|
||||
<Label>Confirm & Reboot</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
|
||||
@@ -1,31 +1,48 @@
|
||||
<script lang="ts" context="module">
|
||||
import { writable } from "svelte/store";
|
||||
import HomeMachineDialog from "$dialogs/HomeMachineDialog.svelte";
|
||||
import ProbeDialog from "$dialogs/ProbeDialog.svelte";
|
||||
import {
|
||||
HomeMachineProps,
|
||||
ProbeProps,
|
||||
type HomeMachinePropsType,
|
||||
type ProbePropsType,
|
||||
} from "$dialogs/DialogProps";
|
||||
import ScreenRotationDialog from "$dialogs/ScreenRotationDialog.svelte";
|
||||
|
||||
const HomeMachineDialogProps = writable<HomeMachineDialogPropsType>();
|
||||
type HomeMachineDialogPropsType = {
|
||||
open: boolean;
|
||||
home: () => void;
|
||||
};
|
||||
|
||||
const ProbeDialogProps = writable<ProbeDialogPropsType>();
|
||||
type ProbeDialogPropsType = {
|
||||
open: boolean;
|
||||
probeType: "xyz" | "z";
|
||||
};
|
||||
|
||||
const ScreenRotationDialogProps = writable<ProbeDialogPropsType>();
|
||||
type ScreenRotationDialogPropsType = {
|
||||
open: boolean;
|
||||
};
|
||||
|
||||
export function showDialog(
|
||||
dialog: "HomeMachine",
|
||||
props: Omit<HomeMachinePropsType, "open">
|
||||
props: Omit<HomeMachineDialogPropsType, "open">
|
||||
);
|
||||
|
||||
export function showDialog(
|
||||
dialog: "Probe",
|
||||
props: Omit<ProbePropsType, "open">
|
||||
props: Omit<ProbeDialogPropsType, "open">
|
||||
);
|
||||
|
||||
export function showDialog(dialog: string, props: any) {
|
||||
switch (dialog) {
|
||||
case "HomeMachine":
|
||||
HomeMachineProps.set({ ...props, open: true });
|
||||
HomeMachineDialogProps.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
case "Probe":
|
||||
ProbeProps.set({ ...props, open: true });
|
||||
ProbeDialogProps.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
case "ScreenRotation":
|
||||
ScreenRotationDialogProps.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -34,5 +51,6 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<HomeMachineDialog {...$HomeMachineProps} />
|
||||
<ProbeDialog {...$ProbeProps} />
|
||||
<HomeMachineDialog {...$HomeMachineDialogProps} />
|
||||
<ProbeDialog {...$ProbeDialogProps} />
|
||||
<ScreenRotationDialog {...$ScreenRotationDialogProps} />
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
export const HomeMachineProps = writable<HomeMachinePropsType>();
|
||||
export type HomeMachinePropsType = {
|
||||
open: boolean,
|
||||
home: () => void
|
||||
}
|
||||
|
||||
export const ProbeProps = writable<ProbePropsType>();
|
||||
export type ProbePropsType = {
|
||||
open: boolean,
|
||||
probeType: "xyz" | "z"
|
||||
};
|
||||
@@ -0,0 +1,76 @@
|
||||
<script type="ts">
|
||||
import Dialog, { Title, Content, Actions } from "@smui/dialog";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import Radio from "@smui/radio";
|
||||
import FormField from "@smui/form-field";
|
||||
import MessageDialog from "$dialogs/MessageDialog.svelte";
|
||||
import * as Api from "$lib/api";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
const options = [
|
||||
{ value: 0, label: "Normal" },
|
||||
{ value: 1, label: "Upside-down" },
|
||||
];
|
||||
|
||||
export let open;
|
||||
let currentValue;
|
||||
let value;
|
||||
let rebooting;
|
||||
|
||||
onMount(async () => {
|
||||
const result = await Api.GET("screen-rotation");
|
||||
currentValue = value = result.rotated ? 1 : 0;
|
||||
});
|
||||
|
||||
async function onConfirm() {
|
||||
rebooting = true;
|
||||
|
||||
await Api.PUT("screen-rotation", { rotated: value === 1 });
|
||||
}
|
||||
</script>
|
||||
|
||||
<MessageDialog open={rebooting} title="Rebooting">
|
||||
Rebooting to apply the new screen rotation...
|
||||
</MessageDialog>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="screen-rotation-title"
|
||||
aria-describedby="screen-rotation-content"
|
||||
>
|
||||
<Title id="screen-rotation-title">Screen Rotation</Title>
|
||||
|
||||
<Content id="screen-rotation-content">
|
||||
{#each options as option}
|
||||
<FormField>
|
||||
<Radio bind:group={value} value={option.value} />
|
||||
<span slot="label">
|
||||
{option.label}
|
||||
</span>
|
||||
</FormField>
|
||||
{/each}
|
||||
</Content>
|
||||
|
||||
<Actions>
|
||||
<Button>
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
<Button
|
||||
defaultAction
|
||||
disabled={value === currentValue}
|
||||
on:click={onConfirm}
|
||||
>
|
||||
<Label>Confirm & Reboot</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
|
||||
<style lang="scss">
|
||||
:global {
|
||||
#screen-rotation-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -92,7 +92,7 @@
|
||||
on:click={onConfirm}
|
||||
disabled={needPassword && (password.length < 8 || password.length > 128)}
|
||||
>
|
||||
<Label>{connectOrDisconnect}</Label>
|
||||
<Label>{connectOrDisconnect} & Reboot</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
|
||||
Reference in New Issue
Block a user