#include "bctimer.h"
#include "clip.h"
#include "bccolors.h"
+#include "cache.h"
+#include "canvas.h"
#include "cplayback.h"
#include "cursors.h"
#include "cwindowgui.h"
#include "pluginset.h"
#include "plugintoggles.h"
#include "preferences.h"
+#include "renderengine.h"
#include "resourcepixmap.h"
#include "resourcethread.h"
#include "swindow.h"
#include "transportque.h"
#include "vframe.h"
#include "vpatchgui.inc"
+#include "vrender.h"
#include "zoombar.h"
#include <string.h>
if (buttonpress != 3)
{
if(i == AUTOMATION_FADE || i == AUTOMATION_SPEED)
- synchronize_autos(0,
- track,
- (FloatAuto*)mwindow->session->drag_auto,
- 1);
+ fill_ganged_autos(get_double_click(), 0, track,
+ (FloatAuto*)mwindow->session->drag_auto);
mwindow->session->current_operation = pre_auto_operations[i];
update_drag_caption();
rerender = 1;
int current_op = mwindow->session->current_operation, dragging = 0;
for( int i=0; !dragging && i<AUTOMATION_TOTAL; ++i )
if( current_op == auto_operations[i] ) dragging = 1;
+ if( dragging && !mwindow->session->drag_auto ) dragging = 0;
- if( keyframe_hairline == HAIRLINE_DRAGGING && dragging ) {
- if( mwindow->session->drag_auto && get_buttonpress() == 1 ) {
- draw_hairline(mwindow->session->drag_auto, RED);
- return;
- }
+ int autoidx = dragging && keyframe_hairline != HAIRLINE_ALWAYS ?
+ mwindow->session->drag_auto->autos->autoidx : -1;
+
+ if( get_buttonpress() == 1 && dragging &&
+ keyframe_hairline == HAIRLINE_DRAGGING ) {
+ draw_hairline(mwindow->session->drag_auto, RED, 1);
+ return;
}
if( keyframe_hairline == HAIRLINE_ALWAYS || ( get_buttonpress() == 2 &&
keyframe_hairline == HAIRLINE_DRAGGING && dragging ) ) {
- for( Track *track = mwindow->edl->tracks->first; track;
- track=track->next ) {
+ int show = dragging || keyframe_hairline == HAIRLINE_ALWAYS ? 1 : 0;
+ for( Track *track = mwindow->edl->tracks->first; track; track=track->next ) {
Automation *automation = track->automation;
for( int i=0; i<AUTOMATION_TOTAL; ++i ) {
if( !mwindow->edl->session->auto_conf->autos[i] ) continue;
// automation visible
Autos *autos = automation->autos[i];
if( !autos ) continue;
+ if( autoidx >= 0 && autos->autoidx != autoidx ) continue;
for( Auto *auto_keyframe=autos->first; auto_keyframe;
auto_keyframe = auto_keyframe->next ) {
- draw_hairline(auto_keyframe, BLUE);
+ draw_hairline(auto_keyframe, BLUE, show);
}
}
-
- if( dragging && mwindow->session->drag_auto ) {
- draw_hairline(mwindow->session->drag_auto, RED);
- }
}
+
+ if( dragging )
+ draw_hairline(mwindow->session->drag_auto, RED, 1);
}
}
}
-void TrackCanvas::synchronize_autos(float change,
- Track *skip, FloatAuto *fauto, int fill_gangs)
+void TrackCanvas::fill_ganged_autos(int all, float change, Track *skip, FloatAuto *fauto)
{
+ if( !skip->gang ) return;
// Handles the special case of modifying a fadeauto
// when there are ganged faders on several tracks
-// (skip and fauto may be NULL if fill_gangs==-1)
-
- if( fill_gangs > 0 && skip->gang ) {
- double position = skip->from_units(fauto->position);
- int autoidx = fauto->autos->autoidx;
-
- for(Track *current = mwindow->edl->tracks->first; current; current = NEXT) {
- if( (current->data_type == skip->data_type || get_double_click()) &&
- current->gang && current->record && current != skip ) {
- int64_t current_position = current->to_units(position, 1);
- FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[autoidx];
- float auto_min = mwindow->edl->local_session->automation_mins[fade_autos->autogrouptype];
- float auto_max = mwindow->edl->local_session->automation_maxs[fade_autos->autogrouptype];
- FloatAuto *previous = 0, *next = 0;
- FloatAuto *keyframe = (FloatAuto*)fade_autos->get_auto_at_position(current_position);
- if( !keyframe ) {
-// create keyframe on neighbouring track at the point in time given by fauto
- float init_value = fade_autos->get_value(current_position, PLAY_FORWARD, previous, next);
- float new_value = init_value + change;
- CLAMP(new_value, auto_min, auto_max);
- keyframe = (FloatAuto*)fade_autos->insert_auto(current_position);
- keyframe->set_value(new_value);
- }
- else {
+ double position = skip->from_units(fauto->position);
+ int autoidx = fauto->autos->autoidx;
+
+ for(Track *current = mwindow->edl->tracks->first; current; current = NEXT) {
+ if( (all || current->data_type == skip->data_type) &&
+ current->gang && current->record && current != skip ) {
+ FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[autoidx];
+ float auto_min = mwindow->edl->local_session->automation_mins[fade_autos->autogrouptype];
+ float auto_max = mwindow->edl->local_session->automation_maxs[fade_autos->autogrouptype];
+ int64_t current_position = current->to_units(position, 1);
+ FloatAuto *keyframe = (FloatAuto*)fade_autos->get_auto_at_position(position);
+ if( keyframe ) {
// keyframe exists, just change it
- float new_value = keyframe->get_value() + change;
- CLAMP(new_value, auto_min, auto_max);
- keyframe->adjust_to_new_coordinates(current_position, new_value);
-// need to (re)set the position, as the existing node could be on a "equivalent" position (within half a frame)
- }
-
- mwindow->session->drag_auto_gang->append((Auto *)keyframe);
+ float value = keyframe->get_value();
+ float new_value = value + change;
+ CLAMP(new_value, auto_min, auto_max);
+ keyframe->adjust_to_new_coordinates(current_position, new_value);
}
+ else if( mwindow->edl->session->auto_keyframes ) {
+// 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);
+ float new_value = value + change;
+ CLAMP(new_value, auto_min, auto_max);
+ keyframe = (FloatAuto*)fade_autos->insert_auto(current_position);
+ keyframe->set_value(new_value);
+ }
+ else
+ continue;
+ mwindow->session->drag_auto_gang->append((Auto *)keyframe);
}
}
- else if( !fill_gangs ) {
- double position = skip->from_units(fauto->position);
-// Move the gangs
- for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++) {
- FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
- int64_t keyframe_position = keyframe->autos->track->to_units(position, 1);
- float new_value = keyframe->get_value() + change;
- CLAMP(new_value,
- mwindow->edl->local_session->automation_mins[keyframe->autos->autogrouptype],
- mwindow->edl->local_session->automation_maxs[keyframe->autos->autogrouptype]);
- keyframe->adjust_to_new_coordinates(keyframe_position, new_value);
- }
+}
+void TrackCanvas::update_ganged_autos(float change, Track *skip, FloatAuto *fauto)
+{
+ double position = skip->from_units(fauto->position);
+// Move the gangs
+ for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++) {
+ FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
+ int64_t keyframe_position = keyframe->autos->track->to_units(position, 1);
+ float new_value = keyframe->get_value() + change;
+ CLAMP(new_value,
+ mwindow->edl->local_session->automation_mins[keyframe->autos->autogrouptype],
+ mwindow->edl->local_session->automation_maxs[keyframe->autos->autogrouptype]);
+ keyframe->adjust_to_new_coordinates(keyframe_position, new_value);
}
- else {
+}
+
+void TrackCanvas::clear_ganged_autos()
+{
// remove the gangs
- for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++) {
- FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
- keyframe->autos->remove_nonsequential(
- keyframe);
- }
- mwindow->session->drag_auto_gang->remove_all();
+ for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++) {
+ FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
+ keyframe->autos->remove_nonsequential(keyframe);
}
+ mwindow->session->drag_auto_gang->remove_all();
}
return result;
}
-int TrackCanvas::draw_hairline(Auto *auto_keyframe, int color)
+int TrackCanvas::draw_hairline(Auto *auto_keyframe, int color, int show)
{
Track *track = auto_keyframe->autos->track;
- int autogrouptype = auto_keyframe->autos->get_type();
+ int autogrouptype = auto_keyframe->autos->autogrouptype;
int center_pixel;
double view_start, unit_start;
set_color(color);
draw_line(ax, 0, ax, get_h());
+
+ if( show ) {
+ char text[BCSTRLEN];
+ if( auto_keyframe->is_floatauto() ) {
+ FloatAuto *float_auto = (FloatAuto *)auto_keyframe;
+ sprintf(text, "%0.2f", float_auto->get_value());
+ }
+ else {
+ IntAuto *int_auto = (IntAuto *)auto_keyframe;
+ sprintf(text, "%d", int_auto->value);
+ }
+ int font = MEDIUMFONT;
+ int tw = get_text_width(font, text) + TOOLTIP_MARGIN * 2;
+ int th = get_text_height(font, text) + TOOLTIP_MARGIN * 2;
+ set_color(get_resources()->tooltip_bg_color);
+ ax += HANDLE_W/2;
+ ay += center_pixel + HANDLE_W/2;
+ draw_box(ax, ay, tw, th);
+ set_color(BLACK);
+ draw_rectangle(ax, ay, tw, th);
+ set_font(font);
+ ax += TOOLTIP_MARGIN;
+ ay += TOOLTIP_MARGIN + get_text_ascent(font);
+ draw_text(ax, ay, text);
+ }
return 0;
}
{
mwindow->session->drag_position = new_position;
gui->mainclock->update(new_position);
-
-
timebar_position = new_position;
gui->update_timebar(0);
-// Que the CWindow. Doesn't do anything if selectionstart and selection end
-// aren't changed.
-// mwindow->cwindow->update(1, 0, 0);
+
+ EDL *edl = new EDL;
+ edl->create_objects();
+ edl->copy_all(mwindow->edl);
+ MainSession *session = mwindow->session;
+ int edit_mode = mwindow->edl->session->edit_handle_mode[session->drag_button];
+ edl->modify_edithandles(session->drag_start,
+ session->drag_position,
+ session->drag_handle,
+ edit_mode,
+ edl->session->labels_follow_edits,
+ edl->session->plugins_follow_edits,
+ edl->session->autos_follow_edits);
+ double position = edit_mode != MOVE_NO_EDITS &&
+ ( session->drag_handle || edit_mode == MOVE_ONE_EDIT ) ?
+ session->drag_position : session->drag_start;
+ Track *track = session->drag_handle_track();
+ int64_t pos = track->to_units(position, 0);
+ render_handle_frame(edl, pos, shift_down() ? 0 :
+ session->drag_handle ? 1 : 2);
+ edl->remove_user();
}
}
+int TrackCanvas::render_handle_frame(EDL *edl, int64_t pos, int mode)
+{
+ int result = 0;
+ int64_t left = pos-1;
+ if( left < 0 ) left = 0;
+ switch( mode ) {
+ 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;
+ command.command = CURRENT_FRAME;
+ command.get_edl()->copy_all((EDL *)edl);
+ command.change_type = CHANGE_ALL;
+ command.realtime = 0;
+ Preferences *preferences = mwindow->preferences;
+ RenderEngine *render_engine = new RenderEngine(0, preferences, 0, 0);
+ CICache *video_cache = new CICache(preferences);
+ render_engine->set_vcache(video_cache);
+ render_engine->arm_command(&command);
+ int64_t left = pos-1;
+ if( left < 0 ) left = 0;
+ VRender *vrender = render_engine->vrender;
+ result = vrender &&
+ !vrender->process_buffer(&vlt, left, 0) &&
+ !vrender->process_buffer(&vrt, pos , 0) ? 0 : 1;
+ delete render_engine;
+ delete video_cache;
+ mwindow->cwindow->gui->lock_window("TrackCanvas::render_handle_frame 0");
+ Canvas *canvas = mwindow->cwindow->gui->canvas;
+ canvas->lock_canvas("TrackCanvas::render_handle_frame 1");
+ int w = canvas->w, h = canvas->h, w2 = w/2, h2 = h/2;
+ int lx = 0, ly = h2/2, rx = w2, ry = h2/2;
+ BC_WindowBase *window = canvas->get_canvas();
+ window->set_color(BLACK);
+ window->clear_box(0,0, window->get_w(),window->get_h());
+ window->draw_vframe(&vlt, lx,ly, w2,h2, 0,0,vlt.get_w(),vlt.get_h());
+ window->draw_vframe(&vrt, rx,ry, w2,h2, 0,0,vrt.get_w(),vrt.get_h());
+ window->flash(1);
+ canvas->unlock_canvas();
+ mwindow->cwindow->gui->unlock_window();
+ break; }
+ case 1:
+ case 2: {
+ Track *track = mwindow->session->drag_handle_track();
+ double position = track->from_units(mode == 1 ? left : pos);
+ if( position < 0 ) position = 0;
+ edl->local_session->set_selectionstart(position);
+ edl->local_session->set_selectionend(position);
+ PlaybackEngine *playback_engine = mwindow->cwindow->playback_engine;
+ if( playback_engine->is_playing_back )
+ playback_engine->stop_playback(1);
+ mwindow->cwindow->playback_engine->refresh_frame(CHANGE_EDL, edl, 0);
+ break; }
+ }
+ return result;
+}
+
int TrackCanvas::update_drag_edit()
{
int result = 0;
result = 1;
float change = value - old_value;
current->adjust_to_new_coordinates(position, value);
- synchronize_autos(change, current->autos->track, current, 0);
+ update_ganged_autos(change, current->autos->track, current);
show_message(current, 1,", %.2f", current->get_value());
}
break;
current->set_control_in_value(
value * levered_position(position - current->position,
current->get_control_in_position()));
- synchronize_autos(0, current->autos->track, current, 0);
+ update_ganged_autos(0, current->autos->track, current);
show_message(current, 1,", %.2f", current->get_control_in_value());
}
break; }
current->set_control_out_value(
value * levered_position(position - current->position,
current->get_control_out_position()));
- synchronize_autos(0, current->autos->track, current, 0);
+ update_ganged_autos(0, current->autos->track, current);
show_message(current, 1,", %.2f", current->get_control_out_value());
}
break; }
load_flags |= LOAD_EDITS;
case DRAG_FADE:
// delete the drag_auto_gang first and remove out of order keys
- synchronize_autos(0, 0, 0, -1);
+ clear_ganged_autos();
case DRAG_CZOOM:
case DRAG_PZOOM:
case DRAG_PLAY:
int result = 0;
for( Track *track=mwindow->edl->tracks->first; track && !result; track=track->next) {
- if( !track->show_assets() ) 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 + HANDLE_W ) {
edit_result = edit;
handle_result = 0;
- if( cursor_y >= edit_y+edit_h - HANDLE_W ) {
+ if( cursor_y >= edit_y+edit_h - HANDLE_W &&
+ track->show_assets() ) {
new_cursor = DOWNLEFT_RESIZE;
if( button_press == LEFT_BUTTON )
result = -1;
else if( cursor_x >= edit_x + edit_w - HANDLE_W ) {
edit_result = edit;
handle_result = 1;
- if( cursor_y >= edit_y+edit_h - HANDLE_W ) {
+ if( cursor_y >= edit_y+edit_h - HANDLE_W &&
+ track->show_assets() ) {
new_cursor = DOWNRIGHT_RESIZE;
if( button_press == LEFT_BUTTON )
result = -1;
update_overlay = 1;
}
}
- else if( result < 0) {
+ else if( result < 0 ) {
mwindow->undo->update_undo_before();
if( !shift_down() ) {
if( handle_result == 0 )
int result = 0;
for(Track *track = mwindow->edl->tracks->first; track && !result; track = track->next) {
- if( !track->show_assets() ) 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);