X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fmidi_region_view.cc;h=0ac2dfc43afe5b7cc430e39be33e09318bd2816f;hb=4d94305cc904cc2cce33d62050f351fe80f0d517;hp=7dcba64baea63a42d53b5bfbb678563f3418117a;hpb=49763a55c9bcbff2cb7844f36df777bbfadab172;p=ardour.git diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 7dcba64bae..0ac2dfc43a 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -69,7 +69,10 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView & , _mouse_state(None) , _pressed_button(0) { + group->lower_to_bottom(); _note_group->raise_to_top(); + + frame->property_fill_color_rgba() = 0xff000033; } MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr r, double spu, Gdk::Color& basic_color, TimeAxisViewItem::Visibility visibility) @@ -149,6 +152,7 @@ MidiRegionView::canvas_event(GdkEvent* ev) switch (ev->type) { case GDK_KEY_PRESS: + cout << "KEY" << endl; if (ev->key.keyval == GDK_Delete && !delete_mod) { delete_mod = true; original_mode = trackview.editor.current_midi_edit_mode(); @@ -302,7 +306,7 @@ MidiRegionView::canvas_event(GdkEvent* ev) clear_selection(); break; case MidiEditPencil: - trackview.editor.snap_to(event_frame); + trackview.editor.snap_to(event_frame, -1); event_x = trackview.editor.frame_to_pixel(event_frame); create_note_at(event_x, event_y, _default_note_length); default: @@ -359,9 +363,9 @@ MidiRegionView::create_note_at(double x, double y, double dur) //double dur = m.frames_per_bar(t, trackview.session().frame_rate()) / m.beats_per_bar(); // Add a 1 beat long note (for now) - const Note new_note(stamp, dur, (uint8_t)note, 0x40); + const boost::shared_ptr new_note(new Note(0, stamp, dur, (uint8_t)note, 0x40)); - view->update_bounds(new_note.note()); + view->update_bounds(new_note->note()); MidiModel::DeltaCommand* cmd = _model->new_delta_command("add note"); cmd->add(new_note); @@ -377,6 +381,14 @@ MidiRegionView::clear_events() for (std::vector::iterator i = _events.begin(); i != _events.end(); ++i) delete *i; + MidiGhostRegion* gr; + + for(vector::iterator g = ghosts.begin(); g != ghosts.end(); ++g) { + if((gr = dynamic_cast(*g)) != 0) { + gr->clear_events(); + } + } + _events.clear(); } @@ -406,7 +418,7 @@ MidiRegionView::redisplay_model() _model->read_lock(); for (size_t i=0; i < _model->n_notes(); ++i) - add_note(_model->note_at(i), false); + add_note(_model->note_at(i)); end_write(); @@ -502,11 +514,23 @@ MidiRegionView::set_y_position_and_height (double y, double h) for (std::vector::const_iterator i = _events.begin(); i != _events.end(); ++i) { CanvasNote* note = dynamic_cast(*i); if (note && note->note()) { - const double y1 = midi_stream_view()->note_to_y(note->note()->note()); - const double y2 = y1 + floor(midi_stream_view()->note_height()); - - note->property_y1() = y1; - note->property_y2() = y2; + if(note->note()->note() < midi_stream_view()->lowest_note() || + note->note()->note() > midi_stream_view()->highest_note()) { + if(canvas_item_visible(note)) { + note->hide(); + } + } + else { + const double y1 = midi_stream_view()->note_to_y(note->note()->note()); + const double y2 = y1 + floor(midi_stream_view()->note_height()); + + if(!canvas_item_visible(note)) { + note->show(); + } + + note->property_y1() = y1; + note->property_y2() = y2; + } } } @@ -519,18 +543,37 @@ MidiRegionView::set_y_position_and_height (double y, double h) } GhostRegion* -MidiRegionView::add_ghost (AutomationTimeAxisView& atv) +MidiRegionView::add_ghost (TimeAxisView& tv) { RouteTimeAxisView* rtv = dynamic_cast(&trackview); + CanvasNote* note; assert(rtv); double unit_position = _region->position () / samples_per_unit; - GhostRegion* ghost = new GhostRegion (atv, unit_position); + MidiTimeAxisView* mtv = dynamic_cast(&tv); + MidiGhostRegion* ghost; + + if(mtv && mtv->midi_view()) { + /* if ghost is inserted into midi track, use a dedicated midi ghost canvas group. + this is because it's nice to have midi notes on top of the note lines and + audio waveforms under it. + */ + ghost = new MidiGhostRegion (*mtv->midi_view(), trackview, unit_position); + } + else { + ghost = new MidiGhostRegion (tv, trackview, unit_position); + } ghost->set_height (); ghost->set_duration (_region->length() / samples_per_unit); ghosts.push_back (ghost); + for (std::vector::iterator i = _events.begin(); i != _events.end(); ++i) { + if((note = dynamic_cast(*i)) != 0) { + ghost->add_note(note); + } + } + ghost->GoingAway.connect (mem_fun(*this, &MidiRegionView::remove_ghost)); return ghost; @@ -596,30 +639,35 @@ MidiRegionView::extend_active_notes() * event arrives, to properly display the note. */ void -MidiRegionView::add_note(const Note& note, bool copy_note) +MidiRegionView::add_note(const boost::shared_ptr note) { - assert(note.time() >= 0); - //assert(note.time() < _region->length()); + assert(note->time() >= 0); + //assert(note->time() < _region->length()); + assert(midi_view()->note_mode() == Sustained || midi_view()->note_mode() == Percussive); ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group(); if (midi_view()->note_mode() == Sustained) { - const double y1 = midi_stream_view()->note_to_y(note.note()); + + //cerr << "MRV::add_note sustained " << note->note() << " @ " << note->time() + // << " .. " << note->end_time() << endl; + + const double y1 = midi_stream_view()->note_to_y(note->note()); - CanvasNote* ev_rect = new CanvasNote(*this, *group, ¬e, copy_note); - ev_rect->property_x1() = trackview.editor.frame_to_pixel((nframes_t)note.time()); + CanvasNote* ev_rect = new CanvasNote(*this, *group, note); + ev_rect->property_x1() = trackview.editor.frame_to_pixel((nframes_t)note->time()); ev_rect->property_y1() = y1; - if (note.duration() > 0) - ev_rect->property_x2() = trackview.editor.frame_to_pixel((nframes_t)(note.end_time())); + if (note->duration() > 0) + ev_rect->property_x2() = trackview.editor.frame_to_pixel((nframes_t)(note->end_time())); else ev_rect->property_x2() = trackview.editor.frame_to_pixel(_region->length()); ev_rect->property_y2() = y1 + floor(midi_stream_view()->note_height()); - ev_rect->property_fill_color_rgba() = note_fill_color(note.velocity()); - ev_rect->property_outline_color_rgba() = note_outline_color(note.velocity()); + ev_rect->property_fill_color_rgba() = note_fill_color(note->velocity()); + ev_rect->property_outline_color_rgba() = note_outline_color(note->velocity()); - if (note.duration() == 0) { - _active_notes[note.note()] = ev_rect; + if (note->duration() == 0) { + _active_notes[note->note()] = ev_rect; /* outline all but right edge */ ev_rect->property_outline_what() = (guint32) (0x1 & 0x4 & 0x8); } else { @@ -630,17 +678,30 @@ MidiRegionView::add_note(const Note& note, bool copy_note) ev_rect->show(); _events.push_back(ev_rect); + MidiGhostRegion* gr; + + for(vector::iterator g = ghosts.begin(); g != ghosts.end(); ++g) { + if((gr = dynamic_cast(*g)) != 0) { + gr->add_note(ev_rect); + } + } + } else if (midi_view()->note_mode() == Percussive) { + + //cerr << "MRV::add_note percussive " << note->note() << " @ " << note->time() + // << " .. " << note->end_time() << endl; + const double diamond_size = midi_stream_view()->note_height() / 2.0; - const double x = trackview.editor.frame_to_pixel((nframes_t)note.time()); - const double y = midi_stream_view()->note_to_y(note.note()) + ((diamond_size-2) / 4.0); + const double x = trackview.editor.frame_to_pixel((nframes_t)note->time()); + const double y = midi_stream_view()->note_to_y(note->note()) + ((diamond_size-2) / 4.0); CanvasHit* ev_diamond = new CanvasHit(*this, *group, diamond_size); ev_diamond->move(x, y); ev_diamond->show(); - ev_diamond->property_fill_color_rgba() = note_fill_color(note.velocity()); - ev_diamond->property_outline_color_rgba() = note_outline_color(note.velocity()); + ev_diamond->property_fill_color_rgba() = note_fill_color(note->velocity()); + ev_diamond->property_outline_color_rgba() = note_outline_color(note->velocity()); _events.push_back(ev_diamond); + } } @@ -651,7 +712,7 @@ MidiRegionView::delete_selection() for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) if ((*i)->selected()) - _delta_command->remove(*(*i)->note()); + _delta_command->remove((*i)->note()); _selection.clear(); } @@ -755,10 +816,10 @@ MidiRegionView::note_dropped(CanvasMidiEvent* ev, double dt, uint8_t dnote) for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) { command_remove_note(*i); - Note copy(*(*i)->note()); + const boost::shared_ptr copy(new Note(*(*i)->note().get())); - copy.set_time((*i)->note()->time() + dt); - copy.set_note((*i)->note()->note() + dnote); + copy->set_time((*i)->note()->time() + dt); + copy->set_note((*i)->note()->note() + dnote); command_add_note(copy); } @@ -773,7 +834,7 @@ MidiRegionView::note_entered(ArdourCanvas::CanvasMidiEvent* ev) if (ev->note() && _mouse_state == EraseTouchDragging) { start_delta_command(); ev->selected(true); - _delta_command->remove(*ev->note()); + _delta_command->remove(ev->note()); } else if (_mouse_state == SelectTouchDragging) { note_selected(ev, true); } @@ -788,3 +849,14 @@ MidiRegionView::switch_source(boost::shared_ptr src) display_model(msrc->model()); } +void +MidiRegionView::set_frame_color() +{ + if (frame) { + if (_selected && should_show_selection) { + frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_SelectedFrameBase.get(); + } else { + frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiFrameBase.get(); + } + } +}