00001 #include "autoconf.h"
00002 #include "automation.h"
00003 #include "edl.h"
00004 #include "edlsession.h"
00005 #include "floatauto.h"
00006 #include "floatautos.h"
00007 #include "intauto.h"
00008 #include "intautos.h"
00009 #include "language.h"
00010 #include "localsession.h"
00011 #include "mainsession.h"
00012 #include "mainundo.h"
00013 #include "mwindow.h"
00014 #include "mwindowgui.h"
00015 #include "overlayframe.inc"
00016 #include "patchbay.h"
00017 #include "theme.h"
00018 #include "trackcanvas.h"
00019 #include "vpatchgui.h"
00020 #include "vtrack.h"
00021
00022 #include <string.h>
00023
00024
00025
00026
00027
00028 VPatchGUI::VPatchGUI(MWindow *mwindow, PatchBay *patchbay, VTrack *track, int x, int y)
00029 : PatchGUI(mwindow, patchbay, track, x, y)
00030 {
00031 data_type = TRACK_VIDEO;
00032 this->vtrack = track;
00033 mode = 0;
00034 fade = 0;
00035 }
00036
00037 VPatchGUI::~VPatchGUI()
00038 {
00039 if(fade) delete fade;
00040 if(mode) delete mode;
00041 }
00042
00043 int VPatchGUI::create_objects()
00044 {
00045 return update(x, y);
00046 }
00047
00048 int VPatchGUI::reposition(int x, int y)
00049 {
00050 int x1 = 0;
00051 int y1 = PatchGUI::reposition(x, y);
00052
00053 if(fade) fade->reposition_window(fade->get_x(),
00054 y1 + y);
00055
00056 y1 += mwindow->theme->fade_h;
00057
00058 if(mode) mode->reposition_window(mode->get_x(),
00059 y1 + y);
00060
00061 if(nudge) nudge->reposition_window(nudge->get_x(),
00062 y1 + y);
00063
00064
00065 y1 += mwindow->theme->mode_h;
00066
00067 return y1;
00068 }
00069
00070 int VPatchGUI::update(int x, int y)
00071 {
00072 int h = track->vertical_span(mwindow->theme);
00073 int x1 = 0;
00074 int y1 = PatchGUI::update(x, y);
00075
00076 if(fade)
00077 {
00078 if(h - y1 < mwindow->theme->fade_h)
00079 {
00080 delete fade;
00081 fade = 0;
00082 }
00083 else
00084 {
00085 FloatAuto *previous = 0, *next = 0;
00086 double unit_position = mwindow->edl->local_session->get_selectionstart(1);
00087 unit_position = mwindow->edl->align_to_frame(unit_position, 0);
00088 unit_position = vtrack->to_units(unit_position, 0);
00089 int value = (int)((FloatAutos*)vtrack->automation->autos[AUTOMATION_FADE])->get_value(
00090 (int64_t)unit_position,
00091 PLAY_FORWARD,
00092 previous,
00093 next);
00094 fade->update(fade->get_w(),
00095 value,
00096 mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_VIDEO_FADE],
00097 mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_VIDEO_FADE]);
00098
00099 }
00100 }
00101 else
00102 if(h - y1 >= mwindow->theme->fade_h)
00103 {
00104 patchbay->add_subwindow(fade = new VFadePatch(mwindow,
00105 this,
00106 x1 + x,
00107 y1 + y,
00108 patchbay->get_w() - 10));
00109 }
00110 y1 += mwindow->theme->fade_h;
00111
00112 if(mode)
00113 {
00114 if(h - y1 < mwindow->theme->mode_h)
00115 {
00116 delete mode;
00117 mode = 0;
00118 delete nudge;
00119 nudge = 0;
00120 }
00121 else
00122 {
00123 mode->update(mode->get_keyframe(mwindow, this)->value);
00124 nudge->update();
00125 }
00126 }
00127 else
00128 if(h - y1 >= mwindow->theme->mode_h)
00129 {
00130 patchbay->add_subwindow(mode = new VModePatch(mwindow,
00131 this,
00132 x1 + x,
00133 y1 + y));
00134 mode->create_objects();
00135 x1 += mode->get_w() + 10;
00136 patchbay->add_subwindow(nudge = new NudgePatch(mwindow,
00137 this,
00138 x1 + x,
00139 y1 + y,
00140 patchbay->get_w() - x1 - 10));
00141 }
00142
00143
00144
00145
00146
00147 y1 += mwindow->theme->mode_h;
00148
00149 return y1;
00150 }
00151
00152
00153
00154 void VPatchGUI::synchronize_fade(float value_change)
00155 {
00156 if(fade && !change_source)
00157 {
00158 fade->update(Units::to_int64(fade->get_value() + value_change));
00159 fade->update_edl();
00160 }
00161 }
00162
00163
00164 VFadePatch::VFadePatch(MWindow *mwindow, VPatchGUI *patch, int x, int y, int w)
00165 : BC_ISlider(x,
00166 y,
00167 0,
00168 w,
00169 w,
00170 mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_VIDEO_FADE],
00171 mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_VIDEO_FADE],
00172 (int64_t)get_keyframe(mwindow, patch)->value)
00173 {
00174 this->mwindow = mwindow;
00175 this->patch = patch;
00176 }
00177
00178 float VFadePatch::update_edl()
00179 {
00180 FloatAuto *current;
00181 double position = mwindow->edl->local_session->get_selectionstart(1);
00182 Autos *fade_autos = patch->vtrack->automation->autos[AUTOMATION_FADE];
00183 int need_undo = !fade_autos->auto_exists_for_editing(position);
00184
00185
00186 current = (FloatAuto*)fade_autos->get_auto_for_editing(position);
00187
00188 float result = get_value() - current->value;
00189 current->value = get_value();
00190
00191 mwindow->undo->update_undo(_("fade"), LOAD_AUTOMATION, need_undo ? 0 : this);
00192
00193 return result;
00194 }
00195
00196 int VFadePatch::handle_event()
00197 {
00198 if(shift_down())
00199 {
00200 update(100);
00201 set_tooltip(get_caption());
00202 }
00203
00204 patch->change_source = 1;
00205
00206 float change = update_edl();
00207
00208 if(patch->track->gang)
00209 patch->patchbay->synchronize_faders(change, TRACK_VIDEO, patch->track);
00210
00211 patch->change_source = 0;
00212
00213
00214 mwindow->gui->unlock_window();
00215 mwindow->restart_brender();
00216 mwindow->sync_parameters(CHANGE_PARAMS);
00217 mwindow->gui->lock_window("VFadePatch::handle_event");
00218 if(mwindow->edl->session->auto_conf->autos[AUTOMATION_FADE])
00219 {
00220 mwindow->gui->canvas->draw_overlays();
00221 mwindow->gui->canvas->flash();
00222 }
00223 return 1;
00224 }
00225
00226 FloatAuto* VFadePatch::get_keyframe(MWindow *mwindow, VPatchGUI *patch)
00227 {
00228 double unit_position = mwindow->edl->local_session->get_selectionstart(1);
00229 unit_position = mwindow->edl->align_to_frame(unit_position, 0);
00230 unit_position = patch->vtrack->to_units(unit_position, 0);
00231 Auto *current = 0;
00232
00233 return (FloatAuto*)patch->vtrack->automation->autos[AUTOMATION_FADE]->get_prev_auto(
00234 (int64_t)unit_position,
00235 PLAY_FORWARD,
00236 current);
00237 }
00238
00239
00240
00241
00242 VModePatch::VModePatch(MWindow *mwindow, VPatchGUI *patch, int x, int y)
00243 : BC_PopupMenu(x,
00244 y,
00245 patch->patchbay->mode_icons[0]->get_w() + 20,
00246 "",
00247 1,
00248 mwindow->theme->get_image_set("mode_popup", 0),
00249 10)
00250 {
00251 this->mwindow = mwindow;
00252 this->patch = patch;
00253 this->mode = get_keyframe(mwindow, patch)->value;
00254 set_icon(patch->patchbay->mode_to_icon(this->mode));
00255 set_tooltip("Overlay mode");
00256 }
00257
00258 int VModePatch::handle_event()
00259 {
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 update(mode);
00270
00271
00272 IntAuto *current;
00273 double position = mwindow->edl->local_session->get_selectionstart(1);
00274 Autos *mode_autos = patch->vtrack->automation->autos[AUTOMATION_MODE];
00275 int need_undo = !mode_autos->auto_exists_for_editing(position);
00276
00277
00278 current = (IntAuto*)mode_autos->get_auto_for_editing(position);
00279 current->value = mode;
00280
00281 mwindow->undo->update_undo(_("mode"), LOAD_AUTOMATION, need_undo ? 0 : this);
00282
00283 mwindow->sync_parameters(CHANGE_PARAMS);
00284
00285 if(mwindow->edl->session->auto_conf->autos[AUTOMATION_MODE])
00286 {
00287 mwindow->gui->canvas->draw_overlays();
00288 mwindow->gui->canvas->flash();
00289 }
00290 mwindow->session->changes_made = 1;
00291 return 1;
00292 }
00293
00294 IntAuto* VModePatch::get_keyframe(MWindow *mwindow, VPatchGUI *patch)
00295 {
00296 Auto *current = 0;
00297 double unit_position = mwindow->edl->local_session->get_selectionstart(1);
00298 unit_position = mwindow->edl->align_to_frame(unit_position, 0);
00299 unit_position = patch->vtrack->to_units(unit_position, 0);
00300
00301 return (IntAuto*)patch->vtrack->automation->autos[AUTOMATION_MODE]->get_prev_auto(
00302 (int64_t)unit_position,
00303 PLAY_FORWARD,
00304 current);
00305 }
00306
00307
00308 int VModePatch::create_objects()
00309 {
00310 add_item(new VModePatchItem(this, mode_to_text(TRANSFER_NORMAL), TRANSFER_NORMAL));
00311 add_item(new VModePatchItem(this, mode_to_text(TRANSFER_ADDITION), TRANSFER_ADDITION));
00312 add_item(new VModePatchItem(this, mode_to_text(TRANSFER_SUBTRACT), TRANSFER_SUBTRACT));
00313 add_item(new VModePatchItem(this, mode_to_text(TRANSFER_MULTIPLY), TRANSFER_MULTIPLY));
00314 add_item(new VModePatchItem(this, mode_to_text(TRANSFER_DIVIDE), TRANSFER_DIVIDE));
00315 add_item(new VModePatchItem(this, mode_to_text(TRANSFER_REPLACE), TRANSFER_REPLACE));
00316 add_item(new VModePatchItem(this, mode_to_text(TRANSFER_MAX), TRANSFER_MAX));
00317 return 0;
00318 }
00319
00320 void VModePatch::update(int mode)
00321 {
00322 set_icon(patch->patchbay->mode_to_icon(mode));
00323 for(int i = 0; i < total_items(); i++)
00324 {
00325 VModePatchItem *item = (VModePatchItem*)get_item(i);
00326 item->set_checked(item->mode == mode);
00327 }
00328 }
00329
00330
00331 char* VModePatch::mode_to_text(int mode)
00332 {
00333 switch(mode)
00334 {
00335 case TRANSFER_NORMAL:
00336 return _("Normal");
00337 break;
00338
00339 case TRANSFER_REPLACE:
00340 return _("Replace");
00341 break;
00342
00343 case TRANSFER_ADDITION:
00344 return _("Addition");
00345 break;
00346
00347 case TRANSFER_SUBTRACT:
00348 return _("Subtract");
00349 break;
00350
00351 case TRANSFER_MULTIPLY:
00352 return _("Multiply");
00353 break;
00354
00355 case TRANSFER_DIVIDE:
00356 return _("Divide");
00357 break;
00358
00359 case TRANSFER_MAX:
00360 return _("Max");
00361 break;
00362
00363 default:
00364 return _("Normal");
00365 break;
00366 }
00367 return "";
00368 }
00369
00370
00371
00372
00373
00374
00375 VModePatchItem::VModePatchItem(VModePatch *popup, char *text, int mode)
00376 : BC_MenuItem(text)
00377 {
00378 this->popup = popup;
00379 this->mode = mode;
00380 if(this->mode == popup->mode) set_checked(1);
00381 }
00382
00383 int VModePatchItem::handle_event()
00384 {
00385 popup->mode = mode;
00386
00387 popup->handle_event();
00388 return 1;
00389 }