summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ardour.rc.in4
-rw-r--r--gtk2_ardour/audio_clock.cc2
-rw-r--r--gtk2_ardour/editor.cc15
-rw-r--r--gtk2_ardour/editor.h4
-rw-r--r--gtk2_ardour/editor_mouse.cc142
-rw-r--r--gtk2_ardour/editor_rulers.cc13
-rw-r--r--gtk2_ardour/evtest.cc91
-rw-r--r--libs/ardour/ardour/playlist.h3
-rw-r--r--libs/ardour/playlist.cc136
-rwxr-xr-xtools/osx_packaging/osx_build3
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