mirror of
https://codeberg.org/armin/monoslicer.git
synced 2026-09-01 12:10:46 +02:00
86 lines
3 KiB
C++
86 lines
3 KiB
C++
#pragma once
|
|
#include <juce_audio_processors/juce_audio_processors.h>
|
|
#include "SliceManager.h"
|
|
#include <functional>
|
|
|
|
class WaveformDisplay : public juce::Component,
|
|
public juce::Timer,
|
|
private juce::ScrollBar::Listener
|
|
{
|
|
public:
|
|
static constexpr float keyWidth = 50.0f;
|
|
static constexpr float scrollbarHeight = 14.0f;
|
|
|
|
WaveformDisplay(SliceManager& sm);
|
|
~WaveformDisplay() override;
|
|
|
|
void paint(juce::Graphics& g) override;
|
|
void resized() override;
|
|
void timerCallback() override;
|
|
|
|
void mouseDown(const juce::MouseEvent& e) override;
|
|
void mouseDrag(const juce::MouseEvent& e) override;
|
|
void mouseUp(const juce::MouseEvent& e) override;
|
|
void mouseMove(const juce::MouseEvent& e) override;
|
|
void mouseWheelMove(const juce::MouseEvent& e, const juce::MouseWheelDetails& wheel) override;
|
|
|
|
void setSampleBuffer(const juce::AudioBuffer<float>* buffer, double sampleRate);
|
|
void setPlaybackPosition(int sample);
|
|
void setActiveSliceIndex(int index);
|
|
void setSelectedSlice(int index);
|
|
void setOnEmptyAreaClick(std::function<void()> callback);
|
|
void setOnKeyClick(std::function<void(int noteNumber)> callback);
|
|
|
|
void zoomIn();
|
|
void zoomOut();
|
|
void zoomReset();
|
|
|
|
int xToSample(int x) const;
|
|
int sampleToX(int sample) const;
|
|
float getZoomFactor() const { return zoomFactor; }
|
|
|
|
private:
|
|
void drawKeys(juce::Graphics& g, juce::Rectangle<float> bounds);
|
|
void drawWaveform(juce::Graphics& g, juce::Rectangle<float> bounds);
|
|
void drawSliceMarkers(juce::Graphics& g, juce::Rectangle<float> bounds);
|
|
void drawRuler(juce::Graphics& g, juce::Rectangle<float> bounds);
|
|
void scrollBarMoved(juce::ScrollBar* scrollBarThatHasMoved, double newRangeStart) override;
|
|
void syncScrollBar();
|
|
|
|
SliceManager& sliceManager;
|
|
const juce::AudioBuffer<float>* sampleBuffer = nullptr;
|
|
double sampleRate = 44100.0;
|
|
|
|
float zoomFactor = 1.0f;
|
|
float scrollOffset = 0.0f;
|
|
int playbackSample = -1;
|
|
int activeSliceIndex = -1;
|
|
int selectedSliceIndex = -1;
|
|
int draggingSliceIndex = -1;
|
|
int hoveredSliceIndex = -1;
|
|
|
|
std::function<void()> onEmptyAreaClick;
|
|
std::function<void(int)> onKeyClick;
|
|
|
|
juce::ScrollBar hScrollBar { false };
|
|
juce::TextButton scrollLeftBtn { "<" };
|
|
juce::TextButton scrollRightBtn { ">" };
|
|
bool updatingScroll = false;
|
|
static constexpr int scrollBtnWidth = 16;
|
|
|
|
juce::AudioBuffer<float> overviewBuffer;
|
|
bool overviewDirty = true;
|
|
static constexpr int overviewResolution = 2048;
|
|
|
|
void rebuildOverview();
|
|
int getNumSamples() const { return sampleBuffer ? sampleBuffer->getNumSamples() : 0; }
|
|
int getVisibleStart() const;
|
|
int getVisibleEnd() const;
|
|
juce::Rectangle<float> getWaveformArea() const;
|
|
|
|
int keyRowToMidiNote(int row) const;
|
|
int midiNoteToSliceIndex(int note) const;
|
|
int findNearestSliceAtPixel(int pixelX, int tolerancePx) const;
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(WaveformDisplay)
|
|
};
|