diff options
-rw-r--r-- | ardour.rc.in | 4 | ||||
-rw-r--r-- | gtk2_ardour/audio_clock.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/editor.cc | 15 | ||||
-rw-r--r-- | gtk2_ardour/editor.h | 4 | ||||
-rw-r--r-- | gtk2_ardour/editor_mouse.cc | 142 | ||||
-rw-r--r-- | gtk2_ardour/editor_rulers.cc | 13 | ||||
-rw-r--r-- | gtk2_ardour/evtest.cc | 91 | ||||
-rw-r--r-- | libs/ardour/ardour/playlist.h | 3 | ||||
-rw-r--r-- | libs/ardour/playlist.cc | 136 | ||||
-rwxr-xr-x | tools/osx_packaging/osx_build | 3 |
10 files changed, 365 insertions, 48 deletions
diff --git a/ardour.rc.in b/ardour.rc.in index fbec4ef748..b5675cfd90 100644 --- a/ardour.rc.in +++ b/ardour.rc.in @@ -36,9 +36,11 @@ <Option name="destructive-xfade-msecs" value="20"/> <Option name="periodic-safety-backups" value="1"/> <Option name="periodic-safety-backup-interval" value="120"/> - <Option name="show-track-meters" value="1"/> + <Option name="show-track-meters" value="1"/> + <Option name="smpte-format" value="6"/> </Config> <extra> + <RulerVisibility smpte="yes" bbt="yes" frames="no" minsec="no" tempo="yes" meter="yes" marker="yes" rangemarker="no" transportmarker="yes" cdmarker="no"/> <Keyboard edit-button="3" edit-modifier="4" delete-button="3" delete-modifier="1" snap-modifier="32"/> </extra> </Ardour> diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc index c3133f38c1..3a8ccd4d2c 100644 --- a/gtk2_ardour/audio_clock.cc +++ b/gtk2_ardour/audio_clock.cc @@ -1880,7 +1880,7 @@ AudioClock::build_ops_menu () ops_items.push_back (MenuElem (_("Timecode"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE))); ops_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT))); ops_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec))); - ops_items.push_back (MenuElem (_("Audio Frames"), bind (mem_fun(*this, &AudioClock::set_mode), Frames))); + ops_items.push_back (MenuElem (_("Samples"), bind (mem_fun(*this, &AudioClock::set_mode), Frames))); ops_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off))); } diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 5dfcff248e..8c5c2cc4c9 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -246,14 +246,6 @@ Editor::Editor () zoom_focus_strings = I18N (_zoom_focus_strings); edit_point_strings = I18N (_edit_point_strings); - snap_type = SnapToBeat; - set_snap_to (snap_type); - snap_mode = SnapOff; - set_snap_mode (snap_mode); - - _edit_point = EditAtMouse; - set_edit_point_preference (_edit_point); - snap_threshold = 5.0; bbt_beat_subdivision = 4; canvas_width = 0; @@ -379,6 +371,13 @@ Editor::Editor () build_cursors (); setup_toolbar (); + snap_type = SnapToBeat; + set_snap_to (snap_type); + snap_mode = SnapOff; + set_snap_mode (snap_mode); + _edit_point = EditAtMouse; + set_edit_point_preference (_edit_point); + edit_point_clock.ValueChanged.connect (mem_fun(*this, &Editor::edit_point_clock_changed)); time_canvas_vbox.pack_start (*_ruler_separator, false, false); diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index e25e365497..c434bc1de8 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -1169,6 +1169,10 @@ class Editor : public PublicEditor RegionSelection pre_drag_region_selection; void region_drag_motion_callback (ArdourCanvas::Item*, GdkEvent*); void region_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*); + bool check_region_drag_possible (AudioTimeAxisView**); + void possibly_copy_regions_during_grab (GdkEvent*); + void region_drag_splice_motion_callback (ArdourCanvas::Item*, GdkEvent*); + void region_drag_splice_finished_callback (ArdourCanvas::Item*, GdkEvent*); bool _dragging_playhead; bool _dragging_edit_point; diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index c3d4cd2c94..14eb8ceff3 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -2869,8 +2869,14 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event) drag_info.copy = false; drag_info.item = item; drag_info.data = clicked_regionview; - drag_info.motion_callback = &Editor::region_drag_motion_callback; - drag_info.finished_callback = &Editor::region_drag_finished_callback; + + if (Config->get_edit_mode() == Splice) { + drag_info.motion_callback = &Editor::region_drag_splice_motion_callback; + drag_info.finished_callback = &Editor::region_drag_splice_finished_callback; + } else { + drag_info.motion_callback = &Editor::region_drag_motion_callback; + drag_info.finished_callback = &Editor::region_drag_finished_callback; + } start_grab (event); @@ -2927,7 +2933,7 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event) void Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event) { - if (selection->regions.empty() || clicked_regionview == 0) { + if (selection->regions.empty() || clicked_regionview == 0 || Config->get_edit_mode() == Splice) { return; } @@ -2958,24 +2964,8 @@ Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event) } void -Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) +Editor::possibly_copy_regions_during_grab (GdkEvent* event) { - double x_delta; - double y_delta = 0; - RegionView* rv = reinterpret_cast<RegionView*> (drag_info.data); - nframes_t pending_region_position = 0; - int32_t pointer_y_span = 0, canvas_pointer_y_span = 0, original_pointer_order; - int32_t visible_y_high = 0, visible_y_low = 512; //high meaning higher numbered.. not the height on the screen - bool clamp_y_axis = false; - vector<int32_t> height_list(512) ; - vector<int32_t>::iterator j; - - if (Config->get_edit_mode() == Splice && drag_info.first_move && drag_info.move_threshold_passed && pre_drag_region_selection.empty()) { - pre_drag_region_selection = selection->regions; - RegionSelection all_after = get_regions_after (clicked_regionview->region()->position(), selection->tracks); - selection->set (all_after); - } - if (drag_info.copy && drag_info.move_threshold_passed && drag_info.want_move_threshold) { drag_info.want_move_threshold = false; // don't copy again @@ -3017,24 +3007,123 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) swap_grab (new_regionviews.front()->get_canvas_group (), 0, event->motion.time); } +} +bool +Editor::check_region_drag_possible (AudioTimeAxisView** tv) +{ /* Which trackview is this ? */ TimeAxisView* tvp = trackview_by_y_position (drag_info.current_pointer_y); - AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp); + (*tv) = dynamic_cast<AudioTimeAxisView*>(tvp); /* The region motion is only processed if the pointer is over an audio track. */ - if (!tv || !tv->is_audio_track()) { + if (!(*tv) || !(*tv)->is_audio_track()) { /* To make sure we hide the verbose canvas cursor when the mouse is not held over and audiotrack. */ hide_verbose_canvas_cursor (); - return; + return false; } + return true; +} + +struct RegionSelectionByPosition { + bool operator() (RegionView*a, RegionView* b) { + return a->region()->position () < b->region()->position(); + } +}; + +void +Editor::region_drag_splice_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) +{ + AudioTimeAxisView* tv; + + if (!check_region_drag_possible (&tv)) { + return; + } + + if (!drag_info.move_threshold_passed) { + return; + } + + int dir; + + if (drag_info.current_pointer_x - drag_info.grab_x > 0) { + dir = 1; + } else { + dir = -1; + } + + RegionSelection copy (selection->regions); + + RegionSelectionByPosition cmp; + copy.sort (cmp); + + for (RegionSelection::iterator i = copy.begin(); i != copy.end(); ++i) { + + AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&(*i)->get_time_axis_view()); + + if (!atv) { + continue; + } + + boost::shared_ptr<Playlist> playlist; + + if ((playlist = atv->playlist()) == 0) { + continue; + } + + if (!playlist->region_is_shuffle_constrained ((*i)->region())) { + continue; + } + + if (dir > 0) { + if (drag_info.current_pointer_frame < (*i)->region()->last_frame() + 1) { + continue; + } + } else { + if (drag_info.current_pointer_frame > (*i)->region()->first_frame()) { + continue; + } + } + + + playlist->shuffle ((*i)->region(), dir); + + drag_info.grab_x = drag_info.current_pointer_x; + } +} + +void +Editor::region_drag_splice_finished_callback (ArdourCanvas::Item* item, GdkEvent* event) +{ +} + +void +Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) +{ + double x_delta; + double y_delta = 0; + RegionView* rv = reinterpret_cast<RegionView*> (drag_info.data); + nframes_t pending_region_position = 0; + int32_t pointer_y_span = 0, canvas_pointer_y_span = 0, original_pointer_order; + int32_t visible_y_high = 0, visible_y_low = 512; //high meaning higher numbered.. not the height on the screen + bool clamp_y_axis = false; + vector<int32_t> height_list(512) ; + vector<int32_t>::iterator j; + AudioTimeAxisView* tv; + + possibly_copy_regions_during_grab (event); + + if (!check_region_drag_possible (&tv)) { + return; + } + original_pointer_order = drag_info.last_trackview->order; /************************************************************ @@ -3049,13 +3138,6 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) if ((pointer_y_span = (drag_info.last_trackview->order - tv->order)) != 0) { - /* drop any splice-induced selection madness */ - - if (!pre_drag_region_selection.empty()) { - selection->set (pre_drag_region_selection); - pre_drag_region_selection.clear (); - } - int32_t children = 0, numtracks = 0; // XXX hard coding track limit, oh my, so very very bad bitset <1024> tracks (0x00); diff --git a/gtk2_ardour/editor_rulers.cc b/gtk2_ardour/editor_rulers.cc index 16f10334ca..149116193a 100644 --- a/gtk2_ardour/editor_rulers.cc +++ b/gtk2_ardour/editor_rulers.cc @@ -91,7 +91,11 @@ Editor::initialize_rulers () ruler_shown[ruler_time_marker] = true; ruler_shown[ruler_time_range_marker] = true; ruler_shown[ruler_time_transport_marker] = true; - ruler_shown[ruler_time_cd_marker] = true; + if (Profile->get_sae()) { + ruler_shown[ruler_time_cd_marker] = false; + } else { + ruler_shown[ruler_time_cd_marker] = true; + } ruler_shown[ruler_metric_frames] = false; ruler_shown[ruler_metric_minsec] = false; @@ -551,8 +555,10 @@ Editor::restore_ruler_visibility () ruler_shown[ruler_time_cd_marker] = true; else ruler_shown[ruler_time_cd_marker] = false; - } - else { + + cerr << "cd marker ruler set to " << ruler_shown[ruler_time_cd_marker] << endl; + + } else { // this session doesn't yet know about the cdmarker ruler // as a benefit to the user who doesn't know the feature exists, show the ruler if // any cd marks exist @@ -564,6 +570,7 @@ Editor::restore_ruler_visibility () break; } } + cerr << "cd marker ruler default to " << ruler_shown[ruler_time_cd_marker] << endl; } } diff --git a/gtk2_ardour/evtest.cc b/gtk2_ardour/evtest.cc new file mode 100644 index 0000000000..db8d502e70 --- /dev/null +++ b/gtk2_ardour/evtest.cc @@ -0,0 +1,91 @@ +#include <gtkmm.h> +#include <iostream> + +using namespace std; + +bool +print_event (GdkEvent* event) +{ + cerr << hex; + cerr << "Event: type = " << event->type << ' '; + + switch (event->type) { + case GDK_BUTTON_PRESS: + cerr << "Button press, button = " + << event->button.button + << " state " + << event->button.state + << endl; + break; + + case GDK_BUTTON_RELEASE: + cerr << "Button release, button = " + << event->button.button + << " state " + << event->button.state + << endl; + break; + + case GDK_SCROLL: + cerr << "Scroll: direction = " + << event->scroll.direction + << " state = " + << event->scroll.state + << endl; + break; + + case GDK_KEY_PRESS: + cerr << "Key press, keycode = " + << event->key.keyval + << " name " + << gdk_keyval_name (event->key.keyval) + << " state = " + << event->key.state + << " hw keycode = " + << event->key.hardware_keycode + << " string = " + << (event->key.string ? event->key.string : "not defined") + << endl; + break; + + case GDK_KEY_RELEASE: + cerr << "Key release, keycode = " + << event->key.keyval + << " name " + << gdk_keyval_name (event->key.keyval) + << " state = " + << event->key.state + << " hw keycode = " + << event->key.hardware_keycode + << " string = " + << (event->key.string ? event->key.string : "not defined") + << endl; + break; + + default: + cerr << endl; + break; + } + cerr << dec; + + return false; +} + +int +main (int argc, char* argv[]) +{ + Gtk::Main app (&argc, &argv); + Gtk::Window window; + Gtk::EventBox eventbox; + + window.add (eventbox); + window.set_size_request (250, 250); + + eventbox.signal_event().connect (sigc::ptr_fun (print_event)); + eventbox.add_events (Gdk::SCROLL_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK); + eventbox.set_flags (Gtk::CAN_FOCUS); + + eventbox.show (); + window.show (); + app.run(); +} diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index 1161afbd9d..402e02109a 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -92,6 +92,7 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f void partition (nframes_t start, nframes_t end, bool just_top_level); void duplicate (boost::shared_ptr<Region>, nframes_t position, float times); void nudge_after (nframes_t start, nframes_t distance, bool forwards); + void shuffle (boost::shared_ptr<Region>, int dir); boost::shared_ptr<Playlist> cut (list<AudioRange>&, bool result_is_hidden = true); boost::shared_ptr<Playlist> copy (list<AudioRange>&, bool result_is_hidden = true); @@ -104,6 +105,7 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f boost::shared_ptr<Region> top_region_at (nframes_t frame); boost::shared_ptr<Region> find_next_region (nframes_t frame, RegionPoint point, int dir); nframes64_t find_next_region_boundary (nframes64_t frame, int dir); + bool region_is_shuffle_constrained (boost::shared_ptr<Region>); template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>, void *), void *arg); template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>)); @@ -187,6 +189,7 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f bool first_set_state; bool _hidden; bool _splicing; + bool _shuffling; bool _nudging; uint32_t _refcnt; EditMode _edit_mode; diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index 344136d2cc..f495e00510 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -228,6 +228,7 @@ Playlist::init (bool hide) _refcnt = 0; _hidden = hide; _splicing = false; + _shuffling = false; _nudging = false; in_set_state = 0; _edit_mode = Config->get_edit_mode(); @@ -1120,7 +1121,7 @@ Playlist::core_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Reg void Playlist::region_bounds_changed (Change what_changed, boost::shared_ptr<Region> region) { - if (in_set_state || _splicing || _nudging) { + if (in_set_state || _splicing || _nudging || _shuffling) { return; } @@ -1478,6 +1479,7 @@ Playlist::find_next_region_boundary (nframes64_t frame, int dir) boost::shared_ptr<Region> r = (*i); nframes64_t distance; + nframes64_t end = r->position() + r->length(); bool reset; reset = false; @@ -1493,12 +1495,12 @@ Playlist::find_next_region_boundary (nframes64_t frame, int dir) } } - if (r->last_frame() > frame) { + if (end > frame) { - distance = r->last_frame() - frame; + distance = end - frame; if (distance < closest) { - ret = r->last_frame(); + ret = end; closest = distance; reset = true; } @@ -2081,3 +2083,129 @@ Playlist::timestamp_layer_op (boost::shared_ptr<Region> region) region->set_last_layer_op (++layer_op_counter); } + +void +Playlist::shuffle (boost::shared_ptr<Region> region, int dir) +{ + bool moved = false; + nframes_t new_pos; + + if (region->locked()) { + return; + } + + _shuffling = true; + + { + RegionLock rlock (const_cast<Playlist*> (this)); + + + if (dir > 0) { + + RegionList::iterator next; + + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + if ((*i) == region) { + next = i; + ++next; + + if (next != regions.end()) { + + if ((*next)->locked()) { + break; + } + + if ((*next)->position() != region->last_frame() + 1) { + /* they didn't used to touch, so after shuffle, + just have them swap positions. + */ + new_pos = (*next)->position(); + } else { + /* they used to touch, so after shuffle, + make sure they still do. put the earlier + region where the later one will end after + it is moved. + */ + new_pos = region->position() + (*next)->length(); + } + + (*next)->set_position (region->position(), this); + region->set_position (new_pos, this); + + /* avoid a full sort */ + + regions.erase (i); // removes the region from the list */ + next++; + regions.insert (next, region); // adds it back after next + + moved = true; + } + break; + } + } + } else { + + RegionList::iterator prev = regions.end(); + + for (RegionList::iterator i = regions.begin(); i != regions.end(); prev = i, ++i) { + if ((*i) == region) { + + if (prev != regions.end()) { + + if ((*prev)->locked()) { + break; + } + + if (region->position() != (*prev)->last_frame() + 1) { + /* they didn't used to touch, so after shuffle, + just have them swap positions. + */ + new_pos = region->position(); + } else { + /* they used to touch, so after shuffle, + make sure they still do. put the earlier + one where the later one will end after + */ + new_pos = (*prev)->position() + region->length(); + } + + region->set_position ((*prev)->position(), this); + (*prev)->set_position (new_pos, this); + + /* avoid a full sort */ + + regions.erase (i); // remove region + regions.insert (prev, region); // insert region before prev + + moved = true; + } + + break; + } + } + } + } + + _shuffling = false; + + if (moved) { + + relayer (); + check_dependents (region, false); + + notify_modified(); + } + +} + +bool +Playlist::region_is_shuffle_constrained (boost::shared_ptr<Region>) +{ + RegionLock rlock (const_cast<Playlist*> (this)); + + if (regions.size() > 1) { + return true; + } + + return false; +} diff --git a/tools/osx_packaging/osx_build b/tools/osx_packaging/osx_build index cb4141de16..346050031c 100755 --- a/tools/osx_packaging/osx_build +++ b/tools/osx_packaging/osx_build @@ -91,6 +91,7 @@ if test x$WITH_JACK != x ; then cp /usr/local/lib/jack/jack_coreaudio.so $Frameworks cp /usr/local/bin/jackd $APPROOT/MacOS fi +cp ../../gtk2_ardour/evtest $APPROOT/MacOS/gtkevents cp -R $GTKQUARTZ_ROOT/etc/* $Etc echo "Copying all Pango modules ..." @@ -180,7 +181,7 @@ done # now fix up the executables echo "Fixing up executable dependency names ..." -executables=Ardour2 +executables="Ardour2 gtkevents" if test x$WITH_JACK != x ; then executables="$executables jackd" fi |