Skip to content

Commit

Permalink
use manhattan distance for envelope point selection
Browse files Browse the repository at this point in the history
  • Loading branch information
charbeljc committed Jun 15, 2021
1 parent 9ed1c7d commit 8b4c80a
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 52 deletions.
118 changes: 66 additions & 52 deletions src/gui/src/SampleEditor/TargetWaveDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ TargetWaveDisplay::TargetWaveDisplay(QWidget* pParent)
m_nY = -10;
m_nLocator = -1;
m_UpdatePosition = false;
m_nSelectedEnvelopePoint = -1;
m_nSnapRadius = 6;
setMouseTracking(true);
}

Expand All @@ -83,15 +85,14 @@ TargetWaveDisplay::~TargetWaveDisplay()
}

static void envelope_paint(Sample::VelocityEnvelope &envelope, QPainter &painter,
bool selection, int mouseX, int VCenter, int LCenter, int RCenter,
const QColor & lineColor, const QColor & handleColor, const QColor & selectedColor)
int selected, const QColor & lineColor, const QColor & handleColor, const QColor & selectedColor)
{
if (envelope.empty())
return;
for ( int i = 0; i < static_cast<int>(envelope.size()) -1; i++){
painter.setPen( QPen(lineColor, 1 , Qt::SolidLine) );
painter.drawLine( envelope[i]->frame, envelope[i]->value, envelope[i + 1]->frame, envelope[i +1]->value );
if (selection && envelope[i]->frame >= mouseX - 3 && envelope[i]->frame <= mouseX + 3)
if ( i == selected )
painter.setBrush( selectedColor );
else
painter.setBrush( handleColor );
Expand Down Expand Up @@ -140,11 +141,11 @@ void TargetWaveDisplay::paintEvent(QPaintEvent *ev)
QColor selectedtHandleColor = QColor( 255, 100, 90 );
//volume line

envelope_paint(m_VelocityEnvelope, painter, m_EditMode == TargetWaveDisplay::VELOCITY, m_nX,
VCenter, LCenter, RCenter, volumeLineColor, volumeHandleColor, selectedtHandleColor);
envelope_paint(m_VelocityEnvelope, painter, m_EditMode == TargetWaveDisplay::VELOCITY ? m_nSelectedEnvelopePoint : -1,
volumeLineColor, volumeHandleColor, selectedtHandleColor);
//pan line
envelope_paint(m_PanEnvelope, painter, m_EditMode == TargetWaveDisplay::PAN, m_nX,
VCenter, LCenter, RCenter, panLineColor, panHandleColor, selectedtHandleColor);
envelope_paint(m_PanEnvelope, painter, m_EditMode == TargetWaveDisplay::PAN ? m_nSelectedEnvelopePoint : -1,
panLineColor, panHandleColor, selectedtHandleColor);

painter.setPen( QPen( QColor( 255, 255, 255 ), 1, Qt::DotLine ) );
painter.drawLine( 0, LCenter, UI_WIDTH, LCenter );
Expand Down Expand Up @@ -239,46 +240,61 @@ void TargetWaveDisplay::updateDisplay( H2Core::InstrumentLayer *pLayer )

}


static bool update_envelope(Sample::VelocityEnvelope & envelope, int x, int y, int snapradius)
static int get_mouse_selected(const Sample::VelocityEnvelope & envelope, int x, int y, int snapradius)
{
int selection = -1;
int min_distance = 1000000;
QPoint mousePoint(x, y);
for ( int i = 0; i < static_cast<int>(envelope.size()); i++){
if ( envelope[i]->frame >= x - snapradius && envelope[i]->frame <= x + snapradius ) {
envelope.erase( envelope.begin() + i);
int Frame = x;
int Value = y;

if ( i == 0 ){
Frame = 0;
} else if ( i == static_cast<int>(envelope.size()) ) {
Frame = UI_WIDTH;
QPoint envelopePoint(envelope[i]->frame, envelope[i]->value);
int delta = (mousePoint - envelopePoint).manhattanLength();
if (delta < min_distance) {
min_distance = delta;
selection = i;
}
envelope.push_back( std::make_unique<EnvelopePoint>( Frame, Value) );
sort( envelope.begin(), envelope.end(), EnvelopePoint::Comparator() );
return true;
}
}
return false;
return selection;
}

static bool update_envelope(Sample::VelocityEnvelope & envelope, int selected, int x, int y, int snapradius)
{
if (selected == -1) {
return false;
}
envelope.erase( envelope.begin() + selected);
if ( selected == 0 ){
x = 0;
} else if ( selected == static_cast<int>(envelope.size()) ) {
x = UI_WIDTH;
}
envelope.push_back( std::make_unique<EnvelopePoint>( x, y ) );
sort( envelope.begin(), envelope.end(), EnvelopePoint::Comparator() );
return true;
}

void TargetWaveDisplay::mouseMoveEvent(QMouseEvent *ev)
{
int snapradius = 10;
m_EditMode = get_current_edit_mode();

Sample::VelocityEnvelope & envelope = (m_EditMode == TargetWaveDisplay::VELOCITY) ? m_VelocityEnvelope : m_PanEnvelope;

m_nX = std::min(UI_WIDTH, std::max(0, ev->x()));
m_nY = std::min(UI_HEIGHT, std::max(0, ev->y()));


if ( ! (ev->buttons() & Qt::LeftButton) ) {
// we are not dragging any point
m_nSelectedEnvelopePoint = get_mouse_selected(envelope, m_nX, m_nY, m_nSnapRadius);
update();
return;
}
float info = (UI_HEIGHT - m_nY) / (float)UI_HEIGHT;
m_sInfo.setNum( info, 'g', 2 );

update_envelope(envelope, m_nX, m_nY, snapradius);
if (update_envelope(envelope, m_nSelectedEnvelopePoint, m_nX, m_nY, m_nSnapRadius)) {
m_nSelectedEnvelopePoint = get_mouse_selected(envelope, m_nX, m_nY, m_nSnapRadius);
}
update();
HydrogenApp::get_instance()->getSampleEditor()->setUnclean();
}
Expand All @@ -287,30 +303,28 @@ void TargetWaveDisplay::mouseMoveEvent(QMouseEvent *ev)

void TargetWaveDisplay::mousePressEvent(QMouseEvent *ev)
{
int SnapRadius = 6;
bool NewPoint = true;
m_EditMode = get_current_edit_mode();

// add new point
Sample::VelocityEnvelope & envelope = (m_EditMode == TargetWaveDisplay::VELOCITY) ? m_VelocityEnvelope : m_PanEnvelope;

///edit envelope points

// test if there is already a point
for ( int i = 0; i < static_cast<int>(envelope.size()); ++i){
if ( envelope[i]->frame >= ev->x() - SnapRadius && envelope[i]->frame <= ev->x() + SnapRadius ){
NewPoint = false;
}
}

int x = std::min(UI_WIDTH, std::max(0, ev->x()));
int y = std::min(UI_HEIGHT, std::max(0, ev->y()));
float info = (UI_HEIGHT - y) / (float)UI_HEIGHT;

m_sInfo.setNum( info, 'g', 2 );

m_nSelectedEnvelopePoint = get_mouse_selected(envelope, m_nX, m_nY, m_nSnapRadius);

///edit envelope points

if (ev->button() == Qt::LeftButton) {
if (NewPoint){
// add or move point
bool NewPoint = false;

if ( m_nSelectedEnvelopePoint == -1 ) {
NewPoint = true;
}

if (NewPoint){
m_nX = x;
m_nY = y;
if (envelope.empty()) {
Expand All @@ -321,31 +335,26 @@ void TargetWaveDisplay::mousePressEvent(QMouseEvent *ev)
}
sort( envelope.begin(), envelope.end(), EnvelopePoint::Comparator() );
} else {
// move old one to new position
update_envelope(envelope, m_nX, m_nY, SnapRadius);
// move old point to new position
update_envelope(envelope, m_nSelectedEnvelopePoint, m_nX, m_nY, m_nSnapRadius);
}
}

//remove point
SnapRadius = 10;
if (ev->button() == Qt::RightButton ) {
} else if (ev->button() == Qt::RightButton ) {
//remove point

if ((x == 0 || x == UI_WIDTH) && envelope.size() > 2) {
// don't remove first and last points if there is more than two points
update();
return;
} else if (envelope.size() == 2) {
// if only 2 points, remove them both
envelope.clear();
} else {
for ( int i = 0; i < static_cast<int>(envelope.size()); i++){
if ( envelope[i]->frame >= x - SnapRadius && envelope[i]->frame <= x + SnapRadius ){
if ( envelope[i]->frame == 0 || envelope[i]->frame == UI_WIDTH)
return;
envelope.erase( envelope.begin() + i);
}
}
envelope.erase( envelope.begin() + m_nSelectedEnvelopePoint );
}
}

m_nSelectedEnvelopePoint = get_mouse_selected( envelope, x, y, m_nSnapRadius );

update();
HydrogenApp::get_instance()->getSampleEditor()->setUnclean();
}
Expand All @@ -356,6 +365,11 @@ void TargetWaveDisplay::mousePressEvent(QMouseEvent *ev)

void TargetWaveDisplay::mouseReleaseEvent(QMouseEvent *ev)
{
m_EditMode = get_current_edit_mode();
Sample::VelocityEnvelope & envelope = (m_EditMode == TargetWaveDisplay::VELOCITY) ? m_VelocityEnvelope : m_PanEnvelope;
int x = std::min(UI_WIDTH, std::max(0, ev->x()));
int y = std::min(UI_HEIGHT, std::max(0, ev->y()));
m_nSelectedEnvelopePoint = get_mouse_selected( envelope, x, y, m_nSnapRadius );
m_sInfo = "";
update();
HydrogenApp::get_instance()->getSampleEditor()->returnAllTargetDisplayValues();
Expand Down
4 changes: 4 additions & 0 deletions src/gui/src/SampleEditor/TargetWaveDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,16 @@ class TargetWaveDisplay : public QWidget, public H2Core::Object
bool m_UpdatePosition;
EnvelopeEditMode m_EditMode;

int m_nSnapRadius;

virtual void mouseMoveEvent(QMouseEvent *ev);
virtual void mousePressEvent(QMouseEvent *ev);
virtual void mouseReleaseEvent(QMouseEvent *ev);

H2Core::Sample::PanEnvelope m_PanEnvelope;
H2Core::Sample::VelocityEnvelope m_VelocityEnvelope;

int m_nSelectedEnvelopePoint;
};

#endif

0 comments on commit 8b4c80a

Please sign in to comment.