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

@ -933,15 +933,11 @@ ARDOUR_UI::update_disk_space()
nframes_t frames = session->available_capture_duration();
char buf[64];
nframes_t fr = session->frame_rate();
if (frames == max_frames) {
strcpy (buf, _("Disk: 24hrs+"));
} else {
int hrs;
int mins;
int secs;
nframes_t fr = session->frame_rate();
rec_enabled_streams = 0;
session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
@ -949,6 +945,10 @@ ARDOUR_UI::update_disk_space()
frames /= rec_enabled_streams;
}
int hrs;
int mins;
int secs;
hrs = frames / (fr * 3600);
frames -= hrs * fr * 3600;
mins = frames / (fr * 60);
@ -959,6 +959,15 @@ ARDOUR_UI::update_disk_space()
}
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

View file

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

View file

@ -61,6 +61,7 @@ class AudioClock : public Gtk::HBox
void set_session (ARDOUR::Session *s);
sigc::signal<void> ValueChanged;
sigc::signal<void> mode_changed;
sigc::signal<void> ChangeAborted;
static sigc::signal<void> ModeChanged;

View file

@ -20,6 +20,8 @@
#ifndef __gtk2_ardour_drag_info_h_
#define __gtk2_ardour_drag_info_h_
#include <list>
#include <gdk/gdk.h>
#include <stdint.h>
@ -64,7 +66,9 @@ struct DragInfo {
bool move_threshold_passed;
bool want_move_threshold;
bool brushing;
ARDOUR::Location* copied_location;
std::list<ARDOUR::Location*> copied_locations;
void clear_copied_locations ();
};
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;
}
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 ()
:
/* time display buttons */
@ -263,7 +272,6 @@ Editor::Editor ()
clicked_control_point = 0;
last_update_frame = 0;
drag_info.item = 0;
drag_info.copied_location = 0;
current_mixer_strip = 0;
current_bbt_points = 0;
@ -641,7 +649,12 @@ Editor::Editor ()
region_list_display.set_model (region_list_model);
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));
region_name_cell->property_editable() = true;
@ -669,7 +682,7 @@ Editor::Editor ()
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.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_release_event().connect (mem_fun(*this, &Editor::region_list_display_key_release));
@ -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.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.set_policy (POLICY_NEVER, POLICY_AUTOMATIC);

View file

@ -545,6 +545,8 @@ class Editor : public PublicEditor
void set_selected_track (TimeAxisView&, Selection::Operation op = Selection::Set, bool no_remove=false);
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);
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);
@ -929,10 +931,20 @@ class Editor : public PublicEditor
add (name);
add (region);
add (color_);
add (start);
add (end);
add (length);
add (used);
add (path);
}
Gtk::TreeModelColumn<Glib::ustring> name;
Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Region> > region;
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;
@ -1080,6 +1092,7 @@ class Editor : public PublicEditor
void add_regions_to_region_display (std::vector<boost::weak_ptr<ARDOUR::Region> > & );
void region_hidden (boost::shared_ptr<ARDOUR::Region>);
void redisplay_regions ();
void update_region_row (boost::shared_ptr<ARDOUR::Region>);
bool no_region_list_redisplay;
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->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->property_outline_pixels() = 0;

View file

@ -1879,11 +1879,7 @@ Editor::finalize_drag ()
drag_info.last_pointer_frame = 0;
drag_info.current_pointer_frame = 0;
drag_info.brushing = false;
if (drag_info.copied_location) {
delete drag_info.copied_location;
drag_info.copied_location = 0;
}
drag_info.clear_copied_locations ();
}
void
@ -1928,7 +1924,7 @@ Editor::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
drag_info.want_move_threshold = false;
drag_info.pointer_frame_offset = 0;
drag_info.brushing = false;
drag_info.copied_location = 0;
drag_info.clear_copied_locations ();
drag_info.original_x = 0;
drag_info.original_y = 0;
@ -2320,6 +2316,7 @@ Editor::update_marker_drag_item (Location *location)
}
}
void
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;
drag_info.copied_location = new Location (*location);
drag_info.pointer_frame_offset = drag_info.grab_frame - (is_start ? location->start() : location->end());
update_marker_drag_item (location);
@ -2369,28 +2365,67 @@ Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event)
selection->toggle (marker);
break;
case Selection::Set:
if (!selection->selected (marker)) {
selection->set (marker);
}
break;
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;
}
case Selection::Add:
selection->add (marker);
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
Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
nframes64_t f_delta;
Marker* marker = (Marker *) drag_info.data;
Location *real_location;
Location *copy_location;
nframes64_t newframe;
bool is_start;
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) {
newframe = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
} else {
@ -2407,40 +2442,97 @@ Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
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)) {
move_both = true;
}
MarkerSelection::iterator i;
list<Location*>::iterator x;
/* find the marker we're dragging, and compute the delta */
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;
if (marker == dragged_marker) {
if ((real_location = find_location_from_marker (marker, is_start)) == 0) {
/* que pasa ?? */
return;
}
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 */
copy_location->set_start (newframe);
copy_location->set_start (copy_location->start() + f_delta);
} else {
nframes64_t new_start = copy_location->start() + f_delta;
nframes64_t new_end = copy_location->end() + f_delta;
if (is_start) { // start-of-range marker
if (move_both) {
copy_location->set_start (newframe);
copy_location->set_end (newframe + f_delta);
} else if (newframe < copy_location->end()) {
copy_location->set_start (newframe);
copy_location->set_start (new_start);
copy_location->set_end (new_end);
} else if (new_start < copy_location->end()) {
copy_location->set_start (new_start);
} else {
snap_to (next, 1, true);
copy_location->set_end (next);
@ -2450,11 +2542,10 @@ Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
} else { // end marker
if (move_both) {
copy_location->set_end (newframe);
copy_location->set_start (newframe - f_delta);
} else if (newframe > copy_location->start()) {
copy_location->set_end (newframe);
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);
@ -2462,36 +2553,73 @@ Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
}
}
}
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.first_move = false;
update_marker_drag_item (copy_location);
LocationMarkers* lm = find_location_markers (real_location);
lm->set_position (copy_location->start(), copy_location->end());
edit_point_clock.set (copy_location->start());
if (drag_info.copied_locations.empty()) {
abort();
}
edit_point_clock.set (drag_info.copied_locations.front()->start());
show_verbose_time_cursor (newframe, 10);
#ifdef GTKOSX
track_canvas->update_now ();
#endif
}
void
Editor::marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
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;
}
_dragging_edit_point = false;
Marker* marker = (Marker *) drag_info.data;
bool is_start;
begin_reversible_command ( _("move marker") );
XMLNode &before = session->locations()->get_state();
Location * location = find_location_from_marker (marker, is_start);
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 ((*i), is_start);
if (location) {
@ -2500,9 +2628,10 @@ Editor::marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
}
if (location->is_mark()) {
location->set_start (drag_info.copied_location->start());
location->set_start ((*x)->start());
} 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
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;
TimeAxisView* tvp2 = trackview_by_y_position (iy1);

View file

@ -426,12 +426,15 @@ Editor::nudge_forward (bool next, bool force_playhead)
} else if (!force_playhead && !selection->markers.empty()) {
bool is_start;
Location* loc = find_location_from_marker (selection->markers.front(), is_start);
if (loc) {
begin_reversible_command (_("nudge location forward"));
for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
Location* loc = find_location_from_marker ((*i), is_start);
if (loc) {
XMLNode& before (loc->get_state());
if (is_start) {
@ -457,8 +460,10 @@ Editor::nudge_forward (bool next, bool force_playhead)
}
XMLNode& after (loc->get_state());
session->add_command (new MementoCommand<Location>(*loc, &before, &after));
commit_reversible_command ();
}
}
commit_reversible_command ();
} else {
distance = get_nudge_distance (playhead_cursor->current_frame, next_distance);
@ -506,11 +511,15 @@ Editor::nudge_backward (bool next, bool force_playhead)
} else if (!force_playhead && !selection->markers.empty()) {
bool is_start;
Location* loc = find_location_from_marker (selection->markers.front(), is_start);
begin_reversible_command (_("nudge location forward"));
for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
Location* loc = find_location_from_marker ((*i), is_start);
if (loc) {
begin_reversible_command (_("nudge location forward"));
XMLNode& before (loc->get_state());
if (is_start) {
@ -540,6 +549,9 @@ Editor::nudge_backward (bool next, bool force_playhead)
XMLNode& after (loc->get_state());
session->add_command (new MementoCommand<Location>(*loc, &before, &after));
}
}
commit_reversible_command ();
} else {

View file

@ -30,6 +30,7 @@
#include <ardour/silentfilesource.h>
#include <ardour/session_region.h>
#include <gtkmm2ext/stop_signal.h>
#include "editor.h"
@ -41,6 +42,7 @@
#include "region_view.h"
#include "utils.h"
#include "i18n.h"
using namespace sigc;
@ -89,9 +91,17 @@ void
Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
{
string str;
char start_str[16];
char end_str[16];
char length_str[16];
char used_str[8];
int used;
TreeModel::Row row;
Gdk::Color c;
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());
@ -100,12 +110,10 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
}
if (region->hidden()) {
TreeModel::iterator iter = region_list_model->get_iter ("0");
TreeModel::Row parent;
TreeModel::Row child;
if (!iter) {
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");
boost::shared_ptr<Region> proxy = parent[region_list_columns.region];
proxy.reset ();
} else {
if ((*iter)[region_list_columns.name] != _("Hidden")) {
parent = *(region_list_model->insert(iter));
parent[region_list_columns.name] = _("Hidden");
boost::shared_ptr<Region> proxy = parent[region_list_columns.region];
proxy.reset ();
} else {
parent = *iter;
}
}
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());
if (missing_source) {
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 {
set_color(c, rgba_from_style ("RegionListWholeFile", 0xff, 0, 0, 0, "fg", Gtk::STATE_NORMAL, false ));
}
row[region_list_columns.color_] = c;
if (region->source()->name()[0] == '/') { // external file
if (region->whole_file()) {
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(region->source());
str = ".../";
if (afs) {
@ -173,9 +175,7 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
}
} else {
str = region->name();
}
if (region->n_channels() > 1) {
@ -186,14 +186,16 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
str += ']';
}
if (missing_source) {
str += _(" (MISSING)");
}
//if (missing_source) {
// str += _(" (MISSING)");
//}
row[region_list_columns.name] = str;
row[region_list_columns.region] = region;
if (region->automatic()) {
return;
}
} else {
@ -204,7 +206,6 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
bool found_parent = false;
for (i = rows.begin(); i != rows.end(); ++i) {
boost::shared_ptr<Region> rr = (*i)[region_list_columns.region];
boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion>(rr);
@ -228,16 +229,96 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
}
}
}
if (!found_parent) {
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;
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) {
row[region_list_columns.name] = string_compose("%1 [%2]", region->name(), region->n_channels());
} else {
@ -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
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);
}
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
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*>
{
void range (nframes64_t& start, nframes64_t& end);
};
#endif /* __ardour_gtk_marker_selection_h__ */

View file

@ -608,6 +608,12 @@ Selection::set (boost::shared_ptr<Evoral::ControlList> ac)
add (ac);
}
bool
Selection::selected (Marker* m)
{
return find (markers.begin(), markers.end(), m) != markers.end();
}
bool
Selection::selected (TimeAxisView* tv)
{
@ -801,3 +807,31 @@ Selection::add (Marker* m)
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 (RegionView*);
bool selected (Marker*);
void set (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 (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
void add (Marker*);
void add (const std::list<Marker*>&);
void add (const RegionSelection&);
void remove (TimeAxisView*);

View file

@ -1181,6 +1181,10 @@ TimeAxisView::color_handler ()
TimeAxisView*
TimeAxisView::covers_y_position (double y)
{
if (y_position < 0) {
abort ();
}
if (hidden()) {
return 0;
}

View file

@ -43,7 +43,7 @@ public:
boost::shared_ptr<ARDOUR::AutomationList>,
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>);
@ -55,7 +55,7 @@ public:
return ((ARDOUR::AutomationList*)_list.get())->automation_write();
}
inline AutoState automation_state() {
inline AutoState automation_state() const {
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_start (bool yn, void* src);
bool is_auto_punch () { return _flags & IsAutoPunch; }
bool is_auto_loop () { return _flags & IsAutoLoop; }
bool is_mark () { return _flags & IsMark; }
bool is_hidden () { return _flags & IsHidden; }
bool is_cd_marker () { return _flags & IsCDMarker; }
bool is_end() { return _flags & IsEnd; }
bool is_start() { return _flags & IsStart; }
bool is_range_marker() { return _flags & IsRangeMarker; }
bool is_auto_punch () const { return _flags & IsAutoPunch; }
bool is_auto_loop () const { return _flags & IsAutoLoop; }
bool is_mark () const { return _flags & IsMark; }
bool is_hidden () const { return _flags & IsHidden; }
bool is_cd_marker () const { return _flags & IsCDMarker; }
bool is_end() const { return _flags & IsEnd; }
bool is_start() const { return _flags & IsStart; }
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*> 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_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> changed;
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;
sigc::signal<void,Change> StateChanged;
static sigc::signal<void,boost::shared_ptr<ARDOUR::Region> > RegionPropertyChanged;
virtual ~Region();

View file

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

View file

@ -924,3 +924,16 @@ Locations::get_location_by_id(PBD::ID id)
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::HiddenChanged = ARDOUR::new_change ();
sigc::signal<void,boost::shared_ptr<ARDOUR::Region> > Region::RegionPropertyChanged;
/* 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)
@ -1350,6 +1351,21 @@ Region::send_change (Change 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

View file

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

View file

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

View file

@ -85,7 +85,7 @@ public:
ControlList (const Parameter& id);
//ControlList (const XMLNode&, Parameter id);
~ControlList();
virtual ~ControlList();
virtual boost::shared_ptr<ControlList> create(Parameter id);

View file

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

View file

@ -56,6 +56,8 @@ public:
std::cerr << "WARNING: Unable to create parameter from string: " << str << std::endl;
}
virtual ~Parameter() {}
inline uint32_t type() const { return _type; }
inline uint32_t id() const { return _id; }
inline uint8_t channel() const { return _channel; }

View file

@ -19,6 +19,7 @@
#define __STDC_LIMIT_MACROS 1
#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdexcept>
#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;
}
_next_read = start + nframes;
_next_read = (nframes_t) floor (start + nframes);
while (_read_iter != end() && _read_iter->time() < start + nframes) {
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.Merge ([
libraries['evoral'],
libraries['ardour'],
libraries['ardour_cp'],
libraries['sndfile'],

View file

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

View file

@ -1019,7 +1019,7 @@ void MackieControlProtocol::notify_panner_changed( RouteSignal * route_signal )
// TODO handle plugin automation polling
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 )
{
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 ) );
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 ) );

View file

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

View file

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