//printf("TrackCanvas::resize_event 2\n");
}
+// *** CONTEXT_HELP ***
+// This complicated implementation (up to *** END_CONTEXT_HELP ***)
+// serves solely for context dependent help
int TrackCanvas::keypress_event()
{
+ int cursor_x, cursor_y;
+
+// printf("TrackCanvas::keypress_event: %d\n", get_keypress());
+ if (get_keypress() != 'h' || ! alt_down()) return 0;
+ if (! is_tooltip_event_win() || ! cursor_inside()) return 0;
+
+ cursor_x = get_cursor_x();
+ cursor_y = get_cursor_y();
+
+// Provide different help depending on the kind of object under the cursor:
+// transition border handles
+// transition icons themselves
+// autos (keyframes or lines) and plugin keyframes
+// asset border handles
+// plugin border handles
+// plugin bars themselves
+ if (help_transition_handles(cursor_x, cursor_y)) return 1;
+ if (help_transitions(cursor_x, cursor_y)) return 1;
+ if (help_keyframes(cursor_x, cursor_y)) return 1;
+ if (help_edit_handles(cursor_x, cursor_y)) return 1;
+ if (help_plugin_handles(cursor_x, cursor_y)) return 1;
+ if (help_plugins(cursor_x, cursor_y)) return 1;
+
+// Show "Editing" chapter as a fallback when cursor was over anything else
+ context_help_show("Editing");
+ return 1;
+}
+
+int TrackCanvas::help_transitions(int cursor_x, int cursor_y)
+{
+ int done = 0;
+ int64_t x, y, w, h;
+ Transition *transition = 0;
+
+ // Detect, if any, the transition under cursor
+ for( Track *track = mwindow->edl->tracks->first; track && !done; track = track->next ) {
+ if( track->is_hidden() ) continue;
+ if( !track->show_transitions() ) continue;
+
+ for( Edit *edit = track->edits->first; edit; edit = edit->next ) {
+ if( edit->transition ) {
+ edit_dimensions(edit, x, y, w, h);
+ get_transition_coords(edit, x, y, w, h);
+
+ if( MWindowGUI::visible(x, x + w, 0, get_w()) &&
+ MWindowGUI::visible(y, y + h, 0, get_h()) ) {
+ if( cursor_x >= x && cursor_x < x + w &&
+ cursor_y >= y && cursor_y < y + h ) {
+ transition = edit->transition;
+ done = 1;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // If transition found, display its context help
+ if(transition) {
+ context_help_show(transition->title);
+ return 1;
+ }
+
+ return 0;
+}
+
+int TrackCanvas::help_keyframes(int cursor_x, int cursor_y)
+{
+ int result = 0;
+ EDLSession *session = mwindow->edl->session;
+
+ static BC_Pixmap *help_pixmaps[AUTOMATION_TOTAL] =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ pankeyframe_pixmap,
+ modekeyframe_pixmap,
+ maskkeyframe_pixmap,
+ 0,
+ };
+
+ for(Track *track = mwindow->edl->tracks->first;
+ track && !result;
+ track = track->next) {
+ if( track->is_hidden() ) continue;
+ Automation *automation = track->automation;
+
+ for(int i = 0; i < AUTOMATION_TOTAL && !result; i ++)
+ {
+// Event not trapped and automation visible
+ Autos *autos = automation->autos[i];
+ if(!result && session->auto_conf->autos[i] && autos) {
+ switch(i) {
+ case AUTOMATION_MODE:
+ case AUTOMATION_PAN:
+ case AUTOMATION_MASK:
+ result = help_autos(track, automation->autos[i],
+ cursor_x, cursor_y,
+ help_pixmaps[i]);
+ break;
+
+ default: {
+ switch(autos->get_type()) {
+ case Autos::AUTOMATION_TYPE_FLOAT: {
+ Automation automation(0, track);
+ int grouptype = automation.autogrouptype(i, track);
+
+ result = help_float_autos(track, autos,
+ cursor_x, cursor_y,
+ grouptype);
+
+ break; }
+
+ case Autos::AUTOMATION_TYPE_INT: {
+ result = help_int_autos(track, autos,
+ cursor_x, cursor_y);
+ break; }
+ }
+ break; }
+ }
+
+ if(result)
+ {
+ context_help_show("Using Autos");
+ }
+ }
+ }
+
+ if(!result && session->auto_conf->plugins) {
+ result = help_plugin_autos(track, cursor_x, cursor_y);
+ if(result) {
+ context_help_show("Edit Params");
+ }
+ }
+ }
+
+ return result;
+}
+
+int TrackCanvas::help_plugin_autos(Track *track, int cursor_x, int cursor_y)
+{
+ int result = 0;
+
+ double view_start;
+ double unit_start;
+ double view_end;
+ double unit_end;
+ double yscale;
+ int center_pixel;
+ double zoom_sample;
+ double zoom_units;
+
+ if(!track->expand_view) return 0;
+
+ calculate_viewport(track,
+ view_start,
+ unit_start,
+ view_end,
+ unit_end,
+ yscale,
+ center_pixel,
+ zoom_sample,
+ zoom_units);
+
+ for(int i = 0; i < track->plugin_set.total && !result; i++)
+ {
+ PluginSet *plugin_set = track->plugin_set.values[i];
+ int center_pixel = track->y_pixel -
+ mwindow->edl->local_session->track_start[pane->number];
+ if( track->show_titles() )
+ center_pixel += mwindow->theme->get_image("title_bg_data")->get_h();
+ if( track->show_assets() )
+ center_pixel += track->data_h;
+ center_pixel += (i + 0.5) * mwindow->theme->get_image("plugin_bg_data")->get_h();
+
+ for(Plugin *plugin = (Plugin*)plugin_set->first;
+ plugin && !result;
+ plugin = (Plugin*)plugin->next)
+ {
+ for(KeyFrame *keyframe = (KeyFrame*)plugin->keyframes->first;
+ keyframe && !result;
+ keyframe = (KeyFrame*)keyframe->next)
+ {
+ if(keyframe->position >= unit_start && keyframe->position < unit_end)
+ {
+ int64_t x = (int64_t)((keyframe->position - unit_start) / zoom_units);
+ int y = center_pixel - keyframe_pixmap->get_h() / 2;
+
+ if(cursor_x >= x && cursor_y >= y &&
+ cursor_x < x + keyframe_pixmap->get_w() &&
+ cursor_y < y + keyframe_pixmap->get_h())
+ {
+ result = 1;
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
+int TrackCanvas::help_autos(Track *track, Autos *autos, int cursor_x,
+ int cursor_y, BC_Pixmap *pixmap)
+{
+ int result = 0;
+
+ double view_start;
+ double unit_start;
+ double view_end;
+ double unit_end;
+ double yscale;
+ int center_pixel;
+ double zoom_sample;
+ double zoom_units;
+
+ calculate_viewport(track,
+ view_start,
+ unit_start,
+ view_end,
+ unit_end,
+ yscale,
+ center_pixel,
+ zoom_sample,
+ zoom_units);
+
+ Auto *current;
+
+ for(current = autos->first; current && !result; current = NEXT)
+ {
+ if(current->position >= unit_start && current->position < unit_end)
+ {
+ int64_t x, y;
+ x = (int64_t)((double)(current->position - unit_start) /
+ zoom_units - (pixmap->get_w() / 2.0 + 0.5));
+ y = center_pixel - pixmap->get_h() / 2;
+
+ if(cursor_x >= x && cursor_y >= y &&
+ cursor_x < x + pixmap->get_w() &&
+ cursor_y < y + pixmap->get_h())
+ {
+ result = 1;
+ }
+ }
+ }
+
+ return result;
+}
+
+int TrackCanvas::help_float_autos(Track *track, Autos *autos, int cursor_x, int cursor_y, int autogrouptype)
+{
+ int result = 0;
+ int center_pixel;
+ double view_start, unit_start;
+ double view_end, unit_end, yscale;
+ double zoom_sample, zoom_units;
+ double slope;
+
+ calculate_viewport(track, view_start, unit_start, view_end, unit_end,
+ yscale, center_pixel, zoom_sample, zoom_units);
+
+// Get first auto before start
+ Auto *current = 0, *previous = 0;
+
+ for( current = autos->last;
+ current && current->position >= unit_start;
+ current = PREVIOUS ) ;
+
+ Auto *first_auto = current ? current :
+ autos->first ? autos->first : autos->default_auto;
+
+ double ax = 0, ay = 0, ax2 = 0, ay2 = 0;
+ if( first_auto ) {
+ calculate_auto_position(0, &ax, &ay, 0, 0, 0, 0,
+ first_auto, unit_start, zoom_units, yscale, autogrouptype);
+ }
+ if( current )
+ current = NEXT;
+ else {
+ current = autos->first;
+ ax = 0;
+ }
+
+ do {
+ if(current) {
+ calculate_auto_position(1, &ax2, &ay2, 0, 0, 0, 0,
+ current, unit_start, zoom_units, yscale, autogrouptype);
+ }
+ else {
+ ax2 = get_w();
+ ay2 = ay;
+ }
+
+ slope = ax2 > ax ? (ay2 - ay) / (ax2 - ax) : 0;
+
+ if(ax2 > get_w()) {
+ ax2 = get_w();
+ ay2 = ay + slope * (get_w() - ax);
+ }
+
+ if(ax < 0) {
+ ay = ay + slope * (0 - ax);
+ ax = 0;
+ }
+
+// test handle
+ if( current && !result && current != autos->default_auto ) {
+ if( track->is_armed() ) {
+ result = test_floatauto((FloatAuto*)current, 0,
+ (int)center_pixel, (int)yscale, cursor_x, cursor_y,
+ unit_start, zoom_units, yscale, autogrouptype);
+ }
+ }
+
+// test joining line
+ if( !result && track->is_armed() ) {
+ result = test_floatline(center_pixel,
+ (FloatAutos*)autos, unit_start, zoom_units, yscale,
+// Exclude auto coverage from the end of the line. The auto overlaps
+ (int)ax, (int)ax2 - HANDLE_W / 2, cursor_x, cursor_y,
+ 0, autogrouptype);
+ }
+
+ if( current ) {
+ previous = current;
+ calculate_auto_position(0, &ax2, &ay2, 0, 0, 0, 0, previous,
+ unit_start, zoom_units, yscale, autogrouptype);
+ current = NEXT;
+ }
+ ax = ax2; ay = ay2;
+ } while( current && current->position <= unit_end && !result );
+
+ if( ax < get_w() && !result ) {
+ ax2 = get_w(); ay2 = ay;
+ if(track->is_armed()) {
+ result = test_floatline(center_pixel,
+ (FloatAutos*)autos, unit_start, zoom_units, yscale,
+ (int)ax, (int)ax2, cursor_x, cursor_y,
+ 0, autogrouptype);
+ }
+ }
+
+ return result;
+}
+
+int TrackCanvas::help_int_autos(Track *track, Autos *autos, int cursor_x, int cursor_y)
+{
+ int result = 0;
+ double view_start;
+ double unit_start;
+ double view_end;
+ double unit_end;
+ double yscale;
+ int center_pixel;
+ double zoom_sample;
+ double zoom_units;
+ double ax, ay, ax2, ay2;
+
+ calculate_viewport(track,
+ view_start,
+ unit_start,
+ view_end,
+ unit_end,
+ yscale,
+ center_pixel,
+ zoom_sample,
+ zoom_units);
+
+ double high = -yscale * 0.8 / 2;
+ double low = yscale * 0.8 / 2;
+
+// Get first auto before start
+ Auto *current;
+ for(current = autos->last; current && current->position >= unit_start; current = PREVIOUS)
+ ;
+
+ if(current)
+ {
+ ax = 0;
+ ay = ((IntAuto*)current)->value > 0 ? high : low;
+ current = NEXT;
+ }
+ else
+ {
+ current = autos->first ? autos->first : autos->default_auto;
+ if(current)
+ {
+ ax = 0;
+ ay = ((IntAuto*)current)->value > 0 ? high : low;
+ }
+ else
+ {
+ ax = 0;
+ ay = yscale;
+ }
+ }
+
+ do
+ {
+ if(current)
+ {
+ ax2 = (double)(current->position - unit_start) / zoom_units;
+ ay2 = ((IntAuto*)current)->value > 0 ? high : low;
+ }
+ else
+ {
+ ax2 = get_w();
+ ay2 = ay;
+ }
+
+ if(ax2 > get_w()) ax2 = get_w();
+
+ if(current && !result)
+ {
+ if(current != autos->default_auto)
+ {
+ if(track->is_armed())
+ {
+ result = test_auto(current,
+ (int)ax2,
+ (int)ay2,
+ (int)center_pixel,
+ (int)yscale,
+ cursor_x,
+ cursor_y,
+ 0);
+ }
+ }
+
+ current = NEXT;
+ }
+
+ if(!result)
+ {
+ if(track->is_armed())
+ {
+ result = test_toggleline(autos,
+ center_pixel,
+ (int)ax,
+ (int)ay,
+ (int)ax2,
+ (int)ay2,
+ cursor_x,
+ cursor_y,
+ 0);
+ }
+ }
+
+ ax = ax2;
+ ay = ay2;
+ }while(current && current->position <= unit_end && !result);
+
+ if(ax < get_w() && !result)
+ {
+ ax2 = get_w();
+ ay2 = ay;
+ if(track->is_armed())
+ {
+ result = test_toggleline(autos,
+ center_pixel,
+ (int)ax,
+ (int)ay,
+ (int)ax2,
+ (int)ay2,
+ cursor_x,
+ cursor_y,
+ 0);
+ }
+ }
+ return result;
+}
+
+int TrackCanvas::help_transition_handles(int cursor_x, int cursor_y)
+{
+ if( !mwindow->edl->session->auto_conf->transitions )
+ return 0;
+ int result = 0;
+
+ Track *track = mwindow->edl->tracks->first;
+ for( ; track && !result; track=track->next) {
+ if( track->is_hidden() ) continue;
+ Edit *edit = track->edits->first;
+ for( ; edit && !result; edit=edit->next ) {
+ Transition *trans = edit->transition;
+ if( !trans ) continue;
+ int64_t x, y, w, h;
+ edit_dimensions(edit, x, y, w, h);
+ int strip_x = x, edit_y = y;
+ get_transition_coords(edit, x, y, w, h);
+ VFrame *strip = mwindow->theme->get_image("plugin_bg_data");
+ int strip_y = y - strip->get_h();
+ if( track->show_assets() && track->show_titles() )
+ edit_y += mwindow->theme->get_image("title_bg_data")->get_h();
+ if( strip_y < edit_y ) strip_y = edit_y;
+ int strip_w = Units::round(edit->track->from_units(edit->transition->length) *
+ mwindow->edl->session->sample_rate / mwindow->edl->local_session->zoom_sample);
+ int x1 = strip_x + strip_w - HANDLE_W/2, x2 = x1 + HANDLE_W;
+ int y1 = strip_y + strip->get_h()/2 - HANDLE_H/2, y2 = y1 + HANDLE_W;
+ if( cursor_x >= x1 && cursor_x < x2 &&
+ cursor_y >= y1 && cursor_y < y2 ) {
+ result = 1;
+ }
+ }
+ }
+
+ if( result ) {
+ context_help_show("Editing Effects");
+ }
+
+ return result;
+}
+
+int TrackCanvas::help_edit_handles(int cursor_x, int cursor_y)
+{
+ int result = 0;
+
+ for( Track *track=mwindow->edl->tracks->first; track && !result; track=track->next) {
+ if( track->is_hidden() ) continue;
+ for( Edit *edit=track->edits->first; edit && !result; edit=edit->next ) {
+ int64_t edit_x, edit_y, edit_w, edit_h;
+ edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
+
+ if( cursor_x >= edit_x && cursor_x <= edit_x + edit_w &&
+ cursor_y >= edit_y && cursor_y < edit_y + edit_h &&
+ ( cursor_x < edit_x + HANDLE_W ||
+ cursor_x >= edit_x + edit_w - HANDLE_W )) {
+ result = 1;
+ }
+ }
+ }
+
+ if( result ) {
+ context_help_show("Trimming");
+ }
+
+ return result;
+}
+
+int TrackCanvas::help_plugin_handles(int cursor_x, int cursor_y)
+{
+ int result = 0;
+
+ for(Track *track = mwindow->edl->tracks->first;
+ track && !result;
+ track = track->next) {
+ if( track->is_hidden() ) continue;
+ for(int i = 0; i < track->plugin_set.total && !result; i++) {
+ PluginSet *plugin_set = track->plugin_set.values[i];
+ for(Plugin *plugin = (Plugin*)plugin_set->first;
+ plugin && !result;
+ plugin = (Plugin*)plugin->next) {
+ int64_t plugin_x, plugin_y, plugin_w, plugin_h;
+ plugin_dimensions(plugin, plugin_x, plugin_y, plugin_w, plugin_h);
+
+ if(cursor_x >= plugin_x && cursor_x <= plugin_x + plugin_w &&
+ cursor_y >= plugin_y && cursor_y < plugin_y + plugin_h &&
+ (cursor_x < plugin_x + HANDLE_W ||
+ cursor_x >= plugin_x + plugin_w - HANDLE_W)) {
+ result = 1;
+ }
+ }
+ }
+ }
+
+ if(result) {
+ context_help_show("Editing Effects");
+ }
+
+ return result;
+}
+
+int TrackCanvas::help_plugins(int cursor_x, int cursor_y)
+{
+ int done = 0;
+ int64_t x, y, w, h;
+ Track *track = 0;
+ Plugin *plugin = 0;
+ char title[BCTEXTLEN];
+
+ // Detect, if any, the plugin under cursor
+ for(track = mwindow->edl->tracks->first; track && !done; track = track->next) {
+ if(!track->expand_view) continue;
+
+ for(int i = 0; i < track->plugin_set.total && !done; i++) {
+ // first check if plugins are visible at all
+ if (!track->expand_view)
+ continue;
+ PluginSet *plugin_set = track->plugin_set.values[i];
+ for(plugin = (Plugin*)plugin_set->first;
+ plugin && !done;
+ plugin = (Plugin*)plugin->next) {
+ plugin_dimensions(plugin, x, y, w, h);
+ if(MWindowGUI::visible(x, x + w, 0, get_w()) &&
+ MWindowGUI::visible(y, y + h, 0, get_h())) {
+ if(cursor_x >= x && cursor_x < x + w &&
+ cursor_y >= y && cursor_y < y + h) {
+ done = 1;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // If plugin found, display its context help
+ if(plugin) {
+ strcpy(title, plugin->title);
+ if(! strcmp(title, "Overlay"))
+ // "Overlay" plugin title is ambiguous
+ switch(plugin->track->data_type)
+ {
+ case TRACK_AUDIO:
+ strcat(title, " \\(Audio\\)");
+ break;
+ case TRACK_VIDEO:
+ strcat(title, " \\(Video\\)");
+ break;
+ }
+ if(! strncmp(title, "F_", 2))
+ // FFmpeg plugins can be audio or video
+ switch(plugin->track->data_type)
+ {
+ case TRACK_AUDIO:
+ strcpy(title, "FFmpeg Audio Plugins");
+ break;
+ case TRACK_VIDEO:
+ strcpy(title, "FFmpeg Video Plugins");
+ break;
+ }
+ context_help_show(title);
+ return 1;
+ }
+
return 0;
}
+// *** END_CONTEXT_HELP ***
int TrackCanvas::cursor_leave_event()
{
Track **over_track, Edit **over_edit,
PluginSet **over_pluginset, Plugin **over_plugin)
{
+ int update_scroll = 0;
int cursor_x = get_relative_cursor_x();
int cursor_y = get_relative_cursor_y();
if( get_cursor_over_window() ) {
}
if( over_track && !*over_track )
*over_track = pane->over_patchbay();
+
+ switch( mwindow->session->current_operation ) {
+ case DRAG_EDIT_SELECT: {
+ Edit *edit = over_edit ? *over_edit : 0;
+ double position = mwindow->edl->get_cursor_position(cursor_x, pane->number);
+ mwindow->session->drag_position = mwindow->edl->align_to_frame(position, 0);
+ drag_edit_select(edit, 0, 1);
+ update_scroll = 1;
+ break; }
+ }
+
+ if( update_scroll ) {
+ if( !drag_scroll &&
+ (cursor_x >= get_w() || cursor_x < 0 ||
+ cursor_y >= get_h() || cursor_y < 0))
+ start_dragscroll();
+ else if( drag_scroll &&
+ cursor_x < get_w() && cursor_x >= 0 &&
+ cursor_y < get_h() && cursor_y >= 0 )
+ stop_dragscroll();
+ }
+
return 0;
}
result = 1;
}
break;
- case DRAG_GROUP:
+ case DRAG_GROUP: {
mwindow->session->current_operation = NO_OPERATION;
EDL *drag_group = mwindow->session->drag_group;
if( drag_group ) {
}
}
result = 1;
+ break; }
+ case DRAG_EDIT_SELECT:
+ int select = ctrl_down() ? -1 : 1;
+ drag_edit_select(mwindow->session->edit_highlighted, select, 0);
break;
}
}
+ switch( mwindow->session->current_operation ) {
+ case DRAG_EDIT_SELECT:
+ mwindow->session->current_operation = NO_OPERATION;
+ result = 1;
+ break;
+ }
+
return result;
}
resource_timer->update();
+ if(!indexes_only) {
// Age resource pixmaps for deletion
- if(!indexes_only)
for(int i = 0; i < gui->resource_pixmaps.total; i++)
gui->resource_pixmaps.values[i]->visible--;
-
- if(mode == FORCE_REDRAW)
- gui->resource_pixmaps.remove_all_objects();
-
+ }
if(debug) PRINT_TRACE
if(mode != IGNORE_THREAD)
gui->resource_thread->reset(pane->number, indexes_only);
if(!result)
{
//SET_TRACE
- result = new ResourcePixmap(mwindow,
- gui,
- edit,
- pane->number,
- pixmap_w,
- pixmap_h);
+ result = new ResourcePixmap(mwindow, gui, edit, pane->number, pixmap_w, pixmap_h);
+ set_bg_color(BLACK);
+ clear_box(0,0, pixmap_w,pixmap_h, result);
//SET_TRACE
gui->resource_pixmaps.append(result);
}
}
break;
+ case DRAG_SPEED:
+ draw_speed_highlight();
+ break;
}
if( draw_box )
draw_selected_edits(mwindow->edl, 0, 0, GREEN+BLUE, RED);
}
+void TrackCanvas::draw_speed_highlight()
+{
+ FloatAuto *drag_speed = (FloatAuto*)mwindow->session->drag_auto;
+ if( !drag_speed ) return;
+ draw_speed_track(drag_speed->autos->track);
+ ArrayList<Auto*> &speed_gang = *mwindow->session->drag_auto_gang;
+ for( int i=0, sz=speed_gang.size(); i<sz; ++i ) {
+ Track *track = speed_gang[i]->autos->track;
+ if( track->is_hidden() ) continue;
+ draw_speed_track(track);
+ }
+}
+
+void TrackCanvas::draw_speed_track(Track *track)
+{
+ for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+ int64_t x, y, w, h;
+ edit_dimensions(edit, x, y, w, h);
+ if( !MWindowGUI::visible(x, x + w, 0, get_w()) ) continue;
+ if( !MWindowGUI::visible(y, y + h, 0, get_h()) ) continue;
+ int color = 0xc00cc0;
+ set_color(color);
+ set_opaque();
+ draw_selected(x, y, w, h);
+ }
+}
+
// x does not reliably draw a really big rectangle
void TrackCanvas::draw_selected(int x, int y, int w, int h)
{
void TrackCanvas::draw_drag_handle()
{
if( mwindow->session->current_operation != DRAG_EDITHANDLE2 &&
- mwindow->session->current_operation != DRAG_PLUGINHANDLE2 ) return;
+ mwindow->session->current_operation != DRAG_PLUGINHANDLE2 &&
+ mwindow->session->current_operation != DRAG_TRANSNHANDLE2 ) return;
int64_t pixel1 = Units::round(mwindow->session->drag_position *
mwindow->edl->session->sample_rate /
mwindow->edl->local_session->zoom_sample -
void TrackCanvas::draw_transitions()
{
int64_t x, y, w, h;
+ if( !mwindow->edl->session->auto_conf->transitions ) return;
for(Track *track = mwindow->edl->tracks->first; track; track = track->next) {
if( track->is_hidden() ) continue;
// track context menu to appear
int result = 0;
EDLSession *session = mwindow->edl->session;
- int gang = session->gang_tracks != GANG_NONE || get_double_click() ? 1 : 0;
+ int gang = mwindow->edl->local_session->gang_tracks != GANG_NONE ||
+ get_double_click() ? 1 : 0;
static BC_Pixmap *auto_pixmaps[AUTOMATION_TOTAL] =
{
auto_keyframe, grouptype);
if( !result && buttonpress && i == AUTOMATION_SPEED )
- mwindow->speed_after(-1);
+ mwindow->speed_after(-1, 0);
if( result && buttonpress ) {
int color = GWindowGUI::auto_colors[i];
mwindow->gui->zoombar->update_autozoom(grouptype, color);
int edge = patch ? patch->edge : 0;
int span = patch ? patch->span : 0;
for(Track *current = mwindow->edl->tracks->first; current; current = NEXT) {
- if( (gang || current->data_type == skip->data_type) &&
- current->armed_gang(skip) && current->is_armed() &&
- current != skip ) {
+ if( current == skip || !current->is_armed() ) continue;
+ if( !gang && current->data_type != skip->data_type ) continue;
+ if( skip->armed_gang(current) || get_double_click() ) {
FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[autoidx];
FloatAuto *keyframe = (FloatAuto*)fade_autos->get_auto_at_position(position);
int64_t current_position = current->to_units(position, 1);
// keyframe exists, just change it
keyframe->bump_update(current_position, change, edge, span);
}
- else if( gang >= 0 && ( get_double_click() ||
- mwindow->edl->session->auto_keyframes ) ) {
+ else if( gang >= 0 ) {
// create keyframe on neighbouring track at the point in time given by fauto
FloatAuto *previous = 0, *next = 0;
float value = fade_autos->get_value(current_position, PLAY_FORWARD, previous, next);
double new_position;
int cursor_x = get_cursor_x();
- new_position =
- (double)(cursor_x +
- mwindow->edl->local_session->view_start[pane->number]) *
- mwindow->edl->local_session->zoom_sample /
- mwindow->edl->session->sample_rate;
-
- new_position =
- mwindow->edl->align_to_frame(new_position, 0);
+ new_position = mwindow->edl->get_cursor_position(cursor_x, pane->number);
+ new_position = mwindow->edl->align_to_frame(new_position, 0);
if( ctrl_down() && alt_down() ) {
#define snapper(v) do { \
case 0: {
VFrame vlt(edl->get_w(), edl->get_h(), edl->session->color_model);
VFrame vrt(edl->get_w(), edl->get_h(), edl->session->color_model);
- TransportCommand command;
+ TransportCommand command(mwindow->preferences);
command.command = CURRENT_FRAME;
command.get_edl()->copy_all((EDL *)edl);
command.change_type = CHANGE_ALL;
}
+void TrackCanvas::drag_edit_select(Edit *over_edit, int select, int draw)
+{
+ if( !over_edit ) return;
+ if( !mwindow->session->drag_edit ) return;
+ Track *drag_track = mwindow->session->drag_edit->track;
+ Track *over_track = over_edit->track;
+ if( !drag_track || !over_track ) return;
+ if( drag_track->number_of() > over_track->number_of() ) {
+ Track *trk = drag_track;
+ drag_track = over_track;
+ over_track = trk;
+ }
+ double start_pos = mwindow->session->drag_start;
+ double end_pos = mwindow->session->drag_position;
+ if( start_pos > end_pos ) {
+ double pos = start_pos;
+ start_pos = end_pos;
+ end_pos = pos;
+ }
+ int done = 0, do_flash = 0;
+ for( Track *track=drag_track; !done; track=track->next ) {
+ if( !track->is_armed() ) continue;
+ for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+ int64_t pos = edit->startproject;
+ int64_t end = pos + edit->length;
+ double edit_start = track->from_units(pos);
+ double edit_end = track->from_units(end);
+ if( start_pos >= edit_end ) continue;
+ if( edit_start > end_pos ) continue;
+ if( select > 0 )
+ edit->is_selected = 1;
+ else if( select < 0 )
+ edit->is_selected = 0;
+ if( draw ) {
+ int64_t edit_x, edit_y, edit_w, edit_h;
+ edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
+ set_color(YELLOW);
+ draw_rectangle(edit_x, edit_y, edit_w, edit_h);
+ do_flash = 1;
+ }
+ }
+ if( track == over_track ) done = 1;
+ }
+ if( do_flash )
+ flash();
+}
+
int TrackCanvas::cursor_update(int in_motion)
{
int update_cursor = 0;
int rerender = 0;
double position = 0.;
-//printf("TrackCanvas::cursor_update %d\n", __LINE__);
+//printf("TrackCanvas::cursor_update %d %d,%d\n", __LINE__, get_cursor_x(), get_cursor_y());
// Default cursor
int new_cursor =
{
case DRAG_EDITHANDLE1:
// Outside threshold. Upgrade status
- if(active)
- {
- if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
- {
- mwindow->session->current_operation = DRAG_EDITHANDLE2;
- update_overlay = 1;
- }
+ if( !active ) break;
+ if( labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W ) {
+ mwindow->session->current_operation = DRAG_EDITHANDLE2;
+ update_overlay = 1;
}
break;
-
case DRAG_EDITHANDLE2:
- if(active)
- {
- update_drag_handle();
- update_overlay = 1;
- }
+ if( !active ) break;
+ update_drag_handle();
+ update_overlay = 1;
break;
case DRAG_PLUGINHANDLE1:
- if(active)
- {
- if(labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W)
- {
- mwindow->session->current_operation = DRAG_PLUGINHANDLE2;
- update_overlay = 1;
- }
+ if( !active ) break;
+ if( labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W ) {
+ mwindow->session->current_operation = DRAG_PLUGINHANDLE2;
+ update_overlay = 1;
}
break;
-
case DRAG_PLUGINHANDLE2:
- if(active)
- {
- update_drag_handle();
+ if( !active ) break;
+ update_drag_handle();
+ update_overlay = 1;
+ break;
+
+ case DRAG_TRANSNHANDLE1:
+ if( !active ) break;
+ if( labs(get_cursor_x() - mwindow->session->drag_origin_x) > HANDLE_W ) {
+ mwindow->session->current_operation = DRAG_TRANSNHANDLE2;
update_overlay = 1;
}
break;
+ case DRAG_TRANSNHANDLE2: {
+ if( !active ) break;
+ position = mwindow->edl->get_cursor_position(get_cursor_x(), pane->number);
+ position = mwindow->edl->align_to_frame(position, 1);
+ drag_transition_handle(position);
+ rerender = 1;
+ update_overlay = 1;
+ break; }
// Rubber band curves
case DRAG_FADE:
if(active) rerender = update_overlay =
update_drag_floatauto(get_cursor_x(), get_cursor_y());
if( rerender && mwindow->session->current_operation == DRAG_SPEED )
- mwindow->speed_after(!in_motion ? 1 : 0);
+ mwindow->speed_after(!in_motion ? 1 : 0, 0);
break;
case DRAG_PLAY:
0, new_cursor, update_cursor)) break;
if(do_keyframes(get_cursor_x(), get_cursor_y(),
0, 0, new_cursor, update_cursor, rerender)) break;
+ if(do_transition_handles(get_cursor_x(), get_cursor_y(),
+ 0, rerender, update_overlay, new_cursor, update_cursor)) break;
if(do_edit_handles(get_cursor_x(), get_cursor_y(),
0, rerender, update_overlay, new_cursor, update_cursor)) break;
// Plugin boundaries
int result = 0;
switch(mwindow->session->current_operation) {
+ case DRAG_EDIT_SELECT:
case SELECT_REGION:
//printf("TrackCanvas::repeat_event 1 %d\n", mwindow->edl->local_session->view_start);
if(get_cursor_x() > get_w()) {
result = 1;
break;
+ case DRAG_TRANSNHANDLE2:
+ mwindow->session->current_operation = NO_OPERATION;
+ drag_scroll = 0;
+ result = 1;
+
+ end_transnhandle_selection();
+ break;
+
+ case DRAG_TRANSNHANDLE1:
+ mwindow->session->current_operation = NO_OPERATION;
+ drag_scroll = 0;
+ result = 1;
+ break;
+
case DRAG_SPEED:
redraw = FORCE_REDRAW;
- load_flags |= LOAD_EDITS;
+ load_flags |= LOAD_EDITS | LOAD_TIMEBAR;
case DRAG_FADE:
// delete the drag_auto_gang first and remove out of order keys
clear_ganged_autos();
drag_scroll = 0;
break; }
+ case DRAG_EDIT_SELECT:
+ //result = 0;
+ break;
+
default:
if( mwindow->session->current_operation ) {
// if(mwindow->session->current_operation == SELECT_REGION) {
return result;
}
+int TrackCanvas::do_transition_handles(int cursor_x, int cursor_y, int button_press,
+ int &rerender, int &update_overlay, int &new_cursor, int &update_cursor)
+{
+ if( !mwindow->edl->session->auto_conf->transitions )
+ return 0;
+ Transition *trans_result = 0;
+ int result = 0;
+
+ Track *track = mwindow->edl->tracks->first;
+ for( ; track && !result; track=track->next) {
+ if( track->is_hidden() ) continue;
+ Edit *edit = track->edits->first;
+ for( ; edit && !result; edit=edit->next ) {
+ Transition *trans = edit->transition;
+ if( !trans ) continue;
+ int64_t x, y, w, h;
+ edit_dimensions(edit, x, y, w, h);
+ int strip_x = x, edit_y = y;
+ get_transition_coords(edit, x, y, w, h);
+ VFrame *strip = mwindow->theme->get_image("plugin_bg_data");
+ int strip_y = y - strip->get_h();
+ if( track->show_assets() && track->show_titles() )
+ edit_y += mwindow->theme->get_image("title_bg_data")->get_h();
+ if( strip_y < edit_y ) strip_y = edit_y;
+ int strip_w = Units::round(edit->track->from_units(edit->transition->length) *
+ mwindow->edl->session->sample_rate / mwindow->edl->local_session->zoom_sample);
+ int x1 = strip_x + strip_w - HANDLE_W/2, x2 = x1 + HANDLE_W;
+ int y1 = strip_y + strip->get_h()/2 - HANDLE_H/2, y2 = y1 + HANDLE_W;
+ if( cursor_x >= x1 && cursor_x < x2 &&
+ cursor_y >= y1 && cursor_y < y2 ) {
+ trans_result = trans;
+ result = 1;
+ }
+ }
+ }
+
+ if( result ) {
+ if( button_press ) {
+ mwindow->session->drag_transition = trans_result;
+ mwindow->session->drag_handle = 1;
+ mwindow->session->drag_button = get_buttonpress() - 1;
+ int64_t trans_end = trans_result->edit->startproject + trans_result->length;
+ double position = trans_result->edit->track->from_units(trans_end);
+ mwindow->session->drag_position = position;
+ mwindow->session->drag_start = position;
+ mwindow->session->current_operation = DRAG_TRANSNHANDLE1;
+ mwindow->session->drag_origin_x = get_cursor_x();
+ mwindow->session->drag_origin_y = get_cursor_y();
+ update_cursor = 1;
+ }
+ new_cursor = RIGHT_CURSOR;
+ update_overlay = 1;
+ }
+
+ return result;
+}
+
+int TrackCanvas::drag_transition_handle(double position)
+{
+ Transition *transition = mwindow->session->drag_transition;
+ if( !transition ) return 1;
+ mwindow->session->drag_position = position;
+ mwindow->edl->local_session->set_selectionstart(position);
+ mwindow->edl->local_session->set_selectionend(position);
+ char string[BCSTRLEN];
+ int64_t length = transition->length;
+ Track *track = transition->edit->track;
+ int64_t start_pos = track->to_units(mwindow->session->drag_start, 0);
+ int64_t end_pos = track->to_units(mwindow->session->drag_position, 0);
+ length += end_pos - start_pos;
+ if( length < 0 ) length = 0;
+ double time = track->from_units(length);
+ Units::totext(string, time,
+ mwindow->edl->session->time_format,
+ mwindow->edl->session->sample_rate,
+ mwindow->edl->session->frame_rate,
+ mwindow->edl->session->frames_per_foot);
+ mwindow->gui->show_message(string);
+ if( mwindow->gui->transition_menu->length_thread->running() ) {
+ TransitionLengthDialog *dialog = (TransitionLengthDialog *)
+ mwindow->gui->transition_menu->length_thread->get_gui();
+ if( dialog ) {
+ dialog->lock_window("TrackCanvas::drag_transition_handle");
+ dialog->update_text(time);
+ dialog->thread->new_length = time;
+ dialog->unlock_window();
+ }
+ }
+ return 0;
+}
+
int TrackCanvas::do_tracks(int cursor_x, int cursor_y, int button_press)
{
mwindow->session->drag_origin_x = cursor_x;
mwindow->session->drag_origin_y = cursor_y;
// Where the drag started, so we know relative position inside the edit later
- mwindow->session->drag_position =
- mwindow->edl->get_cursor_position(cursor_x, pane->number);
+ double position = mwindow->edl->get_cursor_position(cursor_x, pane->number);
+ mwindow->session->drag_position = mwindow->edl->align_to_frame(position, 1);
+ if( get_buttonpress() == LEFT_BUTTON && alt_down() ) {
+ mwindow->session->drag_start = mwindow->session->drag_position;
+ drag_edit_select(edit, 0, 1);
+ mwindow->session->current_operation = DRAG_EDIT_SELECT;
+ result = 1;
+ continue;
+ }
drag_start = 0; // if unselected "fast" drag
if( !edit->silence() && !edit->is_selected ) {
mwindow->edl->tracks->clear_selected_edits();
0, get_buttonpress(), new_cursor,
update_cursor, rerender) ) break;
update_message = 1;
+
+ if( do_transition_handles(cursor_x, cursor_y,
+ 1, rerender, update_overlay, new_cursor,
+ update_cursor) ) break;
// Test edit boundaries
if( do_edit_handles(cursor_x, cursor_y,
1, rerender, update_overlay, new_cursor,
break;
}
update_message = 1;
+ if( do_transition_handles(cursor_x, cursor_y,
+ 1, rerender, update_overlay, new_cursor, update_cursor) ) break;
// Test edit boundaries
if( do_edit_handles(cursor_x, cursor_y,
1, rerender, update_overlay, new_cursor, update_cursor) ) break;
void TrackCanvas::end_edithandle_selection()
{
mwindow->modify_edithandles();
+ mwindow->session->drag_edit = 0;
}
void TrackCanvas::end_pluginhandle_selection()
{
mwindow->modify_pluginhandles();
+ mwindow->session->drag_plugin = 0;
+}
+
+void TrackCanvas::end_transnhandle_selection()
+{
+ mwindow->modify_transnhandles();
+ mwindow->session->drag_transition = 0;
}