summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-04-20 21:02:46 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-04-20 21:02:46 +0000
commit0d36301907afd612f93a7bfa53724cc9a17724de (patch)
tree620c096be24ebc38b5762493d6ad79e839420395 /gtk2_ardour
parentf19c01bbb42f4e80769adb8e3e1015724fe9d6c6 (diff)
3 notable patches from lincoln (a) non-layered track mode (NOTE: this is broken for loop recording right now) (b) trim region to previous/next region (c) region push/pull trimming. work on these 3 features should be assumed to be still slightly ongoing (eg. default bindings and more). great stuff
git-svn-id: svn://localhost/ardour2/branches/3.0@4994 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/add_route_dialog.cc3
-rw-r--r--gtk2_ardour/ardour.menus.in2
-rw-r--r--gtk2_ardour/audio_streamview.cc3
-rw-r--r--gtk2_ardour/audio_time_axis.cc9
-rw-r--r--gtk2_ardour/editor.h8
-rw-r--r--gtk2_ardour/editor_actions.cc7
-rw-r--r--gtk2_ardour/editor_mouse.cc99
-rw-r--r--gtk2_ardour/editor_ops.cc165
-rw-r--r--gtk2_ardour/route_time_axis.cc41
-rw-r--r--gtk2_ardour/route_time_axis.h3
-rw-r--r--gtk2_ardour/streamview.cc2
11 files changed, 276 insertions, 66 deletions
diff --git a/gtk2_ardour/add_route_dialog.cc b/gtk2_ardour/add_route_dialog.cc
index d5856fa4e6..9baa8f3cd2 100644
--- a/gtk2_ardour/add_route_dialog.cc
+++ b/gtk2_ardour/add_route_dialog.cc
@@ -56,6 +56,7 @@ static const char* channel_setup_names[] = {
static const char* track_mode_names[] = {
N_("Normal"),
+ N_("Non Layered"),
N_("Tape"),
0
};
@@ -273,6 +274,8 @@ AddRouteDialog::mode ()
Glib::ustring str = track_mode_combo.get_active_text();
if (str == _("Normal")) {
return ARDOUR::Normal;
+ } else if (str == _("Non Layered")){
+ return ARDOUR::NonLayered;
} else if (str == _("Tape")) {
return ARDOUR::Destructive;
} else {
diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in
index eb0968da4a..c754590102 100644
--- a/gtk2_ardour/ardour.menus.in
+++ b/gtk2_ardour/ardour.menus.in
@@ -185,6 +185,8 @@
<menuitem action='crop'/>
<menuitem action='trim-region-to-loop'/>
<menuitem action='trim-region-to-punch'/>
+ <menuitem action='trim-to-previous-region'/>
+ <menuitem action='trim-to-next-region'/>
</menu>
<menu action="FadeMenu">
<menuitem action='set-fade-in-length'/>
diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc
index ed56651e5f..8dcee5aaab 100644
--- a/gtk2_ardour/audio_streamview.cc
+++ b/gtk2_ardour/audio_streamview.cc
@@ -134,6 +134,8 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
}
switch (_trackview.audio_track()->mode()) {
+
+ case NonLayered:
case Normal:
if (recording) {
region_view = new AudioRegionView (canvas_group, _trackview, region,
@@ -519,6 +521,7 @@ AudioStreamView::setup_rec_box ()
switch (_trackview.audio_track()->mode()) {
case Normal:
+ case NonLayered:
xend = xstart;
fill_color = ARDOUR_UI::config()->canvasvar_RecordingRect.get();
break;
diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc
index 609d7b7d6c..b774182a88 100644
--- a/gtk2_ardour/audio_time_axis.cc
+++ b/gtk2_ardour/audio_time_axis.cc
@@ -245,9 +245,15 @@ AudioTimeAxisView::build_mode_menu()
mode_menu->set_name ("ArdourContextMenu");
RadioMenuItem::Group mode_group;
+
items.push_back (RadioMenuElem (mode_group, _("Normal"),
bind (mem_fun (*this, &AudioTimeAxisView::set_track_mode), ARDOUR::Normal)));
normal_track_mode_item = dynamic_cast<RadioMenuItem*>(&items.back());
+
+ items.push_back (RadioMenuElem (mode_group, _("Non Overlapping"),
+ bind (mem_fun (*this, &AudioTimeAxisView::set_track_mode), ARDOUR::NonLayered)));
+ non_layered_track_mode_item = dynamic_cast<RadioMenuItem*>(&items.back());
+
items.push_back (RadioMenuElem (mode_group, _("Tape"),
bind (mem_fun (*this, &AudioTimeAxisView::set_track_mode), ARDOUR::Destructive)));
destructive_track_mode_item = dynamic_cast<RadioMenuItem*>(&items.back());
@@ -256,6 +262,9 @@ AudioTimeAxisView::build_mode_menu()
case ARDOUR::Destructive:
destructive_track_mode_item->set_active ();
break;
+ case ARDOUR::NonLayered:
+ non_layered_track_mode_item->set_active ();
+ break;
case ARDOUR::Normal:
normal_track_mode_item->set_active ();
break;
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 1c04c76504..82f63792fc 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -1997,8 +1997,8 @@ public:
void point_trim (GdkEvent*);
void trim_motion_callback (ArdourCanvas::Item*, GdkEvent*);
void single_contents_trim (RegionView&, nframes64_t, bool, bool, bool);
- void single_start_trim (RegionView&, nframes64_t, bool, bool);
- void single_end_trim (RegionView&, nframes64_t, bool, bool);
+ void single_start_trim (RegionView&, nframes64_t, bool, bool, bool);
+ void single_end_trim (RegionView&, nframes64_t, bool, bool, bool);
void trim_finished_callback (ArdourCanvas::Item*, GdkEvent*);
void thaw_region_after_trim (RegionView& rv);
@@ -2013,6 +2013,10 @@ public:
void trim_region_to_punch ();
void trim_region_to_location (const ARDOUR::Location&, const char* cmd);
+ void trim_to_region(bool forward);
+ void trim_region_to_previous_region_end();
+ void trim_region_to_next_region_start();
+
bool show_gain_after_trim;
/* Drag-n-Drop */
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index 9606540b6e..f1c4e4b184 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -386,6 +386,13 @@ Editor::register_actions ()
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::region_selection_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "trim-to-previous-region", _("Trim to Previous"), mem_fun(*this, &Editor::trim_region_to_previous_region_end));
+ ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::region_selection_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "trim-to-next-region", _("Trim to Next"), mem_fun(*this, &Editor::trim_region_to_next_region_start));
+ ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::region_selection_sensitive_actions.push_back (act);
+
act = ActionManager::register_action (editor_actions, "set-loop-from-edit-range", _("Set Loop from Edit Range"), bind (mem_fun(*this, &Editor::set_loop_from_edit_range), false));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "set-loop-from-region", _("Set Loop from Region"), bind (mem_fun(*this, &Editor::set_loop_from_region), false));
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 7db90c1ac7..6cc92a2f74 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -4340,6 +4340,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
if (changed_tracks || drag_info.copy) {
boost::shared_ptr<Playlist> to_playlist = dest_rtv->playlist();
+
if (!to_playlist) {
++i;
continue;
@@ -4350,6 +4351,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
sigc::connection c = dest_rtv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
insert_result = modified_playlists.insert (to_playlist);
+
if (insert_result.second) {
session->add_command (new MementoCommand<Playlist>(*to_playlist, &to_playlist->get_state(), 0));
}
@@ -4380,11 +4382,13 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
boost::shared_ptr<Playlist> playlist = dest_rtv->playlist();
insert_result = modified_playlists.insert (playlist);
+
if (insert_result.second) {
session->add_command (new MementoCommand<Playlist>(*playlist, &playlist->get_state(), 0));
}
/* freeze to avoid lots of relayering in the case of a multi-region drag */
frozen_insert_result = frozen_playlists.insert(playlist);
+
if (frozen_insert_result.second) {
playlist->freeze();
}
@@ -4416,6 +4420,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
/* remove the region from the old playlist */
insert_result = modified_playlists.insert (from_playlist);
+
if (insert_result.second) {
session->add_command (new MementoCommand<Playlist>(*from_playlist, &from_playlist->get_state(), 0));
}
@@ -4478,13 +4483,13 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
for (set<boost::shared_ptr<Playlist> >::iterator p = modified_playlists.begin(); p != modified_playlists.end(); ++p) {
session->add_command (new MementoCommand<Playlist>(*(*p), 0, &(*p)->get_state()));
}
+
commit_reversible_command ();
}
for (vector<RegionView*>::iterator x = copies.begin(); x != copies.end(); ++x) {
delete *x;
}
-
}
void
@@ -4807,6 +4812,7 @@ Editor::cancel_selection ()
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
(*i)->hide_selection ();
}
+
selection->clear ();
clicked_selection = 0;
}
@@ -5075,6 +5081,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
RegionView* rv = clicked_regionview;
nframes64_t frame_delta = 0;
+
bool left_direction;
bool obey_snap = !Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier());
@@ -5129,11 +5136,14 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
(*i)->region()->freeze ();
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
- if (arv)
+
+ if (arv){
arv->temporarily_hide_envelope ();
+ }
boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
insert_result = motion_frozen_playlists.insert (pl);
+
if (insert_result.second) {
session->add_command(new MementoCommand<Playlist>(*pl, &pl->get_state(), 0));
pl->freeze();
@@ -5147,13 +5157,20 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
frame_delta = (drag_info.current_pointer_frame - drag_info.last_pointer_frame);
}
+ bool non_overlap_trim = false;
+
+ if (Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) {
+ non_overlap_trim = true;
+ }
+
switch (trim_op) {
case StartTrim:
if ((left_direction == false) && (drag_info.current_pointer_frame <= rv->region()->first_frame()/speed)) {
break;
} else {
+
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
- single_start_trim (**i, frame_delta, left_direction, obey_snap);
+ single_start_trim (**i, frame_delta, left_direction, obey_snap, non_overlap_trim);
}
break;
}
@@ -5162,8 +5179,9 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
if ((left_direction == true) && (drag_info.current_pointer_frame > (nframes64_t) (rv->region()->last_frame()/speed))) {
break;
} else {
+
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
- single_end_trim (**i, frame_delta, left_direction, obey_snap);
+ single_end_trim (**i, frame_delta, left_direction, obey_snap, non_overlap_trim);
}
break;
}
@@ -5242,7 +5260,7 @@ Editor::single_contents_trim (RegionView& rv, nframes64_t frame_delta, bool left
}
void
-Editor::single_start_trim (RegionView& rv, nframes64_t frame_delta, bool left_direction, bool obey_snap)
+Editor::single_start_trim (RegionView& rv, nframes64_t frame_delta, bool left_direction, bool obey_snap, bool no_overlap)
{
boost::shared_ptr<Region> region (rv.region());
@@ -5269,14 +5287,37 @@ Editor::single_start_trim (RegionView& rv, nframes64_t frame_delta, bool left_di
if (obey_snap) {
snap_to (new_bound, (left_direction ? 0 : 1));
}
+
+ nframes64_t pre_trim_first_frame = region->first_frame();
region->trim_front ((nframes64_t) (new_bound * speed), this);
+
+ if (no_overlap) {
+ //Get the next region on the left of this region and shrink/expand it.
+ boost::shared_ptr<Playlist> playlist (region->playlist());
+ boost::shared_ptr<Region> region_left = playlist->find_next_region (pre_trim_first_frame, End, 0);
+
+ bool regions_touching = false;
+
+ if (region_left != 0 && (pre_trim_first_frame == region_left->last_frame() + 1)){
+ regions_touching = true;
+ }
+
+ //Only trim region on the left if the first frame has gone beyond the left region's last frame.
+ if (region_left != 0 &&
+ (region_left->last_frame() > region->first_frame() || regions_touching))
+ {
+ region_left->trim_end(region->first_frame(), this);
+ }
+ }
+
+
rv.region_changed (Change (LengthChanged|PositionChanged|StartChanged));
}
void
-Editor::single_end_trim (RegionView& rv, nframes64_t frame_delta, bool left_direction, bool obey_snap)
+Editor::single_end_trim (RegionView& rv, nframes64_t frame_delta, bool left_direction, bool obey_snap, bool no_overlap)
{
boost::shared_ptr<Region> region (rv.region());
@@ -5293,7 +5334,7 @@ Editor::single_end_trim (RegionView& rv, nframes64_t frame_delta, bool left_dire
if (tv && tv->is_track()) {
speed = tv->get_diskstream()->speed();
}
-
+
if (left_direction) {
new_bound = (nframes64_t) ((region->last_frame() + 1)/speed) - frame_delta;
} else {
@@ -5303,10 +5344,37 @@ Editor::single_end_trim (RegionView& rv, nframes64_t frame_delta, bool left_dire
if (obey_snap) {
snap_to (new_bound);
}
+
+ nframes64_t pre_trim_last_frame = region->last_frame();
+
region->trim_end ((nframes64_t) (new_bound * speed), this);
- rv.region_changed (LengthChanged);
+
+ if (no_overlap) {
+ //Get the next region on the right of this region and shrink/expand it.
+ boost::shared_ptr<Playlist> playlist (region->playlist());
+ boost::shared_ptr<Region> region_right = playlist->find_next_region (pre_trim_last_frame, Start, 1);
+
+ bool regions_touching = false;
+
+ if (region_right != 0 && (pre_trim_last_frame == region_right->first_frame() - 1)){
+ regions_touching = true;
+ }
+
+ //Only trim region on the right if the last frame has gone beyond the right region's first frame.
+ if (region_right != 0 &&
+ (region_right->first_frame() < region->last_frame() || regions_touching))
+ {
+ region_right->trim_front(region->last_frame() + 1, this);
+ }
+
+ rv.region_changed (Change (LengthChanged|PositionChanged|StartChanged));
+ }
+ else {
+ rv.region_changed (LengthChanged);
+ }
}
-
+
+
void
Editor::trim_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
@@ -5343,6 +5411,7 @@ void
Editor::point_trim (GdkEvent* event)
{
RegionView* rv = clicked_regionview;
+
nframes64_t new_bound = drag_info.current_pointer_frame;
if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
@@ -5356,25 +5425,29 @@ Editor::point_trim (GdkEvent* event)
begin_reversible_command (_("Start point trim"));
if (selection->selected (rv)) {
-
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin();
i != selection->regions.by_layer().end(); ++i)
{
+ if ( (*i) == NULL){
+ cerr << "region view contains null region" << endl;
+ }
+
if (!(*i)->region()->locked()) {
boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
XMLNode &before = pl->get_state();
- (*i)->region()->trim_front (new_bound, this);
+
+ (*i)->region()->trim_front (new_bound, this);
+
XMLNode &after = pl->get_state();
session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after));
}
}
} else {
-
if (!rv->region()->locked()) {
boost::shared_ptr<Playlist> pl = rv->region()->playlist();
XMLNode &before = pl->get_state();
- rv->region()->trim_front (new_bound, this);
+ rv->region()->trim_front (new_bound, this);
XMLNode &after = pl->get_state();
session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after));
}
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 1b5067e2ac..5826033072 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -3476,6 +3476,49 @@ Editor::align_region_internal (boost::shared_ptr<Region> region, RegionPoint poi
session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
}
+void
+Editor::trim_region_front ()
+{
+ trim_region (true);
+}
+
+void
+Editor::trim_region_back ()
+{
+ trim_region (false);
+}
+
+void
+Editor::trim_region (bool front)
+{
+ nframes64_t where = get_preferred_edit_position();
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
+ return;
+ }
+
+ begin_reversible_command (front ? _("trim front") : _("trim back"));
+
+ for (list<RegionView*>::const_iterator i = rs.by_layer().begin(); i != rs.by_layer().end(); ++i) {
+ if (!(*i)->region()->locked()) {
+ boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
+ XMLNode &before = pl->get_state();
+ if (front) {
+ (*i)->region()->trim_front (where, this);
+ } else {
+ (*i)->region()->trim_end (where, this);
+ }
+ XMLNode &after = pl->get_state();
+ session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after));
+ }
+ }
+
+ commit_reversible_command ();
+}
+
/** Trim the end of the selected regions to the position of the edit cursor */
void
Editor::trim_region_to_loop ()
@@ -3623,6 +3666,85 @@ Editor::trim_region_from_edit_point ()
}
void
+Editor::trim_region_to_previous_region_end ()
+{
+ return trim_to_region(false);
+}
+
+void
+Editor::trim_region_to_next_region_start ()
+{
+ return trim_to_region(true);
+}
+
+void
+Editor::trim_to_region(bool forward)
+{
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ begin_reversible_command (_("trim to region"));
+
+ boost::shared_ptr<Region> next_region;
+
+ for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
+
+ AudioRegionView* arv = dynamic_cast<AudioRegionView*> (*x);
+
+ if (!arv) {
+ continue;
+ }
+
+ AudioTimeAxisView* atav = dynamic_cast<AudioTimeAxisView*> (&arv->get_time_axis_view());
+
+ if (!atav) {
+ return;
+ }
+
+ float speed = 1.0;
+
+ if (atav->get_diskstream() != 0) {
+ speed = atav->get_diskstream()->speed();
+ }
+
+
+ boost::shared_ptr<Region> region = arv->region();
+ boost::shared_ptr<Playlist> playlist (region->playlist());
+
+ XMLNode &before = playlist->get_state();
+
+ if(forward){
+
+ next_region = playlist->find_next_region (region->first_frame(), Start, 1);
+
+ if(!next_region){
+ continue;
+ }
+
+ region->trim_end((nframes64_t) (next_region->first_frame() * speed), this);
+ arv->region_changed (Change (LengthChanged));
+ }
+ else {
+
+ next_region = playlist->find_next_region (region->first_frame(), Start, 0);
+
+ if(!next_region){
+ continue;
+ }
+
+ region->trim_front((nframes64_t) ((next_region->last_frame() + 1) * speed), this);
+ arv->region_changed (Change (LengthChanged|PositionChanged|StartChanged));
+ }
+
+ XMLNode &after = playlist->get_state();
+ session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
+ }
+
+ commit_reversible_command ();
+}
+
+void
Editor::unfreeze_route ()
{
if (clicked_routeview == 0 || !clicked_routeview->is_track()) {
@@ -5207,49 +5329,6 @@ Editor::ensure_entered_track_selected (bool op_really_wants_one_track_if_none_ar
}
}
-void
-Editor::trim_region_front ()
-{
- trim_region (true);
-}
-
-void
-Editor::trim_region_back ()
-{
- trim_region (false);
-}
-
-void
-Editor::trim_region (bool front)
-{
- nframes64_t where = get_preferred_edit_position();
- RegionSelection rs;
-
- get_regions_for_action (rs);
-
- if (rs.empty()) {
- return;
- }
-
- begin_reversible_command (front ? _("trim front") : _("trim back"));
-
- for (list<RegionView*>::const_iterator i = rs.by_layer().begin(); i != rs.by_layer().end(); ++i) {
- if (!(*i)->region()->locked()) {
- boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
- XMLNode &before = pl->get_state();
- if (front) {
- (*i)->region()->trim_front (where, this);
- } else {
- (*i)->region()->trim_end (where, this);
- }
- XMLNode &after = pl->get_state();
- session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after));
- }
- }
-
- commit_reversible_command ();
-}
-
struct EditorOrderRouteSorter {
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
/* use of ">" forces the correct sort order */
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index a1f41adf6e..2b622bda28 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -128,6 +128,7 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
no_redraw = false;
destructive_track_mode_item = 0;
normal_track_mode_item = 0;
+ non_layered_track_mode_item = 0;
ignore_toggle = false;
@@ -165,8 +166,10 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
/* use icon */
rec_enable_button->remove ();
+
switch (track()->mode()) {
case ARDOUR::Normal:
+ case ARDOUR::NonLayered:
rec_enable_button->add (*(manage (new Image (::get_icon (X_("record_normal_red"))))));
break;
case ARDOUR::Destructive:
@@ -554,10 +557,17 @@ RouteTimeAxisView::build_display_menu ()
mem_fun (*this, &RouteTimeAxisView::set_track_mode),
ARDOUR::Normal)));
normal_track_mode_item = dynamic_cast<RadioMenuItem*>(&items.back());
+
items.push_back (RadioMenuElem (mode_group, _("Tape mode"), bind (
mem_fun (*this, &RouteTimeAxisView::set_track_mode),
ARDOUR::Destructive)));
destructive_track_mode_item = dynamic_cast<RadioMenuItem*>(&items.back());
+
+ items.push_back (RadioMenuElem (mode_group, _("No layering mode"),
+ bind (mem_fun (*this, &RouteTimeAxisView::set_track_mode), ARDOUR::NonLayered)));
+ non_layered_track_mode_item = dynamic_cast<RadioMenuItem*>(&items.back());
+
+
switch (track()->mode()) {
case ARDOUR::Destructive:
@@ -566,6 +576,9 @@ RouteTimeAxisView::build_display_menu ()
case ARDOUR::Normal:
normal_track_mode_item->set_active ();
break;
+ case ARDOUR::NonLayered:
+ non_layered_track_mode_item->set_active ();
+ break;
}
}
@@ -597,9 +610,10 @@ RouteTimeAxisView::build_display_menu ()
}
}
-static bool __reset_item (RadioMenuItem* item)
+static bool __reset_item (RadioMenuItem* item, RadioMenuItem* item_2)
{
item->set_active ();
+ item_2->set_active ();
return false;
}
@@ -608,15 +622,23 @@ RouteTimeAxisView::set_track_mode (TrackMode mode)
{
RadioMenuItem* item;
RadioMenuItem* other_item;
+ RadioMenuItem* other_item_2;
switch (mode) {
case ARDOUR::Normal:
item = normal_track_mode_item;
- other_item = destructive_track_mode_item;
+ other_item = non_layered_track_mode_item;
+ other_item_2 = destructive_track_mode_item;
+ break;
+ case ARDOUR::NonLayered:
+ item = non_layered_track_mode_item;
+ other_item = normal_track_mode_item;
+ other_item_2 = destructive_track_mode_item;
break;
case ARDOUR::Destructive:
item = destructive_track_mode_item;
other_item = normal_track_mode_item;
+ other_item_2 = non_layered_track_mode_item;
break;
default:
fatal << string_compose (_("programming error: %1 %2"), "illegal track mode in RouteTimeAxisView::set_track_mode", mode) << endmsg;
@@ -624,13 +646,13 @@ RouteTimeAxisView::set_track_mode (TrackMode mode)
return;
}
- if (item && other_item && item->get_active () && track()->mode() != mode) {
- _set_track_mode (track().get(), mode, other_item);
+ if (item && other_item && other_item_2 && item->get_active() && track()->mode() != mode) {
+ _set_track_mode (track().get(), mode, other_item, other_item_2);
}
}
void
-RouteTimeAxisView::_set_track_mode (Track* track, TrackMode mode, RadioMenuItem* reset_item)
+RouteTimeAxisView::_set_track_mode (Track* track, TrackMode mode, RadioMenuItem* reset_item, RadioMenuItem* reset_item_2)
{
bool needs_bounce;
@@ -638,7 +660,7 @@ RouteTimeAxisView::_set_track_mode (Track* track, TrackMode mode, RadioMenuItem*
if (!needs_bounce) {
/* cannot be done */
- Glib::signal_idle().connect (bind (sigc::ptr_fun (__reset_item), reset_item));
+ Glib::signal_idle().connect (bind (sigc::ptr_fun (__reset_item), reset_item, reset_item_2));
return;
} else {
cerr << "would bounce this one\n";
@@ -649,7 +671,9 @@ RouteTimeAxisView::_set_track_mode (Track* track, TrackMode mode, RadioMenuItem*
track->set_mode (mode);
rec_enable_button->remove ();
+
switch (mode) {
+ case ARDOUR::NonLayered:
case ARDOUR::Normal:
rec_enable_button->add (*(manage (new Image (::get_icon (X_("record_normal_red"))))));
break;
@@ -657,8 +681,8 @@ RouteTimeAxisView::_set_track_mode (Track* track, TrackMode mode, RadioMenuItem*
rec_enable_button->add (*(manage (new Image (::get_icon (X_("record_tape_red"))))));
break;
}
- rec_enable_button->show_all ();
+ rec_enable_button->show_all ();
}
void
@@ -670,6 +694,9 @@ RouteTimeAxisView::track_mode_changed ()
case ARDOUR::Normal:
item = normal_track_mode_item;
break;
+ case ARDOUR::NonLayered:
+ item = non_layered_track_mode_item;
+ break;
case ARDOUR::Destructive:
item = destructive_track_mode_item;
break;
diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h
index cf1e86c0b4..9c386bafa3 100644
--- a/gtk2_ardour/route_time_axis.h
+++ b/gtk2_ardour/route_time_axis.h
@@ -283,6 +283,7 @@ protected:
Gtk::RadioMenuItem* align_existing_item;
Gtk::RadioMenuItem* align_capture_item;
Gtk::RadioMenuItem* normal_track_mode_item;
+ Gtk::RadioMenuItem* non_layered_track_mode_item;
Gtk::RadioMenuItem* destructive_track_mode_item;
Gtk::Menu* playlist_menu;
Gtk::Menu* playlist_action_menu;
@@ -298,7 +299,7 @@ protected:
ArdourCanvas::SimpleRect* timestretch_rect;
void set_track_mode (ARDOUR::TrackMode);
- void _set_track_mode (ARDOUR::Track* track, ARDOUR::TrackMode mode, Gtk::RadioMenuItem* reset_item);
+ void _set_track_mode (ARDOUR::Track* track, ARDOUR::TrackMode mode, Gtk::RadioMenuItem* reset_item, Gtk::RadioMenuItem* reset_item_2);
void track_mode_changed ();
list<ProcessorAutomationInfo*> processor_automation;
diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc
index 8d36427a0b..27131fa3e3 100644
--- a/gtk2_ardour/streamview.cc
+++ b/gtk2_ardour/streamview.cc
@@ -424,6 +424,8 @@ StreamView::update_rec_box ()
double xend;
switch (_trackview.track()->mode()) {
+
+ case NonLayered:
case Normal:
rect.length = at - rect.start;
xstart = _trackview.editor().frame_to_pixel (rect.start);