Skip to content

Commit 9fabfdd

Browse files
Give each DSP its own labelled readout with a fill bar
On a Floor the header ran the two together as "96.9% · 3.1% free · 0.0% · 100.0% free" — the same separator between the DSPs as inside them, and nothing saying which was which. Each is now a labelled chip with a bar, which is what makes two of them tell apart at a glance, and it turns warning-coloured near the ceiling like the model picker does. Single-DSP devices still read plain "DSP", not "DSP 1".
1 parent b26d411 commit 9fabfdd

1 file changed

Lines changed: 66 additions & 13 deletions

File tree

crates/fretwire-tauri/ui/src/App.svelte

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,13 @@
129129
// you — 72.7 of it meant "nearly full", which is the opposite of how it read. Raw units stay in
130130
// the CLI and the docs; nothing in the GUI shows them.
131131
const pct = (raw) => (raw / BUDGET) * 100;
132-
// Header readout, per DSP: used and actually-left. "96.9% · 3.1% free" on the Stomp, both DSPs
133-
// joined by "·" on the Floor.
134-
const dspLoadLabel = $derived(
135-
dspViews
136-
.map((v) => `${pct(v.dsp_load).toFixed(1)}% · ${Math.max(pct(BUDGET - v.dsp_load), 0).toFixed(1)}% free`)
137-
.join(" · "),
138-
);
132+
// Header readout, per DSP. Rendered as one labelled chip each rather than a joined string: on
133+
// the Floor the two used to run together as "96.9% · 3.1% free · 0.0% · 100.0% free", with the
134+
// same separator between the DSPs as inside them and nothing saying which was which.
135+
const dspUsed = (v) => Math.min(100, Math.max(0, pct(v.dsp_load)));
136+
const dspFree = (v) => Math.max(pct(BUDGET - v.dsp_load), 0);
137+
// Within a few points of the ceiling — the picker is already greying most models out by here.
138+
const dspTight = (v) => dspFree(v) < 10;
139139
140140
// Whether the selected slot is a structural node (split/mixer/input/output) rather than a normal
141141
// block — nodes aren't swappable or deletable.
@@ -740,7 +740,20 @@
740740
<span>device <b>{preset.device_model ?? "—"}</b></span>
741741
<span>fw <b>{preset.firmware ?? "—"}</b></span>
742742
<span>routing <b>{preset.split ? "parallel (split)" : "serial"}</b></span>
743-
<span>DSP <b>{dspLoadLabel}</b></span>
743+
{#each dspViews as v (v.dsp)}
744+
<span
745+
class="dsp-chip"
746+
class:tight={dspTight(v)}
747+
title="{dspViews.length > 1 ? `DSP ${v.dsp + 1}` : 'DSP'}: {dspUsed(v).toFixed(
748+
1,
749+
)}% of what the pedal will accept, {dspFree(v).toFixed(1)}% free"
750+
>
751+
<span class="dsp-name">{dspViews.length > 1 ? `DSP ${v.dsp + 1}` : "DSP"}</span>
752+
<span class="dsp-bar"><span class="fill" style="width:{dspUsed(v)}%"></span></span>
753+
<b>{dspUsed(v).toFixed(1)}%</b>
754+
<span class="dsp-free">{dspFree(v).toFixed(1)}% free</span>
755+
</span>
756+
{/each}
744757
</div>
745758
{#if preset.snapshot_names.length}
746759
<div class="snapshots">
@@ -782,13 +795,13 @@
782795
{/if}
783796
{#each dspViews as dspView (dspView.dsp)}
784797
{#if dspViews.length > 1}
785-
<div class="dsp-head">
798+
<div class="dsp-head" class:tight={dspTight(dspView)}>
786799
DSP {dspView.dsp + 1}
800+
<span class="dsp-bar"
801+
><span class="fill" style="width:{dspUsed(dspView)}%"></span></span
802+
>
787803
<span class="dsp-load"
788-
>{pct(dspView.dsp_load).toFixed(1)}% · {Math.max(
789-
pct(BUDGET - dspView.dsp_load),
790-
0,
791-
).toFixed(1)}% free</span
804+
>{dspUsed(dspView).toFixed(1)}% used · {dspFree(dspView).toFixed(1)}% free</span
792805
>
793806
</div>
794807
{/if}
@@ -1139,6 +1152,43 @@
11391152
font-size: 12px;
11401153
margin-left: 6px;
11411154
}
1155+
/* One per DSP. The bar is what makes two of them tell apart at a glance — the numbers alone
1156+
read as one run-on figure, which is how "96.9% · 3.1% free · 0.0% · 100.0% free" happened. */
1157+
.dsp-chip {
1158+
display: inline-flex;
1159+
align-items: center;
1160+
gap: 8px;
1161+
}
1162+
.dsp-chip .dsp-name {
1163+
font-variant-numeric: tabular-nums;
1164+
}
1165+
.dsp-bar {
1166+
width: 60px;
1167+
height: 6px;
1168+
border-radius: 3px;
1169+
background: #2a2f3a;
1170+
overflow: hidden;
1171+
}
1172+
.dsp-bar .fill {
1173+
display: block;
1174+
height: 100%;
1175+
background: #5b8dd6;
1176+
}
1177+
.dsp-chip b {
1178+
font-variant-numeric: tabular-nums;
1179+
}
1180+
.dsp-chip .dsp-free {
1181+
font-size: 12px;
1182+
color: #6d7688;
1183+
font-variant-numeric: tabular-nums;
1184+
}
1185+
/* Nearly full: the same warning colour the model picker uses on a model that won't fit. */
1186+
.dsp-chip.tight .dsp-bar .fill {
1187+
background: #e0785f;
1188+
}
1189+
.dsp-chip.tight b {
1190+
color: #e0785f;
1191+
}
11421192
.hint {
11431193
color: #9aa3b2;
11441194
}
@@ -1154,6 +1204,9 @@
11541204
color: #9aa3b2;
11551205
text-transform: uppercase;
11561206
}
1207+
.dsp-head.tight .dsp-bar .fill {
1208+
background: #e0785f;
1209+
}
11571210
.dsp-head .dsp-load {
11581211
font-size: 11px;
11591212
font-weight: 600;

0 commit comments

Comments
 (0)