mirror of
https://codeberg.org/armin/justasample.git
synced 2026-09-01 20:30:48 +02:00
125 lines
3.3 KiB
C
125 lines
3.3 KiB
C
|
|
/*
|
||
|
|
==============================================================================
|
||
|
|
|
||
|
|
RangeSelection.h
|
||
|
|
Created: 16 May 2024 8:28:47pm
|
||
|
|
Author: binya
|
||
|
|
|
||
|
|
==============================================================================
|
||
|
|
*/
|
||
|
|
|
||
|
|
#pragma once
|
||
|
|
|
||
|
|
#include <JuceHeader.h>
|
||
|
|
|
||
|
|
#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<void(int startPos, int endPos)>& 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<int>(getX(), getRight(), event.x);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void mouseDrag(const juce::MouseEvent& event) override
|
||
|
|
{
|
||
|
|
if (isSelecting && draggingStarted)
|
||
|
|
{
|
||
|
|
endLoc = juce::jlimit<int>(getX(), getRight(), event.x);
|
||
|
|
repaint();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void mouseUp(const juce::MouseEvent& event) override
|
||
|
|
{
|
||
|
|
if (isSelecting && draggingStarted)
|
||
|
|
{
|
||
|
|
endLoc = juce::jlimit<int>(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<void(int, int)> onSelectedCallback;
|
||
|
|
|
||
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RangeSelector)
|
||
|
|
};
|