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+",
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ $# != 3 ]; then
|
||||
echo "Usage: $0 <width> <height> <rotation>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
WIDTH="$1"
|
||||
HEIGHT="$2"
|
||||
ROTATION="$3"
|
||||
|
||||
if [[ ! "$WIDTH" =~ ^[0-9]+$ ]]; then
|
||||
echo "Invalid width '$WIDTH'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! "$HEIGHT" =~ ^[0-9]+$ ]]; then
|
||||
echo "Invalid height '$HEIGHT'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! "$ROTATION" =~ ^[0-3]$ ]]; then
|
||||
echo "Invalid rotation '$ROTATION'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
OPTIONS="framebuffer_width=$WIDTH "
|
||||
OPTIONS+="framebuffer_height=$HEIGHT "
|
||||
OPTIONS+="display_rotate=$ROTATION"
|
||||
|
||||
edit-boot-config $OPTIONS
|
||||
@@ -29,8 +29,7 @@ if $UPDATE_AVR; then
|
||||
fi
|
||||
|
||||
# Update config.txt
|
||||
./scripts/edit-boot-config max_usb_current=1
|
||||
./scripts/edit-boot-config config_hdmi_boost=8
|
||||
./scripts/edit-boot-config max_usb_current=1 config_hdmi_boost=8 hdmi_force_hotplug=1 hdmi_group=2 hdmi_mode=82
|
||||
|
||||
# TODO Enable GPU
|
||||
#./scripts/edit-boot-config dtoverlay=vc4-kms-v3d
|
||||
|
||||
1
setup.py
1
setup.py
@@ -34,7 +34,6 @@ setup(
|
||||
'scripts/sethostname',
|
||||
'scripts/reset-video',
|
||||
'scripts/config-wifi',
|
||||
'scripts/config-screen',
|
||||
'scripts/edit-config',
|
||||
'scripts/edit-boot-config',
|
||||
'scripts/browser',
|
||||
|
||||
@@ -21,5 +21,11 @@ module.exports = {
|
||||
this.$dispatch('config-changed');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
showScreenRotationDialog: function () {
|
||||
SvelteComponents.showDialog("ScreenRotation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ html(lang="en")
|
||||
head
|
||||
meta(charset="utf-8")
|
||||
meta(name="viewport", content="width=device-width, initial-scale=1.0")
|
||||
link(rel="preload" href="/fonts/material-symbols-outlined.woff2" as="font" type="font/woff2" crossorigin)
|
||||
|
||||
title Onefinity CNC - Web interface
|
||||
|
||||
@@ -16,7 +15,6 @@ html(lang="en")
|
||||
style: include ../svelte-components/node_modules/svelte-material-ui/bare.css
|
||||
style: include ../../build/http/svelte-components/smui.css
|
||||
style: include ../../build/http/svelte-components/style.css
|
||||
style: include ../../build/http/svelte-components/material-symbols-outlined.css
|
||||
style: include:stylus ../stylus/style.styl
|
||||
|
||||
body(v-cloak)
|
||||
|
||||
@@ -61,7 +61,7 @@ script#control-view-template(type="text/x-template")
|
||||
button(@click="jog_fn(-1,0,0,0)") X-
|
||||
td(style="height:100px",align="center")
|
||||
button(@click="ask_zero_xy_msg = true")
|
||||
.fa.fa-bullseye(style="font-size: 172%")
|
||||
.fa.fa-bullseye(style="font-size: 173%")
|
||||
td(style="height:100px",align="center")
|
||||
button(@click="jog_fn(1,0,0,0)") X+
|
||||
td(style="height:100px",align="center")
|
||||
@@ -221,7 +221,7 @@ script#control-view-template(type="text/x-template")
|
||||
| {{message.replace(/^#/, '')}}
|
||||
|
||||
tr
|
||||
th Units
|
||||
th Display Units
|
||||
td.units
|
||||
select(v-model="display_units")
|
||||
option(value="METRIC") METRIC
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -71,6 +71,7 @@ class Ctrl(object):
|
||||
def configure(self):
|
||||
# Indirectly configures state via calls to config() and the AVR
|
||||
self.config.reload()
|
||||
self.state.init()
|
||||
|
||||
def ready(self):
|
||||
# This is used to synchronize the start of the preplanner
|
||||
|
||||
@@ -419,3 +419,12 @@ class State(object):
|
||||
if switch[1:] == '-max':
|
||||
return self.get_axis_switch(switch[0], 'max')
|
||||
raise Exception('Unsupported switch "%s"' % switch)
|
||||
|
||||
def init(self):
|
||||
# Init machine units
|
||||
metric = self.ctrl.config.get('units', 'METRIC').upper() == 'METRIC'
|
||||
self.log.info('INIT Metric %d' % metric)
|
||||
if not 'metric' in self.vars:
|
||||
self.set('metric', metric)
|
||||
if not 'imperial' in self.vars:
|
||||
self.set('imperial', not metric)
|
||||
|
||||
@@ -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'}),
|
||||
|
||||
Binary file not shown.
@@ -4,6 +4,9 @@ body
|
||||
[v-cloak]
|
||||
display none
|
||||
|
||||
.menu-link
|
||||
z-index unset
|
||||
|
||||
tt
|
||||
color #000
|
||||
background #eee
|
||||
@@ -356,6 +359,7 @@ span.unit
|
||||
.axis
|
||||
.name
|
||||
text-transform capitalize
|
||||
vertical-align middle
|
||||
|
||||
.name, .position
|
||||
font-size 24pt
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
/* To browse the icons in material-symbols, see https://marella.me/material-symbols/demo/ */
|
||||
|
||||
@font-face {
|
||||
font-family: "Material Symbols Outlined";
|
||||
font-style: normal;
|
||||
font-weight: 100 700;
|
||||
font-display: block;
|
||||
src: url("./fonts/material-symbols-outlined.woff2") format("woff2");
|
||||
}
|
||||
.material-symbols-outlined {
|
||||
font-family: "Material Symbols Outlined";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-feature-settings: "liga";
|
||||
|
||||
font-variation-settings: "FILL" 1, "wght" 400, "GRAD" 0, "opsz" 48;
|
||||
}
|
||||
@@ -15,21 +15,24 @@
|
||||
network: {} as WifiNetwork,
|
||||
};
|
||||
|
||||
function getWifiStrengthIcon(network: WifiNetwork) {
|
||||
function getWifiStrengthStyle(network: WifiNetwork) {
|
||||
const strength = Math.ceil((Number(network.Quality) / 100) * 4);
|
||||
|
||||
switch (strength) {
|
||||
case 0:
|
||||
return "clip-path: circle(0px at 12.5px 19px);";
|
||||
|
||||
case 1:
|
||||
return "";
|
||||
return "clip-path: circle(4px at 12.5px 19px);";
|
||||
|
||||
case 2:
|
||||
return "wifi_1_bar";
|
||||
return "clip-path: circle(8px at 12.5px 19px);";
|
||||
|
||||
case 3:
|
||||
return "wifi_2_bar";
|
||||
return "clip-path: circle(14px at 12.5px 19px);";
|
||||
|
||||
case 4:
|
||||
return "wifi";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,17 +106,16 @@
|
||||
? 'active'
|
||||
: ''}"
|
||||
>
|
||||
<span class="material-symbols-outlined background"
|
||||
>wifi</span
|
||||
>
|
||||
<span class="material-symbols-outlined">
|
||||
{getWifiStrengthIcon(network)}
|
||||
</span>
|
||||
<span class="fa fa-wifi background" />
|
||||
<span
|
||||
class="fa fa-wifi"
|
||||
style={getWifiStrengthStyle(network)}
|
||||
/>
|
||||
</Graphic>
|
||||
<Text style="margin-right: 20px;">{network.Name}</Text>
|
||||
{#if network.Encryption !== "Open"}
|
||||
<Meta>
|
||||
<span class="material-symbols-outlined lock">lock</span>
|
||||
<span class="fa fa-lock" />
|
||||
</Meta>
|
||||
{/if}
|
||||
</Item>
|
||||
@@ -188,8 +190,8 @@
|
||||
|
||||
span {
|
||||
position: absolute;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
top: 5px;
|
||||
font-size: 22px;
|
||||
|
||||
&.background {
|
||||
opacity: 0.25;
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
<script lang="ts">
|
||||
import * as api from "$lib/api";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
onMount(() => {
|
||||
document.body.style.backgroundColor = "black";
|
||||
const layout = document.querySelector("#layout") as HTMLElement;
|
||||
layout.style.backgroundColor = "white";
|
||||
layout.style.width = "1280px";
|
||||
layout.style.height = "720px";
|
||||
layout.style.overflowY = "scroll";
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="devmode">
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
type Option = {
|
||||
value: number;
|
||||
label: string;
|
||||
metric: boolean;
|
||||
};
|
||||
|
||||
@@ -65,10 +66,7 @@
|
||||
<List>
|
||||
{#each options as option}
|
||||
<Item on:SMUI:action={() => onOptionSelected(option)}>
|
||||
<Text>
|
||||
{option.value}
|
||||
{option.metric ? "mm" : "in"}
|
||||
</Text>
|
||||
<Text>{option.label}</Text>
|
||||
</Item>
|
||||
{/each}
|
||||
</List>
|
||||
@@ -76,12 +74,11 @@
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
:global {
|
||||
.value-and-unit {
|
||||
display: flex;
|
||||
column-gap: 10px;
|
||||
}
|
||||
|
||||
:global {
|
||||
.mdc-select {
|
||||
max-width: 60px;
|
||||
}
|
||||
@@ -90,4 +87,5 @@
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -64,12 +64,12 @@
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="simple-title"
|
||||
aria-describedby="simple-content"
|
||||
aria-labelledby="change-hostname-dialog-title"
|
||||
aria-describedby="change-hostname-dialog-content"
|
||||
>
|
||||
<Title id="simple-title">Change Hostname</Title>
|
||||
<Title id="change-hostname-dialog-title">Change Hostname</Title>
|
||||
|
||||
<Content id="simple-content">
|
||||
<Content id="change-hostname-dialog-content">
|
||||
<TextField
|
||||
bind:value={hostname}
|
||||
label="New Hostname"
|
||||
@@ -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"
|
||||
};
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
aria-labelledby="simple-title"
|
||||
aria-describedby="simple-content"
|
||||
aria-labelledby="home-machine-dialog-title"
|
||||
aria-describedby="home-machine-dialog-content"
|
||||
>
|
||||
<Title id="simple-title">Home Machine</Title>
|
||||
<Title id="home-machine-dialog-title">Home Machine</Title>
|
||||
|
||||
<Content id="simple-content">Home the machine?</Content>
|
||||
<Content id="home-machine-dialog-content">Home the machine?</Content>
|
||||
|
||||
<Actions>
|
||||
<Button>
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
escapeKeyAction=""
|
||||
aria-labelledby="simple-title"
|
||||
aria-describedby="simple-content"
|
||||
aria-labelledby="message-dialog-title"
|
||||
aria-describedby="message-dialog-content"
|
||||
>
|
||||
<Title id="simple-title">{title}</Title>
|
||||
<Content id="simple-content">
|
||||
<Title id="message-dialog-title">{title}</Title>
|
||||
<Content id="message-dialog-content">
|
||||
<slot />
|
||||
</Content>
|
||||
</Dialog>
|
||||
|
||||
@@ -63,28 +63,18 @@
|
||||
import { Config } from "$lib/ConfigStore";
|
||||
|
||||
const cutterDiameterOptions = [
|
||||
{ value: 0.5, metric: false },
|
||||
{ value: 10, metric: true },
|
||||
{ value: 0.25, metric: false },
|
||||
{ value: 6, metric: true },
|
||||
{ value: 0.125, metric: false },
|
||||
{ value: 3, metric: true },
|
||||
];
|
||||
|
||||
const cutterLengthOptions = [
|
||||
{ value: 1, metric: false },
|
||||
{ value: 20, metric: true },
|
||||
{ value: 0.5, metric: false },
|
||||
{ value: 10, metric: true },
|
||||
{ value: 0.25, metric: false },
|
||||
{ value: 6, metric: true },
|
||||
{ value: 0.5, label: '1/2 "', metric: false },
|
||||
{ value: 0.25, label: '1/4 "', metric: false },
|
||||
{ value: 0.125, label: '1/8 "', metric: false },
|
||||
{ value: 10, label: "10 mm", metric: true },
|
||||
{ value: 6, label: "6 mm", metric: true },
|
||||
{ value: 3, label: "10 mm", metric: true },
|
||||
];
|
||||
|
||||
export let open;
|
||||
export let probeType: "xyz" | "z";
|
||||
let currentStep: Step = "None";
|
||||
let cutterDiameter: number;
|
||||
let cutterLength: number;
|
||||
let showCancelButton = true;
|
||||
let steps: Array<Step> = [];
|
||||
let nextButton = {
|
||||
@@ -98,8 +88,6 @@
|
||||
$: if (open) {
|
||||
cutterDiameter =
|
||||
Number.parseFloat(localStorage.getItem("cutterDiameter")) || null;
|
||||
cutterLength =
|
||||
Number.parseFloat(localStorage.getItem("cutterLength")) || null;
|
||||
|
||||
// Svelte appears not to like it when you invoke
|
||||
// an async function from a reactive statement, so we
|
||||
@@ -107,7 +95,7 @@
|
||||
requestAnimationFrame(begin);
|
||||
}
|
||||
|
||||
$: if (cutterDiameter && cutterLength) {
|
||||
$: if (cutterDiameter) {
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
@@ -132,8 +120,7 @@
|
||||
|
||||
if (probeType === "xyz") {
|
||||
await stepCompleted("BitDimensions", userAcknowledged);
|
||||
localStorage.setItem("cutterDiameter", cutterDiameter);
|
||||
localStorage.setItem("cutterLength", cutterLength);
|
||||
localStorage.setItem("cutterDiameter", cutterDiameter.toString());
|
||||
}
|
||||
|
||||
await stepCompleted("PlaceProbeBlock", userAcknowledged);
|
||||
@@ -221,10 +208,7 @@
|
||||
nextButton.disabled = !(
|
||||
cutterDiameter !== null &&
|
||||
cutterDiameter !== 0 &&
|
||||
isFinite(cutterDiameter) &&
|
||||
cutterLength !== null &&
|
||||
cutterLength !== 0 &&
|
||||
isFinite(cutterLength)
|
||||
isFinite(cutterDiameter)
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -246,6 +230,7 @@
|
||||
const slowSeek = $Config.probe["probe-slow-seek"];
|
||||
const fastSeek = $Config.probe["probe-fast-seek"];
|
||||
|
||||
const cutterLength = 12.7;
|
||||
const zLift = 1;
|
||||
const xOffset = probeBlockWidth + cutterDiameter / 2.0;
|
||||
const yOffset = probeBlockLength + cutterDiameter / 2.0;
|
||||
@@ -310,13 +295,13 @@
|
||||
bind:open
|
||||
class="probe-dialog"
|
||||
scrimClickAction=""
|
||||
aria-labelledby="simple-title"
|
||||
aria-describedby="simple-content"
|
||||
aria-labelledby="probe-dialog-title"
|
||||
aria-describedby="probe-dialog-content"
|
||||
surface$style="width: 700px; height: 400px; max-width: calc(100vw - 32px); overflow: visible;"
|
||||
>
|
||||
<Title id="simple-title">Probing {probeType?.toUpperCase()}</Title>
|
||||
<Title id="probe-dialog-title">Probing {probeType?.toUpperCase()}</Title>
|
||||
|
||||
<Content id="simple-content" style="overflow: visible;">
|
||||
<Content id="probe-dialog-content" style="overflow: visible;">
|
||||
<div class="steps">
|
||||
<p><b>Step {steps.indexOf(currentStep) + 1} of {steps.length}</b></p>
|
||||
<ul>
|
||||
@@ -337,12 +322,6 @@
|
||||
bind:value={cutterDiameter}
|
||||
{metric}
|
||||
/>
|
||||
<DimensionInput
|
||||
label="Cutter length"
|
||||
options={cutterLengthOptions}
|
||||
bind:value={cutterLength}
|
||||
{metric}
|
||||
/>
|
||||
{:else if currentStep === "PlaceProbeBlock"}
|
||||
{#if probeType === "xyz"}
|
||||
Place the probe block face up, on the lower-left corner of your
|
||||
@@ -402,7 +381,7 @@
|
||||
$light: #ddd;
|
||||
|
||||
:global {
|
||||
.mdc-dialog__content {
|
||||
#probe-dialog-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
@@ -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-dialog-title"
|
||||
aria-describedby="screen-rotation-dialog-content"
|
||||
>
|
||||
<Title id="screen-rotation-dialog-title">Screen Rotation</Title>
|
||||
|
||||
<Content id="screen-rotation-dialog-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-dialog-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -45,12 +45,14 @@
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="simple-title"
|
||||
aria-describedby="simple-content"
|
||||
aria-labelledby="wifi-connection-dialog-title"
|
||||
aria-describedby="wifi-connection-dialog-content"
|
||||
>
|
||||
<Title id="simple-title">{connectToOrDisconnectFrom} {network.Name}</Title>
|
||||
<Title id="wifi-connection-dialog-title"
|
||||
>{connectToOrDisconnectFrom} {network.Name}</Title
|
||||
>
|
||||
|
||||
<Content id="simple-content">
|
||||
<Content id="wifi-connection-dialog-content">
|
||||
{#if needPassword}
|
||||
<TextField
|
||||
bind:value={password}
|
||||
@@ -64,9 +66,7 @@
|
||||
slot="trailingIcon"
|
||||
on:click={() => (showPassword = !showPassword)}
|
||||
>
|
||||
<Icon class="material-symbols-outlined">
|
||||
{showPassword ? "password" : "abc"}
|
||||
</Icon>
|
||||
<Icon class={`fa ${showPassword ? "fa-eye-slash" : "fa-eye"}`} />
|
||||
</div>
|
||||
<HelperText persistent slot="helper">
|
||||
Wifi passwords must be 8 to 128 characters
|
||||
@@ -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