13
0

unfinished work on selection/HiG details, restore range ops destroyed by autoscroll changes

git-svn-id: svn://localhost/trunk/ardour2@544 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2006-05-31 02:46:04 +00:00
parent 0354401e00
commit 415d3a5018
22 changed files with 587 additions and 280 deletions

View File

@ -14,7 +14,7 @@ import SCons.Node.FS
SConsignFile()
EnsureSConsVersion(0, 96)
version = '2.0alpha2'
version = '2.0beta1'
subst_dict = { }

View File

@ -262,6 +262,7 @@ env.Alias('install', env.Install(os.path.join(install_prefix, 'share/ardour2/pix
env.Alias ('tarball', env.Distribute (env['DISTTREE'],
[ 'SConscript',
'i18n.h', 'gettext.h',
'ardour.sh.in',
'ardour2_ui.rc', 'splash.ppm',
'ardour.menus', 'ardour.bindings', 'ardour.colors',
'editor_xpms'

View File

@ -1048,7 +1048,7 @@ AudioTimeAxisView::get_selectables (jack_nframes_t start, jack_nframes_t end, do
jack_nframes_t start_adjusted = session_frame_to_track_frame(start, speed);
jack_nframes_t end_adjusted = session_frame_to_track_frame(end, speed);
if (view && touched (top, bot)) {
if (view && ((top < 0.0 && bot < 0.0)) || touched (top, bot)) {
view->get_selectables (start_adjusted, end_adjusted, results);
}

View File

@ -38,7 +38,7 @@ struct DragInfo {
bool copy;
bool was_rolling;
bool first_move;
bool move_threshold_passsed;
bool move_threshold_passed;
bool want_move_threshold;
bool brushing;
ARDOUR::Location* copied_location;

View File

@ -326,6 +326,7 @@ Editor::Editor (AudioEngine& eng)
last_canvas_frame = 0;
edit_cursor = 0;
playhead_cursor = 0;
button_release_can_deselect = true;
location_marker_color = color_map[cLocationMarker];
location_range_color = color_map[cLocationRange];
@ -2981,31 +2982,31 @@ Editor::commit_reversible_command ()
}
}
void
Editor::set_selected_track_from_click (Selection::Operation op, bool with_undo, bool no_remove)
bool
Editor::set_selected_track_from_click (bool press, Selection::Operation op, bool with_undo, bool no_remove)
{
bool commit = false;
if (!clicked_trackview) {
return;
return false;
}
if (with_undo) {
begin_reversible_command (_("set selected trackview"));
}
switch (op) {
case Selection::Toggle:
if (selection->selected (clicked_trackview)) {
if (!no_remove) {
selection->remove (clicked_trackview);
commit = true;
}
} else {
selection->toggle (clicked_trackview);
selection->add (clicked_trackview);
commit = false;
}
break;
case Selection::Set:
if (selection->selected (clicked_trackview) && selection->tracks.size() == 1) {
/* no commit necessary */
return;
}
selection->set (clicked_trackview);
@ -3015,27 +3016,19 @@ Editor::set_selected_track_from_click (Selection::Operation op, bool with_undo,
/* not defined yet */
break;
}
if (with_undo) {
commit_reversible_command ();
}
return commit;
}
void
Editor::set_selected_control_point_from_click (Selection::Operation op, bool with_undo, bool no_remove)
bool
Editor::set_selected_control_point_from_click (bool press, Selection::Operation op, bool with_undo, bool no_remove)
{
if (!clicked_control_point) {
return;
return false;
}
/* select this point and any others that it represents */
bool commit;
if (with_undo) {
begin_reversible_command (_("select control points"));
}
double y1, y2;
jack_nframes_t x1, x2;
@ -3044,18 +3037,12 @@ Editor::set_selected_control_point_from_click (Selection::Operation op, bool wit
y1 = clicked_control_point->get_x() - 10;
y2 = clicked_control_point->get_y() + 10;
commit = select_all_within (x1, x2, y1, y2, op);
if (with_undo && commit) {
commit_reversible_command ();
}
return select_all_within (x1, x2, y1, y2, op);
}
void
Editor::mapover_audio_tracks (slot<void,AudioTimeAxisView&,uint32_t> sl)
Editor::get_relevant_audio_tracks (AudioTimeAxisView& base, set<AudioTimeAxisView*>& relevant_tracks)
{
set<AudioTimeAxisView*> relevant_tracks;
/* step one: get all selected tracks and all tracks in the relevant edit groups */
for (TrackSelection::iterator ti = selection->tracks.begin(); ti != selection->tracks.end(); ++ti) {
@ -3088,12 +3075,22 @@ Editor::mapover_audio_tracks (slot<void,AudioTimeAxisView&,uint32_t> sl)
/* no active group, or no group */
relevant_tracks.insert (atv);
relevant_tracks.insert (&base);
}
}
}
/* step two: apply operation to each track */
void
Editor::mapover_audio_tracks (slot<void,AudioTimeAxisView&,uint32_t> sl)
{
set<AudioTimeAxisView*> relevant_tracks;
if (!clicked_audio_trackview) {
return;
}
get_relevant_audio_tracks (*clicked_audio_trackview, relevant_tracks);
uint32_t sz = relevant_tracks.size();
@ -3110,11 +3107,17 @@ Editor::mapped_set_selected_regionview_from_click (AudioTimeAxisView& atv, uint3
vector<AudioRegion*> results;
AudioRegionView* marv;
DiskStream* ds;
if ((ds = atv.get_diskstream()) == 0) {
/* bus */
return;
}
if (&atv == &basis->get_time_axis_view()) {
/* looking in same track as the original */
return;
}
if ((pl = ds->playlist()) != 0) {
pl->get_equivalent_regions (basis->region, results);
@ -3127,70 +3130,192 @@ Editor::mapped_set_selected_regionview_from_click (AudioTimeAxisView& atv, uint3
}
}
void
Editor::set_selected_regionview_from_click (Selection::Operation op, bool no_track_remove)
bool
Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, bool no_track_remove)
{
cerr << "In SSRfC\n";
vector<AudioRegionView*> all_equivalent_regions;
bool commit = false;
if (!clicked_regionview) {
return;
if (!clicked_regionview || !clicked_audio_trackview) {
return false;
}
mapover_audio_tracks (bind (mem_fun (*this, &Editor::mapped_set_selected_regionview_from_click),
clicked_regionview, &all_equivalent_regions));
cerr << "mapover done\n";
begin_reversible_command (_("set selected regionview"));
switch (op) {
case Selection::Toggle:
selection->toggle (clicked_regionview);
#if 0
if (clicked_regionview->get_selected()) {
if (/* group && group->is_active() && */ selection->audio_regions.size() > 1) {
/* reduce selection down to just the one clicked */
selection->set (clicked_regionview);
} else {
selection->remove (clicked_regionview);
}
} else {
selection->add (all_equivalent_regions);
}
#endif
set_selected_track_from_click (op, false, no_track_remove);
break;
case Selection::Set:
// karsten wiese suggested these two lines to make
// a selected region rise to the top. but this
// leads to a mismatch between actual layering
// and visual layering. resolution required ....
//
// gnome_canvas_item_raise_to_top (clicked_regionview->get_canvas_group());
// gnome_canvas_item_raise_to_top (clicked_regionview->get_time_axis_view().canvas_display);
if (clicked_regionview->get_selected()) {
/* no commit necessary: we are the one selected. */
return;
} else {
if (op == Selection::Toggle || op == Selection::Set) {
mapover_audio_tracks (bind (mem_fun (*this, &Editor::mapped_set_selected_regionview_from_click),
clicked_regionview, &all_equivalent_regions));
/* add clicked regionview since we skipped all other regions in the same track as the one it was in */
all_equivalent_regions.push_back (clicked_regionview);
switch (op) {
case Selection::Toggle:
selection->set (all_equivalent_regions);
set_selected_track_from_click (op, false, false);
if (clicked_regionview->get_selected()) {
if (press) {
/* whatever was clicked was selected already; do nothing here but allow
the button release to deselect it
*/
button_release_can_deselect = true;
} else {
if (button_release_can_deselect) {
/* just remove this one region, but only on a permitted button release */
selection->remove (clicked_regionview);
commit = true;
/* no more deselect action on button release till a new press
finds an already selected object.
*/
button_release_can_deselect = false;
}
}
} else {
if (press) {
/* add all the equivalent regions, but only on button press */
if (!all_equivalent_regions.empty()) {
commit = true;
}
for (vector<AudioRegionView*>::iterator i = all_equivalent_regions.begin(); i != all_equivalent_regions.end(); ++i) {
selection->add (*i);
}
}
}
break;
case Selection::Set:
if (!clicked_regionview->get_selected()) {
selection->set (all_equivalent_regions);
commit = true;
} else {
/* no commit necessary: clicked on an already selected region */
goto out;
}
break;
default:
/* silly compiler */
break;
}
break;
case Selection::Extend:
/* not defined yet */
break;
} else if (op == Selection::Extend) {
list<Selectable*> results;
jack_nframes_t last_frame;
jack_nframes_t first_frame;
/* 1. find the last selected regionview in the track that was clicked in */
last_frame = 0;
first_frame = max_frames;
for (AudioRegionSelection::iterator x = selection->audio_regions.begin(); x != selection->audio_regions.end(); ++x) {
if (&(*x)->get_time_axis_view() == &clicked_regionview->get_time_axis_view()) {
if ((*x)->region.last_frame() > last_frame) {
last_frame = (*x)->region.last_frame();
}
if ((*x)->region.first_frame() < first_frame) {
first_frame = (*x)->region.first_frame();
}
}
}
/* 2. figure out the boundaries for our search for new objects */
switch (clicked_regionview->region.coverage (first_frame, last_frame)) {
case OverlapNone:
cerr << "no overlap, first = " << first_frame << " last = " << last_frame << " region = "
<< clicked_regionview->region.first_frame() << " .. " << clicked_regionview->region.last_frame() << endl;
if (last_frame < clicked_regionview->region.first_frame()) {
first_frame = last_frame;
last_frame = clicked_regionview->region.last_frame();
} else {
last_frame = first_frame;
first_frame = clicked_regionview->region.first_frame();
}
break;
case OverlapExternal:
cerr << "external overlap, first = " << first_frame << " last = " << last_frame << " region = "
<< clicked_regionview->region.first_frame() << " .. " << clicked_regionview->region.last_frame() << endl;
if (last_frame < clicked_regionview->region.first_frame()) {
first_frame = last_frame;
last_frame = clicked_regionview->region.last_frame();
} else {
last_frame = first_frame;
first_frame = clicked_regionview->region.first_frame();
}
break;
case OverlapInternal:
cerr << "internal overlap, first = " << first_frame << " last = " << last_frame << " region = "
<< clicked_regionview->region.first_frame() << " .. " << clicked_regionview->region.last_frame() << endl;
if (last_frame < clicked_regionview->region.first_frame()) {
first_frame = last_frame;
last_frame = clicked_regionview->region.last_frame();
} else {
last_frame = first_frame;
first_frame = clicked_regionview->region.first_frame();
}
break;
case OverlapStart:
case OverlapEnd:
/* nothing to do except add clicked region to selection, since it
overlaps with the existing selection in this track.
*/
break;
}
/* 2. find all selectable objects (regionviews in this case) between that one and the end of the
one that was clicked.
*/
set<AudioTimeAxisView*> relevant_tracks;
get_relevant_audio_tracks (*clicked_audio_trackview, relevant_tracks);
for (set<AudioTimeAxisView*>::iterator t = relevant_tracks.begin(); t != relevant_tracks.end(); ++t) {
(*t)->get_selectables (first_frame, last_frame, -1.0, -1.0, results);
}
/* 3. convert to a vector of audio regions */
vector<AudioRegionView*> audio_regions;
for (list<Selectable*>::iterator x = results.begin(); x != results.end(); ++x) {
AudioRegionView* arv;
if ((arv = dynamic_cast<AudioRegionView*>(*x)) != 0) {
audio_regions.push_back (arv);
}
}
if (!audio_regions.empty()) {
selection->add (audio_regions);
commit = true;
}
}
cerr << "case done\n";
commit_reversible_command () ;
out:
return commit;
}
void
@ -3237,13 +3362,13 @@ Editor::set_selected_regionview_from_region_list (Region& r, Selection::Operatio
switch (op) {
case Selection::Toggle:
/* XXX this is not correct */
selection->add (all_equivalent_regions);
selection->toggle (all_equivalent_regions);
break;
case Selection::Set:
selection->set (all_equivalent_regions);
break;
case Selection::Extend:
/* not defined yet */
selection->add (all_equivalent_regions);
break;
}

View File

@ -413,6 +413,7 @@ class Editor : public PublicEditor
CrossfadeView* clicked_crossfadeview;
ControlPoint* clicked_control_point;
void get_relevant_audio_tracks (AudioTimeAxisView& base, std::set<AudioTimeAxisView*>& relevant_tracks);
void mapover_audio_tracks (sigc::slot<void,AudioTimeAxisView&,uint32_t> sl);
/* functions to be passed to mapover_audio_tracks(), possibly with sigc::bind()-supplied arguments */
@ -424,10 +425,15 @@ class Editor : public PublicEditor
/* end */
void button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type);
bool button_release_can_deselect;
void catch_vanishing_audio_regionview (AudioRegionView *);
void set_selected_control_point_from_click (Selection::Operation op = Selection::Set, bool with_undo = true, bool no_remove=false);
void set_selected_track_from_click (Selection::Operation op = Selection::Set, bool with_undo = true, bool no_remove=false);
void set_selected_regionview_from_click (Selection::Operation op = Selection::Set, bool no_track_remove=false);
bool set_selected_control_point_from_click (bool press, Selection::Operation op = Selection::Set, bool with_undo = true, bool no_remove=false);
bool set_selected_track_from_click (bool press, Selection::Operation op = Selection::Set, bool with_undo = true, bool no_remove=false);
bool set_selected_regionview_from_click (bool press, Selection::Operation op = Selection::Set, bool no_track_remove=false);
void set_selected_regionview_from_region_list (ARDOUR::Region& region, Selection::Operation op = Selection::Set);
bool set_selected_regionview_from_map_event (GdkEventAny*, StreamView*, ARDOUR::Region*);
void collect_new_region_view (AudioRegionView *);
@ -1037,6 +1043,7 @@ class Editor : public PublicEditor
void start_grab (GdkEvent*, Gdk::Cursor* cursor = 0);
bool end_grab (ArdourCanvas::Item*, GdkEvent*);
void swap_grab (ArdourCanvas::Item*, Gdk::Cursor* cursor, uint32_t time);
Gtk::Menu fade_context_menu;
void popup_fade_context_menu (int, int, ArdourCanvas::Item*, ItemType);

View File

@ -537,7 +537,6 @@ Editor::maybe_autoscroll (GdkEvent* event)
}
last_autoscroll_direction = autoscroll_direction;
drag_info.last_pointer_frame = drag_info.current_pointer_frame;
}
gint

View File

@ -96,7 +96,6 @@ Editor::event_frame (GdkEvent* event, double* pcx, double* pcy)
break;
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
cerr << "here\n";
// track_canvas.w2c(event->key.x, event->key.y, *pcx, *pcy);
break;
default:
@ -284,6 +283,93 @@ Editor::step_mouse_mode (bool next)
}
}
void
Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
{
bool commit;
bool c1;
bool c2;
/* in object/audition/timefx mode, any button press sets
the selection if the object can be selected. this is a
bit of hack, because we want to avoid this if the
mouse operation is a region alignment.
note: not dbl-click or triple-click
*/
if (((mouse_mode != MouseObject) &&
(mouse_mode != MouseAudition || item_type != RegionItem) &&
(mouse_mode != MouseTimeFX || item_type != RegionItem)) ||
(event->type != GDK_BUTTON_PRESS && event->type != GDK_BUTTON_RELEASE || event->button.button > 3)) {
return;
}
Selection::Operation op = Keyboard::selection_type (event->button.state);
bool press = (event->type == GDK_BUTTON_PRESS);
begin_reversible_command (_("select on click"));
switch (item_type) {
case RegionItem:
c1 = set_selected_track_from_click (press, op, true, true);
c2 = set_selected_regionview_from_click (press, op, true);
commit = (c1 || c2);
break;
case AudioRegionViewNameHighlight:
case AudioRegionViewName:
c1 = set_selected_track_from_click (press, op, true, true);
c2 = set_selected_regionview_from_click (press, op, true);
commit = (c1 || c2);
break;
case GainAutomationControlPointItem:
case PanAutomationControlPointItem:
case RedirectAutomationControlPointItem:
c1 = set_selected_track_from_click (press, op, true, true);
c2 = set_selected_control_point_from_click (press, op, false);
commit = (c1 || c2);
break;
case StreamItem:
commit = set_selected_track_from_click (press, op, true, true);
break;
case AutomationTrackItem:
commit = set_selected_track_from_click (press, op, true, true);
break;
default:
break;
}
#define SELECT_TRACK_FROM_CANVAS_IN_RANGE_MODE
#ifdef SELECT_TRACK_FROM_CANVAS_IN_RANGE_MODE
/* in range mode, button 1/2/3 press potentially selects a track */
if (mouse_mode == MouseRange &&
event->type == GDK_BUTTON_PRESS &&
event->button.button <= 3) {
switch (item_type) {
case StreamItem:
case RegionItem:
case AutomationTrackItem:
commit = set_selected_track_from_click (press, op, true, true);
break;
default:
break;
}
}
#endif
if (commit) {
commit_reversible_command ();
}
}
bool
Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
{
@ -295,81 +381,8 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
return true;
}
/* in object/audition/timefx mode, any button press sets
the selection if the object can be selected. this is a
bit of hack, because we want to avoid this if the
mouse operation is a region alignment.
*/
if (((mouse_mode == MouseObject) ||
(mouse_mode == MouseAudition && item_type == RegionItem) ||
(mouse_mode == MouseTimeFX && item_type == RegionItem)) &&
event->type == GDK_BUTTON_PRESS &&
event->button.button <= 3) {
AudioRegionView* rv;
ControlPoint* cp;
/* not dbl-click or triple-click */
switch (item_type) {
case RegionItem:
set_selected_regionview_from_click (Keyboard::selection_type (event->button.state), true);
break;
case AudioRegionViewNameHighlight:
case AudioRegionViewName:
if ((rv = static_cast<AudioRegionView *> (item->get_data ("regionview"))) != 0) {
set_selected_regionview_from_click (Keyboard::selection_type (event->button.state), true);
}
break;
case GainAutomationControlPointItem:
case PanAutomationControlPointItem:
case RedirectAutomationControlPointItem:
if ((cp = static_cast<ControlPoint *> (item->get_data ("control_point"))) != 0) {
set_selected_control_point_from_click (Keyboard::selection_type (event->button.state), false);
}
break;
case StreamItem:
set_selected_track_from_click (Keyboard::selection_type (event->button.state), true, true);
break;
case AutomationTrackItem:
break;
default:
break;
}
}
#define SELECT_TRACK_FROM_CANVAS_IN_RANGE_MODE
#ifdef SELECT_TRACK_FROM_CANVAS_IN_RANGE_MODE
/* in range mode, button 1/2/3 press potentially selects a track */
if (mouse_mode == MouseRange &&
event->type == GDK_BUTTON_PRESS &&
event->button.button <= 3) {
AudioRegionView* rv;
switch (item_type) {
case StreamItem:
case RegionItem:
case AutomationTrackItem:
set_selected_track_from_click (Keyboard::selection_type (event->button.state), true, true);
break;
case AudioRegionViewNameHighlight:
case AudioRegionViewName:
rv = reinterpret_cast<AudioRegionView *> (item->get_data ("regionview"));
default:
break;
}
}
#endif
button_selection (item, event, item_type);
if (drag_info.item == 0 &&
(Keyboard::is_delete_event (&event->button) ||
Keyboard::is_context_menu_event (&event->button) ||
@ -435,6 +448,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
start_range_markerbar_op (item, event, CreateRangeMarker);
return true;
break;
case TransportMarkerBarItem:
start_range_markerbar_op (item, event, CreateTransportMarker);
return true;
@ -564,6 +578,10 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
break ;
/* </CMT Additions> */
case MarkerBarItem:
break;
default:
break;
}
@ -816,6 +834,8 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
}
}
button_selection (item, event, item_type);
/* edit events get handled here */
if (drag_info.item == 0 && Keyboard::is_edit_event (&event->button)) {
@ -1477,13 +1497,13 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
if (!from_autoscroll && drag_info.item) {
/* item != 0 is the best test i can think of for dragging.
*/
if (!drag_info.move_threshold_passsed) {
if (!drag_info.move_threshold_passed) {
drag_info.move_threshold_passsed = (abs ((int) (drag_info.current_pointer_x - drag_info.grab_x)) > 4);
drag_info.move_threshold_passed = (abs ((int) (drag_info.current_pointer_x - drag_info.grab_x)) > 4);
// and change the initial grab loc/frame if this drag info wants us to
if (drag_info.want_move_threshold && drag_info.move_threshold_passsed) {
if (drag_info.want_move_threshold && drag_info.move_threshold_passed) {
drag_info.grab_frame = drag_info.current_pointer_frame;
drag_info.grab_x = drag_info.current_pointer_x;
drag_info.grab_y = drag_info.current_pointer_y;
@ -1555,6 +1575,7 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
handled:
track_canvas_motion (event);
// drag_info.last_pointer_frame = drag_info.current_pointer_frame;
return true;
not_handled:
@ -1597,7 +1618,7 @@ Editor::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
drag_info.cumulative_x_drag = 0;
drag_info.cumulative_y_drag = 0;
drag_info.first_move = true;
drag_info.move_threshold_passsed = false;
drag_info.move_threshold_passed = false;
drag_info.want_move_threshold = false;
drag_info.pointer_frame_offset = 0;
drag_info.brushing = false;
@ -1625,6 +1646,19 @@ Editor::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
}
}
void
Editor::swap_grab (ArdourCanvas::Item* new_item, Gdk::Cursor* cursor, uint32_t time)
{
drag_info.item->ungrab (0);
drag_info.item = new_item;
if (cursor == 0) {
cursor = grabber_cursor;
}
drag_info.item->grab (Gdk::POINTER_MOTION_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK, *cursor, time);
}
bool
Editor::end_grab (ArdourCanvas::Item* item, GdkEvent* event)
{
@ -2020,6 +2054,7 @@ Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
bool is_start;
bool move_both = false;
jack_nframes_t newframe;
if (drag_info.pointer_frame_offset <= (long) drag_info.current_pointer_frame) {
newframe = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
@ -2027,14 +2062,16 @@ Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
else {
newframe = 0;
}
jack_nframes_t next = newframe;
if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
snap_to (newframe, 0, true);
}
if (drag_info.current_pointer_frame == drag_info.last_pointer_frame) return;
if (drag_info.current_pointer_frame == drag_info.last_pointer_frame) {
return;
}
/* call this to find out if its the start or end */
@ -2101,7 +2138,6 @@ Editor::marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
bool is_start;
begin_reversible_command ( _("move marker") );
session->add_undo( session->locations()->get_memento() );
@ -2634,68 +2670,9 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
return;
}
/* this is committed in the grab finished callback. */
begin_reversible_command (_("Drag region copy"));
/* duplicate the region(s) */
vector<AudioRegionView*> new_regionviews;
set<Playlist*> affected_playlists;
pair<set<Playlist*>::iterator,bool> insert_result;
for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
AudioRegionView* rv;
rv = (*i);
Playlist* to_playlist = rv->region.playlist();
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(&rv->get_time_axis_view());
insert_result = affected_playlists.insert (to_playlist);
if (insert_result.second) {
session->add_undo (to_playlist->get_memento ());
}
latest_regionview = 0;
sigc::connection c = atv->view->AudioRegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
/* create a new region with the same name.
*/
AudioRegion* newregion = new AudioRegion (rv->region);
/* if the original region was locked, we don't care */
newregion->set_locked (false);
to_playlist->add_region (*newregion, (jack_nframes_t) (rv->region.position() * atv->get_diskstream()->speed()));
c.disconnect ();
if (latest_regionview) {
new_regionviews.push_back (latest_regionview);
}
}
if (new_regionviews.empty()) {
return;
}
/* reset selection to new regionviews */
selection->set (new_regionviews);
/* reset drag_info data to reflect the fact that we are dragging the copies */
drag_info.data = new_regionviews.front();
drag_info.item = new_regionviews.front()->get_canvas_group ();
drag_info.copy = true;
drag_info.motion_callback = &Editor::region_drag_motion_callback;
drag_info.finished_callback = &Editor::region_drag_finished_callback;
drag_info.item = item;
drag_info.data = clicked_regionview;
start_grab(event);
@ -2712,10 +2689,8 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position;
// we want a move threshold
drag_info.want_move_threshold = true;
show_verbose_time_cursor (drag_info.last_frame_position, 10);
//begin_reversible_command (_("copy region(s)"));
drag_info.motion_callback = &Editor::region_drag_motion_callback;
drag_info.finished_callback = &Editor::region_drag_finished_callback;
}
void
@ -2764,6 +2739,72 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
vector<int32_t> height_list(512) ;
vector<int32_t>::iterator j;
show_verbose_time_cursor (drag_info.last_frame_position, 10);
if (drag_info.copy && drag_info.move_threshold_passed && drag_info.want_move_threshold) {
drag_info.want_move_threshold = false; // don't copy again
/* this is committed in the grab finished callback. */
begin_reversible_command (_("Drag region copy"));
/* duplicate the region(s) */
vector<AudioRegionView*> new_regionviews;
set<Playlist*> affected_playlists;
pair<set<Playlist*>::iterator,bool> insert_result;
for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
AudioRegionView* rv;
rv = (*i);
Playlist* to_playlist = rv->region.playlist();
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(&rv->get_time_axis_view());
insert_result = affected_playlists.insert (to_playlist);
if (insert_result.second) {
session->add_undo (to_playlist->get_memento ());
}
latest_regionview = 0;
sigc::connection c = atv->view->AudioRegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
/* create a new region with the same name.
*/
AudioRegion* newregion = new AudioRegion (rv->region);
/* if the original region was locked, we don't care */
newregion->set_locked (false);
to_playlist->add_region (*newregion, (jack_nframes_t) (rv->region.position() * atv->get_diskstream()->speed()));
c.disconnect ();
if (latest_regionview) {
new_regionviews.push_back (latest_regionview);
}
}
if (new_regionviews.empty()) {
return;
}
/* reset selection to new regionviews */
selection->set (new_regionviews);
/* reset drag_info data to reflect the fact that we are dragging the copies */
drag_info.data = new_regionviews.front();
swap_grab (new_regionviews.front()->get_canvas_group (), 0, event->motion.time);
}
/* Which trackview is this ? */
TimeAxisView* tvp = trackview_by_y_position (drag_info.current_pointer_y);
@ -2947,7 +2988,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
the region would be if we moved it by that much.
*/
if (drag_info.move_threshold_passsed) {
if (drag_info.move_threshold_passed) {
if ((int32_t)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
@ -3507,7 +3548,7 @@ Editor::show_verbose_duration_cursor (jack_nframes_t start, jack_nframes_t end,
/* XXX fix this to compute min/sec properly */
session->smpte_duration (end - start, smpte);
secs = smpte.seconds + ((float) smpte.frames / session->smpte_frames_per_second);
snprintf (buf, sizeof (buf), "%02ld:%02ld:%.4f", smpte.hours, smpte.minutes, secs);
snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%.4f", smpte.hours, smpte.minutes, secs);
break;
default:
@ -3629,7 +3670,6 @@ Editor::start_selection_op (ArdourCanvas::Item* item, GdkEvent* event, Selection
switch (op) {
case CreateSelection:
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Shift)) {
drag_info.copy = true;
} else {
@ -3639,14 +3679,18 @@ Editor::start_selection_op (ArdourCanvas::Item* item, GdkEvent* event, Selection
break;
case SelectionStartTrim:
clicked_trackview->order_selection_trims (item, true);
if (clicked_trackview) {
clicked_trackview->order_selection_trims (item, true);
}
start_grab (event, trimmer_cursor);
start = selection->time[clicked_selection].start;
drag_info.pointer_frame_offset = drag_info.grab_frame - start;
break;
case SelectionEndTrim:
clicked_trackview->order_selection_trims (item, false);
if (clicked_trackview) {
clicked_trackview->order_selection_trims (item, false);
}
start_grab (event, trimmer_cursor);
end = selection->time[clicked_selection].end;
drag_info.pointer_frame_offset = drag_info.grab_frame - end;
@ -4239,7 +4283,6 @@ Editor::hide_marker (ArdourCanvas::Item* item, GdkEvent* event)
void
Editor::start_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event, RangeMarkerOp op)
{
if (session == 0) {
return;
}
@ -4304,7 +4347,7 @@ Editor::drag_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event)
}
/* first drag: Either add to the selection
or create a new selection->
or create a new selection.
*/
if (drag_info.first_move) {
@ -4371,12 +4414,39 @@ Editor::end_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event)
break;
}
} else {
/* just a click, no pointer movement.*/
/* just a click, no pointer movement. remember that context menu stuff was handled elsewhere */
if (Keyboard::no_modifier_keys_pressed (&event->button)) {
// nothing yet
jack_nframes_t start;
jack_nframes_t end;
start = session->locations()->first_mark_before (drag_info.grab_frame);
end = session->locations()->first_mark_after (drag_info.grab_frame);
if (end == max_frames) {
end = session->current_end_frame ();
}
if (start == 0) {
start = session->current_start_frame ();
}
switch (mouse_mode) {
case MouseObject:
/* find the two markers on either side and then make the selection from it */
cerr << "select between " << start << " .. " << end << endl;
select_all_within (start, end, 0.0f, FLT_MAX, Selection::Set);
break;
case MouseRange:
/* find the two markers on either side of the click and make the range out of it */
selection->set (0, start, end);
break;
default:
break;
}
}
}

View File

@ -36,7 +36,7 @@ bool GTK_ARDOUR::just_version = false;
bool GTK_ARDOUR::use_vst = true;
bool GTK_ARDOUR::new_session = false;
char* GTK_ARDOUR::curvetest_file = 0;
bool GTK_ARDOUR::try_hw_optimization = false;
bool GTK_ARDOUR::try_hw_optimization = true;
using namespace GTK_ARDOUR;

View File

@ -199,18 +199,29 @@ Selection::toggle (AudioRegionView* r)
{
AudioRegionSelection::iterator i;
cerr << "about to toggle a regionview\n";
if ((i = find (audio_regions.begin(), audio_regions.end(), r)) == audio_regions.end()) {
audio_regions.add (r);
cerr << "\tadded\n";
} else {
audio_regions.erase (i);
cerr << "\tremoved\n";
}
RegionsChanged ();
cerr << "done\n";
}
void
Selection::toggle (vector<AudioRegionView*>& r)
{
AudioRegionSelection::iterator i;
for (vector<AudioRegionView*>::iterator x = r.begin(); x != r.end(); ++x) {
if ((i = find (audio_regions.begin(), audio_regions.end(), (*x))) == audio_regions.end()) {
audio_regions.add ((*x));
} else {
audio_regions.erase (i);
}
}
RegionsChanged ();
}
long
@ -633,8 +644,6 @@ Selection::add (list<Selectable*>& selectables)
if (!autos.empty()) {
add (autos);
}
cerr << "Selection @ " << this << " has " << points.size() << " points\n";
}
void

View File

@ -75,10 +75,11 @@ class AudioRegion : public Region
AudioRegion (SourceList &, const XMLNode&);
~AudioRegion();
bool region_list_equivalent (const AudioRegion&);
bool source_equivalent (const AudioRegion&);
bool equivalent (const AudioRegion&);
bool size_equivalent (const AudioRegion&);
bool region_list_equivalent (const AudioRegion&) const ;
bool source_equivalent (const AudioRegion&) const;
bool equivalent (const AudioRegion&) const;
bool size_equivalent (const AudioRegion&) const;
bool overlap_equivalent (const AudioRegion&) const;
bool speed_mismatch (float) const;

View File

@ -42,12 +42,13 @@ CONFIG_VARIABLE(HeaderFormat, native_file_header_format, "native-file-header-fo
CONFIG_VARIABLE(bool, use_tranzport, "use-tranzport", false)
CONFIG_VARIABLE(uint32_t, osc_port, "osc-port", 3819)
CONFIG_VARIABLE(bool, use_osc, "use-osc", true)
CONFIG_VARIABLE(bool, use_overlap_equivalency, "use-overlap-equivalency", true)
CONFIG_VARIABLE(bool, meter_falloff_off, "meter-falloff-off", false)
CONFIG_VARIABLE(bool, meter_falloff_slowest, "meter-falloff-slowest", false)
CONFIG_VARIABLE(bool, meter_falloff_slower, "meter-falloff-slower", false)
CONFIG_VARIABLE(bool, meter_falloff_slow, "meter-falloff-slow", false)
CONFIG_VARIABLE(bool, meter_falloff_medium, "meter-falloff-medium", false)
CONFIG_VARIABLE(bool, meter_falloff_fast, "meter-falloff-fast", false)
CONFIG_VARIABLE(bool, meter_falloff_fast, "meter-falloff-fast", true)
CONFIG_VARIABLE(bool, meter_falloff_faster, "meter-falloff-faster", false)
CONFIG_VARIABLE(bool, meter_falloff_fastest, "meter-falloff-fastest", false)
CONFIG_VARIABLE(bool, meter_hold_off, "meter-hold-off", false)

View File

@ -159,6 +159,9 @@ class Locations : public Stateful, public StateManager
Location *first_location_before (jack_nframes_t);
Location *first_location_after (jack_nframes_t);
jack_nframes_t first_mark_before (jack_nframes_t);
jack_nframes_t first_mark_after (jack_nframes_t);
sigc::signal<void,Location*> current_changed;
sigc::signal<void> changed;
sigc::signal<void,Location*> added;

View File

@ -886,8 +886,14 @@ AudioPlaylist::get_equivalent_regions (const AudioRegion& other, vector<AudioReg
AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
if (ar && ar->equivalent (other)) {
results.push_back (ar);
if (ar) {
if (Config->get_use_overlap_equivalency()) {
if (ar->overlap_equivalent (other)) {
results.push_back (ar);
} else if (ar->equivalent (other)) {
results.push_back (ar);
}
}
}
}
}

View File

@ -1139,15 +1139,15 @@ AudioRegion::master_source_names ()
}
bool
AudioRegion::region_list_equivalent (const AudioRegion& other)
AudioRegion::region_list_equivalent (const AudioRegion& other) const
{
return size_equivalent (other) && source_equivalent (other) && _name == other._name;
}
bool
AudioRegion::source_equivalent (const AudioRegion& other)
AudioRegion::source_equivalent (const AudioRegion& other) const
{
SourceList::iterator i;
SourceList::const_iterator i;
SourceList::const_iterator io;
for (i = sources.begin(), io = other.sources.begin(); i != sources.end() && io != other.sources.end(); ++i, ++io) {
@ -1166,7 +1166,13 @@ AudioRegion::source_equivalent (const AudioRegion& other)
}
bool
AudioRegion::equivalent (const AudioRegion& other)
AudioRegion::overlap_equivalent (const AudioRegion& other) const
{
return coverage (other.first_frame(), other.last_frame()) != OverlapNone;
}
bool
AudioRegion::equivalent (const AudioRegion& other) const
{
return _start == other._start &&
_position == other._position &&
@ -1174,7 +1180,7 @@ AudioRegion::equivalent (const AudioRegion& other)
}
bool
AudioRegion::size_equivalent (const AudioRegion& other)
AudioRegion::size_equivalent (const AudioRegion& other) const
{
return _start == other._start &&
_length == other._length;

View File

@ -656,6 +656,80 @@ Locations::first_location_after (jack_nframes_t frame)
return 0;
}
jack_nframes_t
Locations::first_mark_before (jack_nframes_t frame)
{
LocationList locs;
{
LockMonitor lm (lock, __LINE__, __FILE__);
locs = locations;
}
LocationStartLaterComparison cmp;
locs.sort (cmp);
/* locs is now sorted latest..earliest */
for (LocationList::iterator i = locs.begin(); i != locs.end(); ++i) {
if (!(*i)->is_hidden()) {
if ((*i)->is_mark()) {
/* MARK: start == end */
if ((*i)->start() < frame) {
return (*i)->start();
}
} else {
/* RANGE: start != end, compare start and end */
if ((*i)->end() < frame) {
return (*i)->end();
}
if ((*i)->start () < frame) {
return (*i)->start();
}
}
}
}
return 0;
}
jack_nframes_t
Locations::first_mark_after (jack_nframes_t frame)
{
LocationList locs;
{
LockMonitor lm (lock, __LINE__, __FILE__);
locs = locations;
}
LocationStartEarlierComparison cmp;
locs.sort (cmp);
/* locs is now sorted earliest..latest */
for (LocationList::iterator i = locs.begin(); i != locs.end(); ++i) {
if (!(*i)->is_hidden()) {
if ((*i)->is_mark()) {
/* MARK, start == end so just compare start */
if ((*i)->start() > frame) {
return (*i)->start();
}
} else {
/* RANGE, start != end, compare start and end */
if ((*i)->start() > frame ) {
return (*i)->start ();
}
if ((*i)->end() > frame) {
return (*i)->end ();
}
}
}
}
return max_frames;
}
Location*
Locations::end_location () const
{

View File

@ -175,10 +175,13 @@ tokenize_fullpath (string fullpath, string& path, string& name)
}
int
touch_file(string path)
touch_file (string path)
{
FILE* file = fopen(path.c_str(), "a");
fclose(file);
int fd = open (path.c_str(), O_RDONLY|O_CREAT);
if (fd >= 0) {
close (fd);
return 0;
}
return 1;
}

View File

@ -60,7 +60,7 @@ if env['NLS']:
env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libpbd3))
env.Alias('tarball', env.Distribute (env['DISTTREE'],
[ 'SConscript', 'i18n.h' ] +
[ 'SConscript', 'i18n.h', 'gettext.h', 'pbd/abstract_ui.cc' ] +
pbd3_files +
glob.glob('po/*.po') +
glob.glob('pbd/*.h')))

View File

@ -77,6 +77,7 @@ UndoCommand::clear ()
void
UndoCommand::undo ()
{
cerr << "Undo " << _name << endl;
for (list<UndoAction>::reverse_iterator i = undo_actions.rbegin(); i != undo_actions.rend(); ++i) {
(*i)();
}
@ -85,6 +86,7 @@ UndoCommand::undo ()
void
UndoCommand::redo ()
{
cerr << "Redo " << _name << endl;
for (list<UndoAction>::iterator i = redo_actions.begin(); i != redo_actions.end(); ++i) {
(*i)();
}

View File

@ -49,6 +49,6 @@ if env['NLS']:
env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libardour_cp))
env.Alias('tarball', env.Distribute (env['DISTTREE'],
[ 'SConscript', 'i18n.h', 'gettext.h' ] +
[ 'SConscript' ] +
cp_files +
glob.glob('po/*.po') + glob.glob('*.h')))

View File

@ -50,6 +50,6 @@ if env['NLS']:
env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2/surfaces'), libardour_genericmidi))
env.Alias('tarball', env.Distribute (env['DISTTREE'],
[ 'SConscript', 'i18n.h', 'gettext.h' ] +
[ 'SConscript' ] +
genericmidi_files +
glob.glob('po/*.po') + glob.glob('*.h')))

View File

@ -50,6 +50,6 @@ if env['NLS']:
env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2/surfaces'), libardour_tranzport))
env.Alias('tarball', env.Distribute (env['DISTTREE'],
[ 'SConscript', 'i18n.h', 'gettext.h' ] +
[ 'SConscript' ] +
tranzport_files +
glob.glob('po/*.po') + glob.glob('*.h')))