fix choice of preset via plugin host (safely updates table from non-message thread)
This commit is contained in:
		@ -417,44 +417,39 @@ void FluidSynthModel::setCurrentProgram(int index)
 | 
				
			|||||||
    RangedAudioParameter *param{valueTreeState.getParameter("preset")};
 | 
					    RangedAudioParameter *param{valueTreeState.getParameter("preset")};
 | 
				
			||||||
    jassert(dynamic_cast<AudioParameterInt*>(param) != nullptr);
 | 
					    jassert(dynamic_cast<AudioParameterInt*>(param) != nullptr);
 | 
				
			||||||
    AudioParameterInt* castParam{dynamic_cast<AudioParameterInt*>(param)};
 | 
					    AudioParameterInt* castParam{dynamic_cast<AudioParameterInt*>(param)};
 | 
				
			||||||
 | 
					    // setCurrentProgram() gets invoked from non-message thread.
 | 
				
			||||||
 | 
					    // AudioParameterInt#operator= will activate any listeners of audio parameter "preset".
 | 
				
			||||||
 | 
					    // This includes TableComponent, who will update its UI.
 | 
				
			||||||
 | 
					    // we need to lock the message thread whilst it does that UI update.
 | 
				
			||||||
 | 
					    const MessageManagerLock mmLock;
 | 
				
			||||||
    *castParam = index;
 | 
					    *castParam = index;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const String FluidSynthModel::getProgramName(int index)
 | 
					const String FluidSynthModel::getProgramName(int index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // fluid_sfont_t* sfont{
 | 
					     fluid_sfont_t* sfont{
 | 
				
			||||||
    //     sfont_id == -1
 | 
					         sfont_id == -1
 | 
				
			||||||
    //     ? nullptr
 | 
					         ? nullptr
 | 
				
			||||||
    //     : fluid_synth_get_sfont_by_id(synth.get(), sfont_id)
 | 
					         : fluid_synth_get_sfont_by_id(synth.get(), sfont_id)
 | 
				
			||||||
    // };
 | 
					     };
 | 
				
			||||||
    // if (!sfont) {
 | 
					     if (!sfont) {
 | 
				
			||||||
    //     return {};
 | 
					         String presetName{"Preset "};
 | 
				
			||||||
    // }
 | 
					         return presetName << index;
 | 
				
			||||||
    // int bank, presetNum;
 | 
					     }
 | 
				
			||||||
    // {
 | 
					     RangedAudioParameter *param{valueTreeState.getParameter("bank")};
 | 
				
			||||||
    //     RangedAudioParameter *param {valueTreeState.getParameter("bank")};
 | 
					     jassert(dynamic_cast<AudioParameterInt*>(param) != nullptr);
 | 
				
			||||||
    //     jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
 | 
					     AudioParameterInt* castParam{dynamic_cast<AudioParameterInt*>(param)};
 | 
				
			||||||
    //     AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
 | 
					     int bank{castParam->get()};
 | 
				
			||||||
    //     bank = castParam->get();
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
    // {
 | 
					 | 
				
			||||||
    //     RangedAudioParameter *param {valueTreeState.getParameter("preset")};
 | 
					 | 
				
			||||||
    //     jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
 | 
					 | 
				
			||||||
    //     AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
 | 
					 | 
				
			||||||
    //     presetNum = castParam->get();
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
    // fluid_preset_t *preset{fluid_sfont_get_preset(
 | 
					 | 
				
			||||||
    //     sfont,
 | 
					 | 
				
			||||||
    //     bank,
 | 
					 | 
				
			||||||
    //     presetNum)};
 | 
					 | 
				
			||||||
    // if (!preset) {
 | 
					 | 
				
			||||||
    //     return {};
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
    // return {fluid_preset_get_name(preset)};
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // I think the presets' names will be collected only at synth startup, so we won't yet have loaded the soundfont.
 | 
					     fluid_preset_t *preset{fluid_sfont_get_preset(
 | 
				
			||||||
    String presetName{"Preset "};
 | 
					         sfont,
 | 
				
			||||||
    return presetName << index;
 | 
					         bank,
 | 
				
			||||||
 | 
					         index)};
 | 
				
			||||||
 | 
					     if (!preset) {
 | 
				
			||||||
 | 
					         String presetName{"Preset "};
 | 
				
			||||||
 | 
					         return presetName << index;
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					     return {fluid_preset_get_name(preset)};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void FluidSynthModel::changeProgramName(int index, const String& newName)
 | 
					void FluidSynthModel::changeProgramName(int index, const String& newName)
 | 
				
			||||||
 | 
				
			|||||||
@ -215,30 +215,17 @@ void JuicySFAudioProcessor::getStateInformation (MemoryBlock& destData)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Create an outer XML element..
 | 
					    // Create an outer XML element..
 | 
				
			||||||
    XmlElement xml{"MYPLUGINSETTINGS"};
 | 
					    XmlElement xml{"MYPLUGINSETTINGS"};
 | 
				
			||||||
//    sharedParams->setAttributesOnXml(xml);
 | 
					 | 
				
			||||||
//    auto state{valueTreeState.copyState()};
 | 
					 | 
				
			||||||
//    unique_ptr<XmlElement> xml{state.createXml()};
 | 
					 | 
				
			||||||
//    sharedParams.setAttributesOnXml(xml);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//    list<StateChangeSubscriber*>::iterator p;
 | 
					 | 
				
			||||||
//    for(p = stateChangeSubscribers.begin(); p != stateChangeSubscribers.end(); p++) {
 | 
					 | 
				
			||||||
//        (*p)->getStateInformation(xml);
 | 
					 | 
				
			||||||
//    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Store the values of all our parameters, using their param ID as the XML attribute
 | 
					    // Store the values of all our parameters, using their param ID as the XML attribute
 | 
				
			||||||
    XmlElement* params{xml.createNewChildElement("params")};
 | 
					    XmlElement* params{xml.createNewChildElement("params")};
 | 
				
			||||||
    for (auto* param : getParameters()) {
 | 
					    for (auto* param : getParameters()) {
 | 
				
			||||||
         if (auto* p = dynamic_cast<AudioProcessorParameterWithID*> (param)) {
 | 
					         if (auto* p = dynamic_cast<AudioProcessorParameterWithID*> (param)) {
 | 
				
			||||||
//             xml.setAttribute(p->paramID, p->getValue());
 | 
					 | 
				
			||||||
//             XmlElement* param{params->createNewChildElement("PARAM")};
 | 
					 | 
				
			||||||
//             param->setAttribute(p->paramID, p->getValue());
 | 
					 | 
				
			||||||
             params->setAttribute(p->paramID, p->getValue());
 | 
					             params->setAttribute(p->paramID, p->getValue());
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        ValueTree tree{valueTreeState.state.getChildWithName("uiState")};
 | 
					        ValueTree tree{valueTreeState.state.getChildWithName("uiState")};
 | 
				
			||||||
        XmlElement* newElement{xml.createNewChildElement("uiState")};
 | 
					        XmlElement* newElement{xml.createNewChildElement("uiState")};
 | 
				
			||||||
//        Value value{tree.getPropertyAsValue("width", nullptr)};
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            double value{tree.getProperty("width", GuiConstants::minWidth)};
 | 
					            double value{tree.getProperty("width", GuiConstants::minWidth)};
 | 
				
			||||||
            newElement->setAttribute("width", value);
 | 
					            newElement->setAttribute("width", value);
 | 
				
			||||||
@ -259,10 +246,6 @@ void JuicySFAudioProcessor::getStateInformation (MemoryBlock& destData)
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    DEBUG_PRINT(xml.createDocument("",false,false));
 | 
					    DEBUG_PRINT(xml.createDocument("",false,false));
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // then use this helper function to stuff it into the binary blob and return it..
 | 
					 | 
				
			||||||
//    if (xml.get() != nullptr) {
 | 
					 | 
				
			||||||
//        copyXmlToBinary(*xml, destData);
 | 
					 | 
				
			||||||
//    }
 | 
					 | 
				
			||||||
    copyXmlToBinary(xml, destData);
 | 
					    copyXmlToBinary(xml, destData);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -272,54 +255,24 @@ void JuicySFAudioProcessor::setStateInformation (const void* data, int sizeInByt
 | 
				
			|||||||
    // whose contents will have been created by the getStateInformation() call.
 | 
					    // whose contents will have been created by the getStateInformation() call.
 | 
				
			||||||
    // This getXmlFromBinary() helper function retrieves our XML from the binary blob..
 | 
					    // This getXmlFromBinary() helper function retrieves our XML from the binary blob..
 | 
				
			||||||
    shared_ptr<XmlElement> xmlState{getXmlFromBinary(data, sizeInBytes)};
 | 
					    shared_ptr<XmlElement> xmlState{getXmlFromBinary(data, sizeInBytes)};
 | 
				
			||||||
//    unique_ptr<XmlElement> xmlState{getXmlFromBinary(data, sizeInBytes)};
 | 
					 | 
				
			||||||
    DEBUG_PRINT(xmlState->createDocument("",false,false));
 | 
					    DEBUG_PRINT(xmlState->createDocument("",false,false));
 | 
				
			||||||
/*
 | 
					    
 | 
				
			||||||
 <MYPLUGINSETTINGS soundFontPath="">
 | 
					 | 
				
			||||||
 <PARAM id="attack" value="0.0"/>
 | 
					 | 
				
			||||||
 <PARAM id="bank" value="0.0"/>
 | 
					 | 
				
			||||||
 <PARAM id="decay" value="0.0"/>
 | 
					 | 
				
			||||||
 <PARAM id="filterCutOff" value="0.0"/>
 | 
					 | 
				
			||||||
 <PARAM id="filterResonance" value="0.0"/>
 | 
					 | 
				
			||||||
 <PARAM id="preset" value="0.0"/>
 | 
					 | 
				
			||||||
 <PARAM id="release" value="0.0"/>
 | 
					 | 
				
			||||||
 <PARAM id="sustain" value="0.0"/>
 | 
					 | 
				
			||||||
 <uiState width="722" height="300"/>
 | 
					 | 
				
			||||||
 </MYPLUGINSETTINGS>
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
    if (xmlState.get() != nullptr) {
 | 
					    if (xmlState.get() != nullptr) {
 | 
				
			||||||
        // make sure that it's actually our type of XML object..
 | 
					        // make sure that it's actually our type of XML object..
 | 
				
			||||||
//        if (xmlState->hasTagName ("MYPLUGINSETTINGS")) {
 | 
					 | 
				
			||||||
        if (xmlState->hasTagName(valueTreeState.state.getType())) {
 | 
					        if (xmlState->hasTagName(valueTreeState.state.getType())) {
 | 
				
			||||||
            // valueTreeState.replaceState(ValueTree::fromXml(*xmlState));
 | 
					 | 
				
			||||||
//            for (auto* param : getParameters())
 | 
					 | 
				
			||||||
//                if (auto* p = dynamic_cast<AudioProcessorParameterWithID*>(param))
 | 
					 | 
				
			||||||
//                    p->setValue(static_cast<float>(xmlState->getDoubleAttribute(p->paramID, p->getValue())));
 | 
					 | 
				
			||||||
            XmlElement* params{xmlState->getChildByName("params")};
 | 
					            XmlElement* params{xmlState->getChildByName("params")};
 | 
				
			||||||
            if (params) {
 | 
					            if (params)
 | 
				
			||||||
                for (auto* param : getParameters())
 | 
					                for (auto* param : getParameters())
 | 
				
			||||||
                    if (auto* p = dynamic_cast<AudioProcessorParameterWithID*>(param))
 | 
					                    if (auto* p = dynamic_cast<AudioProcessorParameterWithID*>(param))
 | 
				
			||||||
    //                    XmlElement* xmlParam{params->getChildByAttribute("id", p->paramID)};
 | 
					 | 
				
			||||||
    //                    p->setValue(static_cast<float>(xmlState->getDoubleAttribute(p->paramID, p->getValue())));
 | 
					 | 
				
			||||||
                        p->setValue(static_cast<float>(params->getDoubleAttribute(p->paramID, p->getValue())));
 | 
					                        p->setValue(static_cast<float>(params->getDoubleAttribute(p->paramID, p->getValue())));
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // Value value{valueTreeState.state.getPropertyAsValue("soundFontPath", nullptr)};
 | 
					 | 
				
			||||||
                // value = xmlState->getStringAttribute("soundFontPath", value.getValue());
 | 
					 | 
				
			||||||
                XmlElement* xmlElement{xmlState->getChildByName("soundFont")};
 | 
					                XmlElement* xmlElement{xmlState->getChildByName("soundFont")};
 | 
				
			||||||
                if (xmlElement) {
 | 
					                if (xmlElement) {
 | 
				
			||||||
                    ValueTree tree{valueTreeState.state.getChildWithName("soundFont")};
 | 
					                    ValueTree tree{valueTreeState.state.getChildWithName("soundFont")};
 | 
				
			||||||
                    Value value{tree.getPropertyAsValue("path", nullptr)};
 | 
					                    Value value{tree.getPropertyAsValue("path", nullptr)};
 | 
				
			||||||
                    value = xmlElement->getStringAttribute("path", value.getValue());
 | 
					                    value = xmlElement->getStringAttribute("path", value.getValue());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					 | 
				
			||||||
                // valueTreeState.getParameter("soundFontPath")->getValue()
 | 
					 | 
				
			||||||
                // valueTreeState.getParameter("soundFontPath")->getValue();
 | 
					 | 
				
			||||||
                // RangedAudioParameter *param {valueTreeState.getParameter("release")};
 | 
					 | 
				
			||||||
                // jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
 | 
					 | 
				
			||||||
                // AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
 | 
					 | 
				
			||||||
                // *castParam = m.getControllerValue();
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                ValueTree tree{valueTreeState.state.getChildWithName("uiState")};
 | 
					                ValueTree tree{valueTreeState.state.getChildWithName("uiState")};
 | 
				
			||||||
@ -334,47 +287,7 @@ void JuicySFAudioProcessor::setStateInformation (const void* data, int sizeInByt
 | 
				
			|||||||
                        value = xmlElement->getIntAttribute("height", value.getValue());
 | 
					                        value = xmlElement->getIntAttribute("height", value.getValue());
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                
 | 
					 | 
				
			||||||
//                tree.getPropertyAsValue("width", nullptr)
 | 
					 | 
				
			||||||
//                tree.
 | 
					 | 
				
			||||||
//                valueTreeState.replaceState(ValueTree::fromXml(*xmlState))
 | 
					 | 
				
			||||||
//                value = xmlState->getStringAttribute("soundFontPath", value.getValue());
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
//            list<StateChangeSubscriber*>::iterator p;
 | 
					 | 
				
			||||||
//            for(p = stateChangeSubscribers.begin(); p != stateChangeSubscribers.end(); p++) {
 | 
					 | 
				
			||||||
//                (*p)->setStateInformation(xmlState);
 | 
					 | 
				
			||||||
//            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // ok, now pull out our last window size..
 | 
					 | 
				
			||||||
//           sharedParams.loadAttributesFromXml(xmlState);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Now reload our parameters..
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
//            for (auto* param : getParameters())
 | 
					 | 
				
			||||||
//                if (auto* p = dynamic_cast<AudioProcessorParameterWithID*> (param))
 | 
					 | 
				
			||||||
//                    p->setValue ((float) xmlState->getDoubleAttribute (p->paramID, p->getValue()));
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//            fluidSynthModel.onFileNameChanged(
 | 
					 | 
				
			||||||
//                sharedParams->getSoundFontPath(),
 | 
					 | 
				
			||||||
//                sharedParams->getBank(),
 | 
					 | 
				
			||||||
//                sharedParams->getPreset());
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//            AudioProcessorEditor* editor{getActiveEditor()};
 | 
					 | 
				
			||||||
//            if (editor != nullptr) {
 | 
					 | 
				
			||||||
//                editor->setSize(
 | 
					 | 
				
			||||||
//                    sharedParams->getUiWidth(),
 | 
					 | 
				
			||||||
//                    sharedParams->getUiHeight());
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//                jassert(dynamic_cast<ExposesComponents*> (editor) != nullptr);
 | 
					 | 
				
			||||||
//                ExposesComponents* exposesComponents = dynamic_cast<ExposesComponents*> (editor);
 | 
					 | 
				
			||||||
//                exposesComponents->getFilePicker().setDisplayedFilePath(sharedParams->getSoundFontPath());
 | 
					 | 
				
			||||||
//            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//            const String& currentSoundFontAbsPath = fluidSynthModel->getCurrentSoundFontAbsPath();
 | 
					 | 
				
			||||||
//            if (currentSoundFontAbsPath.isNotEmpty()) {
 | 
					 | 
				
			||||||
//                fileChooser.setCurrentFile(File(currentSoundFontAbsPath), true, dontSendNotification);
 | 
					 | 
				
			||||||
//            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -21,18 +21,9 @@ using namespace Util;
 | 
				
			|||||||
*/
 | 
					*/
 | 
				
			||||||
TableComponent::TableComponent(
 | 
					TableComponent::TableComponent(
 | 
				
			||||||
    AudioProcessorValueTreeState& valueTreeState
 | 
					    AudioProcessorValueTreeState& valueTreeState
 | 
				
			||||||
    // const vector<string> &columns,
 | 
					 | 
				
			||||||
//    const vector<TableRow> &rows,
 | 
					 | 
				
			||||||
    // const function<void (int)> &onRowSelected,
 | 
					 | 
				
			||||||
    // const function<int (const vector<string>&)> &rowToIDMapper,
 | 
					 | 
				
			||||||
    // int initiallySelectedRow
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
: valueTreeState{valueTreeState}
 | 
					: valueTreeState{valueTreeState}
 | 
				
			||||||
, font{14.0f}
 | 
					, font{14.0f}
 | 
				
			||||||
//, columns{columns}
 | 
					 | 
				
			||||||
//, rows{rows}
 | 
					 | 
				
			||||||
// , onRowSelected{onRowSelected}
 | 
					 | 
				
			||||||
// rowToIDMapper(rowToIDMapper)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // Create our table component and add it to this component..
 | 
					    // Create our table component and add it to this component..
 | 
				
			||||||
    addAndMakeVisible (table);
 | 
					    addAndMakeVisible (table);
 | 
				
			||||||
@ -44,19 +35,6 @@ TableComponent::TableComponent(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    int columnIx = 1;
 | 
					    int columnIx = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Add some columns to the table header, based on the column list in our database..
 | 
					 | 
				
			||||||
    // for (auto &column : columns) // access by reference to avoid copying
 | 
					 | 
				
			||||||
    // {
 | 
					 | 
				
			||||||
    //     const int colWidth{ columnIx == 1 ? 30 : 200 };
 | 
					 | 
				
			||||||
    //     table.getHeader().addColumn (
 | 
					 | 
				
			||||||
    //             String(column),
 | 
					 | 
				
			||||||
    //             columnIx++,
 | 
					 | 
				
			||||||
    //             colWidth, // column width
 | 
					 | 
				
			||||||
    //             30, // min width
 | 
					 | 
				
			||||||
    //             400, // max width
 | 
					 | 
				
			||||||
    //             TableHeaderComponent::defaultFlags
 | 
					 | 
				
			||||||
    //     );
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
    table.getHeader().addColumn (
 | 
					    table.getHeader().addColumn (
 | 
				
			||||||
            String("#"),
 | 
					            String("#"),
 | 
				
			||||||
            columnIx++,
 | 
					            columnIx++,
 | 
				
			||||||
@ -76,20 +54,11 @@ TableComponent::TableComponent(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    table.setWantsKeyboardFocus(false);
 | 
					    table.setWantsKeyboardFocus(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // table.selectRow();
 | 
					 | 
				
			||||||
    // ValueTree presets{valueTreeState.state.getChildWithName("presets")};
 | 
					 | 
				
			||||||
    ValueTree banks{valueTreeState.state.getChildWithName("banks")};
 | 
					    ValueTree banks{valueTreeState.state.getChildWithName("banks")};
 | 
				
			||||||
    loadModelFrom(banks);
 | 
					    loadModelFrom(banks);
 | 
				
			||||||
    // selectCurrentPreset();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // we could now change some initial settings..
 | 
					    // we could now change some initial settings..
 | 
				
			||||||
    table.getHeader().setSortColumnId(1, false); // sort ascending by ID column
 | 
					    table.getHeader().setSortColumnId(1, false); // sort ascending by ID column
 | 
				
			||||||
//    table.getHeader().setColumnVisible (7, false); // hide the "length" column until the user shows it
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // un-comment this line to have a go of stretch-to-fit mode
 | 
					 | 
				
			||||||
    // table.getHeader().setStretchToFitActive (true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//    table.setMultipleSelectionEnabled (false);
 | 
					 | 
				
			||||||
    valueTreeState.state.addListener(this);
 | 
					    valueTreeState.state.addListener(this);
 | 
				
			||||||
    valueTreeState.addParameterListener("bank", this);
 | 
					    valueTreeState.addParameterListener("bank", this);
 | 
				
			||||||
    valueTreeState.addParameterListener("preset", this);
 | 
					    valueTreeState.addParameterListener("preset", this);
 | 
				
			||||||
@ -101,27 +70,10 @@ TableComponent::~TableComponent() {
 | 
				
			|||||||
    valueTreeState.state.removeListener(this);
 | 
					    valueTreeState.state.removeListener(this);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// void TableComponent::loadModelFrom(ValueTree& presets) {
 | 
					 | 
				
			||||||
//     rows.clear();
 | 
					 | 
				
			||||||
//     int numChildren{presets.getNumChildren()};
 | 
					 | 
				
			||||||
//     for(int i{0}; i<numChildren; i++) {
 | 
					 | 
				
			||||||
//         ValueTree child{presets.getChild(i)};
 | 
					 | 
				
			||||||
//         int num{child.getProperty("num")};
 | 
					 | 
				
			||||||
//         String name{child.getProperty("name")};
 | 
					 | 
				
			||||||
//         rows.emplace_back(num, name);
 | 
					 | 
				
			||||||
//     }
 | 
					 | 
				
			||||||
//     table.deselectAllRows();
 | 
					 | 
				
			||||||
//     table.updateContent();
 | 
					 | 
				
			||||||
//     table.getHeader().setSortColumnId(0, true);
 | 
					 | 
				
			||||||
//     selectCurrentPreset();
 | 
					 | 
				
			||||||
//     table.repaint();
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void TableComponent::loadModelFrom(ValueTree& banks) {
 | 
					void TableComponent::loadModelFrom(ValueTree& banks) {
 | 
				
			||||||
    banksToPresets.clear();
 | 
					    banksToPresets.clear();
 | 
				
			||||||
    int banksChildren{banks.getNumChildren()};
 | 
					    int banksChildren{banks.getNumChildren()};
 | 
				
			||||||
    for(int bankIx{0}; bankIx<banksChildren; bankIx++) {
 | 
					    for(int bankIx{0}; bankIx<banksChildren; bankIx++) {
 | 
				
			||||||
        // vector<TableRow> presets;
 | 
					 | 
				
			||||||
        ValueTree bank{banks.getChild(bankIx)};
 | 
					        ValueTree bank{banks.getChild(bankIx)};
 | 
				
			||||||
        int bankNum{bank.getProperty("num")};
 | 
					        int bankNum{bank.getProperty("num")};
 | 
				
			||||||
        int bankChildren{bank.getNumChildren()};
 | 
					        int bankChildren{bank.getNumChildren()};
 | 
				
			||||||
@ -129,9 +81,7 @@ void TableComponent::loadModelFrom(ValueTree& banks) {
 | 
				
			|||||||
            ValueTree preset{bank.getChild(presetIx)};
 | 
					            ValueTree preset{bank.getChild(presetIx)};
 | 
				
			||||||
            int presetNum{preset.getProperty("num")};
 | 
					            int presetNum{preset.getProperty("num")};
 | 
				
			||||||
            String presetName{preset.getProperty("name")};
 | 
					            String presetName{preset.getProperty("name")};
 | 
				
			||||||
            // presets.emplace_back(presetNum, presetName);
 | 
					 | 
				
			||||||
            TableRow row{presetNum, move(presetName)};
 | 
					            TableRow row{presetNum, move(presetName)};
 | 
				
			||||||
            // banksToPresets.insert(BanksToPresets::value_type(bankNum, move(row)));
 | 
					 | 
				
			||||||
            banksToPresets.emplace(bankNum, move(row));
 | 
					            banksToPresets.emplace(bankNum, move(row));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -139,15 +89,10 @@ void TableComponent::loadModelFrom(ValueTree& banks) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TableComponent::parameterChanged(const String& parameterID, float newValue) {
 | 
					void TableComponent::parameterChanged(const String& parameterID, float newValue) {
 | 
				
			||||||
    // valueTreeState.getParameter
 | 
					 | 
				
			||||||
    if (parameterID == "bank") {
 | 
					    if (parameterID == "bank") {
 | 
				
			||||||
        repopulateTable();
 | 
					        repopulateTable();
 | 
				
			||||||
    } else if (parameterID == "preset") {
 | 
					    } else if (parameterID == "preset") {
 | 
				
			||||||
        selectCurrentPreset();
 | 
					        selectCurrentPreset();
 | 
				
			||||||
        // RangedAudioParameter *param {valueTreeState.getParameter("preset")};
 | 
					 | 
				
			||||||
        // jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
 | 
					 | 
				
			||||||
        // AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
 | 
					 | 
				
			||||||
        // int value{castParam->get()};
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -170,7 +115,6 @@ void TableComponent::repopulateTable() {
 | 
				
			|||||||
        upperBound,
 | 
					        upperBound,
 | 
				
			||||||
        back_inserter(rows),
 | 
					        back_inserter(rows),
 | 
				
			||||||
        mem_fn(&BanksToPresets::value_type::second)
 | 
					        mem_fn(&BanksToPresets::value_type::second)
 | 
				
			||||||
        // [](BanksToPresets::value_type element){return element.second;}
 | 
					 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    table.deselectAllRows();
 | 
					    table.deselectAllRows();
 | 
				
			||||||
    table.updateContent();
 | 
					    table.updateContent();
 | 
				
			||||||
@ -182,11 +126,6 @@ void TableComponent::repopulateTable() {
 | 
				
			|||||||
void TableComponent::valueTreePropertyChanged(
 | 
					void TableComponent::valueTreePropertyChanged(
 | 
				
			||||||
    ValueTree& treeWhosePropertyHasChanged,
 | 
					    ValueTree& treeWhosePropertyHasChanged,
 | 
				
			||||||
    const Identifier& property) {
 | 
					    const Identifier& property) {
 | 
				
			||||||
    // if (treeWhosePropertyHasChanged.getType() == StringRef("presets")) {
 | 
					 | 
				
			||||||
    //     if (property == StringRef("synthetic")) {
 | 
					 | 
				
			||||||
    //         loadModelFrom(treeWhosePropertyHasChanged);
 | 
					 | 
				
			||||||
    //     }
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
    if (treeWhosePropertyHasChanged.getType() == StringRef("banks")) {
 | 
					    if (treeWhosePropertyHasChanged.getType() == StringRef("banks")) {
 | 
				
			||||||
        if (property == StringRef("synthetic")) {
 | 
					        if (property == StringRef("synthetic")) {
 | 
				
			||||||
            loadModelFrom(treeWhosePropertyHasChanged);
 | 
					            loadModelFrom(treeWhosePropertyHasChanged);
 | 
				
			||||||
@ -194,52 +133,6 @@ void TableComponent::valueTreePropertyChanged(
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// void TableComponent::valueTreeParentChanged(ValueTree& treeWhoseParentHasChanged) {
 | 
					 | 
				
			||||||
//     if (treeWhoseParentHasChanged.getType() == StringRef("presets")) {
 | 
					 | 
				
			||||||
//         loadModelFrom(treeWhoseParentHasChanged);
 | 
					 | 
				
			||||||
//     }
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// void TableComponent::valueTreePropertyChanged(
 | 
					 | 
				
			||||||
//     ValueTree& treeWhosePropertyHasChanged,
 | 
					 | 
				
			||||||
//     const Identifier& property) {
 | 
					 | 
				
			||||||
//     DEBUG_PRINT(treeWhosePropertyHasChanged.getType().toString());
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
// void TableComponent::valueTreeChildAdded(
 | 
					 | 
				
			||||||
//     ValueTree& parentTree,
 | 
					 | 
				
			||||||
//     ValueTree& childWhichHasBeenAdded) {
 | 
					 | 
				
			||||||
//     DEBUG_PRINT(parentTree.getType().toString());
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
// void TableComponent::valueTreeChildRemoved(
 | 
					 | 
				
			||||||
//     ValueTree& parentTree,
 | 
					 | 
				
			||||||
//     ValueTree& childWhichHasBeenRemoved,
 | 
					 | 
				
			||||||
//     int indexFromWhichChildWasRemoved) {
 | 
					 | 
				
			||||||
//     DEBUG_PRINT(parentTree.getType().toString());
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
// void TableComponent::valueTreeChildOrderChanged(
 | 
					 | 
				
			||||||
//     ValueTree& parentTreeWhoseChildrenHaveMoved,
 | 
					 | 
				
			||||||
//     int oldIndex,
 | 
					 | 
				
			||||||
//     int newIndex) {
 | 
					 | 
				
			||||||
//     DEBUG_PRINT(parentTreeWhoseChildrenHaveMoved.getType().toString());
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
// void TableComponent::valueTreeParentChanged(
 | 
					 | 
				
			||||||
//     ValueTree& treeWhoseParentHasChanged) {
 | 
					 | 
				
			||||||
//     DEBUG_PRINT(treeWhoseParentHasChanged.getType().toString());
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
// void TableComponent::valueTreeRedirected(
 | 
					 | 
				
			||||||
//     ValueTree& treeWhichHasBeenChanged) {
 | 
					 | 
				
			||||||
//     DEBUG_PRINT(treeWhichHasBeenChanged.getType().toString());
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// void TableComponent::setRows(const vector<vector<string>>& rows, int initiallySelectedRow) {
 | 
					 | 
				
			||||||
//     this->rows = rows;
 | 
					 | 
				
			||||||
//     table.deselectAllRows();
 | 
					 | 
				
			||||||
//     table.updateContent();
 | 
					 | 
				
			||||||
//     table.getHeader().setSortColumnId(0, true);
 | 
					 | 
				
			||||||
//     table.selectRow(initiallySelectedRow);
 | 
					 | 
				
			||||||
//     table.repaint();
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// This is overloaded from TableListBoxModel, and must return the total number of rows in our table
 | 
					// This is overloaded from TableListBoxModel, and must return the total number of rows in our table
 | 
				
			||||||
int TableComponent::getNumRows()
 | 
					int TableComponent::getNumRows()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -297,40 +190,24 @@ void TableComponent::sortOrderChanged (
 | 
				
			|||||||
        bool isForwards
 | 
					        bool isForwards
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    if (newSortColumnId != 0) {
 | 
					    if (newSortColumnId != 0) {
 | 
				
			||||||
        // int selectedRowIx = table.getSelectedRow();
 | 
					 | 
				
			||||||
        // TableRow* selectedRow;
 | 
					 | 
				
			||||||
        // if (selectedRowIx >= 0) {
 | 
					 | 
				
			||||||
        //     selectedRow = &rows[selectedRowIx];
 | 
					 | 
				
			||||||
        // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        TableComponent::DataSorter sorter (newSortColumnId, isForwards);
 | 
					        TableComponent::DataSorter sorter (newSortColumnId, isForwards);
 | 
				
			||||||
        sort(rows.begin(), rows.end(), sorter);
 | 
					        sort(rows.begin(), rows.end(), sorter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        table.updateContent();
 | 
					        table.updateContent();
 | 
				
			||||||
        selectCurrentPreset();
 | 
					        selectCurrentPreset();
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // if (selectedRowIx >= 0) {
 | 
					 | 
				
			||||||
        //     for (auto it = rows.begin(); it != rows.end(); ++it) {
 | 
					 | 
				
			||||||
        //         if(it->preset == value) {
 | 
					 | 
				
			||||||
        //             int index {static_cast<int>(std::distance(rows.begin(), it))};
 | 
					 | 
				
			||||||
        //             table.selectRow(index);
 | 
					 | 
				
			||||||
        //             break;
 | 
					 | 
				
			||||||
        //         }
 | 
					 | 
				
			||||||
        //     }
 | 
					 | 
				
			||||||
        // }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TableComponent::selectCurrentPreset() {
 | 
					void TableComponent::selectCurrentPreset() {
 | 
				
			||||||
    table.deselectAllRows();
 | 
					    table.deselectAllRows();
 | 
				
			||||||
    RangedAudioParameter *param {valueTreeState.getParameter("preset")};
 | 
					    RangedAudioParameter *param{valueTreeState.getParameter("preset")};
 | 
				
			||||||
    jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
 | 
					    jassert(dynamic_cast<AudioParameterInt*>(param) != nullptr);
 | 
				
			||||||
    AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
 | 
					    AudioParameterInt* castParam{dynamic_cast<AudioParameterInt*>(param)};
 | 
				
			||||||
    int value{castParam->get()};
 | 
					    int value{castParam->get()};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (auto it = rows.begin(); it != rows.end(); ++it) {
 | 
					    for (auto it{rows.begin()}; it != rows.end(); ++it) {
 | 
				
			||||||
        if(it->preset == value) {
 | 
					        if(it->preset == value) {
 | 
				
			||||||
            int index {static_cast<int>(distance(rows.begin(), it))};
 | 
					            int index{static_cast<int>(distance(rows.begin(), it))};
 | 
				
			||||||
            table.selectRow(index);
 | 
					            table.selectRow(index);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -397,12 +274,10 @@ void TableComponent::selectedRowsChanged (int row) {
 | 
				
			|||||||
    if (row < 0) {
 | 
					    if (row < 0) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // onRowSelected(rowToIDMapper(rows[row]));
 | 
					 | 
				
			||||||
    // onRowSelected(stoi(rows[row][0]));
 | 
					 | 
				
			||||||
    int newPreset{rows[row].preset};
 | 
					    int newPreset{rows[row].preset};
 | 
				
			||||||
    RangedAudioParameter *param {valueTreeState.getParameter("preset")};
 | 
					    RangedAudioParameter *param{valueTreeState.getParameter("preset")};
 | 
				
			||||||
    jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
 | 
					    jassert(dynamic_cast<AudioParameterInt*>(param) != nullptr);
 | 
				
			||||||
    AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
 | 
					    AudioParameterInt* castParam{dynamic_cast<AudioParameterInt*>(param)};
 | 
				
			||||||
    *castParam = newPreset;
 | 
					    *castParam = newPreset;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user