/* ============================================================================== RangeSelection.h Created: 16 May 2024 8:28:47pm Author: binya ============================================================================== */ #pragma once #include #include "../Utilities/ComponentUtils.h" /** A component that allows the user to select a range of a display */ class RangeSelector final : public CustomComponent { public: RangeSelector() { cancelRangeSelect(); } /** Begin the range selection prompt */ void promptRangeSelect(const std::function& onCloseCallback = {}) { isSelecting = true; draggingStarted = false; onSelectedCallback = onCloseCallback; setVisible(true); setInterceptsMouseClicks(true, false); resized(); } /** Cancel the prompt */ void cancelRangeSelect() { isSelecting = false; setVisible(false); setInterceptsMouseClicks(false, false); resized(); } bool isSelectingRange() const { return isSelecting; } private: void paint(juce::Graphics& g) override { if (!isSelecting) return; auto colors = getTheme(); if (draggingStarted) { int x = juce::jmin(startLoc, endLoc); int width = juce::jmax(startLoc, endLoc) - x; g.setColour(colors.slate.withAlpha(0.15f)); g.fillRect(x, 0, width, getHeight()); g.setColour(colors.slate); g.fillRect(float(startLoc), 0.f, getWidth() * Layout::boundsWidth / 2.f, float(getHeight())); g.fillRect(float(endLoc), 0.f, getWidth() * Layout::boundsWidth / 2.f, float(getHeight())); } else { int mousePos = getMouseXYRelative().getX(); g.setColour(colors.slate); g.fillRect(float(mousePos), 0.f, getWidth() * Layout::boundsWidth / 2.f, float(getHeight())); } } void mouseDown(const juce::MouseEvent& event) override { if (isSelecting && !draggingStarted) { draggingStarted = true; startLoc = endLoc = juce::jlimit(getX(), getRight(), event.x); } } void mouseDrag(const juce::MouseEvent& event) override { if (isSelecting && draggingStarted) { endLoc = juce::jlimit(getX(), getRight(), event.x); repaint(); } } void mouseUp(const juce::MouseEvent& event) override { if (isSelecting && draggingStarted) { endLoc = juce::jlimit(getX(), getRight(), event.x); int leftLoc = juce::jmin(startLoc, endLoc); int rightLoc = juce::jmax(startLoc, endLoc); cancelRangeSelect(); // To hide the component onSelectedCallback(leftLoc, rightLoc); } } void mouseMove(const juce::MouseEvent&) override { repaint(); } //============================================================================== bool isSelecting{ false }; bool draggingStarted{ false }; int startLoc{ 0 }, endLoc{ 0 }; std::function onSelectedCallback; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RangeSelector) };