444 lines
15 KiB
CoffeeScript
444 lines
15 KiB
CoffeeScript
context = window
|
|
ConfigureTracksStore = @ConfigureTracksStore
|
|
@ConfigureLiveTracksDialog = React.createClass({
|
|
|
|
mixins: [Reflux.listenTo(@ConfigureTracksStore,"onConfigureTracksChanged"), Reflux.listenTo(@AppStore, "onAppInit")]
|
|
|
|
onConfigureTracksChanged:(configureTracks) ->
|
|
@setState({configureTracks: configureTracks})
|
|
|
|
onAppInit: (@app) ->
|
|
|
|
getInitialState: () ->
|
|
{configureTracks: null, midiInterface: null}
|
|
|
|
renderAudio: () ->
|
|
inputOneOptions = []
|
|
inputTwoOptions = []
|
|
|
|
defaultSelectionOne = `<option value="">Select an input port for this track (required)</option>`
|
|
defaultSelectionTwo = `<option value="">Select an input port for this track (optional)</option>`
|
|
|
|
inputOneOptions.push(defaultSelectionOne)
|
|
inputTwoOptions.push(defaultSelectionTwo)
|
|
inputOneValue = ''
|
|
inputTwoValue = ''
|
|
selectedInstrument = ''
|
|
selectedVst = 'NONE'
|
|
|
|
|
|
instruments = []
|
|
instruments.push(`<option value="">Select the instrument for this track</option>`)
|
|
for displayName, value of context.JK.server_to_client_instrument_map
|
|
instruments.push(`<option value={value.server_id}>{displayName}</option>`)
|
|
|
|
vsts = []
|
|
|
|
instrumentDisabled = true
|
|
vstDisabled = true
|
|
|
|
|
|
if @state.configureTracks?
|
|
|
|
if @state.configureTracks.scanningVsts
|
|
scan =
|
|
`<div className="vstScan">
|
|
<div className="spinner-small"></div><span>Scanning your system<br/>for VST & AU plug-ins...</span>
|
|
</div>`
|
|
|
|
selectedInstrument = @state.configureTracks.editingTrack.instrument_id if @state.configureTracks.editingTrack.instrument_id?
|
|
|
|
if @state.configureTracks.editingTrack.length == 1
|
|
input = @state.configureTracks.editingTrack[0]
|
|
if input.number == 0
|
|
inputOneValue = input.id
|
|
else
|
|
inputTwoValue = input.id
|
|
|
|
if @state.configureTracks.editingTrack.length > 1
|
|
inputOneValue = @state.configureTracks.editingTrack[0].id
|
|
inputTwoValue = @state.configureTracks.editingTrack[1].id
|
|
|
|
instrumentDisabled = @state.configureTracks.editingTrack.length == 0
|
|
vstDisabled = @state.configureTracks.editingTrack.length == 0 || @state.configureTracks.unscanned
|
|
|
|
if @state.configureTracks.unscanned
|
|
initialScan = `<a className="button-orange" onClick={this.initialScan}>SCAN</a>`
|
|
|
|
for input in @state.configureTracks.musicPorts.inputs
|
|
|
|
include = false
|
|
# we need to see that this input is unassigned, or one of the two selected
|
|
for unassignedInputs in @state.configureTracks.trackAssignments.inputs.unassigned
|
|
if unassignedInputs.id == input.id
|
|
include = true
|
|
break
|
|
|
|
if !include
|
|
# not see if it's the currently edited track
|
|
for currentInput in @state.configureTracks.editingTrack
|
|
if currentInput.id == input.id
|
|
include = true
|
|
|
|
if include
|
|
item = `<option value={input.id}>{input.name}</option>`
|
|
inputOneOptions.push(item)
|
|
inputTwoOptions.push(item)
|
|
|
|
|
|
for plugin in @state.configureTracks.vstPluginList.vsts
|
|
if plugin.isInstrument == false
|
|
vsts.push(`<option value={plugin.file}>{plugin.name} by {plugin.manuf}</option>`)
|
|
else if plugin.category == 'NONE'
|
|
vsts.push(`<option value={plugin.file}>No VST/AU plugin selected</option>`)
|
|
|
|
if @state.configureTracks.editingTrack.vst?
|
|
vstAssignedThisTrack = true
|
|
selectedVst = @state.configureTracks.editingTrack.vst.file
|
|
|
|
vstSettingBtnClasses = classNames({'button-orange': vstAssignedThisTrack, 'button-grey': !vstAssignedThisTrack})
|
|
`<div className="audio">
|
|
<div className="audio-input-ports">
|
|
<h3>Audio Input Ports</h3>
|
|
<p>Select one or two inputs ports to assign to this track. Note that if you assign a single input port, the app will automatically duplicate this port into a stereo track.</p>
|
|
<select className="input-one" name="input-one" onChange={this.inputChanged} value={inputOneValue}>
|
|
{inputOneOptions}
|
|
</select>
|
|
<select className="input-two" name="input-two" onChange={this.inputChanged} value={inputTwoValue}>
|
|
{inputTwoOptions}
|
|
</select>
|
|
</div>
|
|
<div className="instrument-selection">
|
|
<h3>Instrument</h3>
|
|
<select className="instrument-pick" name="instrument" onChange={this.instrumentSelected} value={selectedInstrument} disabled={instrumentDisabled}>
|
|
{instruments}
|
|
</select>
|
|
</div>
|
|
<div className="audio-effects">
|
|
<h3>Audio Effects (optional) {initialScan}</h3>
|
|
<select className="vsts" name="vsts" onChange={this.vstsChanged} value={selectedVst} disabled={vstDisabled}>
|
|
{vsts}
|
|
</select>
|
|
<a className="manage-audio-plugins" onClick={this.manageAudioPlugins}>manage audio plugins <div className="down-arrow"></div></a>
|
|
<div className="settings-holder">
|
|
<a onClick={this.vstSettings} className={vstSettingBtnClasses}>SETTINGS . . .</a>
|
|
</div>
|
|
{scan}
|
|
</div>
|
|
</div>`
|
|
|
|
renderMidi: () ->
|
|
midiInterfaces = []
|
|
midiInterfaces.push(`<option value="">Select a MIDI interface</option>`)
|
|
midiInstruments = []
|
|
|
|
instruments = []
|
|
for displayName, value of context.JK.server_to_client_instrument_map
|
|
instruments.push(`<option value={value.server_id}>{displayName}</option>`)
|
|
|
|
selectedMidiInterface = ''
|
|
selectedInstrument = context.JK.client_to_server_instrument_map[50].server_id # default to electric guitar
|
|
selectedMidiInstrument = ''
|
|
|
|
instrumentDisabled = true
|
|
midiInstrumentDisabled = true
|
|
vstAssignedThisTrack = false
|
|
|
|
if @state.configureTracks?
|
|
|
|
logger.debug("current midi device: " + @state.configureTracks.editingTrack.midiDeviceIndex)
|
|
selectedMidiInterface = @state.configureTracks.editingTrack.midiDeviceIndex
|
|
|
|
selectedInstrument = @state.configureTracks.editingTrack.instrument_id if @state.configureTracks.editingTrack.instrument_id?
|
|
instrumentDisabled = !@state.midiInterface? || !selectedMidiInterface?
|
|
midiInstrumentDisabled = !@state.midiInterface? || !selectedMidiInterface?
|
|
midiInstrumentDisabled = false
|
|
instrumentDisabled = false
|
|
|
|
if @state.configureTracks.editingTrack.vst?
|
|
vstAssignedThisTrack = true
|
|
selectedMidiInstrument = @state.configureTracks.editingTrack.vst.file
|
|
vstSettingBtnClasses = classNames({'button-orange': vstAssignedThisTrack, 'button-grey': !vstAssignedThisTrack})
|
|
|
|
for midiDevice in @state.configureTracks.attachedMidiDevices.midiDevices
|
|
midiInterfaces.push(`<option value={midiDevice.deviceIndex}>{midiDevice.deviceName}</option>`)
|
|
|
|
for plugin in @state.configureTracks.vstPluginList.vsts
|
|
if plugin.isInstrument == true
|
|
midiInstruments.push(`<option value={plugin.file}>{plugin.name} by {plugin.manuf}</option>`)
|
|
else if plugin.category == 'NONE'
|
|
midiInstruments.push(`<option value={plugin.file}>Select a VST or AU instrument</option>`)
|
|
|
|
`<div className="midi">
|
|
<div className="midi-interface">
|
|
<h3>MIDI Interface</h3>
|
|
<select className="midi-select" name="midi-select" onChange={this.midiInterfaceChanged} value={selectedMidiInterface}>
|
|
{midiInterfaces}
|
|
</select>
|
|
<a className="scan-midi" onClick={this.scanMidi}>scan for connected MIDI interfaces</a>
|
|
</div>
|
|
<div className="instrument-selection">
|
|
<h3>Instrument</h3>
|
|
<select className="instrument-pick" name="instrument" onChange={this.instrumentSelected} value={selectedInstrument} disabled={instrumentDisabled}>
|
|
{instruments}
|
|
</select>
|
|
</div>
|
|
<div className="midi-instrument">
|
|
<h3>MIDI Instrument (VST or AU Plugin)</h3>
|
|
<select className="vsts" name="midi-instrument" onChange={this.vstsChanged} value={selectedMidiInstrument} disabled={midiInstrumentDisabled}>
|
|
{midiInstruments}
|
|
</select>
|
|
<a className="manage-audio-plugins" onClick={this.manageAudioPlugins}>manage audio plugins <div className="down-arrow"></div></a>
|
|
<div className="settings-holder">
|
|
<a onClick={this.vstSettings} className={vstSettingBtnClasses}>SETTING . . .</a>
|
|
</div>
|
|
</div>
|
|
</div>`
|
|
|
|
render: () ->
|
|
|
|
action = 'ADD TRACK'
|
|
header = 'add track'
|
|
|
|
isAudio = !@state.configureTracks? || @state.configureTracks.trackType == 'audio'
|
|
isMidi = !isAudio
|
|
|
|
if isAudio
|
|
activeElement = @renderAudio()
|
|
else
|
|
activeElement = @renderMidi()
|
|
|
|
if !@state.configureTracks?.newTrack
|
|
action = 'CLOSE'
|
|
header = 'update track'
|
|
else
|
|
cancelBtn = `<a onClick={this.onCancel} className="button-grey">CANCEL</a>`
|
|
|
|
if !@state.configureTracks?.unscanned
|
|
scanHelp = `<a className="dont-see-plugin" onClick={this.dontSeePlugin}>Don't see your plug-in in the list above?</a>`
|
|
|
|
|
|
`<div>
|
|
<div className="content-head">
|
|
<img className="content-icon" src="/assets/content/icon_add.png" height={19} width={19}/>
|
|
<h1>{header}</h1>
|
|
</div>
|
|
<div className="dialog-inner">
|
|
<div className="track-type">
|
|
<h3>Track Type</h3>
|
|
<div className="track-type-option"><input type="radio" value="audio" name="track-type" checked={isAudio} /><label>Audio</label></div>
|
|
<div className="track-type-option"><input type="radio" value="midi" name="track-type" checked={isMidi} /><label>MIDI</label></div>
|
|
</div>
|
|
|
|
{activeElement}
|
|
|
|
<div className="actions">
|
|
{cancelBtn}
|
|
<a onClick={this.doClose} className="button-orange">{action}</a>
|
|
</div>
|
|
</div>
|
|
</div>`
|
|
|
|
inputChanged: (e) ->
|
|
$root = $(@getDOMNode())
|
|
$select1 = $root.find('.input-one')
|
|
$select2 = $root.find('.input-two')
|
|
|
|
audioInput1 = $select1.val()
|
|
audioInput2 = $select2.val()
|
|
|
|
if audioInput1 == ''
|
|
audioInput1 = null
|
|
|
|
if audioInput2 == ''
|
|
audioInput2 = null
|
|
|
|
if audioInput1? && audioInput1 == audioInput2
|
|
e.preventDefault()
|
|
# TODO: tell user they can't do this
|
|
return
|
|
|
|
ConfigureTracksActions.associateInputsWithTrack(audioInput1, audioInput2)
|
|
|
|
|
|
vstsChanged: (e) ->
|
|
$root = $(@getDOMNode())
|
|
$select = $root.find('select.vsts')
|
|
vstSelected = $select.val()
|
|
#if vstSelected != 'NONE'
|
|
vstSelected = {file: vstSelected}
|
|
|
|
if @state.configureTracks?.trackType == 'midi'
|
|
@updateMidiAssociations()
|
|
else
|
|
logger.debug("associating vst", vstSelected)
|
|
ConfigureTracksActions.associateVSTWithTrack(vstSelected)
|
|
|
|
|
|
@setState({midiInterface: null})
|
|
|
|
instrumentSelected: (e) ->
|
|
$root = $(@getDOMNode())
|
|
$select = $root.find('.instrument-pick')
|
|
|
|
instrumentId = $select.val()
|
|
ConfigureTracksActions.associateInstrumentWithTrack(instrumentId)
|
|
|
|
|
|
doClose: (e) ->
|
|
e.preventDefault()
|
|
# check that instrument is selected
|
|
|
|
$root = $(@getDOMNode())
|
|
$instrument = $root.find('.instrument-pick')
|
|
|
|
instrumentId = $instrument.val()
|
|
|
|
$select1 = $root.find('.input-one')
|
|
$select2 = $root.find('.input-two')
|
|
|
|
audioInput1 = $select1.val()
|
|
audioInput2 = $select2.val()
|
|
|
|
if audioInput1 == ''
|
|
audioInput1 = null
|
|
|
|
if audioInput2 == ''
|
|
audioInput2 = null
|
|
|
|
if audioInput1 == null && audioInput2 == null
|
|
context.JK.Banner.showAlert("At least one input must be specified.")
|
|
return
|
|
|
|
if instrumentId == null || instrumentId == ''
|
|
context.JK.Banner.showAlert("Please select an instrument.")
|
|
return
|
|
|
|
@app.layout.closeDialog('configure-live-tracks-dialog', false)
|
|
|
|
onCancel: (e) ->
|
|
|
|
ConfigureTracksActions.cancelEdit()
|
|
|
|
@app.layout.closeDialog('configure-live-tracks-dialog', true)
|
|
|
|
vstSettings: (e) ->
|
|
e.preventDefault()
|
|
ConfigureTracksActions.showVstSettings()
|
|
|
|
|
|
componentDidMount: () ->
|
|
$root = $(@getDOMNode())
|
|
$radio = context.JK.checkbox($root.find('input[type="radio"]'))
|
|
$radio.on("ifChanged", @trackTypeChanged);
|
|
|
|
componentWillUpdate: () ->
|
|
@ignoreICheck = true
|
|
$root = $(@getDOMNode())
|
|
$radio = $root.find('input[type="radio"]')
|
|
|
|
if gon.midi_enabled
|
|
$radio.iCheck('disable')
|
|
else
|
|
$radio.iCheck('enable')
|
|
|
|
componentDidUpdate: () ->
|
|
$root = $(@getDOMNode())
|
|
$radio = $root.find('input[type="radio"]')
|
|
$radio = context.JK.checkbox($root.find('input[type="radio"]'))
|
|
$radio.on("ifChanged", @trackTypeChanged);
|
|
if gon.midi_enabled
|
|
if @state.configureTracks.editingTrack.assignment == 1
|
|
$radio.iCheck('disable')
|
|
else
|
|
$radio.iCheck('enable')
|
|
else
|
|
$radio.iCheck('disable')
|
|
|
|
@ignoreICheck = false
|
|
|
|
$manageAudioPlugins = $root.find('.manage-audio-plugins')
|
|
|
|
unless $manageAudioPlugins.data('initialized')
|
|
$manageAudioPlugins.manageVsts().on(context.JK.EVENTS.VST_OPERATION_SELECTED, @vstOperation).data('initialized', true)
|
|
|
|
trackTypeChanged: (event) ->
|
|
|
|
if @ignoreICheck
|
|
logger.debug("ignoring track type changed")
|
|
return
|
|
|
|
$checkedType = $(event.target);
|
|
value = $checkedType.val()
|
|
logger.debug("trackTypeChanged: " + value, $checkedType)
|
|
ConfigureTracksActions.desiredTrackType(value)
|
|
#@setState({trackType: value})
|
|
|
|
initialScan: (e) ->
|
|
e.preventDefault()
|
|
ConfigureTracksActions.vstScan()
|
|
|
|
dontSeePlugin: (e) ->
|
|
e.preventDefault()
|
|
context.JK.popExternalLink('https://jamkazam.desk.com/customer/portal/articles/2252557-adding-a-scan-folder-path-for-plugins')
|
|
|
|
vstOperation: (e, data) ->
|
|
|
|
if data.vstOperation == 'scan'
|
|
ConfigureTracksActions.vstScan()
|
|
else if data.vstOperation == 'clear'
|
|
ConfigureTracksActions.clearVsts()
|
|
else if data.vstOperation == 'manage'
|
|
ConfigureTracksActions.manageVsts()
|
|
|
|
manageAudioPlugins: (e) ->
|
|
e.preventDefault()
|
|
|
|
$root = $(@getDOMNode())
|
|
$manageAudioPlugins = $root.find('.manage-audio-plugins')
|
|
$manageAudioPlugins.btOn()
|
|
|
|
scanMidi: (e) ->
|
|
e.preventDefault()
|
|
|
|
ConfigureTracksActions.midiScan()
|
|
|
|
|
|
midiInterfaceChanged: (e) ->
|
|
|
|
@updateMidiAssociations()
|
|
|
|
updateMidiAssociations: (e) ->
|
|
$root = $(@getDOMNode())
|
|
$select = $root.find('select.midi-select')
|
|
midiInterface = $select.val()
|
|
|
|
$select = $root.find('select.vsts')
|
|
vstSelected = $select.val()
|
|
|
|
logger.debug("updateMidiAssocations", vstSelected, midiInterface)
|
|
if vstSelected != 'NONE'
|
|
vstSelected = {file: vstSelected}
|
|
else
|
|
vstSelected = null
|
|
|
|
if midiInterface == ''
|
|
midiInterface = null
|
|
|
|
midi = @state.midiInterface || midiInterface
|
|
|
|
if vstSelected? && midi?
|
|
logger.debug("updating midi:#{midi} & vst: #{vstSelected.file}")
|
|
|
|
ConfigureTracksActions.associateVSTWithTrack(vstSelected)
|
|
setTimeout((() =>
|
|
ConfigureTracksActions.associateMIDIWithTrack(midi)
|
|
), 250)
|
|
|
|
else if midi?
|
|
logger.debug("updating midi:#{midiInterface}")
|
|
ConfigureTracksActions.associateMIDIWithTrack(midiInterface)
|
|
|
|
@setState({midiInterface: midiInterface})
|
|
|
|
}) |