summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2010-07-06 11:33:27 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2010-07-06 11:33:27 +0000
commit2f9184d65395da75a43ea21ffb5f11b8d577d27a (patch)
treea50a5d5a4bd8b09ca9bd1f3bb6754b7bf86cd3c5 /gtk2_ardour
parent2f11b367cac5fe05f5f69e2c73946312d8145260 (diff)
beat slicing patch #1 from lincoln spiteri
git-svn-id: svn://localhost/ardour2/branches/3.0@7381 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/ardour.menus.in9
-rw-r--r--gtk2_ardour/audio_region_view.cc111
-rw-r--r--gtk2_ardour/audio_region_view.h8
-rw-r--r--gtk2_ardour/editor.h14
-rw-r--r--gtk2_ardour/editor_actions.cc17
-rw-r--r--gtk2_ardour/editor_canvas_events.cc39
-rw-r--r--gtk2_ardour/editor_drag.cc70
-rw-r--r--gtk2_ardour/editor_drag.h27
-rw-r--r--gtk2_ardour/editor_items.h1
-rw-r--r--gtk2_ardour/editor_mouse.cc28
-rw-r--r--gtk2_ardour/editor_ops.cc357
-rw-r--r--gtk2_ardour/midi_streamview.cc15
-rw-r--r--gtk2_ardour/mnemonic-us.bindings.in3
-rw-r--r--gtk2_ardour/public_editor.h1
-rw-r--r--gtk2_ardour/rhythm_ferret.cc61
-rw-r--r--gtk2_ardour/rhythm_ferret.h6
-rw-r--r--gtk2_ardour/time_axis_view.cc56
-rw-r--r--gtk2_ardour/time_axis_view.h7
18 files changed, 678 insertions, 152 deletions
diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in
index e6ae76a74e..85df23ab14 100644
--- a/gtk2_ardour/ardour.menus.in
+++ b/gtk2_ardour/ardour.menus.in
@@ -172,12 +172,13 @@
<menuitem action='editor-delete'/>
<menuitem action='editor-crop'/>
<menuitem action='split-region'/>
+ <menuitem action='split-region-at-transients'/>
<menu action="SeparateMenu">
+ <menuitem action='separate-under-region'/>
<menuitem action='editor-separate'/>
<menuitem action='separate-from-loop'/>
<menuitem action='separate-from-punch'/>
<separator/>
- <menuitem action='split-region-at-transients'/>
</menu>
<menu action="AlignMenu">
<menuitem action='align-regions-start'/>
@@ -272,8 +273,14 @@
<menuitem action='set-punch-from-region'/>
<menuitem action='add-range-marker-from-region'/>
<menuitem action='add-range-markers-from-region'/>
+
+ <separator/>
+ <menuitem action='snap-regions-to-grid'/>
+ <menuitem action='close-region-gaps'/>
<separator/>
+ <menuitem action='place-transient' />
<menuitem action='toggle-rhythm-ferret'/>
+
</menu>
<menu action='TrackMenu'>
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc
index 802d9230fb..06621a20e2 100644
--- a/gtk2_ardour/audio_region_view.cc
+++ b/gtk2_ardour/audio_region_view.cc
@@ -254,6 +254,10 @@ AudioRegionView::~AudioRegionView ()
delete *i;
}
+ for (list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> >::iterator i = feature_lines.begin(); i != feature_lines.end(); ++i) {
+ delete ((*i).second);
+ }
+
/* all waveviews etc will be destroyed when the group is destroyed */
delete gain_line;
@@ -292,6 +296,9 @@ AudioRegionView::region_changed (const PropertyChange& what_changed)
if (what_changed.contains (ARDOUR::Properties::envelope_active)) {
envelope_active_changed ();
}
+ if (what_changed.contains (ARDOUR::Properties::valid_transients)) {
+ transients_changed ();
+ }
}
void
@@ -388,13 +395,26 @@ AudioRegionView::region_resized (const PropertyChange& what_changed)
}
for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
- if((agr = dynamic_cast<AudioGhostRegion*>(*i)) != 0) {
+ if ((agr = dynamic_cast<AudioGhostRegion*>(*i)) != 0) {
for (vector<WaveView*>::iterator w = agr->waves.begin(); w != agr->waves.end(); ++w) {
(*w)->property_region_start() = _region->start();
}
}
}
+
+ /* hide transient lines that extend beyond the region end */
+
+ list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> >::iterator l;
+
+ for (l = feature_lines.begin(); l != feature_lines.end(); ++l) {
+ if ((*l).first > _region->length()- 1){
+ (*l).second->hide();
+ }
+ else {
+ (*l).second->show();
+ }
+ }
}
}
@@ -425,6 +445,15 @@ AudioRegionView::reset_width_dependent_items (double pixel_width)
}
}
+ AnalysisFeatureList analysis_features = _region->transients();
+ AnalysisFeatureList::const_iterator i;
+ list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> >::iterator l;
+
+ for (i = analysis_features.begin(), l = feature_lines.begin(); i != analysis_features.end() && l != feature_lines.end(); ++i, ++l) {
+ (*l).second->property_x1() = trackview.editor().frame_to_pixel (*i);
+ (*l).second->property_x2() = trackview.editor().frame_to_pixel (*i);
+ }
+
reset_fade_shapes ();
}
@@ -501,6 +530,13 @@ AudioRegionView::set_height (gdouble height)
manage_zero_line ();
reset_fade_shapes ();
+
+ /* Update hights for any active feature lines */
+ list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> >::iterator l;
+
+ for (l = feature_lines.begin(); l != feature_lines.end(); ++l) {
+ (*l).second->property_y2() = _height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 1;
+ }
if (name_pixbuf) {
name_pixbuf->raise_to_top();
@@ -583,7 +619,7 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
float curve[npoints];
audio_region()->fade_in()->curve().get_vector (0, audio_region()->fade_in()->back()->when, curve, npoints);
- points = get_canvas_points ("fade in shape", npoints+3);
+ points = get_canvas_points ("fade in shape", npoints + 3);
if (_height >= NAME_HIGHLIGHT_THRESH) {
h = _height - NAME_HIGHLIGHT_SIZE;
@@ -682,7 +718,7 @@ AudioRegionView::reset_fade_out_shape_width (nframes_t width)
/* points *MUST* be in anti-clockwise order */
- points = get_canvas_points ("fade out shape", npoints+3);
+ points = get_canvas_points ("fade out shape", npoints + 3);
uint32_t pi, pc;
double xdelta = pwidth/npoints;
@@ -1380,3 +1416,72 @@ AudioRegionView::show_region_editor ()
editor->present ();
editor->show_all();
}
+
+void
+AudioRegionView::transients_changed ()
+{
+ AnalysisFeatureList analysis_features = _region->transients();
+
+ while (feature_lines.size() < analysis_features.size()) {
+ ArdourCanvas::SimpleLine* l = new ArdourCanvas::SimpleLine (*group);
+ l->property_color_rgba() = (guint) ARDOUR_UI::config()->canvasvar_ZeroLine.get();
+ feature_lines.push_back (make_pair(0, l));
+ }
+
+ while (feature_lines.size() > analysis_features.size()) {
+ ArdourCanvas::SimpleLine *line = feature_lines.back().second;
+ feature_lines.pop_back ();
+ delete line;
+ }
+
+ AnalysisFeatureList::const_iterator i;
+ list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> >::iterator l;
+
+ for (i = analysis_features.begin(), l = feature_lines.begin(); i != analysis_features.end() && l != feature_lines.end(); ++i, ++l) {
+ (*l).first = *i;
+ (*l).second->property_x1() = trackview.editor().frame_to_pixel (*i);
+ (*l).second->property_x2() = trackview.editor().frame_to_pixel (*i);
+ (*l).second->property_y1() = 2;
+ (*l).second->property_y2() = _height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 1;
+ (*l).second->set_data("regionview", this);
+ (*l).second->show ();
+ (*l).second->raise_to_top ();
+
+ (*l).second->signal_event().connect (sigc::bind (sigc::mem_fun (PublicEditor::instance(), &PublicEditor::canvas_feature_line_event), (*l).second, this));
+ }
+}
+
+void
+AudioRegionView::update_transient(float old_pos, float new_pos)
+{
+ /* Find frame at old pos, calulate new frame then update region transients*/
+ list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> >::iterator l;
+
+ for (l = feature_lines.begin(); l != feature_lines.end(); ++l) {
+ /* Simple line x1 has been updated in drag so we compare to new_pos */
+ if (rint(new_pos) == rint((*l).second->property_x1())) {
+
+ nframes64_t old_frame = (*l).first;
+ nframes64_t new_frame = trackview.editor().pixel_to_frame (new_pos);
+
+ _region->update_transient (old_frame, new_frame);
+
+ break;
+ }
+ }
+}
+
+void
+AudioRegionView::remove_transient(float pos)
+{
+ /* Find frame at old pos, calulate new frame then update region transients*/
+ list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> >::iterator l;
+
+ for (l = feature_lines.begin(); l != feature_lines.end(); ++l) {
+ /* Simple line x1 has been updated in drag so we compare to new_pos */
+ if (rint(pos) == rint((*l).second->property_x1())) {
+ _region->remove_transient ((*l).first);
+ break;
+ }
+ }
+} \ No newline at end of file
diff --git a/gtk2_ardour/audio_region_view.h b/gtk2_ardour/audio_region_view.h
index b00fb583fa..0e2b54130c 100644
--- a/gtk2_ardour/audio_region_view.h
+++ b/gtk2_ardour/audio_region_view.h
@@ -105,6 +105,9 @@ class AudioRegionView : public RegionView
void set_fade_visibility (bool);
void update_coverage_frames (LayerDisplay);
+
+ void update_transient(float old_pos, float new_pos);
+ void remove_transient(float pos);
void show_region_editor ();
@@ -127,6 +130,9 @@ class AudioRegionView : public RegionView
std::vector<ArdourCanvas::WaveView *> waves;
std::vector<ArdourCanvas::WaveView *> tmp_waves; ///< see ::create_waves()
+
+ std::list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> > feature_lines;
+
ArdourCanvas::Polygon* sync_mark; ///< polgyon for sync position
ArdourCanvas::SimpleLine* zero_line;
ArdourCanvas::Polygon* fade_in_shape;
@@ -169,6 +175,8 @@ class AudioRegionView : public RegionView
void color_handler ();
std::vector<GnomeCanvasWaveViewCache*> wave_caches;
+
+ void transients_changed();
private:
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 2300fe7c20..44e7289f6d 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -228,6 +228,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void new_region_from_selection ();
void separate_regions_between (const TimeSelection&);
void separate_region_from_selection ();
+ void separate_under_selected_regions ();
void separate_region_from_punch ();
void separate_region_from_loop ();
void separate_regions_using_location (ARDOUR::Location&);
@@ -921,10 +922,10 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void select_all_selectables_between (bool within);
void select_range_between ();
- boost::shared_ptr<ARDOUR::Region> find_next_region (nframes64_t, ARDOUR::RegionPoint, int32_t dir, TrackViewList&, TimeAxisView ** = 0);
- nframes64_t find_next_region_boundary (nframes64_t, int32_t dir, const TrackViewList&);
+ boost::shared_ptr<ARDOUR::Region> find_next_region (ARDOUR::framepos_t, ARDOUR::RegionPoint, int32_t dir, TrackViewList&, TimeAxisView ** = 0);
+ ARDOUR::framepos_t find_next_region_boundary (ARDOUR::framepos_t, int32_t dir, const TrackViewList&);
- std::vector<nframes64_t> region_boundary_cache;
+ std::vector<ARDOUR::framepos_t> region_boundary_cache;
void build_region_boundary_cache ();
Gtk::HBox top_hbox;
@@ -1124,6 +1125,11 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void cut ();
void copy ();
void paste (float times);
+
+ void place_transient ();
+ void remove_transient (ArdourCanvas::Item* item);
+ void snap_regions_to_grid ();
+ void close_region_gaps ();
int get_prefix (float&, bool&);
@@ -1364,6 +1370,7 @@ public:
bool canvas_frame_handle_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
+ bool canvas_feature_line_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*);
bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, RouteTimeAxisView*);
bool canvas_marker_event (GdkEvent* event,ArdourCanvas::Item*, Marker*);
bool canvas_zoom_rect_event (GdkEvent* event,ArdourCanvas::Item*);
@@ -2064,6 +2071,7 @@ public:
friend class EditorGroupTabs;
friend class EditorRoutes;
+ friend class RhythmFerret;
};
#endif /* __ardour_editor_h__ */
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index eeb604c2e5..f1d20fbed7 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -476,6 +476,15 @@ Editor::register_actions ()
act = ActionManager::register_action (editor_actions, "mute-unmute-region", _("Mute/Unmute Region"), sigc::mem_fun(*this, &Editor::kbd_mute_unmute_region));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::region_selection_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "snap-regions-to-grid", _("Snap Regions to Grid"), sigc::mem_fun(*this, &Editor::snap_regions_to_grid));
+ ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::region_selection_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "close-region-gaps", _("Close Region Gaps"), sigc::mem_fun(*this, &Editor::close_region_gaps));
+ ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::region_selection_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "place-transient", _("Place Transient"), sigc::mem_fun(*this, &Editor::place_transient));
+ ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::region_selection_sensitive_actions.push_back (act);
undo_action = act = ActionManager::register_action (editor_actions, "undo", _("Undo"), sigc::bind (sigc::mem_fun(*this, &Editor::undo), 1U));
ActionManager::session_sensitive_actions.push_back (act);
@@ -487,20 +496,28 @@ Editor::register_actions ()
act = ActionManager::register_action (editor_actions, "export-range", _("Export Range"), sigc::mem_fun(*this, &Editor::export_range));
ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "separate-under-region", _("Separate Under Selected Regions"), sigc::mem_fun(*this, &Editor::separate_under_selected_regions));
+ ActionManager::session_sensitive_actions.push_back (act);
+
act = ActionManager::register_action (editor_actions, "editor-separate", _("Separate"), sigc::mem_fun(*this, &Editor::separate_region_from_selection));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
+
act = ActionManager::register_action (editor_actions, "separate-from-punch", _("Separate Using Punch Range"), sigc::mem_fun(*this, &Editor::separate_region_from_punch));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
+
act = ActionManager::register_action (editor_actions, "separate-from-loop", _("Separate Using Loop Range"), sigc::mem_fun(*this, &Editor::separate_region_from_loop));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
+
act = ActionManager::register_action (editor_actions, "editor-crop", _("Crop"), sigc::mem_fun(*this, &Editor::crop_region_to_selection));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
+
act = ActionManager::register_action (editor_actions, "editor-cut", _("Cut"), sigc::mem_fun(*this, &Editor::cut));
ActionManager::session_sensitive_actions.push_back (act);
+
/* Note: for now, editor-delete does the exact same thing as editor-cut */
act = ActionManager::register_action (editor_actions, "editor-delete", _("Delete"), sigc::mem_fun(*this, &Editor::cut));
ActionManager::session_sensitive_actions.push_back (act);
diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc
index 0b9d8a3793..34a73d318c 100644
--- a/gtk2_ardour/editor_canvas_events.cc
+++ b/gtk2_ardour/editor_canvas_events.cc
@@ -900,6 +900,45 @@ Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item
}
bool
+Editor::canvas_feature_line_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView *rv)
+{
+ bool ret = false;
+
+ switch (event->type) {
+ case GDK_BUTTON_PRESS:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ clicked_regionview = 0;
+ clicked_control_point = 0;
+ clicked_axisview = 0;
+ clicked_routeview = 0; //dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
+ ret = button_press_handler (item, event, FeatureLineItem);
+ break;
+
+ case GDK_BUTTON_RELEASE:
+ ret = button_release_handler (item, event, FeatureLineItem);
+ break;
+
+ case GDK_MOTION_NOTIFY:
+ ret = motion_handler (item, event);
+ break;
+
+ case GDK_ENTER_NOTIFY:
+ ret = enter_handler (item, event, FeatureLineItem);
+ break;
+
+ case GDK_LEAVE_NOTIFY:
+ ret = leave_handler (item, event, FeatureLineItem);
+ break;
+
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+bool
Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* /*marker*/)
{
return typed_event (item, event, MarkerItem);
diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc
index b01c79ad91..2aaeaa1038 100644
--- a/gtk2_ardour/editor_drag.cc
+++ b/gtk2_ardour/editor_drag.cc
@@ -2935,6 +2935,76 @@ LineDrag::aborted ()
_line->reset ();
}
+FeatureLineDrag::FeatureLineDrag (Editor* e, ArdourCanvas::Item* i)
+ : Drag (e, i),
+ _line (0),
+ _cumulative_x_drag (0)
+{
+
+}
+void
+FeatureLineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
+{
+
+ Drag::start_grab (event);
+
+ _line = reinterpret_cast<SimpleLine*> (_item);
+ assert (_line);
+
+ /* need to get x coordinate in terms of parent (AudioRegionView) origin. */
+
+ double cx = event->button.x;
+ double cy = event->button.y;
+
+ _item->property_parent().get_value()->w2i(cx, cy);
+
+ /* store grab start in parent frame */
+ _region_view_grab_x = cx;
+
+ _before = _line->property_x1();
+
+ _arv = reinterpret_cast<AudioRegionView*> (_item->get_data ("regionview"));
+
+ _max_x = _editor->frame_to_pixel(_arv->get_duration());
+}
+
+void
+FeatureLineDrag::motion (GdkEvent* event, bool)
+{
+ double dx = _drags->current_pointer_x() - last_pointer_x();
+
+ double cx = _region_view_grab_x + _cumulative_x_drag + dx;
+
+ _cumulative_x_drag += dx;
+
+ /* Clamp the min and max extent of the drag to keep it within the region view bounds */
+
+ if (cx > _max_x){
+ cx = _max_x;
+ }
+ else if(cx < 0){
+ cx = 0;
+ }
+
+ _line->property_x1() = cx;
+ _line->property_x2() = cx;
+
+ _before = _line->property_x1();
+}
+
+void
+FeatureLineDrag::finished (GdkEvent* event, bool)
+{
+ _arv = reinterpret_cast<AudioRegionView*> (_item->get_data ("regionview"));
+ _arv->update_transient(_before, _line->property_x1());
+}
+
+void
+FeatureLineDrag::aborted ()
+{
+ //_line->reset ();
+}
+
void
RubberbandSelectDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{
diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h
index f1634ffb64..9e206cfebf 100644
--- a/gtk2_ardour/editor_drag.h
+++ b/gtk2_ardour/editor_drag.h
@@ -604,6 +604,33 @@ private:
double _cumulative_y_drag;
};
+/** Transient feature line drags*/
+class FeatureLineDrag : public Drag
+{
+public:
+ FeatureLineDrag (Editor *e, ArdourCanvas::Item *i);
+
+ void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
+ void motion (GdkEvent *, bool);
+ void finished (GdkEvent *, bool);
+ void aborted ();
+
+ bool active (Editing::MouseMode) {
+ return true;
+ }
+
+private:
+
+ ArdourCanvas::SimpleLine* _line;
+ AudioRegionView* _arv;
+
+ double _region_view_grab_x;
+ double _cumulative_x_drag;
+
+ uint32_t _before;
+ uint32_t _max_x;
+};
+
/** Dragging of a rubberband rectangle for selecting things */
class RubberbandSelectDrag : public Drag
{
diff --git a/gtk2_ardour/editor_items.h b/gtk2_ardour/editor_items.h
index 08013e30ab..36a5a9e36f 100644
--- a/gtk2_ardour/editor_items.h
+++ b/gtk2_ardour/editor_items.h
@@ -47,6 +47,7 @@ enum ItemType {
FadeOutItem,
FadeOutHandleItem,
NoteItem,
+ FeatureLineItem,
LeftFrameHandle,
RightFrameHandle,
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 55a7e6887f..68d9230028 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -735,10 +735,23 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
return true;
}
+ case FeatureLineItem:
+ {
+ if (Keyboard::modifier_state_contains (event->button.state, Keyboard::TertiaryModifier)) {
+ remove_transient(item);
+ return true;
+ }
+
+ _drags->set (new FeatureLineDrag (this, item), event);
+ return true;
+ break;
+ }
+
case RegionItem:
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
add_region_copy_drag (item, event, clicked_regionview);
- } else if (Keyboard::the_keyboard().key_is_down (GDK_b)) {
+ }
+ else if (Keyboard::the_keyboard().key_is_down (GDK_b)) {
add_region_brush_drag (item, event, clicked_regionview);
} else {
add_region_drag (item, event, clicked_regionview);
@@ -1616,7 +1629,12 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
track_canvas->get_window()->set_cursor (*fade_out_cursor);
}
break;
-
+ case FeatureLineItem:
+ {
+ ArdourCanvas::SimpleLine *line = dynamic_cast<ArdourCanvas::SimpleLine *> (item);
+ line->property_color_rgba() = 0xFF0000FF;
+ }
+ break;
default:
break;
}
@@ -1761,6 +1779,12 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
Glib::signal_idle().connect (sigc::mem_fun(*this, &Editor::left_automation_track));
}
break;
+ case FeatureLineItem:
+ {
+ ArdourCanvas::SimpleLine *line = dynamic_cast<ArdourCanvas::SimpleLine *> (item);
+ line->property_color_rgba() = (guint) ARDOUR_UI::config()->canvasvar_ZeroLine.get();;
+ }
+ break;
default:
break;
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 9bf09557ee..adc9078fba 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -552,7 +552,7 @@ Editor::move_to_end ()
void
Editor::build_region_boundary_cache ()
{
- nframes64_t pos = 0;
+ framepos_t pos = 0;
vector<RegionPoint> interesting_points;
boost::shared_ptr<Region> r;
TrackViewList tracks;
@@ -595,8 +595,8 @@ Editor::build_region_boundary_cache ()
while (pos < _session->current_end_frame() && !at_end) {
- nframes64_t rpos;
- nframes64_t lpos = max_frames;
+ framepos_t rpos;
+ framepos_t lpos = max_frames;
for (vector<RegionPoint>::iterator p = interesting_points.begin(); p != interesting_points.end(); ++p) {
@@ -645,7 +645,7 @@ Editor::build_region_boundary_cache ()
to sort later.
*/
- vector<nframes64_t>::iterator ri;
+ vector<framepos_t>::iterator ri;
for (ri = region_boundary_cache.begin(); ri != region_boundary_cache.end(); ++ri) {
if (*ri == rpos) {
@@ -664,23 +664,29 @@ Editor::build_region_boundary_cache ()
/* finally sort to be sure that the order is correct */
sort (region_boundary_cache.begin(), region_boundary_cache.end());
+
+ cerr << "RBC contains " << region_boundary_cache.size() << endl;
+
+ for (vector<framepos_t>::iterator x = region_boundary_cache.begin(); x != region_boundary_cache.end(); ++x) {
+ cerr << "Region boundary @ " << *x << endl;
+ }
}
boost::shared_ptr<Region>
-Editor::find_next_region (nframes64_t frame, RegionPoint point, int32_t dir, TrackViewList& tracks, TimeAxisView **ontrack)
+Editor::find_next_region (framepos_t frame, RegionPoint point, int32_t dir, TrackViewList& tracks, TimeAxisView **ontrack)
{
TrackViewList::iterator i;
nframes64_t closest = max_frames;
boost::shared_ptr<Region> ret;
- nframes64_t rpos = 0;
+ framepos_t rpos = 0;
float track_speed;
- nframes64_t track_frame;
+ framepos_t track_frame;
RouteTimeAxisView *rtav;
for (i = tracks.begin(); i != tracks.end(); ++i) {
- nframes64_t distance;
+ framecnt_t distance;
boost::shared_ptr<Region> r;
track_speed = 1.0f;
@@ -730,17 +736,16 @@ Editor::find_next_region (nframes64_t frame, RegionPoint point, int32_t dir, Tra
return ret;
}
-nframes64_t
-Editor::find_next_region_boundary (nframes64_t pos, int32_t dir, const TrackViewList& tracks)
+framepos_t
+Editor::find_next_region_boundary (framepos_t pos, int32_t dir, const TrackViewList& tracks)
{
- nframes64_t distance = max_frames;
- nframes64_t current_nearest = -1;
-
+ framecnt_t distance = max_frames;
+ framepos_t current_nearest = -1;
for (TrackViewList::const_iterator i = tracks.begin(); i != tracks.end(); ++i) {
- nframes64_t contender;
- nframes64_t d;
-
+ framepos_t contender;
+ framecnt_t d;
+
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
if (!rtv) {
@@ -762,10 +767,10 @@ Editor::find_next_region_boundary (nframes64_t pos, int32_t dir, const TrackView
return current_nearest;
}
-nframes64_t
-Editor::get_region_boundary (nframes64_t pos, int32_t dir, bool with_selection, bool only_onscreen)
+framepos_t
+Editor::get_region_boundary (framepos_t pos, int32_t dir, bool with_selection, bool only_onscreen)
{
- nframes64_t target;
+ framepos_t target;
TrackViewList tvl;
if (with_selection && Config->get_region_boundaries_from_selected_tracks()) {
@@ -2793,6 +2798,7 @@ Editor::separate_regions_between (const TimeSelection& ts)
sigc::connection c = rtv->view()->RegionViewAdded.connect (
sigc::mem_fun(*this, &Editor::collect_new_region_view));
+
latest_regionviews.clear ();
playlist->partition ((nframes64_t)((*t).start * speed),
@@ -2838,6 +2844,11 @@ Editor::separate_regions_between (const TimeSelection& ts)
}
}
+struct PlaylistState {
+ boost::shared_ptr<Playlist> playlist;
+ XMLNode* before;
+};
+
/** Take tracks from get_tracks_for_range_action and cut any regions
* on those tracks so that the tracks are empty over the time
* selection.
@@ -2903,6 +2914,85 @@ Editor::separate_regions_using_location (Location& loc)
separate_regions_between (ts);
}
+/** Separate regions under the selected region */
+void
+Editor::separate_under_selected_regions ()
+{
+ RegionSelection rs;
+ get_regions_for_action (rs);
+
+ vector<PlaylistState> playlists;
+
+ if (!_session) {
+ return;
+ }
+
+ if (rs.empty()) {
+ return;
+ }
+
+ begin_reversible_command (_("separate region under"));
+
+ list<boost::shared_ptr<Region> > regions_to_remove;
+
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+ // we can't just remove the region(s) in this loop because
+ // this removes them from the RegionSelection, and they thus
+ // disappear from underneath the iterator, and the ++i above
+ // SEGVs in a puzzling fashion.
+
+ // so, first iterate over the regions to be removed from rs and
+ // add them to the regions_to_remove list, and then
+ // iterate over the list to actually remove them.
+
+ regions_to_remove.push_back ((*i)->region());
+ }
+
+ for (list<boost::shared_ptr<Region> >::iterator rl = regions_to_remove.begin(); rl != regions_to_remove.end(); ++rl) {
+
+ boost::shared_ptr<Playlist> playlist = (*rl)->playlist();
+
+ if (!playlist) {
+ // is this check necessary?
+ continue;
+ }
+
+ vector<PlaylistState>::iterator i;
+
+ //only take state if this is a new playlist.
+ for (i = playlists.begin(); i != playlists.end(); ++i) {
+ if ((*i).playlist == playlist) {
+ break;
+ }
+ }
+
+ if (i == playlists.end()) {
+
+ PlaylistState before;
+ before.playlist = playlist;
+ before.before = &playlist->get_state();
+
+ playlist->freeze ();
+ playlists.push_back(before);
+ }
+
+ //Partition on the region bounds
+ playlist->partition ((*rl)->first_frame() - 1, (*rl)->last_frame() + 1, true);
+
+ //Re-add region that was just removed due to the partition operation
+ playlist->add_region( (*rl), (*rl)->first_frame() );
+ }
+
+ vector<PlaylistState>::iterator pl;
+
+ for (pl = playlists.begin(); pl != playlists.end(); ++pl) {
+ (*pl).playlist->thaw ();
+ _session->add_command(new MementoCommand<Playlist>(*(*pl).playlist, (*pl).before, &(*pl).playlist->get_state()));
+ }
+
+ commit_reversible_command ();
+}
+
void
Editor::crop_region_to_selection ()
{
@@ -3354,12 +3444,15 @@ Editor::trim_region (bool front)
for (list<RegionView*>::const_iterator i = rs.by_layer().begin(); i != rs.by_layer().end(); ++i) {
if (!(*i)->region()->locked()) {
- (*i)->region()->clear_history ();
+
+ (*i)->region()->clear_history ();
+
if (front) {
(*i)->region()->trim_front (where, this);
} else {
(*i)->region()->trim_end (where, this);
}
+
_session->add_command (new StatefulDiffCommand ((*i)->region()));
}
}
@@ -3564,7 +3657,7 @@ Editor::trim_to_region(bool forward)
continue;
}
- region->trim_end((nframes64_t) (next_region->first_frame() * speed), this);
+ region->trim_end((nframes64_t) ( (next_region->first_frame() - 1) * speed), this);
arv->region_changed (PropertyChange (ARDOUR::Properties::length));
}
else {
@@ -3892,6 +3985,14 @@ Editor::cut_copy_midi (CutCopyOp op)
}
}
+
+
+struct lt_playlist {
+ bool operator () (const PlaylistState& a, const PlaylistState& b) {
+ return a.playlist < b.playlist;
+ }
+};
+
struct PlaylistMapping {
TimeAxisView* tv;
boost::shared_ptr<Playlist> pl;
@@ -4263,7 +4364,7 @@ Editor::duplicate_some_regions (RegionSelection& regions, float times)
playlist = (*i)->region()->playlist();
playlist->clear_history ();
- playlist->duplicate (r, end_frame + (r->first_frame() - start_frame) + 1, times);
+ playlist->duplicate (r, end_frame + (r->first_frame() - start_frame), times);
_session->add_command(new StatefulDiffCommand (playlist));
c.disconnect ();
@@ -5872,6 +5973,7 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
int response = msg.run();
msg.hide ();
+
switch (response) {
case RESPONSE_OK:
break;
@@ -5890,19 +5992,10 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
AnalysisFeatureList::const_iterator x;
- nframes64_t pos = r->position();
-
pl->clear_history ();
x = positions.begin();
- while (x != positions.end()) {
- if ((*x) > pos) {
- break;
- }
- ++x;
- }
-
if (x == positions.end()) {
return;
}
@@ -5910,18 +6003,26 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
pl->freeze ();
pl->remove_region (r);
+ nframes64_t pos = 0;
+
while (x != positions.end()) {
+
+ /* deal with positons that are out of scope of present region bounds */
+ if (*x <= 0 || *x > r->length()){
+ ++x;
+ continue;
+ }
/* file start = original start + how far we from the initial position ?
*/
- nframes64_t file_start = r->start() + (pos - r->position());
+ nframes64_t file_start = r->start() + pos;
/* length = next position - current position
*/
nframes64_t len = (*x) - pos;
-
+
/* XXX we do we really want to allow even single-sample regions?
shouldn't we have some kind of lower limit on region size?
*/
@@ -5946,35 +6047,190 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
plist.add (ARDOUR::Properties::layer, 0);
boost::shared_ptr<Region> nr = RegionFactory::create (r->sources(), plist, false);
- pl->add_region (nr, pos);
+ pl->add_region (nr, r->position() + pos);
pos += len;
++x;
+ }
- if (*x > r->last_frame()) {
+ string new_name;
- /* add final fragment */
+ RegionFactory::region_name (new_name, r->name());
+
+ /* Add the final region */
+ PropertyList plist;
+
+ plist.add (ARDOUR::Properties::start, r->start() + pos);
+ plist.add (ARDOUR::Properties::length, r->last_frame() - (r->position() + pos) + 1);
+ plist.add (ARDOUR::Properties::name, new_name);
+ plist.add (ARDOUR::Properties::layer, 0);
- file_start = r->start() + (pos - r->position());
- len = r->last_frame() - pos;
+ boost::shared_ptr<Region> nr = RegionFactory::create (r->sources(), plist, false);
+ pl->add_region (nr, r->position() + pos);
- PropertyList plist2;
-
- plist2.add (ARDOUR::Properties::start, file_start);
- plist2.add (ARDOUR::Properties::length, len);
- plist2.add (ARDOUR::Properties::name, new_name);
- plist2.add (ARDOUR::Properties::layer, 0);
+
+ pl->thaw ();
- nr = RegionFactory::create (r->sources(), plist2);
- pl->add_region (nr, pos);
+ _session->add_command (new StatefulDiffCommand (pl));
+}
- break;
- }
+void
+Editor::place_transient()
+{
+ if (!_session) {
+ return;
}
- pl->thaw ();
+ RegionSelection rs;
- _session->add_command (new StatefulDiffCommand (pl));
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
+ return;
+ }
+
+ nframes64_t where = get_preferred_edit_position();
+
+ _session->begin_reversible_command (_("place transient"));
+
+ for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
+ framepos_t position = (*r)->region()->position();
+ (*r)->region()->add_transient(where - position);
+ }
+
+ _session->commit_reversible_command ();
+}
+
+void
+Editor::remove_transient(ArdourCanvas::Item* item)
+{
+ if (!_session) {
+ return;
+ }
+
+ ArdourCanvas::SimpleLine* _line = reinterpret_cast<ArdourCanvas::SimpleLine*> (item);
+ assert (_line);
+
+ AudioRegionView* _arv = reinterpret_cast<AudioRegionView*> (item->get_data ("regionview"));
+ _arv->remove_transient(_line->property_x1());
+}
+
+void
+Editor::snap_regions_to_grid()
+{
+ if (!_session) {
+ return;
+ }
+
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
+ return;
+ }
+
+ _session->begin_reversible_command (_("snap regions to grid"));
+
+ for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
+ framepos_t start_frame = (*r)->region()->first_frame ();
+ snap_to (start_frame);
+ (*r)->region()->set_position (start_frame, this);
+ }
+
+ _session->commit_reversible_command ();
+}
+
+void
+Editor::close_region_gaps()
+{
+ if (!_session) {
+ return;
+ }
+
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
+ return;
+ }
+
+ Dialog dialog (rs.size() > 1 ? _("Conform regions") : _("Conform region"));
+
+ HBox hbox_crossfade;
+ hbox_crossfade.set_spacing (10);
+ //hbox_crossfade.set_border_width (3);
+ hbox_crossfade.pack_start (*manage (new Label (_("Crossfade length:"))));
+
+ SpinButton spin_crossfade (1, 0);
+ spin_crossfade.set_range (0, 15);
+ spin_crossfade.set_increments (1, 1);
+ spin_crossfade.set_value (3);
+
+ hbox_crossfade.pack_start (spin_crossfade);
+ hbox_crossfade.pack_start (*manage (new Label (_("ms"))));
+ hbox_crossfade.show_all ();
+
+ HBox hbox_pullback;
+
+ hbox_pullback.set_spacing (10);
+ //hbox_pullback.set_border_width (3);
+ hbox_pullback.pack_start (*manage (new Label (_("Pull-back length:"))));
+
+ SpinButton spin_pullback (1, 0);
+ spin_pullback.set_range (0, 15);
+ spin_pullback.set_increments (1, 1);
+ spin_pullback.set_value (5);
+
+ hbox_pullback.pack_start (spin_pullback);
+ hbox_pullback.pack_start (*manage (new Label (_("ms"))));
+ hbox_pullback.show_all ();
+
+ dialog.get_vbox()->set_spacing (6);
+ dialog.get_vbox()->pack_start (hbox_crossfade);
+ dialog.get_vbox()->pack_start (hbox_pullback);
+ dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL);
+ dialog.add_button (_("Ok"), RESPONSE_ACCEPT);
+
+ if (dialog.run () == RESPONSE_CANCEL) {
+ return;
+ }
+
+ nframes64_t crossfade_len = spin_crossfade.get_value();
+ nframes64_t pull_back_frames = spin_pullback.get_value();
+
+ crossfade_len = lrintf (crossfade_len * _session->frame_rate()/1000);
+ pull_back_frames = lrintf (pull_back_frames * _session->frame_rate()/1000);
+
+ /* Iterate over the region list and make adjacent regions overlap by crossfade_len_ms */
+
+ _session->begin_reversible_command (_("close region gaps"));
+
+ int idx = 0;
+ boost::shared_ptr<Region> last_region;
+
+ rs.sort_by_position_and_track();
+
+ for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
+
+ nframes64_t position = (*r)->region()->position();
+
+ if (idx == 0 || position < last_region->position()){
+ last_region = (*r)->region();
+ idx++;
+ continue;
+ }
+
+ (*r)->region()->trim_front( (position - pull_back_frames), this );
+ last_region->trim_end( (position - pull_back_frames + crossfade_len), this );
+
+ last_region = (*r)->region();
+
+ idx++;
+ }
+
+ _session->commit_reversible_command ();
}
void
@@ -6053,6 +6309,7 @@ Editor::tab_to_transient (bool forward)
}
}
}
+
void
Editor::playhead_forward_to_grid ()
{
diff --git a/gtk2_ardour/midi_streamview.cc b/gtk2_ardour/midi_streamview.cc
index 96d331ba01..cf58224766 100644
--- a/gtk2_ardour/midi_streamview.cc
+++ b/gtk2_ardour/midi_streamview.cc
@@ -63,6 +63,7 @@ MidiStreamView::MidiStreamView (MidiTimeAxisView& tv)
, _highest_note(71)
, _data_note_min(60)
, _data_note_max(71)
+ , _note_lines (0)
{
/* use a group dedicated to MIDI underlays. Audio underlays are not in this group. */
midi_underlay_group = new ArdourCanvas::Group (*_canvas_group);
@@ -617,11 +618,23 @@ MidiStreamView::update_rec_regions (boost::shared_ptr<MidiModel> data, nframes_t
const boost::shared_ptr<MidiRegionView::NoteType>& note = *i;
+ cerr << "New note arrived, length = " << note->length()
+ << " num " << note->note()
+ << endl;
+
+ if (note->length() == 0) {
+ /* we got NoteOn but not NoteOff (yet)
+ */
+ continue;
+ }
+
nframes_t note_start_frames = tconv.to(note->time());
nframes_t note_end_frames = tconv.to(note->end_time());
- if (note->length() > 0 && note_end_frames + region->position() > start)
+
+ if (note->length() > 0 && note_end_frames + region->position() > start) {
mrv->resolve_note(note->note(), note_end_frames);
+ }
if (note_start_frames + region->position() < start) {
continue;
diff --git a/gtk2_ardour/mnemonic-us.bindings.in b/gtk2_ardour/mnemonic-us.bindings.in
index 3056b2e3e5..3754591015 100644
--- a/gtk2_ardour/mnemonic-us.bindings.in
+++ b/gtk2_ardour/mnemonic-us.bindings.in
@@ -115,6 +115,9 @@ This mode provides many different operations on both regions and control points,
@eep|Editor/trim-from-start|<@TERTIARY@>braceleft|trim region start to edit point
@eep|Editor/trim-to-end|<@TERTIARY@>braceright|trim region end to edit point
+@eep|Editor/trim-to-previous-region|<@PRIMARY@>j|trim region to end of previous region
+@eep|Editor/trim-to-next-region|<@PRIMARY@>k|trim region to start of next region
+
@ranges|Editor/set-loop-from-edit-range|bracketright|set loop range from edit range
@ranges|Editor/set-loop-from-region|<@SECONDARY@>bracketright|set loop range from region(s)
diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h
index 52fb601f8d..ea9ef9dfad 100644
--- a/gtk2_ardour/public_editor.h
+++ b/gtk2_ardour/public_editor.h
@@ -304,6 +304,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible {
virtual bool canvas_frame_handle_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
virtual bool canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
virtual bool canvas_region_view_name_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
+ virtual bool canvas_feature_line_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
virtual bool canvas_stream_view_event (GdkEvent* event, ArdourCanvas::Item*, RouteTimeAxisView*) = 0;
virtual bool canvas_marker_event (GdkEvent* event, ArdourCanvas::Item*, Marker*) = 0;
virtual bool canvas_zoom_rect_event (GdkEvent* event, ArdourCanvas::Item*) = 0;
diff --git a/gtk2_ardour/rhythm_ferret.cc b/gtk2_ardour/rhythm_ferret.cc
index 8c67ceae21..cba0042cfe 100644
--- a/gtk2_ardour/rhythm_ferret.cc
+++ b/gtk2_ardour/rhythm_ferret.cc
@@ -14,7 +14,7 @@
#include "rhythm_ferret.h"
#include "audio_region_view.h"
-#include "public_editor.h"
+#include "editor.h"
#include "utils.h"
#include "time_axis_view.h"
@@ -53,7 +53,7 @@ static const gchar * _operation_strings[] = {
0
};
-RhythmFerret::RhythmFerret (PublicEditor& e)
+RhythmFerret::RhythmFerret (Editor& e)
: ArdourDialog (_("Rhythm Ferret"))
, editor (e)
, detection_threshold_adjustment (3, 0, 20, 1, 4)
@@ -205,13 +205,10 @@ RhythmFerret::run_analysis ()
default:
break;
}
-
+
+ (*i)->region()->set_transients (current_results);
+ current_results.clear();
}
-
- for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) {
- (*i)->get_time_axis_view().show_feature_lines (current_results);
- }
-
}
int
@@ -233,9 +230,9 @@ RhythmFerret::run_percussion_onset_analysis (boost::shared_ptr<Readable> readabl
/* translate all transients to give absolute position */
- for (AnalysisFeatureList::iterator x = these_results.begin(); x != these_results.end(); ++x) {
- (*x) += offset;
- }
+ //for (AnalysisFeatureList::iterator x = these_results.begin(); x != these_results.end(); ++x) {
+ // (*x) += offset;
+ //}
/* merge */
@@ -289,9 +286,9 @@ RhythmFerret::run_note_onset_analysis (boost::shared_ptr<Readable> readable, nfr
/* translate all transients to give absolute position */
- for (AnalysisFeatureList::iterator x = these_results.begin(); x != these_results.end(); ++x) {
- (*x) += offset;
- }
+ //for (AnalysisFeatureList::iterator x = these_results.begin(); x != these_results.end(); ++x) {
+ // (*x) += offset;
+ //}
/* merge */
@@ -314,7 +311,7 @@ RhythmFerret::run_note_onset_analysis (boost::shared_ptr<Readable> readable, nfr
void
RhythmFerret::do_action ()
{
- if (!_session || current_results.empty()) {
+ if (!_session) {
return;
}
@@ -322,7 +319,9 @@ RhythmFerret::do_action ()
case SplitRegion:
do_split_action ();
break;
-
+ case ConformRegion:
+ editor.close_region_gaps();
+ break;
default:
break;
}
@@ -333,13 +332,29 @@ RhythmFerret::do_split_action ()
{
/* this can/will change the current selection, so work with a copy */
- RegionSelection& regions (editor.get_selection().regions);
+ //RegionSelection& regions (editor.get_selection().regions);
+ RegionSelection regions;
+ editor.get_regions_for_action(regions);
if (regions.empty()) {
return;
}
_session->begin_reversible_command (_("split regions (rhythm ferret)"));
+
+ /* Merge the transient positions for regions in consideration */
+ AnalysisFeatureList merged_features;
+
+ for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) {
+
+ AnalysisFeatureList features;
+ features = (*i)->region()->transients();
+
+ merged_features.insert (merged_features.end(), features.begin(), features.end());
+ }
+
+ merged_features.sort();
+ merged_features.unique();
for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ) {
@@ -348,9 +363,9 @@ RhythmFerret::do_split_action ()
tmp = i;
++tmp;
- (*i)->get_time_axis_view().hide_feature_lines ();
-
- editor.split_region_at_points ((*i)->region(), current_results, false);
+ AnalysisFeatureList features;
+ features = (*i)->region()->transients();
+ editor.split_region_at_points ((*i)->region(), merged_features, false);
/* i is invalid at this point */
@@ -367,15 +382,9 @@ RhythmFerret::set_session (Session* s)
current_results.clear ();
}
-static void hide_time_axis_features (TimeAxisView& tav)
-{
- tav.hide_feature_lines ();
-}
-
void
RhythmFerret::on_hide ()
{
- editor.foreach_time_axis_view (sigc::ptr_fun (hide_time_axis_features));
ArdourDialog::on_hide ();
}
diff --git a/gtk2_ardour/rhythm_ferret.h b/gtk2_ardour/rhythm_ferret.h
index b18a86377c..043b9fe8a7 100644
--- a/gtk2_ardour/rhythm_ferret.h
+++ b/gtk2_ardour/rhythm_ferret.h
@@ -17,7 +17,7 @@ namespace ARDOUR {
class Readable;
}
-class PublicEditor;
+class Editor;
class RegionView;
class RhythmFerret : public ArdourDialog {
@@ -36,7 +36,7 @@ class RhythmFerret : public ArdourDialog {
ConformRegion
};
- RhythmFerret (PublicEditor&);
+ RhythmFerret (Editor&);
void set_session (ARDOUR::Session*);
@@ -44,7 +44,7 @@ class RhythmFerret : public ArdourDialog {
void on_hide ();
private:
- PublicEditor& editor;
+ Editor& editor;
Gtk::ComboBoxText operation_selector;
diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc
index 58dbd595bf..803053b8c7 100644
--- a/gtk2_ardour/time_axis_view.cc
+++ b/gtk2_ardour/time_axis_view.cc
@@ -203,10 +203,6 @@ TimeAxisView::~TimeAxisView()
delete (*i)->end_trim;
}
- for (list<SimpleLine*>::iterator i = feature_lines.begin(); i != feature_lines.end(); ++i) {
- delete (*i);
- }
-
delete selection_group;
selection_group = 0;
@@ -426,8 +422,6 @@ TimeAxisView::set_height(uint32_t h)
/* resize the selection rect */
show_selection (_editor.get_selection().time);
}
-
- reshow_feature_lines ();
}
bool
@@ -652,11 +646,6 @@ TimeAxisView::set_samples_per_unit (double spu)
AnalysisFeatureList::const_iterator i;
list<ArdourCanvas::SimpleLine*>::iterator l;
-
- for (i = analysis_features.begin(), l = feature_lines.begin(); i != analysis_features.end() && l != feature_lines.end(); ++i, ++l) {
- (*l)->property_x1() = _editor.frame_to_pixel (*i);
- (*l)->property_x2() = _editor.frame_to_pixel (*i);
- }
}
void
@@ -1188,51 +1177,6 @@ TimeAxisView::covers_y_position (double y)
return std::make_pair ( (TimeAxisView *) 0, 0);
}
-void
-TimeAxisView::show_feature_lines (const AnalysisFeatureList& pos)
-{
- analysis_features = pos;
- reshow_feature_lines ();
-}
-
-
-void
-TimeAxisView::hide_feature_lines ()
-{
- list<ArdourCanvas::SimpleLine*>::iterator l;
-
- for (l = feature_lines.begin(); l != feature_lines.end(); ++l) {
- (*l)->hide();
- }
-}
-
-void
-TimeAxisView::reshow_feature_lines ()
-{
- while (feature_lines.size()< analysis_features.size()) {
- ArdourCanvas::SimpleLine* l = new ArdourCanvas::SimpleLine (*_canvas_display);
- l->property_color_rgba() = (guint) ARDOUR_UI::config()->canvasvar_ZeroLine.get();
- feature_lines.push_back (l);
- }
-
- while (feature_lines.size() > analysis_features.size()) {
- ArdourCanvas::SimpleLine *line = feature_lines.back();
- feature_lines.pop_back ();
- delete line;
- }
-
- AnalysisFeatureList::const_iterator i;
- list<ArdourCanvas::SimpleLine*>::iterator l;
-
- for (i = analysis_features.begin(), l = feature_lines.begin(); i != analysis_features.end() && l != feature_lines.end(); ++i, ++l) {
- (*l)->property_x1() = _editor.frame_to_pixel (*i);
- (*l)->property_x2() = _editor.frame_to_pixel (*i);
- (*l)->property_y1() = 0;
- (*l)->property_y2() = current_height();
- (*l)->show ();
- }
-}
-
bool
TimeAxisView::resizer_button_press (GdkEventButton* event)
{
diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h
index 4e91b15336..93cb7eced3 100644
--- a/gtk2_ardour/time_axis_view.h
+++ b/gtk2_ardour/time_axis_view.h
@@ -165,9 +165,6 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
virtual ARDOUR::RouteGroup* route_group() const { return 0; }
virtual boost::shared_ptr<ARDOUR::Playlist> playlist() const { return boost::shared_ptr<ARDOUR::Playlist> (); }
- virtual void show_feature_lines (const ARDOUR::AnalysisFeatureList&);
- virtual void hide_feature_lines ();
-
virtual void set_samples_per_unit (double);
virtual void show_selection (TimeSelection&);
virtual void hide_selection ();
@@ -310,10 +307,6 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
void set_heights (uint32_t h);
void color_handler ();
- std::list<ArdourCanvas::SimpleLine*> feature_lines;
- ARDOUR::AnalysisFeatureList analysis_features;
- void reshow_feature_lines ();
-
void conditionally_add_to_selection ();
ArdourCanvas::Group* _canvas_display;