|
- /*
- ==============================================================================
-
- This file was auto-generated by the Jucer!
-
- It contains the basic startup code for a Juce application.
-
- ==============================================================================
- */
-
- #include "PluginProcessor.h"
- #include "PluginEditor.h"
-
- //==============================================================================
- JuceDemoPluginAudioProcessorEditor::JuceDemoPluginAudioProcessorEditor (JuceDemoPluginAudioProcessor* ownerFilter)
- : AudioProcessorEditor (ownerFilter),
- midiKeyboard (ownerFilter->keyboardState, MidiKeyboardComponent::horizontalKeyboard),
- infoLabel (String::empty),
- gainLabel ("", "Throughput level:"),
- delayLabel ("", "Delay:"),
- gainSlider ("gain"),
- delaySlider ("delay")
- {
- // add some sliders..
- addAndMakeVisible (&gainSlider);
- gainSlider.setSliderStyle (Slider::Rotary);
- gainSlider.addListener (this);
- gainSlider.setRange (0.0, 1.0, 0.01);
-
- addAndMakeVisible (&delaySlider);
- delaySlider.setSliderStyle (Slider::Rotary);
- delaySlider.addListener (this);
- delaySlider.setRange (0.0, 1.0, 0.01);
-
- // add some labels for the sliders..
- gainLabel.attachToComponent (&gainSlider, false);
- gainLabel.setFont (Font (11.0f));
-
- delayLabel.attachToComponent (&delaySlider, false);
- delayLabel.setFont (Font (11.0f));
-
- // add the midi keyboard component..
- addAndMakeVisible (&midiKeyboard);
-
- // add a label that will display the current timecode and status..
- addAndMakeVisible (&infoLabel);
- infoLabel.setColour (Label::textColourId, Colours::blue);
-
- // add the triangular resizer component for the bottom-right of the UI
- addAndMakeVisible (resizer = new ResizableCornerComponent (this, &resizeLimits));
- resizeLimits.setSizeLimits (150, 150, 800, 300);
-
- // set our component's initial size to be the last one that was stored in the filter's settings
- setSize (ownerFilter->lastUIWidth,
- ownerFilter->lastUIHeight);
-
- startTimer (50);
- }
-
- JuceDemoPluginAudioProcessorEditor::~JuceDemoPluginAudioProcessorEditor()
- {
- }
-
- //==============================================================================
- void JuceDemoPluginAudioProcessorEditor::paint (Graphics& g)
- {
- g.setGradientFill (ColourGradient (Colours::white, 0, 0, Colours::grey, 0, (float) getHeight(), false));
- g.fillAll();
- }
-
- void JuceDemoPluginAudioProcessorEditor::resized()
- {
- infoLabel.setBounds (10, 4, 400, 25);
- gainSlider.setBounds (20, 60, 150, 40);
- delaySlider.setBounds (200, 60, 150, 40);
-
- const int keyboardHeight = 70;
- midiKeyboard.setBounds (4, getHeight() - keyboardHeight - 4, getWidth() - 8, keyboardHeight);
-
- resizer->setBounds (getWidth() - 16, getHeight() - 16, 16, 16);
-
- getProcessor()->lastUIWidth = getWidth();
- getProcessor()->lastUIHeight = getHeight();
- }
-
- //==============================================================================
- // This timer periodically checks whether any of the filter's parameters have changed...
- void JuceDemoPluginAudioProcessorEditor::timerCallback()
- {
- JuceDemoPluginAudioProcessor* ourProcessor = getProcessor();
-
- AudioPlayHead::CurrentPositionInfo newPos (ourProcessor->lastPosInfo);
-
- if (lastDisplayedPosition != newPos)
- displayPositionInfo (newPos);
-
- gainSlider.setValue (ourProcessor->gain, false);
- delaySlider.setValue (ourProcessor->delay, false);
- }
-
- // This is our Slider::Listener callback, when the user drags a slider.
- void JuceDemoPluginAudioProcessorEditor::sliderValueChanged (Slider* slider)
- {
- if (slider == &gainSlider)
- {
- // It's vital to use setParameterNotifyingHost to change any parameters that are automatable
- // by the host, rather than just modifying them directly, otherwise the host won't know
- // that they've changed.
- getProcessor()->setParameterNotifyingHost (JuceDemoPluginAudioProcessor::gainParam,
- (float) gainSlider.getValue());
- }
- else if (slider == &delaySlider)
- {
- getProcessor()->setParameterNotifyingHost (JuceDemoPluginAudioProcessor::delayParam,
- (float) delaySlider.getValue());
- }
- }
-
- //==============================================================================
- // quick-and-dirty function to format a timecode string
- static const String timeToTimecodeString (const double seconds)
- {
- const double absSecs = fabs (seconds);
-
- const int hours = (int) (absSecs / (60.0 * 60.0));
- const int mins = ((int) (absSecs / 60.0)) % 60;
- const int secs = ((int) absSecs) % 60;
-
- String s;
- if (seconds < 0)
- s = "-";
-
- s << String (hours).paddedLeft ('0', 2) << ":"
- << String (mins).paddedLeft ('0', 2) << ":"
- << String (secs).paddedLeft ('0', 2) << ":"
- << String (roundToInt (absSecs * 1000) % 1000).paddedLeft ('0', 3);
-
- return s;
- }
-
- // quick-and-dirty function to format a bars/beats string
- static const String ppqToBarsBeatsString (double ppq, double /*lastBarPPQ*/, int numerator, int denominator)
- {
- if (numerator == 0 || denominator == 0)
- return "1|1|0";
-
- const int ppqPerBar = (numerator * 4 / denominator);
- const double beats = (fmod (ppq, ppqPerBar) / ppqPerBar) * numerator;
-
- const int bar = ((int) ppq) / ppqPerBar + 1;
- const int beat = ((int) beats) + 1;
- const int ticks = ((int) (fmod (beats, 1.0) * 960.0));
-
- String s;
- s << bar << '|' << beat << '|' << ticks;
- return s;
- }
-
- // Updates the text in our position label.
- void JuceDemoPluginAudioProcessorEditor::displayPositionInfo (const AudioPlayHead::CurrentPositionInfo& pos)
- {
- lastDisplayedPosition = pos;
- String displayText;
- displayText.preallocateStorage (64);
-
- displayText << String (pos.bpm, 2) << " bpm, "
- << pos.timeSigNumerator << '/' << pos.timeSigDenominator
- << " - " << timeToTimecodeString (pos.timeInSeconds)
- << " - " << ppqToBarsBeatsString (pos.ppqPosition, pos.ppqPositionOfLastBarStart,
- pos.timeSigNumerator, pos.timeSigDenominator);
-
- if (pos.isRecording)
- displayText << " (recording)";
- else if (pos.isPlaying)
- displayText << " (playing)";
-
- infoLabel.setText (displayText, false);
- }
|