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"
33 #include "localsession.h"
34 #include "mainsession.h"
37 #include "mwindowgui.h"
38 #include "overlayframe.inc"
41 #include "trackcanvas.h"
42 #include "vpatchgui.h"
49 VPatchGUI::VPatchGUI(MWindow *mwindow, PatchBay *patchbay, VTrack *track, int x, int y)
50 : PatchGUI(mwindow, patchbay, track, x, y)
52 data_type = TRACK_VIDEO;
58 VPatchGUI::~VPatchGUI()
60 if( fade ) delete fade;
61 if( mode ) delete mode;
64 void VPatchGUI::create_objects()
69 int VPatchGUI::reposition(int x, int y)
72 int y1 = PatchGUI::reposition(x, y);
75 fade->reposition_window(fade->get_x(), y1+y);
76 y1 += mwindow->theme->fade_h;
78 mix->reposition_window(mix->get_x(), y1+y);
80 mode->reposition_window(mode->get_x(), y1+y);
82 nudge->reposition_window(nudge->get_x(), y1+y);
83 y1 += mwindow->theme->mode_h;
87 int VPatchGUI::update(int x, int y)
89 int h = track->vertical_span(mwindow->theme);
91 int y1 = PatchGUI::update(x, y);
93 int y2 = y1 + mwindow->theme->fade_h;
96 delete fade; fade = 0;
99 FloatAuto *previous = 0, *next = 0;
100 double unit_position = mwindow->edl->local_session->get_selectionstart(1);
101 int64_t unit_pos = vtrack->to_units(unit_position, 0);
102 FloatAutos *ptr = (FloatAutos*)track->automation->autos[AUTOMATION_FADE];
103 float value = ptr->get_value(unit_pos, PLAY_FORWARD, previous, next);
104 fade->update(fade->get_w(), value,
105 mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_VIDEO_FADE],
106 mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_VIDEO_FADE]);
110 int64_t v = mwindow->get_float_auto(this, AUTOMATION_FADE)->get_value();
111 patchbay->add_subwindow(fade = new VFadePatch(this, x1+x, y1+y,
112 patchbay->get_w() - xS(10), v));
116 y2 = y1 + mwindow->theme->mode_h;
120 delete mode; mode = 0;
121 delete nudge; nudge = 0;
124 if( mwindow->session->selected_zwindow >= 0 ) {
125 int v = mwindow->mixer_track_active(track);
128 mode->update(mwindow->get_int_auto(this, AUTOMATION_MODE)->value);
133 patchbay->add_subwindow(mix = new VMixPatch(mwindow, this, x1+x, y1+y+yS(5)));
135 patchbay->add_subwindow(mode = new VModePatch(mwindow, this, x1+x, y1+y));
136 mode->create_objects();
138 patchbay->add_subwindow(nudge = new NudgePatch(mwindow, this, x1+x, y1+y,
139 patchbay->get_w() - x1-x - xS(10)));
146 VFadePatch::VFadePatch(VPatchGUI *patch, int x, int y, int w, int64_t v)
147 : BC_ISlider(x, y, 0, w, w,
148 patch->mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_VIDEO_FADE],
149 patch->mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_VIDEO_FADE],
155 void VPatchGUI::update_faders(float v)
161 double position = mwindow->edl->local_session->get_selectionstart(1);
162 Autos *fade_autos = vtrack->automation->autos[AUTOMATION_FADE];
163 int need_undo = !fade_autos->auto_exists_for_editing(position);
164 mwindow->undo->update_undo_before(_("fade"), need_undo ? 0 : this);
165 FloatAuto *current = (FloatAuto*)fade_autos->get_auto_for_editing(position);
166 float change = v - current->get_value(edge);
167 current->bump_value(v, edge, span);
168 if( track->is_ganged() && track->is_armed() )
169 patchbay->synchronize_faders(change, TRACK_VIDEO, track, edge, span);
170 mwindow->undo->update_undo_after(_("fade"), LOAD_AUTOMATION);
173 mwindow->sync_parameters(CHANGE_PARAMS);
175 if( mwindow->edl->session->auto_conf->autos[AUTOMATION_FADE] ) {
176 mwindow->gui->draw_overlays(1);
180 int VFadePatch::handle_event()
184 set_tooltip(get_caption());
186 patch->update_faders(get_value());
190 VKeyFadePatch::VKeyFadePatch(MWindow *mwindow, VPatchGUI *gui,
191 int bump, int x, int y)
192 : BC_SubWindow(x,y, xS(200),yS(bump ? 50 : 24),
193 GWindowGUI::auto_colors[AUTOMATION_FADE])
195 this->mwindow = mwindow;
198 VKeyFadePatch::~VKeyFadePatch()
202 void VKeyFadePatch::create_objects()
204 int x = 0, x1 = x, y = 0, dy = 0;
205 FloatAuto *fade_auto = mwindow->get_float_auto(gui, AUTOMATION_FADE);
206 int64_t v = fade_auto->get_value(gui->edge);
207 add_subwindow(vkey_fade_text = new VKeyFadeText(this, x, y, xS(64), v));
208 x += vkey_fade_text->get_w();
209 dy = bmax(dy, vkey_fade_text->get_h());
210 VFrame **lok_images = mwindow->theme->get_image_set("lok");
211 int w1 = get_w() - x - lok_images[0]->get_w();
212 add_subwindow(vkey_fade_slider = new VKeyFadeSlider(this, x, y, w1, v));
213 x += vkey_fade_slider->get_w();
214 dy = bmax(dy, vkey_fade_slider->get_h());
215 add_subwindow(vkey_fade_ok = new VKeyFadeOK(this, x, y, lok_images));
216 dy = bmax(dy, vkey_fade_ok->get_h());
217 if( fade_auto->is_bump() ) {
219 set_color(get_resources()->get_bg_color());
220 draw_box(0,y, get_w(),get_h());
221 add_subwindow(auto_edge = new VKeyPatchAutoEdge(mwindow, this, x1, y));
222 x1 += auto_edge->get_w() + xS(15);
223 add_subwindow(auto_span = new VKeyPatchAutoSpan(mwindow, this, x1, y));
225 draw_3d_border(0,0, get_w(), get_h(), 0);
230 void VKeyFadePatch::set_edge(int edge)
233 FloatAuto *fade_auto = mwindow->get_float_auto(gui, AUTOMATION_FADE);
234 int64_t v = fade_auto->get_value(edge);
238 void VKeyFadePatch::set_span(int span)
243 void VKeyFadePatch::update(int64_t v)
245 vkey_fade_text->update(v);
246 vkey_fade_slider->update(v);
247 gui->update_faders(v);
250 VKeyFadeOK::VKeyFadeOK(VKeyFadePatch *vkey_fade_patch, int x, int y, VFrame **images)
251 : BC_Button(x, y, images)
253 this->vkey_fade_patch = vkey_fade_patch;
256 int VKeyFadeOK::handle_event()
258 MWindow *mwindow = vkey_fade_patch->mwindow;
259 mwindow->gui->close_keyvalue_popup();
263 VKeyFadeText::VKeyFadeText(VKeyFadePatch *vkey_fade_patch, int x, int y, int w, int64_t v)
264 : BC_TextBox(x, y, w, 1, v, 1, MEDIUMFONT)
266 this->vkey_fade_patch = vkey_fade_patch;
269 int VKeyFadeText::handle_event()
271 int64_t v = atoi(get_text());
272 vkey_fade_patch->update(v);
273 return get_keypress() != RETURN ? 1 :
274 vkey_fade_patch->vkey_fade_ok->handle_event();
277 VKeyFadeSlider::VKeyFadeSlider(VKeyFadePatch *vkey_fade_patch,
278 int x, int y, int w, int64_t v)
279 : VFadePatch(vkey_fade_patch->gui, x,y, w, v)
281 this->vkey_fade_patch = vkey_fade_patch;
284 int VKeyFadeSlider::handle_event()
286 int64_t v = get_value();
287 vkey_fade_patch->update(v);
292 VModePatch::VModePatch(MWindow *mwindow, VPatchGUI *patch, int x, int y)
293 : BC_PopupMenu(x, y, patch->patchbay->mode_icons[0]->get_w() + xS(20),
294 "", 1, mwindow->theme->get_image_set("mode_popup", 0), 0)
296 this->mwindow = mwindow;
298 this->mode = mwindow->get_int_auto(patch, AUTOMATION_MODE)->value;
299 set_icon(patch->patchbay->mode_to_icon(this->mode));
300 set_tooltip(_("Overlay mode"));
301 // *** CONTEXT_HELP ***
302 context_help_set_keyword("Overlays");
305 VModePatch::VModePatch(MWindow *mwindow, VPatchGUI *patch)
306 : BC_PopupMenu(0, 0, 0, "", 0)
308 this->mwindow = mwindow;
310 this->mode = mwindow->get_int_auto(patch, AUTOMATION_MODE)->value;
314 int VModePatch::handle_event()
317 // for( int i = 0; i < total_items(); i++ )
319 // VModePatchItem *item = (VModePatchItem*)get_item(i);
320 // if( item->mode == mode )
321 // item->set_checked(1);
323 // item->set_checked(0);
329 double position = mwindow->edl->local_session->get_selectionstart(1);
330 Autos *mode_autos = patch->vtrack->automation->autos[AUTOMATION_MODE];
331 int need_undo = !mode_autos->auto_exists_for_editing(position);
332 mwindow->undo->update_undo_before(_("mode"), need_undo ? 0 : this);
333 current = (IntAuto*)mode_autos->get_auto_for_editing(position);
334 current->value = mode;
335 mwindow->undo->update_undo_after(_("mode"), LOAD_AUTOMATION);
336 mwindow->sync_parameters(CHANGE_PARAMS);
338 if( mwindow->edl->session->auto_conf->autos[AUTOMATION_MODE] ) {
339 mwindow->gui->draw_overlays(1);
341 mwindow->session->changes_made = 1;
345 void VModePatch::create_objects()
347 VModePatchItem *mode_item;
348 VModePatchSubMenu *submenu;
349 add_item(mode_item = new VModePatchItem(this, mode_to_text(TRANSFER_NORMAL), TRANSFER_NORMAL));
350 add_item(mode_item = new VModePatchItem(this, _("Arithmetic..."), -1));
351 mode_item->add_submenu(submenu = new VModePatchSubMenu(mode_item));
352 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_ADDITION), TRANSFER_ADDITION));
353 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SUBTRACT), TRANSFER_SUBTRACT));
354 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DIVIDE), TRANSFER_DIVIDE));
355 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_MULTIPLY), TRANSFER_MULTIPLY));
356 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_REPLACE), TRANSFER_REPLACE));
357 add_item(mode_item = new VModePatchItem(this, _("PorterDuff..."), -1));
358 mode_item->add_submenu(submenu = new VModePatchSubMenu(mode_item));
359 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST), TRANSFER_DST));
360 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST_ATOP), TRANSFER_DST_ATOP));
361 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST_IN), TRANSFER_DST_IN));
362 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST_OUT), TRANSFER_DST_OUT));
363 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST_OVER), TRANSFER_DST_OVER));
364 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SRC), TRANSFER_SRC));
365 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SRC_ATOP), TRANSFER_SRC_ATOP));
366 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SRC_IN), TRANSFER_SRC_IN));
367 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SRC_OUT), TRANSFER_SRC_OUT));
368 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SRC_OVER), TRANSFER_SRC_OVER));
369 add_item(mode_item = new VModePatchItem(this, _("Logical..."), -1));
370 mode_item->add_submenu(submenu = new VModePatchSubMenu(mode_item));
371 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_MIN), TRANSFER_MIN));
372 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_MAX), TRANSFER_MAX));
373 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DARKEN), TRANSFER_DARKEN));
374 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_LIGHTEN), TRANSFER_LIGHTEN));
375 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_AND), TRANSFER_AND));
376 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_OR), TRANSFER_OR));
377 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_XOR), TRANSFER_XOR));
378 add_item(mode_item = new VModePatchItem(this, _("Graphic Art..."), -1));
379 mode_item->add_submenu(submenu = new VModePatchSubMenu(mode_item));
380 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_OVERLAY), TRANSFER_OVERLAY));
381 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SCREEN), TRANSFER_SCREEN));
382 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_BURN), TRANSFER_BURN));
383 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DODGE), TRANSFER_DODGE));
384 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DIFFERENCE),TRANSFER_DIFFERENCE));
385 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_HARDLIGHT),TRANSFER_HARDLIGHT));
386 submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SOFTLIGHT),TRANSFER_SOFTLIGHT));
389 void VModePatch::update(int mode)
391 set_icon(patch->patchbay->mode_to_icon(mode));
392 for( int i = 0; i < total_items(); i++ ) {
393 VModePatchItem *item = (VModePatchItem*)get_item(i);
394 item->set_checked(item->mode == mode);
395 VModePatchSubMenu *submenu = (VModePatchSubMenu *)item->get_submenu();
396 if( !submenu ) continue;
397 int n = submenu->total_items();
398 for( int j=0; j<n; ++j ) {
399 VModePatchItem *subitem = (VModePatchItem*)submenu->get_item(j);
400 subitem->set_checked(subitem->mode == mode);
406 const char* VModePatch::mode_to_text(int mode)
409 case TRANSFER_NORMAL: return _("Normal");
410 case TRANSFER_ADDITION: return _("Addition");
411 case TRANSFER_SUBTRACT: return _("Subtract");
412 case TRANSFER_MULTIPLY: return _("Multiply");
413 case TRANSFER_DIVIDE: return _("Divide");
414 case TRANSFER_REPLACE: return _("Replace");
415 case TRANSFER_MAX: return _("Max");
416 case TRANSFER_MIN: return _("Min");
417 case TRANSFER_DARKEN: return _("Darken");
418 case TRANSFER_LIGHTEN: return _("Lighten");
419 case TRANSFER_DST: return _("Dst");
420 case TRANSFER_DST_ATOP: return _("DstAtop");
421 case TRANSFER_DST_IN: return _("DstIn");
422 case TRANSFER_DST_OUT: return _("DstOut");
423 case TRANSFER_DST_OVER: return _("DstOver");
424 case TRANSFER_SRC: return _("Src");
425 case TRANSFER_SRC_ATOP: return _("SrcAtop");
426 case TRANSFER_SRC_IN: return _("SrcIn");
427 case TRANSFER_SRC_OUT: return _("SrcOut");
428 case TRANSFER_SRC_OVER: return _("SrcOver");
429 case TRANSFER_AND: return _("AND");
430 case TRANSFER_OR: return _("OR");
431 case TRANSFER_XOR: return _("XOR");
432 case TRANSFER_OVERLAY: return _("Overlay");
433 case TRANSFER_SCREEN: return _("Screen");
434 case TRANSFER_BURN: return _("Burn");
435 case TRANSFER_DODGE: return _("Dodge");
436 case TRANSFER_HARDLIGHT: return _("Hardlight");
437 case TRANSFER_SOFTLIGHT: return _("Softlight");
438 case TRANSFER_DIFFERENCE: return _("Difference");
445 VModePatchItem::VModePatchItem(VModePatch *popup, const char *text, int mode)
450 if( this->mode == popup->mode ) set_checked(1);
453 int VModePatchItem::handle_event()
457 // popup->set_icon(popup->patch->patchbay->mode_to_icon(mode));
458 popup->handle_event();
463 VModePatchSubMenu::VModePatchSubMenu(VModePatchItem *mode_item)
465 this->mode_item = mode_item;
467 VModePatchSubMenu::~VModePatchSubMenu()
471 VModeSubMenuItem::VModeSubMenuItem(VModePatchSubMenu *submenu, const char *text, int mode)
474 this->submenu = submenu;
476 VModePatch *popup = submenu->mode_item->popup;
477 if( this->mode == popup->mode ) set_checked(1);
479 VModeSubMenuItem::~VModeSubMenuItem()
483 int VModeSubMenuItem::handle_event()
485 VModePatch *popup = submenu->mode_item->popup;
487 // popup->set_icon(popup->patch->patchbay->mode_to_icon(mode));
488 popup->handle_event();
493 VKeyModePatch::VKeyModePatch(MWindow *mwindow, VPatchGUI *patch)
494 : VModePatch(mwindow, patch)
498 int VKeyModePatch::handle_event()
500 int ret = VModePatch::handle_event();
501 VModePatch *mode = patch->mode;
503 mode->update(this->mode);
508 VMixPatch::VMixPatch(MWindow *mwindow, VPatchGUI *patch, int x, int y)
509 : MixPatch(mwindow, patch, x, y)
511 set_tooltip(_("Mixer"));
512 // *** CONTEXT_HELP ***
513 context_help_set_keyword("Recover Mixer Windows");
516 VMixPatch::~VMixPatch()
520 VKeyPatchAutoEdge::VKeyPatchAutoEdge(MWindow *mwindow,
521 VKeyFadePatch *patch, int x, int y)
522 : BC_Toggle(x, y, mwindow->theme->get_image_set("bump_edge"),
523 patch->gui->edge,_("Edge"))
525 this->mwindow = mwindow;
527 set_tooltip(_("Bump uses left edge"));
530 int VKeyPatchAutoEdge::handle_event()
532 patch->set_edge(get_value());
536 VKeyPatchAutoSpan::VKeyPatchAutoSpan(MWindow *mwindow,
537 VKeyFadePatch *patch, int x, int y)
538 : BC_Toggle(x, y, mwindow->theme->get_image_set("bump_span"),
539 patch->gui->span,_("Span"))
541 this->mwindow = mwindow;
543 set_tooltip(_("Bump spans to next"));
546 int VKeyPatchAutoSpan::handle_event()
548 patch->set_span(get_value());