|
1 | 1 | import React, { useState, useEffect } from 'react' |
2 | | -import { findNodeWithKeyFromIdList, HedronEngine, ParamNode, ShotNode } from '@hedron-gl/engine' |
3 | | -import { useEngineStore, ControlGrid, NodeContainer } from '@hedron-gl/ui-core' |
| 2 | +import { HedronEngine, ParamNode, ShotNode } from '@hedron-gl/engine' |
| 3 | +import { useEngineStore, ControlGrid, NodeContainer, getNodeOptionNodes } from '@hedron-gl/ui-core' |
4 | 4 | import { MIDIEvent, MidiMessageType, midiMessageNames } from '@hedron-gl/midi-manager' |
5 | 5 | import { MidiInput } from './MidiInput' |
| 6 | +import { doesMidiEventMatchInput } from './utils' |
6 | 7 | import styles from './MidiGlobalPanel.module.css' |
| 8 | +import { NOTE_MODE_ON } from './constants' |
7 | 9 |
|
8 | 10 | interface MidiGlobalPanelProps { |
9 | 11 | engine: HedronEngine |
@@ -69,24 +71,34 @@ export const MidiGlobalPanel: React.FC<MidiGlobalPanelProps> = ({ engine }) => { |
69 | 71 | Object.values(nodes).forEach((input) => { |
70 | 72 | if (input?.nodeType !== 'input' || input.inputType !== 'midi') return |
71 | 73 |
|
72 | | - const channelNode = findNodeWithKeyFromIdList( |
73 | | - nodes, |
74 | | - 'channel', |
75 | | - input.childGroups.optionNodeIds, |
76 | | - ) |
77 | | - const noteNode = findNodeWithKeyFromIdList(nodes, 'note', input.childGroups.optionNodeIds) |
78 | | - const typeNode = findNodeWithKeyFromIdList(nodes, 'type', input.childGroups.optionNodeIds) |
| 74 | + const { |
| 75 | + channel: channelNode, |
| 76 | + note: noteNode, |
| 77 | + type: typeNode, |
| 78 | + noteMode: noteModeNode, |
| 79 | + } = getNodeOptionNodes({ nodes }, input.id) |
79 | 80 |
|
80 | 81 | if (!channelNode || !noteNode || !typeNode) return |
81 | 82 |
|
82 | | - const channelValue = paramValues[channelNode.id] |
83 | | - const noteValue = paramValues[noteNode.id] |
84 | | - const typeValue = paramValues[typeNode.id] |
| 83 | + const channelValue = paramValues[channelNode.id] as number | undefined |
| 84 | + const noteValue = paramValues[noteNode.id] as number | undefined |
| 85 | + const typeValue = paramValues[typeNode.id] as number | undefined |
| 86 | + const noteModeValue = noteModeNode |
| 87 | + ? ((paramValues[noteModeNode.id] as number | undefined) ?? NOTE_MODE_ON) |
| 88 | + : NOTE_MODE_ON |
| 89 | + |
| 90 | + if (channelValue === undefined || noteValue === undefined || typeValue === undefined) { |
| 91 | + return |
| 92 | + } |
85 | 93 |
|
86 | 94 | if ( |
87 | | - channelValue === event.channel && |
88 | | - noteValue === event.note && |
89 | | - typeValue === event.type |
| 95 | + doesMidiEventMatchInput({ |
| 96 | + event, |
| 97 | + channel: channelValue, |
| 98 | + note: noteValue, |
| 99 | + type: typeValue, |
| 100 | + noteMode: noteModeValue, |
| 101 | + }) |
90 | 102 | ) { |
91 | 103 | const targetNode = nodes[input.targetNodeId] as ParamNode | ShotNode |
92 | 104 | if (targetNode) { |
@@ -130,6 +142,7 @@ export const MidiGlobalPanel: React.FC<MidiGlobalPanelProps> = ({ engine }) => { |
130 | 142 | <div> |
131 | 143 | <ControlGrid> |
132 | 144 | <NodeContainer nodeId={`${globalNodeId}-smoothing`} /> |
| 145 | + <NodeContainer nodeId={`${globalNodeId}-autoMidiLearn`} /> |
133 | 146 | </ControlGrid> |
134 | 147 |
|
135 | 148 | <div className={styles.section}> |
|
0 commit comments