summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-07-31 02:16:46 +0000
committerDavid Robillard <d@drobilla.net>2007-07-31 02:16:46 +0000
commitbb33e5d9f805dadf96cf988de9fcc5c89545add7 (patch)
tree9db98c772d176f12937bca49d448c28b0ce6e1cc /gtk2_ardour
parentea5a4eac105d50000969aa08a35ccd49a40ccd86 (diff)
Get MidiRegionView's hands on MidiModel for editing operations to come.
MIDI select rectangle. Add notes on a proper click only (not mouse down). Fix crash when dragging from region to outside region. git-svn-id: svn://localhost/ardour2/trunk@2196 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/canvas-midi-event.cc2
-rw-r--r--gtk2_ardour/midi_region_view.cc118
-rw-r--r--gtk2_ardour/midi_region_view.h11
-rw-r--r--gtk2_ardour/midi_streamview.cc22
-rw-r--r--gtk2_ardour/midi_streamview.h2
5 files changed, 83 insertions, 72 deletions
diff --git a/gtk2_ardour/canvas-midi-event.cc b/gtk2_ardour/canvas-midi-event.cc
index 6c5c0598f3..73c2b29925 100644
--- a/gtk2_ardour/canvas-midi-event.cc
+++ b/gtk2_ardour/canvas-midi-event.cc
@@ -74,7 +74,7 @@ CanvasMidiEvent::on_event(GdkEvent* ev)
case GDK_MOTION_NOTIFY:
event_x = ev->motion.x;
event_y = ev->motion.y;
- cerr << "MOTION @ " << event_x << ", " << event_y << endl;
+ //cerr << "MOTION @ " << event_x << ", " << event_y << endl;
_item->property_parent().get_value()->w2i(event_x, event_y);
switch (_state) {
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index 3110cdd600..755e896f6c 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -74,10 +74,9 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
void
MidiRegionView::init (Gdk::Color& basic_color, bool wfd)
{
- // FIXME: Some redundancy here with RegionView::init. Need to figure out
- // where order is important and where it isn't...
+ if (wfd)
+ _model = midi_region()->midi_source(0)->model();
- // FIXME
RegionView::init(basic_color, /*wfd*/false);
compute_colors (basic_color);
@@ -94,13 +93,10 @@ MidiRegionView::init (Gdk::Color& basic_color, bool wfd)
set_colors ();
- if (wfd) {
- midi_region()->midi_source(0)->load_model();
- display_events();
- }
+ if (wfd)
+ redisplay_model();
- midi_region()->midi_source(0)->model()->ContentsChanged.connect(sigc::mem_fun(
- this, &MidiRegionView::redisplay_model));
+ _model->ContentsChanged.connect(sigc::mem_fun(this, &MidiRegionView::redisplay_model));
group->signal_event().connect (mem_fun (this, &MidiRegionView::canvas_event), false);
}
@@ -109,10 +105,13 @@ bool
MidiRegionView::canvas_event(GdkEvent* ev)
{
enum State { None, Pressed, Dragging };
+ static int press_button = 0;
static State _state;
static double last_x, last_y;
double event_x, event_y;
+
+ static ArdourCanvas::SimpleRect* select_rect = NULL;
if (trackview.editor.current_mouse_mode() != MouseNote)
return false;
@@ -120,29 +119,40 @@ MidiRegionView::canvas_event(GdkEvent* ev)
switch (ev->type) {
case GDK_BUTTON_PRESS:
//group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, ev->button.time);
- // This should happen on release...
- if (ev->button.button == 1)
- create_note_at(ev->button.x, ev->button.y);
-
_state = Pressed;
+ press_button = ev->button.button;
+ cerr << "PRESSED: " << press_button << endl;
return true;
case GDK_MOTION_NOTIFY:
- cerr << "MOTION, _state = " << _state << endl;
event_x = ev->motion.x;
event_y = ev->motion.y;
group->w2i(event_x, event_y);
switch (_state) {
- case Pressed:
- cerr << "SELECT DRAG START\n";
- group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
- Gdk::Cursor(Gdk::FLEUR), ev->motion.time);
+ case Pressed: // Drag start
+ cerr << "PRESSED MOTION: " << press_button << endl;
+ if (press_button == 1) { // Select rect start
+ group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
+ Gdk::Cursor(Gdk::FLEUR), ev->motion.time);
+ _state = Dragging;
+ last_x = event_x;
+ last_y = event_y;
+
+ select_rect = new ArdourCanvas::SimpleRect(*group);
+ select_rect->property_x1() = event_x;
+ select_rect->property_y1() = event_y;
+ select_rect->property_x2() = event_x;
+ select_rect->property_y2() = event_y;
+ select_rect->property_outline_color_rgba() = 0xFF000099;
+ select_rect->property_fill_color_rgba() = 0xFFDDDD33;
+
+ return true;
+ }
_state = Dragging;
- last_x = event_x;
- last_y = event_y;
- return true;
- case Dragging:
+ break;
+
+ case Dragging: // Select rect motion
if (ev->motion.is_hint) {
int t_x;
int t_y;
@@ -152,30 +162,33 @@ MidiRegionView::canvas_event(GdkEvent* ev)
event_y = t_y;
}
- cerr << "SELECT DRAG" << endl;
- //move(event_x - last_x, event_y - last_y);
+ if (select_rect) {
+ select_rect->property_x2() = event_x;
+ select_rect->property_y2() = event_y;
+ }
last_x = event_x;
last_y = event_y;
return true;
default:
+ _state = None;
break;
}
break;
case GDK_BUTTON_RELEASE:
- cerr << "RELEASE\n";
group->ungrab(ev->button.time);
switch (_state) {
- case Pressed:
- cerr << "CLICK\n";
- //create_note_at(ev->button.x, ev->button.y);
+ case Pressed: // Clicked
+ if (ev->button.button == 1)
+ create_note_at(ev->button.x, ev->button.y);
_state = None;
return true;
- case Dragging:
- cerr << "SELECT RECT DONE\n";
+ case Dragging: // Select rect done
_state = None;
+ delete select_rect;
+ select_rect = NULL;
return true;
default:
break;
@@ -214,14 +227,12 @@ MidiRegionView::create_note_at(double x, double y)
const Tempo& t = trackview.session().tempo_map().tempo_at(stamp);
double dur = m.frames_per_bar(t, trackview.session().frame_rate()) / m.beats_per_bar();
- MidiModel* model = midi_region()->midi_source(0)->model();
-
// 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();
+ _model->begin_command();
+ _model->add_note(new_note);
+ _model->finish_command();
view->update_bounds(new_note.note());
@@ -230,14 +241,6 @@ MidiRegionView::create_note_at(double x, double y)
void
-MidiRegionView::redisplay_model()
-{
- clear_events();
- display_events();
-}
-
-
-void
MidiRegionView::clear_events()
{
for (std::vector<ArdourCanvas::Item*>::iterator i = _events.begin(); i != _events.end(); ++i)
@@ -248,16 +251,29 @@ MidiRegionView::clear_events()
void
-MidiRegionView::display_events()
+MidiRegionView::display_model(boost::shared_ptr<MidiModel> model)
+{
+ _model = model;
+ redisplay_model();
+}
+
+
+void
+MidiRegionView::redisplay_model()
{
clear_events();
- begin_write();
+ if (_model) {
+ begin_write();
- for (size_t i=0; i < midi_region()->midi_source(0)->model()->n_notes(); ++i)
- add_note(midi_region()->midi_source(0)->model()->note_at(i));
+ for (size_t i=0; i < _model->n_notes(); ++i)
+ add_note(_model->note_at(i));
- end_write();
+ end_write();
+ } else {
+ assert(false);
+ warning << "MidiRegionView::redisplay_model called without a model" << endmsg;
+ }
}
@@ -283,7 +299,7 @@ MidiRegionView::region_resized (Change what_changed)
if (what_changed & ARDOUR::PositionChanged) {
- display_events();
+ redisplay_model();
} else if (what_changed & Change (StartChanged)) {
@@ -302,7 +318,7 @@ MidiRegionView::reset_width_dependent_items (double pixel_width)
RegionView::reset_width_dependent_items(pixel_width);
assert(_pixel_width == pixel_width);
- display_events();
+ redisplay_model();
}
void
@@ -310,7 +326,7 @@ MidiRegionView::set_y_position_and_height (double y, double h)
{
RegionView::set_y_position_and_height(y, h - 1);
- display_events();
+ redisplay_model();
if (name_text) {
name_text->raise_to_top();
diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h
index bfac56209d..9207ca6b21 100644
--- a/gtk2_ardour/midi_region_view.h
+++ b/gtk2_ardour/midi_region_view.h
@@ -37,6 +37,7 @@
namespace ARDOUR {
class MidiRegion;
+ class MidiModel;
};
class MidiTimeAxisView;
@@ -54,7 +55,7 @@ class MidiRegionView : public RegionView
~MidiRegionView ();
- virtual void init (Gdk::Color& base_color, bool wait_for_data = false);
+ virtual void init (Gdk::Color& basic_color, bool wfd);
boost::shared_ptr<ARDOUR::MidiRegion> midi_region() const;
@@ -73,6 +74,8 @@ class MidiRegionView : public RegionView
void create_note_at(double x, double y);
+ void display_model(boost::shared_ptr<ARDOUR::MidiModel> model);
+
protected:
/* this constructor allows derived types
@@ -97,14 +100,14 @@ class MidiRegionView : public RegionView
private:
void redisplay_model();
- void display_events();
void clear_events();
bool canvas_event(GdkEvent* ev);
bool note_canvas_event(GdkEvent* ev);
- std::vector<ArdourCanvas::Item*> _events;
- ArdourCanvas::CanvasNote** _active_notes;
+ boost::shared_ptr<ARDOUR::MidiModel> _model;
+ std::vector<ArdourCanvas::Item*> _events;
+ ArdourCanvas::CanvasNote** _active_notes;
};
#endif /* __gtk_ardour_midi_region_view_h__ */
diff --git a/gtk2_ardour/midi_streamview.cc b/gtk2_ardour/midi_streamview.cc
index 7d3c05a876..51a0543d18 100644
--- a/gtk2_ardour/midi_streamview.cc
+++ b/gtk2_ardour/midi_streamview.cc
@@ -93,15 +93,12 @@ 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);
- display_region(dynamic_cast<MidiRegionView*>(*i), false);
+ display_region(dynamic_cast<MidiRegionView*>(*i));
return NULL;
}
}
- // can't we all just get along?
- assert(_trackview.midi_track()->mode() != Destructive);
-
region_view = new MidiRegionView (canvas_group, _trackview, region,
_samples_per_unit, region_color);
@@ -114,7 +111,7 @@ MidiStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait
//region_view->set_waveform_visible(_trackview.editor.show_waveforms());
/* display events and find note range */
- display_region(region_view, false);
+ display_region(region_view);
/* always display at least 1 octave range */
_highest_note = max(_highest_note, static_cast<uint8_t>(_lowest_note + 11));
@@ -128,27 +125,22 @@ MidiStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait
}
void
-MidiStreamView::display_region(MidiRegionView* region_view, bool redisplay_events)
+MidiStreamView::display_region(MidiRegionView* region_view)
{
if ( ! region_view)
return;
- if (redisplay_events)
- region_view->begin_write();
-
boost::shared_ptr<MidiSource> source(region_view->midi_region()->midi_source(0));
+ source->load_model();
+ // Find our note range
for (size_t i=0; i < source->model()->n_notes(); ++i) {
const MidiModel::Note& note = source->model()->note_at(i);
-
update_bounds(note.note());
-
- if (redisplay_events)
- region_view->add_note(note);
}
- if (redisplay_events)
- region_view->end_write();
+ // Display region contents
+ region_view->display_model(source->model());
}
// FIXME: code duplication with AudioStreamView
diff --git a/gtk2_ardour/midi_streamview.h b/gtk2_ardour/midi_streamview.h
index b8ae33cf46..baaf33d67d 100644
--- a/gtk2_ardour/midi_streamview.h
+++ b/gtk2_ardour/midi_streamview.h
@@ -79,7 +79,7 @@ class MidiStreamView : public StreamView
void update_rec_regions (boost::shared_ptr<ARDOUR::MidiBuffer> data, jack_nframes_t start, jack_nframes_t dur);
RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves);
- void display_region(MidiRegionView* region_view, bool redisplay_events);
+ void display_region(MidiRegionView* region_view);
void color_handler ();