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") Probe Rotary div(slot="body") 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 ===== .jog-card .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.ghost(@click="showMoveToZeroDialog('xy')") span.lbl XY span Origin button.jbtn(@click="jog_fn(1, 0, 0, 0)") X+ button.jbtn.ghost(@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 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.ghost(@click="aux_home()", :disabled="!w.enabled") span.lbl Home span W button.jbtn(@click="aux_jog_incr(+1)", :disabled="!w.enabled") .fa.fa-arrow-up.ico span.lbl W+ button.jbtn(@click="show_probe_dialog=true", :class="{'load-on': !state['pw']}") .fa.fa-bullseye.ico span.lbl Probe // 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-map-marker.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()", :disabled="!is_idle") .fa.fa-home.ico span.lbl Home all // ===== DRO + status strip ===== .right-col .dro-card .dro-head div Axis div Position div Absolute div Offset div State div Toolpath div(style="text-align:right") Actions // 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-cog button.icon-btn(:disabled="!can_set_axis", :title=`'Zero ${axis.toUpperCase()} axis offset.'`, @click=`zero('${axis}')`) .fa.fa-map-marker 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-cog button.icon-btn(disabled, style="visibility:hidden") .fa.fa-map-marker 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 |  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%