#include "audio_time_axis.h"
#include "automation_time_axis.h"
#include "streamview.h"
+#include "audio_streamview.h"
#include "audio_region_view.h"
#include "rgb_macros.h"
#include "selection_templates.h"
} else if (!force_playhead && !selection->markers.empty()) {
bool is_start;
- Location* loc = find_location_from_marker (selection->markers.front(), is_start);
- if (loc) {
-
- begin_reversible_command (_("nudge location forward"));
-
- XMLNode& before (loc->get_state());
-
- if (is_start) {
- distance = get_nudge_distance (loc->start(), next_distance);
- if (next) {
- distance = next_distance;
- }
- if (max_frames - distance > loc->start() + loc->length()) {
- loc->set_start (loc->start() + distance);
- } else {
- loc->set_start (max_frames - loc->length());
- }
- } else {
- distance = get_nudge_distance (loc->end(), next_distance);
- if (next) {
- distance = next_distance;
- }
- if (max_frames - distance > loc->end()) {
- loc->set_end (loc->end() + distance);
+ begin_reversible_command (_("nudge location forward"));
+
+ for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
+
+ Location* loc = find_location_from_marker ((*i), is_start);
+
+ if (loc) {
+
+ XMLNode& before (loc->get_state());
+
+ if (is_start) {
+ distance = get_nudge_distance (loc->start(), next_distance);
+ if (next) {
+ distance = next_distance;
+ }
+ if (max_frames - distance > loc->start() + loc->length()) {
+ loc->set_start (loc->start() + distance);
+ } else {
+ loc->set_start (max_frames - loc->length());
+ }
} else {
- loc->set_end (max_frames);
+ distance = get_nudge_distance (loc->end(), next_distance);
+ if (next) {
+ distance = next_distance;
+ }
+ if (max_frames - distance > loc->end()) {
+ loc->set_end (loc->end() + distance);
+ } else {
+ loc->set_end (max_frames);
+ }
}
+ XMLNode& after (loc->get_state());
+ session->add_command (new MementoCommand<Location>(*loc, &before, &after));
}
- XMLNode& after (loc->get_state());
- session->add_command (new MementoCommand<Location>(*loc, &before, &after));
- commit_reversible_command ();
}
+ commit_reversible_command ();
+
} else {
distance = get_nudge_distance (playhead_cursor->current_frame, next_distance);
session->request_locate (playhead_cursor->current_frame + distance);
} else if (!force_playhead && !selection->markers.empty()) {
bool is_start;
- Location* loc = find_location_from_marker (selection->markers.front(), is_start);
- if (loc) {
-
- begin_reversible_command (_("nudge location forward"));
- XMLNode& before (loc->get_state());
+ begin_reversible_command (_("nudge location forward"));
- if (is_start) {
- distance = get_nudge_distance (loc->start(), next_distance);
- if (next) {
- distance = next_distance;
- }
- if (distance < loc->start()) {
- loc->set_start (loc->start() - distance);
- } else {
- loc->set_start (0);
- }
- } else {
- distance = get_nudge_distance (loc->end(), next_distance);
-
- if (next) {
- distance = next_distance;
- }
+ for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
- if (distance < loc->end() - loc->length()) {
- loc->set_end (loc->end() - distance);
+ Location* loc = find_location_from_marker ((*i), is_start);
+
+ if (loc) {
+
+ XMLNode& before (loc->get_state());
+
+ if (is_start) {
+ distance = get_nudge_distance (loc->start(), next_distance);
+ if (next) {
+ distance = next_distance;
+ }
+ if (distance < loc->start()) {
+ loc->set_start (loc->start() - distance);
+ } else {
+ loc->set_start (0);
+ }
} else {
- loc->set_end (loc->length());
+ distance = get_nudge_distance (loc->end(), next_distance);
+
+ if (next) {
+ distance = next_distance;
+ }
+
+ if (distance < loc->end() - loc->length()) {
+ loc->set_end (loc->end() - distance);
+ } else {
+ loc->set_end (loc->length());
+ }
}
+
+ XMLNode& after (loc->get_state());
+ session->add_command (new MementoCommand<Location>(*loc, &before, &after));
}
-
- XMLNode& after (loc->get_state());
- session->add_command (new MementoCommand<Location>(*loc, &before, &after));
}
-
+
+ commit_reversible_command ();
+
} else {
distance = get_nudge_distance (playhead_cursor->current_frame, next_distance);
{
Gtk::Adjustment* adj = edit_vscrollbar.get_adjustment();
- double vert_value = adj->get_value() + 20;
+ double vert_value = adj->get_value() + 60;
if (vert_value>adj->get_upper() - canvas_height) {
vert_value = adj->get_upper() - canvas_height;
Editor::scroll_tracks_up_line ()
{
Gtk::Adjustment* adj = edit_vscrollbar.get_adjustment();
- adj->set_value (adj->get_value() - 20);
+ adj->set_value (adj->get_value() - 60);
}
/* ZOOM */
nframes64_t end = 0;
RegionSelection rs;
set<TimeAxisView*> tracks;
- double top_y_position = DBL_MAX;
get_regions_for_action (rs);
}
tracks.insert (&((*i)->get_time_axis_view()));
-
- if ((*i)->get_time_axis_view().y_position < top_y_position) {
- top_y_position = (*i)->get_time_axis_view().y_position;
- }
}
/* now comes an "interesting" hack ... make sure we leave a little space
temporal_zoom_by_frame (start, end, "zoom to region");
if (both_axes) {
- uint32_t per_track_height = (uint32_t) floor ((canvas_height - 10.0) / tracks.size());
+ uint32_t per_track_height = (uint32_t) floor ((canvas_height - canvas_timebars_vsize - 10.0) / tracks.size());
/* set visible track heights appropriately */
no_route_list_redisplay = false;
redisplay_route_list ();
- vertical_adjustment.set_value (std::max (top_y_position - 5.0, 0.0));
+ vertical_adjustment.set_value (0);
no_save_visual = false;
}
void
Editor::temporal_zoom_to_frame (bool coarser, nframes64_t frame)
{
- if (!session) return;
-
+ if (!session) {
+ return;
+ }
double range_before = frame - leftmost_frame;
double new_fpu;
range_before /= 1.61803399;
}
- if (new_fpu == frames_per_unit) return;
+ if (new_fpu == frames_per_unit) {
+ return;
+ }
nframes64_t new_leftmost = frame - (nframes64_t)range_before;
- if (new_leftmost > frame) new_leftmost = 0;
-
+ if (new_leftmost > frame) {
+ new_leftmost = 0;
+ }
// begin_reversible_command (_("zoom to frame"));
// session->add_undo (bind (mem_fun(*this, &Editor::reposition_and_zoom), leftmost_frame, frames_per_unit));
// session->add_redo (bind (mem_fun(*this, &Editor::reposition_and_zoom), new_leftmost, new_fpu));
boost::shared_ptr<Playlist> playlist;
track_canvas->window_to_world (x, y, wx, wy);
- wx += horizontal_adjustment.get_value();
- wy += vertical_adjustment.get_value();
+ //wx += horizontal_adjustment.get_value();
+ //wy += vertical_adjustment.get_value();
GdkEvent event;
event.type = GDK_BUTTON_RELEASE;
return;
}
- nframes64_t distance;
+ nframes64_t distance = 0;
nframes64_t pos = 0;
- int dir;
+ int dir = 1;
list<RegionView*> sorted;
rs.by_position (sorted);
pos = position;
if (position > r->position()) {
distance = position - r->position();
- dir = 1;
} else {
distance = r->position() - position;
dir = -1;
if (position > r->last_frame()) {
distance = position - r->last_frame();
pos = r->position() + distance;
- dir = 1;
} else {
distance = r->last_frame() - position;
pos = r->position() - distance;
pos = r->adjust_to_sync (position);
if (pos > r->position()) {
distance = pos - r->position();
- dir = 1;
} else {
distance = r->position() - pos;
dir = -1;
}
void
-Editor::bounce_range_selection ()
+Editor::bounce_range_selection (bool replace)
{
if (selection->time.empty()) {
return;
itt.progress = false;
XMLNode &before = playlist->get_state();
- atv->audio_track()->bounce_range (start, cnt, itt);
+ boost::shared_ptr<Region> r = atv->audio_track()->bounce_range (start, start+cnt, itt);
+
+ if (replace) {
+ list<AudioRange> ranges;
+ ranges.push_back (AudioRange (start, start+cnt, 0));
+ playlist->cut (ranges); // discard result
+ playlist->add_region (r, start);
+ }
+
XMLNode &after = playlist->get_state();
session->add_command (new MementoCommand<Playlist> (*playlist, &before, &after));
}
}
}
+void
+Editor::toggle_record_enable ()
+{
+ bool new_state;
+ bool first = true;
+ for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
+ RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView *>(*i);
+ if (!rtav)
+ continue;
+ if (!rtav->is_track())
+ continue;
+
+ if (first) {
+ new_state = !rtav->track()->record_enabled();
+ first = false;
+ }
+
+ rtav->track()->set_record_enable(new_state, this);
+ }
+}
+
+
void
Editor::set_fade_length (bool in)
{
const char* cmd = (in ? _("toggle fade in active") : _("toggle fade out active"));
bool have_switch = false;
- bool yn;
+ bool yn = false;
begin_reversible_command (cmd);
commit_reversible_command ();
}
+void
+Editor::toggle_selected_region_fades (int dir)
+{
+ RegionSelection rs;
+ RegionSelection::iterator i;
+ boost::shared_ptr<AudioRegion> ar;
+ bool yn;
+
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
+ return;
+ }
+
+ for (i = rs.begin(); i != rs.end(); ++i) {
+ if ((ar = boost::dynamic_pointer_cast<AudioRegion>((*i)->region())) != 0) {
+ if (dir == -1) {
+ yn = ar->fade_out_active ();
+ } else {
+ yn = ar->fade_in_active ();
+ }
+ break;
+ }
+ }
+
+ if (i == rs.end()) {
+ return;
+ }
+
+ /* XXX should this undo-able? */
+
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+ if ((ar = boost::dynamic_pointer_cast<AudioRegion>((*i)->region())) == 0) {
+ continue;
+ }
+ if (dir == 1 || dir == 0) {
+ ar->set_fade_in_active (!yn);
+ }
+
+ if (dir == -1 || dir == 0) {
+ ar->set_fade_out_active (!yn);
+ }
+ }
+}
+
+
+/** Update region fade visibility after its configuration has been changed */
+void
+Editor::update_region_fade_visibility ()
+{
+ bool _fade_visibility = Config->get_show_region_fades ();
+
+ for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ AudioTimeAxisView* v = dynamic_cast<AudioTimeAxisView*>(*i);
+ if (v) {
+ if (_fade_visibility) {
+ v->audio_view()->show_all_fades ();
+ } else {
+ v->audio_view()->hide_all_fades ();
+ }
+ }
+ }
+}
/** Update crossfade visibility after its configuration has been changed */
void
TimeAxisView* current = selection->tracks.front();
- for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
- if (*i == current) {
- ++i;
- if (i != track_views.end()) {
- selection->set (*i);
- } else {
- selection->set (*(track_views.begin()));
+ RouteUI *rui;
+ do {
+ for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ if (*i == current) {
+ ++i;
+ if (i != track_views.end()) {
+ current = (*i);
+ } else {
+ current = (*(track_views.begin()));
+ //selection->set (*(track_views.begin()));
+ }
+ break;
}
- break;
}
- }
+ rui = dynamic_cast<RouteUI *>(current);
+ } while ( current->hidden() || (rui != NULL && !rui->route()->active()));
+
+ selection->set(current);
+
+ ensure_track_visible(current);
}
void
TimeAxisView* current = selection->tracks.front();
- for (TrackViewList::reverse_iterator i = track_views.rbegin(); i != track_views.rend(); ++i) {
- if (*i == current) {
- ++i;
- if (i != track_views.rend()) {
- selection->set (*i);
- } else {
- selection->set (*(track_views.rbegin()));
+ RouteUI *rui;
+ do {
+ for (TrackViewList::reverse_iterator i = track_views.rbegin(); i != track_views.rend(); ++i) {
+ if (*i == current) {
+ ++i;
+ if (i != track_views.rend()) {
+ current = (*i);
+ } else {
+ current = *(track_views.rbegin());
+ }
+ break;
}
- break;
}
+ rui = dynamic_cast<RouteUI *>(current);
+ } while ( current->hidden() || (rui != NULL && !rui->route()->active()));
+
+ selection->set (current);
+
+ ensure_track_visible(current);
+}
+
+void
+Editor::ensure_track_visible(TimeAxisView *track)
+{
+ if (track->hidden())
+ return;
+
+ double current_view_min_y = vertical_adjustment.get_value();
+ double current_view_max_y = vertical_adjustment.get_value() + vertical_adjustment.get_page_size() - canvas_timebars_vsize;
+
+ double track_min_y = track->y_position;
+ double track_max_y = track->y_position + (double)track->effective_height;
+
+ if (track_min_y >= current_view_min_y &&
+ track_max_y <= current_view_max_y) {
+ return;
}
+
+ double new_value;
+
+ if (track_min_y < current_view_min_y) {
+ // Track is above the current view
+ new_value = track_min_y;
+ } else {
+ // Track is below the current view
+ new_value = track->y_position + (double)track->effective_height + canvas_timebars_vsize - vertical_adjustment.get_page_size();
+ }
+
+ vertical_adjustment.set_value(new_value);
}
void
child_heights += ((*t)->effective_height - (*t)->current_height());
}
- uint32_t h = (uint32_t) floor ((canvas_height - child_heights)/selection->tracks.size());
+ uint32_t h = (uint32_t) floor ((canvas_height - child_heights - canvas_timebars_vsize)/selection->tracks.size());
double first_y_pos = DBL_MAX;
+ if (h < TimeAxisView::hSmall) {
+ MessageDialog msg (*this, _("There are too many selected tracks to fit in the current window"));
+ /* too small to be displayed */
+ return;
+ }
+
undo_visual_stack.push_back (current_visual_state());
- for (TrackSelection::iterator t = selection->tracks.begin(); t != selection->tracks.end(); ++t) {
- (*t)->set_height (h);
- first_y_pos = std::min ((*t)->y_position, first_y_pos);
+ /* operate on all tracks, hide unselected ones that are in the middle of selected ones */
+
+ bool prev_was_selected = false;
+ bool is_selected = selection->selected (track_views.front());
+ bool next_is_selected;
+
+ for (TrackViewList::iterator t = track_views.begin(); t != track_views.end(); ++t) {
+
+ TrackViewList::iterator next;
+
+ next = t;
+ ++next;
+
+ if (next != track_views.end()) {
+ next_is_selected = selection->selected (*next);
+ } else {
+ next_is_selected = false;
+ }
+
+ if (is_selected) {
+ (*t)->set_height (h);
+ first_y_pos = std::min ((*t)->y_position, first_y_pos);
+ } else {
+ if (prev_was_selected && next_is_selected) {
+ hide_track_in_display (**t);
+ }
+ }
+
+ prev_was_selected = is_selected;
+ is_selected = next_is_selected;
}
+ /*
+ set the controls_layout height now, because waiting for its size
+ request signal handler will cause the vertical adjustment setting to fail
+ */
+ controls_layout.property_height () = full_canvas_height - canvas_timebars_vsize;
vertical_adjustment.set_value (first_y_pos);
redo_visual_stack.push_back (current_visual_state());
return false; // do not call again
}
+