2017-01-23 10:15:08 +00:00
|
|
|
|
/*
|
|
|
|
|
==============================================================================
|
|
|
|
|
This file is part of Obxd synthesizer.
|
|
|
|
|
|
2020-04-19 13:43:40 +00:00
|
|
|
|
Copyright <EFBFBD> 2013-2014 Filatov Vadim
|
2017-01-23 10:15:08 +00:00
|
|
|
|
|
|
|
|
|
Contact author via email :
|
|
|
|
|
justdat_@_e1.ru
|
|
|
|
|
|
|
|
|
|
This file may be licensed under the terms of of the
|
|
|
|
|
GNU General Public License Version 2 (the ``GPL'').
|
|
|
|
|
|
|
|
|
|
Software distributed under the License is distributed
|
|
|
|
|
on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
|
|
|
|
|
express or implied. See the GPL for the specific language
|
|
|
|
|
governing rights and limitations.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GPL along with this
|
|
|
|
|
program. If not, go to http://www.gnu.org/licenses/gpl.html
|
|
|
|
|
or write to the Free Software Foundation, Inc.,
|
|
|
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
==============================================================================
|
|
|
|
|
*/
|
|
|
|
|
#pragma once
|
|
|
|
|
#include "../Source/Engine/SynthEngine.h"
|
2021-09-01 08:38:39 +00:00
|
|
|
|
#include "../Components/ScaleComponent.h"
|
|
|
|
|
class ObxdAudioProcessor;
|
2022-02-20 18:53:09 +00:00
|
|
|
|
|
|
|
|
|
class KnobLookAndFeel : public LookAndFeel_V4
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
KnobLookAndFeel()
|
|
|
|
|
{
|
|
|
|
|
setColour(BubbleComponent::ColourIds::backgroundColourId, Colours::white.withAlpha(0.8f));
|
|
|
|
|
setColour(BubbleComponent::ColourIds::outlineColourId, Colours::transparentBlack);
|
|
|
|
|
setColour(TooltipWindow::textColourId, Colours::black);
|
|
|
|
|
}
|
|
|
|
|
int getSliderPopupPlacement(Slider&) override
|
|
|
|
|
{
|
|
|
|
|
return BubbleComponent::BubblePlacement::above;
|
|
|
|
|
}
|
|
|
|
|
private:
|
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KnobLookAndFeel)
|
|
|
|
|
};
|
|
|
|
|
|
2022-02-20 18:51:30 +00:00
|
|
|
|
class Knob : public Slider, public ScalableComponent, public ActionBroadcaster
|
2017-01-23 10:15:08 +00:00
|
|
|
|
{
|
2021-09-01 08:38:39 +00:00
|
|
|
|
juce::String img_name;
|
2017-01-23 10:15:08 +00:00
|
|
|
|
public:
|
|
|
|
|
//Knob(Image image, const int numFrames, const bool stripIsHorizontal) : Slider("Knob")
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
|
|
// setTextBoxStyle(NoTextBox, 0, 0, 0);
|
|
|
|
|
// setSliderStyle(RotaryVerticalDrag);
|
|
|
|
|
// setRange(0.0f, 1.0f, 0.001f);
|
|
|
|
|
//}
|
2021-09-01 08:38:39 +00:00
|
|
|
|
Knob (juce::String name, int fh, ObxdAudioProcessor* owner_) : Slider("Knob"), ScalableComponent(owner_), img_name(name)
|
2017-01-23 10:15:08 +00:00
|
|
|
|
{
|
2021-09-01 08:38:39 +00:00
|
|
|
|
scaleFactorChanged();
|
|
|
|
|
|
2020-04-19 13:43:40 +00:00
|
|
|
|
h2 = fh;
|
2021-09-01 08:38:39 +00:00
|
|
|
|
w2 = kni.getWidth();
|
|
|
|
|
numFr = kni.getHeight() / h2;
|
2022-02-20 18:53:09 +00:00
|
|
|
|
setLookAndFeel(&lookAndFeel);
|
2022-03-11 17:22:24 +00:00
|
|
|
|
setVelocityModeParameters(1.0, 1, 0.0, true, ModifierKeys::ctrlModifier);
|
2022-02-20 18:53:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~Knob() override
|
|
|
|
|
{
|
|
|
|
|
setLookAndFeel(nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-01 08:38:39 +00:00
|
|
|
|
void scaleFactorChanged() override
|
|
|
|
|
{
|
|
|
|
|
kni = getScaledImageFromCache(img_name, getScaleFactor(), getIsHighResolutionDisplay());
|
|
|
|
|
/*
|
|
|
|
|
backgroundImage =
|
|
|
|
|
allImage.getClippedImage(Rectangle<int>(0,
|
|
|
|
|
allImage.getHeight() / 2,
|
|
|
|
|
allImage.getWidth(),
|
|
|
|
|
allImage.getHeight() / 2));
|
|
|
|
|
*/
|
|
|
|
|
repaint();
|
|
|
|
|
}
|
2022-02-20 18:51:30 +00:00
|
|
|
|
|
|
|
|
|
void mouseDown(const MouseEvent& event) override
|
|
|
|
|
{
|
|
|
|
|
if (event.mods.isShiftDown())
|
|
|
|
|
{
|
|
|
|
|
if (shouldResetOnShiftClick)
|
|
|
|
|
{
|
|
|
|
|
sendActionMessage(resetActionMessage);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Slider::mouseDown(event);
|
|
|
|
|
}
|
2022-02-28 17:22:16 +00:00
|
|
|
|
|
|
|
|
|
void mouseDrag(const MouseEvent& event) override
|
|
|
|
|
{
|
|
|
|
|
Slider::mouseDrag(event);
|
|
|
|
|
if (event.mods.isShiftDown())
|
|
|
|
|
{
|
|
|
|
|
if (shiftDragCallback)
|
|
|
|
|
{
|
|
|
|
|
setValue(shiftDragCallback(getValue()), sendNotificationAsync);
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-11 17:22:24 +00:00
|
|
|
|
if (event.mods.isAltDown())
|
|
|
|
|
{
|
|
|
|
|
if (altDragCallback)
|
|
|
|
|
{
|
|
|
|
|
setValue(altDragCallback(getValue()), sendNotificationAsync);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (alternativeValueMapCallback)
|
|
|
|
|
{
|
|
|
|
|
setValue(alternativeValueMapCallback(getValue()), sendNotificationAsync);
|
|
|
|
|
}
|
2022-02-28 17:22:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-19 13:43:40 +00:00
|
|
|
|
// Source: https://git.iem.at/audioplugins/IEMPluginSuite/-/blob/master/resources/customComponents/ReverseSlider.h
|
|
|
|
|
public:
|
|
|
|
|
class KnobAttachment : public juce::AudioProcessorValueTreeState::SliderAttachment
|
|
|
|
|
{
|
2020-04-23 17:10:28 +00:00
|
|
|
|
RangedAudioParameter* parameter = nullptr;
|
|
|
|
|
Knob* sliderToControl = nullptr;
|
2020-04-19 13:43:40 +00:00
|
|
|
|
public:
|
|
|
|
|
KnobAttachment (juce::AudioProcessorValueTreeState& stateToControl,
|
|
|
|
|
const juce::String& parameterID,
|
2020-04-23 17:10:28 +00:00
|
|
|
|
Knob& sliderToControl) : AudioProcessorValueTreeState::SliderAttachment (stateToControl, parameterID, sliderToControl), sliderToControl(&sliderToControl)
|
2020-04-19 13:43:40 +00:00
|
|
|
|
{
|
2020-04-23 17:10:28 +00:00
|
|
|
|
parameter = stateToControl.getParameter (parameterID);
|
|
|
|
|
sliderToControl.setParameter (parameter);
|
2020-04-19 13:43:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-23 17:10:28 +00:00
|
|
|
|
|
|
|
|
|
/*KnobAttachment (juce::AudioProcessorValueTreeState& stateToControl,
|
2020-04-19 13:43:40 +00:00
|
|
|
|
const juce::String& parameterID,
|
|
|
|
|
Slider& sliderToControl) : AudioProcessorValueTreeState::SliderAttachment (stateToControl, parameterID, sliderToControl)
|
|
|
|
|
{
|
2020-04-23 17:10:28 +00:00
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
void updateToSlider(){
|
|
|
|
|
float val = parameter->getValue();
|
|
|
|
|
//sliderToControl->setValue(parameter->convertFrom0to1(val0to1));
|
|
|
|
|
sliderToControl->setValue(val, NotificationType::dontSendNotification);
|
2021-09-01 08:38:39 +00:00
|
|
|
|
//DBG(" Slider: " << parameter->name << " " << sliderToControl->getValue() << " Parameter: "<< " " << parameter->getValue());
|
2020-04-19 13:43:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~KnobAttachment() = default;
|
|
|
|
|
};
|
|
|
|
|
|
2020-04-23 17:10:28 +00:00
|
|
|
|
void setParameter (AudioProcessorParameter* p)
|
2020-04-19 13:43:40 +00:00
|
|
|
|
{
|
|
|
|
|
if (parameter == p)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
parameter = p;
|
|
|
|
|
updateText();
|
|
|
|
|
repaint();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void paint (Graphics& g) override
|
|
|
|
|
{
|
|
|
|
|
int ofs = (int) ((getValue() - getMinimum()) / (getMaximum() - getMinimum()) * (numFr - 1));
|
2021-09-01 08:38:39 +00:00
|
|
|
|
g.drawImage (kni, 0, 0, getWidth(), getHeight(), 0, h2 * ofs * getScaleInt(), w2 * getScaleInt(), h2 * getScaleInt());
|
2017-01-23 10:15:08 +00:00
|
|
|
|
}
|
2022-02-20 18:51:30 +00:00
|
|
|
|
|
|
|
|
|
void resetOnShiftClick(bool value, const String& identifier)
|
|
|
|
|
{
|
|
|
|
|
shouldResetOnShiftClick = value;
|
|
|
|
|
resetActionMessage = identifier;
|
|
|
|
|
}
|
2022-02-28 17:22:16 +00:00
|
|
|
|
|
2022-03-11 17:22:24 +00:00
|
|
|
|
std::function<double(double)> shiftDragCallback, altDragCallback, alternativeValueMapCallback;
|
2017-01-23 10:15:08 +00:00
|
|
|
|
private:
|
|
|
|
|
Image kni;
|
2020-04-19 13:43:40 +00:00
|
|
|
|
int fh, numFr;
|
|
|
|
|
int w2, h2;
|
2022-02-20 18:51:30 +00:00
|
|
|
|
bool shouldResetOnShiftClick{ false };
|
|
|
|
|
String resetActionMessage{};
|
2020-04-23 17:10:28 +00:00
|
|
|
|
AudioProcessorParameter* parameter {nullptr};
|
2022-02-20 18:53:09 +00:00
|
|
|
|
KnobLookAndFeel lookAndFeel;
|
2020-04-19 13:43:40 +00:00
|
|
|
|
};
|