161 lines
5.7 KiB
C++
161 lines
5.7 KiB
C++
/*
|
|
==============================================================================
|
|
Copyright 2022 Nicolas Chambert
|
|
|
|
This program is free software : you can redistribute itand /or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it 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 General Public License
|
|
along with this program.If not, see < http://www.gnu.org/licenses/>.
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
/*
|
|
==============================================================================
|
|
|
|
Gestion du bouton play et du volume.
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
#include "PlayPanel.h"
|
|
#include "Metronome.h"
|
|
#include "Figures.h"
|
|
|
|
void RoundButtonLookAndFeel::drawButtonBackground(juce::Graphics& g, juce::Button& button, const juce::Colour& backgroundColour,
|
|
bool isMouseOverButton, bool isButtonDown)
|
|
{
|
|
// version addapté du LookAndFeel_V4
|
|
auto baseColour = backgroundColour.withMultipliedSaturation(button.hasKeyboardFocus(true) ? 1.3f : 0.9f)
|
|
.withMultipliedAlpha(button.isEnabled() ? 0.9f : 0.5f);
|
|
|
|
if (isButtonDown || isMouseOverButton)
|
|
baseColour = baseColour.contrasting(isButtonDown ? 0.2f : 0.1f);
|
|
|
|
auto width = (float)button.getWidth() - 1.0f;
|
|
auto height = (float)button.getHeight() - 1.0f;
|
|
|
|
if (width > 0 && height > 0)
|
|
{
|
|
// on viens dessiner un cercle
|
|
auto rect = button.getLocalBounds();
|
|
float rwidth = rect.getWidth() < rect.getHeight() ? (float)rect.getWidth() - 25.0f : (float)rect.getHeight() - 25.0f;
|
|
|
|
g.setGradientFill(juce::ColourGradient::vertical(juce::Colours::lightgrey, 0.0f,
|
|
juce::Colours::lightgrey.darker(0.1f), height));
|
|
g.fillEllipse(rect.getCentreX() - rwidth / 2, rect.getCentreY() - rwidth / 2, rwidth, rwidth);
|
|
|
|
g.setGradientFill(juce::ColourGradient::vertical(baseColour, 0.0f,
|
|
baseColour.darker(0.1f), height));
|
|
|
|
g.drawEllipse(rect.getCentreX() - rwidth / 2, rect.getCentreY() - rwidth / 2, rwidth, rwidth, 4);
|
|
}
|
|
}
|
|
|
|
PlayPanel::PlayPanel(juce::Colour c) : backgroundColour(c)
|
|
{
|
|
// initialisation de l'interface
|
|
lef.reset(new RoundButtonLookAndFeel());
|
|
|
|
// Le dessin du bouton play est dans un svg
|
|
auto doc = juce::XmlDocument::parse(SVGFigures::play);
|
|
auto image = juce::Drawable::createFromSVG(*doc);
|
|
addComponent(volume);
|
|
addComponent(playButton);
|
|
playButton.setRadioGroupId(1);
|
|
playButton.setImages(image.get());
|
|
playButton.setToggleState(false, juce::NotificationType::dontSendNotification);
|
|
playButton.setColour(juce::TextButton::buttonColourId, juce::Colours::lightgreen);
|
|
playButton.setColour(juce::TextButton::textColourOffId, juce::Colours::black);
|
|
playButton.setLookAndFeel(lef.get());
|
|
volume.setRange(-100, 6); // on prend -100db en min, et on s'autorise à amplifier le sample à +6db
|
|
volume.setValue(0); // valeur initiale à 0db
|
|
volume.setSliderStyle(juce::Slider::SliderStyle::LinearVertical);
|
|
volume.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, true, 0, 0);
|
|
volume.setColour(juce::Slider::thumbColourId, backgroundColour);
|
|
volume.setColour(juce::Slider::trackColourId, juce::Colours::green);
|
|
}
|
|
|
|
PlayPanel::~PlayPanel()
|
|
{
|
|
// evite une fuite mémoire à la fermeture due au L&F
|
|
playButton.setLookAndFeel(nullptr);
|
|
}
|
|
|
|
void PlayPanel::addComponent(juce::Component& c)
|
|
{
|
|
addAndMakeVisible(c);
|
|
c.setColour(juce::TextButton::buttonColourId, backgroundColour);
|
|
c.setColour(juce::TextButton::textColourOffId, juce::Colours::black);
|
|
}
|
|
|
|
void PlayPanel::paint(juce::Graphics& g)
|
|
{
|
|
g.fillAll(backgroundColour);
|
|
}
|
|
|
|
void PlayPanel::resized()
|
|
{
|
|
// On gêre le placement via une grille 3 collones
|
|
// la première colonne est vide et sert de "marge"
|
|
juce::Grid vpgrid;
|
|
using Track = juce::Grid::TrackInfo;
|
|
using Fr = juce::Grid::Fr;
|
|
vpgrid.templateRows = { Track(Fr(1)) };
|
|
vpgrid.templateColumns = { Track(Fr(1)), Track(Fr(5)), Track(Fr(1)) };
|
|
|
|
vpgrid.items = { juce::GridItem(), juce::GridItem(playButton), juce::GridItem(volume) };
|
|
vpgrid.performLayout(getLocalBounds());
|
|
}
|
|
|
|
void PlayPanel::init(Metronome& metro)
|
|
{
|
|
// On établi les liaisons entre le Metronome et les composants graphique
|
|
playButton.onClick = [&, this]() { play(metro); };
|
|
volume.setValue(juce::Decibels::gainToDecibels(metro.getGain())); // On récupère la valeur initiale du gain
|
|
volume.onValueChange = [&, this]
|
|
{
|
|
double db = volume.getValue();
|
|
metro.setGain((float)juce::Decibels::decibelsToGain(db));
|
|
};
|
|
}
|
|
|
|
void PlayPanel::play(Metronome& metro)
|
|
{
|
|
// lance la lecture ou met en pause
|
|
playState = playState == PlayState::playing ? PlayState::stopped : PlayState::playing;
|
|
if (playState == PlayState::stopped)
|
|
{
|
|
// en cas de stop, on remet les compteurs à zero sur le metronome
|
|
metro.reset();
|
|
}
|
|
|
|
// On modifie la couleur du bouton en fonction de l'état
|
|
playButton.setColour(juce::TextButton::buttonColourId, playState == PlayState::playing ? juce::Colours::green : juce::Colours::lightgreen);
|
|
}
|
|
|
|
void PlayPanel::highlight()
|
|
{
|
|
// Met le bouton en surbrillance sur le temps
|
|
// la variable highlightFrames decompte 6 frames sur un timer de 20ms soit 120ms
|
|
if (playState == PlayState::playing)
|
|
{
|
|
if (highlightFrames > 0)
|
|
{
|
|
playButton.setColour(juce::TextButton::buttonColourId, juce::Colours::orangered);
|
|
highlightFrames--;
|
|
}
|
|
else
|
|
{
|
|
playButton.setColour(juce::TextButton::buttonColourId, juce::Colours::green);
|
|
}
|
|
}
|
|
} |