chris goddard's region list patch; port 2.X marker drag/move changes to 3.0; compilation fixes-post-evoral

git-svn-id: svn://localhost/ardour2/branches/3.0@3760 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2008-09-19 14:38:46 +00:00
parent 60f588f21d
commit 6f8cd63450
33 changed files with 758 additions and 188 deletions

View file

@ -224,7 +224,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
// We do not have jack linked in yet so; // We do not have jack linked in yet so;
last_shuttle_request = last_peak_grab = 0; // get_microseconds(); last_shuttle_request = last_peak_grab = 0; // get_microseconds();
ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler)); ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler)); ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
@ -933,15 +933,11 @@ ARDOUR_UI::update_disk_space()
nframes_t frames = session->available_capture_duration(); nframes_t frames = session->available_capture_duration();
char buf[64]; char buf[64];
nframes_t fr = session->frame_rate();
if (frames == max_frames) { if (frames == max_frames) {
strcpy (buf, _("Disk: 24hrs+")); strcpy (buf, _("Disk: 24hrs+"));
} else { } else {
int hrs;
int mins;
int secs;
nframes_t fr = session->frame_rate();
rec_enabled_streams = 0; rec_enabled_streams = 0;
session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams); session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
@ -949,16 +945,29 @@ ARDOUR_UI::update_disk_space()
frames /= rec_enabled_streams; frames /= rec_enabled_streams;
} }
int hrs;
int mins;
int secs;
hrs = frames / (fr * 3600); hrs = frames / (fr * 3600);
frames -= hrs * fr * 3600; frames -= hrs * fr * 3600;
mins = frames / (fr * 60); mins = frames / (fr * 60);
frames -= mins * fr * 60; frames -= mins * fr * 60;
secs = frames / fr; secs = frames / fr;
snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs); snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
} }
disk_space_label.set_text (buf); disk_space_label.set_text (buf);
// An attempt to make the disk space label flash red when space has run out.
if (frames < fr * 60 * 5) {
/* disk_space_box.style ("disk_space_label_empty"); */
} else {
/* disk_space_box.style ("disk_space_label"); */
}
} }
gint gint

View file

@ -1994,6 +1994,7 @@ AudioClock::set_mode (Mode m)
if (!is_transient) { if (!is_transient) {
ModeChanged (); /* EMIT SIGNAL */ ModeChanged (); /* EMIT SIGNAL */
mode_changed (); /* EMIT SIGNAL */
} }
} }

View file

@ -61,11 +61,12 @@ class AudioClock : public Gtk::HBox
void set_session (ARDOUR::Session *s); void set_session (ARDOUR::Session *s);
sigc::signal<void> ValueChanged; sigc::signal<void> ValueChanged;
sigc::signal<void> mode_changed;
sigc::signal<void> ChangeAborted; sigc::signal<void> ChangeAborted;
static sigc::signal<void> ModeChanged; static sigc::signal<void> ModeChanged;
static std::vector<AudioClock*> clocks; static std::vector<AudioClock*> clocks;
static bool has_focus() { return _has_focus; } static bool has_focus() { return _has_focus; }
private: private:

View file

@ -20,6 +20,8 @@
#ifndef __gtk2_ardour_drag_info_h_ #ifndef __gtk2_ardour_drag_info_h_
#define __gtk2_ardour_drag_info_h_ #define __gtk2_ardour_drag_info_h_
#include <list>
#include <gdk/gdk.h> #include <gdk/gdk.h>
#include <stdint.h> #include <stdint.h>
@ -64,7 +66,9 @@ struct DragInfo {
bool move_threshold_passed; bool move_threshold_passed;
bool want_move_threshold; bool want_move_threshold;
bool brushing; bool brushing;
ARDOUR::Location* copied_location; std::list<ARDOUR::Location*> copied_locations;
void clear_copied_locations ();
}; };
struct LineDragInfo { struct LineDragInfo {

View file

@ -195,6 +195,15 @@ show_me_the_size (Requisition* r, const char* what)
cerr << "size of " << what << " = " << r->width << " x " << r->height << endl; cerr << "size of " << what << " = " << r->width << " x " << r->height << endl;
} }
void
DragInfo::clear_copied_locations ()
{
for (list<Location*>::iterator i = copied_locations.begin(); i != copied_locations.end(); ++i) {
delete *i;
}
copied_locations.clear ();
}
Editor::Editor () Editor::Editor ()
: :
/* time display buttons */ /* time display buttons */
@ -263,7 +272,6 @@ Editor::Editor ()
clicked_control_point = 0; clicked_control_point = 0;
last_update_frame = 0; last_update_frame = 0;
drag_info.item = 0; drag_info.item = 0;
drag_info.copied_location = 0;
current_mixer_strip = 0; current_mixer_strip = 0;
current_bbt_points = 0; current_bbt_points = 0;
@ -641,7 +649,12 @@ Editor::Editor ()
region_list_display.set_model (region_list_model); region_list_display.set_model (region_list_model);
region_list_display.append_column (_("Regions"), region_list_columns.name); region_list_display.append_column (_("Regions"), region_list_columns.name);
region_list_display.set_headers_visible (false); region_list_display.append_column (_("Start"), region_list_columns.start);
region_list_display.append_column (_("End"), region_list_columns.end);
region_list_display.append_column (_("Length"), region_list_columns.length);
region_list_display.append_column (_("Used"), region_list_columns.used);
region_list_display.append_column (_("Path to parent file"), region_list_columns.path);
region_list_display.set_headers_visible (true);
CellRendererText* region_name_cell = dynamic_cast<CellRendererText*>(region_list_display.get_column_cell_renderer (0)); CellRendererText* region_name_cell = dynamic_cast<CellRendererText*>(region_list_display.get_column_cell_renderer (0));
region_name_cell->property_editable() = true; region_name_cell->property_editable() = true;
@ -656,7 +669,7 @@ Editor::Editor ()
region_list_display.get_selection()->set_mode (SELECTION_MULTIPLE); region_list_display.get_selection()->set_mode (SELECTION_MULTIPLE);
region_list_display.add_object_drag (region_list_columns.region.index(), "regions"); region_list_display.add_object_drag (region_list_columns.region.index(), "regions");
/* setup DnD handling */ /* setup DnD handling */
list<TargetEntry> region_list_target_table; list<TargetEntry> region_list_target_table;
@ -669,8 +682,8 @@ Editor::Editor ()
region_list_display.signal_drag_data_received().connect (mem_fun(*this, &Editor::region_list_display_drag_data_received)); region_list_display.signal_drag_data_received().connect (mem_fun(*this, &Editor::region_list_display_drag_data_received));
region_list_scroller.add (region_list_display); region_list_scroller.add (region_list_display);
region_list_scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC); region_list_scroller.set_policy (POLICY_AUTOMATIC, POLICY_AUTOMATIC);
region_list_display.signal_key_press_event().connect (mem_fun(*this, &Editor::region_list_display_key_press)); region_list_display.signal_key_press_event().connect (mem_fun(*this, &Editor::region_list_display_key_press));
region_list_display.signal_key_release_event().connect (mem_fun(*this, &Editor::region_list_display_key_release)); region_list_display.signal_key_release_event().connect (mem_fun(*this, &Editor::region_list_display_key_release));
region_list_display.signal_button_press_event().connect (mem_fun(*this, &Editor::region_list_display_button_press), false); region_list_display.signal_button_press_event().connect (mem_fun(*this, &Editor::region_list_display_button_press), false);
@ -678,6 +691,9 @@ Editor::Editor ()
region_list_display.get_selection()->signal_changed().connect (mem_fun(*this, &Editor::region_list_selection_changed)); region_list_display.get_selection()->signal_changed().connect (mem_fun(*this, &Editor::region_list_selection_changed));
// region_list_display.signal_popup_menu().connect (bind (mem_fun (*this, &Editor::show_region_list_display_context_menu), 1, 0)); // region_list_display.signal_popup_menu().connect (bind (mem_fun (*this, &Editor::show_region_list_display_context_menu), 1, 0));
ARDOUR_UI::instance()->secondary_clock.mode_changed.connect (mem_fun(*this, &Editor::redisplay_regions));
ARDOUR::Region::RegionPropertyChanged.connect (mem_fun(*this, &Editor::update_region_row));
named_selection_scroller.add (named_selection_display); named_selection_scroller.add (named_selection_display);
named_selection_scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC); named_selection_scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC);

View file

@ -128,7 +128,7 @@ class Editor : public PublicEditor
public: public:
Editor (); Editor ();
~Editor (); ~Editor ();
void connect_to_session (ARDOUR::Session *); void connect_to_session (ARDOUR::Session *);
ARDOUR::Session* current_session() const { return session; } ARDOUR::Session* current_session() const { return session; }
void first_idle (); void first_idle ();
@ -545,6 +545,8 @@ class Editor : public PublicEditor
void set_selected_track (TimeAxisView&, Selection::Operation op = Selection::Set, bool no_remove=false); void set_selected_track (TimeAxisView&, Selection::Operation op = Selection::Set, bool no_remove=false);
void select_all_tracks (); void select_all_tracks ();
int get_regionview_count_from_region_list (boost::shared_ptr<ARDOUR::Region> region);
bool set_selected_control_point_from_click (Selection::Operation op = Selection::Set, bool no_remove=false); bool set_selected_control_point_from_click (Selection::Operation op = Selection::Set, bool no_remove=false);
void set_selected_track_from_click (bool press, Selection::Operation op = Selection::Set, bool no_remove=false); void set_selected_track_from_click (bool press, Selection::Operation op = Selection::Set, bool no_remove=false);
void set_selected_track_as_side_effect (bool force = false); void set_selected_track_as_side_effect (bool force = false);
@ -926,13 +928,23 @@ class Editor : public PublicEditor
struct RegionListDisplayModelColumns : public Gtk::TreeModel::ColumnRecord { struct RegionListDisplayModelColumns : public Gtk::TreeModel::ColumnRecord {
RegionListDisplayModelColumns() { RegionListDisplayModelColumns() {
add (name); add (name);
add (region); add (region);
add (color_); add (color_);
add (start);
add (end);
add (length);
add (used);
add (path);
} }
Gtk::TreeModelColumn<Glib::ustring> name; Gtk::TreeModelColumn<Glib::ustring> name;
Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Region> > region; Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Region> > region;
Gtk::TreeModelColumn<Gdk::Color> color_; Gtk::TreeModelColumn<Gdk::Color> color_;
Gtk::TreeModelColumn<Glib::ustring> start;
Gtk::TreeModelColumn<Glib::ustring> end;
Gtk::TreeModelColumn<Glib::ustring> length;
Gtk::TreeModelColumn<Glib::ustring> used;
Gtk::TreeModelColumn<Glib::ustring> path;
}; };
RegionListDisplayModelColumns region_list_columns; RegionListDisplayModelColumns region_list_columns;
@ -1080,6 +1092,7 @@ class Editor : public PublicEditor
void add_regions_to_region_display (std::vector<boost::weak_ptr<ARDOUR::Region> > & ); void add_regions_to_region_display (std::vector<boost::weak_ptr<ARDOUR::Region> > & );
void region_hidden (boost::shared_ptr<ARDOUR::Region>); void region_hidden (boost::shared_ptr<ARDOUR::Region>);
void redisplay_regions (); void redisplay_regions ();
void update_region_row (boost::shared_ptr<ARDOUR::Region>);
bool no_region_list_redisplay; bool no_region_list_redisplay;
void insert_into_tmp_regionlist(boost::shared_ptr<ARDOUR::Region>); void insert_into_tmp_regionlist(boost::shared_ptr<ARDOUR::Region>);

View file

@ -207,6 +207,7 @@ Editor::initialize_canvas ()
range_bar_drag_rect = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, 100, timebar_height); range_bar_drag_rect = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, 100, timebar_height);
range_bar_drag_rect->property_outline_pixels() = 0; range_bar_drag_rect->property_outline_pixels() = 0;
range_bar_drag_rect->hide ();
transport_bar_drag_rect = new ArdourCanvas::SimpleRect (*transport_marker_group, 0.0, 0.0, 100, timebar_height); transport_bar_drag_rect = new ArdourCanvas::SimpleRect (*transport_marker_group, 0.0, 0.0, 100, timebar_height);
transport_bar_drag_rect->property_outline_pixels() = 0; transport_bar_drag_rect->property_outline_pixels() = 0;

View file

@ -1879,11 +1879,7 @@ Editor::finalize_drag ()
drag_info.last_pointer_frame = 0; drag_info.last_pointer_frame = 0;
drag_info.current_pointer_frame = 0; drag_info.current_pointer_frame = 0;
drag_info.brushing = false; drag_info.brushing = false;
drag_info.clear_copied_locations ();
if (drag_info.copied_location) {
delete drag_info.copied_location;
drag_info.copied_location = 0;
}
} }
void void
@ -1928,7 +1924,7 @@ Editor::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
drag_info.want_move_threshold = false; drag_info.want_move_threshold = false;
drag_info.pointer_frame_offset = 0; drag_info.pointer_frame_offset = 0;
drag_info.brushing = false; drag_info.brushing = false;
drag_info.copied_location = 0; drag_info.clear_copied_locations ();
drag_info.original_x = 0; drag_info.original_x = 0;
drag_info.original_y = 0; drag_info.original_y = 0;
@ -2320,6 +2316,7 @@ Editor::update_marker_drag_item (Location *location)
} }
} }
void void
Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event) Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event)
{ {
@ -2343,7 +2340,6 @@ Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event)
_dragging_edit_point = true; _dragging_edit_point = true;
drag_info.copied_location = new Location (*location);
drag_info.pointer_frame_offset = drag_info.grab_frame - (is_start ? location->start() : location->end()); drag_info.pointer_frame_offset = drag_info.grab_frame - (is_start ? location->start() : location->end());
update_marker_drag_item (location); update_marker_drag_item (location);
@ -2369,28 +2365,67 @@ Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event)
selection->toggle (marker); selection->toggle (marker);
break; break;
case Selection::Set: case Selection::Set:
selection->set (marker); if (!selection->selected (marker)) {
selection->set (marker);
}
break; break;
case Selection::Extend: case Selection::Extend:
selection->add (marker); {
Locations::LocationList ll;
list<Marker*> to_add;
nframes64_t s, e;
selection->markers.range (s, e);
s = min (marker->position(), s);
e = max (marker->position(), e);
s = min (s, e);
e = max (s, e);
if (e < max_frames) {
++e;
}
session->locations()->find_all_between (s, e, ll, Location::Flags (0));
for (Locations::LocationList::iterator i = ll.begin(); i != ll.end(); ++i) {
LocationMarkers* lm = find_location_markers (*i);
if (lm) {
if (lm->start) {
to_add.push_back (lm->start);
}
if (lm->end) {
to_add.push_back (lm->end);
}
}
}
if (!to_add.empty()) {
selection->add (to_add);
}
break; break;
}
case Selection::Add: case Selection::Add:
selection->add (marker); selection->add (marker);
break; break;
} }
/* set up copies for us to manipulate during the drag */
drag_info.clear_copied_locations ();
for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
Location *l = find_location_from_marker (*i, is_start);
drag_info.copied_locations.push_back (new Location (*l));
}
} }
void void
Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
{ {
nframes64_t f_delta; nframes64_t f_delta;
Marker* marker = (Marker *) drag_info.data; nframes64_t newframe;
Location *real_location;
Location *copy_location;
bool is_start; bool is_start;
bool move_both = false; bool move_both = false;
Marker* dragged_marker = (Marker*) drag_info.data;
Marker* marker;
Location *real_location;
Location *copy_location;
nframes64_t newframe;
if (drag_info.pointer_frame_offset <= drag_info.current_pointer_frame) { if (drag_info.pointer_frame_offset <= drag_info.current_pointer_frame) {
newframe = drag_info.current_pointer_frame - drag_info.pointer_frame_offset; newframe = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
} else { } else {
@ -2407,102 +2442,196 @@ Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
return; return;
} }
/* call this to find out if its the start or end */
if ((real_location = find_location_from_marker (marker, is_start)) == 0) {
return;
}
if (real_location->locked()) {
return;
}
/* use the copy that we're "dragging" around */
copy_location = drag_info.copied_location;
f_delta = copy_location->end() - copy_location->start();
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
move_both = true; move_both = true;
} }
if (copy_location->is_mark()) { MarkerSelection::iterator i;
/* just move it */ list<Location*>::iterator x;
copy_location->set_start (newframe); /* find the marker we're dragging, and compute the delta */
} else { for (i = selection->markers.begin(), x = drag_info.copied_locations.begin();
x != drag_info.copied_locations.end() && i != selection->markers.end();
++i, ++x) {
if (is_start) { // start-of-range marker copy_location = *x;
marker = *i;
if (move_both) {
copy_location->set_start (newframe); if (marker == dragged_marker) {
copy_location->set_end (newframe + f_delta);
} else if (newframe < copy_location->end()) { if ((real_location = find_location_from_marker (marker, is_start)) == 0) {
copy_location->set_start (newframe); /* que pasa ?? */
} else { return;
snap_to (next, 1, true);
copy_location->set_end (next);
copy_location->set_start (newframe);
} }
if (real_location->is_mark()) {
f_delta = newframe - copy_location->start();
} else {
switch (marker->type()) {
case Marker::Start:
case Marker::LoopStart:
case Marker::PunchIn:
f_delta = newframe - copy_location->start();
break;
case Marker::End:
case Marker::LoopEnd:
case Marker::PunchOut:
f_delta = newframe - copy_location->end();
break;
default:
/* what kind of marker is this ? */
return;
}
}
break;
}
}
if (i == selection->markers.end()) {
/* hmm, impossible - we didn't find the dragged marker */
return;
}
/* now move them all */
for (i = selection->markers.begin(), x = drag_info.copied_locations.begin();
x != drag_info.copied_locations.end() && i != selection->markers.end();
++i, ++x) {
copy_location = *x;
marker = *i;
/* call this to find out if its the start or end */
if ((real_location = find_location_from_marker (marker, is_start)) == 0) {
continue;
}
if (real_location->locked()) {
continue;
}
if (copy_location->is_mark()) {
/* just move it */
} else { // end marker copy_location->set_start (copy_location->start() + f_delta);
} else {
if (move_both) { nframes64_t new_start = copy_location->start() + f_delta;
copy_location->set_end (newframe); nframes64_t new_end = copy_location->end() + f_delta;
copy_location->set_start (newframe - f_delta);
} else if (newframe > copy_location->start()) { if (is_start) { // start-of-range marker
copy_location->set_end (newframe);
} else if (newframe > 0) { if (move_both) {
snap_to (next, -1, true); copy_location->set_start (new_start);
copy_location->set_start (next); copy_location->set_end (new_end);
copy_location->set_end (newframe); } else if (new_start < copy_location->end()) {
copy_location->set_start (new_start);
} else {
snap_to (next, 1, true);
copy_location->set_end (next);
copy_location->set_start (newframe);
}
} else { // end marker
if (move_both) {
copy_location->set_end (new_end);
copy_location->set_start (new_start);
} else if (new_end > copy_location->start()) {
copy_location->set_end (new_end);
} else if (newframe > 0) {
snap_to (next, -1, true);
copy_location->set_start (next);
copy_location->set_end (newframe);
}
} }
} }
update_marker_drag_item (copy_location);
LocationMarkers* lm = find_location_markers (real_location);
if (lm) {
lm->set_position (copy_location->start(), copy_location->end());
}
} }
drag_info.last_pointer_frame = drag_info.current_pointer_frame; drag_info.last_pointer_frame = drag_info.current_pointer_frame;
drag_info.first_move = false; drag_info.first_move = false;
update_marker_drag_item (copy_location); if (drag_info.copied_locations.empty()) {
abort();
LocationMarkers* lm = find_location_markers (real_location); }
lm->set_position (copy_location->start(), copy_location->end());
edit_point_clock.set (copy_location->start());
edit_point_clock.set (drag_info.copied_locations.front()->start());
show_verbose_time_cursor (newframe, 10); show_verbose_time_cursor (newframe, 10);
#ifdef GTKOSX
track_canvas->update_now ();
#endif
} }
void void
Editor::marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event) Editor::marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
{ {
if (drag_info.first_move) { if (drag_info.first_move) {
/* just a click, do nothing but whatever selection occured */
/* just a click, do nothing but finish
off the selection process
*/
Selection::Operation op = Keyboard::selection_type (event->button.state);
Marker* marker = (Marker *) drag_info.data;
switch (op) {
case Selection::Set:
if (selection->selected (marker) && selection->markers.size() > 1) {
selection->set (marker);
}
break;
case Selection::Toggle:
case Selection::Extend:
case Selection::Add:
break;
}
return; return;
} }
_dragging_edit_point = false; _dragging_edit_point = false;
Marker* marker = (Marker *) drag_info.data;
bool is_start;
begin_reversible_command ( _("move marker") ); begin_reversible_command ( _("move marker") );
XMLNode &before = session->locations()->get_state(); XMLNode &before = session->locations()->get_state();
MarkerSelection::iterator i;
list<Location*>::iterator x;
bool is_start;
for (i = selection->markers.begin(), x = drag_info.copied_locations.begin();
x != drag_info.copied_locations.end() && i != selection->markers.end();
++i, ++x) {
Location * location = find_location_from_marker (marker, is_start); Location * location = find_location_from_marker ((*i), is_start);
if (location) { if (location) {
if (location->locked()) { if (location->locked()) {
return; return;
} }
if (location->is_mark()) { if (location->is_mark()) {
location->set_start (drag_info.copied_location->start()); location->set_start ((*x)->start());
} else { } else {
location->set (drag_info.copied_location->start(), drag_info.copied_location->end()); location->set ((*x)->start(), (*x)->end());
}
} }
} }
@ -3696,6 +3825,12 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
/* for evaluation of the track position of iy1, we have to adjust /* for evaluation of the track position of iy1, we have to adjust
to allow for the vertical scrolling adjustment and the height of the timebars. to allow for the vertical scrolling adjustment and the height of the timebars.
*/ */
cerr << "adjust y from " << iy1 << " using "
<< vertical_adjustment.get_value() << " - "
<< canvas_timebars_vsize
<< endl;
iy1 += vertical_adjustment.get_value() - canvas_timebars_vsize; iy1 += vertical_adjustment.get_value() - canvas_timebars_vsize;
TimeAxisView* tvp2 = trackview_by_y_position (iy1); TimeAxisView* tvp2 = trackview_by_y_position (iy1);

View file

@ -426,40 +426,45 @@ Editor::nudge_forward (bool next, bool force_playhead)
} else if (!force_playhead && !selection->markers.empty()) { } else if (!force_playhead && !selection->markers.empty()) {
bool is_start; bool is_start;
Location* loc = find_location_from_marker (selection->markers.front(), is_start);
if (loc) { begin_reversible_command (_("nudge location forward"));
begin_reversible_command (_("nudge location forward")); for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
XMLNode& before (loc->get_state()); Location* loc = find_location_from_marker ((*i), is_start);
if (is_start) { if (loc) {
distance = get_nudge_distance (loc->start(), next_distance);
if (next) { XMLNode& before (loc->get_state());
distance = next_distance;
} if (is_start) {
if (max_frames - distance > loc->start() + loc->length()) { distance = get_nudge_distance (loc->start(), next_distance);
loc->set_start (loc->start() + 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 { } else {
loc->set_start (max_frames - loc->length()); distance = get_nudge_distance (loc->end(), next_distance);
} if (next) {
} else { distance = next_distance;
distance = get_nudge_distance (loc->end(), next_distance); }
if (next) { if (max_frames - distance > loc->end()) {
distance = next_distance; loc->set_end (loc->end() + distance);
} } else {
if (max_frames - distance > loc->end()) { loc->set_end (max_frames);
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 { } else {
distance = get_nudge_distance (playhead_cursor->current_frame, next_distance); distance = get_nudge_distance (playhead_cursor->current_frame, next_distance);
session->request_locate (playhead_cursor->current_frame + distance); session->request_locate (playhead_cursor->current_frame + distance);
@ -506,41 +511,48 @@ Editor::nudge_backward (bool next, bool force_playhead)
} else if (!force_playhead && !selection->markers.empty()) { } else if (!force_playhead && !selection->markers.empty()) {
bool is_start; bool is_start;
Location* loc = find_location_from_marker (selection->markers.front(), is_start);
if (loc) { begin_reversible_command (_("nudge location forward"));
begin_reversible_command (_("nudge location forward")); for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
XMLNode& before (loc->get_state());
if (is_start) { Location* loc = find_location_from_marker ((*i), is_start);
distance = get_nudge_distance (loc->start(), next_distance);
if (next) { if (loc) {
distance = next_distance;
} XMLNode& before (loc->get_state());
if (distance < loc->start()) {
loc->set_start (loc->start() - distance); 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 { } else {
loc->set_start (0); distance = get_nudge_distance (loc->end(), next_distance);
}
} else { if (next) {
distance = get_nudge_distance (loc->end(), next_distance); distance = next_distance;
}
if (next) {
distance = next_distance; if (distance < loc->end() - loc->length()) {
} loc->set_end (loc->end() - distance);
} else {
if (distance < loc->end() - loc->length()) { loc->set_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 { } else {
distance = get_nudge_distance (playhead_cursor->current_frame, next_distance); distance = get_nudge_distance (playhead_cursor->current_frame, next_distance);

View file

@ -30,6 +30,7 @@
#include <ardour/silentfilesource.h> #include <ardour/silentfilesource.h>
#include <ardour/session_region.h> #include <ardour/session_region.h>
#include <gtkmm2ext/stop_signal.h> #include <gtkmm2ext/stop_signal.h>
#include "editor.h" #include "editor.h"
@ -41,6 +42,7 @@
#include "region_view.h" #include "region_view.h"
#include "utils.h" #include "utils.h"
#include "i18n.h" #include "i18n.h"
using namespace sigc; using namespace sigc;
@ -89,10 +91,18 @@ void
Editor::add_region_to_region_display (boost::shared_ptr<Region> region) Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
{ {
string str; string str;
char start_str[16];
char end_str[16];
char length_str[16];
char used_str[8];
int used;
TreeModel::Row row; TreeModel::Row row;
Gdk::Color c; Gdk::Color c;
bool missing_source; bool missing_source;
BBT_Time bbt; // FIXME Why do these have to be declared here ?
SMPTE::Time smpte; // FIXME I would like them declared in the case statment where they are used.
missing_source = boost::dynamic_pointer_cast<SilentFileSource>(region->source()); missing_source = boost::dynamic_pointer_cast<SilentFileSource>(region->source());
if (!show_automatic_regions_in_region_list && region->automatic()) { if (!show_automatic_regions_in_region_list && region->automatic()) {
@ -100,12 +110,10 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
} }
if (region->hidden()) { if (region->hidden()) {
TreeModel::iterator iter = region_list_model->get_iter ("0"); TreeModel::iterator iter = region_list_model->get_iter ("0");
TreeModel::Row parent; TreeModel::Row parent;
TreeModel::Row child; TreeModel::Row child;
if (!iter) { if (!iter) {
parent = *(region_list_model->append()); parent = *(region_list_model->append());
@ -113,21 +121,16 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
parent[region_list_columns.name] = _("Hidden"); parent[region_list_columns.name] = _("Hidden");
boost::shared_ptr<Region> proxy = parent[region_list_columns.region]; boost::shared_ptr<Region> proxy = parent[region_list_columns.region];
proxy.reset (); proxy.reset ();
} else { } else {
if ((*iter)[region_list_columns.name] != _("Hidden")) { if ((*iter)[region_list_columns.name] != _("Hidden")) {
parent = *(region_list_model->insert(iter)); parent = *(region_list_model->insert(iter));
parent[region_list_columns.name] = _("Hidden"); parent[region_list_columns.name] = _("Hidden");
boost::shared_ptr<Region> proxy = parent[region_list_columns.region]; boost::shared_ptr<Region> proxy = parent[region_list_columns.region];
proxy.reset (); proxy.reset ();
} else { } else {
parent = *iter; parent = *iter;
} }
} }
row = *(region_list_model->append (parent.children())); row = *(region_list_model->append (parent.children()));
@ -149,17 +152,16 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
row = *(region_list_model->append()); row = *(region_list_model->append());
if (missing_source) { if (missing_source) {
c.set_rgb(65535,0,0); // FIXME: error color from style c.set_rgb(65535,0,0); // FIXME: error color from style
} else if (region->automatic()){
c.set_rgb(0,65535,0); // FIXME: error color from style
} else { } else {
set_color(c, rgba_from_style ("RegionListWholeFile", 0xff, 0, 0, 0, "fg", Gtk::STATE_NORMAL, false )); set_color(c, rgba_from_style ("RegionListWholeFile", 0xff, 0, 0, 0, "fg", Gtk::STATE_NORMAL, false ));
} }
row[region_list_columns.color_] = c; row[region_list_columns.color_] = c;
if (region->source()->name()[0] == '/') { // external file if (region->source()->name()[0] == '/') { // external file
if (region->whole_file()) { if (region->whole_file()) {
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(region->source()); boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(region->source());
str = ".../"; str = ".../";
if (afs) { if (afs) {
@ -173,9 +175,7 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
} }
} else { } else {
str = region->name(); str = region->name();
} }
if (region->n_channels() > 1) { if (region->n_channels() > 1) {
@ -186,14 +186,16 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
str += ']'; str += ']';
} }
if (missing_source) { //if (missing_source) {
str += _(" (MISSING)"); // str += _(" (MISSING)");
} //}
row[region_list_columns.name] = str; row[region_list_columns.name] = str;
row[region_list_columns.region] = region; row[region_list_columns.region] = region;
return; if (region->automatic()) {
return;
}
} else { } else {
@ -204,7 +206,6 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
bool found_parent = false; bool found_parent = false;
for (i = rows.begin(); i != rows.end(); ++i) { for (i = rows.begin(); i != rows.end(); ++i) {
boost::shared_ptr<Region> rr = (*i)[region_list_columns.region]; boost::shared_ptr<Region> rr = (*i)[region_list_columns.region];
boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion>(rr); boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion>(rr);
@ -228,21 +229,101 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
} }
} }
} }
if (!found_parent) { if (!found_parent) {
row = *(region_list_model->append()); row = *(region_list_model->append());
} }
}
used = get_regionview_count_from_region_list(region);
sprintf (used_str, "%4d" , used);
switch (ARDOUR_UI::instance()->secondary_clock.mode ()) {
case AudioClock::SMPTE:
case AudioClock::Off: /* If the secondary clock is off, default to SMPTE */
session->smpte_time (region->position(), smpte);
sprintf (start_str, "%02d:%02d:%02d:%02d", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
session->smpte_time (region->position() + region->length() - 1, smpte);
sprintf (end_str, "%02d:%02d:%02d:%02d", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
session->smpte_time (region->length(), smpte);
sprintf (length_str, "%02d:%02d:%02d:%02d", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
break;
case AudioClock::BBT:
session->tempo_map().bbt_time (region->position(), bbt);
sprintf (start_str, "%03d|%02d|%04d" , bbt.bars, bbt.beats, bbt.ticks);
session->tempo_map().bbt_time (region->position() + region->length() - 1, bbt);
sprintf (end_str, "%03d|%02d|%04d" , bbt.bars, bbt.beats, bbt.ticks);
session->tempo_map().bbt_time (region->length(), bbt);
sprintf (length_str, "%03d|%02d|%04d" , bbt.bars, bbt.beats, bbt.ticks);
break;
case AudioClock::MinSec:
nframes_t left;
int hrs;
int mins;
float secs;
left = region->position();
hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
mins = (int) floor (left / (session->frame_rate() * 60.0f));
left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
secs = left / (float) session->frame_rate();
sprintf (start_str, "%02d:%02d:%06.3f", hrs, mins, secs);
left = region->position() + region->length() - 1;
hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
mins = (int) floor (left / (session->frame_rate() * 60.0f));
left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
secs = left / (float) session->frame_rate();
sprintf (end_str, "%02d:%02d:%06.3f", hrs, mins, secs);
left = region->length();
hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
mins = (int) floor (left / (session->frame_rate() * 60.0f));
left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
secs = left / (float) session->frame_rate();
sprintf (length_str, "%02d:%02d:%06.3f", hrs, mins, secs);
break;
case AudioClock::Frames:
snprintf (start_str, sizeof (start_str), "%u", region->position());
snprintf (end_str, sizeof (end_str), "%u", (region->position() + region->length() - 1));
snprintf (length_str, sizeof (length_str), "%u", region->length());
break;
default:
break;
} }
row[region_list_columns.region] = region; row[region_list_columns.region] = region;
if (used > 1) {
row[region_list_columns.start] = "Multiple";
row[region_list_columns.end] = "Multiple";
} else {
row[region_list_columns.start] = start_str;
row[region_list_columns.end] = end_str;
}
row[region_list_columns.length] = length_str;
row[region_list_columns.used] = used_str;
if (missing_source) {
row[region_list_columns.path] = _("(MISSING) ") + region->source()->name();
} else {
row[region_list_columns.path] = region->source()->name();
}
if (region->n_channels() > 1) { if (region->n_channels() > 1) {
row[region_list_columns.name] = string_compose("%1 [%2]", region->name(), region->n_channels()); row[region_list_columns.name] = string_compose("%1 [%2]", region->name(), region->n_channels());
} else { } else {
row[region_list_columns.name] = region->name(); row[region_list_columns.name] = region->name();
} }
} }
@ -356,6 +437,180 @@ Editor::redisplay_regions ()
} }
} }
void
Editor::update_region_row (boost::shared_ptr<Region> region)
{
if (!region || !session) {
return;
}
char start_str[16];
char end_str[16];
char length_str[16];
char used_str[8];
int used;
bool missing_source;
bool matched_region = false;
BBT_Time bbt;
SMPTE::Time smpte;
missing_source = boost::dynamic_pointer_cast<SilentFileSource>(region->source());
TreeModel::iterator found_region;
if (show_automatic_regions_in_region_list) {
TreeModel::iterator i;
TreeModel::iterator ii;
TreeModel::Children rows = region_list_model->children();
for (i = rows.begin(); i != rows.end(); ++i) {
cerr << "Parent " << (*i)[region_list_columns.name] << "\n";
TreeModel::Children subrows = (*i).children();
for (ii = subrows.begin(); ii != subrows.end(); ++ii) {
cerr << "Compare " << region->name() << " with child " << (*ii)[region_list_columns.name] << "\n";
boost::shared_ptr<Region> compared_region = (*ii)[region_list_columns.region];
if (region == compared_region) {
cerr << "Matched\n";
matched_region = true;
found_region = ii;
break;
}
}
if (matched_region) {
break;
}
}
} else {
TreeModel::iterator i;
TreeModel::Children rows = region_list_model->children();
for (i = rows.begin(); i != rows.end(); ++i) {
cerr << "Compare " << region->name() << " with " << (*i)[region_list_columns.name] << "\n";
boost::shared_ptr<Region> compared_region = (*i)[region_list_columns.region];
if (region == compared_region) {
cerr << "Matched\n";
matched_region = true;
found_region = i;
break;
}
}
}
if (!matched_region) {
cerr << "Returning - No match\n\n";
return;
}
used = get_regionview_count_from_region_list(region);
sprintf (used_str, "%4d" , used);
switch (ARDOUR_UI::instance()->secondary_clock.mode ()) {
case AudioClock::SMPTE:
case AudioClock::Off: // If the secondary clock is off, default to SMPTE
session->smpte_time (region->position(), smpte);
sprintf (start_str, "%02d:%02d:%02d:%02d", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
session->smpte_time (region->position() + region->length() - 1, smpte);
sprintf (end_str, "%02d:%02d:%02d:%02d", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
session->smpte_time (region->length(), smpte);
sprintf (length_str, "%02d:%02d:%02d:%02d", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
break;
case AudioClock::BBT:
session->tempo_map().bbt_time (region->position(), bbt);
sprintf (start_str, "%03d|%02d|%04d" , bbt.bars, bbt.beats, bbt.ticks);
session->tempo_map().bbt_time (region->position() + region->length() - 1, bbt);
sprintf (end_str, "%03d|%02d|%04d" , bbt.bars, bbt.beats, bbt.ticks);
session->tempo_map().bbt_time (region->length(), bbt);
sprintf (length_str, "%03d|%02d|%04d" , bbt.bars, bbt.beats, bbt.ticks);
break;
case AudioClock::MinSec:
nframes_t left;
int hrs;
int mins;
float secs;
left = region->position();
hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
mins = (int) floor (left / (session->frame_rate() * 60.0f));
left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
secs = left / (float) session->frame_rate();
sprintf (start_str, "%02d:%02d:%06.3f", hrs, mins, secs);
left = region->position() + region->length() - 1;
hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
mins = (int) floor (left / (session->frame_rate() * 60.0f));
left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
secs = left / (float) session->frame_rate();
sprintf (end_str, "%02d:%02d:%06.3f", hrs, mins, secs);
left = region->length();
hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
mins = (int) floor (left / (session->frame_rate() * 60.0f));
left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
secs = left / (float) session->frame_rate();
sprintf (length_str, "%02d:%02d:%06.3f", hrs, mins, secs);
break;
case AudioClock::Frames:
snprintf (start_str, sizeof (start_str), "%u", region->position());
snprintf (end_str, sizeof (end_str), "%u", (region->position() + region->length() - 1));
snprintf (length_str, sizeof (length_str), "%u", region->length());
break;
default:
break;
}
cerr << "Updating " << (*found_region)[region_list_columns.name] << "\n";
if (used > 1) {
(*found_region)[region_list_columns.start] = "Multiple";
(*found_region)[region_list_columns.end] = "Multiple";
} else {
(*found_region)[region_list_columns.start] = start_str;
(*found_region)[region_list_columns.end] = end_str;
}
(*found_region)[region_list_columns.length] = length_str;
(*found_region)[region_list_columns.used] = used_str;
if (missing_source) {
(*found_region)[region_list_columns.path] = _("(MISSING) ") + region->source()->name();
} else {
(*found_region)[region_list_columns.path] = region->source()->name();
}
if (region->n_channels() > 1) {
(*found_region)[region_list_columns.name] = string_compose("%1 [%2]", region->name(), region->n_channels());
} else {
(*found_region)[region_list_columns.name] = region->name();
}
cerr << "Returning after updating\n\n";
//return;
}
void void
Editor::build_region_list_menu () Editor::build_region_list_menu ()
{ {

View file

@ -362,6 +362,44 @@ Editor::get_equivalent_regions (RegionView* basis, vector<RegionView*>& equivale
equivalent_regions.push_back (basis); equivalent_regions.push_back (basis);
} }
int
Editor::get_regionview_count_from_region_list (boost::shared_ptr<Region> region)
{
int region_count = 0;
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
RouteTimeAxisView* tatv;
if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
boost::shared_ptr<Playlist> pl;
vector<boost::shared_ptr<Region> > results;
RegionView* marv;
boost::shared_ptr<Diskstream> ds;
if ((ds = tatv->get_diskstream()) == 0) {
/* bus */
continue;
}
if ((pl = (ds->playlist())) != 0) {
pl->get_region_list_equivalent_regions (region, results);
}
for (vector<boost::shared_ptr<Region> >::iterator ir = results.begin(); ir != results.end(); ++ir) {
if ((marv = tatv->view()->find_view (*ir)) != 0) {
region_count++;
}
}
}
}
return region_count;
}
bool bool
Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, bool no_track_remove) Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, bool no_track_remove)
{ {

View file

@ -26,6 +26,7 @@
struct MarkerSelection : public std::list<Marker*> struct MarkerSelection : public std::list<Marker*>
{ {
void range (nframes64_t& start, nframes64_t& end);
}; };
#endif /* __ardour_gtk_marker_selection_h__ */ #endif /* __ardour_gtk_marker_selection_h__ */

View file

@ -608,6 +608,12 @@ Selection::set (boost::shared_ptr<Evoral::ControlList> ac)
add (ac); add (ac);
} }
bool
Selection::selected (Marker* m)
{
return find (markers.begin(), markers.end(), m) != markers.end();
}
bool bool
Selection::selected (TimeAxisView* tv) Selection::selected (TimeAxisView* tv)
{ {
@ -801,3 +807,31 @@ Selection::add (Marker* m)
MarkersChanged(); MarkersChanged();
} }
} }
void
Selection::add (const list<Marker*>& m)
{
markers.insert (markers.end(), m.begin(), m.end());
MarkersChanged ();
}
void
MarkerSelection::range (nframes64_t& s, nframes64_t& e)
{
s = max_frames;
e = 0;
for (MarkerSelection::iterator i = begin(); i != end(); ++i) {
if ((*i)->position() < s) {
s = (*i)->position();
}
if ((*i)->position() > e) {
e = (*i)->position();
}
}
s = std::min (s, e);
e = std::max (s, e);
}

View file

@ -99,6 +99,7 @@ class Selection : public sigc::trackable
bool selected (TimeAxisView*); bool selected (TimeAxisView*);
bool selected (RegionView*); bool selected (RegionView*);
bool selected (Marker*);
void set (std::list<Selectable*>&); void set (std::list<Selectable*>&);
void add (std::list<Selectable*>&); void add (std::list<Selectable*>&);
@ -136,6 +137,7 @@ class Selection : public sigc::trackable
void add (boost::shared_ptr<ARDOUR::Playlist>); void add (boost::shared_ptr<ARDOUR::Playlist>);
void add (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&); void add (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
void add (Marker*); void add (Marker*);
void add (const std::list<Marker*>&);
void add (const RegionSelection&); void add (const RegionSelection&);
void remove (TimeAxisView*); void remove (TimeAxisView*);

View file

@ -1181,10 +1181,14 @@ TimeAxisView::color_handler ()
TimeAxisView* TimeAxisView*
TimeAxisView::covers_y_position (double y) TimeAxisView::covers_y_position (double y)
{ {
if (y_position < 0) {
abort ();
}
if (hidden()) { if (hidden()) {
return 0; return 0;
} }
cerr << name() << " check for " << y << " within " << y_position << " and + " << height << endl; cerr << name() << " check for " << y << " within " << y_position << " and + " << height << endl;
if (y_position <= y && y < (y_position + height)) { if (y_position <= y && y < (y_position + height)) {

View file

@ -43,7 +43,7 @@ public:
boost::shared_ptr<ARDOUR::AutomationList>, boost::shared_ptr<ARDOUR::AutomationList>,
std::string name="unnamed controllable"); std::string name="unnamed controllable");
boost::shared_ptr<AutomationList> alist() { return boost::dynamic_pointer_cast<AutomationList>(_list); } boost::shared_ptr<AutomationList> alist() const { return boost::dynamic_pointer_cast<AutomationList>(_list); }
void set_list(boost::shared_ptr<Evoral::ControlList>); void set_list(boost::shared_ptr<Evoral::ControlList>);
@ -55,7 +55,7 @@ public:
return ((ARDOUR::AutomationList*)_list.get())->automation_write(); return ((ARDOUR::AutomationList*)_list.get())->automation_write();
} }
inline AutoState automation_state() { inline AutoState automation_state() const {
return ((ARDOUR::AutomationList*)_list.get())->automation_state(); return ((ARDOUR::AutomationList*)_list.get())->automation_state();
} }

View file

@ -100,14 +100,15 @@ class Location : public PBD::StatefulDestructible
void set_is_end (bool yn, void* src); void set_is_end (bool yn, void* src);
void set_is_start (bool yn, void* src); void set_is_start (bool yn, void* src);
bool is_auto_punch () { return _flags & IsAutoPunch; } bool is_auto_punch () const { return _flags & IsAutoPunch; }
bool is_auto_loop () { return _flags & IsAutoLoop; } bool is_auto_loop () const { return _flags & IsAutoLoop; }
bool is_mark () { return _flags & IsMark; } bool is_mark () const { return _flags & IsMark; }
bool is_hidden () { return _flags & IsHidden; } bool is_hidden () const { return _flags & IsHidden; }
bool is_cd_marker () { return _flags & IsCDMarker; } bool is_cd_marker () const { return _flags & IsCDMarker; }
bool is_end() { return _flags & IsEnd; } bool is_end() const { return _flags & IsEnd; }
bool is_start() { return _flags & IsStart; } bool is_start() const { return _flags & IsStart; }
bool is_range_marker() { return _flags & IsRangeMarker; } bool is_range_marker() const { return _flags & IsRangeMarker; }
bool matches (Flags f) const { return _flags & f; }
sigc::signal<void,Location*> name_changed; sigc::signal<void,Location*> name_changed;
sigc::signal<void,Location*> end_changed; sigc::signal<void,Location*> end_changed;
@ -175,6 +176,8 @@ class Locations : public PBD::StatefulDestructible
nframes_t first_mark_before (nframes_t, bool include_special_ranges = false); nframes_t first_mark_before (nframes_t, bool include_special_ranges = false);
nframes_t first_mark_after (nframes_t, bool include_special_ranges = false); nframes_t first_mark_after (nframes_t, bool include_special_ranges = false);
void find_all_between (nframes64_t start, nframes64_t, LocationList&, Location::Flags);
sigc::signal<void,Location*> current_changed; sigc::signal<void,Location*> current_changed;
sigc::signal<void> changed; sigc::signal<void> changed;
sigc::signal<void,Location*> added; sigc::signal<void,Location*> added;

View file

@ -90,6 +90,7 @@ class Region : public Automatable, public boost::enable_shared_from_this<Region>
static Change HiddenChanged; static Change HiddenChanged;
sigc::signal<void,Change> StateChanged; sigc::signal<void,Change> StateChanged;
static sigc::signal<void,boost::shared_ptr<ARDOUR::Region> > RegionPropertyChanged;
virtual ~Region(); virtual ~Region();

View file

@ -10,6 +10,8 @@
#include <ardour/readable.h> #include <ardour/readable.h>
#include <ardour/readable.h> #include <ardour/readable.h>
#include <cstring>
#include "i18n.h" #include "i18n.h"
using namespace std; using namespace std;

View file

@ -924,3 +924,16 @@ Locations::get_location_by_id(PBD::ID id)
return 0; return 0;
} }
void
Locations::find_all_between (nframes64_t start, nframes64_t end, LocationList& ll, Location::Flags flags)
{
Glib::Mutex::Lock lm (lock);
for (LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) {
if ((flags == 0 || (*i)->matches (flags)) &&
((*i)->start() >= start && (*i)->end() < end)) {
ll.push_back (*i);
}
}
}

View file

@ -53,6 +53,7 @@ Change Region::LockChanged = ARDOUR::new_change ();
Change Region::LayerChanged = ARDOUR::new_change (); Change Region::LayerChanged = ARDOUR::new_change ();
Change Region::HiddenChanged = ARDOUR::new_change (); Change Region::HiddenChanged = ARDOUR::new_change ();
sigc::signal<void,boost::shared_ptr<ARDOUR::Region> > Region::RegionPropertyChanged;
/* derived-from-derived constructor (no sources in constructor) */ /* derived-from-derived constructor (no sources in constructor) */
Region::Region (Session& s, nframes_t start, nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags) Region::Region (Session& s, nframes_t start, nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags)
@ -1350,6 +1351,21 @@ Region::send_change (Change what_changed)
} }
StateChanged (what_changed); StateChanged (what_changed);
if (!(_flags & DoNotSaveState)) {
/* Try and send a shared_pointer unless this is part of the constructor.
If so, do nothing.
*/
try {
boost::shared_ptr<Region> rptr = shared_from_this();
RegionPropertyChanged (rptr);
} catch (...) {
/* no shared_ptr available, relax; */
}
}
} }
void void

View file

@ -24,7 +24,6 @@
#include <cstring> #include <cstring>
#include <cmath> #include <cmath>
#include <cctype> #include <cctype>
#include <string>
#include <cstring> #include <cstring>
#include <cerrno> #include <cerrno>
#include <iostream> #include <iostream>

View file

@ -8,6 +8,8 @@ Import('env libraries install_prefix')
evoral = env.Clone() evoral = env.Clone()
evoral.Merge([ evoral.Merge([
libraries['glib2'],
libraries['sigc2'],
libraries['glibmm2'], libraries['glibmm2'],
libraries['xml'], libraries['xml'],
libraries['pbd'], libraries['pbd'],

View file

@ -47,9 +47,9 @@ struct ControlEvent {
} }
} }
~ControlEvent() { if (coeff) delete[] coeff; } ~ControlEvent() { if (coeff) delete[] coeff; }
void create_coeffs() { void create_coeffs() {
if (!coeff) if (!coeff)
coeff = new double[4]; coeff = new double[4];
@ -85,7 +85,7 @@ public:
ControlList (const Parameter& id); ControlList (const Parameter& id);
//ControlList (const XMLNode&, Parameter id); //ControlList (const XMLNode&, Parameter id);
~ControlList(); virtual ~ControlList();
virtual boost::shared_ptr<ControlList> create(Parameter id); virtual boost::shared_ptr<ControlList> create(Parameter id);

View file

@ -28,6 +28,7 @@ namespace Evoral {
*/ */
class EventSink { class EventSink {
public: public:
virtual ~EventSink() {}
virtual size_t write(timestamp_t time, virtual size_t write(timestamp_t time,
uint32_t size, uint32_t size,
const uint8_t* buf) = 0; const uint8_t* buf) = 0;

View file

@ -43,7 +43,7 @@ public:
Parameter(uint32_t type, uint8_t channel, uint32_t id=0) Parameter(uint32_t type, uint8_t channel, uint32_t id=0)
: _type(type), _id(id), _channel(channel) : _type(type), _id(id), _channel(channel)
{} {}
Parameter(const std::string& str) { Parameter(const std::string& str) {
int channel; int channel;
if (sscanf(str.c_str(), "%d_c%d_n%d", &_type, &channel, &_id) == 3) { if (sscanf(str.c_str(), "%d_c%d_n%d", &_type, &channel, &_id) == 3) {
@ -56,6 +56,8 @@ public:
std::cerr << "WARNING: Unable to create parameter from string: " << str << std::endl; std::cerr << "WARNING: Unable to create parameter from string: " << str << std::endl;
} }
virtual ~Parameter() {}
inline uint32_t type() const { return _type; } inline uint32_t type() const { return _type; }
inline uint32_t id() const { return _id; } inline uint32_t id() const { return _id; }
inline uint8_t channel() const { return _channel; } inline uint8_t channel() const { return _channel; }

View file

@ -19,6 +19,7 @@
#define __STDC_LIMIT_MACROS 1 #define __STDC_LIMIT_MACROS 1
#include <iostream> #include <iostream>
#include <cmath>
#include <algorithm> #include <algorithm>
#include <stdexcept> #include <stdexcept>
#include <stdint.h> #include <stdint.h>
@ -313,7 +314,7 @@ size_t Sequence::read(EventSink& dst, timestamp_t start, timestamp_t nframes, ti
//cerr << "Using cached iterator at " << _next_read << endl; //cerr << "Using cached iterator at " << _next_read << endl;
} }
_next_read = start + nframes; _next_read = (nframes_t) floor (start + nframes);
while (_read_iter != end() && _read_iter->time() < start + nframes) { while (_read_iter != end() && _read_iter->time() < start + nframes) {
assert(_read_iter->size() > 0); assert(_read_iter->size() > 0);

View file

@ -33,6 +33,7 @@ genericmidi.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"")
genericmidi.Append(CPPPATH = libraries['jack'].get('CPPPATH', [])) genericmidi.Append(CPPPATH = libraries['jack'].get('CPPPATH', []))
genericmidi.Merge ([ genericmidi.Merge ([
libraries['evoral'],
libraries['ardour'], libraries['ardour'],
libraries['ardour_cp'], libraries['ardour_cp'],
libraries['sndfile'], libraries['sndfile'],

View file

@ -47,6 +47,7 @@ mackie.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"")
mackie.Append(CPPPATH = libraries['jack'].get('CPPPATH', [])) mackie.Append(CPPPATH = libraries['jack'].get('CPPPATH', []))
mackie.Merge ([ mackie.Merge ([
libraries['evoral'],
libraries['ardour'], libraries['ardour'],
libraries['ardour_cp'], libraries['ardour_cp'],
libraries['sigc2'], libraries['sigc2'],

View file

@ -1019,7 +1019,7 @@ void MackieControlProtocol::notify_panner_changed( RouteSignal * route_signal )
// TODO handle plugin automation polling // TODO handle plugin automation polling
void MackieControlProtocol::update_automation( RouteSignal & rs ) void MackieControlProtocol::update_automation( RouteSignal & rs )
{ {
ARDOUR::AutoState gain_state = rs.route().gain_control()->list()->automation_state(); ARDOUR::AutoState gain_state = rs.route().gain_control()->alist()->automation_state();
if ( gain_state == Touch || gain_state == Play ) if ( gain_state == Touch || gain_state == Play )
{ {
notify_gain_changed( &rs ); notify_gain_changed( &rs );

View file

@ -37,7 +37,7 @@ void RouteSignal::connect()
_mute_changed_connection = _route.mute_control()->Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_mute_changed ), this ) ); _mute_changed_connection = _route.mute_control()->Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_mute_changed ), this ) );
if ( _strip.has_gain() ) if ( _strip.has_gain() )
_gain_changed_connection = _route.control(ARDOUR::GainAutomation)->Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_gain_changed ), this ) ); _gain_changed_connection = _route.gain_control()->Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_gain_changed ), this ) );
_name_changed_connection = _route.NameChanged.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_name_changed ), this ) ); _name_changed_connection = _route.NameChanged.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_name_changed ), this ) );

View file

@ -31,6 +31,7 @@ powermate.Append(CXXFLAGS="-DCONFIG_DIR=\\\""+final_config_prefix+"\\\"")
powermate.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"") powermate.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"")
powermate.Merge ([ powermate.Merge ([
libraries['evoral'],
libraries['ardour'], libraries['ardour'],
libraries['ardour_cp'], libraries['ardour_cp'],
libraries['sigc2'], libraries['sigc2'],

View file

@ -55,6 +55,7 @@ tranzport.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"")
tranzport.Append(CPPPATH = libraries['jack'].get('CPPPATH', [])) tranzport.Append(CPPPATH = libraries['jack'].get('CPPPATH', []))
tranzport.Merge ([ tranzport.Merge ([
libraries['evoral'],
libraries['ardour'], libraries['ardour'],
libraries['ardour_cp'], libraries['ardour_cp'],
libraries['sigc2'], libraries['sigc2'],