| 121 | } |
| 122 | |
| 123 | void EnvelopeGrain::paint(juce::Graphics& g) { |
| 124 | juce::Colour colour = mParamColour; |
| 125 | |
| 126 | // Panel rectangle |
| 127 | g.setColour(Utils::Colour::PANEL); |
| 128 | g.fillRoundedRectangle(getLocalBounds().expanded(0, 20).translated(0, -20).toFloat(), 10); |
| 129 | |
| 130 | // Visualization rect |
| 131 | g.setColour(Utils::Colour::BACKGROUND); |
| 132 | g.fillRect(mVizRect); |
| 133 | |
| 134 | auto drawRect = mVizRect.reduced(Utils::PADDING); |
| 135 | |
| 136 | float durSec, rateSec; |
| 137 | if (mBtnSync.getToggleState()) { |
| 138 | float div = std::pow(2, juce::roundToInt(ParamRanges::SYNC_DIV_MAX * (1.0f - ParamRanges::GRAIN_DURATION.convertTo0to1(mSliderDuration.getValue())))); |
| 139 | // Find synced duration/rate using fixed 120 bpm and 4 beats per bar (different from actual synthesis, just for vis) |
| 140 | durSec = (1.0f / 120) * 60.0f * (4 / div); |
| 141 | div = std::pow(2, juce::roundToInt(ParamRanges::SYNC_DIV_MAX * ParamRanges::GRAIN_RATE.convertTo0to1(mSliderRate.getValue()))); |
| 142 | rateSec = (1.0f / 120) * 60.0f * (4 / div); |
| 143 | } else { |
| 144 | durSec = mSliderDuration.getValue(); |
| 145 | rateSec = 1.0f / mSliderRate.getValue(); |
| 146 | } |
| 147 | |
| 148 | float envWidth = (durSec / WINDOW_SECONDS) * drawRect.getWidth(); |
| 149 | float envOffset = (rateSec / WINDOW_SECONDS) * drawRect.getWidth(); |
| 150 | |
| 151 | float shapeWidth = envWidth * mSliderShape.getValue() / 2.0f; |
| 152 | |
| 153 | juce::Path clipPath; |
| 154 | clipPath.addRectangle(drawRect); |
| 155 | auto envBounds = drawRect.reduced(2, 2); |
| 156 | |
| 157 | // Draw darker odd numbered envelopes |
| 158 | float tiltWidth = (envWidth * 0.5f) + (mSliderTilt.getValue() * envWidth * 0.5f); |
| 159 | float curXStart = envBounds.getX() + envOffset; |
| 160 | juce::Colour envColour = colour.darker(0.5f); |
| 161 | while (curXStart < envBounds.getWidth()) { |
| 162 | juce::Path envPath; |
| 163 | juce::Point<float> lastPt = juce::Point<float>(curXStart, envBounds.getBottom()); |
| 164 | juce::Point<float> pt = juce::Point<float>(juce::jmax(curXStart, curXStart + tiltWidth - shapeWidth), envBounds.getY()); |
| 165 | envPath.addLineSegment(clipPath.getClippedLine(juce::Line(lastPt, pt), false), 1.0f); |
| 166 | lastPt = pt; |
| 167 | pt = juce::Point<float>(juce::jmin(curXStart + envWidth, curXStart + tiltWidth + shapeWidth), envBounds.getY()); |
| 168 | envPath.addLineSegment(clipPath.getClippedLine(juce::Line(lastPt, pt), false), 1.0f); |
| 169 | lastPt = pt; |
| 170 | pt = juce::Point<float>(curXStart + envWidth, envBounds.getBottom()); |
| 171 | envPath.addLineSegment(clipPath.getClippedLine(juce::Line(lastPt, pt), false), 1.0f); |
| 172 | g.setColour(envColour); |
| 173 | g.strokePath(envPath.createPathWithRoundedCorners(5), mPathStroke); |
| 174 | curXStart += (envOffset * 2.0f); |
| 175 | } |
| 176 | curXStart = envBounds.getX(); |
| 177 | // Draw brighter even numbered envelopes |
| 178 | envColour = colour.brighter(0.5f); |
| 179 | while (curXStart < envBounds.getWidth()) { |
| 180 | juce::Path envPath; |
nothing calls this directly
no outgoing calls
no test coverage detected