| 101 | } |
| 102 | |
| 103 | void EnvPanel::paint(juce::Graphics& g) { |
| 104 | g.setColour(Utils::Colour::PANEL); |
| 105 | g.fillRoundedRectangle(getLocalBounds().expanded(0, 20).translated(0, -20).toFloat(), 10); |
| 106 | |
| 107 | g.setColour(Utils::Colour::BACKGROUND); |
| 108 | g.fillRect(mVizRect); |
| 109 | |
| 110 | float attack = ParamRanges::ATTACK.convertTo0to1(mSliderAttack.getValue()); |
| 111 | float decay = ParamRanges::DECAY.convertTo0to1(mSliderDecay.getValue()); |
| 112 | float sustain = ParamRanges::SUSTAIN.convertTo0to1(mSliderSustain.getValue()); |
| 113 | float release = ParamRanges::RELEASE.convertTo0to1(mSliderRelease.getValue()); |
| 114 | |
| 115 | // Draw ADSR path |
| 116 | auto adsrRect = mVizRect.reduced(Utils::PADDING * 2, Utils::PADDING * 2); |
| 117 | |
| 118 | juce::Path adsrPath; |
| 119 | juce::Point<float> startPt = adsrRect.getBottomLeft(); |
| 120 | juce::Point<float> attackPt = startPt.translated(attack * adsrRect.getWidth() * 0.375f, -adsrRect.getHeight()); |
| 121 | juce::Point<float> decayPt = attackPt.translated(decay * adsrRect.getWidth() * 0.375f, (1.0f - sustain) * (adsrRect.getHeight())); |
| 122 | juce::Point<float> sustainPt = adsrRect.getBottomLeft().translated(adsrRect.getWidth() * 0.75f, -sustain * (adsrRect.getHeight())); |
| 123 | juce::Point<float> endPt = sustainPt.translated(release * adsrRect.getWidth() * 0.25f, 0.0f).withY(adsrRect.getBottom()); |
| 124 | |
| 125 | adsrPath.startNewSubPath(startPt); |
| 126 | adsrPath.lineTo(attackPt); |
| 127 | adsrPath.lineTo(decayPt); |
| 128 | adsrPath.lineTo(sustainPt); |
| 129 | adsrPath.lineTo(endPt); |
| 130 | adsrPath.closeSubPath(); |
| 131 | g.setColour(mModEnv.colour); |
| 132 | g.strokePath(adsrPath.createPathWithRoundedCorners(5), juce::PathStrokeType(3)); |
| 133 | } |
| 134 | |
| 135 | void EnvPanel::resized() { |
| 136 | auto r = getLocalBounds().reduced(Utils::PADDING); |