diff options
author | David Robillard <d@drobilla.net> | 2007-08-01 20:50:09 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2007-08-01 20:50:09 +0000 |
commit | d7db3f757fde92126ef9886370ce604992b7e974 (patch) | |
tree | 4ac58366ad0a9980756c23ef58e413ce54bf395f /gtk2_ardour | |
parent | 3f421ac45025a856f03b779363f8f5f60b837b1e (diff) |
Better MidiModel command framework, ready to go for all your canvas editing needs.
Rewrote MidiEvent to be a well-behaved self-contained object that optionally owns it's buffer, has proper copying semantics, etc.
Fixed crazy bugs triggered by adding lots of events with varying times to a region.
Speed up initial session display significantly (don't redraw each MIDI region tons of times, though still happens more than once and can use fixing...).
git-svn-id: svn://localhost/ardour2/trunk@2213 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r-- | gtk2_ardour/audio_streamview.cc | 5 | ||||
-rw-r--r-- | gtk2_ardour/canvas-midi-event.cc | 3 | ||||
-rw-r--r-- | gtk2_ardour/midi_region_view.cc | 71 | ||||
-rw-r--r-- | gtk2_ardour/midi_streamview.cc | 13 | ||||
-rw-r--r-- | gtk2_ardour/region_view.cc | 13 | ||||
-rw-r--r-- | gtk2_ardour/region_view.h | 5 | ||||
-rw-r--r-- | gtk2_ardour/streamview.cc | 3 |
7 files changed, 68 insertions, 45 deletions
diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc index 1e66b29321..3490c9d6c2 100644 --- a/gtk2_ardour/audio_streamview.cc +++ b/gtk2_ardour/audio_streamview.cc @@ -396,7 +396,10 @@ AudioStreamView::redisplay_diskstream () if (!(*i)->is_valid()) { delete *i; region_views.erase (i); - } + } else { + (*i)->enable_display(true); + (*i)->set_y_position_and_height(0, height); + } i = tmp; } diff --git a/gtk2_ardour/canvas-midi-event.cc b/gtk2_ardour/canvas-midi-event.cc index 73c2b29925..dafe94872c 100644 --- a/gtk2_ardour/canvas-midi-event.cc +++ b/gtk2_ardour/canvas-midi-event.cc @@ -60,7 +60,8 @@ CanvasMidiEvent::on_event(GdkEvent* ev) case GDK_LEAVE_NOTIFY: cerr << "LEAVE: " << ev->crossing.state << endl; Keyboard::magic_widget_drop_focus(); - //_item->drop_focus(); + //_region.get_time_axis_view().editor.reset_focus(); + _region.get_canvas_group()->grab_focus(); break; case GDK_KEY_PRESS: diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 755e896f6c..d1156bb9c5 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -74,10 +74,10 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView & void MidiRegionView::init (Gdk::Color& basic_color, bool wfd) { - if (wfd) - _model = midi_region()->midi_source(0)->model(); + _model = midi_region()->midi_source(0)->model(); + _enable_display = false; - RegionView::init(basic_color, /*wfd*/false); + RegionView::init(basic_color, false); compute_colors (basic_color); @@ -93,12 +93,17 @@ MidiRegionView::init (Gdk::Color& basic_color, bool wfd) set_colors (); - if (wfd) - redisplay_model(); - - _model->ContentsChanged.connect(sigc::mem_fun(this, &MidiRegionView::redisplay_model)); + _enable_display = true; + + if (_model) { + if (wfd) { + redisplay_model(); + } + _model->ContentsChanged.connect(sigc::mem_fun(this, &MidiRegionView::redisplay_model)); + } group->signal_event().connect (mem_fun (this, &MidiRegionView::canvas_event), false); + } bool @@ -229,14 +234,14 @@ MidiRegionView::create_note_at(double x, double y) // Add a 1 beat long note (for now) const MidiModel::Note new_note(stamp, dur, (uint8_t)note, 0x40); - - _model->begin_command(); - _model->add_note(new_note); - _model->finish_command(); - + view->update_bounds(new_note.note()); - add_note(new_note); + MidiModel::DeltaCommand* cmd = _model->new_delta_command("add note"); + cmd->add(new_note); + _model->apply_command(cmd); + + //add_note(new_note); } @@ -254,7 +259,9 @@ void MidiRegionView::display_model(boost::shared_ptr<MidiModel> model) { _model = model; - redisplay_model(); + + if (_enable_display) + redisplay_model(); } @@ -271,7 +278,6 @@ MidiRegionView::redisplay_model() end_write(); } else { - assert(false); warning << "MidiRegionView::redisplay_model called without a model" << endmsg; } } @@ -299,7 +305,8 @@ MidiRegionView::region_resized (Change what_changed) if (what_changed & ARDOUR::PositionChanged) { - redisplay_model(); + if (_enable_display) + redisplay_model(); } else if (what_changed & Change (StartChanged)) { @@ -318,7 +325,8 @@ MidiRegionView::reset_width_dependent_items (double pixel_width) RegionView::reset_width_dependent_items(pixel_width); assert(_pixel_width == pixel_width); - redisplay_model(); + if (_enable_display) + redisplay_model(); } void @@ -326,7 +334,8 @@ MidiRegionView::set_y_position_and_height (double y, double h) { RegionView::set_y_position_and_height(y, h - 1); - redisplay_model(); + if (_enable_display) + redisplay_model(); if (name_text) { name_text->raise_to_top(); @@ -402,14 +411,14 @@ MidiRegionView::add_event (const MidiEvent& ev) const double pixel_range = (trackview.height - footer_height - 5.0) / (double)note_range; if (mtv->note_mode() == Sustained) { - if ((ev.buffer[0] & 0xF0) == MIDI_CMD_NOTE_ON) { - const Byte& note = ev.buffer[1]; + if ((ev.buffer()[0] & 0xF0) == MIDI_CMD_NOTE_ON) { + const Byte& note = ev.buffer()[1]; const double y1 = trackview.height - (pixel_range * (note - view->lowest_note() + 1)) - footer_height - 3.0; CanvasNote* ev_rect = new CanvasNote(*this, *group); ev_rect->property_x1() = trackview.editor.frame_to_pixel ( - (nframes_t)ev.time); + (nframes_t)ev.time()); ev_rect->property_y1() = y1; ev_rect->property_x2() = trackview.editor.frame_to_pixel ( _region->length()); @@ -425,18 +434,18 @@ MidiRegionView::add_event (const MidiEvent& ev) if (_active_notes) _active_notes[note] = ev_rect; - } else if ((ev.buffer[0] & 0xF0) == MIDI_CMD_NOTE_OFF) { - const Byte& note = ev.buffer[1]; + } else if ((ev.buffer()[0] & 0xF0) == MIDI_CMD_NOTE_OFF) { + const Byte& note = ev.buffer()[1]; if (_active_notes && _active_notes[note]) { - _active_notes[note]->property_x2() = trackview.editor.frame_to_pixel((nframes_t)ev.time); + _active_notes[note]->property_x2() = trackview.editor.frame_to_pixel((nframes_t)ev.time()); _active_notes[note]->property_outline_what() = (guint32) 0xF; // all edges _active_notes[note] = NULL; } } } else if (mtv->note_mode() == Percussive) { - const Byte& note = ev.buffer[1]; - const double x = trackview.editor.frame_to_pixel((nframes_t)ev.time); + const Byte& note = ev.buffer()[1]; + const double x = trackview.editor.frame_to_pixel((nframes_t)ev.time()); const double y = trackview.height - (pixel_range * (note - view->lowest_note() + 1)) - footer_height - 3.0; @@ -477,12 +486,6 @@ MidiRegionView::add_note (const MidiModel::Note& note) assert(note.time() < _region->length()); //assert(note.time() + note.duration < _region->length()); - /*printf("Event, time = %f, size = %zu, data = ", ev.time, ev.size); - for (size_t i=0; i < ev.size; ++i) { - printf("%X ", ev.buffer[i]); - } - printf("\n\n");*/ - MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview); MidiStreamView* const view = mtv->midi_view(); ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group(); @@ -494,6 +497,10 @@ MidiRegionView::add_note (const MidiModel::Note& note) const uint32_t fill = RGBA_TO_UINT(0xE0 + note.velocity()/127.0 * 0x10, 0xE0, 0xE0, fill_alpha); const uint8_t outline_alpha = 0x80 + (uint8_t)(note.velocity()); const uint32_t outline = RGBA_TO_UINT(0xE0 + note.velocity()/127.0 * 0x10, 0xE0, 0xE0, outline_alpha); + + //printf("Range: %d\n", note_range); + //printf("Event, time = %f, note = %d\n", note.time(), note.note()); + if (mtv->note_mode() == Sustained) { const double y1 = trackview.height - (pixel_range * (note.note() - view->lowest_note() + 1)) diff --git a/gtk2_ardour/midi_streamview.cc b/gtk2_ardour/midi_streamview.cc index 51a0543d18..31a36ebd39 100644 --- a/gtk2_ardour/midi_streamview.cc +++ b/gtk2_ardour/midi_streamview.cc @@ -76,7 +76,7 @@ MidiStreamView::~MidiStreamView () RegionView* -MidiStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait_for_waves) +MidiStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wfd) { boost::shared_ptr<MidiRegion> region = boost::dynamic_pointer_cast<MidiRegion> (r); @@ -93,6 +93,7 @@ MidiStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait /* great. we already have a MidiRegionView for this Region. use it again. */ (*i)->set_valid (true); + (*i)->enable_display(wfd); display_region(dynamic_cast<MidiRegionView*>(*i)); return NULL; @@ -101,14 +102,14 @@ MidiStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait region_view = new MidiRegionView (canvas_group, _trackview, region, _samples_per_unit, region_color); - - region_view->init (region_color, wait_for_waves); + + region_view->init (region_color, false); region_views.push_front (region_view); /* follow global waveform setting */ - // FIXME - //region_view->set_waveform_visible(_trackview.editor.show_waveforms()); + if (wfd) + region_view->enable_display(true); /* display events and find note range */ display_region(region_view); @@ -150,6 +151,7 @@ MidiStreamView::redisplay_diskstream () list<RegionView *>::iterator i, tmp; for (i = region_views.begin(); i != region_views.end(); ++i) { + (*i)->enable_display(false); (*i)->set_valid (false); } @@ -168,6 +170,7 @@ MidiStreamView::redisplay_diskstream () delete *i; region_views.erase (i); } else { + (*i)->enable_display(true); (*i)->set_y_position_and_height(0, height); // apply note range } diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc index 87b384bcd7..27ae6ca7bf 100644 --- a/gtk2_ardour/region_view.cc +++ b/gtk2_ardour/region_view.cc @@ -72,6 +72,7 @@ RegionView::RegionView (ArdourCanvas::Group* parent, , editor(0) , current_visible_sync_position(0.0) , valid(false) + , _enable_display(false) , _pixel_width(1.0) , in_destructor(false) , wait_for_data(false) @@ -87,6 +88,7 @@ RegionView::RegionView (const RegionView& other) editor = other.editor; current_visible_sync_position = other.current_visible_sync_position; valid = false; + _enable_display = false; _pixel_width = other._pixel_width; } @@ -102,6 +104,7 @@ RegionView::RegionView (ArdourCanvas::Group* parent, , editor(0) , current_visible_sync_position(0.0) , valid(false) + , _enable_display(false) , _pixel_width(1.0) , in_destructor(false) , wait_for_data(false) @@ -111,9 +114,10 @@ RegionView::RegionView (ArdourCanvas::Group* parent, void RegionView::init (Gdk::Color& basic_color, bool wfd) { - valid = true; - in_destructor = false; - wait_for_data = wfd; + valid = true; + _enable_display = false; + in_destructor = false; + wait_for_data = wfd; compute_colors (basic_color); @@ -138,6 +142,9 @@ RegionView::init (Gdk::Color& basic_color, bool wfd) reset_width_dependent_items ((double) _region->length() / samples_per_unit); + if (wfd) + _enable_display = true; + set_y_position_and_height (0, trackview.height - 2); _region->StateChanged.connect (mem_fun(*this, &RegionView::region_changed)); diff --git a/gtk2_ardour/region_view.h b/gtk2_ardour/region_view.h index 4bbd68eef0..426529c528 100644 --- a/gtk2_ardour/region_view.h +++ b/gtk2_ardour/region_view.h @@ -82,6 +82,8 @@ class RegionView : public TimeAxisViewItem virtual void entered () {} virtual void exited () {} + + void enable_display(bool yn) { _enable_display = yn; } static sigc::signal<void,RegionView*> RegionViewGoingAway; sigc::signal<void> GoingAway; @@ -127,7 +129,8 @@ class RegionView : public TimeAxisViewItem vector<ControlPoint *> control_points; double current_visible_sync_position; - bool valid; ///< see StreamView::redisplay_diskstream() + bool valid; ///< see StreamView::redisplay_diskstream() + bool _enable_display; ///< see StreamView::redisplay_diskstream() double _pixel_width; bool in_destructor; diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc index 5220b80c10..34c1e4a1c9 100644 --- a/gtk2_ardour/streamview.cc +++ b/gtk2_ardour/streamview.cc @@ -153,8 +153,7 @@ StreamView::set_samples_per_unit (gdouble spp) void StreamView::add_region_view (boost::shared_ptr<Region> r) { - add_region_view_internal (r, true); - update_contents_y_position_and_height (); + add_region_view_internal (r, false); } void |