@imperosoft/cris-webui-components 1.2.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +179 -1
- package/dist/index.d.ts +179 -1
- package/dist/index.js +687 -237
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +680 -238
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31,8 +31,15 @@ __export(index_exports, {
|
|
|
31
31
|
CrisText: () => CrisText,
|
|
32
32
|
CrisTextInput: () => CrisTextInput,
|
|
33
33
|
CrisViewComm: () => CrisViewComm,
|
|
34
|
+
CrisViewDspChannels: () => CrisViewDspChannels,
|
|
34
35
|
CrisViewDspFull: () => CrisViewDspFull,
|
|
36
|
+
CrisViewDspInputs: () => CrisViewDspInputs,
|
|
37
|
+
CrisViewDspMixer: () => CrisViewDspMixer,
|
|
38
|
+
CrisViewDspOutputs: () => CrisViewDspOutputs,
|
|
39
|
+
CrisViewDspPresets: () => CrisViewDspPresets,
|
|
40
|
+
buildIoSections: () => buildIoSections,
|
|
35
41
|
buildMixerAxis: () => buildMixerAxis,
|
|
42
|
+
buildMixerAxisGrouped: () => buildMixerAxisGrouped,
|
|
36
43
|
clampLevel: () => clampLevel,
|
|
37
44
|
collapseStrips: () => collapseStrips,
|
|
38
45
|
commIndicators: () => commIndicators,
|
|
@@ -40,6 +47,7 @@ __export(index_exports, {
|
|
|
40
47
|
getIconConfig: () => getIconConfig,
|
|
41
48
|
getIconFilter: () => getIconFilter,
|
|
42
49
|
getIconUrl: () => getIconUrl,
|
|
50
|
+
groupsFor: () => groupsFor,
|
|
43
51
|
levelToPercent: () => levelToPercent,
|
|
44
52
|
linksFor: () => linksFor,
|
|
45
53
|
normalizeLinked: () => normalizeLinked
|
|
@@ -2388,6 +2396,9 @@ function CrisViewComm({ comm, classes, icons, className }) {
|
|
|
2388
2396
|
|
|
2389
2397
|
// src/components/dsp/CrisViewDspFull.tsx
|
|
2390
2398
|
var import_react9 = require("react");
|
|
2399
|
+
var import_cris_webui_ch5_core14 = require("@imperosoft/cris-webui-ch5-core");
|
|
2400
|
+
|
|
2401
|
+
// src/components/dsp/CrisViewDspInputs.tsx
|
|
2391
2402
|
var import_cris_webui_ch5_core11 = require("@imperosoft/cris-webui-ch5-core");
|
|
2392
2403
|
|
|
2393
2404
|
// src/components/dsp/DspIoPage.tsx
|
|
@@ -2439,6 +2450,127 @@ function collapseStrips(channels, links) {
|
|
|
2439
2450
|
function linksFor(ln, io) {
|
|
2440
2451
|
return io === "in" ? ln?.ip : ln?.op;
|
|
2441
2452
|
}
|
|
2453
|
+
function groupsFor(dg, io) {
|
|
2454
|
+
return io === "in" ? dg?.ip : dg?.op;
|
|
2455
|
+
}
|
|
2456
|
+
function buildLinkIndex(links) {
|
|
2457
|
+
const idx = /* @__PURE__ */ new Map();
|
|
2458
|
+
for (const raw of links ?? []) {
|
|
2459
|
+
const { label, channels } = normalizeLinked(raw);
|
|
2460
|
+
if (channels.length === 0) continue;
|
|
2461
|
+
const info = { label, channels };
|
|
2462
|
+
for (const id of channels) idx.set(id, info);
|
|
2463
|
+
}
|
|
2464
|
+
return idx;
|
|
2465
|
+
}
|
|
2466
|
+
function collapseWithin(ids, byId, linkIdx, idSet, usedLink, consumed) {
|
|
2467
|
+
const strips = [];
|
|
2468
|
+
for (const id of ids) {
|
|
2469
|
+
if (consumed.has(id)) continue;
|
|
2470
|
+
const link = linkIdx.get(id);
|
|
2471
|
+
const contained = !!link && link.channels.every((m) => idSet.has(m));
|
|
2472
|
+
if (link && contained && !usedLink.has(link)) {
|
|
2473
|
+
usedLink.add(link);
|
|
2474
|
+
link.channels.forEach((m) => consumed.add(m));
|
|
2475
|
+
const primary = link.channels.find((m) => byId.has(m));
|
|
2476
|
+
const ref = primary !== void 0 ? byId.get(primary) : void 0;
|
|
2477
|
+
strips.push({
|
|
2478
|
+
kind: "group",
|
|
2479
|
+
key: `g:${link.channels.join("-")}`,
|
|
2480
|
+
label: link.label || ref?.lb || `Grupo ${link.channels[0]}`,
|
|
2481
|
+
channels: link.channels,
|
|
2482
|
+
lv: clampLevel(ref?.lv),
|
|
2483
|
+
mt: ref?.mt ?? false
|
|
2484
|
+
});
|
|
2485
|
+
} else {
|
|
2486
|
+
consumed.add(id);
|
|
2487
|
+
const c = byId.get(id);
|
|
2488
|
+
if (!c) continue;
|
|
2489
|
+
strips.push({
|
|
2490
|
+
kind: "single",
|
|
2491
|
+
key: `c:${c.id}`,
|
|
2492
|
+
label: c.lb ?? `Canal ${c.id}`,
|
|
2493
|
+
channels: [c.id],
|
|
2494
|
+
lv: clampLevel(c.lv),
|
|
2495
|
+
mt: c.mt
|
|
2496
|
+
});
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
return strips;
|
|
2500
|
+
}
|
|
2501
|
+
function buildIoSections(channels, links, groups) {
|
|
2502
|
+
if (!groups || groups.length === 0) {
|
|
2503
|
+
return [{ strips: collapseStrips(channels, links) }];
|
|
2504
|
+
}
|
|
2505
|
+
const byId = new Map(channels.map((c) => [c.id, c]));
|
|
2506
|
+
const linkIdx = buildLinkIndex(links);
|
|
2507
|
+
const usedLink = /* @__PURE__ */ new Set();
|
|
2508
|
+
const consumed = /* @__PURE__ */ new Set();
|
|
2509
|
+
const assigned = /* @__PURE__ */ new Set();
|
|
2510
|
+
const sections = [];
|
|
2511
|
+
for (const g of groups) {
|
|
2512
|
+
g.ch.forEach((id) => assigned.add(id));
|
|
2513
|
+
const present = g.ch.filter((id) => byId.has(id));
|
|
2514
|
+
if (present.length === 0) continue;
|
|
2515
|
+
const strips = collapseWithin(present, byId, linkIdx, new Set(g.ch), usedLink, consumed);
|
|
2516
|
+
if (strips.length) sections.push({ groupName: g.id, strips });
|
|
2517
|
+
}
|
|
2518
|
+
const restIds = channels.filter((c) => !assigned.has(c.id)).map((c) => c.id);
|
|
2519
|
+
if (restIds.length) {
|
|
2520
|
+
const strips = collapseWithin(restIds, byId, linkIdx, new Set(restIds), usedLink, consumed);
|
|
2521
|
+
if (strips.length) sections.push({ strips });
|
|
2522
|
+
}
|
|
2523
|
+
return sections;
|
|
2524
|
+
}
|
|
2525
|
+
function buildMixerAxisGrouped(channels, links, groups) {
|
|
2526
|
+
const byId = new Map(channels.map((c) => [c.id, c]));
|
|
2527
|
+
const ordered = [];
|
|
2528
|
+
const groupOf = /* @__PURE__ */ new Map();
|
|
2529
|
+
const assigned = /* @__PURE__ */ new Set();
|
|
2530
|
+
for (const g of groups ?? []) {
|
|
2531
|
+
for (const id of g.ch) {
|
|
2532
|
+
assigned.add(id);
|
|
2533
|
+
const c = byId.get(id);
|
|
2534
|
+
if (c && !groupOf.has(id)) {
|
|
2535
|
+
ordered.push(c);
|
|
2536
|
+
groupOf.set(id, g.id);
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2540
|
+
for (const c of channels) if (!assigned.has(c.id)) ordered.push(c);
|
|
2541
|
+
const items = ordered.map((c) => ({
|
|
2542
|
+
id: c.id,
|
|
2543
|
+
channelLabel: c.lb ?? `${c.id}`,
|
|
2544
|
+
groupName: groupOf.get(c.id)
|
|
2545
|
+
}));
|
|
2546
|
+
const indexById = new Map(ordered.map((c, idx) => [c.id, idx]));
|
|
2547
|
+
let i = 0;
|
|
2548
|
+
while (i < items.length) {
|
|
2549
|
+
const g = items[i].groupName;
|
|
2550
|
+
if (g === void 0) {
|
|
2551
|
+
i++;
|
|
2552
|
+
continue;
|
|
2553
|
+
}
|
|
2554
|
+
let j = i;
|
|
2555
|
+
while (j < items.length && items[j].groupName === g) j++;
|
|
2556
|
+
items[i].groupStart = true;
|
|
2557
|
+
items[i].groupSpan = j - i;
|
|
2558
|
+
i = j;
|
|
2559
|
+
}
|
|
2560
|
+
for (const raw of links ?? []) {
|
|
2561
|
+
const { label, channels: members } = normalizeLinked(raw);
|
|
2562
|
+
if (members.length < 2) continue;
|
|
2563
|
+
const idxs = members.map((n) => indexById.get(n));
|
|
2564
|
+
if (idxs.some((x) => x === void 0)) continue;
|
|
2565
|
+
const indices = idxs.slice().sort((a, b) => a - b);
|
|
2566
|
+
const consecutive = indices.every((x, k) => k === 0 || x === indices[k - 1] + 1);
|
|
2567
|
+
if (!consecutive) continue;
|
|
2568
|
+
items[indices[0]].linkStart = true;
|
|
2569
|
+
items[indices[0]].linkSpan = indices.length;
|
|
2570
|
+
for (const idx of indices) items[idx].linkCommon = label;
|
|
2571
|
+
}
|
|
2572
|
+
return items;
|
|
2573
|
+
}
|
|
2442
2574
|
function buildMixerAxis(channels, links) {
|
|
2443
2575
|
const items = channels.map((c) => ({
|
|
2444
2576
|
id: c.id,
|
|
@@ -2538,52 +2670,232 @@ function useHorizontalWheel(ref) {
|
|
|
2538
2670
|
|
|
2539
2671
|
// src/components/dsp/DspIoPage.tsx
|
|
2540
2672
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2541
|
-
function DspIoPage({
|
|
2673
|
+
function DspIoPage({
|
|
2674
|
+
status,
|
|
2675
|
+
io,
|
|
2676
|
+
oid,
|
|
2677
|
+
send,
|
|
2678
|
+
show,
|
|
2679
|
+
skip,
|
|
2680
|
+
cls,
|
|
2681
|
+
icons,
|
|
2682
|
+
emptyLabel,
|
|
2683
|
+
bare = false,
|
|
2684
|
+
suppressEmpty = false
|
|
2685
|
+
}) {
|
|
2542
2686
|
const scrollRef = (0, import_react6.useRef)(null);
|
|
2543
2687
|
useHorizontalWheel(scrollRef);
|
|
2688
|
+
const showSet = show ? new Set(show) : null;
|
|
2544
2689
|
const skipSet = new Set(skip ?? []);
|
|
2690
|
+
const keep = (id) => (!showSet || showSet.has(id)) && !skipSet.has(id);
|
|
2545
2691
|
const raw = (io === "in" ? status?.ip : status?.op) ?? [];
|
|
2546
|
-
const channels =
|
|
2692
|
+
const channels = raw.filter((c) => keep(c.id));
|
|
2547
2693
|
const allLinks = linksFor(status?.ln, io);
|
|
2548
|
-
const links =
|
|
2549
|
-
const
|
|
2550
|
-
|
|
2551
|
-
|
|
2694
|
+
const links = allLinks?.filter((g) => (g.ch ?? []).some((id) => keep(id)));
|
|
2695
|
+
const groups = groupsFor(status?.dg, io)?.filter((g) => (g.ch ?? []).some((id) => keep(id)));
|
|
2696
|
+
const sections = buildIoSections(channels, links, groups);
|
|
2697
|
+
const hasHeaders = sections.some((s) => s.groupName);
|
|
2698
|
+
const totalStrips = sections.reduce((n, s) => n + s.strips.length, 0);
|
|
2699
|
+
if (totalStrips === 0) {
|
|
2700
|
+
return suppressEmpty ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cls.message, children: emptyLabel });
|
|
2552
2701
|
}
|
|
2553
|
-
|
|
2702
|
+
const row = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2554
2703
|
"div",
|
|
2555
2704
|
{
|
|
2556
|
-
className:
|
|
2705
|
+
className: `flex h-full items-stretch gap-[0.3em] px-[0.5em] py-[0.5em]${bare ? "" : " w-max mx-auto"}`,
|
|
2557
2706
|
style: { minWidth: "min-content" },
|
|
2558
|
-
children:
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2707
|
+
children: sections.map((sec, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col h-full", children: [
|
|
2708
|
+
hasHeaders && // Header band: spans this group's strips. The 1px separator lives only
|
|
2709
|
+
// here (between groups), never down the full channel height.
|
|
2710
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2711
|
+
"div",
|
|
2712
|
+
{
|
|
2713
|
+
className: "flex items-center justify-center shrink-0 h-[2.2em]",
|
|
2714
|
+
style: { borderLeft: i > 0 ? "1px solid rgba(0,0,0,0.4)" : void 0 },
|
|
2715
|
+
children: sec.groupName && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: cls.groupHeader, title: sec.groupName, children: sec.groupName })
|
|
2716
|
+
}
|
|
2717
|
+
),
|
|
2718
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex flex-1 min-h-0 items-stretch gap-[0.3em]", children: sec.strips.map((strip) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2719
|
+
DspChannelStrip,
|
|
2720
|
+
{
|
|
2721
|
+
strip,
|
|
2722
|
+
io,
|
|
2723
|
+
oid,
|
|
2724
|
+
send,
|
|
2725
|
+
cls,
|
|
2726
|
+
icons
|
|
2727
|
+
},
|
|
2728
|
+
strip.key
|
|
2729
|
+
)) })
|
|
2730
|
+
] }, sec.groupName ?? `rest:${i}`))
|
|
2731
|
+
}
|
|
2732
|
+
);
|
|
2733
|
+
if (bare) return row;
|
|
2734
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { ref: scrollRef, className: "w-full h-full overflow-x-auto no-scrollbar", children: row });
|
|
2735
|
+
}
|
|
2736
|
+
|
|
2737
|
+
// src/components/dsp/dspClasses.ts
|
|
2738
|
+
var DSP_CLASS_DEFAULTS = {
|
|
2739
|
+
root: "w-full h-full flex flex-col",
|
|
2740
|
+
header: "relative w-full flex items-end justify-center gap-[0.3em] px-[1em] pt-[0.5em]",
|
|
2741
|
+
content: "w-full flex-1 min-h-0",
|
|
2742
|
+
tab: "w-[10.5em] h-[3.25em] rounded-b-none rounded-lg flex items-center justify-center transition-colors bg-[#4f5152] text-white text-[1.4em] font-bold",
|
|
2743
|
+
tabActive: "bg-[#007ca0]",
|
|
2744
|
+
message: "w-full h-full flex items-center justify-center text-gray-400 text-[2em]",
|
|
2745
|
+
presetWrap: "absolute left-[1em] bottom-[0.3em] h-[4.5em] flex flex-col items-center",
|
|
2746
|
+
presetLabel: "text-[#4f5152] text-[1.4em] leading-none",
|
|
2747
|
+
preset: "w-[8em] h-full rounded-lg flex items-center justify-center transition-colors bg-[#4f5152] text-white",
|
|
2748
|
+
presetActive: "bg-[#007ca0]",
|
|
2749
|
+
presetPressed: "bg-[#006080]",
|
|
2750
|
+
savedFlash: "absolute inset-0 flex items-center justify-center rounded bg-[#22c55e] text-white text-[1.2em] font-bold pointer-events-none",
|
|
2751
|
+
groupHeader: "text-[#4f5152] text-center font-semibold leading-tight text-[1.1em] line-clamp-2 px-[0.3em]",
|
|
2752
|
+
// NOTE: no font-size on the mixer chrome/group cells — their `em` sticky
|
|
2753
|
+
// offsets must match the grid's `em` track widths. Text size lives on the
|
|
2754
|
+
// inner label spans (text-[1.1em]) instead.
|
|
2755
|
+
mixerGroup: "sticky flex items-center justify-center text-center bg-[#282C34] text-white font-semibold leading-tight border border-black/30",
|
|
2756
|
+
mixerGroupV: "sticky flex items-center justify-center bg-[#282C34] text-white font-semibold leading-tight border border-black/30",
|
|
2757
|
+
strip: "flex flex-col items-center gap-[0.4em] h-full w-[9em] flex-none px-[0.3em]",
|
|
2758
|
+
stripLabel: "text-[#4f5152] text-center leading-tight text-[1.1em] line-clamp-3",
|
|
2759
|
+
levelReadout: "text-[1.1em] text-[#4f5152] leading-none opacity-70 mt-[0.5em]",
|
|
2760
|
+
faderBar: "bg-[#c0c0c0] rounded",
|
|
2761
|
+
faderFill: "bg-[#007ca0] rounded",
|
|
2762
|
+
faderThumb: "bg-[#4f5152] rounded",
|
|
2763
|
+
mute: "w-full h-full rounded-lg flex items-center justify-center transition-colors bg-[#4f5152] text-white",
|
|
2764
|
+
muteActive: "bg-[#dc2626] text-white",
|
|
2765
|
+
mixerBackplate: "bg-[#282C34]",
|
|
2766
|
+
mixerCorner: "sticky z-30 flex items-center justify-center bg-[#282C34] text-[#4f5152] text-[1.1em] font-bold border border-black/30",
|
|
2767
|
+
mixerChrome: "sticky flex items-center justify-center text-center bg-[#282C34] text-white leading-tight border border-black/30",
|
|
2768
|
+
cell: "z-10 flex items-center justify-center border border-black/30",
|
|
2769
|
+
cellOn: "bg-[#22c55e]",
|
|
2770
|
+
cellOff: "bg-[#4f5152]"
|
|
2771
|
+
};
|
|
2772
|
+
var DSP_ICON_DEFAULTS = {
|
|
2773
|
+
crosspointOn: "audio-volume-ok",
|
|
2774
|
+
muteOff: "audio-volume-high",
|
|
2775
|
+
muteOn: "audio-volume-mute",
|
|
2776
|
+
muteOffFilter: "invert(65%) sepia(70%) saturate(500%) hue-rotate(80deg) brightness(110%) contrast(95%)",
|
|
2777
|
+
muteOnFilter: "brightness(0) invert(1)"
|
|
2778
|
+
};
|
|
2779
|
+
function mergeDefined(defaults4, overrides) {
|
|
2780
|
+
if (!overrides) return { ...defaults4 };
|
|
2781
|
+
const out = { ...defaults4 };
|
|
2782
|
+
Object.keys(overrides).forEach((k) => {
|
|
2783
|
+
const v = overrides[k];
|
|
2784
|
+
if (v !== void 0) out[k] = v;
|
|
2785
|
+
});
|
|
2786
|
+
return out;
|
|
2787
|
+
}
|
|
2788
|
+
function resolveDspClasses(classes) {
|
|
2789
|
+
return mergeDefined(DSP_CLASS_DEFAULTS, classes);
|
|
2790
|
+
}
|
|
2791
|
+
function resolveDspIcons(icons) {
|
|
2792
|
+
return mergeDefined(DSP_ICON_DEFAULTS, icons);
|
|
2793
|
+
}
|
|
2794
|
+
|
|
2795
|
+
// src/components/dsp/CrisViewDspInputs.tsx
|
|
2796
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2797
|
+
function CrisViewDspInputs({
|
|
2798
|
+
oid,
|
|
2799
|
+
skip,
|
|
2800
|
+
emptyLabel = "Sin entradas",
|
|
2801
|
+
classes,
|
|
2802
|
+
icons,
|
|
2803
|
+
className
|
|
2804
|
+
}) {
|
|
2805
|
+
const status = (0, import_cris_webui_ch5_core11.useCustomObject)(oid, { subscribe: true });
|
|
2806
|
+
const send = (0, import_cris_webui_ch5_core11.useCustomObjectSend)();
|
|
2807
|
+
const cls = resolveDspClasses(classes);
|
|
2808
|
+
const ic = resolveDspIcons(icons);
|
|
2809
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: `w-full h-full ${className ?? ""}`, children: status === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: cls.message, children: "Conectando\u2026" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2810
|
+
DspIoPage,
|
|
2811
|
+
{
|
|
2812
|
+
status,
|
|
2813
|
+
io: "in",
|
|
2814
|
+
oid,
|
|
2815
|
+
send,
|
|
2816
|
+
skip,
|
|
2817
|
+
cls,
|
|
2818
|
+
icons: ic,
|
|
2819
|
+
emptyLabel
|
|
2820
|
+
}
|
|
2821
|
+
) });
|
|
2822
|
+
}
|
|
2823
|
+
|
|
2824
|
+
// src/components/dsp/CrisViewDspOutputs.tsx
|
|
2825
|
+
var import_cris_webui_ch5_core12 = require("@imperosoft/cris-webui-ch5-core");
|
|
2826
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2827
|
+
function CrisViewDspOutputs({
|
|
2828
|
+
oid,
|
|
2829
|
+
skip,
|
|
2830
|
+
emptyLabel = "Sin salidas",
|
|
2831
|
+
classes,
|
|
2832
|
+
icons,
|
|
2833
|
+
className
|
|
2834
|
+
}) {
|
|
2835
|
+
const status = (0, import_cris_webui_ch5_core12.useCustomObject)(oid, { subscribe: true });
|
|
2836
|
+
const send = (0, import_cris_webui_ch5_core12.useCustomObjectSend)();
|
|
2837
|
+
const cls = resolveDspClasses(classes);
|
|
2838
|
+
const ic = resolveDspIcons(icons);
|
|
2839
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: `w-full h-full ${className ?? ""}`, children: status === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cls.message, children: "Conectando\u2026" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2840
|
+
DspIoPage,
|
|
2841
|
+
{
|
|
2842
|
+
status,
|
|
2843
|
+
io: "out",
|
|
2844
|
+
oid,
|
|
2845
|
+
send,
|
|
2846
|
+
skip,
|
|
2847
|
+
cls,
|
|
2848
|
+
icons: ic,
|
|
2849
|
+
emptyLabel
|
|
2570
2850
|
}
|
|
2571
2851
|
) });
|
|
2572
2852
|
}
|
|
2573
2853
|
|
|
2854
|
+
// src/components/dsp/CrisViewDspMixer.tsx
|
|
2855
|
+
var import_cris_webui_ch5_core13 = require("@imperosoft/cris-webui-ch5-core");
|
|
2856
|
+
|
|
2574
2857
|
// src/components/dsp/DspMixer.tsx
|
|
2575
2858
|
var import_react7 = require("react");
|
|
2576
|
-
var
|
|
2577
|
-
var
|
|
2578
|
-
var
|
|
2579
|
-
var
|
|
2580
|
-
var
|
|
2581
|
-
var
|
|
2582
|
-
var
|
|
2859
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2860
|
+
var DEFAULT_GROUP_W = "2.6em";
|
|
2861
|
+
var DEFAULT_COMMON_W = "9em";
|
|
2862
|
+
var DEFAULT_CHAN_W = "3em";
|
|
2863
|
+
var DEFAULT_GROUP_H = "2.2em";
|
|
2864
|
+
var DEFAULT_COMMON_H = "2.4em";
|
|
2865
|
+
var DEFAULT_CHAN_H = "2.1em";
|
|
2866
|
+
var DEFAULT_CELL_W = "7.5em";
|
|
2867
|
+
var DEFAULT_ROW_H = "4.5em";
|
|
2583
2868
|
var DRAG_FACTOR = 0.6;
|
|
2869
|
+
function resolveGeometry(o, inputCount, outputCount) {
|
|
2870
|
+
const groupW = o?.groupW ?? DEFAULT_GROUP_W;
|
|
2871
|
+
const commonW = o?.commonW ?? DEFAULT_COMMON_W;
|
|
2872
|
+
const chanW = o?.chanW ?? DEFAULT_CHAN_W;
|
|
2873
|
+
const groupH = o?.groupH ?? DEFAULT_GROUP_H;
|
|
2874
|
+
const commonH = o?.commonH ?? DEFAULT_COMMON_H;
|
|
2875
|
+
const chanH = o?.chanH ?? DEFAULT_CHAN_H;
|
|
2876
|
+
const cellW = o?.cellW ?? DEFAULT_CELL_W;
|
|
2877
|
+
const rowH = o?.rowH ?? DEFAULT_ROW_H;
|
|
2878
|
+
return {
|
|
2879
|
+
groupW,
|
|
2880
|
+
commonW,
|
|
2881
|
+
chanW,
|
|
2882
|
+
groupH,
|
|
2883
|
+
commonH,
|
|
2884
|
+
chanH,
|
|
2885
|
+
cellW,
|
|
2886
|
+
rowH,
|
|
2887
|
+
topLink: groupH,
|
|
2888
|
+
topChan: `calc(${groupH} + ${commonH})`,
|
|
2889
|
+
leftLink: groupW,
|
|
2890
|
+
leftChan: `calc(${groupW} + ${commonW})`,
|
|
2891
|
+
z: { corner: 40, group: 30, link: 25, chan: 20 },
|
|
2892
|
+
inputCount,
|
|
2893
|
+
outputCount
|
|
2894
|
+
};
|
|
2895
|
+
}
|
|
2584
2896
|
function CrosspointOnIcon({ icon }) {
|
|
2585
|
-
if (typeof icon !== "string") return /* @__PURE__ */ (0,
|
|
2586
|
-
return /* @__PURE__ */ (0,
|
|
2897
|
+
if (typeof icon !== "string") return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: icon });
|
|
2898
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2587
2899
|
"img",
|
|
2588
2900
|
{
|
|
2589
2901
|
src: getIconUrl(icon),
|
|
@@ -2594,7 +2906,17 @@ function CrosspointOnIcon({ icon }) {
|
|
|
2594
2906
|
}
|
|
2595
2907
|
);
|
|
2596
2908
|
}
|
|
2597
|
-
function DspMixer({
|
|
2909
|
+
function DspMixer({
|
|
2910
|
+
status,
|
|
2911
|
+
oid,
|
|
2912
|
+
send,
|
|
2913
|
+
cls,
|
|
2914
|
+
icons,
|
|
2915
|
+
geometry,
|
|
2916
|
+
renderInputHeader,
|
|
2917
|
+
renderOutputHeader,
|
|
2918
|
+
renderCorner
|
|
2919
|
+
}) {
|
|
2598
2920
|
const scrollRef = (0, import_react7.useRef)(null);
|
|
2599
2921
|
const startRef = (0, import_react7.useRef)(null);
|
|
2600
2922
|
const movedRef = (0, import_react7.useRef)(false);
|
|
@@ -2642,11 +2964,170 @@ function DspMixer({ status, oid, send, cls, icons }) {
|
|
|
2642
2964
|
pendingRef.current = null;
|
|
2643
2965
|
};
|
|
2644
2966
|
if (inputs.length === 0 || outputs.length === 0) {
|
|
2645
|
-
return /* @__PURE__ */ (0,
|
|
2967
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: cls.message, children: "Sin crosspoints" });
|
|
2646
2968
|
}
|
|
2647
|
-
const
|
|
2648
|
-
const
|
|
2649
|
-
|
|
2969
|
+
const geom = resolveGeometry(geometry, inputs.length, outputs.length);
|
|
2970
|
+
const inAxis = buildMixerAxisGrouped(inputs, linksFor(status?.ln, "in"), groupsFor(status?.dg, "in"));
|
|
2971
|
+
const outAxis = buildMixerAxisGrouped(outputs, linksFor(status?.ln, "out"), groupsFor(status?.dg, "out"));
|
|
2972
|
+
const { topLink, topChan, leftLink, leftChan, z: Z } = geom;
|
|
2973
|
+
const defaultInputHeader = () => inAxis.flatMap((it, ii) => {
|
|
2974
|
+
const col = 4 + ii;
|
|
2975
|
+
const nodes = [];
|
|
2976
|
+
if (it.groupStart) {
|
|
2977
|
+
nodes.push(
|
|
2978
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2979
|
+
"div",
|
|
2980
|
+
{
|
|
2981
|
+
className: cls.mixerGroup,
|
|
2982
|
+
style: { top: 0, zIndex: Z.group, gridRow: 1, gridColumn: `${col} / span ${it.groupSpan}` },
|
|
2983
|
+
title: it.groupName,
|
|
2984
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[1.1em] line-clamp-2 px-[0.2em]", children: it.groupName })
|
|
2985
|
+
},
|
|
2986
|
+
`igrp:${it.id}`
|
|
2987
|
+
)
|
|
2988
|
+
);
|
|
2989
|
+
} else if (it.groupName === void 0) {
|
|
2990
|
+
nodes.push(
|
|
2991
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2992
|
+
"div",
|
|
2993
|
+
{
|
|
2994
|
+
className: cls.mixerChrome,
|
|
2995
|
+
style: { top: 0, zIndex: Z.group, gridRow: 1, gridColumn: col }
|
|
2996
|
+
},
|
|
2997
|
+
`ifill:${it.id}`
|
|
2998
|
+
)
|
|
2999
|
+
);
|
|
3000
|
+
}
|
|
3001
|
+
if (it.linkCommon !== void 0) {
|
|
3002
|
+
if (it.linkStart) {
|
|
3003
|
+
nodes.push(
|
|
3004
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3005
|
+
"div",
|
|
3006
|
+
{
|
|
3007
|
+
className: `${cls.mixerChrome} px-[0.2em] font-semibold`,
|
|
3008
|
+
style: { top: topLink, zIndex: Z.link, gridRow: 2, gridColumn: `${col} / span ${it.linkSpan}` },
|
|
3009
|
+
title: it.linkCommon,
|
|
3010
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[1.1em] line-clamp-2", children: it.linkCommon })
|
|
3011
|
+
},
|
|
3012
|
+
`ilnk:${it.id}`
|
|
3013
|
+
)
|
|
3014
|
+
);
|
|
3015
|
+
}
|
|
3016
|
+
nodes.push(
|
|
3017
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3018
|
+
"div",
|
|
3019
|
+
{
|
|
3020
|
+
className: `${cls.mixerChrome} px-[0.2em]`,
|
|
3021
|
+
style: { top: topChan, zIndex: Z.chan, gridRow: 3, gridColumn: col },
|
|
3022
|
+
title: it.channelLabel,
|
|
3023
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[1.1em] line-clamp-1", children: it.channelLabel })
|
|
3024
|
+
},
|
|
3025
|
+
`ichn:${it.id}`
|
|
3026
|
+
)
|
|
3027
|
+
);
|
|
3028
|
+
} else {
|
|
3029
|
+
nodes.push(
|
|
3030
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3031
|
+
"div",
|
|
3032
|
+
{
|
|
3033
|
+
className: cls.mixerChrome,
|
|
3034
|
+
style: { top: topLink, zIndex: Z.link, gridRow: 2, gridColumn: col }
|
|
3035
|
+
},
|
|
3036
|
+
`ilf:${it.id}`
|
|
3037
|
+
),
|
|
3038
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3039
|
+
"div",
|
|
3040
|
+
{
|
|
3041
|
+
className: `${cls.mixerChrome} px-[0.2em]`,
|
|
3042
|
+
style: { top: topChan, zIndex: Z.chan, gridRow: 3, gridColumn: col },
|
|
3043
|
+
title: it.channelLabel,
|
|
3044
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[1.1em] line-clamp-2", children: it.channelLabel })
|
|
3045
|
+
},
|
|
3046
|
+
`ichn:${it.id}`
|
|
3047
|
+
)
|
|
3048
|
+
);
|
|
3049
|
+
}
|
|
3050
|
+
return nodes;
|
|
3051
|
+
});
|
|
3052
|
+
const defaultOutputHeader = () => outAxis.flatMap((it, oo) => {
|
|
3053
|
+
const row = 4 + oo;
|
|
3054
|
+
const nodes = [];
|
|
3055
|
+
if (it.groupStart) {
|
|
3056
|
+
nodes.push(
|
|
3057
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3058
|
+
"div",
|
|
3059
|
+
{
|
|
3060
|
+
className: cls.mixerGroupV,
|
|
3061
|
+
style: {
|
|
3062
|
+
left: 0,
|
|
3063
|
+
zIndex: Z.group,
|
|
3064
|
+
gridColumn: 1,
|
|
3065
|
+
gridRow: `${row} / span ${it.groupSpan}`,
|
|
3066
|
+
writingMode: "vertical-rl",
|
|
3067
|
+
transform: "rotate(180deg)"
|
|
3068
|
+
},
|
|
3069
|
+
title: it.groupName,
|
|
3070
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[1.1em] line-clamp-2", children: it.groupName })
|
|
3071
|
+
},
|
|
3072
|
+
`ogrp:${it.id}`
|
|
3073
|
+
)
|
|
3074
|
+
);
|
|
3075
|
+
} else if (it.groupName === void 0) {
|
|
3076
|
+
nodes.push(
|
|
3077
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3078
|
+
"div",
|
|
3079
|
+
{
|
|
3080
|
+
className: cls.mixerChrome,
|
|
3081
|
+
style: { left: 0, zIndex: Z.group, gridColumn: 1, gridRow: row }
|
|
3082
|
+
},
|
|
3083
|
+
`ofill:${it.id}`
|
|
3084
|
+
)
|
|
3085
|
+
);
|
|
3086
|
+
}
|
|
3087
|
+
if (it.linkCommon !== void 0) {
|
|
3088
|
+
if (it.linkStart) {
|
|
3089
|
+
nodes.push(
|
|
3090
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3091
|
+
"div",
|
|
3092
|
+
{
|
|
3093
|
+
className: `${cls.mixerChrome} justify-start px-[0.4em] font-semibold`,
|
|
3094
|
+
style: { left: leftLink, zIndex: Z.link, gridColumn: 2, gridRow: `${row} / span ${it.linkSpan}` },
|
|
3095
|
+
title: it.linkCommon,
|
|
3096
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[1.1em] line-clamp-2 text-left", children: it.linkCommon })
|
|
3097
|
+
},
|
|
3098
|
+
`olnk:${it.id}`
|
|
3099
|
+
)
|
|
3100
|
+
);
|
|
3101
|
+
}
|
|
3102
|
+
nodes.push(
|
|
3103
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3104
|
+
"div",
|
|
3105
|
+
{
|
|
3106
|
+
className: cls.mixerChrome,
|
|
3107
|
+
style: { left: leftChan, zIndex: Z.chan, gridColumn: 3, gridRow: row },
|
|
3108
|
+
title: it.channelLabel,
|
|
3109
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[1.1em] line-clamp-1", children: it.channelLabel })
|
|
3110
|
+
},
|
|
3111
|
+
`ochn:${it.id}`
|
|
3112
|
+
)
|
|
3113
|
+
);
|
|
3114
|
+
} else {
|
|
3115
|
+
nodes.push(
|
|
3116
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3117
|
+
"div",
|
|
3118
|
+
{
|
|
3119
|
+
className: `${cls.mixerChrome} justify-start px-[0.4em]`,
|
|
3120
|
+
style: { left: leftLink, zIndex: Z.chan, gridColumn: "2 / span 2", gridRow: row },
|
|
3121
|
+
title: it.channelLabel,
|
|
3122
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[1.1em] line-clamp-2 text-left", children: it.channelLabel })
|
|
3123
|
+
},
|
|
3124
|
+
`ochn:${it.id}`
|
|
3125
|
+
)
|
|
3126
|
+
);
|
|
3127
|
+
}
|
|
3128
|
+
return nodes;
|
|
3129
|
+
});
|
|
3130
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2650
3131
|
"div",
|
|
2651
3132
|
{
|
|
2652
3133
|
ref: scrollRef,
|
|
@@ -2654,126 +3135,58 @@ function DspMixer({ status, oid, send, cls, icons }) {
|
|
|
2654
3135
|
onPointerMove,
|
|
2655
3136
|
onPointerUp,
|
|
2656
3137
|
onPointerCancel: onPointerUp,
|
|
2657
|
-
className: "w-full h-full overflow-auto no-scrollbar relative touch-none select-none cursor-grab",
|
|
2658
|
-
children: /* @__PURE__ */ (0,
|
|
3138
|
+
className: "w-full h-full overflow-auto no-scrollbar relative touch-none select-none cursor-grab flex",
|
|
3139
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
2659
3140
|
"div",
|
|
2660
3141
|
{
|
|
2661
|
-
className: "grid",
|
|
3142
|
+
className: "grid m-auto",
|
|
2662
3143
|
style: {
|
|
2663
|
-
// cols: [
|
|
2664
|
-
gridTemplateColumns: `${
|
|
2665
|
-
gridTemplateRows: `${
|
|
3144
|
+
// cols: [out group][out link][out channel][inputs…] rows: [in group][in link][in channel][outputs…]
|
|
3145
|
+
gridTemplateColumns: `${geom.groupW} ${geom.commonW} ${geom.chanW} repeat(${inputs.length}, ${geom.cellW})`,
|
|
3146
|
+
gridTemplateRows: `${geom.groupH} ${geom.commonH} ${geom.chanH} repeat(${outputs.length}, ${geom.rowH})`,
|
|
2666
3147
|
minWidth: "min-content"
|
|
2667
3148
|
},
|
|
2668
3149
|
children: [
|
|
2669
|
-
/* @__PURE__ */ (0,
|
|
3150
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2670
3151
|
"div",
|
|
2671
3152
|
{
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
3153
|
+
"aria-hidden": true,
|
|
3154
|
+
className: `sticky ${cls.mixerBackplate}`,
|
|
3155
|
+
style: { top: 0, zIndex: 15, gridColumn: "1 / -1", gridRow: "1 / span 3" }
|
|
2675
3156
|
}
|
|
2676
3157
|
),
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
{
|
|
2684
|
-
className: `${cls.mixerChrome} z-20 px-[0.2em]`,
|
|
2685
|
-
style: { top: 0, gridRow: "1 / span 2", gridColumn: col, alignItems: "flex-end", paddingBottom: "0.3em" },
|
|
2686
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "line-clamp-1", children: it.channelLabel })
|
|
2687
|
-
},
|
|
2688
|
-
`ich:${it.id}`
|
|
2689
|
-
)
|
|
2690
|
-
];
|
|
2691
|
-
if (it.groupStart) {
|
|
2692
|
-
nodes.unshift(
|
|
2693
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2694
|
-
"div",
|
|
2695
|
-
{
|
|
2696
|
-
className: `${cls.mixerChrome} z-25 px-[0.2em] font-semibold`,
|
|
2697
|
-
style: { top: 0, gridRow: 1, gridColumn: `${col} / span ${it.groupSpan}` },
|
|
2698
|
-
title: it.groupCommon,
|
|
2699
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "line-clamp-2", children: it.groupCommon })
|
|
2700
|
-
},
|
|
2701
|
-
`icc:${it.id}`
|
|
2702
|
-
)
|
|
2703
|
-
);
|
|
2704
|
-
}
|
|
2705
|
-
return nodes;
|
|
3158
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3159
|
+
"div",
|
|
3160
|
+
{
|
|
3161
|
+
"aria-hidden": true,
|
|
3162
|
+
className: `sticky ${cls.mixerBackplate}`,
|
|
3163
|
+
style: { left: 0, zIndex: 15, gridColumn: "1 / span 3", gridRow: "1 / -1" }
|
|
2706
3164
|
}
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "line-clamp-3", children: it.channelLabel })
|
|
2715
|
-
},
|
|
2716
|
-
`is:${it.id}`
|
|
2717
|
-
)
|
|
2718
|
-
];
|
|
2719
|
-
}),
|
|
2720
|
-
outAxis.flatMap((it, oo) => {
|
|
2721
|
-
const row = 3 + oo;
|
|
2722
|
-
if (it.groupCommon !== void 0) {
|
|
2723
|
-
const nodes = [
|
|
2724
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2725
|
-
"div",
|
|
2726
|
-
{
|
|
2727
|
-
className: `${cls.mixerChrome} z-20`,
|
|
2728
|
-
style: { left: 0, gridColumn: "1 / span 2", gridRow: row, justifyContent: "flex-end", paddingRight: "0.6em" },
|
|
2729
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "line-clamp-1", children: it.channelLabel })
|
|
2730
|
-
},
|
|
2731
|
-
`och:${it.id}`
|
|
2732
|
-
)
|
|
2733
|
-
];
|
|
2734
|
-
if (it.groupStart) {
|
|
2735
|
-
nodes.unshift(
|
|
2736
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2737
|
-
"div",
|
|
2738
|
-
{
|
|
2739
|
-
className: `${cls.mixerChrome} z-25 justify-start px-[0.4em] font-semibold`,
|
|
2740
|
-
style: { left: 0, gridColumn: 1, gridRow: `${row} / span ${it.groupSpan}` },
|
|
2741
|
-
title: it.groupCommon,
|
|
2742
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "line-clamp-2 text-left", children: it.groupCommon })
|
|
2743
|
-
},
|
|
2744
|
-
`occ:${it.id}`
|
|
2745
|
-
)
|
|
2746
|
-
);
|
|
2747
|
-
}
|
|
2748
|
-
return nodes;
|
|
3165
|
+
),
|
|
3166
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3167
|
+
"div",
|
|
3168
|
+
{
|
|
3169
|
+
className: cls.mixerCorner,
|
|
3170
|
+
style: { top: 0, left: 0, zIndex: Z.corner, gridColumn: "1 / span 3", gridRow: "1 / span 3" },
|
|
3171
|
+
children: renderCorner ? renderCorner(geom) : "OUT \\ IN"
|
|
2749
3172
|
}
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "line-clamp-2 text-left", children: it.channelLabel })
|
|
2758
|
-
},
|
|
2759
|
-
`os:${it.id}`
|
|
2760
|
-
)
|
|
2761
|
-
];
|
|
2762
|
-
}),
|
|
2763
|
-
outputs.map(
|
|
2764
|
-
(o, oo) => inputs.map((i, ii) => {
|
|
2765
|
-
const on = isOn(o.id, i.id);
|
|
2766
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3173
|
+
),
|
|
3174
|
+
renderInputHeader ? renderInputHeader(inAxis, geom) : defaultInputHeader(),
|
|
3175
|
+
renderOutputHeader ? renderOutputHeader(outAxis, geom) : defaultOutputHeader(),
|
|
3176
|
+
outAxis.map(
|
|
3177
|
+
(orow, oo) => inAxis.map((icol, ii) => {
|
|
3178
|
+
const on = isOn(orow.id, icol.id);
|
|
3179
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2767
3180
|
"div",
|
|
2768
3181
|
{
|
|
2769
3182
|
"data-cell": true,
|
|
2770
|
-
"data-in":
|
|
2771
|
-
"data-out":
|
|
3183
|
+
"data-in": icol.id,
|
|
3184
|
+
"data-out": orow.id,
|
|
2772
3185
|
className: `${cls.cell} ${on ? cls.cellOn : cls.cellOff}`,
|
|
2773
|
-
style: { gridColumn:
|
|
2774
|
-
children: on && /* @__PURE__ */ (0,
|
|
3186
|
+
style: { gridColumn: 4 + ii, gridRow: 4 + oo },
|
|
3187
|
+
children: on && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CrosspointOnIcon, { icon: icons.crosspointOn })
|
|
2775
3188
|
},
|
|
2776
|
-
`x:${
|
|
3189
|
+
`x:${icol.id}:${orow.id}`
|
|
2777
3190
|
);
|
|
2778
3191
|
})
|
|
2779
3192
|
)
|
|
@@ -2784,13 +3197,45 @@ function DspMixer({ status, oid, send, cls, icons }) {
|
|
|
2784
3197
|
);
|
|
2785
3198
|
}
|
|
2786
3199
|
|
|
3200
|
+
// src/components/dsp/CrisViewDspMixer.tsx
|
|
3201
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3202
|
+
function CrisViewDspMixer({
|
|
3203
|
+
oid,
|
|
3204
|
+
classes,
|
|
3205
|
+
icons,
|
|
3206
|
+
className,
|
|
3207
|
+
geometry,
|
|
3208
|
+
renderInputHeader,
|
|
3209
|
+
renderOutputHeader,
|
|
3210
|
+
renderCorner
|
|
3211
|
+
}) {
|
|
3212
|
+
const status = (0, import_cris_webui_ch5_core13.useCustomObject)(oid, { subscribe: true });
|
|
3213
|
+
const send = (0, import_cris_webui_ch5_core13.useCustomObjectSend)();
|
|
3214
|
+
const cls = resolveDspClasses(classes);
|
|
3215
|
+
const ic = resolveDspIcons(icons);
|
|
3216
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: `w-full h-full ${className ?? ""}`, children: status === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: cls.message, children: "Conectando\u2026" }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3217
|
+
DspMixer,
|
|
3218
|
+
{
|
|
3219
|
+
status,
|
|
3220
|
+
oid,
|
|
3221
|
+
send,
|
|
3222
|
+
cls,
|
|
3223
|
+
icons: ic,
|
|
3224
|
+
geometry,
|
|
3225
|
+
renderInputHeader,
|
|
3226
|
+
renderOutputHeader,
|
|
3227
|
+
renderCorner
|
|
3228
|
+
}
|
|
3229
|
+
) });
|
|
3230
|
+
}
|
|
3231
|
+
|
|
2787
3232
|
// src/components/dsp/DspPresets.tsx
|
|
2788
3233
|
var import_react8 = require("react");
|
|
2789
|
-
var
|
|
3234
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2790
3235
|
var HOLD_MS = 2e3;
|
|
2791
3236
|
var SAVED_MS = 1e3;
|
|
2792
3237
|
function PresetButton({ num, name, active, onCall, onSave, cls }) {
|
|
2793
|
-
return /* @__PURE__ */ (0,
|
|
3238
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2794
3239
|
CrisButton,
|
|
2795
3240
|
{
|
|
2796
3241
|
onTap: onCall,
|
|
@@ -2800,9 +3245,9 @@ function PresetButton({ num, name, active, onCall, onSave, cls }) {
|
|
|
2800
3245
|
className: cls.preset,
|
|
2801
3246
|
classActive: cls.presetActive,
|
|
2802
3247
|
classPressed: cls.presetPressed,
|
|
2803
|
-
children: /* @__PURE__ */ (0,
|
|
2804
|
-
/* @__PURE__ */ (0,
|
|
2805
|
-
/* @__PURE__ */ (0,
|
|
3248
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "flex items-center justify-center gap-[0.5em]", children: [
|
|
3249
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-[1.6em] font-bold leading-none", children: num }),
|
|
3250
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-[1.2em] leading-none", children: name })
|
|
2806
3251
|
] })
|
|
2807
3252
|
}
|
|
2808
3253
|
);
|
|
@@ -2829,10 +3274,10 @@ function DspPresets({
|
|
|
2829
3274
|
if (!sustainedFeedback) return false;
|
|
2830
3275
|
return p.kind === "local" ? activeLocal === p.id : activeDevice === p.id;
|
|
2831
3276
|
};
|
|
2832
|
-
return /* @__PURE__ */ (0,
|
|
2833
|
-
/* @__PURE__ */ (0,
|
|
2834
|
-
/* @__PURE__ */ (0,
|
|
2835
|
-
presets.map((p) => /* @__PURE__ */ (0,
|
|
3277
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: cls.presetWrap, children: [
|
|
3278
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: cls.presetLabel, children: "Preset" }),
|
|
3279
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "relative flex-1 flex items-stretch gap-[0.3em] mt-[0.25em]", children: [
|
|
3280
|
+
presets.map((p) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2836
3281
|
PresetButton,
|
|
2837
3282
|
{
|
|
2838
3283
|
num: p.id,
|
|
@@ -2844,64 +3289,14 @@ function DspPresets({
|
|
|
2844
3289
|
},
|
|
2845
3290
|
p.id
|
|
2846
3291
|
)),
|
|
2847
|
-
saved && /* @__PURE__ */ (0,
|
|
3292
|
+
saved && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: cls.savedFlash, children: "Saved" })
|
|
2848
3293
|
] })
|
|
2849
3294
|
] });
|
|
2850
3295
|
}
|
|
2851
3296
|
|
|
2852
|
-
// src/components/dsp/dspClasses.ts
|
|
2853
|
-
var DSP_CLASS_DEFAULTS = {
|
|
2854
|
-
root: "w-full h-full flex flex-col",
|
|
2855
|
-
header: "relative w-full flex items-end justify-center gap-[0.3em] px-[1em] pt-[0.5em]",
|
|
2856
|
-
content: "w-full flex-1 min-h-0",
|
|
2857
|
-
tab: "w-[10.5em] h-[3.25em] rounded-b-none rounded-lg flex items-center justify-center transition-colors bg-[#4f5152] text-white text-[1.4em] font-bold",
|
|
2858
|
-
tabActive: "bg-[#007ca0]",
|
|
2859
|
-
message: "w-full h-full flex items-center justify-center text-gray-400 text-[2em]",
|
|
2860
|
-
presetWrap: "absolute left-[1em] bottom-[0.3em] h-[4.5em] flex flex-col items-center",
|
|
2861
|
-
presetLabel: "text-[#4f5152] text-[1.4em] leading-none",
|
|
2862
|
-
preset: "w-[8em] h-full rounded-lg flex items-center justify-center transition-colors bg-[#4f5152] text-white",
|
|
2863
|
-
presetActive: "bg-[#007ca0]",
|
|
2864
|
-
presetPressed: "bg-[#006080]",
|
|
2865
|
-
savedFlash: "absolute inset-0 flex items-center justify-center rounded bg-[#22c55e] text-white text-[1.2em] font-bold pointer-events-none",
|
|
2866
|
-
strip: "flex flex-col items-center gap-[0.4em] h-full w-[9em] flex-none px-[0.3em]",
|
|
2867
|
-
stripLabel: "text-[#4f5152] text-center leading-tight text-[1.1em] line-clamp-3",
|
|
2868
|
-
levelReadout: "text-[1.1em] text-[#4f5152] leading-none opacity-70 mt-[0.5em]",
|
|
2869
|
-
faderBar: "bg-[#c0c0c0] rounded",
|
|
2870
|
-
faderFill: "bg-[#007ca0] rounded",
|
|
2871
|
-
faderThumb: "bg-[#4f5152] rounded",
|
|
2872
|
-
mute: "w-full h-full rounded-lg flex items-center justify-center transition-colors bg-[#4f5152] text-white",
|
|
2873
|
-
muteActive: "bg-[#dc2626] text-white",
|
|
2874
|
-
mixerCorner: "sticky z-30 flex items-center justify-center bg-[#282C34] text-[#4f5152] text-[1.1em] font-bold border border-black/30",
|
|
2875
|
-
mixerChrome: "sticky flex items-center justify-center text-center bg-[#282C34] text-white text-[1.1em] leading-tight border border-black/30",
|
|
2876
|
-
cell: "z-10 flex items-center justify-center border border-black/30",
|
|
2877
|
-
cellOn: "bg-[#22c55e]",
|
|
2878
|
-
cellOff: "bg-[#4f5152]"
|
|
2879
|
-
};
|
|
2880
|
-
var DSP_ICON_DEFAULTS = {
|
|
2881
|
-
crosspointOn: "audio-volume-ok",
|
|
2882
|
-
muteOff: "audio-volume-high",
|
|
2883
|
-
muteOn: "audio-volume-mute",
|
|
2884
|
-
muteOffFilter: "invert(65%) sepia(70%) saturate(500%) hue-rotate(80deg) brightness(110%) contrast(95%)",
|
|
2885
|
-
muteOnFilter: "brightness(0) invert(1)"
|
|
2886
|
-
};
|
|
2887
|
-
function mergeDefined(defaults4, overrides) {
|
|
2888
|
-
if (!overrides) return { ...defaults4 };
|
|
2889
|
-
const out = { ...defaults4 };
|
|
2890
|
-
Object.keys(overrides).forEach((k) => {
|
|
2891
|
-
const v = overrides[k];
|
|
2892
|
-
if (v !== void 0) out[k] = v;
|
|
2893
|
-
});
|
|
2894
|
-
return out;
|
|
2895
|
-
}
|
|
2896
|
-
function resolveDspClasses(classes) {
|
|
2897
|
-
return mergeDefined(DSP_CLASS_DEFAULTS, classes);
|
|
2898
|
-
}
|
|
2899
|
-
function resolveDspIcons(icons) {
|
|
2900
|
-
return mergeDefined(DSP_ICON_DEFAULTS, icons);
|
|
2901
|
-
}
|
|
2902
|
-
|
|
2903
3297
|
// src/components/dsp/CrisViewDspFull.tsx
|
|
2904
|
-
var
|
|
3298
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
3299
|
+
var lastTabByOid = /* @__PURE__ */ new Map();
|
|
2905
3300
|
function CrisViewDspFull({
|
|
2906
3301
|
oid,
|
|
2907
3302
|
presets,
|
|
@@ -2914,12 +3309,16 @@ function CrisViewDspFull({
|
|
|
2914
3309
|
className,
|
|
2915
3310
|
initialTab = "in"
|
|
2916
3311
|
}) {
|
|
2917
|
-
const
|
|
2918
|
-
const
|
|
2919
|
-
const
|
|
2920
|
-
const
|
|
3312
|
+
const remembered = lastTabByOid.get(oid) ?? initialTab;
|
|
3313
|
+
const safeInitial = remembered === "mix" && skipCrosspoints ? "in" : remembered;
|
|
3314
|
+
const [tab, setTabState] = (0, import_react9.useState)(safeInitial);
|
|
3315
|
+
const setTab = (t) => {
|
|
3316
|
+
lastTabByOid.set(oid, t);
|
|
3317
|
+
setTabState(t);
|
|
3318
|
+
};
|
|
3319
|
+
const status = (0, import_cris_webui_ch5_core14.useCustomObject)(oid, { subscribe: true });
|
|
3320
|
+
const send = (0, import_cris_webui_ch5_core14.useCustomObjectSend)();
|
|
2921
3321
|
const cls = resolveDspClasses(classes);
|
|
2922
|
-
const ic = resolveDspIcons(icons);
|
|
2923
3322
|
const tabs = [
|
|
2924
3323
|
{ id: "in", label: "Inputs" },
|
|
2925
3324
|
...skipCrosspoints ? [] : [{ id: "mix", label: "Mixer" }],
|
|
@@ -2928,9 +3327,9 @@ function CrisViewDspFull({
|
|
|
2928
3327
|
const hasPresets = !!presets && presets.length > 0;
|
|
2929
3328
|
const activeDevice = status?.pr?.dv ?? status?.ps?.dv;
|
|
2930
3329
|
const activeLocal = status?.pr?.lc ?? status?.ps?.lc;
|
|
2931
|
-
return /* @__PURE__ */ (0,
|
|
2932
|
-
/* @__PURE__ */ (0,
|
|
2933
|
-
hasPresets && /* @__PURE__ */ (0,
|
|
3330
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: `${cls.root} ${className ?? ""}`, children: [
|
|
3331
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: cls.header, children: [
|
|
3332
|
+
hasPresets && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2934
3333
|
DspPresets,
|
|
2935
3334
|
{
|
|
2936
3335
|
oid,
|
|
@@ -2942,7 +3341,7 @@ function CrisViewDspFull({
|
|
|
2942
3341
|
cls
|
|
2943
3342
|
}
|
|
2944
3343
|
),
|
|
2945
|
-
tabs.map((t) => /* @__PURE__ */ (0,
|
|
3344
|
+
tabs.map((t) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2946
3345
|
CrisButton,
|
|
2947
3346
|
{
|
|
2948
3347
|
text: t.label,
|
|
@@ -2953,39 +3352,82 @@ function CrisViewDspFull({
|
|
|
2953
3352
|
},
|
|
2954
3353
|
t.id
|
|
2955
3354
|
)),
|
|
2956
|
-
/* @__PURE__ */ (0,
|
|
3355
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CrisViewComm, { comm: status?.cm, className: "absolute right-[1em] bottom-[0.3em] text-[1.25em]" })
|
|
2957
3356
|
] }),
|
|
2958
|
-
/* @__PURE__ */ (0,
|
|
2959
|
-
tab === "in" && /* @__PURE__ */ (0,
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
status,
|
|
2963
|
-
io: "in",
|
|
2964
|
-
oid,
|
|
2965
|
-
send,
|
|
2966
|
-
skip: skipShowInput,
|
|
2967
|
-
cls,
|
|
2968
|
-
icons: ic,
|
|
2969
|
-
emptyLabel: "Sin entradas"
|
|
2970
|
-
}
|
|
2971
|
-
),
|
|
2972
|
-
tab === "mix" && !skipCrosspoints && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DspMixer, { status, oid, send, cls, icons: ic }),
|
|
2973
|
-
tab === "out" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2974
|
-
DspIoPage,
|
|
2975
|
-
{
|
|
2976
|
-
status,
|
|
2977
|
-
io: "out",
|
|
2978
|
-
oid,
|
|
2979
|
-
send,
|
|
2980
|
-
skip: skipShowOutput,
|
|
2981
|
-
cls,
|
|
2982
|
-
icons: ic,
|
|
2983
|
-
emptyLabel: "Sin salidas"
|
|
2984
|
-
}
|
|
2985
|
-
)
|
|
3357
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: cls.content, children: status === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: cls.message, children: "Conectando\u2026" }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
3358
|
+
tab === "in" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CrisViewDspInputs, { oid, skip: skipShowInput, classes, icons }),
|
|
3359
|
+
tab === "mix" && !skipCrosspoints && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CrisViewDspMixer, { oid, classes, icons }),
|
|
3360
|
+
tab === "out" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CrisViewDspOutputs, { oid, skip: skipShowOutput, classes, icons })
|
|
2986
3361
|
] }) })
|
|
2987
3362
|
] });
|
|
2988
3363
|
}
|
|
3364
|
+
|
|
3365
|
+
// src/components/dsp/CrisViewDspPresets.tsx
|
|
3366
|
+
var import_cris_webui_ch5_core15 = require("@imperosoft/cris-webui-ch5-core");
|
|
3367
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3368
|
+
function CrisViewDspPresets({
|
|
3369
|
+
oid,
|
|
3370
|
+
presets,
|
|
3371
|
+
sustainedPresetFeedback = true,
|
|
3372
|
+
classes,
|
|
3373
|
+
className
|
|
3374
|
+
}) {
|
|
3375
|
+
const status = (0, import_cris_webui_ch5_core15.useCustomObject)(oid, { subscribe: true });
|
|
3376
|
+
const send = (0, import_cris_webui_ch5_core15.useCustomObjectSend)();
|
|
3377
|
+
const cls = resolveDspClasses({ presetWrap: "flex flex-col items-center", ...classes });
|
|
3378
|
+
const activeDevice = status?.pr?.dv ?? status?.ps?.dv;
|
|
3379
|
+
const activeLocal = status?.pr?.lc ?? status?.ps?.lc;
|
|
3380
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3381
|
+
DspPresets,
|
|
3382
|
+
{
|
|
3383
|
+
oid,
|
|
3384
|
+
send,
|
|
3385
|
+
presets,
|
|
3386
|
+
activeDevice,
|
|
3387
|
+
activeLocal,
|
|
3388
|
+
sustainedFeedback: sustainedPresetFeedback,
|
|
3389
|
+
cls
|
|
3390
|
+
}
|
|
3391
|
+
) });
|
|
3392
|
+
}
|
|
3393
|
+
|
|
3394
|
+
// src/components/dsp/CrisViewDspChannels.tsx
|
|
3395
|
+
var import_cris_webui_ch5_core16 = require("@imperosoft/cris-webui-ch5-core");
|
|
3396
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3397
|
+
function CrisViewDspChannels({
|
|
3398
|
+
oid,
|
|
3399
|
+
io,
|
|
3400
|
+
show,
|
|
3401
|
+
scroll = false,
|
|
3402
|
+
showEmpty = false,
|
|
3403
|
+
emptyLabel = "",
|
|
3404
|
+
classes,
|
|
3405
|
+
icons,
|
|
3406
|
+
className
|
|
3407
|
+
}) {
|
|
3408
|
+
const status = (0, import_cris_webui_ch5_core16.useCustomObject)(oid, { subscribe: true });
|
|
3409
|
+
const send = (0, import_cris_webui_ch5_core16.useCustomObjectSend)();
|
|
3410
|
+
const cls = resolveDspClasses(classes);
|
|
3411
|
+
const ic = resolveDspIcons(icons);
|
|
3412
|
+
if (status === void 0) {
|
|
3413
|
+
return showEmpty ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cls.message, children: "Conectando\u2026" }) : null;
|
|
3414
|
+
}
|
|
3415
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3416
|
+
DspIoPage,
|
|
3417
|
+
{
|
|
3418
|
+
status,
|
|
3419
|
+
io,
|
|
3420
|
+
oid,
|
|
3421
|
+
send,
|
|
3422
|
+
show,
|
|
3423
|
+
cls,
|
|
3424
|
+
icons: ic,
|
|
3425
|
+
emptyLabel,
|
|
3426
|
+
bare: !scroll,
|
|
3427
|
+
suppressEmpty: !showEmpty
|
|
3428
|
+
}
|
|
3429
|
+
) });
|
|
3430
|
+
}
|
|
2989
3431
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2990
3432
|
0 && (module.exports = {
|
|
2991
3433
|
CrisButton,
|
|
@@ -2999,8 +3441,15 @@ function CrisViewDspFull({
|
|
|
2999
3441
|
CrisText,
|
|
3000
3442
|
CrisTextInput,
|
|
3001
3443
|
CrisViewComm,
|
|
3444
|
+
CrisViewDspChannels,
|
|
3002
3445
|
CrisViewDspFull,
|
|
3446
|
+
CrisViewDspInputs,
|
|
3447
|
+
CrisViewDspMixer,
|
|
3448
|
+
CrisViewDspOutputs,
|
|
3449
|
+
CrisViewDspPresets,
|
|
3450
|
+
buildIoSections,
|
|
3003
3451
|
buildMixerAxis,
|
|
3452
|
+
buildMixerAxisGrouped,
|
|
3004
3453
|
clampLevel,
|
|
3005
3454
|
collapseStrips,
|
|
3006
3455
|
commIndicators,
|
|
@@ -3008,6 +3457,7 @@ function CrisViewDspFull({
|
|
|
3008
3457
|
getIconConfig,
|
|
3009
3458
|
getIconFilter,
|
|
3010
3459
|
getIconUrl,
|
|
3460
|
+
groupsFor,
|
|
3011
3461
|
levelToPercent,
|
|
3012
3462
|
linksFor,
|
|
3013
3463
|
normalizeLinked
|