/* ProbeCNC.js - ESP3D WebUI component file Copyright (c) 2021 Luc LEBOSSE. All rights reserved. This code is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This code 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with This code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import { Fragment, TargetedMouseEvent } from "preact" import type { FunctionalComponent } from "preact" import { useState } from "preact/hooks" import { T } from "../Translations" import { Underline } from "preact-feather" import { useUiContextFn, useSettingsContext, } from "../../contexts" import { useTargetContext, variablesList } from "../../targets" import { ButtonImg, Field, FullScreenButton, CloseButton, ContainerHelper } from "../Controls" import { checkDependencies } from "../Helpers" import { useTargetCommands } from "../../hooks" /* * Local const * */ type NumberValue = { current: number; valid?: boolean } type StringValue = { current: string; valid?: boolean } const maxprobe = {} as Partial const probefeedrate = {} as Partial const probethickness = {} as Partial const proberetract = {} as Partial const probetype = {} as Partial const probeaxis = {} as Partial const ProbeControls: FunctionalComponent = () => { const { gcodeParameters, pinsStates } = useTargetContext() as any if (!useUiContextFn.getValue("showprobepanel")) return null return (
{T("CN104")}
{gcodeParameters.PRB ? T(gcodeParameters.PRB.success ? "CN101" : "CN102") : "?"}
{pinsStates && (
P
)}
) } const ProbePanel: FunctionalComponent = () => { const { interfaceSettings, connectionSettings } = useSettingsContext() //const { status } = useTargetContext() const { targetCommands } = useTargetCommands() const id = "ProbePanel" if (typeof maxprobe.current === "undefined") { maxprobe.current = useUiContextFn.getValue("maxprobe") } if (typeof probefeedrate.current === "undefined") { probefeedrate.current = useUiContextFn.getValue("probefeedrate") } if (typeof probethickness.current === "undefined") { probethickness.current = useUiContextFn.getValue("probethickness") } if (typeof proberetract.current === "undefined") { proberetract.current = useUiContextFn.getValue("proberetract") } if (typeof probetype.current === "undefined") { probetype.current = "G38.2" } if (typeof probeaxis.current === "undefined") { probeaxis.current = "Z" } const hasError = (): boolean => { return !( !!probefeedrate.valid && !!probethickness.valid && !!proberetract.valid && !!maxprobe.valid ) } const probe_controls = [ { label: "", id: "probe_group", controls: [ { id: "probe_type", elements: [ { id: "probe_axis", type: "select", label: "CN99", tooltip: "CN98", options: [ { label: "X", value: "X", depend: [ { id: "showx", value: true }, { connection_id: "Axisletters", contains: "X" } ] }, { label: "Y", value: "Y", depend: [ { id: "showy", value: true }, { connection_id: "Axisletters", contains: "Y", }, ] }, { label: "Z", value: "Z", depend: [ { id: "showz", value: true }, { connection_id: "Axisletters", contains: "Z", }, ] }, { label: "A", value: "A", depend: [ { id: "showa", value: true }, { connection_id: "Axisletters", contains: "A", }, ], }, { label: "B", value: "B", depend: [ { id: "showb", value: true }, { connection_id: "Axisletters", contains: "B", }, ], }, { label: "C", value: "C", depend: [ { id: "showc", value: true }, { connection_id: "Axisletters", contains: "C", }, ], }, { label: "U", value: "U", depend: [ { id: "showu", value: true }, { connection_id: "Axisletters", contains: "U", }, ], }, { label: "V", value: "V", depend: [ { id: "showv", value: true }, { connection_id: "Axisletters", contains: "V", }, ], }, { label: "W", value: "W", depend: [ { id: "showw", value: true }, { connection_id: "Axisletters", contains: "W", }, ], }, ], value: probeaxis, variableName: "#selected_axis#", }, { id: "probe_type", type: "select", label: "CN98", tooltip: "CN98", options: [ { label: "G38.2", value: "G38.2" }, { label: "G38.3", value: "G38.3" }, { label: "G38.4", value: "G38.4" }, { label: "G38.5", value: "G38.5" }, ], value: probetype, }, ], }, { id: "probe_max", elements: [ { id: "probe_max_distance", type: "number", label: "CN93", tooltip: "CN93", min: 1, value: maxprobe, append: "CN96", }, ], }, { id: "probe_feedrate", elements: [ { id: "probe_feedrate", type: "number", label: "CN9", tooltip: "CN9", append: "CN1", min: 1, value: probefeedrate, }, ], }, { id: "probe_thickness", elements: [ { id: "probe_thickness", type: "number", label: "CN94", tooltip: "CN94", min: 0, step: useUiContextFn.getElement("probethickness") .step, value: probethickness, append: "CN96", variableName: "#probe_thickness#", }, ], }, { id: "probe_retract", elements: [ { id: "probe_retract", type: "number", label: "CN200", tooltip: "CN200", min: 0, step: useUiContextFn.getElement("proberetract") .step, value: proberetract, append: "CN96", variableName: "#probe_retract#", }, ], }, { id: "spacer", elements: [ { id: "spacer", type: "m2", }, ], }, { id: "probe_buttons", elements: [ { id: "probe_button", m2: true, icon: , type: "button", label: "CN37", tooltip: "CN100", onclick: (e: TargetedMouseEvent) => { const commands = [ "G91", () => { const signe = probetype.current == "G38.2" || probetype.current == "G38.3" ? "-" : "" return ( `${probetype.current } ${ probeaxis.current }${signe }${maxprobe.current } F${ probefeedrate.current}` ) }, "G90", ...useUiContextFn .getValue("probepostcommand") .split(";"), ] e.currentTarget.blur() useUiContextFn.haptic() targetCommands(commands) }, }, ], }, ], }, ] return (
{probe_controls.map((block) => { return (
0 ? " fieldset-top-separator fieldset-bottom-separator" : "" }`} > {block.label.length > 0 && ( )}
{block.controls.map((control) => { return (
{control.elements.map((element: any) => { if (element.type === "m2") { return
} else if ( element.type === "button" ) { return ( ) } else { //we won't handle modified state just handle error //too many user cases where changing value to show button is not suitable const [ validation, setvalidation, ] = useState({ message: null, valid: true, modified: false, }) const generateValidation = ( element: any ) => { let validation = { message: null, valid: true, modified: false, } if ( element.type === "select" && -1 == filterOptions( element.options ).findIndex( (item: any) => item.value == element .value .current ) ) { const filteredOptions = filterOptions(element.options) if (filteredOptions.length > 0) { element.value.current = filteredOptions[0].value } } if ( typeof element.step !== "undefined" ) { //hack to avoid float precision issue const inv = 1 / element.step const mult = inv > 0 ? Number(inv.toFixed(0)) : 1 const valueMult = Math.round( element .value .current * mult ) const stepMult = Math.round( element.step * mult ) // console.log( // "Element:", // element.value // .current, // "Step:", // element.step, // "Mult", // mult, // "Modal:", // "Value mult", // valueMult, // "Step mult", // stepMult, // "Modulo", // valueMult % // stepMult // ) if ( valueMult % stepMult != 0 ) { // console.log( // "not valid" // ) validation.valid = false } } if ( element.type === "number" && (element.value .current < element.min || element.value .current .length === 0) ) { //No error message to keep all control aligned //may be have a better way ? // validation.message = T("S42"); validation.valid = false } element.value.valid = validation.valid return validation } const filterOptions = ( options: any[] ) => { if (options) return options.filter( (option: any) => { return checkDependencies( option.depend, interfaceSettings .current .settings, connectionSettings.current ) } ) return options } return ( { if (!update) { element.value.current = val } const validationObj = generateValidation( element ) setvalidation( validationObj ) if ( validationObj.valid && element.variableName ) { variablesList.addCommand( { name: element.variableName, value: element .value .current, } ) } }} validation={ validation } /> ) } })}
) })}
) })}
) } const ProbePanelElement = { id: "ProbePanel", content: , name: "CN37", icon: "Underline", show: "showprobepanel", onstart: "openprobeonstart", settingid: "probe", } export { ProbePanel, ProbePanelElement, ProbeControls }