mirror of
https://codeberg.org/armin/monoslicer.git
synced 2026-09-01 12:10:46 +02:00
Move scroll buttons to title bar, add build info status bar
- Replace broken bottom waveform scroll buttons with title bar < > buttons - Add scrollLeft()/scrollRight() methods to WaveformDisplay - Add status bar showing git branch, commit, dirty state, and build timestamp - Inject git version info via CMake at configure time - Enable COPY_PLUGIN_AFTER_BUILD - Increase baseHeight by 20px for status bar
This commit is contained in:
parent
9b7c973622
commit
93c8c73399
5 changed files with 93 additions and 24 deletions
|
|
@ -17,7 +17,7 @@ juce_add_plugin(Monoslicer
|
||||||
NEEDS_MIDI_OUTPUT FALSE
|
NEEDS_MIDI_OUTPUT FALSE
|
||||||
IS_MIDI_EFFECT FALSE
|
IS_MIDI_EFFECT FALSE
|
||||||
EDITOR_WANTS_KEYBOARD_FOCUS TRUE
|
EDITOR_WANTS_KEYBOARD_FOCUS TRUE
|
||||||
COPY_PLUGIN_AFTER_BUILD FALSE
|
COPY_PLUGIN_AFTER_BUILD TRUE
|
||||||
VST3_CATEGORIES Instrument Sampler
|
VST3_CATEGORIES Instrument Sampler
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -29,10 +29,54 @@ target_sources(Monoslicer PRIVATE
|
||||||
Source/PianoRollDisplay.cpp
|
Source/PianoRollDisplay.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND git rev-parse --short HEAD
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
ERROR_QUIET
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT GIT_COMMIT_HASH)
|
||||||
|
set(GIT_COMMIT_HASH "unknown")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND git symbolic-ref --short HEAD
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE GIT_BRANCH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
ERROR_QUIET
|
||||||
|
)
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND git diff --quiet HEAD
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
RESULT_VARIABLE GIT_DIRTY_RESULT
|
||||||
|
)
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND git diff --cached --quiet
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
RESULT_VARIABLE GIT_CACHED_DIRTY_RESULT
|
||||||
|
)
|
||||||
|
|
||||||
|
set(GIT_DIRTY "")
|
||||||
|
if(NOT GIT_DIRTY_RESULT EQUAL 0 OR NOT GIT_CACHED_DIRTY_RESULT EQUAL 0)
|
||||||
|
set(GIT_DIRTY "-dirty")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(GIT_BRANCH)
|
||||||
|
set(GIT_VERSION "${GIT_BRANCH} @ ${GIT_COMMIT_HASH}${GIT_DIRTY}")
|
||||||
|
else()
|
||||||
|
set(GIT_VERSION "detached @ ${GIT_COMMIT_HASH}${GIT_DIRTY}")
|
||||||
|
endif()
|
||||||
|
|
||||||
target_compile_definitions(Monoslicer PUBLIC
|
target_compile_definitions(Monoslicer PUBLIC
|
||||||
JUCE_WEB_BROWSER=0
|
JUCE_WEB_BROWSER=0
|
||||||
JUCE_USE_CURL=0
|
JUCE_USE_CURL=0
|
||||||
JUCE_VST3_CAN_REPLACE_VST2=0
|
JUCE_VST3_CAN_REPLACE_VST2=0
|
||||||
|
GIT_VERSION="${GIT_VERSION}"
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(Monoslicer
|
target_link_libraries(Monoslicer
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ MonoslicerEditor::MonoslicerEditor(MonoslicerProcessor& p)
|
||||||
setupTitleBtn(zoomInButton, "Zoom In");
|
setupTitleBtn(zoomInButton, "Zoom In");
|
||||||
setupTitleBtn(zoomOutButton, "Zoom Out");
|
setupTitleBtn(zoomOutButton, "Zoom Out");
|
||||||
setupTitleBtn(zoomResetButton, "Reset Zoom");
|
setupTitleBtn(zoomResetButton, "Reset Zoom");
|
||||||
|
setupTitleBtn(scrollLeftButton, "Scroll waveform left");
|
||||||
|
setupTitleBtn(scrollRightButton, "Scroll waveform right");
|
||||||
|
|
||||||
addAndMakeVisible(scaleComboBox);
|
addAndMakeVisible(scaleComboBox);
|
||||||
scaleComboBox.addItem("75%", 1);
|
scaleComboBox.addItem("75%", 1);
|
||||||
|
|
@ -55,6 +57,14 @@ MonoslicerEditor::MonoslicerEditor(MonoslicerProcessor& p)
|
||||||
|
|
||||||
addAndMakeVisible(waveformDisplay);
|
addAndMakeVisible(waveformDisplay);
|
||||||
|
|
||||||
|
// Status bar
|
||||||
|
addAndMakeVisible(statusBar);
|
||||||
|
statusBar.setText("Build: " GIT_VERSION " (" __DATE__ ", " __TIME__ ")",
|
||||||
|
juce::dontSendNotification);
|
||||||
|
statusBar.setColour(juce::Label::textColourId, juce::Colour(0xff666688));
|
||||||
|
statusBar.setFont(juce::Font(juce::FontOptions(11.0f)));
|
||||||
|
statusBar.setJustificationType(juce::Justification::centredRight);
|
||||||
|
|
||||||
// Slice knobs
|
// Slice knobs
|
||||||
attachSlider(bassSlider, bassLabel, "Bass", "bass", bassAttachment);
|
attachSlider(bassSlider, bassLabel, "Bass", "bass", bassAttachment);
|
||||||
attachSlider(trebleSlider, trebleLabel, "Treble", "treble", trebleAttachment);
|
attachSlider(trebleSlider, trebleLabel, "Treble", "treble", trebleAttachment);
|
||||||
|
|
@ -197,6 +207,8 @@ MonoslicerEditor::~MonoslicerEditor()
|
||||||
zoomInButton.removeListener(this);
|
zoomInButton.removeListener(this);
|
||||||
zoomOutButton.removeListener(this);
|
zoomOutButton.removeListener(this);
|
||||||
zoomResetButton.removeListener(this);
|
zoomResetButton.removeListener(this);
|
||||||
|
scrollLeftButton.removeListener(this);
|
||||||
|
scrollRightButton.removeListener(this);
|
||||||
stretchButton.removeListener(this);
|
stretchButton.removeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -242,6 +254,8 @@ void MonoslicerEditor::resized()
|
||||||
|
|
||||||
auto bounds = getLocalBounds();
|
auto bounds = getLocalBounds();
|
||||||
auto titleBar = bounds.removeFromTop(40);
|
auto titleBar = bounds.removeFromTop(40);
|
||||||
|
auto statusBarArea = bounds.removeFromBottom(18).withTrimmedRight(5);
|
||||||
|
statusBar.setBounds(statusBarArea);
|
||||||
|
|
||||||
int tx = 120;
|
int tx = 120;
|
||||||
|
|
||||||
|
|
@ -263,6 +277,9 @@ void MonoslicerEditor::resized()
|
||||||
placeBtn(zoomOutButton, 28);
|
placeBtn(zoomOutButton, 28);
|
||||||
placeBtn(zoomResetButton, 32);
|
placeBtn(zoomResetButton, 32);
|
||||||
placeBtn(zoomInButton, 28);
|
placeBtn(zoomInButton, 28);
|
||||||
|
tx += 6;
|
||||||
|
placeBtn(scrollLeftButton, 24);
|
||||||
|
placeBtn(scrollRightButton, 24);
|
||||||
|
|
||||||
scaleComboBox.setBounds(titleBar.getRight() - 100, titleBar.getY() + 8, 90, 24);
|
scaleComboBox.setBounds(titleBar.getRight() - 100, titleBar.getY() + 8, 90, 24);
|
||||||
octaveComboBox.setBounds(titleBar.getRight() - 176, titleBar.getY() + 8, 72, 24);
|
octaveComboBox.setBounds(titleBar.getRight() - 176, titleBar.getY() + 8, 72, 24);
|
||||||
|
|
@ -446,6 +463,14 @@ void MonoslicerEditor::buttonClicked(juce::Button* button)
|
||||||
{
|
{
|
||||||
waveformDisplay.zoomReset();
|
waveformDisplay.zoomReset();
|
||||||
}
|
}
|
||||||
|
else if (button == &scrollLeftButton)
|
||||||
|
{
|
||||||
|
waveformDisplay.scrollLeft();
|
||||||
|
}
|
||||||
|
else if (button == &scrollRightButton)
|
||||||
|
{
|
||||||
|
waveformDisplay.scrollRight();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MonoslicerEditor::comboBoxChanged(juce::ComboBox* comboBoxThatHasChanged)
|
void MonoslicerEditor::comboBoxChanged(juce::ComboBox* comboBoxThatHasChanged)
|
||||||
|
|
|
||||||
|
|
@ -41,11 +41,13 @@ private:
|
||||||
juce::TextButton zoomInButton { "+" };
|
juce::TextButton zoomInButton { "+" };
|
||||||
juce::TextButton zoomOutButton { "-" };
|
juce::TextButton zoomOutButton { "-" };
|
||||||
juce::TextButton zoomResetButton { "1:1" };
|
juce::TextButton zoomResetButton { "1:1" };
|
||||||
|
juce::TextButton scrollLeftButton { "<" };
|
||||||
|
juce::TextButton scrollRightButton { ">" };
|
||||||
juce::ComboBox scaleComboBox;
|
juce::ComboBox scaleComboBox;
|
||||||
juce::ComboBox octaveComboBox;
|
juce::ComboBox octaveComboBox;
|
||||||
|
|
||||||
static constexpr int baseWidth = 1100;
|
static constexpr int baseWidth = 1100;
|
||||||
static constexpr int baseHeight = 550;
|
static constexpr int baseHeight = 570;
|
||||||
|
|
||||||
// Slice knobs
|
// Slice knobs
|
||||||
juce::Slider bassSlider, trebleSlider, sensitivitySlider;
|
juce::Slider bassSlider, trebleSlider, sensitivitySlider;
|
||||||
|
|
@ -88,6 +90,7 @@ private:
|
||||||
std::unique_ptr<ComboBoxAttachment> filterTypeAttachment;
|
std::unique_ptr<ComboBoxAttachment> filterTypeAttachment;
|
||||||
|
|
||||||
juce::FileChooser fileChooser { "Load Audio File", juce::File{}, "*.wav;*.aiff;*.flac;*.ogg" };
|
juce::FileChooser fileChooser { "Load Audio File", juce::File{}, "*.wav;*.aiff;*.flac;*.ogg" };
|
||||||
|
juce::Label statusBar;
|
||||||
|
|
||||||
void setupSlider(juce::Slider& slider, juce::Label& label, const juce::String& name);
|
void setupSlider(juce::Slider& slider, juce::Label& label, const juce::String& name);
|
||||||
void attachSlider(juce::Slider& slider, juce::Label& label, const juce::String& name,
|
void attachSlider(juce::Slider& slider, juce::Label& label, const juce::String& name,
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,6 @@ WaveformDisplay::WaveformDisplay(SliceManager& sm) : sliceManager(sm)
|
||||||
hScrollBar.setRangeLimits(0.0, 1.0);
|
hScrollBar.setRangeLimits(0.0, 1.0);
|
||||||
hScrollBar.setCurrentRange(0.0, 1.0);
|
hScrollBar.setCurrentRange(0.0, 1.0);
|
||||||
|
|
||||||
auto setupScrollBtn = [this](juce::TextButton& btn) {
|
|
||||||
addAndMakeVisible(btn);
|
|
||||||
btn.setColour(juce::TextButton::buttonColourId, juce::Colour(0xff2a2a4a));
|
|
||||||
};
|
|
||||||
setupScrollBtn(scrollLeftBtn);
|
|
||||||
setupScrollBtn(scrollRightBtn);
|
|
||||||
|
|
||||||
startTimerHz(30);
|
startTimerHz(30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,6 +60,22 @@ void WaveformDisplay::zoomReset()
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WaveformDisplay::scrollLeft()
|
||||||
|
{
|
||||||
|
scrollOffset -= 1.0f / zoomFactor;
|
||||||
|
scrollOffset = juce::jlimit(0.0f, 1.0f, scrollOffset);
|
||||||
|
syncScrollBar();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveformDisplay::scrollRight()
|
||||||
|
{
|
||||||
|
scrollOffset += 1.0f / zoomFactor;
|
||||||
|
scrollOffset = juce::jlimit(0.0f, 1.0f, scrollOffset);
|
||||||
|
syncScrollBar();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
void WaveformDisplay::syncScrollBar()
|
void WaveformDisplay::syncScrollBar()
|
||||||
{
|
{
|
||||||
if (updatingScroll) return;
|
if (updatingScroll) return;
|
||||||
|
|
@ -209,7 +218,6 @@ void WaveformDisplay::paint(juce::Graphics& g)
|
||||||
g.setColour(juce::Colours::grey);
|
g.setColour(juce::Colours::grey);
|
||||||
g.setFont(14.0f);
|
g.setFont(14.0f);
|
||||||
g.drawText("No audio file loaded.", textArea, juce::Justification::centred);
|
g.drawText("No audio file loaded.", textArea, juce::Justification::centred);
|
||||||
hScrollBar.setBounds(bounds.removeFromBottom(scrollbarHeight).toNearestInt());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -225,13 +233,6 @@ void WaveformDisplay::paint(juce::Graphics& g)
|
||||||
auto waveArea = waveBounds.withTrimmedLeft(keyWidth);
|
auto waveArea = waveBounds.withTrimmedLeft(keyWidth);
|
||||||
drawWaveform(g, waveArea);
|
drawWaveform(g, waveArea);
|
||||||
drawSliceMarkers(g, waveArea);
|
drawSliceMarkers(g, waveArea);
|
||||||
|
|
||||||
// Scrollbar at bottom
|
|
||||||
hScrollBar.setBounds(juce::Rectangle<int>(
|
|
||||||
static_cast<int>(bounds.getBottomLeft().getX()),
|
|
||||||
static_cast<int>(bounds.getBottom() - scrollbarHeight),
|
|
||||||
static_cast<int>(bounds.getWidth()),
|
|
||||||
static_cast<int>(scrollbarHeight)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaveformDisplay::drawKeys(juce::Graphics& g, juce::Rectangle<float> bounds)
|
void WaveformDisplay::drawKeys(juce::Graphics& g, juce::Rectangle<float> bounds)
|
||||||
|
|
@ -531,10 +532,7 @@ void WaveformDisplay::resized()
|
||||||
{
|
{
|
||||||
auto bounds = getLocalBounds();
|
auto bounds = getLocalBounds();
|
||||||
auto scrollBarRow = bounds.removeFromBottom(static_cast<int>(scrollbarHeight));
|
auto scrollBarRow = bounds.removeFromBottom(static_cast<int>(scrollbarHeight));
|
||||||
scrollLeftBtn.setBounds(scrollBarRow.getX(), scrollBarRow.getY(), scrollBtnWidth, scrollBarRow.getHeight());
|
hScrollBar.setBounds(scrollBarRow);
|
||||||
scrollRightBtn.setBounds(scrollBarRow.getRight() - scrollBtnWidth, scrollBarRow.getY(), scrollBtnWidth, scrollBarRow.getHeight());
|
|
||||||
hScrollBar.setBounds(scrollBarRow.getX() + scrollBtnWidth, scrollBarRow.getY(),
|
|
||||||
scrollBarRow.getWidth() - scrollBtnWidth * 2, scrollBarRow.getHeight());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaveformDisplay::mouseDown(const juce::MouseEvent& e)
|
void WaveformDisplay::mouseDown(const juce::MouseEvent& e)
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ public:
|
||||||
void zoomIn();
|
void zoomIn();
|
||||||
void zoomOut();
|
void zoomOut();
|
||||||
void zoomReset();
|
void zoomReset();
|
||||||
|
void scrollLeft();
|
||||||
|
void scrollRight();
|
||||||
|
|
||||||
int xToSample(int x) const;
|
int xToSample(int x) const;
|
||||||
int sampleToX(int sample) const;
|
int sampleToX(int sample) const;
|
||||||
|
|
@ -63,10 +65,7 @@ private:
|
||||||
std::function<void(int)> onKeyClick;
|
std::function<void(int)> onKeyClick;
|
||||||
|
|
||||||
juce::ScrollBar hScrollBar { false };
|
juce::ScrollBar hScrollBar { false };
|
||||||
juce::TextButton scrollLeftBtn { "<" };
|
|
||||||
juce::TextButton scrollRightBtn { ">" };
|
|
||||||
bool updatingScroll = false;
|
bool updatingScroll = false;
|
||||||
static constexpr int scrollBtnWidth = 16;
|
|
||||||
|
|
||||||
juce::AudioBuffer<float> overviewBuffer;
|
juce::AudioBuffer<float> overviewBuffer;
|
||||||
bool overviewDirty = true;
|
bool overviewDirty = true;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue