-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPatternBank.tish
More file actions
148 lines (139 loc) · 5.57 KB
/
Copy pathPatternBank.tish
File metadata and controls
148 lines (139 loc) · 5.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Pattern launcher — the live surface beside the sequencer. Patterns ARE scenes (one concept).
// Each pattern card stacks three actions:
// LOAD → pull the pattern into the rack so you can edit it (Play Sequence monitors the rack)
// SAVE → copy the current rack back into the pattern (edit-only, never plays)
// LAUNCH → make the pattern the LIVE output (P0); queues to the next bar while a song plays
// P0 is the LIVE card: read-only, it just reflects whichever pattern is currently armed.
// The deck mixer is separate equipment — it is live-only and unrelated to LOAD/SAVE/LAUNCH.
import { h, Fragment } from '@tishlang/lattish'
import { LucideIcon } from './InstrumentKit.tish'
export fn PatternBank(bank) {
let count = Math.floor(Number(bank.count))
if (count < 1 || count !== count) {
count = 4
}
let editing = bank.editingScene
let live = bank.liveScene
let queued = bank.queuedScene
let queuePending = bank.queuePending === true
let cards = []
// P0 — the LIVE output. Not editable; mirrors the currently armed pattern.
let liveLabel = "idle"
if (live !== null) {
liveLabel = "P" + String(Math.floor(Number(live)) + 1)
}
let liveCls = "pb-card pb-card-p0"
if (live !== null) {
liveCls = liveCls + " pb-card-live-on"
}
cards.push(
<div class={liveCls} key="pb-p0" title={"P0 is the live output — launch a pattern to send it here"}>
<span class="pb-card-n">{"P0"}</span>
<span class="pb-live-badge">{"LIVE"}</span>
<span class="pb-live-src">{liveLabel}</span>
</div>
)
let i = 0
while (i < count) {
let sidx = i
let isEditing = editing !== null && Math.floor(Number(editing)) === sidx
let isLive = live !== null && Math.floor(Number(live)) === sidx
let isQueued = queuePending && queued !== null && Math.floor(Number(queued)) === sidx
let cardCls = "pb-card"
if (isEditing) {
cardCls = cardCls + " pb-card-editing"
}
if (isLive) {
cardCls = cardCls + " pb-card-live"
}
if (isQueued) {
cardCls = cardCls + " pb-card-queued"
}
let loadOn = isEditing ? " pb-btn-on" : ""
let launchCls = "pb-btn pb-btn-launch pb-btn-grow"
if (isLive) {
launchCls = launchCls + " pb-btn-on"
}
let launchLabel = "LAUNCH"
if (isQueued) {
if (bank.dropSteps !== null) {
launchLabel = bank.dropSteps === 0 ? "● NOW" : "◷ " + String(bank.dropSteps)
} else {
launchLabel = "◷ QUEUED"
}
}
let barN = bank.viewBar !== null ? Math.floor(Number(bank.viewBar)) + 1 : 1
let one = String(i + 1)
cards.push(
<div class={cardCls} key={"pb-" + String(i)}>
<div class="pb-card-top">
<span class="pb-card-n">{"P" + one}</span>
<button
type="button"
class={launchCls}
title={"Launch pattern " + one + " live (queues to the next bar while a song plays)"}
onclick={() => bank.onLaunch(sidx)}
>
{launchLabel}
</button>
</div>
<div class="pb-split-row">
<span class="pb-split-label" title="LOAD">{LucideIcon("download")}</span>
<button
type="button"
class={"pb-btn pb-btn-load" + loadOn}
title={"Load only bar " + String(barN) + " (the bar you're viewing) of pattern " + one + " — other bars untouched"}
onclick={() => bank.onLoadBar(sidx)}
style={{ display: "flex", alignItems: "center", justifyContent: "center" }}
>
{LucideIcon("square")}
</button>
<button
type="button"
class={"pb-btn pb-btn-load" + loadOn}
title={"Load all bars of pattern " + one + " into the rack"}
onclick={() => bank.onLoad(sidx)}
style={{ display: "flex", alignItems: "center", justifyContent: "center" }}
>
{LucideIcon("layout-grid")}
</button>
</div>
<div class="pb-split-row">
<span class="pb-split-label" title="SAVE">{LucideIcon("save")}</span>
<button
type="button"
class="pb-btn pb-btn-save"
title={"Save only bar " + String(barN) + " (the bar you're viewing) into pattern " + one + " — its other bars untouched"}
onclick={() => bank.onSaveBar(sidx)}
style={{ display: "flex", alignItems: "center", justifyContent: "center" }}
>
{LucideIcon("square")}
</button>
<button
type="button"
class="pb-btn pb-btn-save"
title={"Save the whole rack (all bars) into pattern " + one}
onclick={() => bank.onSave(sidx)}
style={{ display: "flex", alignItems: "center", justifyContent: "center" }}
>
{LucideIcon("layout-grid")}
</button>
</div>
</div>
)
i = i + 1
}
return (
<div class="panel pb-panel pb-panel-col">
<span class="pb-rev" style={{ display: "none" }}>{String(bank.rev)}</span>
<div class="pb-head">
<span class="pb-label">{"PATTERNS"}</span>
<span class="pb-sub" style={{ display: "flex", alignItems: "center", gap: "4px" }}>{LucideIcon("square")} {"·"} {LucideIcon("layout-grid")}</span>
</div>
<div class="pb-cards">{cards}</div>
<span class="pb-hint" style={{ display: "flex", alignItems: "center", gap: "4px", flexWrap: "wrap", justifyContent: "center" }}>
{LucideIcon("square")} {" = just the bar you're viewing · "} {LucideIcon("layout-grid")} {" = the whole pattern. LAUNCH sends it live."}
</span>
</div>
)
}