Replaces the legacy side-menu chrome with a 4-tab top header. - index.pug: tablet/kiosk fit-to-viewport script, header tab nav, estop/state badges in header. - app.js: route hash to (control|program|console|<settings-family>), multi-section settings shell. - control-view: header DRO, jog grid, MDI/probe/macros panels. - program-view + program-mixin: file browser + toolpath preview + run/pause/stop, replaces the legacy 'macros' tab content. - console-view: MDI shell, message log, indicators. - settings-shell-view: rail-driven inner pages (Display & Units, Probing, G-code & Motion, Macros, Network, etc.). - settings-view: filter Svelte SettingsView to one rail section. - SettingsView.svelte: tag every section with data-sec=… so the filter above can hide non-matching ones. - style.styl: ~2700 lines of V09 layout, DRO, jog grid, status strip, and tablet/kiosk variants. No A-axis / auxiliary-axis content lives on this branch.
297 lines
13 KiB
Plaintext
297 lines
13 KiB
Plaintext
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 — A axis (rotary) when rotary is enabled.
|
||
template(v-if="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="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
|
||
.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).
|
||
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}.toolmsg ? (${axis}.title + ' — ' + ${axis}.toolmsg) : ${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)
|
||
.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(:class=`${axis}.tklass.indexOf('error') !== -1 ? 'state-red' : (${axis}.tklass.indexOf('warn') !== -1 ? 'state-amber' : 'state-green')`,
|
||
:disabled="!can_set_axis",
|
||
:title=`${axis}.toolmsg || ('Zero ${axis.toUpperCase()} axis offset.')`,
|
||
@click=`zero('${axis}')`)
|
||
.fa.fa-location-dot
|
||
button.icon-btn(:class=`${axis}.klass.indexOf('error') !== -1 ? 'state-red' : (${axis}.homed ? 'state-green' : 'state-amber')`,
|
||
:disabled="!is_idle",
|
||
:title=`${axis}.title`,
|
||
@click=`home('${axis}')`)
|
||
.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
|
||
| 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%
|