diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index fbb9bf8..f5b9766 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -168,8 +168,8 @@ void VuMeter::paint(juce::Graphics& g) { clipPath.addRoundedRectangle(bounds, 9.0f); g.reduceClipRegion(clipPath); - juce::ColourGradient grad(juce::Colour(0xff00cc44).withAlpha(0.4f), 0.0f, bounds.getBottom(), - juce::Colour(0xffcc2200).withAlpha(0.4f), 0.0f, bounds.getY(), false); + juce::ColourGradient grad(juce::Colour(0xff00cc44).withAlpha(0.7f), 0.0f, bounds.getBottom(), + juce::Colour(0xffcc2200).withAlpha(0.7f), 0.0f, bounds.getY(), false); g.setGradientFill(grad); g.fillRoundedRectangle(innerBar, 2.0f); } @@ -230,8 +230,8 @@ void WaveformDisplay::paint(juce::Graphics& g) { clipPath.addRoundedRectangle(bounds, 9.0f); g.reduceClipRegion(clipPath); - juce::ColourGradient waveGrad(juce::Colour(0xff00ff88).withAlpha(0.33f), 0.0f, bounds.getY(), - juce::Colour(0xff005522).withAlpha(0.12f), 0.0f, bounds.getBottom(), false); + juce::ColourGradient waveGrad(juce::Colour(0xff00ff88).withAlpha(0.5f), 0.0f, bounds.getY(), + juce::Colour(0xff005522).withAlpha(0.4f), 0.0f, bounds.getBottom(), false); g.setGradientFill(waveGrad); g.fillPath(filledPath); @@ -309,7 +309,7 @@ void SpectrumAnalyzer::paint(juce::Graphics& g) { float bx = x + 1.0f; float by = barBottom - barH; - g.setColour(juce::Colour(0xff00ff88).withAlpha(0.3f)); + g.setColour(juce::Colour(0xff00ff88).withAlpha(0.4f)); g.fillRect(bx, by, bw, barH); } @@ -1126,7 +1126,7 @@ void PianoRollComponent::paint(juce::Graphics& g) { bool pressed = processor.isNoteActive(note); if (pressed) { - g.setColour(juce::Colour(0xffccaa44).withAlpha(0.8f)); + g.setColour(juce::Colour(0xffccaa44).withAlpha(0.7f)); } else { juce::ColourGradient grad(juce::Colour(0xffe4e4e4).withAlpha(0.7f), static_cast(kx), 0.0f, juce::Colour(0xffc8c8c8).withAlpha(0.7f), static_cast(kx), static_cast(whiteKeyHeight), false); @@ -1179,12 +1179,9 @@ void PianoRollComponent::paint(juce::Graphics& g) { void PianoRollComponent::mouseDown(const juce::MouseEvent& e) { auto pos = e.getPosition(); - // Pitch bend strip + // Pitch bend strip: ignore plain clicks — require a vertical drag (see mouseDrag) if (pos.x < pitchBendWidth) { - float pbNorm = 1.0f - static_cast(pos.y) / static_cast(whiteKeyHeight); - pbNorm = std::clamp(pbNorm, -1.0f, 1.0f); - currentPitchBend = 64 + static_cast(pbNorm * 64.0f); - processor.pitchBendValue.store(pbNorm); + pitchBendDragging = false; return; } @@ -1199,14 +1196,13 @@ void PianoRollComponent::mouseDown(const juce::MouseEvent& e) { } void PianoRollComponent::mouseUp(const juce::MouseEvent& e) { - // Reset pitch bend to center on release - if (e.getPosition().x < pitchBendWidth || lastTriggeredNote < 0) { - if (e.getPosition().x < pitchBendWidth) { - currentPitchBend = 64; - processor.pitchBendValue.store(0.0f); - repaint(); - } - if (lastTriggeredNote < 0) return; + // Reset pitch bend to center on release (only if it was actually dragged) + if (pitchBendDragging) { + pitchBendDragging = false; + pitchBendGliding = true; + pitchBendGlideStart = static_cast(currentPitchBend - 64) / 64.0f; + pitchBendGlideStartMs = juce::Time::currentTimeMillis(); + repaint(); } if (lastTriggeredNote >= 0) { @@ -1216,12 +1212,33 @@ void PianoRollComponent::mouseUp(const juce::MouseEvent& e) { } } +void PianoRollComponent::timerCallback() { + if (pitchBendGliding) { + float t = static_cast(juce::Time::currentTimeMillis() - pitchBendGlideStartMs) + / static_cast(pitchBendGlideMs); + if (t >= 1.0f) { + pitchBendGliding = false; + currentPitchBend = 64; + processor.pitchBendValue.store(0.0f); + } else { + float pbNorm = pitchBendGlideStart * (1.0f - t); + currentPitchBend = 64 + static_cast(pbNorm * 64.0f); + processor.pitchBendValue.store(pbNorm); + } + repaint(); + } else { + repaint(); + } +} + void PianoRollComponent::mouseDrag(const juce::MouseEvent& e) { auto pos = e.getPosition(); - // Pitch bend drag + // Pitch bend drag — only while touching the strip if (pos.x < pitchBendWidth) { - float pbNorm = 1.0f - static_cast(pos.y) / static_cast(whiteKeyHeight); + pitchBendDragging = true; + pitchBendGliding = false; + float pbNorm = 1.0f - 2.0f * static_cast(pos.y) / static_cast(whiteKeyHeight); pbNorm = std::clamp(pbNorm, -1.0f, 1.0f); currentPitchBend = 64 + static_cast(pbNorm * 64.0f); processor.pitchBendValue.store(pbNorm); diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index b954375..c352733 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -65,9 +65,9 @@ private: class PianoRollComponent : public juce::Component, public juce::Timer { public: - explicit PianoRollComponent(ChromaFlockProcessor& p) : processor(p) { startTimerHz(30); } + explicit PianoRollComponent(ChromaFlockProcessor& p) : processor(p) { startTimerHz(60); } void paint(juce::Graphics& g) override; - void timerCallback() override { repaint(); } + void timerCallback() override; void mouseDown(const juce::MouseEvent& e) override; void mouseUp(const juce::MouseEvent& e) override; void mouseDrag(const juce::MouseEvent& e) override; @@ -91,6 +91,12 @@ private: int lastTriggeredNote = -1; int currentPitchBend = 64; // 0..127, 64 = center + bool pitchBendDragging = false; + + bool pitchBendGliding = false; + float pitchBendGlideStart = 0.0f; + juce::int64 pitchBendGlideStartMs = 0; + static constexpr int pitchBendGlideMs = 50; }; class MainContentComponent : public juce::Component { diff --git a/bg.png b/bg.png index 429be9c..5124c34 100644 Binary files a/bg.png and b/bg.png differ diff --git a/newlogo.png-autosave.kra b/newlogo.png-autosave.kra deleted file mode 100644 index b85f3c0..0000000 Binary files a/newlogo.png-autosave.kra and /dev/null differ