| @@ -1732,26 +1732,20 @@ void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t | |||||
| plugin->process(inBuf, outBuf, frames); | plugin->process(inBuf, outBuf, frames); | ||||
| plugin->unlock(); | plugin->unlock(); | ||||
| #if 0 | |||||
| // if plugin has no audio inputs, add previous buffers | // if plugin has no audio inputs, add previous buffers | ||||
| if (plugin->audioInCount() == 0) | |||||
| if (plugin->getAudioInCount() == 0) | |||||
| { | { | ||||
| for (uint32_t j=0; j < frames; ++j) | |||||
| { | |||||
| outBuf[0][j] += inBuf[0][j]; | |||||
| outBuf[1][j] += inBuf[1][j]; | |||||
| } | |||||
| carla_addFloat(outBuf[0], inBuf[0], frames); | |||||
| carla_addFloat(outBuf[1], inBuf[1], frames); | |||||
| } | } | ||||
| // if plugin has no midi output, add previous events | // if plugin has no midi output, add previous events | ||||
| if (plugin->midiOutCount() == 0) | |||||
| if (plugin->getMidiOutCount() == 0) | |||||
| { | { | ||||
| for (uint32_t j=0, k=0; j < frames; ++j) | |||||
| { | |||||
| } | |||||
| std::memcpy(pData->rack.out, pData->rack.in, sizeof(EngineEvent)*RACK_EVENT_COUNT); | |||||
| //for (uint32_t j=0, k=0; j < frames; ++j) | |||||
| //{ | |||||
| //} | |||||
| std::memcpy(pData->bufEvents.out, pData->bufEvents.in, sizeof(EngineEvent)*kEngineMaxInternalEventCount); | |||||
| } | } | ||||
| #endif | |||||
| // set peaks | // set peaks | ||||
| { | { | ||||
| @@ -1183,6 +1183,8 @@ protected: | |||||
| processPlugin(plugin, nframes); | processPlugin(plugin, nframes); | ||||
| plugin->unlock(); | plugin->unlock(); | ||||
| } | } | ||||
| return runPendingRtEvents(); | |||||
| #else | #else | ||||
| if (fOptions.processMode == PROCESS_MODE_SINGLE_CLIENT) | if (fOptions.processMode == PROCESS_MODE_SINGLE_CLIENT) | ||||
| { | { | ||||
| @@ -1197,8 +1199,11 @@ protected: | |||||
| plugin->unlock(); | plugin->unlock(); | ||||
| } | } | ||||
| } | } | ||||
| return runPendingRtEvents(); | |||||
| } | } | ||||
| else if (fOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK) | |||||
| if (fOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK) | |||||
| { | { | ||||
| // get buffers from jack | // get buffers from jack | ||||
| float* const audioIn1 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioIn1], nframes); | float* const audioIn1 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioIn1], nframes); | ||||
| @@ -1242,7 +1247,7 @@ protected: | |||||
| engineEvent->time = jackEvent.time; | engineEvent->time = jackEvent.time; | ||||
| engineEvent->channel = midiChannel; | engineEvent->channel = midiChannel; | ||||
| if (MIDI_IS_STATUS_CONTROL_CHANGE(midiStatus)) | |||||
| if (midiStatus == MIDI_STATUS_CONTROL_CHANGE) | |||||
| { | { | ||||
| CARLA_ASSERT(jackEvent.size == 2 || jackEvent.size == 3); | CARLA_ASSERT(jackEvent.size == 2 || jackEvent.size == 3); | ||||
| @@ -1280,7 +1285,7 @@ protected: | |||||
| engineEvent->ctrl.value = float(midiValue)/127.0f; | engineEvent->ctrl.value = float(midiValue)/127.0f; | ||||
| } | } | ||||
| } | } | ||||
| else if (MIDI_IS_STATUS_PROGRAM_CHANGE(midiStatus)) | |||||
| else if (midiStatus == MIDI_STATUS_PROGRAM_CHANGE) | |||||
| { | { | ||||
| CARLA_ASSERT(jackEvent.size == 2); | CARLA_ASSERT(jackEvent.size == 2); | ||||
| @@ -1389,6 +1394,8 @@ protected: | |||||
| jackbridge_midi_event_write(eventOut, engineEvent->time, data, size); | jackbridge_midi_event_write(eventOut, engineEvent->time, data, size); | ||||
| } | } | ||||
| } | } | ||||
| return runPendingRtEvents(); | |||||
| } | } | ||||
| #endif // ! BUILD_BRIDGE | #endif // ! BUILD_BRIDGE | ||||
| @@ -17,7 +17,7 @@ | |||||
| #include "CarlaNative.hpp" | #include "CarlaNative.hpp" | ||||
| #include "juce_core.h" | |||||
| #include "juce_gui_basics.h" | |||||
| using namespace juce; | using namespace juce; | ||||
| @@ -31,4 +31,6 @@ using namespace juce; | |||||
| #include "vex/VexVoice.cpp" | #include "vex/VexVoice.cpp" | ||||
| #include "vex/VexWaveRenderer.cpp" | #include "vex/VexWaveRenderer.cpp" | ||||
| #include "vex/lookandfeel/MyLookAndFeel.cpp" | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -28,6 +28,10 @@ using namespace juce; | |||||
| #include "vex/VexSyntModule.h" | #include "vex/VexSyntModule.h" | ||||
| #include "vex/PeggyViewComponent.h" | #include "vex/PeggyViewComponent.h" | ||||
| #include "vex/lookandfeel/MyLookAndFeel.h" | |||||
| #include "vex/resources/Resources.h" | |||||
| #include "vex/resources/Resources.cpp" | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -35,22 +39,27 @@ class HelperWindow : public DocumentWindow | |||||
| { | { | ||||
| public: | public: | ||||
| HelperWindow() | HelperWindow() | ||||
| : DocumentWindow("PlugWindow", Colour(0, 0, 0), DocumentWindow::closeButton, false), | |||||
| : DocumentWindow("PlugWindow", Colour(50, 50, 200), DocumentWindow::closeButton, false), | |||||
| fClosed(false) | fClosed(false) | ||||
| { | { | ||||
| setVisible(false); | |||||
| setAlwaysOnTop(true); | |||||
| setDropShadowEnabled(false); | setDropShadowEnabled(false); | ||||
| setOpaque(true); | setOpaque(true); | ||||
| setResizable(false, false); | |||||
| //setUsingNativeTitleBar(true); | |||||
| setVisible(false); | |||||
| //setResizable(false, false); | |||||
| //setUsingNativeTitleBar(false); | |||||
| } | } | ||||
| void show(Component* const comp) | void show(Component* const comp) | ||||
| { | { | ||||
| fClosed = false; | fClosed = false; | ||||
| setContentNonOwned(comp, true); | |||||
| centreWithSize(comp->getWidth(), comp->getHeight()); | |||||
| const int width = comp->getWidth(); | |||||
| const int height = comp->getHeight()+getTitleBarHeight(); | |||||
| centreWithSize(width, height); | |||||
| setContentNonOwned(comp, false); | |||||
| setSize(width, height); | |||||
| if (! isOnDesktop()) | if (! isOnDesktop()) | ||||
| addToDesktop(); | addToDesktop(); | ||||
| @@ -81,6 +90,141 @@ protected: | |||||
| private: | private: | ||||
| bool fClosed; | bool fClosed; | ||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(HelperWindow) | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| class VexEditorComponent : public ComboBox::Listener, | |||||
| public Slider::Listener, | |||||
| public Button::Listener, | |||||
| public ChangeListener, | |||||
| public Component, | |||||
| public PeggyViewComponent::Callback | |||||
| { | |||||
| public: | |||||
| VexEditorComponent() | |||||
| { | |||||
| internalCachedImage1 = ImageCache::getFromMemory(Resources::vex3_png, Resources::vex3_pngSize); | |||||
| // Comboboxes, wave selection | |||||
| addAndMakeVisible(comboBox1 = new ComboBox (String::empty)); | |||||
| comboBox1->setEditableText(false); | |||||
| comboBox1->setJustificationType(Justification::centredLeft); | |||||
| comboBox1->setTextWhenNothingSelected(String("silent")); | |||||
| comboBox1->setTextWhenNoChoicesAvailable(String("silent")); | |||||
| comboBox1->addListener(this); | |||||
| comboBox1->setColour(ComboBox::backgroundColourId, Colours::black); | |||||
| comboBox1->setColour(ComboBox::textColourId, Colours::lightgrey); | |||||
| comboBox1->setColour(ComboBox::outlineColourId, Colours::grey); | |||||
| comboBox1->setColour(ComboBox::buttonColourId, Colours::grey); | |||||
| comboBox1->setWantsKeyboardFocus(false); | |||||
| comboBox1->setLookAndFeel(&mlaf); | |||||
| addAndMakeVisible (comboBox2 = new ComboBox (String::empty)); | |||||
| comboBox2->setEditableText (false); | |||||
| comboBox2->setJustificationType (Justification::centredLeft); | |||||
| comboBox2->setTextWhenNothingSelected (String("silent")); | |||||
| comboBox2->setTextWhenNoChoicesAvailable (String("silent")); | |||||
| comboBox2->addListener (this); | |||||
| comboBox2->setColour(ComboBox::backgroundColourId, Colours::black); | |||||
| comboBox2->setColour(ComboBox::textColourId, Colours::lightgrey); | |||||
| comboBox2->setColour(ComboBox::outlineColourId, Colours::grey); | |||||
| comboBox2->setColour(ComboBox::buttonColourId, Colours::grey); | |||||
| comboBox2->setWantsKeyboardFocus(false); | |||||
| comboBox2->setLookAndFeel(&mlaf); | |||||
| addAndMakeVisible (comboBox3 = new ComboBox (String::empty)); | |||||
| comboBox3->setEditableText (false); | |||||
| comboBox3->setJustificationType (Justification::centredLeft); | |||||
| comboBox3->setTextWhenNothingSelected (String("silent")); | |||||
| comboBox3->setTextWhenNoChoicesAvailable (String("silent")); | |||||
| comboBox3->addListener (this); | |||||
| comboBox3->setColour(ComboBox::backgroundColourId, Colours::black); | |||||
| comboBox3->setColour(ComboBox::textColourId, Colours::lightgrey); | |||||
| comboBox3->setColour(ComboBox::outlineColourId, Colours::grey); | |||||
| comboBox3->setColour(ComboBox::buttonColourId, Colours::grey); | |||||
| comboBox3->setWantsKeyboardFocus(false); | |||||
| comboBox3->setLookAndFeel(&mlaf); | |||||
| for (int i = 0, tableSize = WaveRenderer::getWaveTableSize(); i < tableSize; ++i) | |||||
| { | |||||
| String tableName(WaveRenderer::getWaveTableName(i)); | |||||
| comboBox1->addItem(tableName, i + 1); | |||||
| comboBox2->addItem(tableName, i + 1); | |||||
| comboBox3->addItem(tableName, i + 1); | |||||
| } | |||||
| addChildComponent(p1 = new PeggyViewComponent(1, _d, this)); | |||||
| p1->setLookAndFeel(&mlaf); | |||||
| addChildComponent(p2 = new PeggyViewComponent(2, _d, this)); | |||||
| p2->setLookAndFeel(&mlaf); | |||||
| addChildComponent(p3 = new PeggyViewComponent(3, _d, this)); | |||||
| p3->setLookAndFeel(&mlaf); | |||||
| //ownerFilter->addChangeListener (this); | |||||
| setSize(800,500); | |||||
| } | |||||
| ~VexEditorComponent() | |||||
| { | |||||
| removeAllChildren(); | |||||
| } | |||||
| protected: | |||||
| void paint(Graphics& g) override | |||||
| { | |||||
| g.drawImage(internalCachedImage1, | |||||
| 0, 0, 800, 500, | |||||
| 0, 0, internalCachedImage1.getWidth(), internalCachedImage1.getHeight()); | |||||
| } | |||||
| void resized() override | |||||
| { | |||||
| comboBox1->setBounds(13, 38, 173, 23); | |||||
| comboBox2->setBounds(213, 38, 173, 23); | |||||
| comboBox3->setBounds(413, 38, 173, 23); | |||||
| p1->setBounds(10, 20, 207, 280); | |||||
| p2->setBounds(210, 20, 207, 280); | |||||
| p3->setBounds(410, 20, 207, 280); | |||||
| } | |||||
| void changeListenerCallback(ChangeBroadcaster* source) override | |||||
| { | |||||
| } | |||||
| void comboBoxChanged(ComboBox* comboBoxThatHasChanged) override | |||||
| { | |||||
| } | |||||
| void sliderValueChanged(Slider* sliderThatWasMoved) override | |||||
| { | |||||
| } | |||||
| void buttonClicked(Button* buttonThatWasClicked) override | |||||
| { | |||||
| } | |||||
| void somethingChanged(const uint32_t id) override | |||||
| { | |||||
| } | |||||
| private: | |||||
| Image internalCachedImage1; | |||||
| MyLookAndFeel mlaf; | |||||
| ScopedPointer<ComboBox> comboBox1; | |||||
| ScopedPointer<ComboBox> comboBox2; | |||||
| ScopedPointer<ComboBox> comboBox3; | |||||
| ScopedPointer<PeggyViewComponent> p1; | |||||
| ScopedPointer<PeggyViewComponent> p2; | |||||
| ScopedPointer<PeggyViewComponent> p3; | |||||
| VexArpSettings _d; | |||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -96,7 +240,8 @@ public: | |||||
| kParamSyncMode, | kParamSyncMode, | ||||
| kParamFailMode, | kParamFailMode, | ||||
| kParamVelMode, | kParamVelMode, | ||||
| kParamCount | |||||
| kParamLast, | |||||
| kParamCount = kParamLast + VexArpSettings::kVelocitiesSize + VexArpSettings::kGridSize | |||||
| }; | }; | ||||
| VexArpPlugin(const HostDescriptor* const host) | VexArpPlugin(const HostDescriptor* const host) | ||||
| @@ -120,118 +265,155 @@ protected: | |||||
| { | { | ||||
| static Parameter paramInfo; | static Parameter paramInfo; | ||||
| static ParameterScalePoint scalePoints[4]; | static ParameterScalePoint scalePoints[4]; | ||||
| static char bufName[24+1]; | |||||
| int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE|PARAMETER_IS_INTEGER; | |||||
| int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE; | |||||
| paramInfo.name = nullptr; | paramInfo.name = nullptr; | ||||
| paramInfo.unit = nullptr; | paramInfo.unit = nullptr; | ||||
| paramInfo.ranges.def = 0.0f; | paramInfo.ranges.def = 0.0f; | ||||
| paramInfo.ranges.min = 0.0f; | paramInfo.ranges.min = 0.0f; | ||||
| paramInfo.ranges.max = 1.0f; | paramInfo.ranges.max = 1.0f; | ||||
| paramInfo.ranges.step = 1.0f; | |||||
| paramInfo.ranges.stepSmall = 1.0f; | |||||
| paramInfo.ranges.stepLarge = 1.0f; | |||||
| paramInfo.ranges.step = PARAMETER_RANGES_DEFAULT_STEP; | |||||
| paramInfo.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL; | |||||
| paramInfo.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE; | |||||
| paramInfo.scalePointCount = 0; | paramInfo.scalePointCount = 0; | ||||
| paramInfo.scalePoints = nullptr; | paramInfo.scalePoints = nullptr; | ||||
| switch (index) | |||||
| if (index < kParamLast) | |||||
| { | { | ||||
| case kParamOnOff: | |||||
| hints |= PARAMETER_IS_BOOLEAN; | |||||
| paramInfo.name = "On/Off"; | |||||
| paramInfo.ranges.def = 0.0f; | |||||
| paramInfo.ranges.min = 0.0f; | |||||
| paramInfo.ranges.max = 1.0f; | |||||
| break; | |||||
| case kParamLength: | |||||
| paramInfo.name = "Length"; | |||||
| paramInfo.ranges.def = 8.0f; | |||||
| paramInfo.ranges.min = 1.0f; | |||||
| paramInfo.ranges.max = 16.0f; | |||||
| break; | |||||
| case kParamTimeMode: | |||||
| hints |= PARAMETER_USES_SCALEPOINTS; | |||||
| paramInfo.name = "Time Signature"; | |||||
| paramInfo.ranges.def = 2.0f; | |||||
| paramInfo.ranges.min = 1.0f; | |||||
| paramInfo.ranges.max = 3.0f; | |||||
| paramInfo.scalePointCount = 3; | |||||
| paramInfo.scalePoints = scalePoints; | |||||
| scalePoints[0].label = "8"; | |||||
| scalePoints[1].label = "16"; | |||||
| scalePoints[2].label = "32"; | |||||
| scalePoints[0].value = 1.0f; | |||||
| scalePoints[1].value = 2.0f; | |||||
| scalePoints[2].value = 3.0f; | |||||
| break; | |||||
| case kParamSyncMode: | |||||
| hints |= PARAMETER_USES_SCALEPOINTS; | |||||
| paramInfo.name = "Sync Mode"; | |||||
| paramInfo.ranges.def = 1.0f; | |||||
| paramInfo.ranges.min = 1.0f; | |||||
| paramInfo.ranges.max = 2.0f; | |||||
| paramInfo.scalePointCount = 2; | |||||
| paramInfo.scalePoints = scalePoints; | |||||
| scalePoints[0].label = "Key Sync"; | |||||
| scalePoints[1].label = "Bar Sync"; | |||||
| scalePoints[0].value = 1.0f; | |||||
| scalePoints[1].value = 2.0f; | |||||
| break; | |||||
| case kParamFailMode: | |||||
| hints |= PARAMETER_USES_SCALEPOINTS; | |||||
| paramInfo.name = "Fail Mode"; | |||||
| paramInfo.ranges.def = 1.0f; | |||||
| paramInfo.ranges.min = 1.0f; | |||||
| paramInfo.ranges.max = 3.0f; | |||||
| paramInfo.scalePointCount = 3; | |||||
| paramInfo.scalePoints = scalePoints; | |||||
| scalePoints[0].label = "Silent Step"; | |||||
| scalePoints[1].label = "Skip One"; | |||||
| scalePoints[2].label = "Skip Two"; | |||||
| scalePoints[0].value = 1.0f; | |||||
| scalePoints[1].value = 2.0f; | |||||
| scalePoints[2].value = 3.0f; | |||||
| break; | |||||
| case kParamVelMode: | |||||
| hints |= PARAMETER_USES_SCALEPOINTS; | |||||
| paramInfo.name = "Velocity Mode"; | |||||
| paramInfo.ranges.def = 1.0f; | |||||
| paramInfo.ranges.min = 1.0f; | |||||
| paramInfo.ranges.max = 3.0f; | |||||
| paramInfo.scalePointCount = 3; | |||||
| paramInfo.scalePoints = scalePoints; | |||||
| scalePoints[0].label = "Pattern Velocity"; | |||||
| scalePoints[1].label = "Input Velocity"; | |||||
| scalePoints[2].label = "Sum Velocities"; | |||||
| scalePoints[0].value = 1.0f; | |||||
| scalePoints[1].value = 2.0f; | |||||
| scalePoints[2].value = 3.0f; | |||||
| break; | |||||
| hints |= PARAMETER_IS_INTEGER; | |||||
| paramInfo.ranges.step = 1.0f; | |||||
| paramInfo.ranges.stepSmall = 1.0f; | |||||
| paramInfo.ranges.stepLarge = 1.0f; | |||||
| switch (index) | |||||
| { | |||||
| case kParamOnOff: | |||||
| hints |= PARAMETER_IS_BOOLEAN; | |||||
| paramInfo.name = "On/Off"; | |||||
| paramInfo.ranges.def = 0.0f; | |||||
| paramInfo.ranges.min = 0.0f; | |||||
| paramInfo.ranges.max = 1.0f; | |||||
| break; | |||||
| case kParamLength: | |||||
| paramInfo.name = "Length"; | |||||
| paramInfo.ranges.def = 8.0f; | |||||
| paramInfo.ranges.min = 1.0f; | |||||
| paramInfo.ranges.max = 16.0f; | |||||
| break; | |||||
| case kParamTimeMode: | |||||
| hints |= PARAMETER_USES_SCALEPOINTS; | |||||
| paramInfo.name = "Time Signature"; | |||||
| paramInfo.ranges.def = 2.0f; | |||||
| paramInfo.ranges.min = 1.0f; | |||||
| paramInfo.ranges.max = 3.0f; | |||||
| paramInfo.scalePointCount = 3; | |||||
| paramInfo.scalePoints = scalePoints; | |||||
| scalePoints[0].label = "1/8"; | |||||
| scalePoints[1].label = "1/16"; | |||||
| scalePoints[2].label = "1/32"; | |||||
| scalePoints[0].value = 1.0f; | |||||
| scalePoints[1].value = 2.0f; | |||||
| scalePoints[2].value = 3.0f; | |||||
| break; | |||||
| case kParamSyncMode: | |||||
| hints |= PARAMETER_USES_SCALEPOINTS; | |||||
| paramInfo.name = "Sync Mode"; | |||||
| paramInfo.ranges.def = 1.0f; | |||||
| paramInfo.ranges.min = 1.0f; | |||||
| paramInfo.ranges.max = 2.0f; | |||||
| paramInfo.scalePointCount = 2; | |||||
| paramInfo.scalePoints = scalePoints; | |||||
| scalePoints[0].label = "Key Sync"; | |||||
| scalePoints[1].label = "Bar Sync"; | |||||
| scalePoints[0].value = 1.0f; | |||||
| scalePoints[1].value = 2.0f; | |||||
| break; | |||||
| case kParamFailMode: | |||||
| hints |= PARAMETER_USES_SCALEPOINTS; | |||||
| paramInfo.name = "Fail Mode"; | |||||
| paramInfo.ranges.def = 1.0f; | |||||
| paramInfo.ranges.min = 1.0f; | |||||
| paramInfo.ranges.max = 3.0f; | |||||
| paramInfo.scalePointCount = 3; | |||||
| paramInfo.scalePoints = scalePoints; | |||||
| scalePoints[0].label = "Silent Step"; | |||||
| scalePoints[1].label = "Skip One"; | |||||
| scalePoints[2].label = "Skip Two"; | |||||
| scalePoints[0].value = 1.0f; | |||||
| scalePoints[1].value = 2.0f; | |||||
| scalePoints[2].value = 3.0f; | |||||
| break; | |||||
| case kParamVelMode: | |||||
| hints |= PARAMETER_USES_SCALEPOINTS; | |||||
| paramInfo.name = "Velocity Mode"; | |||||
| paramInfo.ranges.def = 1.0f; | |||||
| paramInfo.ranges.min = 1.0f; | |||||
| paramInfo.ranges.max = 3.0f; | |||||
| paramInfo.scalePointCount = 3; | |||||
| paramInfo.scalePoints = scalePoints; | |||||
| scalePoints[0].label = "Pattern Velocity"; | |||||
| scalePoints[1].label = "Input Velocity"; | |||||
| scalePoints[2].label = "Sum Velocities"; | |||||
| scalePoints[0].value = 1.0f; | |||||
| scalePoints[1].value = 2.0f; | |||||
| scalePoints[2].value = 3.0f; | |||||
| break; | |||||
| } | |||||
| } | |||||
| else if (index < kParamLast + VexArpSettings::kVelocitiesSize) | |||||
| { | |||||
| carla_zeroChar(bufName, 24+1); | |||||
| std::snprintf(bufName, 24, "Grid Velocity %i", index - kParamLast); | |||||
| paramInfo.name = bufName; | |||||
| } | |||||
| else | |||||
| { | |||||
| carla_zeroChar(bufName, 24+1); | |||||
| hints |= PARAMETER_IS_BOOLEAN|PARAMETER_IS_INTEGER; | |||||
| paramInfo.ranges.step = 1.0f; | |||||
| paramInfo.ranges.stepSmall = 1.0f; | |||||
| paramInfo.ranges.stepLarge = 1.0f; | |||||
| carla_zeroChar(bufName, 24+1); | |||||
| std::snprintf(bufName, 24, "Grid on/off %i", index - (kParamLast + VexArpSettings::kVelocitiesSize)); | |||||
| paramInfo.name = bufName; | |||||
| } | } | ||||
| paramInfo.hints = static_cast<ParameterHints>(hints); | paramInfo.hints = static_cast<ParameterHints>(hints); | ||||
| return ¶mInfo; | return ¶mInfo; | ||||
| } | } | ||||
| float getParameterValue(const uint32_t index) const override | float getParameterValue(const uint32_t index) const override | ||||
| { | { | ||||
| switch (index) | |||||
| if (index < kParamLast) | |||||
| { | { | ||||
| case kParamOnOff: | |||||
| return fSettings.on ? 1.0f : 0.0f; | |||||
| case kParamLength: | |||||
| return fSettings.length; | |||||
| case kParamTimeMode: | |||||
| return fSettings.timeMode; | |||||
| case kParamSyncMode: | |||||
| return fSettings.syncMode; | |||||
| case kParamFailMode: | |||||
| return fSettings.failMode; | |||||
| case kParamVelMode: | |||||
| return fSettings.velMode; | |||||
| default: | |||||
| return 0.0f; | |||||
| switch (index) | |||||
| { | |||||
| case kParamOnOff: | |||||
| return fSettings.on ? 1.0f : 0.0f; | |||||
| case kParamLength: | |||||
| return fSettings.length; | |||||
| case kParamTimeMode: | |||||
| return fSettings.timeMode; | |||||
| case kParamSyncMode: | |||||
| return fSettings.syncMode; | |||||
| case kParamFailMode: | |||||
| return fSettings.failMode; | |||||
| case kParamVelMode: | |||||
| return fSettings.velMode; | |||||
| default: | |||||
| return 0.0f; | |||||
| } | |||||
| } | |||||
| else if (index < kParamLast + VexArpSettings::kVelocitiesSize) | |||||
| { | |||||
| return fSettings.velocities[index-kParamLast]; | |||||
| } | |||||
| else | |||||
| { | |||||
| return fSettings.grid[index-(kParamLast+VexArpSettings::kVelocitiesSize)] ? 1.0f : 0.0f; | |||||
| } | } | ||||
| } | } | ||||
| @@ -240,26 +422,37 @@ protected: | |||||
| void setParameterValue(const uint32_t index, const float value) override | void setParameterValue(const uint32_t index, const float value) override | ||||
| { | { | ||||
| switch (index) | |||||
| if (index < kParamLast) | |||||
| { | { | ||||
| case kParamOnOff: | |||||
| fSettings.on = (value >= 0.5f); | |||||
| break; | |||||
| case kParamLength: | |||||
| fSettings.length = value; | |||||
| break; | |||||
| case kParamTimeMode: | |||||
| fSettings.timeMode = value; | |||||
| break; | |||||
| case kParamSyncMode: | |||||
| fSettings.syncMode = value; | |||||
| break; | |||||
| case kParamFailMode: | |||||
| fSettings.failMode = value; | |||||
| break; | |||||
| case kParamVelMode: | |||||
| fSettings.velMode = value; | |||||
| break; | |||||
| switch (index) | |||||
| { | |||||
| case kParamOnOff: | |||||
| fSettings.on = (value >= 0.5f); | |||||
| break; | |||||
| case kParamLength: | |||||
| fSettings.length = value; | |||||
| break; | |||||
| case kParamTimeMode: | |||||
| fSettings.timeMode = value; | |||||
| break; | |||||
| case kParamSyncMode: | |||||
| fSettings.syncMode = value; | |||||
| break; | |||||
| case kParamFailMode: | |||||
| fSettings.failMode = value; | |||||
| break; | |||||
| case kParamVelMode: | |||||
| fSettings.velMode = value; | |||||
| break; | |||||
| } | |||||
| } | |||||
| else if (index < kParamLast + VexArpSettings::kVelocitiesSize) | |||||
| { | |||||
| fSettings.velocities[index-kParamLast] = value; | |||||
| } | |||||
| else | |||||
| { | |||||
| fSettings.grid[index-(kParamLast+VexArpSettings::kVelocitiesSize)] = (value >= 0.5f); | |||||
| } | } | ||||
| } | } | ||||
| @@ -345,7 +538,7 @@ protected: | |||||
| if (fView == nullptr) | if (fView == nullptr) | ||||
| { | { | ||||
| fView = new PeggyViewComponent(1, fSettings, this); | fView = new PeggyViewComponent(1, fSettings, this); | ||||
| fView->setSize(207, 280); | |||||
| fView->setSize(207, 320); | |||||
| } | } | ||||
| fWindow->show(fView); | fWindow->show(fView); | ||||
| @@ -1176,6 +1369,53 @@ protected: | |||||
| output.addFrom(1, 0, *obf, 1, 0, frames, fParameters[0]); | output.addFrom(1, 0, *obf, 1, 0, frames, fParameters[0]); | ||||
| } | } | ||||
| // ------------------------------------------------------------------- | |||||
| // Plugin UI calls | |||||
| void uiShow(const bool show) override | |||||
| { | |||||
| if (show) | |||||
| { | |||||
| if (fWindow == nullptr) | |||||
| { | |||||
| fWindow = new HelperWindow(); | |||||
| fWindow->setName(getUiName()); | |||||
| } | |||||
| if (fView == nullptr) | |||||
| fView = new VexEditorComponent(); | |||||
| fWindow->show(fView); | |||||
| } | |||||
| else if (fWindow != nullptr) | |||||
| { | |||||
| fWindow->hide(); | |||||
| fView = nullptr; | |||||
| fWindow = nullptr; | |||||
| } | |||||
| } | |||||
| void uiIdle() override | |||||
| { | |||||
| if (fWindow == nullptr) | |||||
| return; | |||||
| if (fWindow->wasClosedByUser()) | |||||
| { | |||||
| uiShow(false); | |||||
| uiClosed(); | |||||
| } | |||||
| } | |||||
| void uiSetParameterValue(const uint32_t, const float) override | |||||
| { | |||||
| if (fView == nullptr) | |||||
| return; | |||||
| //fView->update(); | |||||
| } | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Plugin dispatcher calls | // Plugin dispatcher calls | ||||
| @@ -1201,6 +1441,14 @@ protected: | |||||
| fSynth.setSampleRate(sampleRate); | fSynth.setSampleRate(sampleRate); | ||||
| } | } | ||||
| void uiNameChanged(const char* const uiName) override | |||||
| { | |||||
| if (fWindow == nullptr) | |||||
| return; | |||||
| fWindow->setName(uiName); | |||||
| } | |||||
| private: | private: | ||||
| float fParameters[92]; | float fParameters[92]; | ||||
| @@ -1215,6 +1463,9 @@ private: | |||||
| VexReverb fReverb; | VexReverb fReverb; | ||||
| VexSyntModule fSynth; | VexSyntModule fSynth; | ||||
| ScopedPointer<VexEditorComponent> fView; | |||||
| ScopedPointer<HelperWindow> fWindow; | |||||
| PluginClassEND(VexSynthPlugin) | PluginClassEND(VexSynthPlugin) | ||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexSynthPlugin) | CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexSynthPlugin) | ||||
| }; | }; | ||||
| @@ -1291,7 +1542,7 @@ static const PluginDescriptor vexReverbDesc = { | |||||
| static const PluginDescriptor vexSynthDesc = { | static const PluginDescriptor vexSynthDesc = { | ||||
| /* category */ PLUGIN_CATEGORY_SYNTH, | /* category */ PLUGIN_CATEGORY_SYNTH, | ||||
| /* hints */ static_cast<PluginHints>(0x0), | |||||
| /* hints */ static_cast<PluginHints>(PLUGIN_HAS_GUI|PLUGIN_NEEDS_SINGLE_THREAD|PLUGIN_USES_TIME), | |||||
| /* supports */ static_cast<PluginSupports>(0x0), | /* supports */ static_cast<PluginSupports>(0x0), | ||||
| /* audioIns */ 0, | /* audioIns */ 0, | ||||
| /* audioOuts */ 2, | /* audioOuts */ 2, | ||||
| @@ -0,0 +1,265 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCETICE project - Copyright 2008 by Lucio Asnaghi. | |||||
| JUCETICE is based around the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2008 by Julian Storer. | |||||
| ------------------------------------------------------------------------------ | |||||
| JUCE and JUCETICE can be redistributed and/or modified under the terms of | |||||
| the GNU Lesser General Public License, as published by the Free Software | |||||
| Foundation; either version 2 of the License, or (at your option) any later | |||||
| version. | |||||
| JUCE and JUCETICE are distributed in the hope that they will be useful, | |||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| GNU General Public License for more details. | |||||
| You should have received a copy of the GNU Lesser General Public License | |||||
| along with JUCE and JUCETICE; if not, visit www.gnu.org/licenses or write to | |||||
| Free Software Foundation, Inc., 59 Temple Place, Suite 330, | |||||
| Boston, MA 02111-1307 USA | |||||
| ============================================================================== | |||||
| @author rockhardbuns | |||||
| @tweaker Lucio Asnaghi | |||||
| @tweaker falkTX | |||||
| ============================================================================== | |||||
| */ | |||||
| #ifndef DISTRHO_VEX_PEGGYVIEWCOMPONENT_HEADER_INCLUDED | |||||
| #define DISTRHO_VEX_PEGGYVIEWCOMPONENT_HEADER_INCLUDED | |||||
| #include "VexArpSettings.h" | |||||
| #include "gui/BoolGridComponent.h" | |||||
| #include "gui/SliderFieldComponent.h" | |||||
| class PeggyViewComponent : public Component, | |||||
| public ChangeListener, | |||||
| public SliderListener, | |||||
| public ComboBoxListener, | |||||
| public ButtonListener | |||||
| { | |||||
| public: | |||||
| class Callback | |||||
| { | |||||
| public: | |||||
| virtual ~Callback() {} | |||||
| virtual void somethingChanged(const uint32_t id) = 0; | |||||
| }; | |||||
| PeggyViewComponent(const int partID, VexArpSettings& arpSet, Callback* const callback) | |||||
| : fPart(partID), | |||||
| fArpSettings(arpSet), | |||||
| fCallback(callback) | |||||
| { | |||||
| addAndMakeVisible(boolGrid = new BoolGridComponent()); | |||||
| boolGrid->addChangeListener(this); | |||||
| addAndMakeVisible(sliderField = new SliderFieldComponent()); | |||||
| sliderField->addChangeListener(this); | |||||
| addAndMakeVisible(length = new Slider("sdf")); | |||||
| length->setRange(1, 16, 1); | |||||
| length->setTextBoxStyle(Slider::NoTextBox, true, 0, 0 ); | |||||
| length->addListener(this); | |||||
| addAndMakeVisible(timeMode = new ComboBox("a")); | |||||
| timeMode->setEditableText (false); | |||||
| timeMode->setJustificationType (Justification::centredLeft); | |||||
| timeMode->setTextWhenNothingSelected (String("_")); | |||||
| timeMode->setTextWhenNoChoicesAvailable (String("_")); | |||||
| timeMode->setColour(ComboBox::backgroundColourId, Colours::black); | |||||
| timeMode->setColour(ComboBox::textColourId, Colours::lightgrey); | |||||
| timeMode->setColour(ComboBox::outlineColourId, Colours::grey); | |||||
| timeMode->setColour(ComboBox::buttonColourId, Colours::grey); | |||||
| timeMode->setWantsKeyboardFocus(false); | |||||
| timeMode->addItem("1/8", 1); | |||||
| timeMode->addItem("1/16", 2); | |||||
| timeMode->addItem("1/32", 3); | |||||
| timeMode->addListener(this); | |||||
| addAndMakeVisible(syncMode = new ComboBox("a")); | |||||
| syncMode->setEditableText (false); | |||||
| syncMode->setJustificationType (Justification::centredLeft); | |||||
| syncMode->setTextWhenNothingSelected (String("_")); | |||||
| syncMode->setTextWhenNoChoicesAvailable (String("_")); | |||||
| syncMode->setColour(ComboBox::backgroundColourId, Colours::black); | |||||
| syncMode->setColour(ComboBox::textColourId, Colours::lightgrey); | |||||
| syncMode->setColour(ComboBox::outlineColourId, Colours::grey); | |||||
| syncMode->setColour(ComboBox::buttonColourId, Colours::grey); | |||||
| syncMode->setWantsKeyboardFocus(false); | |||||
| syncMode->addItem("Key Sync", 1); | |||||
| syncMode->addItem("Bar Sync", 2); | |||||
| syncMode->addListener(this); | |||||
| addAndMakeVisible(failMode = new ComboBox("a")); | |||||
| failMode->setEditableText(false); | |||||
| failMode->setJustificationType (Justification::centredLeft); | |||||
| failMode->setTextWhenNothingSelected (String("_")); | |||||
| failMode->setTextWhenNoChoicesAvailable (String("_")); | |||||
| failMode->setColour(ComboBox::backgroundColourId, Colours::black); | |||||
| failMode->setColour(ComboBox::textColourId, Colours::lightgrey); | |||||
| failMode->setColour(ComboBox::outlineColourId, Colours::grey); | |||||
| failMode->setColour(ComboBox::buttonColourId, Colours::grey); | |||||
| failMode->setWantsKeyboardFocus(false); | |||||
| failMode->addItem("Silent Step", 1); | |||||
| failMode->addItem("Skip One", 2); | |||||
| failMode->addItem("Skip Two", 3); | |||||
| failMode->addListener(this); | |||||
| addAndMakeVisible(velMode = new ComboBox("a")); | |||||
| velMode->setEditableText(false); | |||||
| velMode->setJustificationType(Justification::centredLeft); | |||||
| velMode->setTextWhenNothingSelected (String("_")); | |||||
| velMode->setTextWhenNoChoicesAvailable (String("_")); | |||||
| velMode->setColour(ComboBox::backgroundColourId, Colours::black); | |||||
| velMode->setColour(ComboBox::textColourId, Colours::lightgrey); | |||||
| velMode->setColour(ComboBox::outlineColourId, Colours::grey); | |||||
| velMode->setColour(ComboBox::buttonColourId, Colours::grey); | |||||
| velMode->setWantsKeyboardFocus(false); | |||||
| velMode->addItem("Pattern Velocity", 1); | |||||
| velMode->addItem("Input Velocity", 2); | |||||
| velMode->addItem("Sum Velocities", 3); | |||||
| velMode->addListener(this); | |||||
| addAndMakeVisible(onOffBtn = new ToggleButton ("new button")); | |||||
| onOffBtn->setButtonText(String( "On")); | |||||
| onOffBtn->addListener(this); | |||||
| onOffBtn->setClickingTogglesState(true); | |||||
| update(); | |||||
| } | |||||
| ~PeggyViewComponent() override | |||||
| { | |||||
| //deleteAllChildren(); | |||||
| removeAllChildren(); | |||||
| } | |||||
| void resized() override | |||||
| { | |||||
| boolGrid->setBounds(5, 5, 193, 63); | |||||
| sliderField->setBounds(5, 68, 193, 63); | |||||
| length->setBounds(4, 140, 194, 16); | |||||
| timeMode->setBounds(6, 160, 93, 23); | |||||
| syncMode->setBounds(102, 160, 93, 23); | |||||
| failMode->setBounds(6, 190, 189, 23); | |||||
| velMode-> setBounds(6, 220, 189, 23); | |||||
| onOffBtn->setBounds(6, 250, 60, 24); | |||||
| } | |||||
| void paint(Graphics& g) override | |||||
| { | |||||
| g.setColour(Colours::black.withAlpha(.5f)); | |||||
| g.fillRect(5,5,getWidth(), getHeight()); | |||||
| g.setGradientFill(ColourGradient(Colour(0xffffffff), 0.0f, 0.0f, | |||||
| Colour(0xff888899), (float)getWidth(), (float)getHeight(), false)); | |||||
| g.fillRect(0,0,getWidth() - 5, getHeight() - 5); | |||||
| g.setColour(Colours::black); | |||||
| g.drawRect(0,0,getWidth() - 5, getHeight() - 5); | |||||
| } | |||||
| void changeListenerCallback(ChangeBroadcaster* caller) override | |||||
| { | |||||
| if (caller == boolGrid) | |||||
| { | |||||
| int i = boolGrid->getLastChanged(); | |||||
| fArpSettings.grid[i] = boolGrid->getCellState(i); | |||||
| fCallback->somethingChanged(6+VexArpSettings::kVelocitiesSize+i); | |||||
| } | |||||
| else if (caller == sliderField) | |||||
| { | |||||
| int i = sliderField->getLastSlider(); | |||||
| fArpSettings.velocities[i] = jlimit(0.0f, 1.0f, sliderField->getValue(i)); | |||||
| fCallback->somethingChanged(6+i); | |||||
| } | |||||
| } | |||||
| void comboBoxChanged(ComboBox* caller) override | |||||
| { | |||||
| if (caller == timeMode) | |||||
| { | |||||
| fArpSettings.timeMode = timeMode->getSelectedId(); | |||||
| fCallback->somethingChanged(2); | |||||
| } | |||||
| else if (caller == syncMode) | |||||
| { | |||||
| fArpSettings.syncMode = syncMode->getSelectedId(); | |||||
| fCallback->somethingChanged(3); | |||||
| } | |||||
| else if (caller == failMode) | |||||
| { | |||||
| fArpSettings.failMode = failMode->getSelectedId(); | |||||
| fCallback->somethingChanged(4); | |||||
| } | |||||
| else if (caller == velMode) | |||||
| { | |||||
| fArpSettings.velMode = velMode->getSelectedId(); | |||||
| fCallback->somethingChanged(5); | |||||
| } | |||||
| } | |||||
| void sliderValueChanged(Slider* /*caller*/) override | |||||
| { | |||||
| boolGrid->setLength((int)length->getValue()); | |||||
| sliderField->setLength((int)length->getValue()); | |||||
| fArpSettings.length = (int)length->getValue(); | |||||
| fCallback->somethingChanged(1); | |||||
| } | |||||
| void buttonClicked(Button* /*caller*/) override | |||||
| { | |||||
| fArpSettings.on = onOffBtn->getToggleState(); | |||||
| fCallback->somethingChanged(0); | |||||
| } | |||||
| void update() | |||||
| { | |||||
| onOffBtn->setToggleState(fArpSettings.on, dontSendNotification); | |||||
| sliderField->setLength(fArpSettings.length); | |||||
| boolGrid->setLength(fArpSettings.length); | |||||
| length->setValue(fArpSettings.length); | |||||
| for (int i = 0; i < VexArpSettings::kVelocitiesSize; ++i) | |||||
| sliderField->setValue(i, fArpSettings.velocities[i]); | |||||
| for (int i = 0; i < VexArpSettings::kGridSize; ++i) | |||||
| boolGrid->setCellState(i, fArpSettings.grid[i]); | |||||
| timeMode->setSelectedId(fArpSettings.timeMode); | |||||
| syncMode->setSelectedId(fArpSettings.syncMode); | |||||
| failMode->setSelectedId(fArpSettings.failMode); | |||||
| velMode->setSelectedId(fArpSettings.velMode); | |||||
| } | |||||
| private: | |||||
| const int fPart; | |||||
| VexArpSettings& fArpSettings; | |||||
| Callback* const fCallback; | |||||
| ScopedPointer<BoolGridComponent> boolGrid; | |||||
| ScopedPointer<SliderFieldComponent> sliderField; | |||||
| ScopedPointer<ComboBox> timeMode; | |||||
| ScopedPointer<ComboBox> syncMode; | |||||
| ScopedPointer<ComboBox> failMode; | |||||
| ScopedPointer<ComboBox> velMode; | |||||
| ScopedPointer<ToggleButton> onOffBtn; | |||||
| ScopedPointer<Slider> length; | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PeggyViewComponent) | |||||
| }; | |||||
| #endif // DISTRHO_VEX_PEGGYVIEWCOMPONENT_HEADER_INCLUDED | |||||
| @@ -0,0 +1,199 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCETICE project - Copyright 2008 by Lucio Asnaghi. | |||||
| JUCETICE is based around the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2008 by Julian Storer. | |||||
| ------------------------------------------------------------------------------ | |||||
| JUCE and JUCETICE can be redistributed and/or modified under the terms of | |||||
| the GNU Lesser General Public License, as published by the Free Software | |||||
| Foundation; either version 2 of the License, or (at your option) any later | |||||
| version. | |||||
| JUCE and JUCETICE are distributed in the hope that they will be useful, | |||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| GNU General Public License for more details. | |||||
| You should have received a copy of the GNU Lesser General Public License | |||||
| along with JUCE and JUCETICE; if not, visit www.gnu.org/licenses or write to | |||||
| Free Software Foundation, Inc., 59 Temple Place, Suite 330, | |||||
| Boston, MA 02111-1307 USA | |||||
| ============================================================================== | |||||
| @author rockhardbuns | |||||
| @tweaker Lucio Asnaghi | |||||
| @tweaker falkTX | |||||
| ============================================================================== | |||||
| */ | |||||
| #ifndef DISTRHO_VEX_BOOLGRIDCOMPONENT_HEADER_INCLUDED | |||||
| #define DISTRHO_VEX_BOOLGRIDCOMPONENT_HEADER_INCLUDED | |||||
| #ifndef CARLA_EXPORT | |||||
| #define CARLA_EXPORT | |||||
| #endif | |||||
| #ifdef CARLA_EXPORT | |||||
| #include "juce_gui_basics.h" | |||||
| #else | |||||
| #include "../StandardHeader.h" | |||||
| #endif | |||||
| class BoolGridComponent : public Component, | |||||
| public ChangeBroadcaster | |||||
| { | |||||
| public: | |||||
| BoolGridComponent() | |||||
| : Component("Bool Grid Component") | |||||
| { | |||||
| grid = new bool[80]; | |||||
| lastCell = -1; | |||||
| cellX = -1; cellY = -1; | |||||
| sizeX = 16; sizeY = 5; | |||||
| activeLength = 8; | |||||
| for(int x = 0; x < sizeX; x++) | |||||
| { | |||||
| for(int y = 0; y < sizeY; y++) | |||||
| { | |||||
| grid[(x * sizeY) + y] = false; | |||||
| } | |||||
| } | |||||
| } | |||||
| ~BoolGridComponent() override | |||||
| { | |||||
| delete[] grid; | |||||
| } | |||||
| void paint(Graphics& g) override | |||||
| { | |||||
| //background | |||||
| //g.setColour(Colour(200,200,210).withAlpha(0.4f)); | |||||
| //g.fillRect(0,0,getWidth(),getHeight()); | |||||
| //cell size -recalculate in case of resizing | |||||
| cellX = getWidth() / sizeX; | |||||
| cellY = getHeight() / sizeY; | |||||
| //Draw lines and checkmarks | |||||
| for(int x = 0; x < sizeX; x++){ | |||||
| for(int y = 0; y < sizeY; y++){ | |||||
| //lines | |||||
| g.setColour(Colour(100,100,130)); | |||||
| g.drawLine((float) x*cellX, 0.0f,(float) x*cellX, (float) getHeight() ); | |||||
| g.drawLine(0.0f, (float) y*cellY, (float)getWidth(), (float) y*cellY); | |||||
| //checkmarks | |||||
| g.setColour(Colours::black); | |||||
| if (grid[(x * sizeY) + sizeY - y -1]){ | |||||
| g.fillEllipse((float) x*cellX+3, (float) y*cellY+3 ,(float) cellX - 5 ,(float) cellY - 5); | |||||
| } | |||||
| } | |||||
| } | |||||
| //Grey stuff out | |||||
| g.setColour(Colour(uint8(170),170,170,.7f)); | |||||
| g.fillRect(cellX*activeLength,0,getWidth(),getHeight()); | |||||
| //bevel outline for the entire draw area | |||||
| LookAndFeel::drawBevel(g, 0, 0, getWidth(), getHeight(), 1, Colours::black, Colours::white, 0); | |||||
| } | |||||
| //Yay, someone clicked my component! | |||||
| void mouseDown(const MouseEvent& e) override | |||||
| { | |||||
| if (e.mouseWasClicked()) | |||||
| { | |||||
| if ((e.y < getHeight()-1) && (e.x < getWidth()-1)){ //this avoids false triggers along the rims | |||||
| int cx = (e.x-1)/cellX; int cy = (e.y-1)/cellY; //cx,cy are the cell coords | |||||
| if (cx < activeLength){ //if the click was on the greyed out portion, we dont do jack | |||||
| lastCell = (cx * sizeY) + sizeY - cy -1; | |||||
| grid[lastCell]= !grid[lastCell]; //toggle the clicked cell | |||||
| repaint(); | |||||
| sendChangeMessage(); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| //get the state of a specific cell | |||||
| bool getCellState(int x, int y) const | |||||
| { | |||||
| return grid[(x * sizeY) + y]; | |||||
| } | |||||
| bool getCellState(int x) const | |||||
| { | |||||
| return grid[x]; | |||||
| } | |||||
| //set the state of a specific cell. the last param determines if we broadcast | |||||
| //Cell determined by grid coords i.e X * Y | |||||
| void setCellState(int x, int y, bool state, bool broadcast = false) | |||||
| { | |||||
| grid[(x * sizeY) + y] = state; | |||||
| if (broadcast){sendChangeMessage();} | |||||
| repaint(); | |||||
| } | |||||
| //Overloaded - cell determined soley by array index | |||||
| void setCellState(int x, bool state, bool broadcast = false) | |||||
| { | |||||
| grid[x] = state; | |||||
| if (broadcast){sendChangeMessage();} | |||||
| repaint(); | |||||
| } | |||||
| // the last changed cell, in terms of array index | |||||
| int getLastChanged() | |||||
| { | |||||
| return lastCell; | |||||
| lastCell = -1; | |||||
| } | |||||
| //Get the active length | |||||
| int getLength() const | |||||
| { | |||||
| return activeLength; | |||||
| } | |||||
| //Set the active length of the grid | |||||
| void setLength(int l) | |||||
| { | |||||
| activeLength = jmin(l, sizeX); | |||||
| activeLength = jmax(activeLength, 1); | |||||
| repaint(); | |||||
| } | |||||
| //Clear the grid | |||||
| void reset() | |||||
| { | |||||
| for(int x = 0; x < sizeX; x++){ | |||||
| for(int y = 0; y < sizeY; y++){ | |||||
| grid[(x * sizeY) + y] = false; | |||||
| } | |||||
| } | |||||
| repaint(); | |||||
| } | |||||
| private: | |||||
| int sizeX, sizeY; // grid size in number of cells | |||||
| int cellX, cellY; // cell size in pixels, used by paint(); | |||||
| int lastCell; // last cell clicked, for outside interaction | |||||
| int activeLength; // How much of the grid should be usable vs greyed | |||||
| bool* grid; // SizeX * SizeY | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(BoolGridComponent) | |||||
| }; | |||||
| #endif // DISTRHO_VEX_BOOLGRIDCOMPONENT_HEADER_INCLUDED | |||||
| @@ -0,0 +1,185 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCETICE project - Copyright 2008 by Lucio Asnaghi. | |||||
| JUCETICE is based around the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2008 by Julian Storer. | |||||
| ------------------------------------------------------------------------------ | |||||
| JUCE and JUCETICE can be redistributed and/or modified under the terms of | |||||
| the GNU Lesser General Public License, as published by the Free Software | |||||
| Foundation; either version 2 of the License, or (at your option) any later | |||||
| version. | |||||
| JUCE and JUCETICE are distributed in the hope that they will be useful, | |||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| GNU General Public License for more details. | |||||
| You should have received a copy of the GNU Lesser General Public License | |||||
| along with JUCE and JUCETICE; if not, visit www.gnu.org/licenses or write to | |||||
| Free Software Foundation, Inc., 59 Temple Place, Suite 330, | |||||
| Boston, MA 02111-1307 USA | |||||
| ============================================================================== | |||||
| @author rockhardbuns | |||||
| @tweaker Lucio Asnaghi | |||||
| @tweaker falkTX | |||||
| ============================================================================== | |||||
| */ | |||||
| #ifndef DISTRHO_VEX_SLIDERFIELDCOMPONENT_HEADER_INCLUDED | |||||
| #define DISTRHO_VEX_SLIDERFIELDCOMPONENT_HEADER_INCLUDED | |||||
| #ifndef CARLA_EXPORT | |||||
| #define CARLA_EXPORT | |||||
| #endif | |||||
| #ifdef CARLA_EXPORT | |||||
| #include "juce_gui_basics.h" | |||||
| #else | |||||
| #include "../StandardHeader.h" | |||||
| #endif | |||||
| class SliderFieldComponent : public Component, | |||||
| public ChangeBroadcaster | |||||
| { | |||||
| public: | |||||
| SliderFieldComponent() | |||||
| : Component("Slider Field Component") | |||||
| { | |||||
| array = new float[16]; | |||||
| lastSlider = -1; // -1, not to test against really | |||||
| sliderWidth = -1; // but it makes fuckups more visible | |||||
| numSliders = 16; | |||||
| activeLength = 8; | |||||
| //empty out the array.. to make sure | |||||
| for(int i = 0; i < numSliders; i++) | |||||
| array[i] = 0.5f; | |||||
| } | |||||
| ~SliderFieldComponent() override | |||||
| { | |||||
| delete[] array; | |||||
| deleteAllChildren(); | |||||
| } | |||||
| void paint(Graphics& g) override | |||||
| { | |||||
| //cell size -recalculate in case of resizing | |||||
| sliderWidth = getWidth() / numSliders; | |||||
| //int middle = int(getHeight() * 0.5f); | |||||
| //Draw bars | |||||
| g.setColour(Colour(50,50,50)); | |||||
| for(int i = 0; i < numSliders; i++) | |||||
| { | |||||
| if(array[i] > 0.0f){ | |||||
| g.fillRect(i * sliderWidth + 2, getHeight() - int(array[i] * getHeight()), sliderWidth - 4, int(getHeight() * array[i])) ; | |||||
| } | |||||
| } | |||||
| g.setColour(Colour(100,100,130)); | |||||
| //Grey stuff out | |||||
| g.setColour(Colour(uint8(170),170,170,.7f)); | |||||
| g.fillRect(sliderWidth*activeLength,0,getWidth(),getHeight()); | |||||
| //bevel outline for the entire draw area | |||||
| LookAndFeel::drawBevel(g, 0, 0, getWidth(), getHeight(), 1, Colours::black, Colours::white, 0); | |||||
| } | |||||
| void mouseDrag(const MouseEvent& e) override | |||||
| { | |||||
| if ((e.y < getHeight()-1) && (e.x < getWidth()-1)) | |||||
| { | |||||
| //this avoids false triggers along the rims | |||||
| float height = (float) getHeight(); | |||||
| int index = (e.x-1)/sliderWidth; | |||||
| float value = ((height - e.y -1.0f) / height); | |||||
| //if the click was on the greyed out portion, we dont do jack | |||||
| if (index < activeLength) | |||||
| { | |||||
| lastSlider = index; | |||||
| array[index]= value; | |||||
| repaint(); | |||||
| sendChangeMessage(); | |||||
| } | |||||
| } | |||||
| } | |||||
| void mouseDown(const MouseEvent& e) override | |||||
| { | |||||
| if ((e.y < getHeight()-1) && (e.x < getWidth()-1)) | |||||
| { | |||||
| //this avoids false triggers along the rims | |||||
| float height = (float) getHeight(); | |||||
| int index = (e.x-1)/sliderWidth; | |||||
| float value = ((height - e.y ) / height); | |||||
| //if the click was on the greyed out portion, we dont do jack | |||||
| if (index < activeLength) | |||||
| { | |||||
| lastSlider = index; | |||||
| array[index]= value; | |||||
| repaint(); | |||||
| sendChangeMessage(); | |||||
| } | |||||
| } | |||||
| } | |||||
| int getLastSlider() const | |||||
| { | |||||
| return lastSlider; | |||||
| } | |||||
| float getValue(int i) const | |||||
| { | |||||
| return array[i]; | |||||
| } | |||||
| void setValue(int i, float v) const | |||||
| { | |||||
| array[i] = v; | |||||
| } | |||||
| int getLength() const | |||||
| { | |||||
| return activeLength; | |||||
| } | |||||
| void setLength(const int l) | |||||
| { | |||||
| activeLength = jmin(l, numSliders); | |||||
| activeLength = jmax(activeLength, 1); | |||||
| repaint(); | |||||
| } | |||||
| void reset() | |||||
| { | |||||
| //empty out the array.. to make sure | |||||
| for(int i = 0; i < numSliders; i++) | |||||
| array[i] = 0.0f; | |||||
| repaint(); | |||||
| } | |||||
| private: | |||||
| int numSliders; | |||||
| int sliderWidth; | |||||
| int lastSlider; // last cell clicked, for outside interaction | |||||
| int activeLength; // How much of the grid should be usable vs greyed | |||||
| float* array; // SizeX | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SliderFieldComponent) | |||||
| }; | |||||
| #endif // DISTRHO_VEX_SLIDERFIELDCOMPONENT_HEADER_INCLUDED | |||||
| @@ -0,0 +1,67 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCETICE project - Copyright 2008 by Lucio Asnaghi. | |||||
| JUCETICE is based around the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2008 by Julian Storer. | |||||
| ------------------------------------------------------------------------------ | |||||
| JUCE and JUCETICE can be redistributed and/or modified under the terms of | |||||
| the GNU Lesser General Public License, as published by the Free Software | |||||
| Foundation; either version 2 of the License, or (at your option) any later | |||||
| version. | |||||
| JUCE and JUCETICE are distributed in the hope that they will be useful, | |||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| GNU General Public License for more details. | |||||
| You should have received a copy of the GNU Lesser General Public License | |||||
| along with JUCE and JUCETICE; if not, visit www.gnu.org/licenses or write to | |||||
| Free Software Foundation, Inc., 59 Temple Place, Suite 330, | |||||
| Boston, MA 02111-1307 USA | |||||
| ============================================================================== | |||||
| @author rockhardbuns | |||||
| @tweaker Lucio Asnaghi | |||||
| ============================================================================== | |||||
| */ | |||||
| #ifndef __JUCETICE_VEXSNAPPINGSLIDERCOMPONENT_HEADER__ | |||||
| #define __JUCETICE_VEXSNAPPINGSLIDERCOMPONENT_HEADER__ | |||||
| #include "../StandardHeader.h" | |||||
| class SnappingSlider : public Slider | |||||
| { | |||||
| public: | |||||
| SnappingSlider(const String& name) | |||||
| : Slider(name), | |||||
| snapTarget(0.0f), | |||||
| snapMargin(0.05f) | |||||
| { | |||||
| } | |||||
| void setSnap(const float target, const float margin) | |||||
| { | |||||
| snapTarget = target; | |||||
| snapMargin = margin; | |||||
| } | |||||
| double snapValue(const double attemptedValue, const bool userIsDragging) | |||||
| { | |||||
| if (std::fabs(attemptedValue - snapTarget) < snapMargin) | |||||
| return snapTarget; | |||||
| return attemptedValue; | |||||
| } | |||||
| private: | |||||
| float snapTarget, snapMargin; | |||||
| }; | |||||
| #endif | |||||
| @@ -0,0 +1,142 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCETICE project - Copyright 2008 by Lucio Asnaghi. | |||||
| JUCETICE is based around the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2008 by Julian Storer. | |||||
| ------------------------------------------------------------------------------ | |||||
| JUCE and JUCETICE can be redistributed and/or modified under the terms of | |||||
| the GNU Lesser General Public License, as published by the Free Software | |||||
| Foundation; either version 2 of the License, or (at your option) any later | |||||
| version. | |||||
| JUCE and JUCETICE are distributed in the hope that they will be useful, | |||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| GNU General Public License for more details. | |||||
| You should have received a copy of the GNU Lesser General Public License | |||||
| along with JUCE and JUCETICE; if not, visit www.gnu.org/licenses or write to | |||||
| Free Software Foundation, Inc., 59 Temple Place, Suite 330, | |||||
| Boston, MA 02111-1307 USA | |||||
| ============================================================================== | |||||
| @author rockhardbuns | |||||
| @tweaker Lucio Asnaghi | |||||
| ============================================================================== | |||||
| */ | |||||
| #include "MyLookAndFeel.h" | |||||
| MyLookAndFeel::MyLookAndFeel() | |||||
| { | |||||
| MemoryInputStream fontStream (Resources::t_bin, Resources::t_binSize, false); | |||||
| CustomTypeface* tf = new CustomTypeface (fontStream); | |||||
| Topaz = new Font (tf); | |||||
| // delete tf; | |||||
| Topaz->setHeight (9.0f); | |||||
| Topaz->setHorizontalScale (1.0f); | |||||
| // Topaz = new Font (Font::getDefaultMonospacedFontName (), 12.0f, Font::plain); | |||||
| // Topaz->setHorizontalScale (1.0f); | |||||
| } | |||||
| MyLookAndFeel::~MyLookAndFeel() | |||||
| { | |||||
| delete Topaz; | |||||
| } | |||||
| Font MyLookAndFeel::getComboBoxFont (ComboBox& box) | |||||
| { | |||||
| return *Topaz; | |||||
| } | |||||
| Font MyLookAndFeel::getPopupMenuFont() | |||||
| { | |||||
| return *Topaz; | |||||
| } | |||||
| void MyLookAndFeel::getIdealPopupMenuItemSize(const String& text, | |||||
| const bool isSeparator, | |||||
| int standardMenuItemHeight, | |||||
| int& idealWidth, | |||||
| int& idealHeight) | |||||
| { | |||||
| if (isSeparator) | |||||
| { | |||||
| idealWidth = 50; | |||||
| idealHeight = standardMenuItemHeight > 0 ? standardMenuItemHeight / 2 : 10; | |||||
| } | |||||
| else | |||||
| { | |||||
| Font font (getPopupMenuFont()); | |||||
| idealHeight = roundFloatToInt (font.getHeight() * 1.3f); | |||||
| idealWidth = font.getStringWidth (text) + idealHeight * 2; | |||||
| } | |||||
| } | |||||
| void MyLookAndFeel::drawToggleButton(Graphics& g, | |||||
| ToggleButton& button, | |||||
| bool isMouseOverButton, | |||||
| bool isButtonDown) | |||||
| { | |||||
| const int tickWidth = jmin (20, button.getHeight() - 4); | |||||
| drawTickBox (g, button, 4, (button.getHeight() - tickWidth) / 2, | |||||
| tickWidth, tickWidth, | |||||
| button.getToggleState(), | |||||
| button.isEnabled(), | |||||
| isMouseOverButton, | |||||
| isButtonDown); | |||||
| g.setColour (button.findColour (ToggleButton::textColourId)); | |||||
| g.setFont (*Topaz); | |||||
| const int textX = tickWidth + 5; | |||||
| g.drawFittedText (button.getButtonText(), | |||||
| textX, 4, | |||||
| button.getWidth() - textX - 2, button.getHeight() - 8, | |||||
| Justification::centredLeft, 10); | |||||
| } | |||||
| void MyLookAndFeel::drawRotarySlider (Graphics& g, | |||||
| int x, int y, | |||||
| int width, int height, | |||||
| float sliderPos, | |||||
| const float rotaryStartAngle, | |||||
| const float rotaryEndAngle, | |||||
| Slider& slider) | |||||
| { | |||||
| const float radius = jmin (width / 2, height / 2) - 2.0f; | |||||
| const float centreX = x + width * 0.5f; | |||||
| const float centreY = y + height * 0.5f; | |||||
| const float rx = centreX - radius; | |||||
| const float ry = centreY - radius; | |||||
| const float rw = radius * 2.0f; | |||||
| const float angle = rotaryStartAngle + sliderPos * (rotaryEndAngle - rotaryStartAngle); | |||||
| //const bool isMouseOver = slider.isMouseOverOrDragging() && slider.isEnabled(); | |||||
| // const float zeroPos = rotaryStartAngle + fabs((float)slider.getMinimum() / ((float)slider.getMaximum() - (float)slider.getMinimum())) * (rotaryEndAngle - rotaryStartAngle); | |||||
| Path p; | |||||
| PathStrokeType (rw * 0.01f).createStrokedPath (p, p); | |||||
| p.addLineSegment (Line<float>(0.0f, -radius * 0.5f, 0.00f, -radius), rw * 0.08f); | |||||
| g.setColour (Colours::white.withAlpha (1.0f)); | |||||
| g.fillPath (p, AffineTransform::rotation (angle).translated (centreX, centreY)); | |||||
| g.setColour (Colours::black.withAlpha (0.7f)); | |||||
| g.drawEllipse (rx, ry, rw, rw, 1.0f); | |||||
| } | |||||
| @@ -0,0 +1,80 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCETICE project - Copyright 2008 by Lucio Asnaghi. | |||||
| JUCETICE is based around the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2008 by Julian Storer. | |||||
| ------------------------------------------------------------------------------ | |||||
| JUCE and JUCETICE can be redistributed and/or modified under the terms of | |||||
| the GNU Lesser General Public License, as published by the Free Software | |||||
| Foundation; either version 2 of the License, or (at your option) any later | |||||
| version. | |||||
| JUCE and JUCETICE are distributed in the hope that they will be useful, | |||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| GNU General Public License for more details. | |||||
| You should have received a copy of the GNU Lesser General Public License | |||||
| along with JUCE and JUCETICE; if not, visit www.gnu.org/licenses or write to | |||||
| Free Software Foundation, Inc., 59 Temple Place, Suite 330, | |||||
| Boston, MA 02111-1307 USA | |||||
| ============================================================================== | |||||
| @author rockhardbuns | |||||
| @tweaker Lucio Asnaghi | |||||
| ============================================================================== | |||||
| */ | |||||
| #ifndef __JUCETICE_VEXMYLOOKANDFEEL_HEADER__ | |||||
| #define __JUCETICE_VEXMYLOOKANDFEEL_HEADER__ | |||||
| #ifndef CARLA_EXPORT | |||||
| #define CARLA_EXPORT | |||||
| #endif | |||||
| #ifdef CARLA_EXPORT | |||||
| #include "juce_gui_basics.h" | |||||
| #else | |||||
| #include "../StandardHeader.h" | |||||
| #endif | |||||
| #include "../resources/Resources.h" | |||||
| class MyLookAndFeel : public LookAndFeel | |||||
| { | |||||
| public: | |||||
| MyLookAndFeel(); | |||||
| ~MyLookAndFeel(); | |||||
| Font getComboBoxFont (ComboBox& box); | |||||
| Font getPopupMenuFont(); | |||||
| void getIdealPopupMenuItemSize (const String& text, | |||||
| const bool isSeparator, | |||||
| int standardMenuItemHeight, | |||||
| int& idealWidth, | |||||
| int& idealHeight); | |||||
| void drawToggleButton (Graphics& g, | |||||
| ToggleButton& button, | |||||
| bool isMouseOverButton, | |||||
| bool isButtonDown); | |||||
| void drawRotarySlider (Graphics& g, | |||||
| int x, int y, | |||||
| int width, int height, | |||||
| float sliderPosProportional, | |||||
| const float rotaryStartAngle, | |||||
| const float rotaryEndAngle, | |||||
| Slider& slider); | |||||
| public: | |||||
| Font* Topaz; | |||||
| }; | |||||
| #endif | |||||
| @@ -0,0 +1,15 @@ | |||||
| /* (Auto-generated binary data file). */ | |||||
| #ifndef BINARY_RESOURCES_H | |||||
| #define BINARY_RESOURCES_H | |||||
| namespace Resources | |||||
| { | |||||
| extern const char* vex3_png; | |||||
| const int vex3_pngSize = 298205; | |||||
| extern const char* t_bin; | |||||
| const int t_binSize = 4261; | |||||
| }; | |||||
| #endif | |||||
| @@ -336,7 +336,7 @@ class ParamSpinBox(QAbstractSpinBox): | |||||
| if self.fValue != None: | if self.fValue != None: | ||||
| self._setScalePointValue(self.fValue) | self._setScalePointValue(self.fValue) | ||||
| self.fBox.currentIndexChanged.connect(self.slot_comboBoxIndexChanged) | |||||
| self.fBox.currentIndexChanged['QString'].connect(self.slot_comboBoxIndexChanged) | |||||
| def stepBy(self, steps): | def stepBy(self, steps): | ||||
| if steps == 0 or self.fValue is None: | if steps == 0 or self.fValue is None: | ||||
| @@ -376,7 +376,7 @@ class ParamSpinBox(QAbstractSpinBox): | |||||
| return | return | ||||
| value = float(boxText.split(" - ", 1)[0]) | value = float(boxText.split(" - ", 1)[0]) | ||||
| lastScaleValue = self.fScalePoints[-1]["value"] | |||||
| lastScaleValue = self.fScalePoints[-1]['value'] | |||||
| if value == lastScaleValue: | if value == lastScaleValue: | ||||
| value = self.fMaximum | value = self.fMaximum | ||||