add a new canvas item for cue start/end dragging

This commit is contained in:
Paul Davis
2024-12-27 13:44:56 -07:00
parent 07046510d9
commit c98fc2477a
2 changed files with 127 additions and 5 deletions

View File

@@ -204,7 +204,7 @@ MidiView::show_start (bool yn)
}
if (!_start_boundary_rect) {
_start_boundary_rect = new ArdourCanvas::Rectangle (_note_group->parent());
_start_boundary_rect = new StartBoundaryRect (_note_group->parent());
_start_boundary_rect->set_outline_what (ArdourCanvas::Rectangle::RIGHT);
_start_boundary_rect->set_fill_color (UIConfiguration::instance().color_mod ("cue editor start rect fill", "cue boundary alpha"));
_start_boundary_rect->set_outline_color (UIConfiguration::instance().color ("cue editor start rect outline"));
@@ -252,7 +252,7 @@ MidiView::show_end (bool yn)
}
if (!_end_boundary_rect) {
_end_boundary_rect = new ArdourCanvas::Rectangle (_note_group->parent());
_end_boundary_rect = new EndBoundaryRect (_note_group->parent());
_end_boundary_rect->set_outline_what (ArdourCanvas::Rectangle::LEFT);
_end_boundary_rect->set_fill_color (UIConfiguration::instance().color_mod ("cue editor end rect fill", "cue boundary alpha"));
_end_boundary_rect->set_outline_color (UIConfiguration::instance().color ("cue editor end rect outline"));
@@ -283,7 +283,8 @@ MidiView::size_end_rect ()
double offset = _editing_context.sample_to_pixel ((_midi_region->start() + _midi_region->length()).samples());
std::cerr << "end starts at " << (_midi_region->start() + _midi_region->length()).beats().str() << " aka " << offset << " from " << (_midi_region->start() + _midi_region->length()).samples() << std::endl;
_end_boundary_rect->set (ArdourCanvas::Rect (offset, 0., ArdourCanvas::COORD_MAX, height()));
_end_boundary_rect->set_position (ArdourCanvas::Duple (offset, 0.));
_end_boundary_rect->set (ArdourCanvas::Rect (0., 0., ArdourCanvas::COORD_MAX, height()));
}
void
@@ -5237,3 +5238,101 @@ MidiView::set_visibility_note_range (MidiViewBackground::VisibleNoteRange nvr, b
{
_midi_context.set_note_visibility_range_style (nvr);
}
void
StartBoundaryRect::render (ArdourCanvas::Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
{
Rectangle::render (area, context);
ArdourCanvas::Rect self (item_to_window (_rect));
const double scale = UIConfiguration::instance().get_ui_scale();
const double radius = 10. * scale;
context->arc (self.x1, (self.y0 + (self.height() / 2.)) - radius, radius, -(M_PI/2.), (M_PI/2.));
Gtkmm2ext::set_source_rgba (context, _outline_color);
context->fill ();
}
bool
StartBoundaryRect::covers (ArdourCanvas::Duple const & point) const
{
ArdourCanvas::Rect self (item_to_window (_rect));
const double scale = UIConfiguration::instance().get_ui_scale();
/* 10-20 pixels of the right edge */
if (point.x >= self.x0 - (20. * scale) && point.x < self.x1) {
return true;
}
const double radius = 10. * scale;
/* Approximate the semicircle handle with a square */
double cy = self.y0 + (self.height() / 2.);
if (point.x >= self.x1 - (10. * scale) && point.x < self.x1 + radius &&
point.y >= cy - radius && point.y < cy + radius) {
std::cerr << "\n\nWe're in! " << whoami() << std::endl;
return true;
}
return false;
}
void
StartBoundaryRect::compute_bounding_box() const
{
Rectangle::compute_bounding_box ();
const double scale = UIConfiguration::instance().get_ui_scale();
const double radius = 10. * scale;
_bounding_box = _bounding_box.expand (0., radius + _outline_width + 1.0, 0., 0.);
}
void
EndBoundaryRect::render (ArdourCanvas::Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
{
Rectangle::render (area, context);
ArdourCanvas::Rect self (item_to_window (_rect));
const double scale = UIConfiguration::instance().get_ui_scale();
const double radius = 10. * scale;
context->arc (self.x0, (self.y0 + (self.height() / 2.)) - radius, radius, (M_PI/2.), -(M_PI/2.));
Gtkmm2ext::set_source_rgba (context, _outline_color);
context->fill ();
}
bool
EndBoundaryRect::covers (ArdourCanvas::Duple const & point) const
{
ArdourCanvas::Rect self (item_to_window (_rect));
const double scale = UIConfiguration::instance().get_ui_scale();
const double radius = 10. * scale;
/* 10-20 pixels of the left edge */
if (point.x >= self.x0 && point.x < self.x0 + (20. * scale)) {
return true;
}
/* Approximate the semicircle handle with a square */
double cy = self.y0 + (self.height() / 2.);
if (point.x >= self.x0 - radius && point.x < self.x0 + (10. * scale) &&
point.y >= cy - radius && point.y < cy + radius) {
return true;
}
return false;
}
void
EndBoundaryRect::compute_bounding_box() const
{
Rectangle::compute_bounding_box ();
const double scale = UIConfiguration::instance().get_ui_scale();
const double radius = 10. * scale;
_bounding_box = _bounding_box.expand (0., 0., 0., radius + _outline_width);
}

View File

@@ -37,6 +37,8 @@
#include "ardour/midi_model.h"
#include "ardour/types.h"
#include "canvas/rectangle.h"
#include "editing.h"
#include "region_view.h"
#include "midi_view_background.h"
@@ -75,6 +77,27 @@ class CursorContext;
class VelocityGhostRegion;
class EditingContext;
class PasteContext;
class Drag;
class StartBoundaryRect : public ArdourCanvas::Rectangle
{
public:
StartBoundaryRect (ArdourCanvas::Item* p) : ArdourCanvas::Rectangle (p) {}
void render (ArdourCanvas::Rect const & area, Cairo::RefPtr<Cairo::Context> context) const;
bool covers (ArdourCanvas::Duple const& point) const;
void compute_bounding_box () const;
};
class EndBoundaryRect : public ArdourCanvas::Rectangle
{
public:
EndBoundaryRect (ArdourCanvas::Item* p) : ArdourCanvas::Rectangle (p) {}
void render (ArdourCanvas::Rect const & area, Cairo::RefPtr<Cairo::Context> context) const;
bool covers (ArdourCanvas::Duple const& point) const;
void compute_bounding_box () const;
};
class MidiView : public virtual sigc::trackable, public LineMerger
{
@@ -509,8 +532,8 @@ class MidiView : public virtual sigc::trackable, public LineMerger
NoteBase* _channel_selection_scoped_note;
MouseState _mouse_state;
int _pressed_button;
ArdourCanvas::Rectangle* _start_boundary_rect;
ArdourCanvas::Rectangle* _end_boundary_rect;
StartBoundaryRect* _start_boundary_rect;
EndBoundaryRect* _end_boundary_rect;
bool _show_source;
/** Currently selected NoteBase objects */