#include "panauto.h"
#include "panautos.h"
#include "patchbay.h"
+#include "plugin.h"
#include "mainsession.h"
#include "strack.h"
#include "theme.h"
}
+void Tracks::clear_selected_edits()
+{
+ for( Track *track=first; track; track=track->next ) {
+ for( Edit *edit=track->edits->first; edit; edit=edit->next )
+ edit->is_selected = 0;
+ }
+}
-
-void Tracks::get_affected_edits(ArrayList<Edit*> *drag_edits, double position, Track *start_track)
+void Tracks::get_selected_edits(ArrayList<Edit*> *drag_edits)
{
drag_edits->remove_all();
-
- for(Track *track = start_track;
- track;
- track = track->next)
- {
-//printf("Tracks::get_affected_edits 1 %p %d %d\n", track, track->data_type, track->record);
- if(track->record)
- {
- for(Edit *edit = track->edits->first; edit; edit = edit->next)
- {
- double startproject = track->from_units(edit->startproject);
-//printf("Tracks::get_affected_edits 1 %d\n", edl->equivalent(startproject, position));
- if(edl->equivalent(startproject, position))
- {
- drag_edits->append(edit);
- break;
- }
- }
+ for( Track *track=first; track; track=track->next ) {
+ if( !track->is_armed() ) continue;
+ for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+ if( !edit->is_selected ) continue;
+ drag_edits->append(edit);
}
}
+}
+void Tracks::select_edits(double start, double end, int v)
+{
+ for( Track *track=first; track; track=track->next ) {
+ if( !track->is_armed() ) continue;
+ int64_t start_pos = track->to_units(start, 0);
+ int64_t end_pos = track->to_units(end, 0);
+ for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+ if( start_pos >= edit->startproject+edit->length ) continue;
+ if( edit->startproject >= end_pos ) continue;
+ edit->is_selected = v > 1 ? 1 : v < 0 ? 0 : !edit->is_selected ;
+ }
+ }
}
void Tracks::get_automation_extents(float *min,
int coords_undefined = 1;
for(Track *current = first; current; current = NEXT)
{
- if(current->record)
+ if(current->is_armed())
{
current->automation->get_extents(min,
max,
Track *new_track = 0;
delete_all_tracks();
+ int solo_track_id = tracks->edl->local_session->solo_track_id;
+
for(Track *current = tracks->first; current; current = NEXT)
{
switch(current->data_type)
continue;
}
new_track->copy_from(current);
+
+ if( current->get_id() == solo_track_id )
+ edl->local_session->solo_track_id = new_track->get_id();
}
}
}
-int Tracks::delete_track(Track *track)
+int Tracks::delete_track(Track *track, int gang)
{
- if (!track)
- return 0;
-
- int old_location = number_of(track);
- detach_shared_effects(old_location);
-
+ if( !track ) return 0;
+ if( gang < 0 )
+ gang = edl->local_session->gang_tracks != GANG_NONE ? 1 : 0;
+ Track *nxt = track->next;
+ if( gang ) {
+ track = track->gang_master();
+ while( nxt && !nxt->master )
+ nxt = nxt->next;
+ }
+ Track *current = track;
+ int old_location = number_of(current);
+ for( Track *next_track=0; current!=nxt; current=next_track ) {
+ next_track = current->next;
+ detach_shared_effects(old_location);
+ for( Track *curr=current; curr; curr=curr->next ) {
// Shift effects referencing effects below the deleted track
- for(Track *current = track;
- current;
- current = NEXT)
- {
- change_modules(number_of(current), number_of(current) - 1, 0);
+ change_modules(number_of(curr), number_of(curr)-1, 0);
+ }
+ delete current;
}
- if(track) delete track;
-
return 0;
}
int Tracks::detach_shared_effects(int module)
{
- for(Track *current = first; current; current = NEXT)
- {
+ for( Track *current=first; current; current=NEXT ) {
current->detach_shared_effects(module);
}
-
return 0;
- }
+}
+int Tracks::detach_ganged_effects(Plugin *plugin)
+{
+ if( edl->local_session->gang_tracks == GANG_NONE ) return 1;
+ for( Track *current=first; current; current=NEXT ) {
+ if( current == plugin->track ) continue;
+ if( !current->armed_gang(plugin->track) ) continue;
+ current->detach_ganged_effects(plugin);
+ }
+ return 0;
+}
int Tracks::total_of(int type)
{
IntAuto *mute_auto = (IntAuto *)mute_keyframe;
result +=
- (current->play && type == PLAY) ||
- (current->record && type == RECORD) ||
- (current->gang && type == GANG) ||
+ (current->plays() && type == PLAY) ||
+ (current->is_armed() && type == RECORD) ||
+ (current->is_ganged() && type == GANG) ||
(current->draw && type == DRAW) ||
(mute_auto->value && type == MUTE) ||
(current->expand_view && type == EXPAND);
{
int result = 0;
for(Track *current = first; current; current = NEXT)
- if(current->data_type == TRACK_AUDIO && current->record) result++;
+ if(current->data_type == TRACK_AUDIO && current->is_armed()) result++;
return result;
}
int result = 0;
for(Track *current = first; current; current = NEXT)
{
- if(current->data_type == TRACK_VIDEO && current->record) result++;
+ if(current->data_type == TRACK_VIDEO && current->is_armed()) result++;
}
return result;
}
for(Track *current = first; current; current = NEXT)
{
- if(current->data_type == TRACK_AUDIO && current->play)
+ if(current->data_type == TRACK_AUDIO && current->plays())
{
result++;
}
for(Track *current = first; current; current = NEXT)
{
- if(current->data_type == TRACK_VIDEO && current->play)
+ if(current->data_type == TRACK_VIDEO && current->plays())
{
result++;
}
double total = 0;
for(Track *current = first; current; current = NEXT)
{
- if( current->play )
+ if( current->plays() )
{
double length = current->get_length();
if(length > total) total = length;
double total = -1;
for(Track *current = first; current; current = NEXT)
{
- if(current->record)
+ if(current->is_armed())
{
double length = current->get_length();
if(length > total) total = length;
return 0;
}
-void Tracks::translate_projector(float offset_x, float offset_y)
+void Tracks::translate_fauto_xy(int fauto, float dx, float dy, int all)
{
- for(Track *current = first; current; current = NEXT)
- {
- if(current->data_type == TRACK_VIDEO)
- {
- ((VTrack*)current)->translate(offset_x, offset_y, 0);
- }
+ Track *track = first;
+ for( ; track; track=track->next ) {
+ if( !all && !track->is_armed() ) continue;
+ if( track->data_type != TRACK_VIDEO ) continue;
+ ((VTrack*)track)->translate(fauto, dx, dy, all);
+ }
+}
+
+void Tracks::translate_projector(float dx, float dy, int all)
+{
+ translate_fauto_xy(AUTOMATION_PROJECTOR_X, dx, dy, all);
+}
+
+void Tracks::translate_camera(float dx, float dy, int all)
+{
+ translate_fauto_xy(AUTOMATION_CAMERA_X, dx, dy, all);
+}
+
+void Tracks::crop_resize(float x, float y, float z)
+{
+ float ctr_x = edl->session->output_w / 2.;
+ float ctr_y = edl->session->output_h / 2.;
+ Track *track = first;
+ for( ; track; track=track->next ) {
+ if( !track->is_armed() ) continue;
+ if( track->data_type != TRACK_VIDEO ) continue;
+ float px, py, pz;
+ track->get_projector(px, py, pz);
+ float old_x = px + ctr_x;
+ float old_y = py + ctr_y;
+ float nx = (old_x - x) * z;
+ float ny = (old_y - y) * z;
+ track->set_projector(nx, ny, pz * z);
+ }
+}
+
+void Tracks::crop_shrink(float x, float y, float z)
+{
+ float ctr_x = edl->session->output_w / 2.;
+ float ctr_y = edl->session->output_h / 2.;
+ Track *track = first;
+ for( ; track; track=track->next ) {
+ if( !track->is_armed() ) continue;
+ if( track->data_type != TRACK_VIDEO ) continue;
+ float cx, cy, cz, px, py, pz;
+ track->get_camera(cx, cy, cz);
+ track->get_projector(px, py, pz);
+ float dx = x - (px + ctr_x);
+ float dy = y - (py + ctr_y);
+ cz *= pz;
+ cx += dx / cz; cy += dy / cz;
+ track->set_camera(cx, cy, cz * z);
+ px += dx; py += dy;
+ track->set_projector(px, py, 1 / z);
}
}
{
//printf("Tracks::update_y_pixels %d\n", y);
current->y_pixel = y;
+ if( current->is_hidden() ) continue;
y += current->vertical_span(theme);
}
}
double position = edl->local_session->get_selectionstart(1);
if(type == PLAY) current->play = value;
- if(type == RECORD) current->record = value;
- if(type == GANG) current->gang = value;
+ if(type == RECORD) current->armed = value;
+ if(type == GANG) current->ganged = value;
if(type == DRAW) current->draw = value;
if(type == MUTE)
int result = 0;
for(Track* current = first; current; current = NEXT)
{
- result += edl->local_session->zoom_track;
+ result += current->data_h;
}
return result;
}
return current;
}
+Track* Tracks::get_track_by_id(int id)
+{
+ Track *track = edl->tracks->first;
+ while( track && track->get_id() != id ) track = track->next;
+ return track;
+}
int Tracks::total_playable_vtracks()
{
return result;
}
-int Tracks::plugin_exists(Plugin *plugin)
+Plugin *Tracks::plugin_exists(int plugin_id)
{
- for(Track *track = first; track; track = track->next)
- {
- if(track->plugin_exists(plugin)) return 1;
+ if( plugin_id < 0 ) return 0;
+ Plugin *plugin = 0;
+ for( Track *track=first; !plugin && track; track=track->next ) {
+ plugin = track->plugin_exists(plugin_id);
}
- return 0;
+ return plugin;
}
int Tracks::track_exists(Track *track)
return 0;
}
+int Tracks::new_group(int id)
+{
+ int count = 0;
+ for( Track *track=first; track; track=track->next ) {
+ if( !track->is_armed() ) continue;
+ for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+ if( edit->group_id > 0 ) continue;
+ if( !edit->is_selected ) continue;
+ edit->group_id = id;
+ ++count;
+ }
+ }
+ return count;
+}
+
+int Tracks::set_group_selected(int id, int v)
+{
+ int count = 0;
+ int gang = edl->local_session->gang_tracks != GANG_NONE ? 1 : 0;
+ for( Track *track=first; track; track=track->next ) {
+ if( track->is_hidden() ) continue;
+ for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+ if( edit->group_id != id ) continue;
+ if( v < 0 ) v = !edit->is_selected ? 1 : 0;
+ edit->select_affected_edits(v, gang);
+ ++count;
+ }
+ }
+ return count;
+}
+
+int Tracks::del_group(int id)
+{
+ int count = 0;
+ for( Track *track=first; track; track=track->next ) {
+ for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+ if( edit->group_id != id ) continue;
+ edit->is_selected = 1;
+ edit->group_id = 0;
+ ++count;
+ }
+ }
+ return count;
+}
Track *Tracks::get(int idx, int data_type)
{
return 0;
}
+void Tracks::roll_tracks(Track *src, Track *dst, int n)
+{
+ if( src == dst ) return;
+ while( --n >= 0 && src ) {
+ Track *nxt = src->next;
+ change_modules(number_of(src), total(), 0);
+ for( Track *track=nxt; track; track=track->next )
+ change_modules(number_of(track), number_of(track)-1, 0);
+ remove_pointer(src);
+ int ndst = dst ? number_of(dst) : total();
+ insert_before(dst, src);
+ for( Track *track=last; track && track!=src; track=track->previous )
+ change_modules(number_of(track)-1, number_of(track), 0);
+ change_modules(total(), ndst, 0);
+ src = nxt;
+ }
+}
+
+double Tracks::align_timecodes()
+{
+ double offset = -1;
+ for( Track *track=first; track; track=track->next ) {
+ if( !track->is_armed() ) continue;
+ double early_offset = track->edits->early_timecode();
+ if( offset < 0 || offset > early_offset )
+ offset = early_offset;
+ }
+ if( offset >= 0 ) {
+ for( Track *track=first; track; track=track->next ) {
+ if( !track->is_armed() ) continue;
+ track->edits->align_timecodes(offset);
+ }
+ }
+ return offset;
+}
+
+void Tracks::update_idxbl_length(int id, double dt)
+{
+ for( Track *track=first; track; track=track->next ) {
+ if( !track->is_armed() ) continue;
+ int64_t du = track->to_units(dt,0);
+ track->edits->update_idxbl_length(id, du);
+ track->optimize();
+ }
+}
+
+void Tracks::create_keyframes(double position, int mask, int mode)
+{
+ for( Track *track=first; track; track=track->next ) {
+ if( !track->is_armed() ) continue;
+ track->create_keyframes(position, mask, mode);
+ }
+}