Files
onefinity-firmware/src/pug/templates/control-view.pug
muehe ecf3191fcc control: restore Home All button in DRO header
Legacy Onefinity exposed a master Home All in the DRO header. Our
V09 redesign only kept it inside the no-W fallback row, so machines
with the W axis enabled (which is most users now) had no master
home button. Add it back to the DRO header's Actions column.

home_all() fires /api/home for X/Y/Z/A and /api/aux/home for W in
parallel \u2014 the AVR and the auxcnc ESP run independent homing cycles
so the user sees one click homing everything.
2026-05-01 15:54:52 +02:00

352 lines
15 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
script#control-view-template(type="text/x-template")
.control-page
// ----- Modal dialogs (kept verbatim from legacy) -----
message(:show.sync="showGcodeMessage")
h3(slot="header") Processing New File
div(slot="body")
h3 Please wait..
p Simulating GCode to check for errors, calculate ETA and generate 3D view.
div(slot="footer")
label Simulating {{(toolpath_progress || 0) | percent}}
message(:show.sync="showNoGcodeMessage")
h3(slot="header") GCode Not Set
div(slot="body")
p Configure the GCode for the selected macro to use it
div(slot="footer")
button.pure-button(@click="showNoGcodeMessage=false") OK
message(:show.sync="macrosLoading")
h3(slot="header") Run Macro?
div(slot="body")
p
| The macro file
strong {{state.selected}}
| is being loaded.
div(slot="footer")
button.pure-button(@click="macrosLoading=false") Cancel
button.pure-button.pure-button-primary(@click="start_pause") Run
message(:show.sync="GCodeNotFound")
h3(slot="header") File not found
div(slot="body")
p It seems like the file you selected cannot be found. Try uploading again.
div(slot="footer")
button.pure-button.button-error(@click="GCodeNotFound=false") OK
message(:show.sync="show_probe_dialog")
h3(slot="header") Choose probe type
div(slot="body")
p Pick which probe routine to run.
button.pure-button(:class="state['pw'] ? '' : 'load-on'", @click="showProbeDialog('xyz')") Probe XYZ
button.pure-button(:class="state['pw'] ? '' : 'load-on'", @click="showProbeDialog('z')") Probe Z
div(slot="footer")
button.pure-button(@click="show_probe_dialog=false") Cancel
// ----- Main grid: jog | (DRO + status strip) -----
.control-grid
// ===== JOG =====
// Hidden only while a G-code program is running / paused /
// stopping. Jogging / homing / MDI moves do not hide it.
.jog-card(v-if="!is_program_executing")
.jog-head
.jog-title
| Jog
span.step-pre · step
span.step {{jog_incr_amounts[display_units][jog_incr]}}#[span.unit {{metric ? 'mm' : 'in'}}]
.step-seg
button(:class="{active: jog_incr === 'fine'}", @click="jog_incr = 'fine'")
| {{jog_incr_amounts[display_units].fine}}
button(:class="{active: jog_incr === 'small'}", @click="jog_incr = 'small'")
| {{jog_incr_amounts[display_units].small}}
button(:class="{active: jog_incr === 'medium'}", @click="jog_incr = 'medium'")
| {{jog_incr_amounts[display_units].medium}}
button(:class="{active: jog_incr === 'large'}", @click="jog_incr = 'large'")
| {{jog_incr_amounts[display_units].large}}
.jog-grid
// Row 1
button.jbtn.dir(@click="jog_fn(-1, 1, 0, 0)", title="X- Y+")
.fa.fa-arrow-up.ico(style="transform: rotate(-45deg)")
button.jbtn(@click="jog_fn(0, 1, 0, 0)") Y+
button.jbtn.dir(@click="jog_fn(1, 1, 0, 0)", title="X+ Y+")
.fa.fa-arrow-up.ico(style="transform: rotate(45deg)")
button.jbtn(@click="jog_fn(0, 0, 1, 0)") Z+
// Row 2
button.jbtn(@click="jog_fn(-1, 0, 0, 0)") X
button.jbtn(@click="showMoveToZeroDialog('xy')")
span.lbl XY
span Origin
button.jbtn(@click="jog_fn(1, 0, 0, 0)") X+
button.jbtn(@click="showMoveToZeroDialog('z')")
span.lbl Z
span Origin
// Row 3
button.jbtn.dir(@click="jog_fn(-1, -1, 0, 0)", title="X- Y-")
.fa.fa-arrow-down.ico(style="transform: rotate(45deg)")
button.jbtn(@click="jog_fn(0, -1, 0, 0)") Y
button.jbtn.dir(@click="jog_fn(1, -1, 0, 0)", title="X+ Y-")
.fa.fa-arrow-down.ico(style="transform: rotate(-45deg)")
button.jbtn(@click="jog_fn(0, 0, -1, 0)") Z
// Row 4 — W axis (auxcnc) when enabled.
// W- | W+ | Probe XYZ | Probe Z
// "Home W" lives in the DRO table's actions column on the
// right, so it doesn't need a tile here.
template(v-if="w.enabled")
button.jbtn(@click="aux_jog_incr(-1)", :disabled="!w.enabled")
.fa.fa-arrow-down.ico
span.lbl W
button.jbtn(@click="aux_jog_incr(+1)", :disabled="!w.enabled")
.fa.fa-arrow-up.ico
span.lbl W+
button.jbtn(@click="showProbeDialog('xyz')",
:class="{'load-on': !state['pw']}")
.fa.fa-bullseye.ico
span.lbl Probe XYZ
button.jbtn(@click="showProbeDialog('z')",
:class="{'load-on': !state['pw']}")
.fa.fa-bullseye.ico
span.lbl Probe Z
// Row 4 — A axis (rotary) when no W and rotary is enabled
// (Vue 1 has no v-else-if; we negate w.enabled explicitly.)
template(v-if="!w.enabled && state['2an'] == 3")
button.jbtn.dir(@click="jog_fn(0, 0, 0, -1)")
.fa.fa-rotate-left.ico
span.lbl A
button.jbtn.ghost(@click="showMoveToZeroDialog('a')")
span.lbl A
span Origin
button.jbtn.dir(@click="jog_fn(0, 0, 0, 1)")
.fa.fa-rotate-right.ico
span.lbl A+
button.jbtn(@click="show_probe_dialog=true",
:class="{'load-on': !state['pw']}")
.fa.fa-bullseye.ico
span.lbl Probe
// Row 4 — fallback probe / zero / home shortcuts
template(v-if="!w.enabled && state['2an'] != 3")
button.jbtn(@click="showProbeDialog('xyz')",
:class="{'load-on': !state['pw']}")
.fa.fa-bullseye.ico
span.lbl Probe XYZ
button.jbtn.ghost(@click="zero()", :disabled="!can_set_axis")
.fa.fa-location-dot.ico
span.lbl Zero all
button.jbtn(@click="showProbeDialog('z')",
:class="{'load-on': !state['pw']}")
.fa.fa-bullseye.ico
span.lbl Probe Z
button.jbtn.ghost(@click="home()")
.fa.fa-home.ico
span.lbl Home all
// ===== NOW RUNNING (replaces jog grid only while a G-code
// program is actually executing). Jogging is excluded.
.running-panel(v-if="is_program_executing")
.running-top
div
.running-file
.fa.fa-file-code
span(v-if="state.selected")  {{state.selected}}
span(v-else)  {{(mach_state || 'BUSY').toLowerCase()}}
.running-meta
span(v-if="is_running") {{ (mach_state || 'RUNNING').toLowerCase() }}
span(v-if="is_holding") paused
span(v-if="is_holding && pause_reason") · {{pause_reason}}
span(v-if="is_stopping") stopping
span(v-if="toolpath.lines") · line {{state.line || 0 | number}} / {{toolpath.lines | number}}
span(v-if="plan_time_remaining") · ETA {{plan_time_remaining | time}}
.running-pct
| {{((progress || 0) * 100) | fixed 0}}
span %
.running-progress
div(:style="'width:' + ((progress || 0) * 100) + '%'")
.running-stats
.running-stat
.lbl Velocity
.val
unit-value(:value="state.v", precision="2", unit="", iunit="", scale="0.0254")
|  {{metric ? 'm/min' : 'IPM'}}
.running-stat
.lbl Feed
.val
unit-value(:value="state.feed", precision="0", unit="", iunit="")
|  {{metric ? 'mm/min' : 'IPM'}}
.running-stat
.lbl Spindle
.val
| {{(state.speed || 0) | fixed 0}}
span(v-if="state.s != null && !isNaN(state.s)") ({{state.s | fixed 0}})
|  RPM
.running-stat
.lbl Tool
.val T{{state.tool || 0}}
.running-row
// While RUNNING the primary action is Pause; while HOLDING / STOPPING it's Resume.
button.tx-btn.pause(v-if="is_running", @click="pause()")
.fa.fa-pause
span.lbl PAUSE
button.tx-btn.run(v-if="is_holding || is_stopping", @click="unpause()")
.fa.fa-play
span.lbl RESUME
button.tx-btn.stop(@click="stop()")
.fa.fa-stop
span.lbl STOP
button.tx-btn.step(v-if="is_holding", @click="step()")
.fa.fa-forward-step
span.lbl STEP
// ===== DRO + status strip =====
.right-col
.dro-card
.dro-head
div Axis
div Position
div Absolute
div Offset
div State
div Toolpath
.actions-cell
// Master Home All. Each row's Actions cell has a per-axis
// home button; this header-level button homes every
// enabled axis (legacy Onefinity behavior). Auto-includes
// the W axis when it is enabled.
button.icon-btn(:disabled="!is_idle",
title="Home all axes.", @click="home_all()")
.fa.fa-house-chimney
// Per-axis rows — keep unit-value + bindings from axis-vars
each axis in 'xyzabc'
.dro-row(:class=`${axis}.klass + ' ' + ${axis}.tklass`,
v-if=`${axis}.enabled`,
:title=`${axis}.title`)
.dro-axis(:class=`'axis-' + '${axis}'`)= axis.toUpperCase()
.dro-pos: unit-value(:value=`${axis}.pos`, precision=4)
.dro-sec: unit-value(:value=`${axis}.abs`, precision=3)
.dro-sec: unit-value(:value=`${axis}.off`, precision=3)
.dro-state
span.chip(:class=`${axis}.tklass.indexOf('error') !== -1 ? 'chip-red' : (${axis}.homed ? 'chip-green' : 'chip-amber')`)
.fa(:class=`'fa-' + ${axis}.icon`)
|  {{#{axis}.state}}
.dro-toolpath
span.chip(:class=`${axis}.tklass.indexOf('error') !== -1 ? 'chip-red' : (${axis}.tklass.indexOf('warn') !== -1 ? 'chip-amber' : 'chip-green')`,
@click=`showToolpathMessageDialog('${axis}')`)
.fa(:class=`'fa-' + ${axis}.ticon`)
|  {{#{axis}.tstate}}
.actions-cell
button.icon-btn(:disabled="!can_set_axis",
:title=`'Set ${axis.toUpperCase()} axis position.'`,
@click=`show_set_position('${axis}')`)
.fa.fa-gear
button.icon-btn(:disabled="!can_set_axis",
:title=`'Zero ${axis.toUpperCase()} axis offset.'`,
@click=`zero('${axis}')`)
.fa.fa-location-dot
button.icon-btn(:disabled="!is_idle",
:title=`'Home ${axis.toUpperCase()} axis.'`,
@click=`home('${axis}')`)
.fa.fa-home
// W axis (auxiliary) — no offset, no set-zero / no set-position
.dro-row(:class="w.klass + ' ' + w.tklass", v-if="w.enabled",
:title="w.title")
.dro-axis.axis-w W
.dro-pos: unit-value(:value="w.pos", precision=4)
.dro-sec: unit-value(:value="w.abs", precision=3)
.dro-sec —
.dro-state
span.chip(:class="w.homed ? 'chip-green' : 'chip-amber'")
.fa(:class="'fa-' + w.icon")
|  {{w.state}}
.dro-toolpath
span.chip.chip-green
.fa(:class="'fa-' + w.ticon")
|  {{w.tstate}}
.actions-cell
button.icon-btn(disabled, style="visibility:hidden")
.fa.fa-gear
button.icon-btn(disabled, style="visibility:hidden")
.fa.fa-location-dot
button.icon-btn(:disabled="!w.enabled",
title="Home W axis.", @click="aux_home()")
.fa.fa-home
// ----- Status strip -----
.status-strip
.stat-card
.stat-label State
.stat-val(:class="state_kpi_class") {{mach_state || '--'}}
.stat-sub(v-if="message") {{message.replace(/^#/, '')}}
.stat-sub(v-else) No alerts
.stat-card
.stat-label Velocity / Feed
.stat-val
unit-value(:value="state.v", precision="2", unit="", iunit="",
scale="0.0254")
| · 
unit-value(:value="state.feed", precision="0", unit="", iunit="")
.stat-sub {{metric ? 'm/min · mm/min' : 'IPM · IPM'}}
.stat-card.stat-tappable(@click="overrides_open = !overrides_open",
:class="{open: overrides_open}", title="Tap to adjust feed/spindle override")
.stat-label Spindle
.stat-val
| {{(state.speed || 0) | fixed 0}}
span(v-if="state.s != null && !isNaN(state.s)") ({{state.s | fixed 0}})
.stat-sub
| RPM (commanded / actual)
.fa.fa-sliders.tap-hint(title="Open override drawer")
.stat-card
.stat-label Job
.stat-val
| {{0 <= state.line ? state.line : 0 | number}}
span(v-if="toolpath.lines")
| / {{toolpath.lines | number}}
.stat-sub(v-if="plan_time_remaining || toolpath.time")
| Line · {{plan_time_remaining ? (plan_time_remaining | time) : (toolpath.time | time)}} remaining
.stat-sub(v-else) Line · ETA --
// ----- Macro row (slice 0..7); full list lives in Settings → Macros -----
// The colored left stripe (.has-color) is suppressed for white,
// near-white and other default placeholder colors so unconfigured
// macros render as clean slate tiles instead of looking lopsided.
.macro-row(v-if="state.macros && state.macros.length")
button.macro-btn(v-for="(index, macros) in state.macros.slice(0, 8)",
title="Click to run macro",
@click="run_macro(index)",
:disabled="!is_ready",
:class="{'has-color': has_macro_color(macros)}",
:style="has_macro_color(macros) ? {borderLeftColor: macros.color} : {}")
span.mnum {{index + 1}}
span.mname {{macros.name || ('Macro ' + (index + 1))}}
// ----- Override drawer (anchored to bottom; toggled by Spindle KPI tile) -----
.override-drawer(:class="{open: overrides_open}")
.od-head
.od-title
.fa.fa-sliders
| &nbsp;Overrides
button.od-close(@click="overrides_open = false") ✕
.od-body
.od-row
label Feed
input(type="range", min="0", max="2", step="0.01",
v-model="feed_override", @change="override_feed")
.od-val {{feed_override | percent 0}}
button.od-reset(@click="feed_override = 1; override_feed()") Reset 100%
.od-row
label Spindle
input(type="range", min="0", max="2", step="0.01",
v-model="speed_override", @change="override_speed")
.od-val {{speed_override | percent 0}}
button.od-reset(@click="speed_override = 1; override_speed()") Reset 100%