a variety of changes to make timeline-region editing-in-pianoroll to start to work

This also removes the useless "new pianoroll window" menu option and action
This commit is contained in:
Paul Davis 2025-01-20 18:05:19 -07:00
parent f052c3ae15
commit ab39c26f68
16 changed files with 112 additions and 48 deletions

View file

@ -698,8 +698,7 @@
<separator/><!-- Video Monitor !-->
<menuitem action='ToggleJadeo'/>
<separator/><!-- MIDI Pianoroll !-->
<menuitem action='new-pianoroll'/>
<separator/>
<separator/><!-- Connection dialogs !-->
<menuitem action='toggle-audio-connection-manager'/>
@ -900,6 +899,7 @@
<menuitem action='loop-region'/>
<menuitem action='rename-region'/>
<menuitem action='show-region-properties'/>
<menuitem action='edit-region-pianoroll-window'/>
<menu action='RegionMenuEdit'>
<menuitem action='combine-regions'/>
<menuitem action='uncombine-regions'/>

View file

@ -281,7 +281,6 @@ public:
Gtk::Menu* shared_popup_menu ();
void new_midi_tracer_window ();
void new_pianoroll_window ();
void toggle_editing_space();
void toggle_mixer_space();
void toggle_keep_tearoffs();
@ -522,7 +521,6 @@ private:
void record_state_changed ();
std::list<MidiTracer*> _midi_tracer_windows;
std::list<PianorollWindow*> _pianoroll_windows;
/* Transport Control */

View file

@ -888,30 +888,6 @@ ARDOUR_UI::toggle_meterbridge ()
}
}
void
ARDOUR_UI::new_pianoroll_window ()
{
RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("new-pianoroll"));
if (!act) {
return;
}
std::list<PianorollWindow*>::iterator i = _pianoroll_windows.begin ();
while (i != _pianoroll_windows.end() && (*i)->get_visible() == true) {
++i;
}
if (i == _pianoroll_windows.end()) {
/* all our MIDITracer windows are visible; make a new one */
PianorollWindow* pr = new PianorollWindow (string_compose (_("Pianoroll %1"), _pianoroll_windows.size() + 1));
pr->show_all ();
_pianoroll_windows.push_back (pr);
} else {
/* re-use the hidden one */
(*i)->show_all ();
}
}
void
ARDOUR_UI::new_midi_tracer_window ()
{

View file

@ -286,8 +286,6 @@ ARDOUR_UI::install_actions ()
act = ActionManager::register_action (common_actions, X_("NewMIDITracer"), _("MIDI Tracer"), sigc::mem_fun(*this, &ARDOUR_UI::new_midi_tracer_window));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (common_actions, X_("new-pianoroll"), _("Piano Roll"), sigc::mem_fun(*this, &ARDOUR_UI::new_pianoroll_window));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::register_action (common_actions, X_("chat"), _("Chat"), sigc::mem_fun(*this, &ARDOUR_UI::launch_chat));
ActionManager::register_action (common_actions, X_("tutorial"), S_("Help|Tutorial"), mem_fun(*this, &ARDOUR_UI::launch_tutorial));

View file

@ -229,6 +229,8 @@ public:
bool extend_selection_to_track (TimeAxisView&);
void edit_region_in_pianoroll_window ();
void play_selection ();
void maybe_locate_with_edit_preroll (samplepos_t);
void play_with_preroll ();

View file

@ -1253,6 +1253,9 @@ Editor::register_region_actions ()
/* Open the region properties dialogue for the selected regions */
register_region_action (_region_actions, RegionActionTarget (SelectedRegions), "show-region-properties", _("Properties..."), sigc::mem_fun (*this, &Editor::show_region_properties));
/* Edit the region in a separate region pianoroll window */
register_region_action (_region_actions, RegionActionTarget (SelectedRegions), "edit-region-pianoroll-window", _("Edit in separate window..."), sigc::mem_fun (*this, &Editor::edit_region_in_pianoroll_window));
register_region_action (_region_actions, RegionActionTarget (SelectedRegions|EnteredRegions), "play-selected-regions", _("Play Selected Regions"), sigc::mem_fun(*this, &Editor::play_selected_region));
register_region_action (_region_actions, RegionActionTarget (SelectedRegions|EnteredRegions), "tag-selected-regions", _("Tag Selected Regions"), sigc::mem_fun(*this, &Editor::tag_selected_region));

View file

@ -113,6 +113,7 @@
#include "note.h"
#include "paste_context.h"
#include "patch_change_dialog.h"
#include "pianoroll_window.h"
#include "region_gain_line.h"
#include "route_time_axis.h"
#include "selection.h"
@ -9517,3 +9518,10 @@ Editor::temporal_zoom_extents ()
temporal_zoom_by_sample (start, end);
}
}
void
Editor::edit_region_in_pianoroll_window ()
{
selection->foreach_midi_regionview (&MidiRegionView::edit_in_pianoroll_window);
}

View file

@ -48,7 +48,6 @@
#include "ardour/midi_track.h"
#include "ardour/operations.h"
#include "ardour/quantize.h"
#include "ardour/session.h"
#include "evoral/Parameter.h"
#include "evoral/Event.h"
@ -77,6 +76,7 @@
#include "midi_velocity_dialog.h"
#include "note_player.h"
#include "paste_context.h"
#include "pianoroll_window.h"
#include "public_editor.h"
#include "route_time_axis.h"
#include "rgb_macros.h"
@ -681,3 +681,16 @@ MidiRegionView::add_control_points_to_selection (timepos_t const & start, timepo
at.second->set_selected_points (_editing_context.get_selection().points);
}
}
void
MidiRegionView::edit_in_pianoroll_window ()
{
std::shared_ptr<MidiTrack> track = std::dynamic_pointer_cast<MidiTrack> (trackview.stripable());
assert (track);
PianorollWindow* pr = new PianorollWindow (string_compose (_("Pianoroll: %1"), _region->name()), track->session());;
pr->set (track, midi_region());
pr->show_all ();
pr->present ();
}

View file

@ -134,6 +134,7 @@ public:
void set_visibility_note_range (MidiViewBackground::VisibleNoteRange, bool);
MergeableLine* make_merger ();
void edit_in_pianoroll_window ();
protected:
void reset_width_dependent_items (double pixel_width);

View file

@ -317,10 +317,19 @@ MidiView::region_going_away ()
{
_midi_region.reset ();
_model.reset ();
clear_events ();
connections_requiring_model.drop_connections();
region_connections.drop_connections ();
}
void
MidiView::set_show_source (bool yn)
{
_show_source = yn;
}
void
MidiView::set_region (std::shared_ptr<MidiRegion> mr)
{
@ -334,6 +343,9 @@ MidiView::set_region (std::shared_ptr<MidiRegion> mr)
_midi_region->DropReferences.connect (region_connections, invalidator (*this), std::bind (&MidiView::region_going_away, this), gui_context());
_midi_region->PropertyChanged.connect (region_connections, invalidator (*this), std::bind (&MidiView::region_resized, this, _1), gui_context());
size_start_rect ();
size_end_rect ();
set_model (_midi_region->midi_source (0)->model());
}

View file

@ -145,6 +145,8 @@ class MidiView : public virtual sigc::trackable, public LineMerger
virtual void set_track (std::shared_ptr<ARDOUR::MidiTrack>);
virtual void set_model (std::shared_ptr<ARDOUR::MidiModel>);
void set_show_source (bool yn);
NoteBase* add_note(const std::shared_ptr<NoteType> note, bool visible);
void cut_copy_clear (Editing::CutCopyOp);

View file

@ -229,6 +229,7 @@ MidiViewBackground::maybe_extend_note_range (uint8_t note_num)
}
if (changed) {
std::cerr << "changing it\n";
apply_note_range (_data_note_min, _data_note_max, true);
}
}

View file

@ -16,6 +16,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "pbd/stateful_diff_command.h"
#include "ardour/midi_region.h"
#include "ardour/midi_track.h"
#include "ardour/smf_source.h"
@ -51,6 +53,7 @@
#include "pbd/i18n.h"
using namespace PBD;
using namespace ARDOUR;
using namespace ArdourCanvas;
using namespace ArdourWidgets;
@ -502,6 +505,12 @@ Pianoroll::canvas_allocate (Gtk::Allocation alloc)
prh->set (ArdourCanvas::Rect (0, 0, prh->x1(), view->midi_context().height()));
_track_canvas_width = _visible_canvas_width - prh->x1();
if (_canvas->is_mapped()) {
// zoom_to_show (timecnt_t (timepos_t (Temporal::BeatTime), timepos_t (max_zoom_extent ().second.beats() * 1.1)));
}
std::cerr << "new size " << _visible_canvas_width << " x " << _visible_canvas_width << std::endl;
}
timepos_t
@ -608,13 +617,29 @@ Pianoroll::canvas_cue_end_event (GdkEvent* event, ArdourCanvas::Item* item)
void
Pianoroll::set_trigger_start (Temporal::timepos_t const & p)
{
if (ref.trigger()) {
ref.trigger()->the_region()->trim_front (p);
} else {
begin_reversible_command (_("trim region front"));
view->midi_region()->clear_changes ();
view->midi_region()->trim_front (view->midi_region()->position() + p);
add_command (new StatefulDiffCommand (view->midi_region()));
commit_reversible_command ();
}
}
void
Pianoroll::set_trigger_end (Temporal::timepos_t const & p)
{
if (ref.trigger()) {
ref.trigger()->the_region()->trim_end (p);
} else {
begin_reversible_command (_("trim region end"));
view->midi_region()->clear_changes ();
view->midi_region()->trim_end (view->midi_region()->position() + p);
add_command (new StatefulDiffCommand (view->midi_region()));
commit_reversible_command ();
}
}
Gtk::Widget&
@ -1937,6 +1962,14 @@ Pianoroll::unset ()
ref = TriggerReference ();
}
void
Pianoroll::set_track (std::shared_ptr<ARDOUR::MidiTrack> track)
{
if (view) {
view->set_track (track);
}
}
void
Pianoroll::set_region (std::shared_ptr<ARDOUR::MidiRegion> r)
{
@ -1949,12 +1982,6 @@ Pianoroll::set_region (std::shared_ptr<ARDOUR::MidiRegion> r)
view->show_start (true);
view->show_end (true);
/* Compute zoom level to show entire source plus some margin if possible */
Temporal::timecnt_t duration = Temporal::timecnt_t (r->midi_source()->length().beats());
std::cerr << "new region: " << duration << std::endl;
bool provided = false;
std::shared_ptr<Temporal::TempoMap> map;
std::shared_ptr<SMFSource> smf (std::dynamic_pointer_cast<SMFSource> (r->midi_source()));
@ -1964,22 +1991,34 @@ Pianoroll::set_region (std::shared_ptr<ARDOUR::MidiRegion> r)
}
if (!provided) {
/* COPY MAIN SESSION TEMPO MAP? */
map.reset (new Temporal::TempoMap (Temporal::Tempo (120, 4), Temporal::Meter (4, 4)));
}
{
EditingContext::TempoMapScope tms (*this, map);
double width = bg->width();
/* make it 20% wider than we need */
samplecnt_t samples = (samplecnt_t) floor (1.2 * duration.samples());
std::cerr << "new spp from " << samples << " / " << width << std::endl;
samplecnt_t spp = floor (samples / width);
reset_zoom (spp);
/* Compute zoom level to show entire source plus some margin if possible */
zoom_to_show (timecnt_t (timepos_t (Temporal::BeatTime), timepos_t (max_zoom_extent ().second.beats() * 1.1)));
}
set_visible_channel (0);
}
void
Pianoroll::zoom_to_show (Temporal::timecnt_t const & duration)
{
if (!_visible_canvas_width) {
return;
}
/* make it 20% wider than we need */
samplecnt_t samples = (samplecnt_t) floor (1.2 * duration.samples());
std::cerr << "new spp from " << samples << " / " << _visible_canvas_width << std::endl;
samplecnt_t spp = floor (samples / _visible_canvas_width);
reset_zoom (spp);
}
bool
Pianoroll::automation_button_event (GdkEventButton* ev, Evoral::ParameterType type, int id)
{
@ -2091,6 +2130,7 @@ std::pair<Temporal::timepos_t,Temporal::timepos_t>
Pianoroll::max_zoom_extent() const
{
if (view && view->midi_region()) {
/* XXX make this dependent on view _show_source setting */
return std::make_pair (Temporal::timepos_t (Temporal::Beats()), Temporal::timepos_t (view->midi_region()->midi_source()->length().beats()));
}

View file

@ -79,6 +79,7 @@ class Pianoroll : public CueEditor
void set (ARDOUR::TriggerReference&);
void set_region (std::shared_ptr<ARDOUR::MidiRegion>);
void set_track (std::shared_ptr<ARDOUR::MidiTrack>);
ArdourCanvas::ScrollGroup* get_hscroll_group () const { return h_scroll_group; }
ArdourCanvas::ScrollGroup* get_cursor_scroll_group () const { return cursor_scroll_group; }
@ -126,6 +127,7 @@ class Pianoroll : public CueEditor
void set_trigger_bounds (Temporal::timepos_t const &, Temporal::timepos_t const &);
void full_zoom_clicked();
void zoom_to_show (Temporal::timecnt_t const &);
void delete_ ();
void paste (float times, bool from_context_menu);

View file

@ -23,10 +23,11 @@
using namespace ARDOUR;
PianorollWindow::PianorollWindow (std::string const & name)
PianorollWindow::PianorollWindow (std::string const & name, Session& s)
: ArdourWindow (string_compose ("%1 - %2", PROGRAM_NAME, name))
, pianoroll (new Pianoroll (name))
{
pianoroll->set_session (&s);
pianoroll->viewport().set_size_request (600, 120);
add (pianoroll->toolbox());
@ -37,3 +38,10 @@ PianorollWindow::~PianorollWindow ()
{
delete pianoroll;
}
void
PianorollWindow::set (std::shared_ptr<MidiTrack> track, std::shared_ptr<MidiRegion> region)
{
pianoroll->set_track (track);
pianoroll->set_region (region);
}

View file

@ -30,10 +30,10 @@ class Pianoroll;
class PianorollWindow : public ArdourWindow
{
public:
PianorollWindow (std::string const & name);
PianorollWindow (std::string const & name, ARDOUR::Session&);
~PianorollWindow ();
void set (std::shared_ptr<ARDOUR::Track>, std::shared_ptr<ARDOUR::MidiRegion>);
void set (std::shared_ptr<ARDOUR::MidiTrack>, std::shared_ptr<ARDOUR::MidiRegion>);
private:
Pianoroll* pianoroll;