lock in some major steps for the midi cue/pianoroll editor

This commit is contained in:
Paul Davis 2024-01-26 20:45:22 -07:00
parent 97cf69a408
commit e061c775f0
20 changed files with 140 additions and 43 deletions

View File

@ -7,12 +7,6 @@ CueEditor::~CueEditor ()
{
}
VerboseCursor*
CueEditor::verbose_cursor () const
{
return nullptr;
}
void
CueEditor::set_snapped_cursor_position (Temporal::timepos_t const & pos)
{
@ -167,15 +161,11 @@ CueEditor::get_zoom_focus () const
return Editing::ZoomFocusPlayhead;
}
samplecnt_t
CueEditor::get_current_zoom () const
{
return 2048;
}
void
CueEditor::reset_zoom (samplecnt_t)
CueEditor::reset_zoom (samplecnt_t n)
{
samples_per_pixel = n;
ZoomChanged(); /* EMIT SIGNAL */
}
void
@ -228,3 +218,18 @@ CueEditor::current_mouse_mode () const
return Editing::MouseContent;
}
std::shared_ptr<Temporal::TempoMap const>
CueEditor::start_local_tempo_map (std::shared_ptr<Temporal::TempoMap> map)
{
std::shared_ptr<Temporal::TempoMap const> tmp = Temporal::TempoMap::use();
Temporal::TempoMap::set (map);
return tmp;
}
void
CueEditor::end_local_tempo_map (std::shared_ptr<Temporal::TempoMap const> map)
{
Temporal::TempoMap::set (map);
}

View File

@ -90,12 +90,13 @@ class CueEditor : public EditingContext
MouseCursors const* cursors () const {
return _cursors;
}
VerboseCursor* verbose_cursor () const;
void set_snapped_cursor_position (Temporal::timepos_t const & pos);
std::vector<MidiRegionView*> filter_to_unique_midi_region_views (RegionSelection const & ms) const;
std::shared_ptr<Temporal::TempoMap const> start_local_tempo_map (std::shared_ptr<Temporal::TempoMap>);
void end_local_tempo_map (std::shared_ptr<Temporal::TempoMap const>);
protected:
void set_canvas_cursor (Gdk::Cursor*);
size_t push_canvas_cursor (Gdk::Cursor*);

View File

@ -1586,3 +1586,10 @@ EditingContext::snap_relative_time_to_relative_time (timepos_t const & origin, t
/* back to relative */
return origin.distance (snapped);
}
std::shared_ptr<Temporal::TempoMap const>
EditingContext::start_local_tempo_map (std::shared_ptr<Temporal::TempoMap>)
{
/* default is a no-op */
return Temporal::TempoMap::use ();
}

View File

@ -51,6 +51,10 @@
using ARDOUR::samplepos_t;
using ARDOUR::samplecnt_t;
namespace Temporal {
class TempoMap;
}
class XMLNode;
class CursorContext;
@ -79,6 +83,20 @@ public:
Temporal::TimeDomain time_domain () const;
struct TempoMapScope {
TempoMapScope (EditingContext& context, std::shared_ptr<Temporal::TempoMap> map)
: ec (context)
{
old_map = ec.start_local_tempo_map (map);
}
~TempoMapScope () {
ec.end_local_tempo_map (old_map);
}
EditingContext& ec;
std::shared_ptr<Temporal::TempoMap const> old_map;
};
DragManager* drags () const {
return _drags;
}
@ -86,6 +104,8 @@ public:
bool drag_active () const;
bool preview_video_drag_active () const;
virtual ArdourCanvas::Duple upper_left() const { return ArdourCanvas::Duple (0, 0); }
virtual void select_all_within (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, TrackViewList const &, Selection::Operation, bool) = 0;
virtual void get_per_region_note_selection (std::list<std::pair<PBD::ID, std::set<std::shared_ptr<Evoral::Note<Temporal::Beats> > > > >&) const = 0;
virtual void get_regionviews_by_id (PBD::ID const id, RegionSelection & regions) const = 0;
@ -249,6 +269,8 @@ public:
virtual void reset_zoom (samplecnt_t) = 0;
virtual void reposition_and_zoom (samplepos_t, double) = 0;
sigc::signal<void> ZoomChanged;
virtual Selection& get_selection() const { return *selection; }
virtual Selection& get_cut_buffer () const { return *cut_buffer; }
@ -295,6 +317,9 @@ public:
ArdourCanvas::Rectangle* rubberband_rect;
virtual ArdourCanvas::Container* get_noscroll_group() const = 0;
virtual ArdourCanvas::ScrollGroup* get_hscroll_group () const = 0;
virtual ArdourCanvas::ScrollGroup* get_cursor_scroll_group () const = 0;
virtual bool canvas_playhead_cursor_event (GdkEvent* event, ArdourCanvas::Item*) { return false; }
protected:
Glib::RefPtr<Gtk::ActionGroup> _midi_actions;
@ -426,6 +451,10 @@ public:
double _visible_canvas_height; ///< height of the visible area of the track canvas
QuantizeDialog* quantize_dialog;
friend class TempoMapScope;
virtual std::shared_ptr<Temporal::TempoMap const> start_local_tempo_map (std::shared_ptr<Temporal::TempoMap>);
virtual void end_local_tempo_map (std::shared_ptr<Temporal::TempoMap const>) { /* no-op by default */ }
};

View File

@ -6293,3 +6293,8 @@ Editor::snap_to_internal (timepos_t& start, Temporal::RoundMode direction, SnapP
start = best;
}
ArdourCanvas::Duple
Editor::upper_left() const
{
get_trackview_group ()->canvas_origin ().y;
}

View File

@ -659,6 +659,8 @@ private:
void reparent_location_markers (LocationMarkers*, ArdourCanvas::Item*);
ArdourCanvas::Duple upper_left() const;
LocationMarkers* find_location_markers (ARDOUR::Location*) const;
ARDOUR::Location* find_location_from_marker (ArdourMarker*, bool& is_start) const;
ArdourMarker* find_marker_from_location_id (PBD::ID const&, bool) const;
@ -1632,6 +1634,7 @@ private:
void mid_tempo_change (MidTempoChanges);
Editing::EditPoint edit_point() const { return _edit_point; }
bool canvas_playhead_cursor_event (GdkEvent* event, ArdourCanvas::Item*);
protected:
void _commit_tempo_map_edit (Temporal::TempoMap::WritableSharedPtr&, bool with_update = false);
@ -1646,7 +1649,6 @@ private:
/* non-public event handlers */
bool canvas_section_box_event (GdkEvent* event);
bool canvas_playhead_cursor_event (GdkEvent* event, ArdourCanvas::Item*);
bool track_canvas_scroll (GdkEventScroll* event);
bool track_canvas_button_press_event (GdkEventButton* event);

View File

@ -256,7 +256,7 @@ Editor::initialize_canvas ()
range_marker_bar->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_bar_event), range_marker_bar, RangeMarkerBarItem, "range marker bar"));
transport_marker_bar->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_bar_event), transport_marker_bar, TransportMarkerBarItem, "transport marker bar"));
_playhead_cursor = new EditorCursor (*this, &Editor::canvas_playhead_cursor_event, X_("playhead"));
_playhead_cursor = new EditorCursor (*this, &EditingContext::canvas_playhead_cursor_event, X_("playhead"));
_playhead_cursor->set_sensitive (UIConfiguration::instance().get_sensitize_playhead());
_snapped_cursor = new EditorCursor (*this, X_("snapped"));

View File

@ -29,13 +29,13 @@
#include "canvas/scroll_group.h"
#include "editor_cursors.h"
#include "editor.h"
#include "editing_context.h"
using namespace ARDOUR;
using namespace PBD;
using namespace Gtk;
EditorCursor::EditorCursor (Editor& ed, bool (Editor::*callback)(GdkEvent*,ArdourCanvas::Item*), std::string const & name)
EditorCursor::EditorCursor (EditingContext& ed, bool (EditingContext::*callback)(GdkEvent*,ArdourCanvas::Item*), std::string const & name)
: _editor (ed)
, _track_canvas_item (new ArdourCanvas::Arrow (_editor.get_cursor_scroll_group()))
{
@ -57,7 +57,7 @@ EditorCursor::EditorCursor (Editor& ed, bool (Editor::*callback)(GdkEvent*,Ardou
_current_sample = 1; /* force redraw at 0 */
}
EditorCursor::EditorCursor (Editor& ed, std::string const & name)
EditorCursor::EditorCursor (EditingContext& ed, std::string const & name)
: _editor (ed)
, _track_canvas_item (new ArdourCanvas::Arrow (_editor.get_hscroll_group()))
{

View File

@ -29,13 +29,13 @@
#include "canvas/line.h"
#include "canvas/types.h"
class Editor;
class EditingContext;
class EditorCursor
{
public:
EditorCursor (Editor&, bool (Editor::*)(GdkEvent*,ArdourCanvas::Item*), std::string const &);
EditorCursor (Editor&, std::string const &);
EditorCursor (EditingContext&, bool (EditingContext::*)(GdkEvent*,ArdourCanvas::Item*), std::string const &);
EditorCursor (EditingContext&, std::string const &);
~EditorCursor ();
void set_position (samplepos_t);
@ -57,7 +57,7 @@ public:
PBD::Signal1<void, samplepos_t> PositionChanged;
private:
Editor& _editor;
EditingContext& _editor;
ArdourCanvas::Arrow* _track_canvas_item;
samplepos_t _current_sample;
};

View File

@ -471,10 +471,7 @@ Drag::current_pointer_y () const
return _drags->current_pointer_y ();
}
Editor* editor = dynamic_cast<Editor*>(&editing_context);
assert (editor);
return _drags->current_pointer_y () - editor->get_trackview_group ()->canvas_origin ().y;
return _drags->current_pointer_y () - editing_context.upper_left ().y;
}
void

View File

@ -41,8 +41,6 @@ CueMidiBackground::set_size (double w, double h)
_width = w;
_height = h;
std::cerr << "Size for cue midi: " << w << " x " << h << std::endl;
update_contents_height ();
}
@ -58,6 +56,12 @@ CueMidiBackground::height() const
return _height;
}
double
CueMidiBackground::width() const
{
return _width;
}
uint8_t
CueMidiBackground::get_preferred_midi_channel () const
{

View File

@ -40,6 +40,7 @@ class CueMidiBackground : public MidiViewBackground
~CueMidiBackground ();
double height() const;
double width() const;
double contents_height() const;
uint8_t get_preferred_midi_channel () const;

View File

@ -16,18 +16,24 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "ardour/midi_region.h"
#include "ardour/midi_source.h"
#include "canvas/canvas.h"
#include "canvas/container.h"
#include "canvas/debug.h"
#include "canvas/scroll_group.h"
#include "canvas/rectangle.h"
#include "editor_cursors.h"
#include "midi_cue_background.h"
#include "midi_cue_editor.h"
#include "midi_view.h"
#include "midi_cue_view.h"
#include "ui_config.h"
#include "verbose_cursor.h"
#include "pbd/i18n.h"
using namespace ARDOUR;
using namespace ArdourCanvas;
using namespace Temporal;
@ -40,6 +46,12 @@ MidiCueEditor::MidiCueEditor()
build_canvas ();
_verbose_cursor = new VerboseCursor (*this);
// _playhead_cursor = new EditorCursor (*this, &Editor::canvas_playhead_cursor_event, X_("playhead"));
_playhead_cursor = new EditorCursor (*this, X_("playhead"));
_playhead_cursor->set_sensitive (UIConfiguration::instance().get_sensitize_playhead());
_snapped_cursor = new EditorCursor (*this, X_("snapped"));
}
MidiCueEditor::~MidiCueEditor ()
@ -90,9 +102,6 @@ MidiCueEditor::build_canvas ()
time_line_group = new ArdourCanvas::Container (h_scroll_group);
CANVAS_DEBUG_NAME (time_line_group, "time line group");
_trackview_group = new ArdourCanvas::Container (hv_scroll_group);
CANVAS_DEBUG_NAME (_trackview_group, "Canvas TrackViews");
// used as rubberband rect
rubberband_rect = new ArdourCanvas::Rectangle (hv_scroll_group, ArdourCanvas::Rect (0.0, 0.0, 0.0, 0.0));
rubberband_rect->hide();
@ -146,6 +155,16 @@ MidiCueEditor::snap_to_internal (timepos_t& start, Temporal::RoundMode direction
start = best;
}
void
MidiCueEditor::reset_zoom (samplecnt_t spp)
{
CueEditor::reset_zoom (spp);
if (view) {
view->set_samples_per_pixel (spp);
}
}
samplecnt_t
MidiCueEditor::current_page_samples() const
{
@ -201,8 +220,26 @@ MidiCueEditor::set_region (std::shared_ptr<ARDOUR::MidiTrack> t, std::shared_ptr
return;
}
view = new MidiView (t, *hv_scroll_group, *this, *bg, 0xff0000ff);
view = new MidiCueView (t, *hv_scroll_group, *this, *bg, 0xff0000ff);
view->set_region (r);
bg->set_view (view);
/* Compute zoom level to show entire source plus some margin if possible */
std::shared_ptr<Temporal::TempoMap> map;
Temporal::timecnt_t duration = Temporal::timecnt_t (r->midi_source()->length().beats());
/* XXX build tempo map from source */
map.reset (new Temporal::TempoMap (Temporal::Tempo (120, 4), Temporal::Meter (4, 4)));
{
EditingContext::TempoMapScope tms (*this, map);
double width = bg->width();
samplecnt_t samples = duration.samples();
samplecnt_t spp = floor (samples / width);
reset_zoom (spp);
}
}

View File

@ -64,6 +64,11 @@ class MidiCueEditor : public CueEditor
void set_region (std::shared_ptr<ARDOUR::MidiTrack>, std::shared_ptr<ARDOUR::MidiRegion>);
ArdourCanvas::ScrollGroup* get_hscroll_group () const { return h_scroll_group; }
ArdourCanvas::ScrollGroup* get_cursor_scroll_group () const { return cursor_scroll_group; }
void reset_zoom (samplecnt_t);
protected:
Temporal::timepos_t snap_to_grid (Temporal::timepos_t const & start,
Temporal::RoundMode direction,
@ -98,8 +103,6 @@ class MidiCueEditor : public CueEditor
/* The group containing all trackviews. */
ArdourCanvas::Container* no_scroll_group;
/* The group containing all trackviews. */
ArdourCanvas::Container* _trackview_group;
ArdourCanvas::Container* global_rect_group;
ArdourCanvas::Container* time_line_group;

View File

@ -150,6 +150,8 @@ MidiRegionView::init (bool /*wfd*/)
RegionView::init (false);
CANVAS_DEBUG_NAME (_note_group, string_compose ("note group for %1", get_item_name()));
set_region (std::dynamic_pointer_cast<MidiRegion> (_region));
//set_height (trackview.current_height());

View File

@ -31,8 +31,6 @@
#include <gtkmm.h>
#include "gtkmm2ext/gtk_ui.h"
#include <sigc++/signal.h>
#include "midi++/midnam_patch.h"
@ -57,6 +55,9 @@
#include "canvas/debug.h"
#include "gtkmm2ext/gtk_ui.h"
#include "gtkmm2ext/utils.h"
#include "automation_region_view.h"
#include "automation_time_axis.h"
#include "control_point.h"
@ -172,8 +173,6 @@ MidiView::MidiView (MidiView const & other)
void
MidiView::init ()
{
// CANVAS_DEBUG_NAME (_note_group, string_compose ("note group for %1", get_item_name()));
_patch_change_outline = UIConfiguration::instance().color ("midi patch change outline");
_patch_change_fill = UIConfiguration::instance().color_mod ("midi patch change fill", "midi patch change fill");
@ -239,6 +238,8 @@ MidiView::canvas_group_event (GdkEvent* ev)
//For now, move the snapped cursor aside so it doesn't bother you during internal editing
//_editing_context.set_snapped_cursor_position(_midi_region->position());
std::cerr << "MV @ " << this << " CGE " << Gtkmm2ext::event_type_string (ev->type) << std::endl;
bool r;
switch (ev->type) {

View File

@ -92,6 +92,9 @@ class MidiView : public virtual sigc::trackable
virtual ~MidiView ();
void init (bool wfd);
virtual void set_samples_per_pixel (double) {};
virtual bool display_is_enabled() const { return true; }
virtual ArdourCanvas::Item* drag_group() const;

View File

@ -345,7 +345,6 @@ public:
virtual RegionView* regionview_from_region (std::shared_ptr<ARDOUR::Region>) const = 0;
virtual RouteTimeAxisView* rtav_from_route (std::shared_ptr<ARDOUR::Route>) const = 0;
sigc::signal<void> ZoomChanged;
sigc::signal<void> Realized;
sigc::signal<void,samplepos_t> UpdateAllTransportClocks;

View File

@ -161,6 +161,7 @@ gtk2_ardour_sources = [
'midi_channel_selector.cc',
'midi_cue_background.cc',
'midi_cue_editor.cc',
'midi_cue_view.cc',
'midi_cut_buffer.cc',
'midi_export_dialog.cc',
'midi_list_editor.cc',

View File

@ -656,7 +656,7 @@ GtkCanvas::pick_current_item (Duple const & point, int state)
}
if (_current_item) {
DEBUG_TRACE (PBD::DEBUG::CanvasEnterLeave, string_compose ("CURRENT ITEM %1/%2\n", _new_current_item->whatami(), _current_item->name));
DEBUG_TRACE (PBD::DEBUG::CanvasEnterLeave, string_compose ("CURRENT ITEM %1/%2\n", _current_item->whatami(), _current_item->name));
} else {
DEBUG_TRACE (PBD::DEBUG::CanvasEnterLeave, "--- no current item\n");
}