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(value);
00095
00096 }
00097 }
00098 else
00099 if(h - y1 >= mwindow->theme->fade_h)
00100 {
00101 patchbay->add_subwindow(fade = new VFadePatch(mwindow,
00102 this,
00103 x1 + x,
00104 y1 + y,
00105 patchbay->get_w() - 10));
00106 }
00107 y1 += mwindow->theme->fade_h;
00108
00109 if(mode)
00110 {
00111 if(h - y1 < mwindow->theme->mode_h)
00112 {
00113 delete mode;
00114 mode = 0;
00115 delete nudge;
00116 nudge = 0;
00117 }
00118 else
00119 {
00120 mode->update(mode->get_keyframe(mwindow, this)->value);
00121 nudge->update();
00122 }
00123 }
00124 else
00125 if(h - y1 >= mwindow->theme->mode_h)
00126 {
00127 patchbay->add_subwindow(mode = new VModePatch(mwindow,
00128 this,
00129 x1 + x,
00130 y1 + y));
00131 mode->create_objects();
00132 x1 += mode->get_w() + 10;
00133 patchbay->add_subwindow(nudge = new NudgePatch(mwindow,
00134 this,
00135 x1 + x,
00136 y1 + y,
00137 patchbay->get_w() - x1 - 10));
00138 }
00139
00140
00141
00142
00143
00144 y1 += mwindow->theme->mode_h;
00145
00146 return y1;
00147 }
00148
00149
00150
00151 void VPatchGUI::synchronize_fade(float value_change)
00152 {
00153 if(fade && !change_source)
00154 {
00155 fade->update(Units::to_int64(fade->get_value() + value_change));
00156 fade->update_edl();
00157 }
00158 }
00159
00160
00161 VFadePatch::VFadePatch(MWindow *mwindow, VPatchGUI *patch, int x, int y, int w)
00162 : BC_ISlider(x,
00163 y,
00164 0,
00165 w,
00166 w,
00167 0,
00168 MAX_VIDEO_FADE,
00169 (int64_t)get_keyframe(mwindow, patch)->value)
00170 {
00171 this->mwindow = mwindow;
00172 this->patch = patch;
00173 }
00174
00175 float VFadePatch::update_edl()
00176 {
00177 FloatAuto *current;
00178 double position = mwindow->edl->local_session->get_selectionstart(1);
00179 Autos *fade_autos = patch->vtrack->automation->autos[AUTOMATION_FADE];
00180 int need_undo = !fade_autos->auto_exists_for_editing(position);
00181
00182
00183 current = (FloatAuto*)fade_autos->get_auto_for_editing(position);
00184
00185 float result = get_value() - current->value;
00186 current->value = get_value();
00187
00188 mwindow->undo->update_undo(_("fade"), LOAD_AUTOMATION, need_undo ? 0 : this);
00189
00190 return result;
00191 }
00192
00193 int VFadePatch::handle_event()
00194 {
00195 if(shift_down())
00196 {
00197 update(100);
00198 set_tooltip(get_caption());
00199 }
00200
00201 patch->change_source = 1;
00202
00203 float change = update_edl();
00204
00205 if(patch->track->gang)
00206 patch->patchbay->synchronize_faders(change, TRACK_VIDEO, patch->track);
00207
00208 patch->change_source = 0;
00209
00210
00211 mwindow->gui->unlock_window();
00212 mwindow->restart_brender();
00213 mwindow->sync_parameters(CHANGE_PARAMS);
00214 mwindow->gui->lock_window("VFadePatch::handle_event");
00215 if(mwindow->edl->session->auto_conf->autos[AUTOMATION_FADE])
00216 {
00217 mwindow->gui->canvas->draw_overlays();
00218 mwindow->gui->canvas->flash();
00219 }
00220 return 1;
00221 }
00222
00223 FloatAuto* VFadePatch::get_keyframe(MWindow *mwindow, VPatchGUI *patch)
00224 {
00225 double unit_position = mwindow->edl->local_session->get_selectionstart(1);
00226 unit_position = mwindow->edl->align_to_frame(unit_position, 0);
00227 unit_position = patch->vtrack->to_units(unit_position, 0);
00228 Auto *current = 0;
00229
00230 return (FloatAuto*)patch->vtrack->automation->autos[AUTOMATION_FADE]->get_prev_auto(
00231 (int64_t)unit_position,
00232 PLAY_FORWARD,
00233 current);
00234 }
00235
00236
00237
00238
00239 VModePatch::VModePatch(MWindow *mwindow, VPatchGUI *patch, int x, int y)
00240 : BC_PopupMenu(x,
00241 y,
00242 patch->patchbay->mode_icons[0]->get_w() + 20,
00243 "",
00244 1,
00245 mwindow->theme->get_image_set("mode_popup", 0),
00246 10)
00247 {
00248 this->mwindow = mwindow;
00249 this->patch = patch;
00250 this->mode = get_keyframe(mwindow, patch)->value;
00251 set_icon(patch->patchbay->mode_to_icon(this->mode));
00252 set_tooltip("Overlay mode");
00253 }
00254
00255 int VModePatch::handle_event()
00256 {
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 update(mode);
00267
00268
00269 IntAuto *current;
00270 double position = mwindow->edl->local_session->get_selectionstart(1);
00271 Autos *mode_autos = patch->vtrack->automation->autos[AUTOMATION_MODE];
00272 int need_undo = !mode_autos->auto_exists_for_editing(position);
00273
00274
00275 current = (IntAuto*)mode_autos->get_auto_for_editing(position);
00276 current->value = mode;
00277
00278 mwindow->undo->update_undo(_("mode"), LOAD_AUTOMATION, need_undo ? 0 : this);
00279
00280 mwindow->sync_parameters(CHANGE_PARAMS);
00281
00282 if(mwindow->edl->session->auto_conf->autos[AUTOMATION_MODE])
00283 {
00284 mwindow->gui->canvas->draw_overlays();
00285 mwindow->gui->canvas->flash();
00286 }
00287 mwindow->session->changes_made = 1;
00288 return 1;
00289 }
00290
00291 IntAuto* VModePatch::get_keyframe(MWindow *mwindow, VPatchGUI *patch)
00292 {
00293 Auto *current = 0;
00294 double unit_position = mwindow->edl->local_session->get_selectionstart(1);
00295 unit_position = mwindow->edl->align_to_frame(unit_position, 0);
00296 unit_position = patch->vtrack->to_units(unit_position, 0);
00297
00298 return (IntAuto*)patch->vtrack->automation->autos[AUTOMATION_MODE]->get_prev_auto(
00299 (int64_t)unit_position,
00300 PLAY_FORWARD,
00301 current);
00302 }
00303
00304
00305 int VModePatch::create_objects()
00306 {
00307 add_item(new VModePatchItem(this, mode_to_text(TRANSFER_NORMAL), TRANSFER_NORMAL));
00308 add_item(new VModePatchItem(this, mode_to_text(TRANSFER_ADDITION), TRANSFER_ADDITION));
00309 add_item(new VModePatchItem(this, mode_to_text(TRANSFER_SUBTRACT), TRANSFER_SUBTRACT));
00310 add_item(new VModePatchItem(this, mode_to_text(TRANSFER_MULTIPLY), TRANSFER_MULTIPLY));
00311 add_item(new VModePatchItem(this, mode_to_text(TRANSFER_DIVIDE), TRANSFER_DIVIDE));
00312 add_item(new VModePatchItem(this, mode_to_text(TRANSFER_REPLACE), TRANSFER_REPLACE));
00313 return 0;
00314 }
00315
00316 void VModePatch::update(int mode)
00317 {
00318 set_icon(patch->patchbay->mode_to_icon(mode));
00319 for(int i = 0; i < total_items(); i++)
00320 {
00321 VModePatchItem *item = (VModePatchItem*)get_item(i);
00322 item->set_checked(item->mode == mode);
00323 }
00324 }
00325
00326
00327 char* VModePatch::mode_to_text(int mode)
00328 {
00329 switch(mode)
00330 {
00331 case TRANSFER_NORMAL:
00332 return _("Normal");
00333 break;
00334
00335 case TRANSFER_REPLACE:
00336 return _("Replace");
00337 break;
00338
00339 case TRANSFER_ADDITION:
00340 return _("Addition");
00341 break;
00342
00343 case TRANSFER_SUBTRACT:
00344 return _("Subtract");
00345 break;
00346
00347 case TRANSFER_MULTIPLY:
00348 return _("Multiply");
00349 break;
00350
00351 case TRANSFER_DIVIDE:
00352 return _("Divide");
00353 break;
00354
00355 default:
00356 return _("Normal");
00357 break;
00358 }
00359 return "";
00360 }
00361
00362
00363
00364
00365
00366
00367 VModePatchItem::VModePatchItem(VModePatch *popup, char *text, int mode)
00368 : BC_MenuItem(text)
00369 {
00370 this->popup = popup;
00371 this->mode = mode;
00372 if(this->mode == popup->mode) set_checked(1);
00373 }
00374
00375 int VModePatchItem::handle_event()
00376 {
00377 popup->mode = mode;
00378
00379 popup->handle_event();
00380 return 1;
00381 }