| @@ -1732,26 +1732,20 @@ void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t | |||
| plugin->process(inBuf, outBuf, frames); | |||
| plugin->unlock(); | |||
| #if 0 | |||
| // 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->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 | |||
| { | |||
| @@ -1183,6 +1183,8 @@ protected: | |||
| processPlugin(plugin, nframes); | |||
| plugin->unlock(); | |||
| } | |||
| return runPendingRtEvents(); | |||
| #else | |||
| if (fOptions.processMode == PROCESS_MODE_SINGLE_CLIENT) | |||
| { | |||
| @@ -1197,8 +1199,11 @@ protected: | |||
| plugin->unlock(); | |||
| } | |||
| } | |||
| return runPendingRtEvents(); | |||
| } | |||
| else if (fOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK) | |||
| if (fOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK) | |||
| { | |||
| // get buffers from jack | |||
| float* const audioIn1 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioIn1], nframes); | |||
| @@ -1242,7 +1247,7 @@ protected: | |||
| engineEvent->time = jackEvent.time; | |||
| engineEvent->channel = midiChannel; | |||
| if (MIDI_IS_STATUS_CONTROL_CHANGE(midiStatus)) | |||
| if (midiStatus == MIDI_STATUS_CONTROL_CHANGE) | |||
| { | |||
| CARLA_ASSERT(jackEvent.size == 2 || jackEvent.size == 3); | |||
| @@ -1280,7 +1285,7 @@ protected: | |||
| 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); | |||
| @@ -1389,6 +1394,8 @@ protected: | |||
| jackbridge_midi_event_write(eventOut, engineEvent->time, data, size); | |||
| } | |||
| } | |||
| return runPendingRtEvents(); | |||
| } | |||
| #endif // ! BUILD_BRIDGE | |||
| @@ -17,7 +17,7 @@ | |||
| #include "CarlaNative.hpp" | |||
| #include "juce_core.h" | |||
| #include "juce_gui_basics.h" | |||
| using namespace juce; | |||
| @@ -31,4 +31,6 @@ using namespace juce; | |||
| #include "vex/VexVoice.cpp" | |||
| #include "vex/VexWaveRenderer.cpp" | |||
| #include "vex/lookandfeel/MyLookAndFeel.cpp" | |||
| // ----------------------------------------------------------------------- | |||
| @@ -28,6 +28,10 @@ using namespace juce; | |||
| #include "vex/VexSyntModule.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: | |||
| HelperWindow() | |||
| : DocumentWindow("PlugWindow", Colour(0, 0, 0), DocumentWindow::closeButton, false), | |||
| : DocumentWindow("PlugWindow", Colour(50, 50, 200), DocumentWindow::closeButton, false), | |||
| fClosed(false) | |||
| { | |||
| setVisible(false); | |||
| setAlwaysOnTop(true); | |||
| setDropShadowEnabled(false); | |||
| setOpaque(true); | |||
| setResizable(false, false); | |||
| //setUsingNativeTitleBar(true); | |||
| setVisible(false); | |||
| //setResizable(false, false); | |||
| //setUsingNativeTitleBar(false); | |||
| } | |||
| void show(Component* const comp) | |||
| { | |||
| 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()) | |||
| addToDesktop(); | |||
| @@ -81,6 +90,141 @@ protected: | |||
| private: | |||
| 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, | |||
| kParamFailMode, | |||
| kParamVelMode, | |||
| kParamCount | |||
| kParamLast, | |||
| kParamCount = kParamLast + VexArpSettings::kVelocitiesSize + VexArpSettings::kGridSize | |||
| }; | |||
| VexArpPlugin(const HostDescriptor* const host) | |||
| @@ -120,118 +265,155 @@ protected: | |||
| { | |||
| static Parameter paramInfo; | |||
| 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.unit = nullptr; | |||
| paramInfo.ranges.def = 0.0f; | |||
| paramInfo.ranges.min = 0.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.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); | |||
| return ¶mInfo; | |||
| } | |||
| 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 | |||
| { | |||
| 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) | |||
| { | |||
| fView = new PeggyViewComponent(1, fSettings, this); | |||
| fView->setSize(207, 280); | |||
| fView->setSize(207, 320); | |||
| } | |||
| fWindow->show(fView); | |||
| @@ -1176,6 +1369,53 @@ protected: | |||
| 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 | |||
| @@ -1201,6 +1441,14 @@ protected: | |||
| fSynth.setSampleRate(sampleRate); | |||
| } | |||
| void uiNameChanged(const char* const uiName) override | |||
| { | |||
| if (fWindow == nullptr) | |||
| return; | |||
| fWindow->setName(uiName); | |||
| } | |||
| private: | |||
| float fParameters[92]; | |||
| @@ -1215,6 +1463,9 @@ private: | |||
| VexReverb fReverb; | |||
| VexSyntModule fSynth; | |||
| ScopedPointer<VexEditorComponent> fView; | |||
| ScopedPointer<HelperWindow> fWindow; | |||
| PluginClassEND(VexSynthPlugin) | |||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexSynthPlugin) | |||
| }; | |||
| @@ -1291,7 +1542,7 @@ static const PluginDescriptor vexReverbDesc = { | |||
| static const PluginDescriptor vexSynthDesc = { | |||
| /* 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), | |||
| /* audioIns */ 0, | |||
| /* 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: | |||
| self._setScalePointValue(self.fValue) | |||
| self.fBox.currentIndexChanged.connect(self.slot_comboBoxIndexChanged) | |||
| self.fBox.currentIndexChanged['QString'].connect(self.slot_comboBoxIndexChanged) | |||
| def stepBy(self, steps): | |||
| if steps == 0 or self.fValue is None: | |||
| @@ -376,7 +376,7 @@ class ParamSpinBox(QAbstractSpinBox): | |||
| return | |||
| value = float(boxText.split(" - ", 1)[0]) | |||
| lastScaleValue = self.fScalePoints[-1]["value"] | |||
| lastScaleValue = self.fScalePoints[-1]['value'] | |||
| if value == lastScaleValue: | |||
| value = self.fMaximum | |||