4 * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "automation.h"
25 #include "edlsession.h"
26 #include "floatauto.h"
27 #include "floatautos.h"
28 #include "gwindowgui.h"
32 #include "localsession.h"
33 #include "mainsession.h"
36 #include "mwindowgui.h"
37 #include "overlayframe.inc"
40 #include "trackcanvas.h"
41 #include "vpatchgui.h"
48 VPatchGUI::VPatchGUI(MWindow *mwindow, PatchBay *patchbay, VTrack *track, int x, int y)
49 : PatchGUI(mwindow, patchbay, track, x, y)
51 data_type = TRACK_VIDEO;
57 VPatchGUI::~VPatchGUI()
59 if( fade ) delete fade;
60 if( mode ) delete mode;
63 void VPatchGUI::create_objects()
68 int VPatchGUI::reposition(int x, int y)
71 int y1 = PatchGUI::reposition(x, y);
74 fade->reposition_window(fade->get_x(), y1+y);
75 y1 += mwindow->theme->fade_h;
77 mix->reposition_window(mix->get_x(), y1+y);
79 mode->reposition_window(mode->get_x(), y1+y);
81 nudge->reposition_window(nudge->get_x(), y1+y);
82 y1 += mwindow->theme->mode_h;
86 int VPatchGUI::update(int x, int y)
88 int h = track->vertical_span(mwindow->theme);
90 int y1 = PatchGUI::update(x, y);
93 if( h - y1 < mwindow->theme->fade_h ) {
98 fade->update(fade->get_w(), mwindow->get_float_auto(this, AUTOMATION_FADE)->get_value(),
99 mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_VIDEO_FADE],
100 mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_VIDEO_FADE]);
104 if( h - y1 >= mwindow->theme->fade_h ) {
105 patchbay->add_subwindow(fade = new VFadePatch(mwindow, this, x1+x, y1+y,
106 patchbay->get_w() - 10));
108 y1 += mwindow->theme->fade_h;
111 if( h - y1 < mwindow->theme->mode_h ) {
113 delete mode; mode = 0;
114 delete nudge; nudge = 0;
117 if( mwindow->session->selected_zwindow >= 0 ) {
118 int v = mwindow->mixer_track_active(track);
121 mode->update(mwindow->get_int_auto(this, AUTOMATION_MODE)->value);
126 if( h - y1 >= mwindow->theme->mode_h ) {
127 patchbay->add_subwindow(mix = new VMixPatch(mwindow, this, x1+x, y1+y+5));
129 patchbay->add_subwindow(mode = new VModePatch(mwindow, this, x1+x, y1+y));
130 mode->create_objects();
132 patchbay->add_subwindow(nudge = new NudgePatch(mwindow, this, x1+x, y1+y,
133 patchbay->get_w() - x1-x - 10));
136 y1 += mwindow->theme->mode_h;
142 void VPatchGUI::synchronize_fade(float value_change)
144 if( fade && !change_source ) {
145 fade->update(Units::to_int64(fade->get_value() + value_change));
151 VFadePatch::VFadePatch(MWindow *mwindow, VPatchGUI *patch, int x, int y, int w)
152 : BC_ISlider(x, y, 0, w, w,
153 mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_VIDEO_FADE],
154 mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_VIDEO_FADE],
155 (int64_t)mwindow->get_float_auto(patch,AUTOMATION_FADE)->get_value())
157 this->mwindow = mwindow;
161 float VFadePatch::update_edl()
164 double position = mwindow->edl->local_session->get_selectionstart(1);
165 Autos *fade_autos = patch->vtrack->automation->autos[AUTOMATION_FADE];
166 int need_undo = !fade_autos->auto_exists_for_editing(position);
168 mwindow->undo->update_undo_before(_("fade"), need_undo ? 0 : this);
170 current = (FloatAuto*)fade_autos->get_auto_for_editing(position);
172 float result = get_value() - current->get_value();
173 current->set_value(get_value());
175 mwindow->undo->update_undo_after(_("fade"), LOAD_AUTOMATION);
180 int VFadePatch::handle_event()
184 set_tooltip(get_caption());
187 patch->change_source = 1;
189 float change = update_edl();
191 if( patch->track->gang && patch->track->record )
192 patch->patchbay->synchronize_faders(change, TRACK_VIDEO, patch->track);
194 patch->change_source = 0;
197 mwindow->gui->unlock_window();
198 mwindow->restart_brender();
199 mwindow->sync_parameters(CHANGE_PARAMS);
200 mwindow->gui->lock_window("VFadePatch::handle_event");
201 if( mwindow->edl->session->auto_conf->autos[AUTOMATION_FADE] ) {
202 mwindow->gui->draw_overlays(1);
208 VKeyFadePatch::VKeyFadePatch(MWindow *mwindow, VPatchGUI *patch, int x, int y)
209 : BC_SubWindow(x,y, patch->patchbay->get_w(),20,
210 GWindowGUI::auto_colors[AUTOMATION_FADE])
212 this->mwindow = mwindow;
216 void VKeyFadePatch::create_objects()
218 vkey_fade_value = new VKeyFadeValue(this);
219 add_subwindow(vkey_fade_value);
220 vkey_fade_value->activate();
224 VKeyFadeValue::VKeyFadeValue(VKeyFadePatch *vkey_fade_patch)
225 : VFadePatch(vkey_fade_patch->mwindow, vkey_fade_patch->patch,
226 0,0, vkey_fade_patch->get_w())
228 this->vkey_fade_patch = vkey_fade_patch;
231 int VKeyFadeValue::button_release_event()
233 VFadePatch::button_release_event();
237 int VKeyFadeValue::handle_event()
239 VPatchGUI *patch = vkey_fade_patch->patch;
240 int ret = VFadePatch::handle_event();
241 VFadePatch *fade = patch->fade;
243 fade->update(get_value());
248 VModePatch::VModePatch(MWindow *mwindow, VPatchGUI *patch, int x, int y)
249 : BC_PopupMenu(x, y, patch->patchbay->mode_icons[0]->get_w() + 20,
250 "", 1, mwindow->theme->get_image_set("mode_popup", 0), 10)
252 this->mwindow = mwindow;
254 this->mode = mwindow->get_int_auto(patch, AUTOMATION_MODE)->value;
255 set_icon(patch->patchbay->mode_to_icon(this->mode));
256 set_tooltip(_("Overlay mode"));
259 VModePatch::VModePatch(MWindow *mwindow, VPatchGUI *patch)
260 : BC_PopupMenu(0, 0, 0, "", 0)
262 this->mwindow = mwindow;
264 this->mode = mwindow->get_int_auto(patch, AUTOMATION_MODE)->value;
268 int VModePatch::handle_event()
271 // for( int i = 0; i < total_items(); i++ )
273 // VModePatchItem *item = (VModePatchItem*)get_item(i);
274 // if( item->mode == mode )
275 // item->set_checked(1);
277 // item->set_checked(0);
283 double position = mwindow->edl->local_session->get_selectionstart(1);
284 Autos *mode_autos = patch->vtrack->automation->autos[AUTOMATION_MODE];
285 int need_undo = !mode_autos->auto_exists_for_editing(position);
287 mwindow->undo->update_undo_before(_("mode"), need_undo ? 0 : this);
289 current = (IntAuto*)mode_autos->get_auto_for_editing(position);
290 current->value = mode;
292 mwindow->undo->update_undo_after(_("mode"), LOAD_AUTOMATION);
294 mwindow->sync_parameters(CHANGE_PARAMS);
296 if( mwindow->edl->session->auto_conf->autos[AUTOMATION_MODE] ) {
297 mwindow->gui->draw_overlays(1);
299 mwindow->session->changes_made = 1;
303 void VModePatch::create_objects()
305 VModePatchItem *mode_item;
306 VModePatchSubMenu *submenu;
307 add_item(mode_item = new VModePatchItem(this, mode_to_text(TRANSFER_NORMAL), TRANSFER_NORMAL));
308 add_item(mode_item = new VModePatchItem(this, _("Arithmetic..."), -1));
309 mode_item->add_submenu(submenu = new VModePatchSubMenu(mode_item));
310 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_ADDITION), TRANSFER_ADDITION));
311 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SUBTRACT), TRANSFER_SUBTRACT));
312 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DIVIDE), TRANSFER_DIVIDE));
313 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_MULTIPLY), TRANSFER_MULTIPLY));
314 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_REPLACE), TRANSFER_REPLACE));
315 add_item(mode_item = new VModePatchItem(this, _("PorterDuff..."), -1));
316 mode_item->add_submenu(submenu = new VModePatchSubMenu(mode_item));
317 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST), TRANSFER_DST));
318 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST_ATOP), TRANSFER_DST_ATOP));
319 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST_IN), TRANSFER_DST_IN));
320 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST_OUT), TRANSFER_DST_OUT));
321 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST_OVER), TRANSFER_DST_OVER));
322 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SRC), TRANSFER_SRC));
323 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SRC_ATOP), TRANSFER_SRC_ATOP));
324 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SRC_IN), TRANSFER_SRC_IN));
325 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SRC_OUT), TRANSFER_SRC_OUT));
326 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SRC_OVER), TRANSFER_SRC_OVER));
327 add_item(mode_item = new VModePatchItem(this, _("Logical..."), -1));
328 mode_item->add_submenu(submenu = new VModePatchSubMenu(mode_item));
329 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_MIN), TRANSFER_MIN));
330 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_MAX), TRANSFER_MAX));
331 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DARKEN), TRANSFER_DARKEN));
332 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_LIGHTEN), TRANSFER_LIGHTEN));
333 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_AND), TRANSFER_AND));
334 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_OR), TRANSFER_OR));
335 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_XOR), TRANSFER_XOR));
336 add_item(mode_item = new VModePatchItem(this, _("Graphic Art..."), -1));
337 mode_item->add_submenu(submenu = new VModePatchSubMenu(mode_item));
338 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_OVERLAY), TRANSFER_OVERLAY));
339 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SCREEN), TRANSFER_SCREEN));
340 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_BURN), TRANSFER_BURN));
341 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DODGE), TRANSFER_DODGE));
342 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DIFFERENCE),TRANSFER_DIFFERENCE));
343 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_HARDLIGHT),TRANSFER_HARDLIGHT));
344 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SOFTLIGHT),TRANSFER_SOFTLIGHT));
347 void VModePatch::update(int mode)
349 set_icon(patch->patchbay->mode_to_icon(mode));
350 for( int i = 0; i < total_items(); i++ ) {
351 VModePatchItem *item = (VModePatchItem*)get_item(i);
352 item->set_checked(item->mode == mode);
353 VModePatchSubMenu *submenu = (VModePatchSubMenu *)item->get_submenu();
354 if( !submenu ) continue;
355 int n = submenu->total_items();
356 for( int j=0; j<n; ++j ) {
357 VModePatchItem *subitem = (VModePatchItem*)submenu->get_item(j);
358 subitem->set_checked(subitem->mode == mode);
364 const char* VModePatch::mode_to_text(int mode)
367 case TRANSFER_NORMAL: return _("Normal");
368 case TRANSFER_ADDITION: return _("Addition");
369 case TRANSFER_SUBTRACT: return _("Subtract");
370 case TRANSFER_MULTIPLY: return _("Multiply");
371 case TRANSFER_DIVIDE: return _("Divide");
372 case TRANSFER_REPLACE: return _("Replace");
373 case TRANSFER_MAX: return _("Max");
374 case TRANSFER_MIN: return _("Min");
375 case TRANSFER_DARKEN: return _("Darken");
376 case TRANSFER_LIGHTEN: return _("Lighten");
377 case TRANSFER_DST: return _("Dst");
378 case TRANSFER_DST_ATOP: return _("DstAtop");
379 case TRANSFER_DST_IN: return _("DstIn");
380 case TRANSFER_DST_OUT: return _("DstOut");
381 case TRANSFER_DST_OVER: return _("DstOver");
382 case TRANSFER_SRC: return _("Src");
383 case TRANSFER_SRC_ATOP: return _("SrcAtop");
384 case TRANSFER_SRC_IN: return _("SrcIn");
385 case TRANSFER_SRC_OUT: return _("SrcOut");
386 case TRANSFER_SRC_OVER: return _("SrcOver");
387 case TRANSFER_AND: return _("AND");
388 case TRANSFER_OR: return _("OR");
389 case TRANSFER_XOR: return _("XOR");
390 case TRANSFER_OVERLAY: return _("Overlay");
391 case TRANSFER_SCREEN: return _("Screen");
392 case TRANSFER_BURN: return _("Burn");
393 case TRANSFER_DODGE: return _("Dodge");
394 case TRANSFER_HARDLIGHT: return _("Hardlight");
395 case TRANSFER_SOFTLIGHT: return _("Softlight");
396 case TRANSFER_DIFFERENCE: return _("Difference");
403 VModePatchItem::VModePatchItem(VModePatch *popup, const char *text, int mode)
408 if( this->mode == popup->mode ) set_checked(1);
411 int VModePatchItem::handle_event()
415 // popup->set_icon(popup->patch->patchbay->mode_to_icon(mode));
416 popup->handle_event();
421 VModePatchSubMenu::VModePatchSubMenu(VModePatchItem *mode_item)
423 this->mode_item = mode_item;
425 VModePatchSubMenu::~VModePatchSubMenu()
429 VModeSubMenuItem::VModeSubMenuItem(VModePatchSubMenu *submenu, const char *text, int mode)
432 this->submenu = submenu;
434 VModePatch *popup = submenu->mode_item->popup;
435 if( this->mode == popup->mode ) set_checked(1);
437 VModeSubMenuItem::~VModeSubMenuItem()
441 int VModeSubMenuItem::handle_event()
443 VModePatch *popup = submenu->mode_item->popup;
445 // popup->set_icon(popup->patch->patchbay->mode_to_icon(mode));
446 popup->handle_event();
451 VKeyModePatch::VKeyModePatch(MWindow *mwindow, VPatchGUI *patch)
452 : VModePatch(mwindow, patch)
456 int VKeyModePatch::button_release_event()
458 VModePatch::button_release_event();
462 int VKeyModePatch::handle_event()
464 int ret = VModePatch::handle_event();
465 VModePatch *mode = patch->mode;
467 mode->update(this->mode);
472 VMixPatch::VMixPatch(MWindow *mwindow, VPatchGUI *patch, int x, int y)
473 : MixPatch(mwindow, patch, x, y)
475 set_tooltip(_("Mixer"));
478 VMixPatch::~VMixPatch()