| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library.
 -    Copyright (c) 2017 - ROLI Ltd.
 - 
 -    JUCE is an open source library subject to commercial or open-source
 -    licensing.
 - 
 -    By using JUCE, you agree to the terms of both the JUCE 5 End-User License
 -    Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
 -    27th April 2017).
 - 
 -    End User License Agreement: www.juce.com/juce-5-licence
 -    Privacy Policy: www.juce.com/juce-5-privacy-policy
 - 
 -    Or: You may also use this code under the terms of the GPL v3 (see
 -    www.gnu.org/licenses).
 - 
 -    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 -    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 -    DISCLAIMED.
 - 
 -   ==============================================================================
 - */
 - 
 - #include "PluginProcessor.h"
 - #include "PluginEditor.h"
 - 
 - //==============================================================================
 - // This is a handy slider subclass that controls an AudioProcessorParameter
 - // (may move this class into the library itself at some point in the future..)
 - class JuceDemoPluginAudioProcessorEditor::ParameterSlider   : public Slider,
 -                                                               private Timer
 - {
 - public:
 -     ParameterSlider (AudioProcessorParameter& p)
 -         : Slider (p.getName (256)), param (p)
 -     {
 -         setRange (0.0, 1.0, 0.0);
 -         startTimerHz (30);
 -         updateSliderPos();
 -     }
 - 
 -     void valueChanged() override
 -     {
 -         if (isMouseButtonDown())
 -             param.setValueNotifyingHost ((float) Slider::getValue());
 -         else
 -             param.setValue ((float) Slider::getValue());
 -     }
 - 
 -     void timerCallback() override       { updateSliderPos(); }
 - 
 -     void startedDragging() override     { param.beginChangeGesture(); }
 -     void stoppedDragging() override     { param.endChangeGesture();   }
 - 
 -     double getValueFromText (const String& text) override   { return param.getValueForText (text); }
 -     String getTextFromValue (double value) override         { return param.getText ((float) value, 1024); }
 - 
 -     void updateSliderPos()
 -     {
 -         const float newValue = param.getValue();
 - 
 -         if (newValue != (float) Slider::getValue() && ! isMouseButtonDown())
 -             Slider::setValue (newValue);
 -     }
 - 
 -     AudioProcessorParameter& param;
 - 
 -     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParameterSlider)
 - };
 - 
 - //==============================================================================
 - JuceDemoPluginAudioProcessorEditor::JuceDemoPluginAudioProcessorEditor (JuceDemoPluginAudioProcessor& owner)
 -     : AudioProcessorEditor (owner),
 -       midiKeyboard (owner.keyboardState, MidiKeyboardComponent::horizontalKeyboard),
 -       timecodeDisplayLabel (String()),
 -       gainLabel (String(), "Throughput level:"),
 -       delayLabel (String(), "Delay:")
 - {
 -     // add some sliders..
 -     addAndMakeVisible (gainSlider = new ParameterSlider (*owner.gainParam));
 -     gainSlider->setSliderStyle (Slider::Rotary);
 - 
 -     addAndMakeVisible (delaySlider = new ParameterSlider (*owner.delayParam));
 -     delaySlider->setSliderStyle (Slider::Rotary);
 - 
 -     // 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 (timecodeDisplayLabel);
 -     timecodeDisplayLabel.setFont (Font (Font::getDefaultMonospacedFontName(), 15.0f, Font::plain));
 - 
 -     // set resize limits for this plug-in
 -     setResizeLimits (400, 200, 1024, 700);
 - 
 -     // set our component's initial size to be the last one that was stored in the filter's settings
 -     setSize (owner.lastUIWidth,
 -              owner.lastUIHeight);
 - 
 -     updateTrackProperties();
 - 
 -     // start a timer which will keep our timecode display updated
 -     startTimerHz (30);
 - }
 - 
 - JuceDemoPluginAudioProcessorEditor::~JuceDemoPluginAudioProcessorEditor()
 - {
 - }
 - 
 - //==============================================================================
 - void JuceDemoPluginAudioProcessorEditor::paint (Graphics& g)
 - {
 -     g.setColour (backgroundColour);
 -     g.fillAll();
 - }
 - 
 - void JuceDemoPluginAudioProcessorEditor::resized()
 - {
 -     // This lays out our child components...
 - 
 -     Rectangle<int> r (getLocalBounds().reduced (8));
 - 
 -     timecodeDisplayLabel.setBounds (r.removeFromTop (26));
 -     midiKeyboard.setBounds (r.removeFromBottom (70));
 - 
 -     r.removeFromTop (20);
 -     Rectangle<int> sliderArea (r.removeFromTop (60));
 -     gainSlider->setBounds (sliderArea.removeFromLeft (jmin (180, sliderArea.getWidth() / 2)));
 -     delaySlider->setBounds (sliderArea.removeFromLeft (jmin (180, sliderArea.getWidth())));
 - 
 -     getProcessor().lastUIWidth = getWidth();
 -     getProcessor().lastUIHeight = getHeight();
 - }
 - 
 - //==============================================================================
 - void JuceDemoPluginAudioProcessorEditor::timerCallback()
 - {
 -     updateTimecodeDisplay (getProcessor().lastPosInfo);
 - }
 - 
 - void JuceDemoPluginAudioProcessorEditor::hostMIDIControllerIsAvailable (bool controllerIsAvailable)
 - {
 -     midiKeyboard.setVisible (! controllerIsAvailable);
 - }
 - 
 - void JuceDemoPluginAudioProcessorEditor::updateTrackProperties ()
 - {
 -     auto trackColour = getProcessor().trackProperties.colour;
 -     auto& lf = getLookAndFeel();
 - 
 -     backgroundColour = (trackColour == Colour() ? lf.findColour (ResizableWindow::backgroundColourId)
 -                                                 : trackColour.withAlpha (1.0f).withBrightness (0.266f));
 -     repaint();
 - }
 - 
 - //==============================================================================
 - // quick-and-dirty function to format a timecode string
 - static String timeToTimecodeString (double seconds)
 - {
 -     const int millisecs = roundToInt (seconds * 1000.0);
 -     const int absMillisecs = std::abs (millisecs);
 - 
 -     return String::formatted ("%02d:%02d:%02d.%03d",
 -                               millisecs / 3600000,
 -                               (absMillisecs / 60000) % 60,
 -                               (absMillisecs / 1000) % 60,
 -                               absMillisecs % 1000);
 - }
 - 
 - // quick-and-dirty function to format a bars/beats string
 - static String quarterNotePositionToBarsBeatsString (double quarterNotes, int numerator, int denominator)
 - {
 -     if (numerator == 0 || denominator == 0)
 -         return "1|1|000";
 - 
 -     const int quarterNotesPerBar = (numerator * 4 / denominator);
 -     const double beats  = (fmod (quarterNotes, quarterNotesPerBar) / quarterNotesPerBar) * numerator;
 - 
 -     const int bar    = ((int) quarterNotes) / quarterNotesPerBar + 1;
 -     const int beat   = ((int) beats) + 1;
 -     const int ticks  = ((int) (fmod (beats, 1.0) * 960.0 + 0.5));
 - 
 -     return String::formatted ("%d|%d|%03d", bar, beat, ticks);
 - }
 - 
 - // Updates the text in our position label.
 - void JuceDemoPluginAudioProcessorEditor::updateTimecodeDisplay (AudioPlayHead::CurrentPositionInfo pos)
 - {
 -     MemoryOutputStream displayText;
 - 
 -     displayText << "[" << SystemStats::getJUCEVersion() << "]   "
 -                 << String (pos.bpm, 2) << " bpm, "
 -                 << pos.timeSigNumerator << '/' << pos.timeSigDenominator
 -                 << "  -  " << timeToTimecodeString (pos.timeInSeconds)
 -                 << "  -  " << quarterNotePositionToBarsBeatsString (pos.ppqPosition,
 -                                                                     pos.timeSigNumerator,
 -                                                                     pos.timeSigDenominator);
 - 
 -     if (pos.isRecording)
 -         displayText << "  (recording)";
 -     else if (pos.isPlaying)
 -         displayText << "  (playing)";
 - 
 -     timecodeDisplayLabel.setText (displayText.toString(), dontSendNotification);
 - }
 
 
  |