@gorilla-engine-sdk/create-gorilla-engine-plugin 1.0.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/LICENSE.md +64 -0
- package/README.md +103 -0
- package/generator-gorilla-engine-plugin/app/index.js +338 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/SKILL.md +295 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/references/effects-filters.md +186 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/references/indexing.md +129 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/references/instrument-files.md +547 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/references/key-rules.md +81 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/references/modulation.md +210 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/references/module-control.md +217 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/references/module-reference-bus-effects.md +663 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/references/module-reference-core.md +145 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/references/module-reference-misc.md +59 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/references/module-reference-modulation.md +85 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/references/module-reference-voice-effects.md +407 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/references/note-events.md +278 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/references/properties.md +230 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/references/script-patterns.md +494 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-dsp/references/time-tempo.md +209 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-ui/SKILL.md +104 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-ui/references/advanced-controls.md +194 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-ui/references/base-props.md +167 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-ui/references/basic-controls.md +230 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-ui/references/bindings.md +183 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-ui/references/composite-components.md +258 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-ui/references/containers.md +149 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-ui/references/editors.md +191 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-ui/references/event-handlers.md +150 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-ui/references/getting-started.md +143 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-ui/references/gorilla-engine-api.md +147 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-ui/references/instrument-api.md +250 -0
- package/generator-gorilla-engine-plugin/app/templates/.agents/skills/gorilla-engine-ui/references/visualization.md +209 -0
- package/generator-gorilla-engine-plugin/app/templates/.prettierignore +13 -0
- package/generator-gorilla-engine-plugin/app/templates/.vscode/settings.json +14 -0
- package/generator-gorilla-engine-plugin/app/templates/.vscode_input/launch.json +89 -0
- package/generator-gorilla-engine-plugin/app/templates/README.md +36 -0
- package/generator-gorilla-engine-plugin/app/templates/assets/fonts/OFL.txt +93 -0
- package/generator-gorilla-engine-plugin/app/templates/assets/fonts/Roboto-Bold.otf +0 -0
- package/generator-gorilla-engine-plugin/app/templates/assets/fonts/Roboto-Medium.otf +0 -0
- package/generator-gorilla-engine-plugin/app/templates/assets/fonts/Roboto-Regular.otf +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/Presets/Factory/Category 1/Init.preset +1 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/Presets/Factory/Category 1/Three Quarters.preset +1 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/Horizontal Slider.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/Horizontal Slider@2x.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/Rotary Bipolar.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/Rotary-Bipolar@2x.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/Rotary.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/Rotary@2x.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/arrow-down-default.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/arrow-down-default@2x.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/arrow-down-hover.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/arrow-down-hover@2x.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/arrow-down-pressed.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/arrow-down-pressed@2x.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/arrow-up-default.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/arrow-up-default@2x.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/arrow-up-hover.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/arrow-up-hover@2x.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/arrow-up-pressed.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/arrow-up-pressed@2x.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/toggle-default.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/toggle-default@2x.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/toggle-pressed.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/images/toggle-pressed@2x.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/instruments/Basic Synth Example_part1.blob +0 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/assets/instruments/Basic Synth Example_part2.blob +1 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/instrument/Basic Synth Example.inst +157 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/instrument/Basic Synth Example.txt +184 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/src/app/Root.tsx +35 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/src/app/components/ErrorBoundary.tsx +138 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/src/app/components/UserInterface.tsx +338 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/src/app/pluginConfig.ts +4 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/src/dialogsCustomStyle.ts +98 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/src/index.tsx +217 -0
- package/generator-gorilla-engine-plugin/app/templates/basic-synth/src/presetBrowserCustomStyle.ts +124 -0
- package/generator-gorilla-engine-plugin/app/templates/build.ugep +173 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/assets/Presets/Factory/Category 1/01 - All The Way Down.preset +1 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/assets/Presets/Factory/Category 1/02 - About Half.preset +1 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/assets/Presets/Factory/Category 1/03 - Three Quarters.preset +1 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/assets/Presets/Factory/Category 1/04 - All The Way Up.preset +1 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/assets/images/Rotary.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/assets/images/Rotary@2x.png +0 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/assets/instruments/Reverb Example_part1.blob +0 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/assets/instruments/Reverb Example_part2.blob +1 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/instrument/Reverb Example.inst +73 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/instrument/Reverb Example.txt +21 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/src/app/Root.tsx +35 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/src/app/components/ErrorBoundary.tsx +114 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/src/app/components/UserInterface.tsx +85 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/src/app/pluginConfig.ts +4 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/src/dialogsCustomStyle.ts +101 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/src/index.tsx +214 -0
- package/generator-gorilla-engine-plugin/app/templates/effect/src/presetBrowserCustomStyle.ts +124 -0
- package/generator-gorilla-engine-plugin/app/templates/gitignore +9 -0
- package/generator-gorilla-engine-plugin/app/templates/licence.txt +0 -0
- package/generator-gorilla-engine-plugin/app/templates/package.json +38 -0
- package/generator-gorilla-engine-plugin/app/templates/prettierrc +9 -0
- package/generator-gorilla-engine-plugin/app/templates/tsconfig.json +20 -0
- package/generator-gorilla-engine-plugin/package.json +17 -0
- package/index.js +72 -0
- package/package.json +42 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# Basic Controls
|
|
2
|
+
|
|
3
|
+
## geLabel
|
|
4
|
+
|
|
5
|
+
Display text, images, or act as a container/panel. The most versatile component.
|
|
6
|
+
|
|
7
|
+
**JSX tag:** `<geLabel />`
|
|
8
|
+
**Interfaces:** Common, Bounds, Background, Font, Clickable, Margin, Keyable
|
|
9
|
+
**Handlers:** ClickableHandlers, KeyableHandlers
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Description |
|
|
12
|
+
|------|------|-------------|
|
|
13
|
+
| `text` | `string \| number` | Display text (updates at runtime) |
|
|
14
|
+
| `value` | `any` | Initial text (doesn't update at runtime) |
|
|
15
|
+
| `format` | `string` | Text format string |
|
|
16
|
+
| `multiLine` | `boolean` | Enable multi-line text |
|
|
17
|
+
| `stretchText` | `boolean` | Stretch text to fit bounds |
|
|
18
|
+
|
|
19
|
+
**As a container/panel:**
|
|
20
|
+
```tsx
|
|
21
|
+
<geLabel x={0} y={0} width={400} height={300}
|
|
22
|
+
backgroundColor="FF1a1a2e" cornerRadius={8}
|
|
23
|
+
border={{ width: 1, color: "FF444444" }}>
|
|
24
|
+
<geKnob x={10} y={10} width={60} height={60} />
|
|
25
|
+
<geLabel x={80} y={25} width={100} height={20} text="Volume" textColor="FFFFFF" />
|
|
26
|
+
</geLabel>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**As a text label:**
|
|
30
|
+
```tsx
|
|
31
|
+
<geLabel x={10} y={10} width={100} height={20}
|
|
32
|
+
text="Hello World" textColor="FFFFFF" fontSize={14} textAlign="center"
|
|
33
|
+
/>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## geButton
|
|
39
|
+
|
|
40
|
+
Trigger button — fires an action on click, does NOT toggle.
|
|
41
|
+
|
|
42
|
+
**JSX tag:** `<geButton />`
|
|
43
|
+
**Native class:** `GorillaEngine.UI.Trigger`
|
|
44
|
+
**Interfaces:** Common, Bounds, Font, Clickable, Background, KeyboardFocus, Keyable
|
|
45
|
+
**Handlers:** ClickableHandlers, KeyableHandlers
|
|
46
|
+
|
|
47
|
+
| Prop | Type | Description |
|
|
48
|
+
|------|------|-------------|
|
|
49
|
+
| `text` | `string` | Button label text |
|
|
50
|
+
| `isDumb` | `boolean` | If true, button has no built-in behavior |
|
|
51
|
+
| `images` | `object` | `{ normal?, hover?, down? }` — image paths per state |
|
|
52
|
+
| `animation` | `LottieAnimation` | Linked Lottie animation |
|
|
53
|
+
|
|
54
|
+
**Note:** geButton gets a default `keyboardFocus.color` of `"00000000"` (transparent).
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
<geButton x={10} y={10} width={120} height={35}
|
|
58
|
+
text="Save Preset"
|
|
59
|
+
backgroundColor="FF4444FF" textColor="FFFFFF"
|
|
60
|
+
images={{ normal: 'btn.png', hover: 'btn_hover.png', down: 'btn_down.png' }}
|
|
61
|
+
onClick={() => savePreset()}
|
|
62
|
+
/>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## geKnob
|
|
68
|
+
|
|
69
|
+
Rotary dial control for numeric values.
|
|
70
|
+
|
|
71
|
+
**JSX tag:** `<geKnob />`
|
|
72
|
+
**Interfaces:** Common, Bounds, Clickable, Background, Skinnable, MIDILearn, Highlight
|
|
73
|
+
**Handlers:** ClickableHandlers, `onChange`
|
|
74
|
+
|
|
75
|
+
| Prop | Type | Description |
|
|
76
|
+
|------|------|-------------|
|
|
77
|
+
| `text` | `string` | Display text |
|
|
78
|
+
| `min` | `number` | Minimum value |
|
|
79
|
+
| `max` | `number` | Maximum value |
|
|
80
|
+
| `value` | `number` | Current value (between min and max) |
|
|
81
|
+
| `stepSize` | `number` | Value increment per interaction step |
|
|
82
|
+
| `scrollWheelEnabled` | `boolean` | Allow mouse wheel adjustment |
|
|
83
|
+
| `image` | `string` | Single image path (rotated between minRotation/maxRotation) |
|
|
84
|
+
| `minRotation` | `number` | Min rotation angle in degrees (for `image` mode) |
|
|
85
|
+
| `maxRotation` | `number` | Max rotation angle in degrees (for `image` mode) |
|
|
86
|
+
| `inverted` | `boolean` | Invert the control direction |
|
|
87
|
+
| `filmstrip` | `object` | `{ path, count, direction? }` — filmstrip animation |
|
|
88
|
+
|
|
89
|
+
**Filmstrip mode (most common):**
|
|
90
|
+
```tsx
|
|
91
|
+
<geKnob x={50} y={50} width={60} height={60}
|
|
92
|
+
min={0} max={100} value={50}
|
|
93
|
+
filmstrip={{ path: 'assets/knob.png', count: 128 }}
|
|
94
|
+
onChange={(v) => setVolume(v)}
|
|
95
|
+
/>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Single image rotation mode:**
|
|
99
|
+
```tsx
|
|
100
|
+
<geKnob x={50} y={50} width={60} height={60}
|
|
101
|
+
min={0} max={127} value={64}
|
|
102
|
+
image="assets/knob_pointer.png"
|
|
103
|
+
minRotation={-135} maxRotation={135}
|
|
104
|
+
/>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## geSlider
|
|
110
|
+
|
|
111
|
+
Linear slider control (horizontal or vertical). Internally a Knob with `type: 'slider'`.
|
|
112
|
+
|
|
113
|
+
**JSX tag:** `<geSlider />`
|
|
114
|
+
**Native class:** `GorillaEngine.UI.Knob` with `type: 'slider'`
|
|
115
|
+
**Interfaces:** Same as geKnob + slider-specific props
|
|
116
|
+
**Handlers:** ClickableHandlers, `onChange`
|
|
117
|
+
|
|
118
|
+
| Prop | Type | Description |
|
|
119
|
+
|------|------|-------------|
|
|
120
|
+
| *(all geKnob props)* | | Inherits knob properties |
|
|
121
|
+
| `direction` | `'horizontal' \| 'vertical'` | Slider orientation |
|
|
122
|
+
| `thumbImage` | `string` | Path to thumb/handle image |
|
|
123
|
+
| `sliderBounds` | `object` | `{ x, y, width, height }` — custom track bounds |
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
<geSlider x={10} y={100} width={200} height={30}
|
|
127
|
+
min={0} max={100} value={75}
|
|
128
|
+
direction="horizontal"
|
|
129
|
+
filmstrip={{ path: 'assets/slider_track.png', count: 128 }}
|
|
130
|
+
thumbImage="assets/slider_thumb.png"
|
|
131
|
+
onChange={(v) => setPan(v)}
|
|
132
|
+
/>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## geToggle
|
|
138
|
+
|
|
139
|
+
Two-state toggle control (on/off).
|
|
140
|
+
|
|
141
|
+
**JSX tag:** `<geToggle />`
|
|
142
|
+
**Interfaces:** Common, Bounds, Font, Clickable, Background, Highlight, MIDILearn, Margin
|
|
143
|
+
**Handlers:** ClickableHandlers, `onChange`
|
|
144
|
+
|
|
145
|
+
| Prop | Type | Description |
|
|
146
|
+
|------|------|-------------|
|
|
147
|
+
| `text` | `string` | Label text |
|
|
148
|
+
| `value` | `boolean` | Current state |
|
|
149
|
+
| `onColor` | `string` | Background color when on |
|
|
150
|
+
| `offColor` | `string` | Background color when off |
|
|
151
|
+
| `onColorHover` | `string` | Hover color when on |
|
|
152
|
+
| `offColorHover` | `string` | Hover color when off |
|
|
153
|
+
| `textColorOn` / `textColorOff` | `string` | Text color per state |
|
|
154
|
+
| `textColorOnHover` / `textColorOffHover` | `string` | Text hover color per state |
|
|
155
|
+
| `onImage` / `offImage` | `string` | Image per state |
|
|
156
|
+
| `onImagePressed` / `offImagePressed` | `string` | Pressed image per state |
|
|
157
|
+
| `onImageHovered` / `offImageHovered` | `string` | Hover image per state |
|
|
158
|
+
| `disabledImage` | `string` | Image when disabled |
|
|
159
|
+
| `radioIndex` / `radioValue` | `number` | Radio group behavior |
|
|
160
|
+
| `drawTick` | `boolean` | Draw a tick box |
|
|
161
|
+
| `fitToText` | `boolean` | Auto-size font to fit bounds |
|
|
162
|
+
| `animation` | `LottieAnimation` | Linked Lottie animation |
|
|
163
|
+
|
|
164
|
+
**Color-based toggle:**
|
|
165
|
+
```tsx
|
|
166
|
+
<geToggle x={10} y={10} width={60} height={30}
|
|
167
|
+
value={isMuted}
|
|
168
|
+
text="Mute"
|
|
169
|
+
onColor="FFFF4444" offColor="FF444444"
|
|
170
|
+
textColorOn="FFFFFF" textColorOff="AAAAAA"
|
|
171
|
+
onChange={(isOn) => setMuted(isOn)}
|
|
172
|
+
/>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**Image-based toggle:**
|
|
176
|
+
```tsx
|
|
177
|
+
<geToggle x={10} y={10} width={40} height={40}
|
|
178
|
+
value={isSolo}
|
|
179
|
+
onImage="solo_on.png" offImage="solo_off.png"
|
|
180
|
+
onChange={(isOn) => setSolo(isOn)}
|
|
181
|
+
/>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## geTextBox
|
|
187
|
+
|
|
188
|
+
Editable text input.
|
|
189
|
+
|
|
190
|
+
**JSX tag:** `<geTextBox />`
|
|
191
|
+
**Interfaces:** Font, Clickable, Bounds, Background, Margin, Keyable
|
|
192
|
+
**Handlers:** KeyableHandlers, `onChange`, `onFocusLost`
|
|
193
|
+
|
|
194
|
+
| Prop | Type | Description |
|
|
195
|
+
|------|------|-------------|
|
|
196
|
+
| `text` | `string` | Current text value |
|
|
197
|
+
| `placeholder` | `string` | Placeholder text |
|
|
198
|
+
| `unit` | `string` | Suffix displayed (doesn't alter value) |
|
|
199
|
+
| `placeHolderColor` | `string` | Placeholder text color |
|
|
200
|
+
| `caretColor` | `string` | Cursor color |
|
|
201
|
+
| `maxLength` | `number` | Max character count |
|
|
202
|
+
| `passwordCharacter` | `string` | Mask character for passwords |
|
|
203
|
+
| `multiLine` | `boolean` | Allow multiple lines |
|
|
204
|
+
| `readOnly` | `boolean` | Disable editing |
|
|
205
|
+
| `acceptedDataType` | `string` | `'integer'`, `'int'`, `'float'`, or `'string'` |
|
|
206
|
+
| `minValue` / `maxValue` | `number` | Numeric bounds (when numeric type) |
|
|
207
|
+
| `textChangedAction` | `string` | ViewModel action on enter (not on change) |
|
|
208
|
+
| `focusLostUpdate` | `boolean` | Update on focus lost |
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
<geTextBox x={10} y={10} width={200} height={30}
|
|
212
|
+
text={presetName}
|
|
213
|
+
placeholder="Enter preset name..."
|
|
214
|
+
backgroundColor="FF222222" textColor="FFFFFF"
|
|
215
|
+
fontSize={13}
|
|
216
|
+
onChange={(text) => setPresetName(text)}
|
|
217
|
+
onFocusLost={(text) => savePresetName(text)}
|
|
218
|
+
/>
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Numeric input:**
|
|
222
|
+
```tsx
|
|
223
|
+
<geTextBox x={10} y={50} width={80} height={30}
|
|
224
|
+
text="440"
|
|
225
|
+
acceptedDataType="float"
|
|
226
|
+
minValue={20} maxValue={20000}
|
|
227
|
+
unit=" Hz"
|
|
228
|
+
onChange={(text) => setFrequency(parseFloat(text))}
|
|
229
|
+
/>
|
|
230
|
+
```
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# Bindings
|
|
2
|
+
|
|
3
|
+
Declarative data binding connects UI component properties to instrument parameters or view model paths.
|
|
4
|
+
|
|
5
|
+
## Binding Targets
|
|
6
|
+
|
|
7
|
+
Binding values can be either an **`InstrumentProperty` object** (preferred) or a **string path**.
|
|
8
|
+
|
|
9
|
+
### Object binding (preferred)
|
|
10
|
+
|
|
11
|
+
Pass the `InstrumentProperty` directly. This is type-safe and avoids string typos:
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
// instrument[propName] returns an InstrumentProperty object
|
|
15
|
+
bindings={{ value: instrument.volume }}
|
|
16
|
+
bindings={{ value: instrument.filtercutoff, text: instrument.filtercutoff }}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### String path binding
|
|
20
|
+
|
|
21
|
+
Three string formats are supported:
|
|
22
|
+
|
|
23
|
+
| Format | Example | Description |
|
|
24
|
+
| -------------------- | ---------------------- | --------------------------------------------------------- |
|
|
25
|
+
| Instrument parameter | `'instrument.volume'` | References an instrument parameter by key name |
|
|
26
|
+
| Engine path | `'Scripts/0/Volume'` | Direct path into the instrument parameter tree |
|
|
27
|
+
| View model path | `'viewModel.property'` | `namespace.property` — references a registered view model |
|
|
28
|
+
|
|
29
|
+
**View model namespaces:**
|
|
30
|
+
|
|
31
|
+
- `'instrument'` — the active instrument (set via `GorillaEngine.setActiveInstrument()`); each property is an `InstrumentProperty` by its key name
|
|
32
|
+
- Any custom name registered with `initViewModel(name, initialState)` (e.g. `'viewModel.myProp'`)
|
|
33
|
+
|
|
34
|
+
> **`initViewModel` is deprecated.** Prefer using `useInstrumentProperty` hooks or object bindings.
|
|
35
|
+
|
|
36
|
+
## React Props Syntax
|
|
37
|
+
|
|
38
|
+
Use the `bindings` prop on any component. Values can be `InstrumentProperty` objects or string paths:
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
// Object binding (preferred) — pass the InstrumentProperty directly
|
|
42
|
+
<geKnob
|
|
43
|
+
x={0} y={0} width={60} height={60}
|
|
44
|
+
bindings={{ value: instrument.volume }}
|
|
45
|
+
filmstrip={{ path: 'knob.png', count: 128 }}
|
|
46
|
+
/>
|
|
47
|
+
|
|
48
|
+
// String binding — equivalent, but less safe
|
|
49
|
+
<geKnob
|
|
50
|
+
x={0} y={0} width={60} height={60}
|
|
51
|
+
bindings={{ value: 'instrument.volume' }}
|
|
52
|
+
filmstrip={{ path: 'knob.png', count: 128 }}
|
|
53
|
+
/>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The `bindings` object maps **native property names** to **binding targets** (object or string).
|
|
57
|
+
|
|
58
|
+
### How It Works
|
|
59
|
+
|
|
60
|
+
The reconciler appends `&` to each binding key and passes the target through to the native layer:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
React: { bindings: { value: instrument.volume } } → Native: { 'value&': instrument.volume }
|
|
64
|
+
React: { bindings: { value: 'instrument.volume' } } → Native: { 'value&': 'instrument.volume' }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Nested Bindings
|
|
68
|
+
|
|
69
|
+
Bindings can also be applied to nested object properties:
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
<geKnob
|
|
73
|
+
x={0}
|
|
74
|
+
y={0}
|
|
75
|
+
width={60}
|
|
76
|
+
height={60}
|
|
77
|
+
filmstrip={{ path: 'knob.png', count: 128, bindings: { path: 'vm.knobAsset' } }}
|
|
78
|
+
/>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
This translates to:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
Native: { filmstrip: { count: 128, 'path&': 'vm.knobAsset' } }
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Runtime Binding API
|
|
90
|
+
|
|
91
|
+
All controls that support dynamic bindings expose these methods. Check support with `control.supportsSetBindings()` — returns `true` for most controls.
|
|
92
|
+
|
|
93
|
+
### `control.setBindings(bindingsObj)`
|
|
94
|
+
|
|
95
|
+
Binds multiple properties at once. Pass `{}` to clear all bindings on the control.
|
|
96
|
+
|
|
97
|
+
The binding target can be a **string path** or an **`InstrumentProperty` object** directly (preferred).
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
// Bind by InstrumentProperty object (preferred)
|
|
101
|
+
control.setBindings({ value: instrument.volume });
|
|
102
|
+
|
|
103
|
+
// Bind by string path
|
|
104
|
+
control.setBindings({ value: 'instrument.volume', width: 'viewModel.size' });
|
|
105
|
+
|
|
106
|
+
// Clear all bindings
|
|
107
|
+
control.setBindings({});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### `control.bind(propertyPath, target)`
|
|
111
|
+
|
|
112
|
+
Rebinds a single property at runtime. Supports dot-separated paths for nested properties. Replaces any existing binding for that property.
|
|
113
|
+
|
|
114
|
+
```js
|
|
115
|
+
// Bind by object (preferred)
|
|
116
|
+
control.bind('value', instrument.volume);
|
|
117
|
+
|
|
118
|
+
// Bind by string path
|
|
119
|
+
control.bind('value', 'instrument.volume');
|
|
120
|
+
|
|
121
|
+
// Bind nested property
|
|
122
|
+
control.bind('midiLearn.enabled', instrument.int1);
|
|
123
|
+
control.bind('filmstrip.path', 'viewModel.assetPath');
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### `control.unbind(propertyPath)`
|
|
127
|
+
|
|
128
|
+
Removes the binding for a single property.
|
|
129
|
+
|
|
130
|
+
```js
|
|
131
|
+
control.unbind('value');
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### `control.supportsSetBindings()`
|
|
135
|
+
|
|
136
|
+
Returns `true` if the control supports runtime `setBindings`/`bind`. Most controls support this.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Common Binding Targets
|
|
141
|
+
|
|
142
|
+
| Component | Object binding (preferred) | String equivalent |
|
|
143
|
+
| ---------- | --------------------------------- | ----------------------------------------- |
|
|
144
|
+
| geKnob | `{ value: instrument.volume }` | `{ value: 'instrument.volume' }` |
|
|
145
|
+
| geSlider | `{ value: instrument.Pan }` | `{ value: 'instrument.Pan' }` |
|
|
146
|
+
| geToggle | `{ value: instrument.Mute }` | `{ value: 'instrument.Mute' }` |
|
|
147
|
+
| geComboBox | `{ value: instrument.WaveShape }` | `{ value: 'instrument.WaveShape' }` |
|
|
148
|
+
| geLabel | `{ text: instrument.volume }` | `{ text: 'vm.displayText' }` (view model) |
|
|
149
|
+
| geWaveform | — | `{ value: 'vm.waveformData' }` |
|
|
150
|
+
|
|
151
|
+
## Bindings vs. Hooks
|
|
152
|
+
|
|
153
|
+
| Approach | When to use |
|
|
154
|
+
| ----------------------- | ------------------------------------------------------------------------------------- |
|
|
155
|
+
| `bindings` | Direct engine parameter binding; no React state needed; simpler |
|
|
156
|
+
| `useInstrumentProperty` | Need React-side state, formatting, conditional logic, or cross-component coordination |
|
|
157
|
+
|
|
158
|
+
You can mix both approaches. Bindings are processed natively (more efficient for simple cases), while hooks give you full React control.
|
|
159
|
+
|
|
160
|
+
## Example: Combined Approach
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
function FilterSection({ instrument }) {
|
|
164
|
+
// Use hook when you need the value in React
|
|
165
|
+
const [cutoff, setCutoff] = useInstrumentProperty(instrument, 'FilterCutoff');
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<geLabel x={0} y={0} width={200} height={100} backgroundColor="FF333333">
|
|
169
|
+
{/* Binding: knob value syncs directly with engine (object preferred) */}
|
|
170
|
+
<geKnob
|
|
171
|
+
x={10}
|
|
172
|
+
y={10}
|
|
173
|
+
width={60}
|
|
174
|
+
height={60}
|
|
175
|
+
bindings={{ value: instrument.filtercutoff }}
|
|
176
|
+
filmstrip={{ path: 'knob.png', count: 128 }}
|
|
177
|
+
/>
|
|
178
|
+
{/* Hook: use React state for display text */}
|
|
179
|
+
<geLabel x={80} y={30} width={100} height={20} text={`${cutoff.text}`} textColor="FFFFFF" />
|
|
180
|
+
</geLabel>
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
```
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# Composite & Utility Components
|
|
2
|
+
|
|
3
|
+
## geTagBrowser
|
|
4
|
+
|
|
5
|
+
Tag-based browser UI for filtering content.
|
|
6
|
+
|
|
7
|
+
**JSX tag:** `<geTagBrowser />`
|
|
8
|
+
**Interfaces:** Common, Bounds, Background, Font
|
|
9
|
+
|
|
10
|
+
| Prop | Type | Description |
|
|
11
|
+
| ------- | ------- | ------------------------ |
|
|
12
|
+
| `value` | `any` | Current selection value |
|
|
13
|
+
| `tags` | `Tag[]` | Array of tag definitions |
|
|
14
|
+
|
|
15
|
+
**Tag configuration:**
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
interface Tag {
|
|
19
|
+
height: number;
|
|
20
|
+
borderSize: number;
|
|
21
|
+
cornerRadius: number;
|
|
22
|
+
textColor: { normal: string; active: string; header: string };
|
|
23
|
+
backgroundColor: { normal: string; active: string; header: string };
|
|
24
|
+
cancel: { x: number; width: number };
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
<geTagBrowser
|
|
30
|
+
x={10}
|
|
31
|
+
y={10}
|
|
32
|
+
width={300}
|
|
33
|
+
height={400}
|
|
34
|
+
backgroundColor="FF222222"
|
|
35
|
+
tags={tagDefinitions}
|
|
36
|
+
bindings={{ value: 'vm.selectedTags' }}
|
|
37
|
+
/>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## geTagEditor
|
|
43
|
+
|
|
44
|
+
Editable tag interface.
|
|
45
|
+
|
|
46
|
+
**JSX tag:** `<geTagEditor />`
|
|
47
|
+
**Interfaces:** Common, Bounds, Background, Font
|
|
48
|
+
|
|
49
|
+
| Prop | Type | Description |
|
|
50
|
+
| -------------- | --------- | -------------------------------------- |
|
|
51
|
+
| `value` | `any` | Current tags value |
|
|
52
|
+
| `tags` | `Tag[]` | Tag definitions (same as geTagBrowser) |
|
|
53
|
+
| `editable` | `boolean` | Allow editing tags |
|
|
54
|
+
| `action` | `string` | ViewModel action on change |
|
|
55
|
+
| `removeAction` | `string` | ViewModel action on tag removal |
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
<geTagEditor
|
|
59
|
+
x={10}
|
|
60
|
+
y={10}
|
|
61
|
+
width={300}
|
|
62
|
+
height={100}
|
|
63
|
+
backgroundColor="FF222222"
|
|
64
|
+
editable={true}
|
|
65
|
+
tags={tagDefinitions}
|
|
66
|
+
bindings={{ value: 'vm.editableTags' }}
|
|
67
|
+
/>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Labeled Controls
|
|
73
|
+
|
|
74
|
+
Use `@gorilla-engine-sdk/ge-labeled-components` when a control needs a name label, a formatted value label, or interaction-driven label visibility. These components bind directly to Gorilla Engine instrument properties.
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
import {
|
|
78
|
+
LabeledComboBox,
|
|
79
|
+
LabeledKnob,
|
|
80
|
+
LabeledMeterSlider,
|
|
81
|
+
LabeledRTToggle,
|
|
82
|
+
LabeledSlider,
|
|
83
|
+
LabeledToggle,
|
|
84
|
+
} from '@gorilla-engine-sdk/ge-labeled-components';
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The package exports:
|
|
88
|
+
|
|
89
|
+
| Component | Use case | Control configuration prop |
|
|
90
|
+
| -------------------- | --------------------------------------------- | -------------------------- |
|
|
91
|
+
| `LabeledKnob` | Rotary parameter control | `knob` |
|
|
92
|
+
| `LabeledSlider` | Horizontal or vertical parameter control | `slider` |
|
|
93
|
+
| `LabeledToggle` | Persistent on/off parameter control | `toggle` |
|
|
94
|
+
| `LabeledComboBox` | Selection from a parameter's available values | `comboBox` |
|
|
95
|
+
| `LabeledMeterSlider` | Parameter slider over a live level meter | `slider`, `meter` |
|
|
96
|
+
| `LabeledRTToggle` | Momentary control active while pressed | `button` |
|
|
97
|
+
|
|
98
|
+
### Shared Props
|
|
99
|
+
|
|
100
|
+
| Prop | Type | Description |
|
|
101
|
+
| ------------------------- | ---------------------------------- | ----------------------------------------------- |
|
|
102
|
+
| `x`, `y` | `number` | Position of the labeled component container |
|
|
103
|
+
| `width`, `height` | `number` | Size of the labeled component container |
|
|
104
|
+
| `instrument` | `GorillaEngine.Instrument` | Instrument instance supplied to the UI |
|
|
105
|
+
| `instrumentProp` | `GorillaEngine.InstrumentProperty` | Instrument property controlled by the component |
|
|
106
|
+
| `textLabel` | Partial label props | Name-label position, appearance, and `text` |
|
|
107
|
+
| `valueLabel` | Partial label props | Value-label position and appearance |
|
|
108
|
+
| `hideValueLabel` | `boolean` | Hide the value until the configured interaction |
|
|
109
|
+
| `hideTextValue` | `boolean` | Hide the name while the value is visible |
|
|
110
|
+
| `toggleVisibilityOnHover` | `boolean` | Show the value on hover instead of mouse down |
|
|
111
|
+
| `ranges` | `{ from?, to?, text }[]` | Format values for matching numeric ranges |
|
|
112
|
+
|
|
113
|
+
Pass geometry and assets for the native control inside its component-specific configuration prop. Bind through `instrumentProp`; do not mirror parameter values into React state.
|
|
114
|
+
|
|
115
|
+
### Knob Example
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
<LabeledKnob
|
|
119
|
+
x={40}
|
|
120
|
+
y={40}
|
|
121
|
+
width={90}
|
|
122
|
+
height={110}
|
|
123
|
+
instrument={instrument}
|
|
124
|
+
instrumentProp={instrument.volume}
|
|
125
|
+
hideValueLabel={true}
|
|
126
|
+
hideTextValue={true}
|
|
127
|
+
toggleVisibilityOnHover={true}
|
|
128
|
+
textLabel={{
|
|
129
|
+
y: 88,
|
|
130
|
+
height: 18,
|
|
131
|
+
text: 'VOLUME',
|
|
132
|
+
font: 'fonts/Roboto-Medium.otf',
|
|
133
|
+
fontSize: 12,
|
|
134
|
+
textAlign: 'center',
|
|
135
|
+
}}
|
|
136
|
+
valueLabel={{
|
|
137
|
+
y: 88,
|
|
138
|
+
height: 18,
|
|
139
|
+
font: 'fonts/Roboto-Medium.otf',
|
|
140
|
+
fontSize: 12,
|
|
141
|
+
textAlign: 'center',
|
|
142
|
+
}}
|
|
143
|
+
ranges={[{ text: '$value(1) dB' }]}
|
|
144
|
+
knob={{
|
|
145
|
+
width: 80,
|
|
146
|
+
height: 80,
|
|
147
|
+
filmstrip: {
|
|
148
|
+
path: 'images/volume-knob.png',
|
|
149
|
+
count: 128,
|
|
150
|
+
direction: 'vertical',
|
|
151
|
+
},
|
|
152
|
+
}}
|
|
153
|
+
/>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Slider And Toggle Example
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
<LabeledSlider
|
|
160
|
+
x={160}
|
|
161
|
+
y={40}
|
|
162
|
+
width={60}
|
|
163
|
+
height={220}
|
|
164
|
+
instrument={instrument}
|
|
165
|
+
instrumentProp={instrument.output}
|
|
166
|
+
textLabel={{ y: 194, height: 18, text: 'OUTPUT', textAlign: 'center' }}
|
|
167
|
+
valueLabel={{ y: 194, height: 18, textAlign: 'center' }}
|
|
168
|
+
ranges={[{ text: '$value(1) dB' }]}
|
|
169
|
+
slider={{
|
|
170
|
+
y: 0,
|
|
171
|
+
width: 40,
|
|
172
|
+
height: 180,
|
|
173
|
+
filmstrip: {
|
|
174
|
+
path: 'images/output-slider.png',
|
|
175
|
+
count: 128,
|
|
176
|
+
direction: 'vertical',
|
|
177
|
+
},
|
|
178
|
+
}}
|
|
179
|
+
/>
|
|
180
|
+
|
|
181
|
+
<LabeledToggle
|
|
182
|
+
x={250}
|
|
183
|
+
y={40}
|
|
184
|
+
width={80}
|
|
185
|
+
height={90}
|
|
186
|
+
instrument={instrument}
|
|
187
|
+
instrumentProp={instrument.bypass}
|
|
188
|
+
textLabel={{ y: 66, height: 18, text: 'BYPASS', textAlign: 'center' }}
|
|
189
|
+
toggle={{
|
|
190
|
+
width: 60,
|
|
191
|
+
height: 60,
|
|
192
|
+
filmstrip: {
|
|
193
|
+
path: 'images/bypass-toggle.png',
|
|
194
|
+
count: 2,
|
|
195
|
+
direction: 'vertical',
|
|
196
|
+
},
|
|
197
|
+
}}
|
|
198
|
+
/>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Selection, Meter, And Momentary Examples
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
<LabeledComboBox
|
|
205
|
+
x={360}
|
|
206
|
+
y={40}
|
|
207
|
+
width={140}
|
|
208
|
+
height={70}
|
|
209
|
+
instrument={instrument}
|
|
210
|
+
instrumentProp={instrument.mode}
|
|
211
|
+
textLabel={{ y: 48, height: 18, text: 'MODE', textAlign: 'center' }}
|
|
212
|
+
comboBox={{ y: 0, width: 120, height: 36 }}
|
|
213
|
+
/>
|
|
214
|
+
|
|
215
|
+
<LabeledMeterSlider
|
|
216
|
+
x={520}
|
|
217
|
+
y={40}
|
|
218
|
+
width={60}
|
|
219
|
+
height={240}
|
|
220
|
+
instrument={instrument}
|
|
221
|
+
instrumentProp={instrument.master_volume}
|
|
222
|
+
meterProp={instrument.master_level}
|
|
223
|
+
textLabel={{ y: 214, height: 18, text: 'MASTER', textAlign: 'center' }}
|
|
224
|
+
valueLabel={{ y: 214, height: 18, textAlign: 'center' }}
|
|
225
|
+
meter={{ y: 0, width: 30, height: 200 }}
|
|
226
|
+
slider={{ y: 0, width: 40, height: 200 }}
|
|
227
|
+
/>
|
|
228
|
+
|
|
229
|
+
<LabeledRTToggle
|
|
230
|
+
x={610}
|
|
231
|
+
y={40}
|
|
232
|
+
width={80}
|
|
233
|
+
height={90}
|
|
234
|
+
instrument={instrument}
|
|
235
|
+
instrumentProp={instrument.trigger}
|
|
236
|
+
textLabel={{ y: 66, height: 18, text: 'TRIGGER', textAlign: 'center' }}
|
|
237
|
+
button={{ width: 60, height: 60 }}
|
|
238
|
+
/>
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
`LabeledRTToggle` writes `1` while pressed and returns the property to `0` when released.
|
|
242
|
+
|
|
243
|
+
### Value Formatting
|
|
244
|
+
|
|
245
|
+
Use `ranges` to format the displayed value. `$value` inserts the raw value, `$value(n)` fixes it to `n` decimal places, and `$text_value` uses the parameter's formatted text.
|
|
246
|
+
|
|
247
|
+
```tsx
|
|
248
|
+
<LabeledKnob
|
|
249
|
+
instrument={instrument}
|
|
250
|
+
instrumentProp={instrument.frequency}
|
|
251
|
+
ranges={[
|
|
252
|
+
{ to: 999, text: '$value(0) Hz' },
|
|
253
|
+
{ from: 1000, text: '$value(2) kHz' },
|
|
254
|
+
]}
|
|
255
|
+
textLabel={{ text: 'FREQUENCY' }}
|
|
256
|
+
knob={{ width: 80, height: 80 }}
|
|
257
|
+
/>
|
|
258
|
+
```
|