Parts.cpp (6553B)
1 #include "Parts.h" 2 3 #include "PartButton.h" 4 #include "VirusEditor.h" 5 6 #include "VirusController.h" 7 #include "VirusProcessor.h" 8 #include "ParameterNames.h" 9 10 #include "jucePluginEditorLib/pluginProcessor.h" 11 #include "jucePluginEditorLib/patchmanager/savepatchdesc.h" 12 13 #include "jucePluginLib/parameterbinding.h" 14 15 #include "virusLib/device.h" 16 17 namespace genericVirusUI 18 { 19 Parts::Parts(VirusEditor& _editor) : m_editor(_editor) 20 { 21 _editor.findComponents<genericUI::Button<juce::DrawableButton>>(m_partSelect, "SelectPart"); 22 _editor.findComponents<juce::Button>(m_presetPrev, "PresetPrev"); 23 _editor.findComponents<juce::Button>(m_presetNext, "PresetNext"); 24 25 _editor.findComponents<juce::Slider>(m_partVolume, "PartVolume"); 26 _editor.findComponents<juce::Slider>(m_partPan, "PartPan"); 27 _editor.findComponents<PartButton>(m_presetName, "PresetName"); 28 _editor.findComponents<juce::Component>(m_partActive, "PartActive"); 29 30 for(size_t i=0; i<m_partSelect.size(); ++i) 31 { 32 m_partSelect[i]->onClick = [this, i]{ selectPart(i); }; 33 m_partSelect[i]->onDown = [this, i](const juce::MouseEvent& _e) 34 { 35 if(!_e.mods.isPopupMenu()) 36 return false; 37 selectPartMidiChannel(i); 38 return true; 39 }; 40 41 if(i < m_presetPrev.size()) 42 m_presetPrev[i]->onClick = [this, i]{ selectPrevPreset(i); }; 43 44 if(i < m_presetNext.size()) 45 m_presetNext[i]->onClick = [this, i]{ selectNextPreset(i); }; 46 47 m_presetName[i]->initalize(static_cast<uint8_t>(i)); 48 49 const auto partVolume = _editor.getController().getParameterIndexByName(virus::g_paramPartVolume); 50 const auto partPanorama = _editor.getController().getParameterIndexByName(virus::g_paramPartPanorama); 51 52 _editor.getParameterBinding().bind(*m_partVolume[i], partVolume, static_cast<uint8_t>(i)); 53 _editor.getParameterBinding().bind(*m_partPan[i], partPanorama, static_cast<uint8_t>(i)); 54 55 m_partVolume[i]->getProperties().set("parameter", static_cast<int>(partVolume)); 56 m_partPan[i]->getProperties().set("parameter", static_cast<int>(partPanorama)); 57 58 m_partVolume[i]->getProperties().set("part", static_cast<int>(i)); 59 m_partPan[i]->getProperties().set("part", static_cast<int>(i)); 60 } 61 62 updateAll(); 63 64 if(!m_partActive.empty()) 65 { 66 for (const auto & partActive : m_partActive) 67 { 68 partActive->setInterceptsMouseClicks(false, false); 69 partActive->setVisible(false); 70 } 71 72 startTimer(1000/20); 73 } 74 75 m_onFrontpanelStateChanged.set(_editor.getController().onFrontPanelStateChanged, [this](const virusLib::FrontpanelState& _frontpanelState) 76 { 77 for(size_t i=0; i<m_frontpanelState.m_midiEventReceived.size(); ++i) 78 m_frontpanelState.m_midiEventReceived[i] |= _frontpanelState.m_midiEventReceived[i]; 79 }); 80 } 81 82 Parts::~Parts() = default; 83 84 void Parts::onProgramChange() const 85 { 86 updateAll(); 87 } 88 89 void Parts::onPlayModeChanged() const 90 { 91 updateAll(); 92 } 93 94 void Parts::onCurrentPartChanged() const 95 { 96 updateSelectedPart(); 97 } 98 99 void Parts::selectPart(const size_t _part) const 100 { 101 m_editor.setPart(_part); 102 } 103 104 void Parts::selectPartMidiChannel(const size_t _part) const 105 { 106 const auto multiMode = m_editor.getController().isMultiMode(); 107 108 if(!multiMode && _part > 0) 109 return; 110 111 juce::PopupMenu menu; 112 113 const auto idx = m_editor.getController().getParameterIndexByName(multiMode ? "Part Midi Channel" : "Midi Channel"); 114 if(idx == pluginLib::Controller::InvalidParameterIndex) 115 return; 116 117 const auto v = m_editor.getController().getParameter(idx, static_cast<uint8_t>(multiMode ? _part : 0)); 118 119 const std::string name = multiMode ? "Midi Channel " : "Global Midi Channel "; 120 121 for(uint8_t i=0; i<16; ++i) 122 { 123 menu.addItem(name + ' ' + std::to_string(i + 1), true, v->getUnnormalizedValue() == i, [v, i] 124 { 125 v->setUnnormalizedValueNotifyingHost(i, pluginLib::Parameter::Origin::Ui); 126 }); 127 } 128 129 menu.showMenuAsync({}); 130 } 131 132 void Parts::selectPrevPreset(size_t _part) const 133 { 134 if(m_presetPrev.size() == 1) 135 _part = m_editor.getController().getCurrentPart(); 136 137 auto* pm = m_editor.getPatchManager(); 138 if(pm && pm->selectPrevPreset(static_cast<uint32_t>(_part))) 139 return; 140 m_editor.getController().selectPrevPreset(static_cast<uint8_t>(_part)); 141 } 142 143 void Parts::selectNextPreset(size_t _part) const 144 { 145 if(m_presetNext.size() == 1) 146 _part = m_editor.getController().getCurrentPart(); 147 148 auto* pm = m_editor.getPatchManager(); 149 if(pm && pm->selectNextPreset(static_cast<uint32_t>(_part))) 150 return; 151 m_editor.getController().selectNextPreset(static_cast<uint8_t>(_part)); 152 } 153 154 void Parts::updatePresetNames() const 155 { 156 for(size_t i=0; i<m_presetName.size(); ++i) 157 m_presetName[i]->setButtonText(m_editor.getController().getCurrentPartPresetName(static_cast<uint8_t>(i))); 158 } 159 160 void Parts::updateSelectedPart() const 161 { 162 const auto part = m_editor.getController().getCurrentPart(); 163 164 if(part < m_partSelect.size()) 165 m_partSelect[part]->setToggleState(true, juce::dontSendNotification); 166 167 for(size_t i=0; i<m_partSelect.size(); ++i) 168 { 169 if(i == part) 170 continue; 171 m_partSelect[i]->setToggleState(false, juce::dontSendNotification); 172 } 173 } 174 175 void Parts::updateSingleOrMultiMode() const 176 { 177 const auto multiMode = m_editor.getController().isMultiMode(); 178 179 const auto partCount = multiMode ? static_cast<virus::VirusProcessor&>(m_editor.getProcessor()).getPartCount() : 1; 180 181 for(size_t i=0; i<m_partSelect.size(); ++i) 182 { 183 const bool visible = i < partCount; 184 185 VirusEditor::setEnabled(*m_partSelect[i], visible); 186 VirusEditor::setEnabled(*m_partPan[i], visible); 187 VirusEditor::setEnabled(*m_partVolume[i], visible); 188 189 if(i < m_presetPrev.size()) 190 VirusEditor::setEnabled(*m_presetPrev[i], visible); 191 192 if(i < m_presetNext.size()) 193 VirusEditor::setEnabled(*m_presetNext[i], visible); 194 195 m_presetName[i]->setVisible(visible); 196 } 197 198 const auto volumeParam = m_editor.getController().getParameterIndexByName(multiMode ? virus::g_paramPartVolume : virus::g_paramPatchVolume); 199 m_editor.getParameterBinding().bind(*m_partVolume[0], volumeParam, 0); 200 m_partVolume[0]->getProperties().set("parameter", static_cast<int>(volumeParam)); 201 } 202 203 void Parts::timerCallback() 204 { 205 auto& fpState = m_frontpanelState; 206 207 const uint32_t maxPart = m_editor.getController().isMultiMode() ? 16 : 1; 208 209 for(uint32_t i=0; i<m_partActive.size(); ++i) 210 { 211 m_partActive[i]->setVisible(i < maxPart && fpState.m_midiEventReceived[i]); 212 fpState.m_midiEventReceived[i] = false; 213 } 214 } 215 216 void Parts::updateAll() const 217 { 218 updatePresetNames(); 219 updateSelectedPart(); 220 updateSingleOrMultiMode(); 221 } 222 }