summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-08-01 20:50:09 +0000
committerDavid Robillard <d@drobilla.net>2007-08-01 20:50:09 +0000
commitd7db3f757fde92126ef9886370ce604992b7e974 (patch)
tree4ac58366ad0a9980756c23ef58e413ce54bf395f /gtk2_ardour
parent3f421ac45025a856f03b779363f8f5f60b837b1e (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.cc5
-rw-r--r--gtk2_ardour/canvas-midi-event.cc3
-rw-r--r--gtk2_ardour/midi_region_view.cc71
-rw-r--r--gtk2_ardour/midi_streamview.cc13
-rw-r--r--gtk2_ardour/region_view.cc13
-rw-r--r--gtk2_ardour/region_view.h5
-rw-r--r--gtk2_ardour/streamview.cc3
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