diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index 2a2a59b..8e34e15 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -574,6 +574,14 @@ void TrommelkisteEditor::paint(Graphics& g) g.setColour(lnf.accent.withAlpha(alpha)); g.fillRect(scaled(0), scaled(ry + 4), scaled(3), scaled(ROW_H - 8)); } + + if (i == dropHoverIndex) + { + g.setColour(lnf.accent.withAlpha(0.25f)); + g.fillRect(scaled(COL_FILE), scaled(ry), scaled(COL_DELAY - 8 - COL_FILE), scaled(ROW_H)); + g.setColour(lnf.accent); + g.drawRect(scaled(COL_FILE), scaled(ry), scaled(COL_DELAY - 8 - COL_FILE), scaled(ROW_H), scaled(2)); + } } } @@ -653,3 +661,80 @@ void TrommelkisteEditor::mouseDown(const MouseEvent& event) } } } + +// ── Drag & drop ──────────────────────────────────────────────── + +int TrommelkisteEditor::getSlotIndexForPosition(int x, int y) const +{ + for (int i = 0; i < NUM_TRACKS; ++i) + { + const int ry = scaled(TOP + i * ROW_H); + if (y >= ry && y < ry + scaled(ROW_H)) + { + if (x >= scaled(COL_FILE) && x < scaled(COL_DELAY - 8)) + return i; + return -1; + } + } + return -1; +} + +bool TrommelkisteEditor::isInterestedInFileDrag(const StringArray& files) +{ + for (const auto& f : files) + { + const File file(f); + if (file.hasFileExtension("wav;aiff;aif;flac")) + return true; + } + return false; +} + +void TrommelkisteEditor::fileDragEnter(const StringArray& files, int x, int y) +{ + fileDragMove(files, x, y); +} + +void TrommelkisteEditor::fileDragMove(const StringArray&, int x, int y) +{ + const int newIndex = getSlotIndexForPosition(x, y); + if (newIndex != dropHoverIndex) + { + dropHoverIndex = newIndex; + repaint(); + } +} + +void TrommelkisteEditor::fileDragExit(const StringArray&) +{ + if (dropHoverIndex != -1) + { + dropHoverIndex = -1; + repaint(); + } +} + +void TrommelkisteEditor::filesDropped(const StringArray& files, int x, int y) +{ + if (dropHoverIndex != -1) + { + dropHoverIndex = -1; + repaint(); + } + + const int idx = getSlotIndexForPosition(x, y); + if (idx < 0) + return; + + for (const auto& f : files) + { + const File file(f); + if (file.hasFileExtension("wav;aiff;aif;flac")) + { + proc.loadSample(idx, file); + proc.currentSampleIndex[idx] = -1; + ui[idx].fileLabel.setText(file.getFileNameWithoutExtension(), dontSendNotification); + break; + } + } +} diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index 33f8b07..c69ee23 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -30,7 +30,8 @@ struct KnobSlider : juce::Slider } }; -class TrommelkisteEditor : public juce::AudioProcessorEditor, private juce::Timer +class TrommelkisteEditor : public juce::AudioProcessorEditor, private juce::Timer, + public juce::FileDragAndDropTarget { public: TrommelkisteEditor(TrommelkisteProcessor&); @@ -97,6 +98,8 @@ private: void loadForTrack(int idx); void updateFileLabel(int idx); void refreshPresetCombo(); + int getSlotIndexForPosition(int x, int y) const; + int dropHoverIndex = -1; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TrommelkisteEditor) };