mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 23:35:03 +01:00
lollis: better selection algorithm during drag, plus drawn line
This commit is contained in:
parent
91500795d8
commit
006779d4c3
2 changed files with 44 additions and 1 deletions
|
|
@ -53,6 +53,8 @@ static double const lollipop_radius = 8.0;
|
||||||
VelocityGhostRegion::VelocityGhostRegion (MidiRegionView& mrv, TimeAxisView& tv, TimeAxisView& source_tv, double initial_unit_pos)
|
VelocityGhostRegion::VelocityGhostRegion (MidiRegionView& mrv, TimeAxisView& tv, TimeAxisView& source_tv, double initial_unit_pos)
|
||||||
: MidiGhostRegion (mrv, tv, source_tv, initial_unit_pos)
|
: MidiGhostRegion (mrv, tv, source_tv, initial_unit_pos)
|
||||||
, dragging (false)
|
, dragging (false)
|
||||||
|
, dragging_line (nullptr)
|
||||||
|
, last_drag_x (-1)
|
||||||
{
|
{
|
||||||
base_rect->Event.connect (sigc::mem_fun (*this, &VelocityGhostRegion::base_event));
|
base_rect->Event.connect (sigc::mem_fun (*this, &VelocityGhostRegion::base_event));
|
||||||
}
|
}
|
||||||
|
|
@ -72,23 +74,45 @@ VelocityGhostRegion::base_event (GdkEvent* ev)
|
||||||
switch (ev->type) {
|
switch (ev->type) {
|
||||||
case GDK_MOTION_NOTIFY:
|
case GDK_MOTION_NOTIFY:
|
||||||
if (dragging) {
|
if (dragging) {
|
||||||
lollis_close_to_x (ev->motion.x, 20., affected_lollis);
|
if (last_drag_x < 0) {
|
||||||
|
lollis_close_to_x (ev->motion.x, 20., affected_lollis);
|
||||||
|
} else if (last_drag_x < ev->motion.x) {
|
||||||
|
/* rightward, "later" motion */
|
||||||
|
lollis_between (last_drag_x, ev->motion.x, affected_lollis);
|
||||||
|
} else {
|
||||||
|
/* leftward, "earlier" motion */
|
||||||
|
lollis_between (ev->motion.x, last_drag_x, affected_lollis);
|
||||||
|
}
|
||||||
if (!affected_lollis.empty()) {
|
if (!affected_lollis.empty()) {
|
||||||
int velocity = y_position_to_velocity (r.height() - (r.y1 - ev->motion.y));
|
int velocity = y_position_to_velocity (r.height() - (r.y1 - ev->motion.y));
|
||||||
mrv->set_velocity_for_notes (affected_lollis, velocity);
|
mrv->set_velocity_for_notes (affected_lollis, velocity);
|
||||||
}
|
}
|
||||||
|
if (dragging) {
|
||||||
|
dragging_line->add_point (ArdourCanvas::Duple (ev->motion.x - r.x0, ev->motion.y - r.y0));
|
||||||
|
last_drag_x = ev->motion.x;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GDK_BUTTON_PRESS:
|
case GDK_BUTTON_PRESS:
|
||||||
if (ev->button.button == 1) {
|
if (ev->button.button == 1) {
|
||||||
desensitize_lollis ();
|
desensitize_lollis ();
|
||||||
dragging = true;
|
dragging = true;
|
||||||
|
last_drag_x = -1;
|
||||||
|
if (!dragging_line) {
|
||||||
|
dragging_line = new ArdourCanvas::PolyLine (_note_group);
|
||||||
|
dragging_line->set_ignore_events (true);
|
||||||
|
dragging_line->set_outline_color (0x00ff00ff);
|
||||||
|
}
|
||||||
|
dragging_line->set (ArdourCanvas::Points());
|
||||||
|
dragging_line->show();
|
||||||
|
dragging_line->raise_to_top();
|
||||||
base_rect->grab();
|
base_rect->grab();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GDK_BUTTON_RELEASE:
|
case GDK_BUTTON_RELEASE:
|
||||||
if (ev->button.button == 1) {
|
if (ev->button.button == 1) {
|
||||||
base_rect->ungrab();
|
base_rect->ungrab();
|
||||||
|
dragging_line->hide ();
|
||||||
dragging = false;
|
dragging = false;
|
||||||
sensitize_lollis ();
|
sensitize_lollis ();
|
||||||
}
|
}
|
||||||
|
|
@ -284,6 +308,20 @@ VelocityGhostRegion::note_selected (NoteBase* ev)
|
||||||
lolli->set_outline_color (ev->selected() ? UIConfiguration::instance().color ("midi note selected outline") : 0x000000ff);
|
lolli->set_outline_color (ev->selected() ? UIConfiguration::instance().color ("midi note selected outline") : 0x000000ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
VelocityGhostRegion::lollis_between (int x0, int x1, std::vector<NoteBase*>& within)
|
||||||
|
{
|
||||||
|
for (auto & gev : events) {
|
||||||
|
ArdourCanvas::Lollipop* l = dynamic_cast<ArdourCanvas::Lollipop*> (gev.second->item);
|
||||||
|
if (l) {
|
||||||
|
ArdourCanvas::Duple pos = l->item_to_canvas (ArdourCanvas::Duple (l->x(), l->y0()));
|
||||||
|
if (pos.x >= x0 && pos.x < x1) {
|
||||||
|
within.push_back (gev.second->event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
VelocityGhostRegion::lollis_close_to_x (int x, double distance, std::vector<NoteBase*>& within)
|
VelocityGhostRegion::lollis_close_to_x (int x, double distance, std::vector<NoteBase*>& within)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@
|
||||||
#ifndef __gtk_ardour_velocity_region_view_h__
|
#ifndef __gtk_ardour_velocity_region_view_h__
|
||||||
#define __gtk_ardour_velocity_region_view_h__
|
#define __gtk_ardour_velocity_region_view_h__
|
||||||
|
|
||||||
|
#include "canvas/poly_line.h"
|
||||||
|
|
||||||
#include "ghostregion.h"
|
#include "ghostregion.h"
|
||||||
|
|
||||||
namespace ArdourCanvas {
|
namespace ArdourCanvas {
|
||||||
|
|
@ -47,11 +49,14 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool dragging;
|
bool dragging;
|
||||||
|
ArdourCanvas::PolyLine* dragging_line;
|
||||||
|
int last_drag_x;
|
||||||
|
|
||||||
bool base_event (GdkEvent*);
|
bool base_event (GdkEvent*);
|
||||||
bool lollevent (GdkEvent*, MidiGhostRegion::GhostEvent*);
|
bool lollevent (GdkEvent*, MidiGhostRegion::GhostEvent*);
|
||||||
void set_size_and_position (MidiGhostRegion::GhostEvent&);
|
void set_size_and_position (MidiGhostRegion::GhostEvent&);
|
||||||
void lollis_close_to_x (int x, double distance, std::vector<NoteBase*>& events);
|
void lollis_close_to_x (int x, double distance, std::vector<NoteBase*>& events);
|
||||||
|
void lollis_between (int x0, int x1, std::vector<NoteBase*>& events);
|
||||||
void desensitize_lollis ();
|
void desensitize_lollis ();
|
||||||
void sensitize_lollis ();
|
void sensitize_lollis ();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue