Screen rotation dialog
This commit is contained in:
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "bbctrl",
|
"name": "bbctrl",
|
||||||
"version": "1.0.10b2",
|
"version": "1.0.10b4",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "bbctrl",
|
"name": "bbctrl",
|
||||||
"version": "1.0.10b2",
|
"version": "1.0.10b4",
|
||||||
"license": "GPL-3.0+",
|
"license": "GPL-3.0+",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"browserify": "^17.0.0",
|
"browserify": "^17.0.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "bbctrl",
|
"name": "bbctrl",
|
||||||
"version": "1.0.10b2",
|
"version": "1.0.10b4",
|
||||||
"homepage": "https://onefinitycnc.com/",
|
"homepage": "https://onefinitycnc.com/",
|
||||||
"repository": "https://github.com/OneFinityCNC/onefinity",
|
"repository": "https://github.com/OneFinityCNC/onefinity",
|
||||||
"license": "GPL-3.0+",
|
"license": "GPL-3.0+",
|
||||||
|
|||||||
@@ -21,5 +21,11 @@ module.exports = {
|
|||||||
this.$dispatch('config-changed');
|
this.$dispatch('config-changed');
|
||||||
return false;
|
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
|
.pure-form.pure-form-aligned
|
||||||
fieldset
|
fieldset
|
||||||
h2 Units
|
h2 Screen
|
||||||
.pure-control-group
|
.pure-control-group
|
||||||
label(for="units") units
|
label(for="screen-rotation")
|
||||||
select(name="units", v-model="display_units")
|
button.pure-button(name="screen-rotation", @click="showScreenRotationDialog") Change Screen Rotation
|
||||||
option(value="METRIC") METRIC
|
|
||||||
option(value="IMPERIAL") IMPERIAL
|
|
||||||
|
|
||||||
fieldset
|
fieldset
|
||||||
h2 Probe Dimensions
|
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")
|
:model.sync="config.probe[$key]", :template="templ")
|
||||||
|
|
||||||
fieldset
|
fieldset
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import json
|
import json
|
||||||
import tornado
|
import tornado
|
||||||
import sockjs.tornado
|
import sockjs.tornado
|
||||||
@@ -349,6 +350,46 @@ class JogHandler(bbctrl.APIHandler):
|
|||||||
self.get_ctrl().mach.jog(self.json)
|
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
|
# Base class for Web Socket connections
|
||||||
class ClientConnection(object):
|
class ClientConnection(object):
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
@@ -484,6 +525,7 @@ class Web(tornado.web.Application):
|
|||||||
(r'/api/modbus/write', ModbusWriteHandler),
|
(r'/api/modbus/write', ModbusWriteHandler),
|
||||||
(r'/api/jog', JogHandler),
|
(r'/api/jog', JogHandler),
|
||||||
(r'/api/video', bbctrl.VideoHandler),
|
(r'/api/video', bbctrl.VideoHandler),
|
||||||
|
(r'/api/screen-rotation', ScreenRotationHandler),
|
||||||
(r'/(.*)', StaticFileHandler,
|
(r'/(.*)', StaticFileHandler,
|
||||||
{'path': bbctrl.get_resource('http/'),
|
{'path': bbctrl.get_resource('http/'),
|
||||||
'default_filename': 'index.html'}),
|
'default_filename': 'index.html'}),
|
||||||
|
|||||||
@@ -88,7 +88,7 @@
|
|||||||
<Label>Cancel</Label>
|
<Label>Cancel</Label>
|
||||||
</Button>
|
</Button>
|
||||||
<Button defaultAction on:click={onConfirm} disabled={hostname.length === 0}>
|
<Button defaultAction on:click={onConfirm} disabled={hostname.length === 0}>
|
||||||
<Label>Confirm</Label>
|
<Label>Confirm & Reboot</Label>
|
||||||
</Button>
|
</Button>
|
||||||
</Actions>
|
</Actions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|||||||
@@ -1,31 +1,48 @@
|
|||||||
<script lang="ts" context="module">
|
<script lang="ts" context="module">
|
||||||
|
import { writable } from "svelte/store";
|
||||||
import HomeMachineDialog from "$dialogs/HomeMachineDialog.svelte";
|
import HomeMachineDialog from "$dialogs/HomeMachineDialog.svelte";
|
||||||
import ProbeDialog from "$dialogs/ProbeDialog.svelte";
|
import ProbeDialog from "$dialogs/ProbeDialog.svelte";
|
||||||
import {
|
import ScreenRotationDialog from "$dialogs/ScreenRotationDialog.svelte";
|
||||||
HomeMachineProps,
|
|
||||||
ProbeProps,
|
const HomeMachineDialogProps = writable<HomeMachineDialogPropsType>();
|
||||||
type HomeMachinePropsType,
|
type HomeMachineDialogPropsType = {
|
||||||
type ProbePropsType,
|
open: boolean;
|
||||||
} from "$dialogs/DialogProps";
|
home: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ProbeDialogProps = writable<ProbeDialogPropsType>();
|
||||||
|
type ProbeDialogPropsType = {
|
||||||
|
open: boolean;
|
||||||
|
probeType: "xyz" | "z";
|
||||||
|
};
|
||||||
|
|
||||||
|
const ScreenRotationDialogProps = writable<ProbeDialogPropsType>();
|
||||||
|
type ScreenRotationDialogPropsType = {
|
||||||
|
open: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
export function showDialog(
|
export function showDialog(
|
||||||
dialog: "HomeMachine",
|
dialog: "HomeMachine",
|
||||||
props: Omit<HomeMachinePropsType, "open">
|
props: Omit<HomeMachineDialogPropsType, "open">
|
||||||
);
|
);
|
||||||
|
|
||||||
export function showDialog(
|
export function showDialog(
|
||||||
dialog: "Probe",
|
dialog: "Probe",
|
||||||
props: Omit<ProbePropsType, "open">
|
props: Omit<ProbeDialogPropsType, "open">
|
||||||
);
|
);
|
||||||
|
|
||||||
export function showDialog(dialog: string, props: any) {
|
export function showDialog(dialog: string, props: any) {
|
||||||
switch (dialog) {
|
switch (dialog) {
|
||||||
case "HomeMachine":
|
case "HomeMachine":
|
||||||
HomeMachineProps.set({ ...props, open: true });
|
HomeMachineDialogProps.set({ ...props, open: true });
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "Probe":
|
case "Probe":
|
||||||
ProbeProps.set({ ...props, open: true });
|
ProbeDialogProps.set({ ...props, open: true });
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "ScreenRotation":
|
||||||
|
ScreenRotationDialogProps.set({ ...props, open: true });
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -34,5 +51,6 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<HomeMachineDialog {...$HomeMachineProps} />
|
<HomeMachineDialog {...$HomeMachineDialogProps} />
|
||||||
<ProbeDialog {...$ProbeProps} />
|
<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}
|
on:click={onConfirm}
|
||||||
disabled={needPassword && (password.length < 8 || password.length > 128)}
|
disabled={needPassword && (password.length < 8 || password.length > 128)}
|
||||||
>
|
>
|
||||||
<Label>{connectOrDisconnect}</Label>
|
<Label>{connectOrDisconnect} & Reboot</Label>
|
||||||
</Button>
|
</Button>
|
||||||
</Actions>
|
</Actions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|||||||
Reference in New Issue
Block a user